import type { Meta, StoryObj } from '@storybook/vue3' import { ref } from 'vue' import FdsButtonPrimary from '../Buttons/FdsButtonPrimary/FdsButtonPrimary.vue' import FdsButtonSecondary from '../Buttons/FdsButtonSecondary/FdsButtonSecondary.vue' import FdsModal from './FdsModal.vue' const meta: Meta = { title: 'FDS/FdsModal', component: FdsModal, tags: ['autodocs'], argTypes: { heading: { control: { type: 'text' } }, size: { control: { type: 'select' }, options: ['sm', 'md', 'lg', 'xl'] }, alignTop: { control: { type: 'boolean' } }, alignLeftFooter: { control: { type: 'boolean' } }, stickyFooter: { control: { type: 'boolean' } }, strict: { control: { type: 'boolean' } }, lockScroll: { control: { type: 'boolean' } }, info: { control: { type: 'select' }, options: ['valid', 'invalid', 'warning'] }, open: { control: { type: 'boolean' } }, }, args: { heading: 'Modal heading', size: 'md', alignTop: false, alignLeftFooter: false, stickyFooter: false, strict: false, lockScroll: false, info: undefined, open: false, }, } export default meta type Story = StoryObj // Helper to create modal story setup with reactive open state const createModalStory = (args: any) => { const open = ref(args.open ?? false) const handleClose = () => { open.value = false } const handleOpen = () => { open.value = true } return { args, open, handleClose, handleOpen } } const modalTransform = (storyContext: { args?: { heading?: string size?: string open?: boolean lockScroll?: boolean info?: string strict?: boolean } }) => { const args = storyContext?.args || {} const attrs = [] if (args.heading) attrs.push(`heading="${args.heading}"`) if (args.size && args.size !== 'md') attrs.push(`size="${args.size}"`) if (args.open) attrs.push(':open="true"') if (args.lockScroll) attrs.push('lockScroll') if (args.info) attrs.push(`info="${args.info}"`) if (args.strict) attrs.push('strict') const attrsStr = attrs.length ? ` ${attrs.join(' ')}` : '' return `

This is the modal content. You can add any content here.

` } export const Default: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary, FdsButtonSecondary }, setup: () => createModalStory(args), template: `

This is the modal content. You can add any content here.

`, }), parameters: { docs: { source: { transform: modalTransform, }, }, }, } export const WithFooter: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary, FdsButtonSecondary }, setup: () => createModalStory(args), template: `

This is the modal content with a footer.

`, }), } export const Strict: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary, FdsButtonSecondary }, setup: () => createModalStory(args), template: `

This is a strict modal. You cannot close it by clicking the backdrop or pressing Escape.

`, }), args: { strict: true, }, } export const ValidInfo: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary }, setup: () => createModalStory(args), template: `

Your changes have been saved successfully.

`, }), args: { info: 'valid', }, } export const WarningInfo: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary, FdsButtonSecondary }, setup: () => createModalStory(args), template: `

Are you sure you want to continue? This action cannot be undone.

`, }), args: { info: 'warning', }, } export const LargeSize: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary }, setup: () => createModalStory(args), template: `

This is a large modal with more space for content.

You can add multiple paragraphs and other content here.

`, }), args: { size: 'xl', }, } export const LongContentWithStickyFooter: Story = { render: (args: Story['args']) => ({ components: { FdsModal, FdsButtonPrimary, FdsButtonSecondary }, setup: () => createModalStory(args), template: `

This is the first paragraph of content.

This is the second paragraph with more information about the topic at hand.

Here is a third paragraph that provides additional context and details.

And yet another paragraph to demonstrate the scrolling behavior.

This paragraph continues to show how the content flows in the modal.

More content is added here to make the modal longer and more scrollable.

Another paragraph to show the sticky footer functionality in action.

This content should be long enough to require scrolling.

The footer should remain sticky at the bottom as you scroll through the content.

This is the final paragraph to complete the long content example.

`, }), args: { heading: 'Long Content Modal', size: 'md', stickyFooter: true, lockScroll: true, }, }