import type { Meta, StoryObj } from '@storybook/react-vite'
import { IconDotsVertical } from '@tabler/icons-react'
import { IconButton } from './IconButton'
import { Panel } from './Panel'
/**
* A panel of a page: a header, a body that scrolls whenever it is taller than
* the panel, and a row fixed under it when there is one. The body's words are
* stand-ins.
*/
const meta = {
title: 'Layout/Panel',
component: Panel,
parameters: { layout: 'fullscreen' },
args: { title: 'Details', children: null, bodyClassName: 'flex flex-col gap-3 px-4 pt-3 pb-4' },
argTypes: { children: { control: false }, actions: { control: false }, footer: { control: false } },
// A side column of the frame: 380px wide and a fixed height, where a panel sits beside a page.
decorators: [
(Story) => (
{Story()}
),
],
} satisfies Meta
export default meta
type Story = StoryObj
const paragraph = (n: number) => (
Paragraph {n}. What this item is for, who it is for, and what it leaves for later, written out in full the way a real description is.
)
const paragraphs = (count: number) => Array.from({ length: count }, (_, i) => paragraph(i + 1))
const menu =
/** A short body: it fits, so there is no bar. */
export const Default: Story = {
args: { actions: menu },
render: (args) => {paragraphs(2)},
}
/** A title that opens something: the chevron after it, as ContainerHeader draws it. */
export const WithChevron: Story = {
args: { chevron: true },
render: (args) => {paragraphs(2)},
}
/** A body taller than the panel: it scrolls, and the bar shows at rest because there is more below. */
export const ALongBody: Story = {
args: { actions: menu },
render: (args) => {paragraphs(14)},
}
/** A row fixed under the body, such as a reply box: the body scrolls above it, and it stays put. */
export const WithAFooter: Story = {
render: (args) => (
Footer
}
>
{paragraphs(12)}
),
}
/** Two panels in one column: the first capped at three fifths, each scrolls in its own room. */
export const TwoInAColumn: Story = {
render: (args) => (
<>
{paragraphs(10)}
{paragraphs(6)}
>
),
}
/** In a plain box with a height, not a flex column: it still fills it, and the body still scrolls. */
export const InAPlainBox: Story = {
decorators: [
(Story) => (
{Story()}
),
],
parameters: { layout: 'fullscreen' },
render: (args) => {paragraphs(14)},
}
function Broken(): never {
throw new Error('The body could not draw itself')
}
/** A crash inside it stays inside it: the title stays, and the message takes the body's room. */
export const WhenTheBodyBreaks: Story = {
render: (args) => (
),
}