import React, { CSSProperties, useState } from 'react'; import { useNode, UserComponent } from '@craftjs/core'; import { cssPropsToString } from '../../utils/style-helpers'; import { escapeHtml, escapeAttr, scopeId, cssValue } from '../../utils/escape'; interface TabItem { label: string; content: string; } interface TabsProps { tabs?: TabItem[]; style?: CSSProperties; activeTabBg?: string; activeTabColor?: string; inactiveTabBg?: string; inactiveTabColor?: string; contentBg?: string; anchorId?: string; animation?: string; animationDelay?: string; hideOnDesktop?: boolean; hideOnTablet?: boolean; hideOnMobile?: boolean; } const defaultTabs: TabItem[] = [ { label: 'Overview', content: 'Welcome to our platform. We provide the tools you need to build, launch, and grow your online presence. Our intuitive interface makes it simple to get started in minutes.' }, { label: 'Features', content: 'Drag-and-drop editor, responsive templates, custom domains, analytics dashboard, SEO tools, and integrations with your favorite services. Everything you need in one place.' }, { label: 'Support', content: 'Our dedicated support team is available 24/7 to help you with any questions. Access our knowledge base, community forums, or reach out directly via live chat or email.' }, ]; export const Tabs: UserComponent = ({ tabs = defaultTabs, style = {}, activeTabBg = '#3b82f6', activeTabColor = '#ffffff', inactiveTabBg = '#f1f5f9', inactiveTabColor = '#64748b', contentBg = '#ffffff', anchorId, }) => { const { connectors: { connect, drag }, selected, } = useNode((node) => ({ selected: node.events.selected, })); const [activeIndex, setActiveIndex] = useState(0); return (
{ if (ref) connect(drag(ref)); }} id={anchorId || undefined} style={{ padding: '60px 20px', backgroundColor: '#ffffff', outline: selected ? '2px solid #3b82f6' : 'none', ...style, }} >
{/* Tab buttons */}
{tabs.map((tab, i) => ( ))}
{/* Content panel */}
{tabs[activeIndex]?.content || ''}
); }; /* ---------- Craft config ---------- */ Tabs.craft = { displayName: 'Tabs', props: { tabs: defaultTabs, style: { backgroundColor: '#ffffff' }, activeTabBg: '#3b82f6', activeTabColor: '#ffffff', inactiveTabBg: '#f1f5f9', inactiveTabColor: '#64748b', contentBg: '#ffffff', anchorId: '', animation: '', animationDelay: '', hideOnDesktop: false, hideOnTablet: false, hideOnMobile: false, }, rules: { canDrag: () => true, canMoveIn: () => false, canMoveOut: () => true, }, }; /* ---------- HTML export ---------- */ (Tabs as any).toHtml = (props: TabsProps, _childrenHtml: string, nodeId?: string) => { const sectionStyle = cssPropsToString({ padding: '60px 20px', ...props.style, }); const idAttr = props.anchorId ? ` id="${escapeAttr(props.anchorId)}"` : ''; const tabs = props.tabs || defaultTabs; // Sanitized -- raw string-interpolation sinks below, both into style="..." // attributes AND into an inline `; return { html: `
${tabButtons}
${tabPanels}
${switchScript} `, }; };