import "./lane_board.css"; import type * as React from "react"; import { type ReactNode } from "react"; import { useRender } from "@base-ui/react/use-render"; import { type ColorName } from "./color_tokens"; import { type PeriodStepsLabels } from "./period_steps"; import type { StateMatrixPeriod } from "./state_matrix"; import { type StyleProps } from "./style_props"; /** * LANES DOWN THE SIDE, WORK ALONG A SHARED AXIS, AND WHAT IS STILL OPEN — a despatch board, a bay * plan, a chair's day, a machine's month. A lane is one resource carrying everything on it, so empty * stretches — what is left to sell or book — are drawn and named, and where the host adds work an * opening is the press that adds it there. Each lane may carry its load against its ceiling, since time * and capacity run out independently; overflow is named on the lane, never a block. A block that may change * lane carries a menu of the lanes it may move to, each read by what it would carry with the block on it — * never a drag, which along a time axis would also move it in time. Positions are shares * of the axis the caller computed (`lane_board_layout.ts`), so it holds at any width; below * `compactBelow` each lane is a list of its work and openings in clock order instead. */ export interface LaneBoardProps extends StyleProps { lanes: readonly LaneBoardLane[]; /** Each at its own share of the axis. */ ticks: readonly LaneBoardTick[]; /** Default {@link LANE_BOARD_HEAD}. */ laneWidth?: number; /** The window the axis shows, stepped back and forth above the board as `StateMatrix` steps its own. */ period?: StateMatrixPeriod; /** Per-instance words; the rest resolve from `LoticsLocale.stateMatrix`. */ labels?: Partial; /** Width below which each lane is a list rather than a track. Default {@link LANE_BOARD_COMPACT}. */ compactBelow?: number; testID?: string; ref?: React.Ref; render?: useRender.RenderProp; } /** The period's words. */ export type LaneBoardLabels = PeriodStepsLabels; export interface LaneBoardTick { key: string; label: string; /** Over the label, as a weekday stands over a day's number. */ caption?: string; /** Today: its label ringed as the calendar rings it. */ current?: boolean; /** A position read less (a weekend): the quiet ink. */ quiet?: boolean; /** 0–1. */ share: number; } export interface LaneBoardLane { key: string; label: string; /** A picture or a face at the name's lead. */ leading?: ReactNode; /** One reading per stated ceiling, at most two. */ loads: readonly LaneBoardLoad[]; blocks: readonly LaneBoardBlock[]; /** In clock order. */ openings: readonly LaneBoardOpening[]; } /** The caller's meter and the overflow past it. */ export interface LaneBoardLoad { key: string; /** Drawn by whichever cell the measure takes. */ reading: ReactNode; /** In words; nothing while inside. */ overflow?: string; } export interface LaneBoardBlock { key: string; /** Inside the bar where it fits. */ label: string; /** A second, quieter line under the label where the bar has room for it. */ detail?: string; /** Its time in the reader's words (09:00–10:30), which the compact list leads its line with. */ when?: string; /** * What it is, whose lane and when: position is its content, so a label alone leaves the reading * in the geometry. */ name: string; /** As shares (0–1) of the axis. Drawn at least a mark's room wide (up to a name's readable run), work standing * where it is drawn stacks in its lane's stripes rather than hides. */ left: number; width: number; /** The kit's neutral where none is stated. */ color?: ColorName; /** * Hatched as well as toned: on a state-coloured board, colour alone would make cancelled and late * one ink. The hatch survives monochrome print. */ late?: boolean; /** The one the record surface stands on. */ selected?: boolean; onOpen?: () => void; /** The lanes it may move to, in a menu on the block; absent, it stays in its lane here. */ move?: LaneBoardMove; } /** * A block's way to another lane: each lane offered by its name and what it would carry with the block on it, so the * reader sees where it fits before it moves. */ export interface LaneBoardMove { /** The menu's accessible name, the block's in it ("Move Order 12"). */ name: string; /** In the order offered. */ to: readonly LaneBoardMoveTo[]; /** Why it cannot move now: each lane is still read, none taken. */ refused?: string; onMove: (lane: string) => void; } export interface LaneBoardMoveTo { /** A lane's key: its face and name are that lane's. */ lane: string; /** What the lane would carry with the block on it, at most two. */ loads: readonly LaneBoardLoad[]; /** The lane and those loads in words, announced for its row. */ name: string; } /** Drawn where it is, and named. */ export interface LaneBoardOpening { key: string; /** As shares (0–1) of the axis. */ left: number; width: number; /** Start and duration in the reader's words. */ label: string; /** Its accessible name where it adds ("Add at 10:30, Chair 2"); absent, the label. */ name?: string; /** Adds work there: the opening is a button, its "+" shown on hover and focus. */ onPress?: () => void; } /** A registration and its two readings. */ export declare const LANE_BOARD_HEAD = 168; /** Below this a track is too short to read a day by (a phone): each lane lists its work instead. */ export declare const LANE_BOARD_COMPACT = 600; /** * Each mark kept only where its label fits before the next, left to right; overlapping labels name * nothing. Unmeasured, every mark stands. */ export declare function seatedTicks(ticks: readonly LaneBoardTick[], width: number | null): readonly LaneBoardTick[]; /** A lane's work and openings as one list in clock order, work first where both start at one share. */ export declare function laneEntries(lane: Pick): ({ kind: "block"; block: LaneBoardBlock; } | { kind: "opening"; opening: LaneBoardOpening; })[]; export declare function LaneBoard(props: LaneBoardProps): React.ReactElement>;