import { Button } from '@/components/ui/button';
import { Modal } from '@/components/ui/modal/modal';
import type { Meta, StoryObj } from '@storybook/react-webpack5';
import { useState } from 'react';
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: 'Example/Modal',
component: Modal,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: 'centered',
docs: {
description: {
component: `
## Modal Component
The Modal component is a dialog overlay that can be used to present content in a modal window. It provides a flexible way to display information, forms, or any other content on top of the main page content.
### Import Path
\`\`\`typescript
import { Modal } from '@/components/ui/modal/modal';
\`\`\`
### Basic Usage
\`\`\`tsx
import { Modal } from '@/components/ui/modal/modal';
import { useState } from 'react';
function MyComponent() {
const [open, setOpen] = useState(false);
return (
<>
Modal content goes here
>
);
}
\`\`\`
### Features
- Multiple sizes: small, default, and large
- Customizable header with title and close button
- Customizable footer with default OK/Cancel buttons
- Support for controlled and uncontrolled usage
- Loading state for confirmation button
- Keyboard navigation support (ESC to close)
- Click outside to close functionality
- Full screen mode option
- Built with Radix UI primitives for accessibility
- Customizable styling with className props
`,
},
},
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
tags: ['autodocs'],
// More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: {
open: {
description: 'Whether the modal is open or not',
control: { type: 'boolean' },
},
onOpenChange: {
description:
'Callback function that is called when the open state changes',
control: false,
},
title: {
description: 'Title of the modal',
control: { type: 'text' },
},
titleClassName: {
description: 'Additional CSS classes for the title container',
control: { type: 'text' },
},
children: {
description: 'Content to be displayed inside the modal',
control: false,
},
footer: {
description:
'Custom footer content. If not provided, default buttons will be shown',
control: { type: 'text' },
},
footerClassName: {
description: 'Additional CSS classes for the footer container',
control: { type: 'text' },
},
showfooter: {
description: 'Whether to show the footer or not',
control: { type: 'boolean' },
},
className: {
description: 'Additional CSS classes for the modal container',
control: { type: 'text' },
},
size: {
description: 'Size of the modal',
control: { type: 'select' },
options: ['small', 'default', 'large'],
},
closable: {
description: 'Whether to show the close button in the header',
control: { type: 'boolean' },
},
closeIcon: {
description: 'Custom close icon',
control: false,
},
maskClosable: {
description: 'Whether to close the modal when clicking on the mask',
control: { type: 'boolean' },
},
destroyOnClose: {
description: 'Whether to unmount the modal content when closed',
control: { type: 'boolean' },
},
full: {
description: 'Whether the modal should take the full screen',
control: { type: 'boolean' },
},
confirmLoading: {
description: 'Whether the confirm button should show a loading state',
control: { type: 'boolean' },
},
cancelText: {
description: 'Text for the cancel button',
control: { type: 'text' },
},
okText: {
description: 'Text for the OK button',
control: { type: 'text' },
},
onOk: {
description: 'Callback function for the OK button',
control: false,
},
onCancel: {
description: 'Callback function for the Cancel button',
control: false,
},
},
} satisfies Meta;
export default meta;
type Story = StoryObj;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Default: Story = {
args: {
open: false,
title: 'Default Modal',
children: (
Modal Content
This is the default modal with standard size and functionality.
);
},
parameters: {
docs: {
description: {
story: `
### Large Modal
Shows a large-sized modal, suitable for complex content like forms or data tables.
\`\`\`tsx
const [open, setOpen] = useState(false);
Large Modal
This is a large modal with more content. It can accommodate forms, tables, or other complex content.
}
>
{args.children}
);
},
parameters: {
docs: {
description: {
story: `
### Custom Footer
Shows a modal with a custom footer. You can provide your own footer content instead of using the default OK/Cancel buttons.
\`\`\`tsx
const [open, setOpen] = useState(false);
}
>
Modal with Custom Footer
This modal has a custom footer with multiple buttons.
);
},
parameters: {
docs: {
description: {
story: `
### Without Footer
Shows a modal without a footer. Useful when you want to include action buttons within the content area or don't need any footer actions.
\`\`\`tsx
const [open, setOpen] = useState(false);
Modal without Footer
This modal has no footer. The content area extends to the bottom of the modal.
);
},
parameters: {
docs: {
description: {
story: `
### Full Screen Modal
Shows a full screen modal that takes up the entire viewport. Useful for complex workflows or when maximum space is needed.
\`\`\`tsx
const [open, setOpen] = useState(false);
Full Screen Modal
This modal takes up the full screen. Useful for complex workflows or when you need maximum space.
Content area that can expand to fill available space
);
},
parameters: {
docs: {
description: {
story: `
### Loading State
Shows a modal with the confirm button in a loading state. This is useful when performing async operations after clicking OK.
\`\`\`tsx
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
const handleOk = () => {
setLoading(true);
setTimeout(() => {
setLoading(false);
setOpen(false);
}, 2000);
};
Modal with Loading State
The OK button shows a loading spinner when confirmLoading is true.
\`\`\`
`,
},
},
},
};
// Interactive example showing how to use the modal in a real component
export const Interactive: Story = {
args: {
open: false,
title: 'Interactive Modal',
children: (
Interactive Modal
Click OK to see the loading state, or click Cancel/Close to close the
modal.
);
},
parameters: {
docs: {
description: {
story: `
### Interactive Example
This is a fully interactive example showing how to use the modal in a real component with state management.
\`\`\`tsx
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Modal } from '@/components/ui/modal/modal';
function InteractiveModal() {
const [open, setOpen] = useState(false);
return (