import type { Args, Meta, StoryObj } from '@storybook/vue3-vite' import { action } from 'storybook/actions' import { ref } from 'vue' import CpTabs from '@/components/CpTabs.vue' const meta = { title: 'Molecules/CpTabs', component: CpTabs, argTypes: { defaultActiveIndex: { control: 'number', description: 'The index of the initially active tab', }, isLoading: { control: 'boolean', description: 'Whether the tabs are in loading state', }, tabs: { control: 'object', description: 'Array of tab objects with title, optional icon, and optional count', }, size: { control: 'select', options: ['xs', 'sm', 'md', 'lg'], description: 'The size of the tabs', }, variant: { control: 'select', options: ['brand', 'underline'], description: 'The variant of the tabs', }, }, } satisfies Meta export default meta type Story = StoryObj const defaultRender = (args: Args) => ({ components: { CpTabs }, setup() { return { args } }, template: `
`, }) /** * Default tabs rendered from an array of `{ title }` objects. Use the * controls to experiment with each prop in isolation. */ export const Default: Story = { args: { defaultActiveIndex: 0, isLoading: false, tabs: [{ title: 'Tab 1' }, { title: 'Tab 2' }, { title: 'Tab 3' }, { title: 'Tab 4' }], onOnTabClick: action('tab-clicked'), }, render: defaultRender, } /** * Tabs augmented with leading icons through the `icon` property on each * tab object. */ export const WithIcons: Story = { args: { ...Default.args, tabs: [ { title: 'Home', leadingIcon: 'circle', trailingIcon: 'circle' }, { title: 'Settings', leadingIcon: 'circle', trailingIcon: 'circle' }, { title: 'User', leadingIcon: 'circle', trailingIcon: 'circle' }, ], }, render: defaultRender, } /** * Tabs that display a count badge on the right — typically used for * notifications or list sizes. */ export const WithCounts: Story = { args: { ...Default.args, tabs: [ { title: 'Inbox', count: 5 }, { title: 'Sent', count: 12 }, { title: 'Drafts', count: 3 }, ], }, render: defaultRender, } /** * Icons and counts combined on the same tab. */ export const WithIconsAndCounts: Story = { args: { ...Default.args, tabs: [ { title: 'Notifications', leadingIcon: 'circle', trailingIcon: 'circle', count: 8 }, { title: 'Messages', leadingIcon: 'circle', trailingIcon: 'circle', count: 3 }, { title: 'Tasks', leadingIcon: 'circle', trailingIcon: 'circle', count: 15 }, ], }, render: defaultRender, } /** * Tabs nested inside a dialog — verifies the integration with overlay * surfaces and the focus ring behaviour. */ export const InDialog: Story = { args: { ...Default.args, defaultActiveIndex: 1, tabs: [ { title: 'Notifications', leadingIcon: 'circle', trailingIcon: 'circle', count: 8 }, { title: 'Messages', leadingIcon: 'circle', trailingIcon: 'circle', count: 3 }, { title: 'Tasks', leadingIcon: 'circle', trailingIcon: 'circle', count: 15 }, ], }, render: (args) => ({ components: { CpTabs }, setup() { const isVisible = ref(false) return { args, isVisible } }, template: `
Open dialog
`, }), }