import type { Meta, StoryObj } from 'storybook-solidjs-vite'; import { fn } from 'storybook/test'; import { ResizablePanelGroup, ResizablePanel, ResizableHandle, Resizable } from './resizable'; import { componentDescription } from '../stories/docs/element-controls'; const meta = { title: 'Solid (Advanced)/Primitives/Resizable', component: ResizablePanelGroup, tags: ['autodocs'], parameters: { layout: 'padded', docs: { controls: { exclude: ['use:eventListener'] }, description: componentDescription([ 'A **resizable split layout**: `ResizablePanelGroup` lays out `ResizablePanel` children along an axis, divided by a draggable `ResizableHandle`.', '**When to use:** to let users adjust the relative size of two or more regions — e.g. a collapsible sidebar next to the main chat, or a chat pane next to an inspector.', '**How to use:** wrap panels in `ResizablePanelGroup` and set `orientation` (`horizontal` row / `vertical` column). Give panels a `defaultSize` (percent) and optional `minSize`/`maxSize`; min/max are read from `data-min-size`/`data-max-size` attributes at drag time. Place a `ResizableHandle` (add `withHandle` for a visible grip) between panels. The group needs a sized container (height/width).', '**Placement:** app shells — sidebar + conversation, conversation + context/inspector panels, or stacked editor/preview regions.', ]), }, }, argTypes: { orientation: { control: 'select', options: ['horizontal', 'vertical'], description: 'Axis the panels are laid out along.', table: { defaultValue: { summary: 'horizontal' } }, }, }, args: { orientation: 'horizontal', }, render: (args) => (
Sidebar
Content
), } satisfies Meta; export default meta; type Story = StoryObj; const IMPORT = `import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@kitn.ai/chat';`; const src = (code: string) => ({ parameters: { docs: { source: { code: `${IMPORT}\n\n${code}`, language: 'tsx' } } }, }); /** Interactive playground — flip the orientation, then drag the handle. */ export const Playground: Story = { ...src(` Sidebar Content `), }; export const Horizontal: Story = { args: { orientation: 'horizontal' }, ...src(` Sidebar Content `), }; /** Stacked top/bottom split (showcase). */ export const Vertical: Story = { render: () => (
Top
Bottom
), ...src(` Top Bottom `), }; /** Three panels with two handles (showcase). */ export const ThreePanels: Story = { name: 'Three Panels', render: () => (
Left
Center
Right
), ...src(` Left Center Right `), }; /** Handle without a visible grip; reports drag deltas via `onPanelResize` (showcase). */ export const NoHandle: Story = { name: 'Without Handle', render: () => (
Panel A
Panel B
), ...src(` Panel A console.log(delta)} /> Panel B `), }; /** * The `Resizable` convenience: pass `ResizablePanel` children and it * auto-inserts a handle between each visible pair. A `locked` panel makes its * neighbouring handle a static (non-draggable) divider; a `hidden` panel drops * its divider entirely. */ export const ConvenienceGroup: Story = { name: 'Resizable (convenience)', render: () => (
console.log('sizes', sizes)}>
Locked sidebar (240px)
Chat
Preview
), ...src(` console.log(sizes)}> Locked sidebar Chat Preview `), }; /** * Min/max + keyboard: focus the handle (Tab) and use ←/→ to nudge, Home/End to * jump to the panel's min/max. Sizes accept px or %. */ export const MinMaxKeyboard: Story = { name: 'Min/Max + Keyboard', render: () => (
min 120px · max 50%
Content (min 160px)
), ...src(` Sidebar Content `), };