import type { Meta, StoryObj } from '@storybook/nextjs-vite' import { useState } from 'react' import { fn } from 'storybook/test' import { BracketCurlyIcon, ChartDonutIcon, IdCardIcon, MonitorIcon, Settings02Icon, } from '../components/icons-v2-generated' import { AppLayout, AppLayoutDrawer, AppLayoutDrawerBody, AppLayoutDrawerContent, AppLayoutDrawerDescription, AppLayoutDrawerHeader, AppLayoutDrawerTitle, } from '../components/navigation' import { Button } from '../components/ui/button' import { NavigationSidebarConfig } from '../types/navigation' const navigationItems: NavigationSidebarConfig['items'] = [ { id: 'dashboard', label: 'Dashboard', icon: , path: '/dashboard', isActive: true }, { id: 'customers', label: 'Customers', icon: , path: '/customers' }, { id: 'devices', label: 'Devices', icon: , path: '/devices' }, { id: 'scripts', label: 'Scripts', icon: , path: '/scripts' }, { id: 'settings', label: 'Settings', icon: , path: '/settings', section: 'secondary' }, ] const meta = { title: 'Navigation/AppLayoutDrawer', component: AppLayoutDrawer, parameters: { layout: 'fullscreen', docs: { description: { component: ` A Drawer variant that renders **inside** AppLayout's main content area instead of as a viewport-level overlay. The sidebar and header remain visible and interactive while it is open. ## When to use - Side panels (chat, details, filters) that should not cover the global chrome (header, sidebar). - Anything that conceptually belongs to the current page rather than the whole app. For an overlay that covers the entire viewport (e.g. notifications, auth modals), use the standard \`Drawer\` from \`components/ui\` instead. `, }, }, }, tags: ['autodocs'], } satisfies Meta export default meta type Story = StoryObj function DashboardChildren({ onOpenDrawer }: { onOpenDrawer: () => void }) { return (

Devices Overview

8,250 Devices in Total

{[ { label: 'Active Devices', value: '6,930' }, { label: 'Active Tickets', value: '136' }, { label: 'Resolved Tickets', value: '825' }, ].map((stat) => (

{stat.label}

{stat.value}

))}
) } /** * Right-side in-layout drawer, passed via the `drawer` slot prop. * The drawer is persistent — clicks on the overlay/header/sidebar * do NOT close it; use the X button or Escape. */ export const Right: Story = { render: function Render() { const [open, setOpen] = useState(false) return ( Current Chats Persistent: clicks on AppLayout chrome don't close this.

Chat content goes here.

} > setOpen(true)} />
) }, } /** * Resizable variant — drag the inside edge to resize. Clamped to the * AppLayout main-area dimensions (not the viewport). */ export const ResizableRight: Story = { render: function Render() { const [open, setOpen] = useState(true) return ( Resizable Drawer

Drag the grip on the left edge to resize. The panel can extend all the way to the container edge (minus a 16px symmetric gap).

} > setOpen(true)} />
) }, } /** * Left-side variant. */ export const Left: Story = { render: function Render() { const [open, setOpen] = useState(false) return ( Filters

Left-side drawer content.

} > setOpen(true)} />
) }, }