import type { ReactNode } from "react"; import type { BoardItem } from "./BoardCard.tsx"; export type BoardLane = { /** * Lane-level controls, beside the count — Docket's *"Accept all"* * on the review lane. `Button`s, usually. */ actions?: ReactNode; /** * Shown instead of the rows when the lane is empty. Defaults to a * real `EmptyState`, because *"Real empty states"* was a stated * requirement and an empty lane is the one a person sees most. */ emptyState?: ReactNode; /** * Where the lane's own heading navigates — a route showing this * lane and nothing else. * * **A link inside the heading, never a heading replaced by a * link.** The `

` keeps its level, its id and its place in the * document outline, so the lane stays a named `group` and the * screen-reader outline is unchanged; the anchor sits inside it. * Routed through `RouterLinkProvider` like every other `href` in * this library, so an app with a client-side router navigates * without a full page load and one without it still gets a real * ``. * * Absent means the heading is plain text, which is what every * existing consumer gets. */ href?: string; /** * The **true** size of the lane, when `items` is a truncated page * of it. This is what the count badge shows, and the difference * between it and `items.length` is what the "+ n more" line says. * * Defaults to `items.length`, so a consumer that does not truncate * says nothing about truncation. */ itemCount?: number; items: readonly BoardItem[]; key: string; /** * The lane's name, and it stays a **string** rather than widening * to a `ReactNode`. * * It is not only a heading: the same value names the lane in the * move menu on every card, in the Narrow View's segmented control, * in the "+ n more in Todo" line, and in the sentence the live * region reads out after a move. A `ReactNode` is not something * any of those four can put in a string, so widening this would * trade one linkable heading for four places that can no longer * say which lane they mean. `href` buys the link without that. */ label: string; /** * What "+ n more in this lane" does. With no handler the line is * still shown — the honest count matters more than the * affordance — but it is text rather than a button. */ onShowMore?: () => void; }; export type BoardLaneListProps = { /** * Pixels from the top of the list box, or `null` for no * indicator. Absolute rather than a real element between two * cards: an indicator that takes up space moves the cards it is * measured against, and the resulting feedback loop is why so many * hand-rolled boards flicker. */ dropIndicatorOffset: number | null; /** * The lane heading's level. The caller's, because only the caller * knows what the board sits under — an `

` directly below the * page's `

` is an axe `heading-order` failure, and a board is * as likely to sit under a section heading as under the page * title. */ headingLevel: 2 | 3 | 4 | 5; isVisibleWhenNarrow: boolean; lane: BoardLane; laneLayout: "columns" | "rows"; moveIcon?: ReactNode; moveTargets: readonly { key: string; label: string; }[]; onMoveToLane?: (itemKey: string, toLaneKey: string) => void; onStartDrag?: (pointerEvent: { clientX: number; clientY: number; currentTarget: EventTarget & Element; pointerId: number; }, origin: { fromIndex: number; itemKey: string; }) => void; registerListElement: (element: HTMLElement | null) => void; }; /** * One lane: a named heading, an honest count, its rows, and what it * says when there are none. * * ### The lane is the container, and that is the whole design * * `@container` sits on a wrapper inside this section, so everything * below it — the panel, its rows — is sized by **the lane**. Three * lanes in a 1600px window are ~500px each; one lane in the Narrow * View is ~360px; the same lane in a docked sidebar is 280px. All * three happen on the same monitor, and no media query can tell * them apart. * * The wrapper is a wrapper because a container query matches * **descendants only**. Declaring `@container` on the panel itself * would compile, generate real CSS, and silently never fire — so * the panel could never take its own frame off at `cq-lg`, which is * the one thing the widest layout asks for. * * This `
` is outside all of that: it carries the * hidden/shown classes, and those resolve against the **board's** * container, one level up. * * ### Long lanes truncate; they do not scroll * * *"Long lanes truncate with an honest `+ n more` rather than * scrolling forever."* So the lane never grows a scrollbar and never * virtualises. `itemCount` is the real total and `items` is whatever * the consumer chose to render — which keeps paging, sorting and any * windowing on the side that owns the data, and keeps this component * from pretending to know how many rows are worth painting. */ export declare const BoardLaneList: ({ dropIndicatorOffset, headingLevel, isVisibleWhenNarrow, lane, laneLayout, moveIcon, moveTargets, onMoveToLane, onStartDrag, registerListElement, }: BoardLaneListProps) => ReactNode; //# sourceMappingURL=BoardLaneList.d.ts.map