'use client'; import { useMemo } from 'react'; import { WidgetContentProps } from '../types/widget'; import clsx from 'clsx'; import { getResponsiveStyle, ResponsiveSize } from '../utils/styles'; import { ActionTooltip } from '@theme/components'; export function WidgetContent({ widgetData, skipParentWrapper = false, onWidgetClick, selectedWidget, designMode, responsive, draggable, onDragStart, onDragOver, onDragLeave, onDrop }: WidgetContentProps) { const componentId = Object.keys(widgetData.attributes)[0]; const componentData = widgetData.attributes[componentId]; const parentData = widgetData.parent; const combinedStyles = useMemo( () => getResponsiveStyle( componentData?.style || {}, responsive as ResponsiveSize ), [componentData?.style, responsive] ); if (!componentData) return null; const parentStyles = parentData?.style ? Object.keys(parentData.style).reduce( (acc, breakpoint) => ({ ...acc, ...parentData.style[breakpoint] }), {} ) : {}; const getClickableStyles = (isSelected: boolean) => { const baseComponentId = componentId.split('-')[0]; const baseSelectedId = selectedWidget?.id?.split('-')[0]; return clsx( designMode && [ 'cursor-pointer', (isSelected || baseComponentId === baseSelectedId) && 'outline outline-2 outline-[#3B82F6] outline-offset-2' ] ); }; const renderActionTooltip = () => { if (!designMode || !selectedWidget || selectedWidget.id !== componentId) { return null; } return ( { window.parent.postMessage( { type: 'WIDGET_DELETE', data: { id: componentId } }, '*' ); }} onMoveUp={() => { window.parent.postMessage( { type: 'WIDGET_MOVE', data: { id: componentId, direction: 'up' } }, '*' ); }} onMoveDown={() => { window.parent.postMessage( { type: 'WIDGET_MOVE', data: { id: componentId, direction: 'down' } }, '*' ); }} onCopy={() => { window.parent.postMessage( { type: 'WIDGET_COPY', data: { id: componentId } }, '*' ); }} /> ); }; const wrapWithTooltip = (component: React.ReactNode) => { return (
{renderActionTooltip()} {component}
); }; const renderComponent = () => { let iconSvg; let Tag; let CustomTag; const dragProps = designMode && draggable ? { draggable: true, onDragStart, onDragOver, onDragLeave, onDrop } : {}; switch (componentData.type) { case 'text': Tag = ( componentData.tag || 'div' ).toLowerCase() as keyof React.JSX.IntrinsicElements; return wrapWithTooltip( {componentData.value?.text} ); case 'image': { const { src, mobileSrc, tabletSrc, desktopSrc, alt = '', sizes, mediaQueries = { mobile: '(max-width: 767px)', tablet: '(min-width: 768px) and (max-width: 1023px)', desktop: '(min-width: 1024px)' } } = componentData.value || {}; return wrapWithTooltip( {mobileSrc && ( )} {tabletSrc && ( )} {desktopSrc && ( )} {alt} ); } case 'icon': iconSvg = componentData.value?.sizes?.[ Object.keys(componentData.value.sizes || {})[0] ]; if (!iconSvg) return null; return wrapWithTooltip(
); case 'link': return wrapWithTooltip( {componentData.value?.text || componentData.value?.title || 'Link'} ); case 'divider': return wrapWithTooltip(
); default: if (componentData.tag) { CustomTag = componentData.tag.toLowerCase() as keyof React.JSX.IntrinsicElements; return wrapWithTooltip( {componentData.value?.text} ); } return wrapWithTooltip(
{componentData.value?.text}
); } }; if (parentData && !skipParentWrapper) { const ParentTag = ( parentData.tag || 'div' ).toLowerCase() as keyof React.JSX.IntrinsicElements; return ( {renderComponent()} ); } return renderComponent(); }