@stll/ui 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -211,6 +211,31 @@ Pointer and touch drops outside registered board targets cancel. Choose an
211
211
  explicit `{ type: "handle" }` activation for the 44px handle, or `{ type:
212
212
  "item" }` when the whole item is the intended activation surface.
213
213
 
214
+ ### Column bands
215
+
216
+ Columns whose options carry a `band` (`KanbanColumnBand`, usually a status
217
+ property's option groups) render under one `KanbanColumnBandHeader` and fold
218
+ as a run. `resolveKanbanColumnBands` derives the bands from the column order
219
+ and rejects a band that resumes after another column, so a header can never
220
+ span two separate runs. A folded band takes one narrow slot in every row;
221
+ render a drop target in `renderCollapsedBandCell` to keep its hidden cells
222
+ reachable, and the slot peeks open while a pointer rests on it. Pass
223
+ `isBandCollapsed` and `onBandCollapsedChange` to persist the fold in a view.
224
+
225
+ ```tsx
226
+ <KanbanSubgroupBoard
227
+ isBandCollapsed={(band) => collapsedBands.includes(band.id)}
228
+ matrix={matrix}
229
+ renderCell={renderCell}
230
+ renderCollapsedBandCell={({ band, cells, count }) => (
231
+ <FoldedDropTarget bandId={band.id} cells={cells} count={count} />
232
+ )}
233
+ renderColumnHeader={renderColumnHeader}
234
+ renderLaneIdentity={renderLaneIdentity}
235
+ onBandCollapsedChange={(band, collapsed) => saveFold(band.id, collapsed)}
236
+ />
237
+ ```
238
+
214
239
  ## Styles
215
240
 
216
241
  No compiled CSS ships. The components carry Tailwind class names, so the
@@ -10,8 +10,8 @@
10
10
  */
11
11
  declare const buttonAccessibleDisabledClass = "cursor-not-allowed opacity-64";
12
12
  declare const buttonVariants: (props?: ({
13
- size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "sm" | "xl" | "xs" | null | undefined;
14
- variant?: "link" | "default" | "destructive" | "destructive-outline" | "ghost" | "outline" | "secondary" | null | undefined;
13
+ size?: "xs" | "sm" | "icon" | "default" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "lg" | "xl" | null | undefined;
14
+ variant?: "destructive" | "outline" | "link" | "default" | "destructive-outline" | "ghost" | "secondary" | null | undefined;
15
15
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
16
16
  //#endregion
17
17
  export { buttonAccessibleDisabledClass, buttonVariants };
package/dist/index.d.ts CHANGED
@@ -70,15 +70,17 @@ import "./inspector/index.js";
70
70
  import { KanbanCardFieldSelection, selectKanbanCardFieldIds } from "./kanban/card-properties.js";
71
71
  import { KanbanCardShell, KanbanCardShellProps } from "./kanban/card-shell.js";
72
72
  import { KanbanCellAction, KanbanCellActionProps } from "./kanban/cell-action.js";
73
+ import { KanbanColumnBandHeader, KanbanColumnBandHeaderProps } from "./kanban/column-band-header.js";
74
+ import { ColorVariants, OptionColor, emptyColor, optionColors, resolveOptionColor } from "./lib/option-color.js";
75
+ import { KanbanBuiltInGroup, KanbanColumnBand, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./kanban/grouping.js";
76
+ import { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardColumn, KanbanBoardCoordinate, KanbanBoardDestination, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./kanban/matrix.js";
77
+ import { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KanbanColumnBandSpan, hasKanbanColumnBands, resolveKanbanColumnBands } from "./kanban/column-bands.js";
73
78
  import { KanbanColumnHeader, KanbanColumnHeaderProps } from "./kanban/column-header.js";
74
79
  import { KANBAN_BOARD_COLLISION_DETECTION, KanbanCellVirtualNavigation, KanbanSortableCellPosition, KanbanVirtualScrollRequest, kanbanKeyboardCoordinates } from "./kanban/sortable-interactions.logic.js";
75
80
  import { KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KanbanCardDragSurface, KanbanCardDragSurfaceProps, KanbanDragCancelEvent, KanbanDragEndEvent, KanbanDragHandle, KanbanDragHandleProps, KanbanDragOverEvent, KanbanDragStartEvent, KanbanSortableActivationMode, KanbanSortableBindings, KanbanSortableBoard, KanbanSortableBoardProps, KanbanSortableColumns, KanbanSortableColumnsProps, KanbanSortableList, KanbanSortableListProps, UseKanbanDropTargetOptions, UseKanbanSortableOptions, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors } from "./kanban/sortable-interactions.js";
76
81
  import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KanbanDirection, KanbanHorizontalEdge, getKanbanHorizontalEdge } from "./kanban/sortable-edge.js";
77
82
  import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, RegisterKanbanBoardAutoScrollOptions, RegisterKanbanCardDragOptions, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./kanban/drag-interactions.js";
78
- import { ColorVariants, OptionColor, emptyColor, optionColors, resolveOptionColor } from "./lib/option-color.js";
79
- import { KanbanBuiltInGroup, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./kanban/grouping.js";
80
- import { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardColumn, KanbanBoardCoordinate, KanbanBoardDestination, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./kanban/matrix.js";
81
- import { KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./kanban/subgroup-board.js";
83
+ import { KANBAN_BAND_PEEK_DELAY_MS, KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupCollapsedBandCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./kanban/subgroup-board.js";
82
84
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps, KanbanVirtualCellSortableContext } from "./kanban/virtual-cell.js";
83
85
  import "./kanban/index.js";
84
86
  import { getInitials } from "./lib/initials.js";
@@ -91,4 +93,4 @@ import { ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffSegment, ReviewDiffS
91
93
  import { ReviewOutOfDateNotice, ReviewOutOfDateReason, ReviewOutOfDateTone } from "./review/review-out-of-date-notice.js";
92
94
  import { ReviewStatusBadge, ReviewStatusSize, ReviewStatusTone, ReviewStatusVariant } from "./review/review-status-badge.js";
93
95
  import { ReviewSeverityDot, ReviewSeverityLevel, ReviewStatusDot, reviewSeverityTone } from "./review/review-severity-dot.js";
94
- export { APPLICATION_RAIL_BUTTON_SIZE, APPLICATION_RAIL_ICON_SIZE, APPLICATION_RAIL_WIDTH, Accordion, AccordionPanel as AccordionContent, AccordionPanel, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogBackdrop, AlertDialogBackdrop as AlertDialogOverlay, AlertDialogClose, AlertDialogPopup as AlertDialogContent, AlertDialogPopup, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPanel, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertDialogViewport, AnchoredToastProvider, ApplicationRail, ApplicationRailButton, ApplicationRailContent, ApplicationRailFooter, ApplicationRailHeader, ApplicationRailMenu, ApplicationRailSeparator, Avatar, AvatarFallback, AvatarImage, BOARD_DRAG_OVERLAY_Z_INDEX, type BidiDirection, BidiText, type BidiTextProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, type BuildKanbanBoardMatrixParams, Button, CONTROL_SIZE, CONTROL_SIZES, CalendarCell, type CalendarDateRange, CalendarEntryButton, CalendarEntrySurface, CalendarGrid, CalendarHeaderCell, CalendarHeaderRow, Checkbox, ColorPicker, ColorPickerContent, type ColorPickerContentProps, type ColorPickerProps, type ColorPreset, ColorVariants, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxClear, ComboboxCollection, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxList, ComboboxPopup, ComboboxRow, ComboboxSeparator, ComboboxStatus, ComboboxTrigger, ComboboxValue, Command, CommandCollection, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut, type ControlSize, type CreateKanbanDropIntentParams, DEFAULT_PRESETS, DataTable, type DataTableAriaSort, type DataTableColumn, type DataTableProps, type DataTableRowAction, DatePickerPopover, type DatePickerPopoverProps, DestructiveActionConfirmation, DestructiveConfirmDialog, type DestructiveConfirmDialogProps, Dialog, DialogBackdrop, DialogBackdrop as DialogOverlay, DialogClose, DialogPopup as DialogContent, DialogPopup, DialogCreateHandle, DialogDescription, DialogFooter, DialogHeader, DialogPanel, DialogPortal, DialogTitle, DialogTrigger, DialogViewport, DirectionalIcon, DiscordLogoIcon, Menu as DropdownMenu, Menu, MenuCheckboxItem as DropdownMenuCheckboxItem, MenuCheckboxItem, MenuPopup as DropdownMenuContent, MenuPopup, MenuCreateHandle as DropdownMenuCreateHandle, MenuCreateHandle, MenuGroup as DropdownMenuGroup, MenuGroup, MenuItem as DropdownMenuItem, MenuItem, MenuGroupLabel as DropdownMenuLabel, MenuGroupLabel, MenuPortal as DropdownMenuPortal, MenuPortal, MenuRadioGroup as DropdownMenuRadioGroup, MenuRadioGroup, MenuRadioItem as DropdownMenuRadioItem, MenuRadioItem, MenuSeparator as DropdownMenuSeparator, MenuSeparator, MenuShortcut as DropdownMenuShortcut, MenuShortcut, MenuSub as DropdownMenuSub, MenuSub, MenuSubPopup as DropdownMenuSubContent, MenuSubPopup, MenuSubTrigger as DropdownMenuSubTrigger, MenuSubTrigger, MenuTrigger as DropdownMenuTrigger, MenuTrigger, Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, Form, Frame, FrameDescription, FrameFooter, FrameHeader, FramePanel, FrameTitle, GitHubLogoIcon, HexColorPicker, type HexColorPickerProps, PreviewCard as HoverCard, PreviewCard, PreviewCardPopup as HoverCardContent, PreviewCardPopup, PreviewCardTrigger as HoverCardTrigger, PreviewCardTrigger, INSPECTOR_CONTENT_MIN_WIDTH, INSPECTOR_EDITOR_MIN_WIDTH, INSPECTOR_PANE_DEFAULT_WIDTH, INSPECTOR_PANE_KEYBOARD_PAGE_STEP, INSPECTOR_PANE_KEYBOARD_STEP, INSPECTOR_PANE_MAX_WIDTH, INSPECTOR_PANE_MIN_WIDTH, INSPECTOR_RAIL_WIDTH, Input, InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Inspector, InspectorActions, InspectorContent, InspectorDescription, InspectorDock, InspectorEmptyRow, InspectorHeader, InspectorHeaderText, InspectorProperty, InspectorPropertyLabel, InspectorPropertyList, InspectorPropertyValue, InspectorRail, InspectorRailCell, InspectorRailContent, InspectorRailFooter, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBoardAxis, type KanbanBoardCell, type KanbanBoardColumn, type KanbanBoardCoordinate, type KanbanBoardDestination, type KanbanBoardLane, type KanbanBoardMatrix, type KanbanBuiltInGroup, KanbanCardDragSurface, type KanbanCardDragSurfaceProps, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanCellAction, type KanbanCellActionProps, type KanbanCellVirtualNavigation, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, type KanbanDragCancelEvent, type KanbanDragEndEvent, KanbanDragHandle, type KanbanDragHandleProps, type KanbanDragOverEvent, type KanbanDragStartEvent, type KanbanDropAxisChange, type KanbanDropIntent, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableActivationMode, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, type KanbanSortableCellPosition, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, KanbanSubgroupBoard, type KanbanSubgroupBoardProps, type KanbanSubgroupCellContext, type KanbanSubgroupColumnHeaderContext, type KanbanSubgroupLaneIdentityContext, KanbanVirtualCell, type KanbanVirtualCellPagination, type KanbanVirtualCellProps, type KanbanVirtualCellSortableContext, type KanbanVirtualScrollRequest, Label, MenuPreviewLayout, OVERLAY_LAYER_CLASS_NAMES, OptionColor, type OrderKanbanCellsByColumnsParams, OutlineItem, OutlineRail, OutlineRailProps, OverlayLayer, PROPERTY_ROW_GRID, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverClose, PopoverPopup as PopoverContent, PopoverPopup, PopoverCreateHandle, PopoverDescription, PopoverPanel, PopoverTitle, PopoverTrigger, PreviewCardPrimitive, PreviewPane, type RegisterKanbanBoardAutoScrollOptions, type RegisterKanbanCardDragOptions, type ResolveKanbanGroupValueParams, type ResolveKanbanGroupingParams, ResourceCalendar, type ResourceCalendarColumn, type ResourceCalendarEntry, type ResourceCalendarEntryTone, type ResourceCalendarLaneLayout, type ResourceCalendarLanePlacement, type ResourceCalendarPlacement, type ResourceCalendarResource, ReviewAuthorAvatar, ReviewCommentAuthor, ReviewCommentCard, ReviewDecisionActions, ReviewDecisionSize, ReviewDecisionState, ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffSegment, ReviewDiffSegmentType, ReviewDiffText, ReviewOutOfDateNotice, ReviewOutOfDateReason, ReviewOutOfDateTone, ReviewSeverityDot, ReviewSeverityLevel, ReviewStatusBadge, ReviewStatusDot, ReviewStatusSize, ReviewStatusTone, ReviewStatusVariant, SIDE_RAIL_CONTAINER_CLASS, SIDE_RAIL_ICON_BUTTON_SIZE, SIDE_RAIL_TAB_ICON_SIZE, SIDE_RAIL_WIDTH, ScrollArea, ScrollBar, ScrollToTop, ScrollToTopProps, SecretInput, type SecretInputProps, SegmentedIconToggle, Select, SelectPopup as SelectContent, SelectPopup, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBackdrop, SheetBackdrop as SheetOverlay, SheetClose, SheetPopup as SheetContent, SheetPopup, SheetDescription, SheetFooter, SheetHeader, SheetPanel, SheetPortal, type SheetSide, SheetTitle, SheetTrigger, Skeleton, type SortDirection, SortableHead, StellaMark, StellaWordmarkLatin, TOAST_RIGHT_OFFSET_VAR, TOOLBAR_ROW_HEIGHT, TOOLBAR_ROW_HEIGHT_PX, TRACKED_DELETION_STYLE, TRACKED_INSERTION_STYLE, Table, TableBody, TableCaption, TableCell, type TableColumnCapabilities, type TableColumnDescriptor, TableFooter, TableHead, TableHeader, TableRow, type TableSchema, Tabs, TabsPanel as TabsContent, TabsPanel, TabsList, TabsTab, TabsTab as TabsTrigger, TextSeparator, Textarea, type TextareaProps, type ToastPosition, ToastProvider, Tooltip, TooltipPopup as TooltipContent, TooltipPopup, TooltipCreateHandle, TooltipProvider, TooltipTrigger, UNKNOWN_AUTHOR_LABEL, type UseKanbanDropTargetOptions, type UseKanbanSortableOptions, UserText, type WorkspaceCompactNavigation, WorkspaceEndRail, type WorkspaceEndRailChatAction, type WorkspaceEndRailProps, type WorkspaceNavigation, WorkspaceShell, type WorkspaceShellProps, type WorkspaceTopBarContext, assertConsecutiveCalendarDates, buildKanbanBoardMatrix, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, createKanbanDropIntent, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, kanbanKeyboardCoordinates, layoutResourceCalendarEntries, nextCalendarDate, optionColors, orderKanbanCellsByColumns, parsePersistedPaneWidth, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveDragWidth, resolveInspectorDockWidth, resolveInspectorPaneMaxWidth, resolveInspectorPaneWidth, resolveKanbanGroupOptions, resolveKanbanGrouping, resolveKeyboardWidth, resolveOptionColor, reviewDiffSegmentKeys, reviewSeverityTone, selectKanbanCardFieldIds, selectKanbanRows, shouldForceSidebarCollapsed, sortableColumnIds, stellaToast, tableColumnIds, tableColumnSizing, useComboboxFilter, useContentDir, useDestructiveActionConfirmation, useInspectorPaneWidth, useIsMobile, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
96
+ export { APPLICATION_RAIL_BUTTON_SIZE, APPLICATION_RAIL_ICON_SIZE, APPLICATION_RAIL_WIDTH, Accordion, AccordionPanel as AccordionContent, AccordionPanel, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogBackdrop, AlertDialogBackdrop as AlertDialogOverlay, AlertDialogClose, AlertDialogPopup as AlertDialogContent, AlertDialogPopup, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPanel, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertDialogViewport, AnchoredToastProvider, ApplicationRail, ApplicationRailButton, ApplicationRailContent, ApplicationRailFooter, ApplicationRailHeader, ApplicationRailMenu, ApplicationRailSeparator, Avatar, AvatarFallback, AvatarImage, BOARD_DRAG_OVERLAY_Z_INDEX, type BidiDirection, BidiText, type BidiTextProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, type BuildKanbanBoardMatrixParams, Button, CONTROL_SIZE, CONTROL_SIZES, CalendarCell, type CalendarDateRange, CalendarEntryButton, CalendarEntrySurface, CalendarGrid, CalendarHeaderCell, CalendarHeaderRow, Checkbox, ColorPicker, ColorPickerContent, type ColorPickerContentProps, type ColorPickerProps, type ColorPreset, ColorVariants, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxClear, ComboboxCollection, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxList, ComboboxPopup, ComboboxRow, ComboboxSeparator, ComboboxStatus, ComboboxTrigger, ComboboxValue, Command, CommandCollection, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut, type ControlSize, type CreateKanbanDropIntentParams, DEFAULT_PRESETS, DataTable, type DataTableAriaSort, type DataTableColumn, type DataTableProps, type DataTableRowAction, DatePickerPopover, type DatePickerPopoverProps, DestructiveActionConfirmation, DestructiveConfirmDialog, type DestructiveConfirmDialogProps, Dialog, DialogBackdrop, DialogBackdrop as DialogOverlay, DialogClose, DialogPopup as DialogContent, DialogPopup, DialogCreateHandle, DialogDescription, DialogFooter, DialogHeader, DialogPanel, DialogPortal, DialogTitle, DialogTrigger, DialogViewport, DirectionalIcon, DiscordLogoIcon, Menu as DropdownMenu, Menu, MenuCheckboxItem as DropdownMenuCheckboxItem, MenuCheckboxItem, MenuPopup as DropdownMenuContent, MenuPopup, MenuCreateHandle as DropdownMenuCreateHandle, MenuCreateHandle, MenuGroup as DropdownMenuGroup, MenuGroup, MenuItem as DropdownMenuItem, MenuItem, MenuGroupLabel as DropdownMenuLabel, MenuGroupLabel, MenuPortal as DropdownMenuPortal, MenuPortal, MenuRadioGroup as DropdownMenuRadioGroup, MenuRadioGroup, MenuRadioItem as DropdownMenuRadioItem, MenuRadioItem, MenuSeparator as DropdownMenuSeparator, MenuSeparator, MenuShortcut as DropdownMenuShortcut, MenuShortcut, MenuSub as DropdownMenuSub, MenuSub, MenuSubPopup as DropdownMenuSubContent, MenuSubPopup, MenuSubTrigger as DropdownMenuSubTrigger, MenuSubTrigger, MenuTrigger as DropdownMenuTrigger, MenuTrigger, Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, Form, Frame, FrameDescription, FrameFooter, FrameHeader, FramePanel, FrameTitle, GitHubLogoIcon, HexColorPicker, type HexColorPickerProps, PreviewCard as HoverCard, PreviewCard, PreviewCardPopup as HoverCardContent, PreviewCardPopup, PreviewCardTrigger as HoverCardTrigger, PreviewCardTrigger, INSPECTOR_CONTENT_MIN_WIDTH, INSPECTOR_EDITOR_MIN_WIDTH, INSPECTOR_PANE_DEFAULT_WIDTH, INSPECTOR_PANE_KEYBOARD_PAGE_STEP, INSPECTOR_PANE_KEYBOARD_STEP, INSPECTOR_PANE_MAX_WIDTH, INSPECTOR_PANE_MIN_WIDTH, INSPECTOR_RAIL_WIDTH, Input, InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Inspector, InspectorActions, InspectorContent, InspectorDescription, InspectorDock, InspectorEmptyRow, InspectorHeader, InspectorHeaderText, InspectorProperty, InspectorPropertyLabel, InspectorPropertyList, InspectorPropertyValue, InspectorRail, InspectorRailCell, InspectorRailContent, InspectorRailFooter, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBoardAxis, type KanbanBoardCell, type KanbanBoardColumn, type KanbanBoardCoordinate, type KanbanBoardDestination, type KanbanBoardLane, type KanbanBoardMatrix, type KanbanBuiltInGroup, KanbanCardDragSurface, type KanbanCardDragSurfaceProps, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanCellAction, type KanbanCellActionProps, type KanbanCellVirtualNavigation, type KanbanColumnBand, KanbanColumnBandHeader, type KanbanColumnBandHeaderProps, type KanbanColumnBandSpan, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, type KanbanDragCancelEvent, type KanbanDragEndEvent, KanbanDragHandle, type KanbanDragHandleProps, type KanbanDragOverEvent, type KanbanDragStartEvent, type KanbanDropAxisChange, type KanbanDropIntent, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableActivationMode, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, type KanbanSortableCellPosition, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, type KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, type KanbanSubgroupBoardProps, type KanbanSubgroupCellContext, type KanbanSubgroupCollapsedBandCellContext, type KanbanSubgroupColumnHeaderContext, type KanbanSubgroupLaneIdentityContext, KanbanVirtualCell, type KanbanVirtualCellPagination, type KanbanVirtualCellProps, type KanbanVirtualCellSortableContext, type KanbanVirtualScrollRequest, Label, MenuPreviewLayout, OVERLAY_LAYER_CLASS_NAMES, OptionColor, type OrderKanbanCellsByColumnsParams, OutlineItem, OutlineRail, OutlineRailProps, OverlayLayer, PROPERTY_ROW_GRID, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverClose, PopoverPopup as PopoverContent, PopoverPopup, PopoverCreateHandle, PopoverDescription, PopoverPanel, PopoverTitle, PopoverTrigger, PreviewCardPrimitive, PreviewPane, type RegisterKanbanBoardAutoScrollOptions, type RegisterKanbanCardDragOptions, type ResolveKanbanGroupValueParams, type ResolveKanbanGroupingParams, ResourceCalendar, type ResourceCalendarColumn, type ResourceCalendarEntry, type ResourceCalendarEntryTone, type ResourceCalendarLaneLayout, type ResourceCalendarLanePlacement, type ResourceCalendarPlacement, type ResourceCalendarResource, ReviewAuthorAvatar, ReviewCommentAuthor, ReviewCommentCard, ReviewDecisionActions, ReviewDecisionSize, ReviewDecisionState, ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffSegment, ReviewDiffSegmentType, ReviewDiffText, ReviewOutOfDateNotice, ReviewOutOfDateReason, ReviewOutOfDateTone, ReviewSeverityDot, ReviewSeverityLevel, ReviewStatusBadge, ReviewStatusDot, ReviewStatusSize, ReviewStatusTone, ReviewStatusVariant, SIDE_RAIL_CONTAINER_CLASS, SIDE_RAIL_ICON_BUTTON_SIZE, SIDE_RAIL_TAB_ICON_SIZE, SIDE_RAIL_WIDTH, ScrollArea, ScrollBar, ScrollToTop, ScrollToTopProps, SecretInput, type SecretInputProps, SegmentedIconToggle, Select, SelectPopup as SelectContent, SelectPopup, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBackdrop, SheetBackdrop as SheetOverlay, SheetClose, SheetPopup as SheetContent, SheetPopup, SheetDescription, SheetFooter, SheetHeader, SheetPanel, SheetPortal, type SheetSide, SheetTitle, SheetTrigger, Skeleton, type SortDirection, SortableHead, StellaMark, StellaWordmarkLatin, TOAST_RIGHT_OFFSET_VAR, TOOLBAR_ROW_HEIGHT, TOOLBAR_ROW_HEIGHT_PX, TRACKED_DELETION_STYLE, TRACKED_INSERTION_STYLE, Table, TableBody, TableCaption, TableCell, type TableColumnCapabilities, type TableColumnDescriptor, TableFooter, TableHead, TableHeader, TableRow, type TableSchema, Tabs, TabsPanel as TabsContent, TabsPanel, TabsList, TabsTab, TabsTab as TabsTrigger, TextSeparator, Textarea, type TextareaProps, type ToastPosition, ToastProvider, Tooltip, TooltipPopup as TooltipContent, TooltipPopup, TooltipCreateHandle, TooltipProvider, TooltipTrigger, UNKNOWN_AUTHOR_LABEL, type UseKanbanDropTargetOptions, type UseKanbanSortableOptions, UserText, type WorkspaceCompactNavigation, WorkspaceEndRail, type WorkspaceEndRailChatAction, type WorkspaceEndRailProps, type WorkspaceNavigation, WorkspaceShell, type WorkspaceShellProps, type WorkspaceTopBarContext, assertConsecutiveCalendarDates, buildKanbanBoardMatrix, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, createKanbanDropIntent, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hasKanbanColumnBands, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, kanbanKeyboardCoordinates, layoutResourceCalendarEntries, nextCalendarDate, optionColors, orderKanbanCellsByColumns, parsePersistedPaneWidth, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveDragWidth, resolveInspectorDockWidth, resolveInspectorPaneMaxWidth, resolveInspectorPaneWidth, resolveKanbanColumnBands, resolveKanbanGroupOptions, resolveKanbanGrouping, resolveKeyboardWidth, resolveOptionColor, reviewDiffSegmentKeys, reviewSeverityTone, selectKanbanCardFieldIds, selectKanbanRows, shouldForceSidebarCollapsed, sortableColumnIds, stellaToast, tableColumnIds, tableColumnSizing, useComboboxFilter, useContentDir, useDestructiveActionConfirmation, useInspectorPaneWidth, useIsMobile, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
package/dist/index.js CHANGED
@@ -69,14 +69,16 @@ import { INSPECTOR_PANE_KEYBOARD_PAGE_STEP, INSPECTOR_PANE_KEYBOARD_STEP, parseP
69
69
  import { selectKanbanCardFieldIds } from "./kanban/card-properties.js";
70
70
  import { KanbanCardShell } from "./kanban/card-shell.js";
71
71
  import { KanbanCellAction } from "./kanban/cell-action.js";
72
+ import { KanbanColumnBandHeader } from "./kanban/column-band-header.js";
73
+ import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./kanban/grouping.js";
74
+ import { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./kanban/matrix.js";
75
+ import { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, hasKanbanColumnBands, resolveKanbanColumnBands } from "./kanban/column-bands.js";
72
76
  import { KanbanColumnHeader } from "./kanban/column-header.js";
73
77
  import { KANBAN_BOARD_COLLISION_DETECTION, kanbanKeyboardCoordinates } from "./kanban/sortable-interactions.logic.js";
74
78
  import { KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KanbanCardDragSurface, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors } from "./kanban/sortable-interactions.js";
75
79
  import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, getKanbanHorizontalEdge } from "./kanban/sortable-edge.js";
76
80
  import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./kanban/drag-interactions.js";
77
- import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./kanban/grouping.js";
78
- import { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./kanban/matrix.js";
79
- import { KanbanSubgroupBoard } from "./kanban/subgroup-board.js";
81
+ import { KANBAN_BAND_PEEK_DELAY_MS, KanbanSubgroupBoard } from "./kanban/subgroup-board.js";
80
82
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell } from "./kanban/virtual-cell.js";
81
83
  import { getInitials } from "./lib/initials.js";
82
84
  import { emptyColor, optionColors, resolveOptionColor } from "./lib/option-color.js";
@@ -87,4 +89,4 @@ import { ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffText, TRACKED_DELETI
87
89
  import { ReviewOutOfDateNotice } from "./review/review-out-of-date-notice.js";
88
90
  import { ReviewSeverityDot, ReviewStatusDot, reviewSeverityTone } from "./review/review-severity-dot.js";
89
91
  import { ReviewStatusBadge } from "./review/review-status-badge.js";
90
- export { APPLICATION_RAIL_BUTTON_SIZE, APPLICATION_RAIL_ICON_SIZE, APPLICATION_RAIL_WIDTH, Accordion, AccordionPanel as AccordionContent, AccordionPanel, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogBackdrop, AlertDialogBackdrop as AlertDialogOverlay, AlertDialogClose, AlertDialogPopup as AlertDialogContent, AlertDialogPopup, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPanel, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertDialogViewport, AnchoredToastProvider, ApplicationRail, ApplicationRailButton, ApplicationRailContent, ApplicationRailFooter, ApplicationRailHeader, ApplicationRailMenu, ApplicationRailSeparator, Avatar, AvatarFallback, AvatarImage, BOARD_DRAG_OVERLAY_Z_INDEX, BidiText, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, CONTROL_SIZE, CONTROL_SIZES, CalendarCell, CalendarEntryButton, CalendarEntrySurface, CalendarGrid, CalendarHeaderCell, CalendarHeaderRow, Checkbox, ColorPicker, ColorPickerContent, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxClear, ComboboxCollection, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxList, ComboboxPopup, ComboboxRow, ComboboxSeparator, ComboboxStatus, ComboboxTrigger, ComboboxValue, Command, CommandCollection, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut, DEFAULT_PRESETS, DataTable, DatePickerPopover, DestructiveActionConfirmation, DestructiveConfirmDialog, Dialog, DialogBackdrop, DialogBackdrop as DialogOverlay, DialogClose, DialogPopup as DialogContent, DialogPopup, DialogCreateHandle, DialogDescription, DialogFooter, DialogHeader, DialogPanel, DialogPortal, DialogTitle, DialogTrigger, DialogViewport, DirectionalIcon, DiscordLogoIcon, Menu as DropdownMenu, Menu, MenuCheckboxItem as DropdownMenuCheckboxItem, MenuCheckboxItem, MenuPopup as DropdownMenuContent, MenuPopup, MenuCreateHandle as DropdownMenuCreateHandle, MenuCreateHandle, MenuGroup as DropdownMenuGroup, MenuGroup, MenuItem as DropdownMenuItem, MenuItem, MenuGroupLabel as DropdownMenuLabel, MenuGroupLabel, MenuPortal as DropdownMenuPortal, MenuPortal, MenuRadioGroup as DropdownMenuRadioGroup, MenuRadioGroup, MenuRadioItem as DropdownMenuRadioItem, MenuRadioItem, MenuSeparator as DropdownMenuSeparator, MenuSeparator, MenuShortcut as DropdownMenuShortcut, MenuShortcut, MenuSub as DropdownMenuSub, MenuSub, MenuSubPopup as DropdownMenuSubContent, MenuSubPopup, MenuSubTrigger as DropdownMenuSubTrigger, MenuSubTrigger, MenuTrigger as DropdownMenuTrigger, MenuTrigger, Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, Form, Frame, FrameDescription, FrameFooter, FrameHeader, FramePanel, FrameTitle, GitHubLogoIcon, HexColorPicker, PreviewCard as HoverCard, PreviewCard, PreviewCardPopup as HoverCardContent, PreviewCardPopup, PreviewCardTrigger as HoverCardTrigger, PreviewCardTrigger, INSPECTOR_CONTENT_MIN_WIDTH, INSPECTOR_EDITOR_MIN_WIDTH, INSPECTOR_PANE_DEFAULT_WIDTH, INSPECTOR_PANE_KEYBOARD_PAGE_STEP, INSPECTOR_PANE_KEYBOARD_STEP, INSPECTOR_PANE_MAX_WIDTH, INSPECTOR_PANE_MIN_WIDTH, INSPECTOR_RAIL_WIDTH, Input, InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Inspector, InspectorActions, InspectorContent, InspectorDescription, InspectorDock, InspectorEmptyRow, InspectorHeader, InspectorHeaderText, InspectorProperty, InspectorPropertyLabel, InspectorPropertyList, InspectorPropertyValue, InspectorRail, InspectorRailCell, InspectorRailContent, InspectorRailFooter, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardDragSurface, KanbanCardShell, KanbanCellAction, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, KanbanSubgroupBoard, KanbanVirtualCell, Label, MenuPreviewLayout, OVERLAY_LAYER_CLASS_NAMES, OutlineRail, PROPERTY_ROW_GRID, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverClose, PopoverPopup as PopoverContent, PopoverPopup, PopoverCreateHandle, PopoverDescription, PopoverPanel, PopoverTitle, PopoverTrigger, PreviewCardPrimitive, PreviewPane, ResourceCalendar, ReviewAuthorAvatar, ReviewCommentCard, ReviewDecisionActions, ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffText, ReviewOutOfDateNotice, ReviewSeverityDot, ReviewStatusBadge, ReviewStatusDot, SIDE_RAIL_CONTAINER_CLASS, SIDE_RAIL_ICON_BUTTON_SIZE, SIDE_RAIL_TAB_ICON_SIZE, SIDE_RAIL_WIDTH, ScrollArea, ScrollBar, ScrollToTop, SecretInput, SegmentedIconToggle, Select, SelectPopup as SelectContent, SelectPopup, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBackdrop, SheetBackdrop as SheetOverlay, SheetClose, SheetPopup as SheetContent, SheetPopup, SheetDescription, SheetFooter, SheetHeader, SheetPanel, SheetPortal, SheetTitle, SheetTrigger, Skeleton, SortableHead, StellaMark, StellaWordmarkLatin, TOAST_RIGHT_OFFSET_VAR, TOOLBAR_ROW_HEIGHT, TOOLBAR_ROW_HEIGHT_PX, TRACKED_DELETION_STYLE, TRACKED_INSERTION_STYLE, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsPanel as TabsContent, TabsPanel, TabsList, TabsTab, TabsTab as TabsTrigger, TextSeparator, Textarea, ToastProvider, Tooltip, TooltipPopup as TooltipContent, TooltipPopup, TooltipCreateHandle, TooltipProvider, TooltipTrigger, UNKNOWN_AUTHOR_LABEL, UserText, WorkspaceEndRail, WorkspaceShell, assertConsecutiveCalendarDates, buildKanbanBoardMatrix, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, createKanbanDropIntent, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, kanbanKeyboardCoordinates, layoutResourceCalendarEntries, nextCalendarDate, optionColors, orderKanbanCellsByColumns, parsePersistedPaneWidth, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveDragWidth, resolveInspectorDockWidth, resolveInspectorPaneMaxWidth, resolveInspectorPaneWidth, resolveKanbanGroupOptions, resolveKanbanGrouping, resolveKeyboardWidth, resolveOptionColor, reviewDiffSegmentKeys, reviewSeverityTone, selectKanbanCardFieldIds, selectKanbanRows, shouldForceSidebarCollapsed, sortableColumnIds, stellaToast, tableColumnIds, tableColumnSizing, useComboboxFilter, useContentDir, useDestructiveActionConfirmation, useInspectorPaneWidth, useIsMobile, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
92
+ export { APPLICATION_RAIL_BUTTON_SIZE, APPLICATION_RAIL_ICON_SIZE, APPLICATION_RAIL_WIDTH, Accordion, AccordionPanel as AccordionContent, AccordionPanel, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogBackdrop, AlertDialogBackdrop as AlertDialogOverlay, AlertDialogClose, AlertDialogPopup as AlertDialogContent, AlertDialogPopup, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPanel, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertDialogViewport, AnchoredToastProvider, ApplicationRail, ApplicationRailButton, ApplicationRailContent, ApplicationRailFooter, ApplicationRailHeader, ApplicationRailMenu, ApplicationRailSeparator, Avatar, AvatarFallback, AvatarImage, BOARD_DRAG_OVERLAY_Z_INDEX, BidiText, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, CONTROL_SIZE, CONTROL_SIZES, CalendarCell, CalendarEntryButton, CalendarEntrySurface, CalendarGrid, CalendarHeaderCell, CalendarHeaderRow, Checkbox, ColorPicker, ColorPickerContent, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxClear, ComboboxCollection, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxList, ComboboxPopup, ComboboxRow, ComboboxSeparator, ComboboxStatus, ComboboxTrigger, ComboboxValue, Command, CommandCollection, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut, DEFAULT_PRESETS, DataTable, DatePickerPopover, DestructiveActionConfirmation, DestructiveConfirmDialog, Dialog, DialogBackdrop, DialogBackdrop as DialogOverlay, DialogClose, DialogPopup as DialogContent, DialogPopup, DialogCreateHandle, DialogDescription, DialogFooter, DialogHeader, DialogPanel, DialogPortal, DialogTitle, DialogTrigger, DialogViewport, DirectionalIcon, DiscordLogoIcon, Menu as DropdownMenu, Menu, MenuCheckboxItem as DropdownMenuCheckboxItem, MenuCheckboxItem, MenuPopup as DropdownMenuContent, MenuPopup, MenuCreateHandle as DropdownMenuCreateHandle, MenuCreateHandle, MenuGroup as DropdownMenuGroup, MenuGroup, MenuItem as DropdownMenuItem, MenuItem, MenuGroupLabel as DropdownMenuLabel, MenuGroupLabel, MenuPortal as DropdownMenuPortal, MenuPortal, MenuRadioGroup as DropdownMenuRadioGroup, MenuRadioGroup, MenuRadioItem as DropdownMenuRadioItem, MenuRadioItem, MenuSeparator as DropdownMenuSeparator, MenuSeparator, MenuShortcut as DropdownMenuShortcut, MenuShortcut, MenuSub as DropdownMenuSub, MenuSub, MenuSubPopup as DropdownMenuSubContent, MenuSubPopup, MenuSubTrigger as DropdownMenuSubTrigger, MenuSubTrigger, MenuTrigger as DropdownMenuTrigger, MenuTrigger, Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, Form, Frame, FrameDescription, FrameFooter, FrameHeader, FramePanel, FrameTitle, GitHubLogoIcon, HexColorPicker, PreviewCard as HoverCard, PreviewCard, PreviewCardPopup as HoverCardContent, PreviewCardPopup, PreviewCardTrigger as HoverCardTrigger, PreviewCardTrigger, INSPECTOR_CONTENT_MIN_WIDTH, INSPECTOR_EDITOR_MIN_WIDTH, INSPECTOR_PANE_DEFAULT_WIDTH, INSPECTOR_PANE_KEYBOARD_PAGE_STEP, INSPECTOR_PANE_KEYBOARD_STEP, INSPECTOR_PANE_MAX_WIDTH, INSPECTOR_PANE_MIN_WIDTH, INSPECTOR_RAIL_WIDTH, Input, InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Inspector, InspectorActions, InspectorContent, InspectorDescription, InspectorDock, InspectorEmptyRow, InspectorHeader, InspectorHeaderText, InspectorProperty, InspectorPropertyLabel, InspectorPropertyList, InspectorPropertyValue, InspectorRail, InspectorRailCell, InspectorRailContent, InspectorRailFooter, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardDragSurface, KanbanCardShell, KanbanCellAction, KanbanColumnBandHeader, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, KanbanSubgroupBoard, KanbanVirtualCell, Label, MenuPreviewLayout, OVERLAY_LAYER_CLASS_NAMES, OutlineRail, PROPERTY_ROW_GRID, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverClose, PopoverPopup as PopoverContent, PopoverPopup, PopoverCreateHandle, PopoverDescription, PopoverPanel, PopoverTitle, PopoverTrigger, PreviewCardPrimitive, PreviewPane, ResourceCalendar, ReviewAuthorAvatar, ReviewCommentCard, ReviewDecisionActions, ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffText, ReviewOutOfDateNotice, ReviewSeverityDot, ReviewStatusBadge, ReviewStatusDot, SIDE_RAIL_CONTAINER_CLASS, SIDE_RAIL_ICON_BUTTON_SIZE, SIDE_RAIL_TAB_ICON_SIZE, SIDE_RAIL_WIDTH, ScrollArea, ScrollBar, ScrollToTop, SecretInput, SegmentedIconToggle, Select, SelectPopup as SelectContent, SelectPopup, SelectGroup, SelectGroupLabel, SelectItem, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBackdrop, SheetBackdrop as SheetOverlay, SheetClose, SheetPopup as SheetContent, SheetPopup, SheetDescription, SheetFooter, SheetHeader, SheetPanel, SheetPortal, SheetTitle, SheetTrigger, Skeleton, SortableHead, StellaMark, StellaWordmarkLatin, TOAST_RIGHT_OFFSET_VAR, TOOLBAR_ROW_HEIGHT, TOOLBAR_ROW_HEIGHT_PX, TRACKED_DELETION_STYLE, TRACKED_INSERTION_STYLE, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsPanel as TabsContent, TabsPanel, TabsList, TabsTab, TabsTab as TabsTrigger, TextSeparator, Textarea, ToastProvider, Tooltip, TooltipPopup as TooltipContent, TooltipPopup, TooltipCreateHandle, TooltipProvider, TooltipTrigger, UNKNOWN_AUTHOR_LABEL, UserText, WorkspaceEndRail, WorkspaceShell, assertConsecutiveCalendarDates, buildKanbanBoardMatrix, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, createKanbanDropIntent, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hasKanbanColumnBands, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, kanbanKeyboardCoordinates, layoutResourceCalendarEntries, nextCalendarDate, optionColors, orderKanbanCellsByColumns, parsePersistedPaneWidth, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveDragWidth, resolveInspectorDockWidth, resolveInspectorPaneMaxWidth, resolveInspectorPaneWidth, resolveKanbanColumnBands, resolveKanbanGroupOptions, resolveKanbanGrouping, resolveKeyboardWidth, resolveOptionColor, reviewDiffSegmentKeys, reviewSeverityTone, selectKanbanCardFieldIds, selectKanbanRows, shouldForceSidebarCollapsed, sortableColumnIds, stellaToast, tableColumnIds, tableColumnSizing, useComboboxFilter, useContentDir, useDestructiveActionConfirmation, useInspectorPaneWidth, useIsMobile, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
@@ -0,0 +1,27 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/kanban/column-band-header.d.ts
3
+ type KanbanColumnBandHeaderProps = {
4
+ /** The band name, or the control that has taken its place. */
5
+ title: ReactNode;
6
+ /** Colour swatch for the band. */
7
+ swatch?: ReactNode;
8
+ /** Short text after the name, such as the band's card count. */
9
+ meta?: ReactNode;
10
+ /** Whether the band's columns are shown; drives the toggle and its icon. */
11
+ collapsed: boolean;
12
+ /** Accessible name for the toggle, such as "Collapse To do". */
13
+ toggleLabel: string;
14
+ onCollapsedChange: (collapsed: boolean) => void;
15
+ /** Band menu or other controls, after the toggle. */
16
+ actions?: ReactNode;
17
+ };
18
+ /**
19
+ * The band header row above a run of columns: the same rhythm as
20
+ * `KanbanColumnHeader` (swatch, name, count, controls), plus the collapse
21
+ * toggle that folds the run into one narrow lane. Collapsed, the header is
22
+ * the only thing left of the band, so it also carries the band's identity on
23
+ * `aria-expanded` for the columns it hides.
24
+ */
25
+ declare const KanbanColumnBandHeader: ({ title, swatch, meta, collapsed, toggleLabel, onCollapsedChange, actions }: KanbanColumnBandHeaderProps) => import("react").JSX.Element;
26
+ //#endregion
27
+ export { KanbanColumnBandHeader, KanbanColumnBandHeaderProps };
@@ -0,0 +1,42 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { DirectionalIcon } from "../components/directional-icon.js";
3
+ import { ChevronDownIcon } from "lucide-react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/kanban/column-band-header.tsx
6
+ /**
7
+ * The band header row above a run of columns: the same rhythm as
8
+ * `KanbanColumnHeader` (swatch, name, count, controls), plus the collapse
9
+ * toggle that folds the run into one narrow lane. Collapsed, the header is
10
+ * the only thing left of the band, so it also carries the band's identity on
11
+ * `aria-expanded` for the columns it hides.
12
+ */
13
+ const KanbanColumnBandHeader = ({ title, swatch, meta, collapsed, toggleLabel, onCollapsedChange, actions }) => /* @__PURE__ */ jsxs("div", {
14
+ className: cn("flex items-center gap-2 py-2", collapsed ? "flex-col px-1" : "px-3"),
15
+ "data-collapsed": collapsed ? "" : void 0,
16
+ "data-slot": "kanban-column-band-header",
17
+ children: [
18
+ /* @__PURE__ */ jsx("button", {
19
+ "aria-expanded": !collapsed,
20
+ "aria-label": toggleLabel,
21
+ className: "hover:bg-muted/60 text-muted-foreground hover:text-foreground flex size-8 shrink-0 items-center justify-center rounded-md transition-[background-color]",
22
+ onClick: () => onCollapsedChange(!collapsed),
23
+ type: "button",
24
+ children: /* @__PURE__ */ jsx(DirectionalIcon, {
25
+ className: cn("size-4 transition-transform", collapsed && "-rotate-90"),
26
+ flip: collapsed,
27
+ icon: ChevronDownIcon
28
+ })
29
+ }),
30
+ swatch,
31
+ /* @__PURE__ */ jsxs("span", {
32
+ className: cn("flex min-w-0 items-center gap-1.5 text-sm font-medium", collapsed ? "rotate-180 [writing-mode:vertical-rl]" : "flex-1 truncate"),
33
+ children: [title, meta !== void 0 && /* @__PURE__ */ jsx("span", {
34
+ className: "text-muted-foreground text-xs tabular-nums",
35
+ children: meta
36
+ })]
37
+ }),
38
+ collapsed ? null : actions
39
+ ]
40
+ });
41
+ //#endregion
42
+ export { KanbanColumnBandHeader };
@@ -0,0 +1,41 @@
1
+ import { KanbanColumnBand } from "./grouping.js";
2
+ import { KanbanBoardColumn } from "./matrix.js";
3
+ //#region src/kanban/column-bands.d.ts
4
+ /**
5
+ * Column bands: named runs of adjacent columns the board shows under one
6
+ * header and can collapse as a unit.
7
+ *
8
+ * A band is presentation over the column order, never a second axis: cards
9
+ * keep their column, and the matrix stays the placement authority. The board
10
+ * only needs to know which adjacent columns share a header, which is what
11
+ * `resolveKanbanColumnBands` derives from the columns' `band` metadata.
12
+ */
13
+ /** Every board column takes this inline size; a collapsed band takes one lane. */
14
+ declare const KANBAN_COLUMN_WIDTH_CLASS = "w-[300px] shrink-0";
15
+ declare const KANBAN_COLUMN_WIDTH_PX = 300;
16
+ /** The `gap-3` between columns, so a band header can span its columns. */
17
+ declare const KANBAN_COLUMN_GAP_PX = 12;
18
+ /** A collapsed band folds its columns into one narrow lane. */
19
+ declare const KANBAN_COLLAPSED_BAND_WIDTH_CLASS = "w-12 shrink-0";
20
+ declare const KANBAN_COLLAPSED_BAND_WIDTH_PX = 48;
21
+ /**
22
+ * A run of adjacent columns under one header. `band` is `null` for a column
23
+ * that belongs to no band, which renders as a run of one without a header.
24
+ */
25
+ type KanbanColumnBandSpan = {
26
+ band: KanbanColumnBand | null;
27
+ columns: KanbanBoardColumn[];
28
+ };
29
+ /**
30
+ * Group the presented columns into bands, in column order.
31
+ *
32
+ * Bands must be contiguous: the same band id appearing again after a column
33
+ * of another band (or of none) is a programming error in the caller's schema,
34
+ * not a state to render, because a header that spans two separate runs has no
35
+ * meaning. The check fails loudly instead of silently drawing a second header.
36
+ */
37
+ declare const resolveKanbanColumnBands: (columns: readonly KanbanBoardColumn[]) => KanbanColumnBandSpan[];
38
+ /** Whether any presented column carries band metadata. */
39
+ declare const hasKanbanColumnBands: (columns: readonly KanbanBoardColumn[]) => boolean;
40
+ //#endregion
41
+ export { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KanbanColumnBandSpan, hasKanbanColumnBands, resolveKanbanColumnBands };
@@ -0,0 +1,52 @@
1
+ import { getKanbanBoardColumnIdentity } from "./matrix.js";
2
+ import { panic } from "better-result";
3
+ //#region src/kanban/column-bands.ts
4
+ /**
5
+ * Column bands: named runs of adjacent columns the board shows under one
6
+ * header and can collapse as a unit.
7
+ *
8
+ * A band is presentation over the column order, never a second axis: cards
9
+ * keep their column, and the matrix stays the placement authority. The board
10
+ * only needs to know which adjacent columns share a header, which is what
11
+ * `resolveKanbanColumnBands` derives from the columns' `band` metadata.
12
+ */
13
+ /** Every board column takes this inline size; a collapsed band takes one lane. */
14
+ const KANBAN_COLUMN_WIDTH_CLASS = "w-[300px] shrink-0";
15
+ const KANBAN_COLUMN_WIDTH_PX = 300;
16
+ /** The `gap-3` between columns, so a band header can span its columns. */
17
+ const KANBAN_COLUMN_GAP_PX = 12;
18
+ /** A collapsed band folds its columns into one narrow lane. */
19
+ const KANBAN_COLLAPSED_BAND_WIDTH_CLASS = "w-12 shrink-0";
20
+ const KANBAN_COLLAPSED_BAND_WIDTH_PX = 48;
21
+ const bandOf = (column) => column.type === "group" ? column.group.band ?? null : null;
22
+ /**
23
+ * Group the presented columns into bands, in column order.
24
+ *
25
+ * Bands must be contiguous: the same band id appearing again after a column
26
+ * of another band (or of none) is a programming error in the caller's schema,
27
+ * not a state to render, because a header that spans two separate runs has no
28
+ * meaning. The check fails loudly instead of silently drawing a second header.
29
+ */
30
+ const resolveKanbanColumnBands = (columns) => {
31
+ const spans = [];
32
+ const closedBandIds = /* @__PURE__ */ new Set();
33
+ for (const column of columns) {
34
+ const band = bandOf(column);
35
+ const last = spans.at(-1);
36
+ if (band !== null && last?.band?.id === band.id) {
37
+ last.columns.push(column);
38
+ continue;
39
+ }
40
+ if (last?.band !== null && last?.band !== void 0) closedBandIds.add(last.band.id);
41
+ if (band !== null && closedBandIds.has(band.id)) return panic(`Kanban column band "${band.id}" is not contiguous: it resumes at column ${getKanbanBoardColumnIdentity(column)}`);
42
+ spans.push({
43
+ band,
44
+ columns: [column]
45
+ });
46
+ }
47
+ return spans;
48
+ };
49
+ /** Whether any presented column carries band metadata. */
50
+ const hasKanbanColumnBands = (columns) => columns.some((column) => bandOf(column) !== null);
51
+ //#endregion
52
+ export { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, hasKanbanColumnBands, resolveKanbanColumnBands };
@@ -1,5 +1,15 @@
1
1
  import { OptionColor } from "../lib/option-color.js";
2
2
  //#region src/kanban/grouping.d.ts
3
+ /**
4
+ * The band a column belongs to: a named run of adjacent columns the board
5
+ * shows under one header and can collapse as a unit. A status property's
6
+ * option groups ("To do", "In progress", "Done") are the usual source.
7
+ */
8
+ type KanbanColumnBand = {
9
+ id: string;
10
+ label: string;
11
+ optionColor?: OptionColor | undefined;
12
+ };
3
13
  /** One column, before the uncategorized bucket is appended. */
4
14
  type KanbanGroupOption = {
5
15
  value: string;
@@ -8,6 +18,7 @@ type KanbanGroupOption = {
8
18
  color?: string | undefined;
9
19
  colorBg?: string | undefined;
10
20
  optionColor?: OptionColor | undefined;
21
+ band?: KanbanColumnBand | undefined;
11
22
  };
12
23
  /** A column, including the uncategorized bucket (`value: null`). */
13
24
  type KanbanGroup = {
@@ -17,6 +28,7 @@ type KanbanGroup = {
17
28
  color?: string | undefined;
18
29
  colorBg?: string | undefined;
19
30
  optionColor?: OptionColor | undefined;
31
+ band?: KanbanColumnBand | undefined;
20
32
  };
21
33
  /**
22
34
  * A column source that is not a schema property, addressed by a reserved id.
@@ -83,4 +95,4 @@ declare const resolveKanbanGroupOptions: <TRow, TProperty, TGroupId extends stri
83
95
  /** Append the uncategorized bucket (null value) after the options. */
84
96
  declare const getKanbanGroups: (options: readonly KanbanGroupOption[], uncategorizedLabel: string) => KanbanGroup[];
85
97
  //#endregion
86
- export { KanbanBuiltInGroup, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows };
98
+ export { KanbanBuiltInGroup, KanbanColumnBand, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows };
@@ -65,7 +65,8 @@ const getKanbanGroups = (options, uncategorizedLabel) => {
65
65
  image: option.image,
66
66
  color: option.color,
67
67
  colorBg: option.colorBg,
68
- optionColor: option.optionColor
68
+ optionColor: option.optionColor,
69
+ band: option.band
69
70
  }));
70
71
  result.push({
71
72
  value: null,
@@ -1,13 +1,15 @@
1
1
  import { KanbanCardFieldSelection, selectKanbanCardFieldIds } from "./card-properties.js";
2
2
  import { KanbanCardShell, KanbanCardShellProps } from "./card-shell.js";
3
3
  import { KanbanCellAction, KanbanCellActionProps } from "./cell-action.js";
4
+ import { KanbanColumnBandHeader, KanbanColumnBandHeaderProps } from "./column-band-header.js";
5
+ import { KanbanBuiltInGroup, KanbanColumnBand, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./grouping.js";
6
+ import { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardColumn, KanbanBoardCoordinate, KanbanBoardDestination, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./matrix.js";
7
+ import { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KanbanColumnBandSpan, hasKanbanColumnBands, resolveKanbanColumnBands } from "./column-bands.js";
4
8
  import { KanbanColumnHeader, KanbanColumnHeaderProps } from "./column-header.js";
5
9
  import { KANBAN_BOARD_COLLISION_DETECTION, KanbanCellVirtualNavigation, KanbanSortableCellPosition, KanbanVirtualScrollRequest, kanbanKeyboardCoordinates } from "./sortable-interactions.logic.js";
6
10
  import { KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KanbanCardDragSurface, KanbanCardDragSurfaceProps, KanbanDragCancelEvent, KanbanDragEndEvent, KanbanDragHandle, KanbanDragHandleProps, KanbanDragOverEvent, KanbanDragStartEvent, KanbanSortableActivationMode, KanbanSortableBindings, KanbanSortableBoard, KanbanSortableBoardProps, KanbanSortableColumns, KanbanSortableColumnsProps, KanbanSortableList, KanbanSortableListProps, UseKanbanDropTargetOptions, UseKanbanSortableOptions, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors } from "./sortable-interactions.js";
7
11
  import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KanbanDirection, KanbanHorizontalEdge, getKanbanHorizontalEdge } from "./sortable-edge.js";
8
12
  import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, RegisterKanbanBoardAutoScrollOptions, RegisterKanbanCardDragOptions, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./drag-interactions.js";
9
- import { KanbanBuiltInGroup, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./grouping.js";
10
- import { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardColumn, KanbanBoardCoordinate, KanbanBoardDestination, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./matrix.js";
11
- import { KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./subgroup-board.js";
13
+ import { KANBAN_BAND_PEEK_DELAY_MS, KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupCollapsedBandCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./subgroup-board.js";
12
14
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps, KanbanVirtualCellSortableContext } from "./virtual-cell.js";
13
- export { type BuildKanbanBoardMatrixParams, type CreateKanbanDropIntentParams, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBoardAxis, type KanbanBoardCell, type KanbanBoardColumn, type KanbanBoardCoordinate, type KanbanBoardDestination, type KanbanBoardLane, type KanbanBoardMatrix, type KanbanBuiltInGroup, KanbanCardDragSurface, type KanbanCardDragSurfaceProps, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanCellAction, type KanbanCellActionProps, type KanbanCellVirtualNavigation, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, type KanbanDragCancelEvent, type KanbanDragEndEvent, KanbanDragHandle, type KanbanDragHandleProps, type KanbanDragOverEvent, type KanbanDragStartEvent, type KanbanDropAxisChange, type KanbanDropIntent, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableActivationMode, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, type KanbanSortableCellPosition, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, KanbanSubgroupBoard, type KanbanSubgroupBoardProps, type KanbanSubgroupCellContext, type KanbanSubgroupColumnHeaderContext, type KanbanSubgroupLaneIdentityContext, KanbanVirtualCell, type KanbanVirtualCellPagination, type KanbanVirtualCellProps, type KanbanVirtualCellSortableContext, type KanbanVirtualScrollRequest, type OrderKanbanCellsByColumnsParams, type RegisterKanbanBoardAutoScrollOptions, type RegisterKanbanCardDragOptions, type ResolveKanbanGroupValueParams, type ResolveKanbanGroupingParams, type UseKanbanDropTargetOptions, type UseKanbanSortableOptions, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, isKanbanGroupingRenderable, kanbanKeyboardCoordinates, orderKanbanCellsByColumns, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanCardFieldIds, selectKanbanRows, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors };
15
+ export { type BuildKanbanBoardMatrixParams, type CreateKanbanDropIntentParams, KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBoardAxis, type KanbanBoardCell, type KanbanBoardColumn, type KanbanBoardCoordinate, type KanbanBoardDestination, type KanbanBoardLane, type KanbanBoardMatrix, type KanbanBuiltInGroup, KanbanCardDragSurface, type KanbanCardDragSurfaceProps, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanCellAction, type KanbanCellActionProps, type KanbanCellVirtualNavigation, type KanbanColumnBand, KanbanColumnBandHeader, type KanbanColumnBandHeaderProps, type KanbanColumnBandSpan, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, type KanbanDragCancelEvent, type KanbanDragEndEvent, KanbanDragHandle, type KanbanDragHandleProps, type KanbanDragOverEvent, type KanbanDragStartEvent, type KanbanDropAxisChange, type KanbanDropIntent, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableActivationMode, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, type KanbanSortableCellPosition, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, type KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, type KanbanSubgroupBoardProps, type KanbanSubgroupCellContext, type KanbanSubgroupCollapsedBandCellContext, type KanbanSubgroupColumnHeaderContext, type KanbanSubgroupLaneIdentityContext, KanbanVirtualCell, type KanbanVirtualCellPagination, type KanbanVirtualCellProps, type KanbanVirtualCellSortableContext, type KanbanVirtualScrollRequest, type OrderKanbanCellsByColumnsParams, type RegisterKanbanBoardAutoScrollOptions, type RegisterKanbanCardDragOptions, type ResolveKanbanGroupValueParams, type ResolveKanbanGroupingParams, type UseKanbanDropTargetOptions, type UseKanbanSortableOptions, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, hasKanbanColumnBands, isKanbanGroupingRenderable, kanbanKeyboardCoordinates, orderKanbanCellsByColumns, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveKanbanColumnBands, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanCardFieldIds, selectKanbanRows, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors };
@@ -1,13 +1,15 @@
1
1
  import { selectKanbanCardFieldIds } from "./card-properties.js";
2
2
  import { KanbanCardShell } from "./card-shell.js";
3
3
  import { KanbanCellAction } from "./cell-action.js";
4
+ import { KanbanColumnBandHeader } from "./column-band-header.js";
5
+ import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./grouping.js";
6
+ import { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./matrix.js";
7
+ import { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, hasKanbanColumnBands, resolveKanbanColumnBands } from "./column-bands.js";
4
8
  import { KanbanColumnHeader } from "./column-header.js";
5
9
  import { KANBAN_BOARD_COLLISION_DETECTION, kanbanKeyboardCoordinates } from "./sortable-interactions.logic.js";
6
10
  import { KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KanbanCardDragSurface, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors } from "./sortable-interactions.js";
7
11
  import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, getKanbanHorizontalEdge } from "./sortable-edge.js";
8
12
  import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./drag-interactions.js";
9
- import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./grouping.js";
10
- import { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, orderKanbanCellsByColumns } from "./matrix.js";
11
- import { KanbanSubgroupBoard } from "./subgroup-board.js";
13
+ import { KANBAN_BAND_PEEK_DELAY_MS, KanbanSubgroupBoard } from "./subgroup-board.js";
12
14
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell } from "./virtual-cell.js";
13
- export { KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardDragSurface, KanbanCardShell, KanbanCellAction, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, KanbanSubgroupBoard, KanbanVirtualCell, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, isKanbanGroupingRenderable, kanbanKeyboardCoordinates, orderKanbanCellsByColumns, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanCardFieldIds, selectKanbanRows, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors };
15
+ export { KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLLAPSED_BAND_WIDTH_PX, KANBAN_COLUMN_GAP_PX, KANBAN_COLUMN_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_PX, KANBAN_DIRECTIONS, KANBAN_DRAG_OVERLAY_Z_INDEX, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_SORTABLE_ACTIVATION_MODES, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardDragSurface, KanbanCardShell, KanbanCellAction, KanbanColumnBandHeader, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, KanbanSubgroupBoard, KanbanVirtualCell, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanBoardColumnIdentity, getKanbanBoardLaneIdentity, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, hasKanbanColumnBands, isKanbanGroupingRenderable, kanbanKeyboardCoordinates, orderKanbanCellsByColumns, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveKanbanColumnBands, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanCardFieldIds, selectKanbanRows, useKanbanDropTarget, useKanbanSortable, useKanbanSortableSensors };
@@ -1,7 +1,9 @@
1
- import { KanbanGroup } from "./grouping.js";
1
+ import { KanbanColumnBand, KanbanGroup } from "./grouping.js";
2
2
  import { KanbanBoardCell, KanbanBoardColumn, KanbanBoardMatrix } from "./matrix.js";
3
3
  import { ReactNode } from "react";
4
4
  //#region src/kanban/subgroup-board.d.ts
5
+ /** How long a pointer rests on a collapsed band before it peeks open. */
6
+ declare const KANBAN_BAND_PEEK_DELAY_MS = 400;
5
7
  type KanbanSubgroupColumnHeaderContext = {
6
8
  column: KanbanBoardColumn;
7
9
  count: number;
@@ -16,6 +18,25 @@ type KanbanSubgroupCellContext<TRow> = {
16
18
  count: number;
17
19
  laneValue: string | null;
18
20
  };
21
+ type KanbanSubgroupBandHeaderContext = {
22
+ band: KanbanColumnBand;
23
+ columns: KanbanBoardColumn[];
24
+ /** Rows across the band's columns, every lane included. */
25
+ count: number;
26
+ collapsed: boolean;
27
+ onCollapsedChange: (collapsed: boolean) => void;
28
+ };
29
+ /**
30
+ * One lane's slot for a collapsed band: the cells it hides, so a host can
31
+ * register the slot as a drop target that lands in the band's first column
32
+ * (or asks which), and the count it stands in for.
33
+ */
34
+ type KanbanSubgroupCollapsedBandCellContext<TRow> = {
35
+ band: KanbanColumnBand;
36
+ cells: KanbanBoardCell<TRow>[];
37
+ count: number;
38
+ laneValue: string | null;
39
+ };
19
40
  type KanbanSubgroupCollapseControl = {
20
41
  isLaneCollapsed?: undefined;
21
42
  onLaneCollapsedChange?: undefined;
@@ -28,11 +49,38 @@ type KanbanSubgroupBoardProps<TRow> = {
28
49
  renderColumnHeader: (context: KanbanSubgroupColumnHeaderContext) => ReactNode;
29
50
  renderLaneIdentity: (context: KanbanSubgroupLaneIdentityContext) => ReactNode;
30
51
  renderCell: (context: KanbanSubgroupCellContext<TRow>) => ReactNode;
52
+ /**
53
+ * The header above a band's columns. Defaults to `KanbanColumnBandHeader`
54
+ * with the band's label and count.
55
+ */
56
+ renderBandHeader?: ((context: KanbanSubgroupBandHeaderContext) => ReactNode) | undefined;
57
+ /**
58
+ * A lane's slot while its band is collapsed. Defaults to the count alone;
59
+ * a host that accepts drops into a collapsed band renders its target here.
60
+ */
61
+ renderCollapsedBandCell?: ((context: KanbanSubgroupCollapsedBandCellContext<TRow>) => ReactNode) | undefined;
62
+ /** Accessible name for a band's collapse toggle. */
63
+ formatBandToggleLabel?: ((band: KanbanColumnBand, collapsed: boolean) => string) | undefined;
64
+ /**
65
+ * Controlled band collapse. Omit both and the board keeps the collapsed
66
+ * bands itself; a persisted view supplies both.
67
+ */
68
+ isBandCollapsed?: ((band: KanbanColumnBand) => boolean) | undefined;
69
+ onBandCollapsedChange?: ((band: KanbanColumnBand, collapsed: boolean) => void) | undefined;
31
70
  formatCount?: ((count: number) => ReactNode) | undefined;
32
71
  footer?: ReactNode;
33
72
  className?: string | undefined;
34
73
  } & KanbanSubgroupCollapseControl;
35
- /** Reusable swimlane layout over the canonical two-axis Kanban matrix. */
36
- declare const KanbanSubgroupBoard: <TRow>({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, formatCount, isLaneCollapsed, onLaneCollapsedChange, footer, className }: KanbanSubgroupBoardProps<TRow>) => import("react").JSX.Element;
74
+ /**
75
+ * Reusable swimlane layout over the canonical two-axis Kanban matrix.
76
+ *
77
+ * Columns that carry band metadata render under a band header and can be
78
+ * collapsed as a run: the band folds into one narrow slot in every row, whose
79
+ * cells stay reachable (a host renders its drop target in them), and peeks
80
+ * open while a pointer rests on it, so a drag can still land on a specific
81
+ * column inside. Every row is laid out span by span with the same widths,
82
+ * which is what keeps headers, counts, and cells aligned in every state.
83
+ */
84
+ declare const KanbanSubgroupBoard: <TRow>({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, renderBandHeader, renderCollapsedBandCell, formatBandToggleLabel, formatCount, isLaneCollapsed, onLaneCollapsedChange, isBandCollapsed, onBandCollapsedChange, footer, className }: KanbanSubgroupBoardProps<TRow>) => import("react").JSX.Element;
37
85
  //#endregion
38
- export { KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext };
86
+ export { KANBAN_BAND_PEEK_DELAY_MS, KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupCollapsedBandCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext };
@@ -1,15 +1,32 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import { DirectionalIcon } from "../components/directional-icon.js";
3
+ import { KanbanColumnBandHeader } from "./column-band-header.js";
4
+ import { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_CLASS, resolveKanbanColumnBands } from "./column-bands.js";
3
5
  import { ChevronDownIcon } from "lucide-react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
- import { useMemo, useState } from "react";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { useEffect, useMemo, useRef, useState } from "react";
6
8
  //#region src/kanban/subgroup-board.tsx
7
9
  const groupValueKey = (value) => value === null ? "null" : `value:${value.length}:${value}`;
8
10
  const columnKey = (column) => column.type === "group" ? `group:${groupValueKey(column.group.value)}` : `destination:${column.destination.id}`;
9
- /** Reusable swimlane layout over the canonical two-axis Kanban matrix. */
10
- const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, formatCount = String, isLaneCollapsed, onLaneCollapsedChange, footer, className }) => {
11
+ const spanKey = (span) => span.band === null ? `single:${span.columns.map(columnKey).join("|")}` : `band:${span.band.id}`;
12
+ const rowsIn = (cells) => cells.reduce((sum, cell) => sum + cell.rows.length, 0);
13
+ /** How long a pointer rests on a collapsed band before it peeks open. */
14
+ const KANBAN_BAND_PEEK_DELAY_MS = 400;
15
+ /**
16
+ * Reusable swimlane layout over the canonical two-axis Kanban matrix.
17
+ *
18
+ * Columns that carry band metadata render under a band header and can be
19
+ * collapsed as a run: the band folds into one narrow slot in every row, whose
20
+ * cells stay reachable (a host renders its drop target in them), and peeks
21
+ * open while a pointer rests on it, so a drag can still land on a specific
22
+ * column inside. Every row is laid out span by span with the same widths,
23
+ * which is what keeps headers, counts, and cells aligned in every state.
24
+ */
25
+ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, renderBandHeader, renderCollapsedBandCell, formatBandToggleLabel, formatCount = String, isLaneCollapsed, onLaneCollapsedChange, isBandCollapsed, onBandCollapsedChange, footer, className }) => {
11
26
  const [collapsedLaneValues, setCollapsedLaneValues] = useState(() => /* @__PURE__ */ new Set());
12
27
  const [expandedEmptyLaneValues, setExpandedEmptyLaneValues] = useState(() => /* @__PURE__ */ new Set());
28
+ const [collapsedBandIds, setCollapsedBandIds] = useState(() => /* @__PURE__ */ new Set());
29
+ const [peekingBandId, setPeekingBandId] = useState(null);
13
30
  const { cellsByLaneValue, countByColumnValue, ungroupedCells } = useMemo(() => {
14
31
  const laneCells = /* @__PURE__ */ new Map();
15
32
  const columnCounts = /* @__PURE__ */ new Map();
@@ -32,6 +49,8 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
32
49
  ungroupedCells: cellsWithoutLane
33
50
  };
34
51
  }, [matrix.cells]);
52
+ const spans = useMemo(() => resolveKanbanColumnBands(matrix.columns), [matrix.columns]);
53
+ const hasBands = spans.some((span) => span.band !== null);
35
54
  const setLaneCollapsed = (group, count, collapsed) => {
36
55
  if (onLaneCollapsedChange) {
37
56
  onLaneCollapsedChange(group, collapsed);
@@ -54,39 +73,157 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
54
73
  return next;
55
74
  });
56
75
  };
76
+ const isBandFolded = (band) => {
77
+ if (peekingBandId === band.id) return false;
78
+ return isBandCollapsed ? isBandCollapsed(band) : collapsedBandIds.has(band.id);
79
+ };
80
+ const setBandCollapsed = (band, collapsed) => {
81
+ setPeekingBandId(null);
82
+ if (onBandCollapsedChange) {
83
+ onBandCollapsedChange(band, collapsed);
84
+ return;
85
+ }
86
+ setCollapsedBandIds((current) => {
87
+ const next = new Set(current);
88
+ if (collapsed) next.add(band.id);
89
+ else next.delete(band.id);
90
+ return next;
91
+ });
92
+ };
93
+ const endPeek = () => setPeekingBandId(null);
94
+ const columnCount = (column) => countByColumnValue.get(columnKey(column)) ?? 0;
95
+ const cellsOf = (span, cells) => span.columns.flatMap((column) => cells.filter((cell) => columnKey(cell.coordinate.column) === columnKey(column)));
96
+ const spanWidth = (span) => span.columns.length * 300 + (span.columns.length - 1) * 12;
97
+ /**
98
+ * One row of the board, span by span. A folded band takes one narrow slot
99
+ * in every row; an open span lays its columns out at the column width.
100
+ */
101
+ const renderRow = ({ className: rowClassName, label, renderColumn, renderFoldedBand }) => /* @__PURE__ */ jsx("div", {
102
+ "aria-label": label,
103
+ className: cn("flex gap-3", rowClassName),
104
+ children: spans.map((span) => {
105
+ const band = span.band;
106
+ if (band !== null && isBandFolded(band)) return /* @__PURE__ */ jsx(FoldedBandSlot, {
107
+ band,
108
+ className: KANBAN_COLLAPSED_BAND_WIDTH_CLASS,
109
+ onPeek: setPeekingBandId,
110
+ onPeekEnd: endPeek,
111
+ children: renderFoldedBand(band, span)
112
+ }, spanKey(span));
113
+ return /* @__PURE__ */ jsx("div", {
114
+ className: "flex gap-3",
115
+ "data-kanban-band": band?.id,
116
+ onPointerLeave: band !== null && peekingBandId === band.id ? endPeek : void 0,
117
+ children: span.columns.map((column) => /* @__PURE__ */ jsx("div", {
118
+ className: KANBAN_COLUMN_WIDTH_CLASS,
119
+ children: renderColumn(column)
120
+ }, columnKey(column)))
121
+ }, spanKey(span));
122
+ })
123
+ });
124
+ const bandHeader = (band, span) => {
125
+ const collapsed = isBandFolded(band);
126
+ const context = {
127
+ band,
128
+ collapsed,
129
+ columns: span.columns,
130
+ count: span.columns.reduce((sum, column) => sum + columnCount(column), 0),
131
+ onCollapsedChange: (next) => setBandCollapsed(band, next)
132
+ };
133
+ if (renderBandHeader) return /* @__PURE__ */ jsx(Fragment, { children: renderBandHeader(context) });
134
+ return /* @__PURE__ */ jsx(KanbanColumnBandHeader, {
135
+ collapsed,
136
+ meta: formatCount(context.count),
137
+ title: band.label,
138
+ toggleLabel: formatBandToggleLabel ? formatBandToggleLabel(band, collapsed) : band.label,
139
+ onCollapsedChange: context.onCollapsedChange
140
+ });
141
+ };
142
+ const foldedCell = (band, span, cells, laneValue) => {
143
+ const bandCells = cellsOf(span, cells);
144
+ const count = rowsIn(bandCells);
145
+ if (renderCollapsedBandCell) return /* @__PURE__ */ jsx(Fragment, { children: renderCollapsedBandCell({
146
+ band,
147
+ cells: bandCells,
148
+ count,
149
+ laneValue
150
+ }) });
151
+ return /* @__PURE__ */ jsx("div", {
152
+ className: "text-muted-foreground flex justify-center px-1 py-2 text-xs tabular-nums",
153
+ "data-kanban-collapsed-band-count": count,
154
+ children: formatCount(count)
155
+ });
156
+ };
157
+ const foldedCount = (span, cells) => {
158
+ const count = rowsIn(cellsOf(span, cells));
159
+ return /* @__PURE__ */ jsx("div", {
160
+ className: "flex justify-center",
161
+ "data-kanban-lane-column-count": count,
162
+ children: /* @__PURE__ */ jsx("span", {
163
+ className: "text-muted-foreground text-xs tabular-nums",
164
+ children: formatCount(count)
165
+ })
166
+ });
167
+ };
57
168
  return /* @__PURE__ */ jsx("div", {
58
169
  className: cn("h-full overflow-auto px-4 pb-4", className),
59
170
  children: /* @__PURE__ */ jsxs("div", {
60
171
  className: "min-w-max",
61
172
  children: [
62
- /* @__PURE__ */ jsx("div", {
63
- className: "bg-background sticky top-0 z-20 flex gap-3 pt-4 pb-3",
64
- children: matrix.columns.map((column) => /* @__PURE__ */ jsx("div", {
65
- className: "w-[300px] shrink-0",
66
- children: renderColumnHeader({
67
- column,
68
- count: countByColumnValue.get(columnKey(column)) ?? 0
173
+ /* @__PURE__ */ jsxs("div", {
174
+ className: "bg-background sticky top-0 z-20 pt-4 pb-3",
175
+ children: [hasBands ? /* @__PURE__ */ jsx("div", {
176
+ className: "flex gap-3 pb-2",
177
+ "data-kanban-band-row": "",
178
+ children: spans.map((span) => {
179
+ const band = span.band;
180
+ if (band === null) return /* @__PURE__ */ jsx("div", {
181
+ className: "shrink-0",
182
+ style: { width: `${String(spanWidth(span))}px` }
183
+ }, spanKey(span));
184
+ if (isBandFolded(band)) return /* @__PURE__ */ jsx(FoldedBandSlot, {
185
+ band,
186
+ className: cn("border-border/60 bg-muted/40 rounded-lg border", KANBAN_COLLAPSED_BAND_WIDTH_CLASS),
187
+ onPeek: setPeekingBandId,
188
+ onPeekEnd: endPeek,
189
+ children: bandHeader(band, span)
190
+ }, spanKey(span));
191
+ return /* @__PURE__ */ jsx("div", {
192
+ className: "border-border/60 bg-muted/40 shrink-0 rounded-lg border",
193
+ "data-kanban-band": band.id,
194
+ style: { width: `${String(spanWidth(span))}px` },
195
+ onPointerLeave: peekingBandId === band.id ? endPeek : void 0,
196
+ children: bandHeader(band, span)
197
+ }, spanKey(span));
69
198
  })
70
- }, columnKey(column)))
199
+ }) : null, renderRow({
200
+ renderColumn: (column) => /* @__PURE__ */ jsx(Fragment, { children: renderColumnHeader({
201
+ column,
202
+ count: columnCount(column)
203
+ }) }),
204
+ renderFoldedBand: () => null
205
+ })]
71
206
  }),
72
- ungroupedCells.length === 0 ? null : /* @__PURE__ */ jsx("div", {
73
- className: "flex gap-3 pb-1",
74
- children: ungroupedCells.map((cell) => /* @__PURE__ */ jsx("div", {
75
- className: "w-[300px] shrink-0",
76
- children: renderCell({
207
+ ungroupedCells.length === 0 ? null : renderRow({
208
+ className: "pb-1",
209
+ renderColumn: (column) => {
210
+ const cell = ungroupedCells.find((candidate) => columnKey(candidate.coordinate.column) === columnKey(column));
211
+ return cell === void 0 ? null : /* @__PURE__ */ jsx(Fragment, { children: renderCell({
77
212
  cell,
78
213
  count: cell.rows.length,
79
214
  laneValue: null
80
- })
81
- }, columnKey(cell.coordinate.column)))
215
+ }) });
216
+ },
217
+ renderFoldedBand: (band, span) => foldedCell(band, span, ungroupedCells, null)
82
218
  }),
83
219
  matrix.lanes.map((lane) => {
84
220
  if (lane.type === "none") return null;
85
221
  const { group } = lane;
86
222
  const cells = cellsByLaneValue.get(group.value) ?? [];
87
- const count = cells.reduce((sum, cell) => sum + cell.rows.length, 0);
223
+ const count = rowsIn(cells);
88
224
  const defaultCollapsed = count === 0 ? !expandedEmptyLaneValues.has(group.value) : collapsedLaneValues.has(group.value);
89
225
  const collapsed = isLaneCollapsed ? isLaneCollapsed(group, count) : defaultCollapsed;
226
+ const cellFor = (column) => cells.find((candidate) => columnKey(candidate.coordinate.column) === columnKey(column));
90
227
  return /* @__PURE__ */ jsxs("section", {
91
228
  className: "border-border/60 border-b py-2 first:pt-0 last:border-b-0",
92
229
  children: [
@@ -114,28 +251,32 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
114
251
  ]
115
252
  })
116
253
  }),
117
- /* @__PURE__ */ jsx("div", {
118
- className: "flex gap-3",
119
- "aria-label": "Lane column counts",
120
- children: cells.map((cell) => /* @__PURE__ */ jsx("div", {
121
- className: "w-[300px] shrink-0 px-3",
122
- "data-kanban-lane-column-count": cell.rows.length,
123
- children: /* @__PURE__ */ jsx("span", {
124
- className: "text-muted-foreground text-xs tabular-nums",
125
- children: formatCount(cell.rows.length)
126
- })
127
- }, columnKey(cell.coordinate.column)))
254
+ renderRow({
255
+ label: "Lane column counts",
256
+ renderColumn: (column) => {
257
+ const columnRows = cellFor(column)?.rows.length ?? 0;
258
+ return /* @__PURE__ */ jsx("div", {
259
+ className: "px-3",
260
+ "data-kanban-lane-column-count": columnRows,
261
+ children: /* @__PURE__ */ jsx("span", {
262
+ className: "text-muted-foreground text-xs tabular-nums",
263
+ children: formatCount(columnRows)
264
+ })
265
+ });
266
+ },
267
+ renderFoldedBand: (_band, span) => foldedCount(span, cells)
128
268
  }),
129
- !collapsed && /* @__PURE__ */ jsx("div", {
130
- className: "flex gap-3 pb-1",
131
- children: cells.map((cell) => /* @__PURE__ */ jsx("div", {
132
- className: "w-[300px] shrink-0",
133
- children: renderCell({
269
+ !collapsed && renderRow({
270
+ className: "pb-1",
271
+ renderColumn: (column) => {
272
+ const cell = cellFor(column);
273
+ return cell === void 0 ? null : /* @__PURE__ */ jsx(Fragment, { children: renderCell({
134
274
  cell,
135
275
  count: cell.rows.length,
136
276
  laneValue: group.value
137
- })
138
- }, columnKey(cell.coordinate.column)))
277
+ }) });
278
+ },
279
+ renderFoldedBand: (band, span) => foldedCell(band, span, cells, group.value)
139
280
  })
140
281
  ]
141
282
  }, groupValueKey(group.value));
@@ -145,5 +286,36 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
145
286
  })
146
287
  });
147
288
  };
289
+ /**
290
+ * The narrow slot a folded band occupies in a row. A pointer resting on it
291
+ * for `KANBAN_BAND_PEEK_DELAY_MS` peeks the band open; leaving ends the peek
292
+ * and cancels a pending one, so a drag passing over it does not unfold it.
293
+ */
294
+ const FoldedBandSlot = ({ band, children, className, onPeek, onPeekEnd }) => {
295
+ const timer = useRef(null);
296
+ useEffect(() => () => {
297
+ if (timer.current !== null) clearTimeout(timer.current);
298
+ }, []);
299
+ return /* @__PURE__ */ jsx("div", {
300
+ className,
301
+ "data-kanban-band": band.id,
302
+ "data-kanban-band-collapsed": "",
303
+ onPointerEnter: () => {
304
+ if (timer.current !== null) clearTimeout(timer.current);
305
+ timer.current = setTimeout(() => {
306
+ timer.current = null;
307
+ onPeek(band.id);
308
+ }, 400);
309
+ },
310
+ onPointerLeave: () => {
311
+ if (timer.current !== null) {
312
+ clearTimeout(timer.current);
313
+ timer.current = null;
314
+ }
315
+ onPeekEnd();
316
+ },
317
+ children
318
+ });
319
+ };
148
320
  //#endregion
149
- export { KanbanSubgroupBoard };
321
+ export { KANBAN_BAND_PEEK_DELAY_MS, KanbanSubgroupBoard };
@@ -5,6 +5,6 @@ declare const CONTROL_SIZE: Readonly<{
5
5
  readonly lg: "lg";
6
6
  }>;
7
7
  type ControlSize = (typeof CONTROL_SIZE)[keyof typeof CONTROL_SIZE];
8
- declare const CONTROL_SIZES: readonly ("default" | "lg" | "sm")[];
8
+ declare const CONTROL_SIZES: readonly ("sm" | "default" | "lg")[];
9
9
  //#endregion
10
10
  export { CONTROL_SIZE, CONTROL_SIZES, type ControlSize };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/ui",
3
- "version": "0.16.1",
3
+ "version": "0.17.0",
4
4
  "description": "Stella's design system: bidi-aware React primitives built on Base UI, the dockable inspector pane, and the Tailwind v4 theme they are styled with.",
5
5
  "keywords": [
6
6
  "base-ui",