import type { Args, Meta, StoryObj } from '@storybook/vue3-vite' import CpAlert from '@/components/CpAlert.vue' import { docCellStyle, docLabelStyle, docRowColumnStyle } from '@/stories/documentationStyles' const alertColors = ['neutral', 'accent', 'success', 'warning', 'error'] as const const alertTypes = ['expanded', 'inline'] as const const alertStackStyle = `${docCellStyle} width: 100%; min-width: 420px;` const meta = { title: 'Molecules/CpAlert', component: CpAlert, argTypes: { color: { control: 'select', options: alertColors, description: 'The color variant of the alert', }, type: { control: 'select', options: alertTypes, description: 'The layout type of the alert', }, title: { control: 'text', description: 'The title of the alert', }, content: { control: 'text', description: 'The text content of the alert (expanded type only)', }, icon: { control: 'select', options: ['', 'info', 'check', 'alert-triangle', 'x-octagon', 'bell', 'star'], description: 'Custom icon override. Defaults to the color-specific icon when empty.', }, isClosable: { control: 'boolean', description: 'Whether the alert shows a close button', }, primaryActionLabel: { control: 'text', description: 'Label for the primary action button', }, secondaryActionLabel: { control: 'text', description: 'Label for the secondary action button', }, }, } satisfies Meta export default meta type Story = StoryObj const defaultTemplate = '' const defaultRender = (args: Args) => ({ components: { CpAlert }, setup() { return { args } }, template: defaultTemplate, }) /** * Default alert with a neutral color, expanded layout, a title and a content * message. Use the controls to experiment with each prop in isolation. */ export const Default: Story = { args: { color: 'neutral', type: 'expanded', title: 'Alert title', content: 'This is an informational alert message.', isClosable: false, icon: undefined, primaryActionLabel: undefined, secondaryActionLabel: undefined, }, render: defaultRender, } /* -------------------------------------------------------------------------- */ /* Colors */ /* -------------------------------------------------------------------------- */ /** * Every semantic color available for the alert, stacked vertically. */ export const Colors: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpAlert }, setup() { return { alertColors, docRowColumnStyle, alertStackStyle, docLabelStyle } }, template: `
{{ color }}
`, }), } /* -------------------------------------------------------------------------- */ /* Layout types */ /* -------------------------------------------------------------------------- */ /** * `expanded` stacks the title, content and actions vertically. `inline` keeps * them on a single line and hides the content area — best for short messages. */ export const Types: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpAlert }, setup() { return { alertTypes, docRowColumnStyle, alertStackStyle, docLabelStyle } }, template: `
{{ type }}
`, }), } /* -------------------------------------------------------------------------- */ /* Content combinations */ /* -------------------------------------------------------------------------- */ /** * The three supported content combinations: title only, content only, and * both title and content. */ export const ContentLayouts: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpAlert }, setup() { return { docRowColumnStyle, alertStackStyle, docLabelStyle } }, template: `
Title only
Content only
Title and content
`, }), } /* -------------------------------------------------------------------------- */ /* Dismiss & actions */ /* -------------------------------------------------------------------------- */ /** * All dismiss and action affordances shown side by side: closable, primary * action, secondary action, and both actions together. */ export const Actions: Story = { parameters: { controls: { disable: true } }, render: () => ({ components: { CpAlert }, setup() { return { docRowColumnStyle, alertStackStyle, docLabelStyle } }, template: `
Closable
Primary action
Secondary action
Both actions
`, }), } /* -------------------------------------------------------------------------- */ /* Icon */ /* -------------------------------------------------------------------------- */ /** * Override the default color-specific icon with any icon name. */ export const CustomIcon: Story = { args: { ...Default.args, color: 'accent', title: 'Custom icon', content: 'Any icon from the design system can replace the default one.', icon: 'bell', }, render: defaultRender, } /* -------------------------------------------------------------------------- */ /* Slots */ /* -------------------------------------------------------------------------- */ /** * Customize every part of the alert using slots: `icon`, `title`, default * (content), `primary-action` and `secondary-action`. */ export const WithSlots: Story = { args: { color: 'accent', type: 'expanded', isClosable: true, }, render: (args: Args) => ({ components: { CpAlert }, setup() { return { args } }, template: ` Custom default slot with a link and inline code. `, }), }