import { computed, h } from 'vue' import OsButton from './OsButton.vue' import type { Meta, StoryObj } from '@storybook/vue3-vite' /** * Inline SVG icons for demo purposes (from Heroicons). * In real usage, the webapp passes its own BaseIcon component. */ const CheckIcon = () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor' }, [ h('path', { 'fill-rule': 'evenodd', d: 'M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z', 'clip-rule': 'evenodd', }), ]) const CloseIcon = () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor' }, [ h('path', { d: 'M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z', }), ]) const PlusIcon = () => h('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor' }, [ h('path', { d: 'M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z', }), ]) const meta: Meta = { title: 'Components/OsButton', component: OsButton, tags: ['autodocs'], } export default meta type Story = StoryObj /** Custom args for Playground (icon selector + label are not real component props) */ interface PlaygroundArgs { as: string variant: string appearance: string size: string fullWidth: boolean circle: boolean disabled: boolean loading: boolean icon: string label: string } const iconMap: Record ReturnType) | null> = { none: null, check: CheckIcon, close: CloseIcon, plus: PlusIcon, } export const Playground: StoryObj = { argTypes: { as: { control: 'select', options: ['button', 'a'], }, variant: { control: 'select', options: ['default', 'primary', 'secondary', 'danger', 'warning', 'success', 'info'], }, appearance: { control: 'select', options: ['filled', 'outline', 'ghost'], }, size: { control: 'select', options: ['sm', 'md', 'lg', 'xl'], }, fullWidth: { control: 'boolean', }, circle: { control: 'boolean', }, disabled: { control: 'boolean', }, loading: { control: 'boolean', }, icon: { control: 'select', options: Object.keys(iconMap), }, label: { control: 'text', }, }, args: { as: 'button', variant: 'primary', appearance: 'filled', size: 'md', fullWidth: false, circle: false, disabled: false, loading: false, icon: 'none', label: 'Button', }, render: (args) => ({ components: { OsButton }, setup() { const buttonProps = computed(() => { const { icon: _icon, label: _label, ...rest } = args return rest }) const IconComponent = computed(() => iconMap[args.icon] ?? null) const label = computed(() => args.label) return { buttonProps, IconComponent, label } }, template: ` {{ label }} `, }), } export const AllVariants: Story = { render: () => ({ components: { OsButton }, template: `
Default Primary Secondary Danger Warning Success Info
`, }), } export const AllSizes: Story = { render: () => ({ components: { OsButton }, template: `

Small (26px)

Default Primary Secondary Danger Warning Success Info

Medium (36px)

Default Primary Secondary Danger Warning Success Info

Large

Default Primary Secondary Danger Warning Success Info

Extra Large

Default Primary Secondary Danger Warning Success Info
`, }), } export const AllAppearances: Story = { render: () => ({ components: { OsButton }, template: `

Filled (default)

Default Primary Secondary Danger Warning Success Info

Outline

Default Primary Secondary Danger Warning Success Info

Ghost

Default Primary Secondary Danger Warning Success Info
`, }), } export const AppearanceFilled: Story = { name: 'Appearance: Filled', render: () => ({ components: { OsButton }, template: `
Default Primary Secondary Danger Warning Success Info
`, }), } export const AppearanceOutline: Story = { name: 'Appearance: Outline', render: () => ({ components: { OsButton }, template: `
Default Primary Secondary Danger Warning Success Info
`, }), } export const AppearanceGhost: Story = { name: 'Appearance: Ghost', render: () => ({ components: { OsButton }, template: `
Default Primary Secondary Danger Warning Success Info
`, }), } export const Disabled: Story = { render: () => ({ components: { OsButton }, template: `

Filled

Default Primary Secondary Danger Warning Success Info

Outline

Default Primary Secondary Danger Warning Success Info

Ghost

Default Primary Secondary Danger Warning Success Info
`, }), } export const FullWidth: Story = { render: () => ({ components: { OsButton }, template: `
Default Primary Secondary Danger Warning Success Info
`, }), } export const Icon: Story = { render: () => ({ components: { OsButton, CheckIcon, PlusIcon, CloseIcon }, template: `
Save Confirm Add Delete Create
`, }), } export const IconOnly: Story = { render: () => ({ components: { OsButton, CloseIcon, PlusIcon, CheckIcon }, template: `
`, }), } export const IconSizes: Story = { render: () => ({ components: { OsButton, CheckIcon }, template: `
Small Medium Large Extra Large
`, }), } export const IconAppearances: Story = { render: () => ({ components: { OsButton, CheckIcon }, template: `

Filled

Primary Danger Success

Outline

Primary Danger Success

Ghost

Primary Danger Success
`, }), } export const Circle: Story = { render: () => ({ components: { OsButton, PlusIcon, CloseIcon, CheckIcon }, template: `
`, }), } export const CircleSizes: Story = { render: () => ({ components: { OsButton, PlusIcon }, template: `

Small (26px)

Medium (36px)

Large (48px)

Extra Large (56px)

`, }), } export const CircleAppearances: Story = { render: () => ({ components: { OsButton, PlusIcon, CloseIcon, CheckIcon }, template: `

Filled

Outline

Ghost

`, }), } export const Polymorphic: Story = { render: () => ({ components: { OsButton, CheckIcon, PlusIcon }, template: `

as="a" (anchor element)

Primary Link Outline Link Ghost Link Danger Link

as="a" with icon

Save

as="button" (default)

Button (default) Button (explicit)
`, }), } export const Loading: Story = { render: () => ({ components: { OsButton, CheckIcon }, template: `

Filled

Default Primary Danger Success

Outline

Default Primary Danger Success

With Icon

Save Delete
`, }), }