import React, { CSSProperties, useState } from 'react'; import { useNode, UserComponent } from '@craftjs/core'; import { cssPropsToString } from '../../utils/style-helpers'; import { escapeHtml, escapeAttr } 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; } 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: '', }, rules: { canDrag: () => true, canMoveIn: () => false, canMoveOut: () => true, }, }; /* ---------- HTML export ---------- */ (Tabs as any).toHtml = (props: TabsProps, _childrenHtml: string) => { const sectionStyle = cssPropsToString({ padding: '60px 20px', ...props.style, }); const idAttr = props.anchorId ? ` id="${escapeAttr(props.anchorId)}"` : ''; const tabs = props.tabs || defaultTabs; const activeTabBg = props.activeTabBg || '#3b82f6'; const activeTabColor = props.activeTabColor || '#ffffff'; const inactiveTabBg = props.inactiveTabBg || '#f1f5f9'; const inactiveTabColor = props.inactiveTabColor || '#64748b'; const contentBg = props.contentBg || '#ffffff'; const tabId = 'tabs_' + Math.random().toString(36).slice(2, 8); const tabButtons = tabs.map((tab, i) => { const isActive = i === 0; return ``; }).join('\n '); const tabPanels = tabs.map((tab, i) => { return `
${escapeHtml(tab.content)}
`; }).join('\n '); const switchScript = ``; return { html: `
${tabButtons}
${tabPanels}
${switchScript} `, }; };