Files
sigpro-ui/docs/components/tabs.md
2026-04-06 03:19:15 +02:00

12 KiB
Raw Blame History

Tabs

Tabs component for organizing content into separate panels with tab navigation.

Tag

Tabs

Props

Prop Type Default Description
items Array<TabItem> | Signal<Array> [] Array of tab items
class string '' Additional CSS classes (DaisyUI + Tailwind)

TabItem Structure

Property Type Description
label string | VNode Tab button label
content VNode | function Content to display when tab is active
active boolean | Signal<boolean> Whether this tab is active (only one per group)
disabled boolean Whether tab is disabled
tip string Tooltip text for the tab
onclick function Click handler (optional, overrides default)

Styling

Tabs supports all daisyUI Tabs classes:

Category Keywords Description
Base tabs Base tabs container
Variant tabs-box, tabs-lifted Tab style variants
Size tabs-xs, tabs-sm, tabs-md, tabs-lg Tab scale
State tab-active, tab-disabled Tab states

For further details, check the daisyUI Tabs Documentation Full reference for CSS classes.

Example

Tabs({
  items: [
    { label: "Tab 1", content: "Content 1", active: true },
    { label: "Tab 2", content: "Content 2" }
  ],
  class: "tabs-box"
});

Live Examples

Basic Tabs

Live Demo

const BasicDemo = () => {
  const activeTab = $('tab1');
  
  return Tabs({
    items: [
      {
        label: 'Tab 1',
        active: () => activeTab() === 'tab1',
        onclick: () => activeTab('tab1'),
        content: Div({ class: 'p-4' }, 'Content for Tab 1')
      },
      {
        label: 'Tab 2',
        active: () => activeTab() === 'tab2',
        onclick: () => activeTab('tab2'),
        content: Div({ class: 'p-4' }, 'Content for Tab 2')
      },
      {
        label: 'Tab 3',
        active: () => activeTab() === 'tab3',
        onclick: () => activeTab('tab3'),
        content: Div({ class: 'p-4' }, 'Content for Tab 3')
      }
    ]
  });
};
Mount(BasicDemo, '#demo-basic');

With Icons

Live Demo

const IconsDemo = () => {
  const activeTab = $('home');
  
  return Tabs({
    items: [
      {
        label: Span({ class: 'flex items-center gap-2' }, ['🏠', 'Home']),
        active: () => activeTab() === 'home',
        onclick: () => activeTab('home'),
        content: Div({ class: 'p-4' }, 'Welcome to the Home tab!')
      },
      {
        label: Span({ class: 'flex items-center gap-2' }, ['⭐', 'Favorites']),
        active: () => activeTab() === 'favorites',
        onclick: () => activeTab('favorites'),
        content: Div({ class: 'p-4' }, 'Your favorite items appear here.')
      },
      {
        label: Span({ class: 'flex items-center gap-2' }, ['⚙️', 'Settings']),
        active: () => activeTab() === 'settings',
        onclick: () => activeTab('settings'),
        content: Div({ class: 'p-4' }, 'Configure your preferences.')
      }
    ]
  });
};
Mount(IconsDemo, '#demo-icons');

With Tooltips

Live Demo

const TooltipsDemo = () => {
  const activeTab = $('profile');
  
  return Tabs({
    items: [
      {
        label: 'Profile',
        tip: 'View your profile information',
        active: () => activeTab() === 'profile',
        onclick: () => activeTab('profile'),
        content: Div({ class: 'p-4' }, 'Profile information here.')
      },
      {
        label: 'Settings',
        tip: 'Adjust your preferences',
        active: () => activeTab() === 'settings',
        onclick: () => activeTab('settings'),
        content: Div({ class: 'p-4' }, 'Settings configuration.')
      },
      {
        label: 'Notifications',
        tip: 'Manage notifications',
        active: () => activeTab() === 'notifications',
        onclick: () => activeTab('notifications'),
        content: Div({ class: 'p-4' }, 'Notification settings.')
      }
    ]
  });
};
Mount(TooltipsDemo, '#demo-tooltips');

Disabled Tab

Live Demo

const DisabledDemo = () => {
  const activeTab = $('basic');
  
  return Tabs({
    items: [
      {
        label: 'Basic',
        active: () => activeTab() === 'basic',
        onclick: () => activeTab('basic'),
        content: Div({ class: 'p-4' }, 'Basic features available.')
      },
      {
        label: 'Premium',
        disabled: true,
        tip: 'Upgrade to access',
        content: Div({ class: 'p-4' }, 'Premium content (locked)')
      },
      {
        label: 'Pro',
        disabled: true,
        tip: 'Coming soon',
        content: Div({ class: 'p-4' }, 'Pro features (coming soon)')
      }
    ]
  });
};
Mount(DisabledDemo, '#demo-disabled');

Reactive Content

Live Demo

const ReactiveDemo = () => {
  const activeTab = $('counter');
  const count = $(0);
  
  return Tabs({
    items: [
      {
        label: 'Counter',
        active: () => activeTab() === 'counter',
        onclick: () => activeTab('counter'),
        content: Div({ class: 'p-4 text-center' }, [
          Div({ class: 'text-4xl font-bold mb-4' }, () => count()),
          Button({ 
            class: 'btn btn-primary',
            onclick: () => count(count() + 1)
          }, 'Increment')
        ])
      },
      {
        label: 'Timer',
        active: () => activeTab() === 'timer',
        onclick: () => activeTab('timer'),
        content: Div({ class: 'p-4' }, () => `Current time: ${new Date().toLocaleTimeString()}`)
      },
      {
        label: 'Status',
        active: () => activeTab() === 'status',
        onclick: () => activeTab('status'),
        content: Div({ class: 'p-4' }, () => `Counter value: ${count()}, Last updated: ${new Date().toLocaleTimeString()}`)
      }
    ]
  });
};
Mount(ReactiveDemo, '#demo-reactive');

Form Tabs

Live Demo

const FormTabs = () => {
  const activeTab = $('personal');
  const formData = $({
    name: '',
    email: '',
    address: '',
    city: '',
    notifications: true,
    newsletter: false
  });
  
  const updateField = (field, value) => {
    formData({ ...formData(), [field]: value });
  };
  
  const handleSubmit = () => {
    Toast('Form submitted!', 'alert-success', 2000);
    console.log(formData());
  };
  
  return Div({ class: 'flex flex-col gap-4' }, [
    Tabs({
      items: [
        {
          label: 'Personal Info',
          active: () => activeTab() === 'personal',
          onclick: () => activeTab('personal'),
          content: Div({ class: 'p-4 space-y-4' }, [
            Input({
              label: 'Name',
              value: () => formData().name,
              placeholder: 'Enter your name',
              oninput: (e) => updateField('name', e.target.value)
            }),
            Input({
              label: 'Email',
              type: 'email',
              value: () => formData().email,
              placeholder: 'email@example.com',
              oninput: (e) => updateField('email', e.target.value)
            })
          ])
        },
        {
          label: 'Address',
          active: () => activeTab() === 'address',
          onclick: () => activeTab('address'),
          content: Div({ class: 'p-4 space-y-4' }, [
            Input({
              label: 'Address',
              value: () => formData().address,
              placeholder: 'Street address',
              oninput: (e) => updateField('address', e.target.value)
            }),
            Input({
              label: 'City',
              value: () => formData().city,
              placeholder: 'City',
              oninput: (e) => updateField('city', e.target.value)
            })
          ])
        },
        {
          label: 'Preferences',
          active: () => activeTab() === 'prefs',
          onclick: () => activeTab('prefs'),
          content: Div({ class: 'p-4 space-y-4' }, [
            Checkbox({
              label: 'Email notifications',
              value: () => formData().notifications,
              onclick: () => updateField('notifications', !formData().notifications)
            }),
            Checkbox({
              label: 'Newsletter subscription',
              value: () => formData().newsletter,
              onclick: () => updateField('newsletter', !formData().newsletter)
            })
          ])
        }
      ]
    }),
    Div({ class: 'flex justify-end mt-4' }, [
      Button({ 
        class: 'btn btn-primary',
        onclick: handleSubmit
      }, 'Submit')
    ])
  ]);
};
Mount(FormTabs, '#demo-form');

All Variants

Live Demo

const VariantsDemo = () => {
  const active1 = $('tab1');
  const active2 = $('tab1');
  const active3 = $('tab1');
  
  const createItems = (active) => [
    {
      label: 'Tab 1',
      active: () => active() === 'tab1',
      onclick: () => active('tab1'),
      content: Div({ class: 'p-4' }, 'Content 1')
    },
    {
      label: 'Tab 2',
      active: () => active() === 'tab2',
      onclick: () => active('tab2'),
      content: Div({ class: 'p-4' }, 'Content 2')
    },
    {
      label: 'Tab 3',
      active: () => active() === 'tab3',
      onclick: () => active('tab3'),
      content: Div({ class: 'p-4' }, 'Content 3')
    }
  ];
  
  return Div({ class: 'flex flex-col gap-6' }, [
    Div({ class: 'text-sm font-bold' }, 'Default Tabs'),
    Tabs({ items: createItems(active1) }),
    
    Div({ class: 'text-sm font-bold mt-4' }, 'Boxed Tabs'),
    Tabs({ items: createItems(active2), class: 'tabs-box' }),
    
    Div({ class: 'text-sm font-bold mt-4' }, 'Lifted Tabs'),
    Tabs({ items: createItems(active3), class: 'tabs-lifted' })
  ]);
};
Mount(VariantsDemo, '#demo-variants');