import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters" import type { Meta, StoryObj } from "@storybook/react" import { Button } from "../Button/Button.tsx" import { ContainerBoard, StoryCell, StoryGrid, StorySection, } from "../board.storyHelpers.tsx" import { Card } from "../Card/Card.tsx" import { AlertIcon, InboxIcon, PlayIcon, SearchIcon, } from "../icons.storyHelpers.tsx" import { EmptyState } from "./EmptyState.tsx" const meta = { title: "Components/Feedback/EmptyState", component: EmptyState, parameters: { layout: "padded" }, args: { headingLevel: 2, size: "md" }, } satisfies Meta export default meta type Story = StoryObj /** * The heading is the handle. Eleven copies of "Nothing here" in a * `
` are indistinguishable to an agent; a named heading is not. */ export const Playground: Story = { parameters: playgroundParameters, args: { description: "Insert a disc and rip-deck will pick it up automatically.", heading: "No discs queued", }, } /** * There is no `variant` prop, on purpose: "empty" and "failed" * differ in wording and in whether there is a retry button, both of * which are props already. A `variant="error"` that only changes a * colour invites callers to encode the meaning in the colour alone, * which is the one thing a colour cannot carry. */ export const AllVariants: Story = { args: { heading: "No discs queued" }, render: () => ( } /> } /> Clear filters } description="No titles match “blade” with the 4K filter on." heading="No matches" icon={} /> Reconnect } description="The websocket closed after 3 retries. Nothing has been lost — the tower keeps ripping." heading="Lost the connection" icon={} /> ), } export const AllStates: Story = { args: { heading: "No discs queued" }, render: () => ( Scan drives} description="Insert a disc and rip-deck will pick it up automatically." heading="No discs queued" icon={} /> ), } /** * The container-query story that actually changes something: the * `md` size gains air past `--cq-md`, so the same component is * appropriately tight in a 15rem sidebar and appropriately generous * filling a dashboard — decided by the panel, not by the window. */ export const Responsive: Story = { args: { heading: "No discs queued" }, render: () => ( } /> ), } /** * Two things an agent needs from an empty state: read *why* it is * empty, and reach the way out. So the heading carries the reason * and Tab lands on the action. */ export const Interactive: Story = { args: { heading: "No discs queued" }, render: (emptyStateProps) => ( Scan drives} description="Insert a disc and rip-deck will pick it up automatically." headingLevel={3} /> ), } /** * Nested inside an already-deep section, an empty state is not an * `

`. The level goes to `6` so the outline never has to skip — * the cap was a guess about document depth the consumer knows * better than the component does. */ export const DeeplyNested: Story = { args: { description: "Insert a disc and rip-deck will pick it up automatically.", heading: "No discs queued", headingLevel: 6, }, }