import { useEffect, type ReactNode } from 'react'; import { HStack } from '@astryxdesign/core/HStack'; import { Text } from '@astryxdesign/core/Text'; import { VStack } from '@astryxdesign/core/VStack'; import { X } from 'lucide-react'; /** * The side drawer, matched to `OrderDetailDrawer`. * * That one is the site's drawer and every measurement here is taken from it: * the flex-end wrapper at z-index 70, a full-bleed scrim BUTTON rather than a * div (so it is reachable and announces itself), a 460px panel capped at 92vw, * `-24px 0 56px -12px` of shadow, a STICKY header on a hairline, and a 30px * rounded close button on `--color-surface-sunken`. * * Extracted rather than copied a third time. The drawers I added had drifted — * different scrim opacity, different shadow, a bare `X`, a header that scrolled * away — which is exactly how two screens stop looking like one product. */ export interface DrawerProps { title: string; /** One line under the title. */ subtitle?: string; /** Sits beside the title — a status chip, usually. */ titleAside?: ReactNode; /** * Panel width in px. 460 is the site default; only widen for content that * genuinely cannot fold, such as a grid of product cards. */ width?: number; /** Renders the body unpadded, for panels that manage their own layout. */ isBare?: boolean; onClose: () => void; children: ReactNode; } export function Drawer({ title, subtitle, titleAside, width = 460, isBare, onClose, children, }: DrawerProps) { useEffect(() => { const onKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') onClose(); }; window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [onClose]); return (