import type { ElementType } from "react"; /** Emphasis of a bulk action: "primary" is the affirmative one, "danger" the destructive one, "default" the rest. */ export type BulkActionTone = "default" | "primary" | "danger"; /** One button in the bar; actions render in array order. */ export interface BulkAction { /** Stable key; also the suffix of the button's `data-testid` (`bulk-action-`). */ id: string; /** Button text; also the loading text while `isLoading`. */ label: string; /** Called when the button is pressed. */ onClick: () => void; /** Defaults to "default". */ tone?: BulkActionTone; /** Icon component (e.g. a lucide icon); rendered at 16px, decorative. */ icon?: ElementType; /** Disables the button. */ isDisabled?: boolean; /** Spinner on this action; the label stays as the loading text. */ isLoading?: boolean; } /** Props for the selection bar shown while table rows are selected; it renders nothing at zero. */ export interface BulkSelectionBarProps { /** Rows selected; the bar renders nothing at 0 and announces each change politely. */ selectedCount: number; /** Short claims true of the whole selection, e.g. ["all leave", "no clashes"]; joined after the count with " ยท ". */ facts?: string[]; /** Buttons shown after the count, in array order, before the clear button. */ actions: BulkAction[]; /** Called when the clear button is pressed. */ onClearSelection: () => void; /** Clear button text; defaults to "Clear selection". */ clearLabel?: string; /** Replaces the default "{n} selected" text, and what is announced. */ countLabel?: string; /** "sticky" (default) pins to the bottom of the nearest scroll container; "inline" stays in flow. */ placement?: "inline" | "sticky"; /** Accessible name of the region; defaults to "Selection actions". */ "aria-label"?: string; /** Test id on the bar; defaults to "bulk-selection-bar". */ "data-testid"?: string; }