import { useState } from "react"; import { ExitIcon } from "~/assets/icons/ExitIcon"; import { Button } from "~/components/primitives/Buttons"; import { Header2 } from "~/components/primitives/Headers"; import { Paragraph } from "~/components/primitives/Paragraph"; import * as Property from "~/components/primitives/PropertyTable"; import { RESIZABLE_PANEL_ANIMATION, ResizableHandle, ResizablePanel, ResizablePanelGroup, collapsibleHandleClassName, useFrozenValue, } from "~/components/primitives/Resizable"; import { Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableRow, } from "~/components/primitives/Table"; type DemoItem = { id: string; name: string; status: "completed" | "running" | "failed" | "queued"; duration: string; task: string; }; const demoItems: DemoItem[] = [ { id: "run_a1b2c3d4", name: "Process invoices", status: "completed", duration: "2.3s", task: "invoice/process", }, { id: "run_e5f6g7h8", name: "Send welcome email", status: "running", duration: "0.8s", task: "email/welcome", }, { id: "run_i9j0k1l2", name: "Generate report", status: "failed", duration: "12.1s", task: "report/generate", }, { id: "run_m3n4o5p6", name: "Sync inventory", status: "completed", duration: "5.7s", task: "inventory/sync", }, { id: "run_q7r8s9t0", name: "Resize images", status: "queued", duration: "—", task: "image/resize", }, { id: "run_u1v2w3x4", name: "Update search index", status: "completed", duration: "1.1s", task: "search/index", }, { id: "run_y5z6a7b8", name: "Calculate analytics", status: "running", duration: "8.4s", task: "analytics/calc", }, { id: "run_c9d0e1f2", name: "Deploy preview", status: "completed", duration: "34.2s", task: "deploy/preview", }, { id: "run_g3h4i5j6", name: "Run migrations", status: "failed", duration: "0.3s", task: "db/migrate", }, { id: "run_k7l8m9n0", name: "Notify Slack", status: "completed", duration: "0.5s", task: "notify/slack", }, ]; const statusColors: Record = { completed: "text-success", running: "text-blue-500", failed: "text-error", queued: "text-text-dimmed", }; function DetailPanel({ item, onClose }: { item: DemoItem; onClose: () => void }) { return (
{item.name}
Run ID {item.id} Task {item.task} Status {item.status.charAt(0).toUpperCase() + item.status.slice(1)} Duration {item.duration}
This is a demo detail panel showing the animated slide-in/out behavior using react-window-splitter's collapseAnimation. Click a different row to change the detail, or press Esc / click the close button to dismiss.
); } export default function Story() { const [selectedItem, setSelectedItem] = useState(null); const show = !!selectedItem; const frozenItem = useFrozenValue(selectedItem); const displayItem = selectedItem ?? frozenItem; return (
Runs
Run ID Name Task Status Duration {demoItems.map((item) => ( setSelectedItem(item)} isTabbableCell> {item.id} setSelectedItem(item)}>{item.name} setSelectedItem(item)}>{item.task} setSelectedItem(item)}> {item.status.charAt(0).toUpperCase() + item.status.slice(1)} setSelectedItem(item)} alignment="right"> {item.duration} ))}
{ if (isCollapsed) setSelectedItem(null); }} collapsedSize="0px" collapseAnimation={RESIZABLE_PANEL_ANIMATION} >
{displayItem && ( setSelectedItem(null)} /> )}
); }