import type { ReactNode } from "react";
import type { BoardLane } from "./BoardLaneList.tsx";
export type BoardMove = {
/** Where the card was, in `fromLane.items`. */
fromIndex: number;
fromLaneKey: string;
itemKey: string;
/**
* Where it goes, **already corrected for its own removal** — so a
* consumer's handler is `splice(fromIndex, 1)` then
* `splice(toIndex, 0, item)` with no arithmetic of its own. A
* within-lane move quoted against the un-spliced list is one too
* high for every position below the origin, and that off-by-one is
* the single most common bug in a hand-rolled board.
*/
toIndex: number;
toLaneKey: string;
};
export type BoardProps = {
className?: string;
/**
* What level the lane headings are. The caller's, because only the
* caller knows what the board sits under: a board directly below a
* page `
` wants `2`, and one inside an already-deep section
* wants `4`. Getting it wrong is an axe `heading-order` failure and
* a broken screen-reader outline.
*/
headingLevel?: 2 | 3 | 4 | 5;
/** The board's accessible name. Required — it is a landmark. */
label: string;
/**
* How the lanes themselves are arranged.
*
* `columns` is the workflow shape: lanes sit side by side above
* `cq-lg`, and the Narrow View selects one lane. `rows` is the
* project-pool shape: every lane is one horizontal band, its cards
* form a responsive grid inside that band, and every lane stays on
* screen at every width.
*/
laneLayout?: "columns" | "rows";
lanes: readonly BoardLane[];
/**
* What the move handle shows **while the lanes are side by side**.
* Below `cq-lg` the handle says "Move" whatever this is, because
* there is nowhere to drag to — see `BoardCard`.
*
* The library ships no icons and no symbol glyphs in a default —
* they render as nothing where the font lacks them, which
* includes this sandbox's chromium, the kiosk image and the
* ePaper build — so the default is a word and an app that owns a
* glyph set passes one. On a dense board it is worth ~35px a row.
*/
moveIcon?: ReactNode;
/**
* Which lane is on screen below `cq-lg`. **Initial only** — the
* segmented control owns it from then on, matching every other
* uncontrolled control in this library.
*/
narrowLaneKey?: string;
/**
* The one thing that makes a board a board. **Absent means
* read-only**: no handles, no menus, no drag, and nothing
* announcing itself. A board with no `onMove` is a legitimate
* thing — a dashboard, an ePaper render — and it should not be
* carrying affordances that do nothing.
*/
onMove?: (move: BoardMove) => void;
};
/**
* Lanes of cards, sized by their **container**, moved by keyboard or
* by pointer.
*
* ### The container rule, which is the whole point
*
* There is no media query in this component, and adding one would be
* a defect rather than a shortcut. Two facts make window width
* useless here and they compound:
*
* - **A lane in a three-up board is narrow on any monitor.** Three
* lanes across 1600px is ~500px each, which is a phone's worth of
* room, on a 4K display, in a maximised window.
* - **The owner browses zoomed in.** A 1500px window at 175% zoom
* is ~860 effective CSS pixels, so the number a media query reads
* is not the number of pixels anything actually has.
*
* So there are **two nested containers**, and they answer two
* different questions:
*
* - The board's own box decides *how workflow lanes are shown* —
* side by side at `cq-lg` and wider, one lane plus a segmented
* control below it. A project-pool board with
* `laneLayout="rows"` keeps every lane on screen and grids the
* cards inside each horizontal band instead.
* - Each lane's list decides *what shape a card is* — two lines,
* one line, or its own card. See `BoardCard`.
*
* Both are `@container`, and neither is queried by the element that
* declares it, because a container query matches descendants only.
*
* ### There is no horizontal scroll, at any width
*
* *"No horizontal scroll, ever. The board becomes a segmented
* control, never a pan surface."* A board that pans sideways hides
* lanes behind a gesture with no affordance, and on a trackpad it
* fights the browser's own back-navigation. So the narrow workflow
* layout shows one lane at a time and names the others in a
* `radiogroup` that says how many cards each holds. A row layout
* wraps its cards inside each lane and also never pans.
*
* ### Moving a card is a first-class operation, and it is not a drag
*
* The move is a **`Menu` on every card**, listing the other lanes.
* That is the primary path, not an accessibility fallback: it is the
* only one that works from the keyboard, the only one a screen
* reader can drive, and the only one available in the Narrow View
* where the other lanes are not on screen to drop onto. Pointer
* dragging is layered on the same handle and commits through the
* same callback.
*
* **No drag-and-drop dependency is taken.** The reasoning — licence,
* provenance, bundle cost, and what a general DnD library would
* actually be buying for one card going into one lane — is in
* [the decision](../../../docs/decisions/2026-08-19-the-board-owns-the-move-and-takes-no-drag-and-drop-dependency.md).
*
* ### What this component deliberately does not do
*
* Lanes, counts, truncation, empty states and the move; **not**
* data, not virtualisation, and not the cross-lane "needs attention"
* summary. A board is a view of a list the consumer owns, the lane
* truncates by construction so there is nothing to virtualise, and a
* panel that reaches across every lane is not a lane — it is an
* `Alert` above the board, which is how the docs page composes it.
*/
export declare const Board: ({ className, headingLevel, label, laneLayout, lanes, moveIcon, narrowLaneKey, onMove, }: BoardProps) => ReactNode;
//# sourceMappingURL=Board.d.ts.map