import type { Args, Meta, StoryObj } from '@storybook/vue3-vite' import CpSelectableButton from '@/components/CpSelectableButton.vue' import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles' const selectableAppearances = ['primary', 'secondary', 'tertiary', 'quaternary', 'inverse'] as const const selectableSizes = ['3xs', '2xs', 'xs', 'sm', 'md'] as const const meta = { title: 'Atoms/CpSelectableButton', component: CpSelectableButton, argTypes: { appearance: { control: 'select', options: selectableAppearances, description: 'Visual style of the selectable button', }, isSelected: { control: 'boolean', description: 'Whether the button is selected', }, isExpanded: { control: 'boolean', description: 'Whether the button is expanded', }, size: { control: 'select', options: selectableSizes, description: 'Size of the button', }, disabled: { control: 'boolean', description: 'Whether the button is disabled', }, label: { control: 'text', description: 'Text displayed inside the button', }, }, } satisfies Meta export default meta type Story = StoryObj const defaultRender = (args: Args) => ({ components: { CpSelectableButton }, setup() { return { args } }, template: `
`, }) /** * Default selectable button. Use the controls to experiment with each prop * in isolation. */ export const Default: Story = { args: { appearance: 'primary', size: 'md', disabled: false, label: 'Label', isSelected: false, isExpanded: false, }, render: defaultRender, } /* -------------------------------------------------------------------------- */ /* Appearances */ /* -------------------------------------------------------------------------- */ /** * Every appearance rendered side by side. The `inverse` appearance is meant * for dark backgrounds. */ export const Appearances: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpSelectableButton }, setup() { return { selectableAppearances, docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
{{ appearance }}
`, }), } /* -------------------------------------------------------------------------- */ /* Sizes */ /* -------------------------------------------------------------------------- */ /** * All sizes rendered side by side, from `3xs` to `md`. */ export const Sizes: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpSelectableButton }, setup() { return { selectableSizes, docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
{{ size }}
`, }), } /* -------------------------------------------------------------------------- */ /* States */ /* -------------------------------------------------------------------------- */ /** * The three selection states: default, `isExpanded` and `isSelected`. */ export const States: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpSelectableButton }, setup() { return { docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
Default
Expanded
Selected
Disabled
`, }), } /* -------------------------------------------------------------------------- */ /* Icons */ /* -------------------------------------------------------------------------- */ /** * Slot `#leading-icon` and `#trailing-icon` accept any icon component. */ export const WithIcons: Story = { args: { appearance: 'primary', size: 'md', }, render: (args: Args) => ({ components: { CpSelectableButton }, setup() { return { args } }, template: ` Custom label `, }), } /** * Stretch the button to fill its container by setting `width: 100%`. */ export const FullWidth: Story = { args: { appearance: 'secondary', size: 'md', label: 'Label', isSelected: true, }, render: (args: Args) => ({ components: { CpSelectableButton }, setup() { return { args } }, template: `
`, }), } /* -------------------------------------------------------------------------- */ /* Icon only */ /* -------------------------------------------------------------------------- */ export const IconOnly: Story = { args: { appearance: 'primary', size: 'md', }, render: (args: Args) => ({ components: { CpSelectableButton }, setup() { return { args } }, template: ` `, }), } /* -------------------------------------------------------------------------- */ /* Matrix */ /* -------------------------------------------------------------------------- */ /** * Full appearance × size matrix, each cell showing default / expanded / * selected side by side. Useful for visual regression. */ export const Matrix: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpSelectableButton }, setup() { return { selectableAppearances, selectableSizes } }, template: `

{{ appearance }}

{{ size }}

`, }), }