import { CSSProperties, ReactNode } from 'react'; import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js'; export interface KanbanColumnDef { id: string; title: string; itemIds: string[]; /** * Optional work-in-progress limit. When set, the column header shows a `count/maxItems` * badge, and the column gets a warning style once `itemIds.length` exceeds it. This is * display-only — `KanbanBoard` doesn't block drops on its own. To enforce a hard limit, * check it in `onChange` and skip updating your state when a drop would push a column over. */ maxItems?: number; /** * Freezes the column: cards inside it can't be picked up, and nothing can be dropped into it. * Use for a workflow rule like "cards in Done can't be moved back out." */ disabled?: boolean; /** * Whether more items exist for this column beyond what's currently in `itemIds` — enables the * scroll-triggered `onLoadMore` request. Only meaningful alongside `KanbanBoardProps.onLoadMore`; * a column without it never asks for more regardless of this flag. Set `false` (or omit) once * the column's source is exhausted to stop asking. */ hasMore?: boolean; } export type KanbanBoardSlots = 'dragOverlay'; export interface KanbanBoardProps extends Omit { /** Ordered list of column definitions. Each column owns its itemIds. */ columns: KanbanColumnDef[]; /** Flat map of all items keyed by their id. */ items: Record; /** Render function for each item. Receives the item data and its id. */ renderItem: (item: T, id: string) => ReactNode; /** * Called after every drop that changes column or order. * Receives the full updated columns array — replace your state with this value. */ onChange: (columns: KanbanColumnDef[]) => void; /** * Drag a card only by the element marked `data-drag-handle` inside it, with the mouse, touch * and the keyboard, instead of by the whole card. The handle is made focusable and named with * `getItemLabel` unless it has a name, and the card stops being a button. Use when `renderItem` * includes controls (buttons, inputs): inside a card that is itself the button, a screen reader * reads them as plain text. */ dragHandle?: boolean; /** * Produce an accessible label for a card, announced to screen-reader users while dragging * (e.g. "Picked up