import type { Args, Meta, StoryObj } from '@storybook/vue3-vite' import CpBadge from '@/components/CpBadge.vue' import { docCellStyle, docLabelStyle, docRowWrapStyle } from '@/stories/documentationStyles' const badgeColors = [ 'neutral', 'accent', 'error', 'warning', 'success', 'blue', 'pink', 'magenta', 'yellow', 'white', ] as const const badgeSizes = ['2xs', 'xs', 'sm', 'md', 'lg'] as const const badgeVariants = ['outline', 'soft', 'solid'] as const const badgeIcons = ['', 'check', 'arrow-right', 'arrow-left', 'arrow-up', 'arrow-down', 'plus'] as const const meta = { title: 'Atoms/CpBadge', component: CpBadge, argTypes: { color: { control: 'select', options: badgeColors, description: 'The color variant of the badge', }, size: { control: 'select', options: badgeSizes, description: 'The size of the badge', }, variant: { control: 'select', options: badgeVariants, description: 'The variant of the badge', }, disabled: { control: 'boolean', description: 'Whether the badge is disabled', }, isSquare: { control: 'boolean', description: 'Whether the badge has a square border', }, leadingIcon: { control: 'select', options: badgeIcons, description: 'Type of leading icon (if any)', }, trailingIcon: { control: 'select', options: badgeIcons, description: 'Type of trailing icon (if any)', }, label: { control: 'text', description: 'The label text', }, isClearable: { control: 'boolean', description: 'Whether the badge is clearable', }, }, } satisfies Meta export default meta type Story = StoryObj const defaultTemplate = '' const defaultRender = (args: Args) => ({ components: { CpBadge }, setup() { return { args } }, template: defaultTemplate, }) /** * Default badge: neutral color, outline variant, medium size. Use the controls * to experiment with each prop in isolation. */ export const Default: Story = { args: { color: 'neutral', size: 'md', variant: 'outline', isSquare: false, disabled: false, leadingIcon: '', trailingIcon: '', label: 'Badge', isClearable: false, }, render: defaultRender, } /* -------------------------------------------------------------------------- */ /* Sizes */ /* -------------------------------------------------------------------------- */ /** * All sizes rendered side by side, from `2xs` to `md`. */ export const Sizes: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpBadge }, setup() { return { badgeSizes, docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
{{ size }}
`, }), } /* -------------------------------------------------------------------------- */ /* Colors */ /* -------------------------------------------------------------------------- */ /** * Every semantic and utility color available for the badge. */ export const Colors: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpBadge }, setup() { return { badgeColors, docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
{{ color }}
`, }), } /* -------------------------------------------------------------------------- */ /* Variants */ /* -------------------------------------------------------------------------- */ /** * Variant × color matrix, showing how each variant renders across every color. */ export const Variants: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpBadge }, setup() { return { badgeColors, badgeVariants } }, template: `
{{ color }}
{{ variant }}
`, }), } /* -------------------------------------------------------------------------- */ /* Disabled */ /* -------------------------------------------------------------------------- */ /** * Enabled and disabled states compared side by side. */ export const Disabled: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpBadge }, setup() { return { docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
Enabled
Disabled
`, }), } /* -------------------------------------------------------------------------- */ /* Square vs rounded */ /* -------------------------------------------------------------------------- */ /** * Fully rounded (default) compared with the square variant. */ export const Squared: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpBadge }, setup() { return { docCellStyle, docLabelStyle, docRowWrapStyle } }, template: `
Rounded
Square
`, }), } /* -------------------------------------------------------------------------- */ /* Icons */ /* -------------------------------------------------------------------------- */ /** * Badge with a leading icon. */ export const WithLeadingIcon: Story = { args: { ...Default.args, color: 'accent', leadingIcon: 'check' }, render: defaultRender, } /** * Badge with a trailing icon. */ export const WithTrailingIcon: Story = { args: { ...Default.args, color: 'accent', trailingIcon: 'arrow-right' }, render: defaultRender, } /** * Badge with both a leading and a trailing icon. */ export const WithBothIcons: Story = { args: { ...Default.args, color: 'accent', leadingIcon: 'check', trailingIcon: 'arrow-right' }, render: defaultRender, } /** * Badge without a label, acting as an icon-only indicator. */ export const WithoutLabel: Story = { args: { ...Default.args, color: 'accent', leadingIcon: 'check', label: '' }, render: defaultRender, } /* -------------------------------------------------------------------------- */ /* Clearable */ /* -------------------------------------------------------------------------- */ /** * The clearable affordance shows up when `isClearable` is `true` and an * `onClear` listener is provided. The clear button follows the badge disabled * state. */ export const Clearable: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpBadge }, setup() { const onClear = () => console.log('clear') return { docCellStyle, docLabelStyle, docRowWrapStyle, onClear } }, template: `
Not clearable
Clearable
Clearable (disabled)
`, }), } /* -------------------------------------------------------------------------- */ /* Slots */ /* -------------------------------------------------------------------------- */ /** * Customize the icons and the label through `#leading-icon`, `#trailing-icon` * and the default slot. */ export const WithSlot: Story = { render: (args: Args) => ({ components: { CpBadge }, setup() { return { args } }, template: `
Custom div inside default slot
`, }), }