import { playgroundParameters } from "@charcuterie/storybook-config/story-parameters" import type { Meta, StoryObj } from "@storybook/react" import { useState } from "react" import { Button } from "../Button/Button.tsx" import { ContainerBoard, StoryCell, StoryGrid, StorySection, } from "../board.storyHelpers.tsx" import { Card } from "../Card/Card.tsx" import type { Step } from "./Stepper.tsx" import { Stepper } from "./Stepper.tsx" const RIP: Step[] = [ { description: "3 of 3 discs read", key: "rip", label: "Rip", status: "done", }, { description: "2 of 5 titles tagged", key: "tag", label: "Tag", status: "current", }, { description: "Opens when Tag is finished", key: "file", label: "File", status: "upcoming", }, ] const meta = { title: "Components/Data/Stepper", component: Stepper, parameters: { layout: "padded" }, args: { headingLevel: 3, label: "Ingest sequence", orientation: "vertical", steps: RIP, }, } satisfies Meta export default meta type Story = StoryObj /** * The marker is the ordinal and never a tick — this library ships * no icons and no symbol glyphs, and a `✓` the font lacks renders * as an empty box in the one position where an empty box reads as * an error. */ export const Playground: Story = { parameters: playgroundParameters, } export const AllVariants: Story = { render: (stepperProps) => ( {/* Blocked is not a worse `upcoming`. Its turn HAS come and something is in the way — a thing to go and fix rather than a thing to wait for. */} Read the disc into an ISO ), key: "a", label: "Rip", status: "done", }, { content: Match each title, key: "b", label: "Tag", status: "current", }, ]} /> ), } export const AllStates: Story = { render: (stepperProps) => ( ), } /** * `horizontal` is a REQUEST. Below `cq-md` it falls back to the * column, because four steps side by side in a narrow container * squash into `2. / De- / dupe` — measured, in the app this * component came out of. */ export const Responsive: Story = { args: { orientation: "horizontal" }, render: (stepperProps) => ( ), } /** Short labels can opt out of the collapse when the sequence is a * compact status ladder inside a card. */ export const CompactCard: Story = { args: { appearance: "compact", isResponsive: false, orientation: "horizontal", steps: [ { key: "ordered", label: "Ordered", status: "done" }, { key: "shipped", label: "Shipped", status: "done" }, { key: "out", label: "Out today", status: "current" }, { key: "delivered", label: "Delivered", status: "upcoming", }, ], }, render: (stepperProps) => (
), } /** * The whole keyboard path, which is the point of the headings: a * stepper is a document outline, not a widget. There is nothing to * focus and nothing to arrow between — advancing is the app's * operation, and the component only reports where the sequence got * to. */ export const Interactive: Story = { render: (stepperProps) => { const [reached, setReached] = useState(1) return (
({ ...step, description: undefined, status: index < reached ? ("done" as const) : index === reached ? ("current" as const) : ("upcoming" as const), }))} />
) }, } /** A wizard permits returning to completed stages without skipping answers. */ export const WizardNavigation: Story = { render: (stepperProps) => { const [currentKey, setCurrentKey] = useState("tag") return ( ({ ...step, status: step.key === currentKey ? "current" : step.key === "rip" ? "done" : "upcoming", }))} /> ) }, }