import React, { CSSProperties, useState } from 'react'; import { useNode, UserComponent } from '@craftjs/core'; import { cssPropsToString } from '../../utils/style-helpers'; interface TabItem { label: string; content: string; } interface TabsProps { tabs?: TabItem[]; style?: CSSProperties; activeTabBg?: string; activeTabColor?: string; inactiveTabBg?: string; inactiveTabColor?: string; contentBg?: 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', }) => { const { connectors: { connect, drag }, selected, } = useNode((node) => ({ selected: node.events.selected, })); const [activeIndex, setActiveIndex] = useState(0); return (
{ if (ref) connect(drag(ref)); }} style={{ padding: '60px 20px', backgroundColor: '#ffffff', outline: selected ? '2px solid #3b82f6' : 'none', ...style, }} >
{/* Tab buttons */}
{tabs.map((tab, i) => ( ))}
{/* Content panel */}
{tabs[activeIndex]?.content || ''}
); }; /* ---------- Settings panel ---------- */ const TabsSettings: React.FC = () => { const { actions: { setProp }, props } = useNode((node) => ({ props: node.data.props as TabsProps, })); const tabs = props.tabs || defaultTabs; const inputStyle: CSSProperties = { width: '100%', padding: '3px 6px', background: '#27272a', color: '#e4e4e7', border: '1px solid #3f3f46', borderRadius: 4, fontSize: 11, }; const labelStyle: CSSProperties = { fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }; const updateTab = (index: number, field: keyof TabItem, value: string) => { setProp((p: TabsProps) => { const updated = [...(p.tabs || defaultTabs)]; updated[index] = { ...updated[index], [field]: value }; p.tabs = updated; }); }; const addTab = () => { setProp((p: TabsProps) => { p.tabs = [...(p.tabs || defaultTabs), { label: 'New Tab', content: 'Tab content goes here.' }]; }); }; const removeTab = (index: number) => { setProp((p: TabsProps) => { const updated = [...(p.tabs || defaultTabs)]; updated.splice(index, 1); p.tabs = updated; }); }; const colorSwatches = ['#3b82f6', '#8b5cf6', '#10b981', '#f59e0b', '#ef4444', '#18181b', '#ffffff', '#f1f5f9']; return (
{colorSwatches.map((c) => (
{['#ffffff', '#18181b', '#1f2937', '#e2e8f0'].map((c) => (
{['#f1f5f9', '#e2e8f0', '#f8fafc', '#ffffff', '#27272a', '#18181b'].map((c) => (
{['#64748b', '#94a3b8', '#18181b', '#ffffff'].map((c) => (
{['#ffffff', '#f8fafc', '#f1f5f9', '#18181b', '#1e293b'].map((c) => (
{tabs.map((tab, i) => (
updateTab(i, 'label', e.target.value)} placeholder="Label" style={{ ...inputStyle, flex: 1 }} />