import type { Meta, StoryObj } from '@storybook/vue3-vite' import { ref } from 'vue' import CpDynamicDialog from '@/components/CpDynamicDialog.vue' const STORY_TRIGGER_LAYOUT = 'display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 60vh; width: 100%;' const createStoryRender = (content: string) => (args: Record) => ({ components: { CpDynamicDialog }, setup() { const isVisible = ref(false) return { args, isVisible } }, template: `
Open Dynamic Dialog

Resize me

${content} `, }) const meta = { title: 'Organisms/CpDynamicDialog', component: CpDynamicDialog, parameters: { layout: 'fullscreen', docs: { description: { component: 'Responsive dialog wrapper that renders `CpDialog` inside `CpTransitionDialog` on desktop and `CpBottomSheet` on mobile viewports. Visibility is controlled with `v-model:is-visible`.', }, }, }, argTypes: { breakpoint: { control: 'number', description: 'Viewport width (px) below which the dialog switches to a bottom sheet. Defaults to Breakpoints.MOBILE (552)', }, maxWidth: { control: 'number', description: 'Maximum width of the desktop dialog (px)', }, isClosableOnClickOutside: { control: 'boolean', description: 'Allow closing the desktop dialog by clicking the backdrop', }, preventClose: { control: 'boolean', description: 'Prevent dismiss actions from emitting close', }, title: { control: 'text', description: 'Title passed as a prop (desktop) or rendered in the bottom sheet header (mobile)', }, subtitle: { control: 'text', description: 'Subtitle passed as a prop on desktop', }, onClose: { action: 'close' }, }, } satisfies Meta export default meta type Story = StoryObj /** * Desktop viewport — opens a centered dialog with title, subtitle, body and footer slots. */ export const Default: Story = { args: { maxWidth: 600, title: 'Dialog title', subtitle: 'Dialog subtitle', }, render: createStoryRender('

This is the default slot content. You can put any content here.

'), } /** * Desktop viewport — the same API renders a dialog instead of a bottom sheet. */ export const Desktop: Story = { args: { maxWidth: 600, title: 'Dialog title', subtitle: 'Dialog subtitle', }, globals: { viewport: { value: 'tablet', isRotated: false }, }, render: createStoryRender('

On desktop viewports, the dynamic dialog renders as a centered dialog.

'), } /** * Mobile viewport — the same API renders a bottom sheet instead of a dialog. */ export const Mobile: Story = { args: { title: 'Bottom sheet title', }, globals: { viewport: { value: 'mobile1', isRotated: false }, }, render: createStoryRender('

On mobile viewports, the dynamic dialog becomes a bottom sheet.

'), } /** * Prevent the dialog or bottom sheet from being closed by the user. */ export const PreventClose: Story = { args: { maxWidth: 600, title: 'Dialog title', subtitle: 'Dialog subtitle', preventClose: true, }, render: createStoryRender('

Dismiss actions are blocked — use the button below to close programmatically.

'), }