import type { Args, Meta, StoryObj } from '@storybook/vue3-vite' import type { MenuItem } from 'primevue/menuitem' import { computed } from 'vue' import CpAccordion from '@/components/CpAccordion.vue' import CpAccordionGroup from '@/components/CpAccordionGroup.vue' const sampleContentStyle = 'padding: 16px; font-size: 13px; color: #374151; background: repeating-linear-gradient(45deg, #fff9c4, #fff9c4 4px, #fffde7 4px, #fffde7 8px);' const wrapperStyle = 'box-sizing: border-box; width: 100%; max-width: 1200px; margin: 0 auto; padding: 24px; width: 500px;' type CpAccordionGroupStoryArgs = { itemActions: MenuItem[] itemDefaultOpenState: boolean itemHideActionTrigger: boolean itemIconPosition: 'leading' | 'trailing' itemQuickOptionsLimit: number itemTitle: string variant: 'default' | 'minimal' | 'primary' } const defaultItemActions: MenuItem[] = [ { icon: 'copy', label: 'Duplicate', command: () => {}, }, { icon: 'trash-2', label: 'Delete', command: () => {}, isCritical: true, }, ] const meta = { title: 'Molecules/CpAccordionGroup', component: CpAccordionGroup, argTypes: { variant: { control: 'select', options: ['minimal', 'default', 'primary'], description: 'Visual style variant for the accordion group container', table: { category: 'CpAccordionGroup' }, }, itemTitle: { control: 'text', description: 'Title prefix for each item (suffix 1, 2, 3)', table: { category: 'CpAccordion (items)' }, }, itemDefaultOpenState: { control: 'boolean', description: 'Initial open state for each accordion', table: { category: 'CpAccordion (items)' }, }, itemIconPosition: { control: 'select', options: ['leading', 'trailing'], description: 'Chevron position on each accordion', table: { category: 'CpAccordion (items)' }, }, itemQuickOptionsLimit: { control: 'number', description: 'Quick options limit (leading + actions)', table: { category: 'CpAccordion (items)' }, }, itemHideActionTrigger: { control: 'boolean', description: 'Hide action trigger when leading + actions', table: { category: 'CpAccordion (items)' }, }, itemActions: { control: 'object', description: 'MenuItem[] for each item (leading only). JSON edit drops `command`; use Reset to restore.', table: { category: 'CpAccordion (items)' }, }, }, } as Meta export default meta type Story = StoryObj const defaultRender = (args: Args) => ({ components: { CpAccordion, CpAccordionGroup }, setup() { const accordionBind = computed(() => { if (args.itemIconPosition === 'trailing') { return { defaultOpenState: args.itemDefaultOpenState, iconPosition: args.itemIconPosition, quickOptionsLimit: args.itemQuickOptionsLimit, } } return { actions: args.itemActions, defaultOpenState: args.itemDefaultOpenState, hideActionTrigger: args.itemHideActionTrigger, iconPosition: args.itemIconPosition, quickOptionsLimit: args.itemQuickOptionsLimit, } }) return { accordionBind, args, sampleContentStyle, wrapperStyle } }, template: `
`, }) /** * Default accordion group rendered with the `default` variant. */ export const Default: Story = { args: { variant: 'default', itemTitle: 'Accordion', itemDefaultOpenState: false, itemIconPosition: 'leading', itemQuickOptionsLimit: 2, itemHideActionTrigger: false, itemActions: defaultItemActions, }, render: defaultRender, } /* -------------------------------------------------------------------------- */ /* Variants */ /* -------------------------------------------------------------------------- */ /** * Minimal variant: no container border, no separators between items. Use when * the grouping is implicit in the surrounding layout. */ export const Minimal: Story = { args: { ...Default.args, variant: 'minimal', }, render: defaultRender, } /** * Default variant: thin separator lines between items, no outer border. * This is the most common variant. */ export const DefaultVariant: Story = { args: { ...Default.args, variant: 'default', }, render: defaultRender, } /** * Primary variant: the group is wrapped in a rounded card with an outer border * and separators between items. */ export const Primary: Story = { args: { ...Default.args, variant: 'primary', }, render: defaultRender, }