@stll/ui 0.8.0 → 0.9.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 +41 -5
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/kanban/grouping.d.ts +2 -0
- package/dist/kanban/grouping.js +1 -0
- package/dist/kanban/index.d.ts +4 -1
- package/dist/kanban/index.js +4 -1
- package/dist/kanban/matrix.d.ts +85 -0
- package/dist/kanban/matrix.js +121 -0
- package/dist/kanban/subgroup-board.d.ts +36 -0
- package/dist/kanban/subgroup-board.js +115 -0
- package/dist/kanban/virtual-cell.d.ts +33 -0
- package/dist/kanban/virtual-cell.js +58 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ cannot reach into product code by accident. Lint enforces that boundary; the
|
|
|
11
11
|
export map below is what "part of the design system" means.
|
|
12
12
|
|
|
13
13
|
Peer dependencies: `react`, `react-dom`, `@base-ui/react`, `tailwindcss` (v4),
|
|
14
|
-
`@dnd-kit/core`,
|
|
14
|
+
`@dnd-kit/core`, `@dnd-kit/sortable`, and `@tanstack/react-virtual`.
|
|
15
15
|
|
|
16
16
|
## Import
|
|
17
17
|
|
|
@@ -58,10 +58,11 @@ spellings land on the same module for as long as they both exist.
|
|
|
58
58
|
|
|
59
59
|
## Sortable boards
|
|
60
60
|
|
|
61
|
-
`@stll/ui/kanban` provides
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
`@stll/ui/kanban` provides board matrices, subgroup swimlanes, bounded virtual
|
|
62
|
+
cells, and input/accessibility primitives. The caller keeps domain identifiers,
|
|
63
|
+
card rendering, permissions, and persisted mutations. Wrap sortable boards in
|
|
64
|
+
`KanbanSortableBoard`, render items through `useKanbanSortable`, and attach the
|
|
65
|
+
returned bindings to `KanbanDragHandle`.
|
|
65
66
|
|
|
66
67
|
```tsx
|
|
67
68
|
import {
|
|
@@ -100,6 +101,41 @@ auto-scroll options, and an `overlay` render function.
|
|
|
100
101
|
`input: "keyboard"` and require source and target indices, so every move has a
|
|
101
102
|
logical edge without relying on ambiguous geometry.
|
|
102
103
|
|
|
104
|
+
For Group/Sub-group boards, build one canonical matrix and render it with the
|
|
105
|
+
installable layout and virtual cell:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import {
|
|
109
|
+
KanbanSubgroupBoard,
|
|
110
|
+
KanbanVirtualCell,
|
|
111
|
+
buildKanbanBoardMatrix,
|
|
112
|
+
} from "@stll/ui/kanban";
|
|
113
|
+
|
|
114
|
+
const matrix = buildKanbanBoardMatrix({
|
|
115
|
+
group,
|
|
116
|
+
subgroup,
|
|
117
|
+
rows,
|
|
118
|
+
resolveGroupValue,
|
|
119
|
+
uncategorizedLabel: "No value",
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
<KanbanSubgroupBoard
|
|
123
|
+
matrix={matrix}
|
|
124
|
+
renderColumnHeader={({ column, count }) => (
|
|
125
|
+
<ColumnHeader column={column} count={count} />
|
|
126
|
+
)}
|
|
127
|
+
renderLaneIdentity={({ group: lane }) => <Lane group={lane} />}
|
|
128
|
+
renderCell={({ cell }) => (
|
|
129
|
+
<KanbanVirtualCell
|
|
130
|
+
getRowKey={(row) => row.id}
|
|
131
|
+
pagination={{ type: "none" }}
|
|
132
|
+
renderRow={(row) => <Card row={row} />}
|
|
133
|
+
rows={cell.rows}
|
|
134
|
+
/>
|
|
135
|
+
)}
|
|
136
|
+
/>;
|
|
137
|
+
```
|
|
138
|
+
|
|
103
139
|
## Styles
|
|
104
140
|
|
|
105
141
|
No compiled CSS ships. The components carry Tailwind class names, so the
|
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,9 @@ import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KanbanDirection, KanbanHori
|
|
|
75
75
|
import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, RegisterKanbanBoardAutoScrollOptions, RegisterKanbanCardDragOptions, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./kanban/drag-interactions.js";
|
|
76
76
|
import { ColorVariants, OptionColor, emptyColor, optionColors, resolveOptionColor } from "./lib/option-color.js";
|
|
77
77
|
import { KanbanBuiltInGroup, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./kanban/grouping.js";
|
|
78
|
+
import { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardCoordinate, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, orderKanbanCellsByColumns } from "./kanban/matrix.js";
|
|
79
|
+
import { KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./kanban/subgroup-board.js";
|
|
80
|
+
import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps } from "./kanban/virtual-cell.js";
|
|
78
81
|
import "./kanban/index.js";
|
|
79
82
|
import { getInitials } from "./lib/initials.js";
|
|
80
83
|
import { cn, composeRefs } from "./lib/utils.js";
|
|
@@ -86,4 +89,4 @@ import { ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffSegment, ReviewDiffS
|
|
|
86
89
|
import { ReviewOutOfDateNotice, ReviewOutOfDateReason, ReviewOutOfDateTone } from "./review/review-out-of-date-notice.js";
|
|
87
90
|
import { ReviewStatusBadge, ReviewStatusSize, ReviewStatusTone, ReviewStatusVariant } from "./review/review-status-badge.js";
|
|
88
91
|
import { ReviewSeverityDot, ReviewSeverityLevel, ReviewStatusDot, reviewSeverityTone } from "./review/review-severity-dot.js";
|
|
89
|
-
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, ApplicationShell, type ApplicationShellProps, Avatar, AvatarFallback, AvatarImage, type BidiDirection, BidiText, type BidiTextProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, 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, 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_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, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, type KanbanBuiltInGroup, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, KanbanDragHandle, type KanbanDragHandleProps, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, Label, MenuPreviewLayout, OVERLAY_LAYER_CLASS_NAMES, OptionColor, 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 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 UseKanbanSortableOptions, UserText, assertConsecutiveCalendarDates, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, layoutResourceCalendarEntries, nextCalendarDate, optionColors, 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, 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, ApplicationShell, type ApplicationShellProps, Avatar, AvatarFallback, AvatarImage, 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_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, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBoardAxis, type KanbanBoardCell, type KanbanBoardCoordinate, type KanbanBoardLane, type KanbanBoardMatrix, type KanbanBuiltInGroup, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, KanbanDragHandle, type KanbanDragHandleProps, type KanbanDropAxisChange, type KanbanDropIntent, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, KanbanSubgroupBoard, type KanbanSubgroupBoardProps, type KanbanSubgroupCellContext, type KanbanSubgroupColumnHeaderContext, type KanbanSubgroupLaneIdentityContext, KanbanVirtualCell, type KanbanVirtualCellPagination, type KanbanVirtualCellProps, 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 UseKanbanSortableOptions, UserText, assertConsecutiveCalendarDates, buildKanbanBoardMatrix, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, createKanbanDropIntent, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, 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, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
|
package/dist/index.js
CHANGED
|
@@ -73,6 +73,9 @@ import { KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, K
|
|
|
73
73
|
import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, getKanbanHorizontalEdge } from "./kanban/sortable-edge.js";
|
|
74
74
|
import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./kanban/drag-interactions.js";
|
|
75
75
|
import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./kanban/grouping.js";
|
|
76
|
+
import { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, orderKanbanCellsByColumns } from "./kanban/matrix.js";
|
|
77
|
+
import { KanbanSubgroupBoard } from "./kanban/subgroup-board.js";
|
|
78
|
+
import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell } from "./kanban/virtual-cell.js";
|
|
76
79
|
import { getInitials } from "./lib/initials.js";
|
|
77
80
|
import { emptyColor, optionColors, resolveOptionColor } from "./lib/option-color.js";
|
|
78
81
|
import { ReviewAuthorAvatar, UNKNOWN_AUTHOR_LABEL } from "./review/review-author-avatar.js";
|
|
@@ -82,4 +85,4 @@ import { ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffText, TRACKED_DELETI
|
|
|
82
85
|
import { ReviewOutOfDateNotice } from "./review/review-out-of-date-notice.js";
|
|
83
86
|
import { ReviewSeverityDot, ReviewStatusDot, reviewSeverityTone } from "./review/review-severity-dot.js";
|
|
84
87
|
import { ReviewStatusBadge } from "./review/review-status-badge.js";
|
|
85
|
-
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, ApplicationShell, Avatar, AvatarFallback, AvatarImage, 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_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, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KanbanCardShell, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, 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, assertConsecutiveCalendarDates, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, layoutResourceCalendarEntries, nextCalendarDate, optionColors, 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, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
|
|
88
|
+
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, ApplicationShell, Avatar, AvatarFallback, AvatarImage, 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_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, InspectorRailIconButton, InspectorRailTab, InspectorSection, InspectorSectionTitle, InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs, InspectorTitle, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardShell, 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, assertConsecutiveCalendarDates, buildKanbanBoardMatrix, buttonAccessibleDisabledClass, buttonVariants, cn, composeRefs, containedEventHandler, containedHandler, contentDir, createKanbanDropIntent, duplicateColumnIds, emptyColor, findTableColumn, getFirstWeekday, getInitials, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, getLocaleWeekInfo, getResourceCalendarPlacement, getWeekendDays, hideableColumnIds, isKanbanGroupingRenderable, isStructuredInputType, 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, useKanbanSortable, useKanbanSortableSensors, useLatest, useViewportWidth, visibleColumnIds };
|
|
@@ -4,6 +4,7 @@ import { OptionColor } from "../lib/option-color.js";
|
|
|
4
4
|
type KanbanGroupOption = {
|
|
5
5
|
value: string;
|
|
6
6
|
label: string;
|
|
7
|
+
image?: string | null | undefined;
|
|
7
8
|
color?: string | undefined;
|
|
8
9
|
colorBg?: string | undefined;
|
|
9
10
|
optionColor?: OptionColor | undefined;
|
|
@@ -12,6 +13,7 @@ type KanbanGroupOption = {
|
|
|
12
13
|
type KanbanGroup = {
|
|
13
14
|
value: string | null;
|
|
14
15
|
label: string;
|
|
16
|
+
image?: string | null | undefined;
|
|
15
17
|
color?: string | undefined;
|
|
16
18
|
colorBg?: string | undefined;
|
|
17
19
|
optionColor?: OptionColor | undefined;
|
package/dist/kanban/grouping.js
CHANGED
|
@@ -62,6 +62,7 @@ const getKanbanGroups = (options, uncategorizedLabel) => {
|
|
|
62
62
|
const result = options.map((option) => ({
|
|
63
63
|
value: option.value,
|
|
64
64
|
label: option.label,
|
|
65
|
+
image: option.image,
|
|
65
66
|
color: option.color,
|
|
66
67
|
colorBg: option.colorBg,
|
|
67
68
|
optionColor: option.optionColor
|
package/dist/kanban/index.d.ts
CHANGED
|
@@ -5,4 +5,7 @@ import { KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, K
|
|
|
5
5
|
import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KanbanDirection, KanbanHorizontalEdge, getKanbanHorizontalEdge } from "./sortable-edge.js";
|
|
6
6
|
import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, RegisterKanbanBoardAutoScrollOptions, RegisterKanbanCardDragOptions, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./drag-interactions.js";
|
|
7
7
|
import { KanbanBuiltInGroup, KanbanGroup, KanbanGroupOption, KanbanGrouping, KanbanSchema, ResolveKanbanGroupingParams, getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./grouping.js";
|
|
8
|
-
|
|
8
|
+
import { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardCoordinate, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, orderKanbanCellsByColumns } from "./matrix.js";
|
|
9
|
+
import { KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./subgroup-board.js";
|
|
10
|
+
import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps } from "./virtual-cell.js";
|
|
11
|
+
export { type BuildKanbanBoardMatrixParams, type CreateKanbanDropIntentParams, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBoardAxis, type KanbanBoardCell, type KanbanBoardCoordinate, type KanbanBoardLane, type KanbanBoardMatrix, type KanbanBuiltInGroup, type KanbanCardFieldSelection, KanbanCardShell, type KanbanCardShellProps, KanbanColumnHeader, type KanbanColumnHeaderProps, type KanbanDirection, KanbanDragHandle, type KanbanDragHandleProps, type KanbanDropAxisChange, type KanbanDropIntent, type KanbanGroup, type KanbanGroupOption, type KanbanGrouping, type KanbanHorizontalEdge, type KanbanSchema, type KanbanSortableBindings, KanbanSortableBoard, type KanbanSortableBoardProps, KanbanSortableColumns, type KanbanSortableColumnsProps, KanbanSortableList, type KanbanSortableListProps, KanbanSubgroupBoard, type KanbanSubgroupBoardProps, type KanbanSubgroupCellContext, type KanbanSubgroupColumnHeaderContext, type KanbanSubgroupLaneIdentityContext, KanbanVirtualCell, type KanbanVirtualCellPagination, type KanbanVirtualCellProps, type OrderKanbanCellsByColumnsParams, type RegisterKanbanBoardAutoScrollOptions, type RegisterKanbanCardDragOptions, type ResolveKanbanGroupValueParams, type ResolveKanbanGroupingParams, type UseKanbanSortableOptions, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, isKanbanGroupingRenderable, orderKanbanCellsByColumns, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanCardFieldIds, selectKanbanRows, useKanbanSortable, useKanbanSortableSensors };
|
package/dist/kanban/index.js
CHANGED
|
@@ -5,4 +5,7 @@ import { KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, K
|
|
|
5
5
|
import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, getKanbanHorizontalEdge } from "./sortable-edge.js";
|
|
6
6
|
import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./drag-interactions.js";
|
|
7
7
|
import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanRows } from "./grouping.js";
|
|
8
|
-
|
|
8
|
+
import { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, orderKanbanCellsByColumns } from "./matrix.js";
|
|
9
|
+
import { KanbanSubgroupBoard } from "./subgroup-board.js";
|
|
10
|
+
import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell } from "./virtual-cell.js";
|
|
11
|
+
export { KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KANBAN_MOUSE_ACTIVATION_DISTANCE, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardShell, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, KanbanSubgroupBoard, KanbanVirtualCell, buildKanbanBoardMatrix, createKanbanDropIntent, getKanbanGroupingPropertyId, getKanbanGroups, getKanbanHorizontalEdge, isKanbanGroupingRenderable, orderKanbanCellsByColumns, registerKanbanBoardAutoScroll, registerKanbanCardDrag, resolveKanbanGroupOptions, resolveKanbanGrouping, selectKanbanCardFieldIds, selectKanbanRows, useKanbanSortable, useKanbanSortableSensors };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { KanbanGroup, KanbanGrouping } from "./grouping.js";
|
|
2
|
+
//#region src/kanban/matrix.d.ts
|
|
3
|
+
/** Which axis of a board a grouping controls. */
|
|
4
|
+
declare const KANBAN_BOARD_AXES: {
|
|
5
|
+
readonly group: "group";
|
|
6
|
+
readonly subgroup: "subgroup";
|
|
7
|
+
};
|
|
8
|
+
type KanbanBoardAxis = (typeof KANBAN_BOARD_AXES)[keyof typeof KANBAN_BOARD_AXES];
|
|
9
|
+
/** The optional horizontal swimlane dimension is intentionally explicit. */
|
|
10
|
+
type KanbanBoardLane = {
|
|
11
|
+
type: "none";
|
|
12
|
+
} | {
|
|
13
|
+
group: KanbanGroup;
|
|
14
|
+
type: "group";
|
|
15
|
+
};
|
|
16
|
+
type KanbanBoardCoordinate = {
|
|
17
|
+
column: KanbanGroup;
|
|
18
|
+
lane: KanbanBoardLane;
|
|
19
|
+
};
|
|
20
|
+
type KanbanBoardCell<TRow> = {
|
|
21
|
+
coordinate: KanbanBoardCoordinate;
|
|
22
|
+
rows: TRow[];
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The full, ordered cartesian board. Presentation may hide or collapse parts
|
|
26
|
+
* of it, but it must not derive cards independently: every board row is in
|
|
27
|
+
* exactly one cell here before that presentation step.
|
|
28
|
+
*/
|
|
29
|
+
type KanbanBoardMatrix<TRow> = {
|
|
30
|
+
cells: KanbanBoardCell<TRow>[];
|
|
31
|
+
columns: KanbanGroup[];
|
|
32
|
+
lanes: KanbanBoardLane[];
|
|
33
|
+
rows: TRow[];
|
|
34
|
+
};
|
|
35
|
+
type ResolveKanbanGroupValueParams<TRow, TProperty> = {
|
|
36
|
+
grouping: KanbanGrouping<TRow, TProperty>;
|
|
37
|
+
row: TRow;
|
|
38
|
+
};
|
|
39
|
+
type BuildKanbanBoardMatrixParams<TRow, TProperty> = {
|
|
40
|
+
/** The vertical board columns. This must be a renderable grouping. */
|
|
41
|
+
group: KanbanGrouping<TRow, TProperty>;
|
|
42
|
+
/** Optional horizontal swimlanes. `none` makes this a one-lane board. */
|
|
43
|
+
subgroup: KanbanGrouping<TRow, TProperty>;
|
|
44
|
+
rows: readonly TRow[];
|
|
45
|
+
uncategorizedLabel: string;
|
|
46
|
+
resolveGroupValue: (params: ResolveKanbanGroupValueParams<TRow, TProperty>) => string | null;
|
|
47
|
+
};
|
|
48
|
+
type OrderKanbanCellsByColumnsParams<TRow> = {
|
|
49
|
+
cells: readonly KanbanBoardCell<TRow>[];
|
|
50
|
+
columns: readonly KanbanGroup[];
|
|
51
|
+
};
|
|
52
|
+
/** Apply the visible header order to any lane's cells. */
|
|
53
|
+
declare const orderKanbanCellsByColumns: <TRow>({ cells, columns }: OrderKanbanCellsByColumnsParams<TRow>) => KanbanBoardCell<TRow>[];
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the board's one source of placement truth.
|
|
56
|
+
*
|
|
57
|
+
* A subgroup never filters the primary board scope. A row outside a subgroup's
|
|
58
|
+
* declared values goes to its explicit No value lane, rather than disappearing.
|
|
59
|
+
*/
|
|
60
|
+
declare const buildKanbanBoardMatrix: <TRow, TProperty>({ group, subgroup, rows, uncategorizedLabel, resolveGroupValue }: BuildKanbanBoardMatrixParams<TRow, TProperty>) => KanbanBoardMatrix<TRow>;
|
|
61
|
+
type KanbanDropAxisChange = {
|
|
62
|
+
groupBy: string;
|
|
63
|
+
value: string | null;
|
|
64
|
+
};
|
|
65
|
+
/** A complete, atomic move request for a domain mutation adapter. */
|
|
66
|
+
type KanbanDropIntent<TCardId> = {
|
|
67
|
+
cardId: TCardId;
|
|
68
|
+
changes: readonly KanbanDropAxisChange[];
|
|
69
|
+
type: "move";
|
|
70
|
+
};
|
|
71
|
+
type CreateKanbanDropIntentParams<TRow, TProperty, TCardId> = {
|
|
72
|
+
cardId: TCardId;
|
|
73
|
+
group: KanbanGrouping<TRow, TProperty>;
|
|
74
|
+
source: KanbanBoardCoordinate;
|
|
75
|
+
subgroup: KanbanGrouping<TRow, TProperty>;
|
|
76
|
+
target: KanbanBoardCoordinate;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Builds a single mutation payload for a pointer, touch, or keyboard drop.
|
|
80
|
+
* Diagonal drops carry both changes together; an adapter must commit this
|
|
81
|
+
* intent atomically or reject it as a whole.
|
|
82
|
+
*/
|
|
83
|
+
declare const createKanbanDropIntent: <TRow, TProperty, TCardId>({ cardId, group, source, subgroup, target }: CreateKanbanDropIntentParams<TRow, TProperty, TCardId>) => KanbanDropIntent<TCardId> | null;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { BuildKanbanBoardMatrixParams, CreateKanbanDropIntentParams, KANBAN_BOARD_AXES, KanbanBoardAxis, KanbanBoardCell, KanbanBoardCoordinate, KanbanBoardLane, KanbanBoardMatrix, KanbanDropAxisChange, KanbanDropIntent, OrderKanbanCellsByColumnsParams, ResolveKanbanGroupValueParams, buildKanbanBoardMatrix, createKanbanDropIntent, orderKanbanCellsByColumns };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { getKanbanGroupingPropertyId, getKanbanGroups, isKanbanGroupingRenderable, resolveKanbanGroupOptions, selectKanbanRows } from "./grouping.js";
|
|
2
|
+
import { panic } from "better-result";
|
|
3
|
+
//#region src/kanban/matrix.ts
|
|
4
|
+
/** Which axis of a board a grouping controls. */
|
|
5
|
+
const KANBAN_BOARD_AXES = {
|
|
6
|
+
group: "group",
|
|
7
|
+
subgroup: "subgroup"
|
|
8
|
+
};
|
|
9
|
+
const optionValueKey = (value) => value === null ? "null" : `string:${value.length}:${value}`;
|
|
10
|
+
/** Apply the visible header order to any lane's cells. */
|
|
11
|
+
const orderKanbanCellsByColumns = ({ cells, columns }) => {
|
|
12
|
+
const orderByValue = new Map(columns.map((column, index) => [optionValueKey(column.value), index]));
|
|
13
|
+
const getColumnOrder = (cell) => {
|
|
14
|
+
return orderByValue.get(optionValueKey(cell.coordinate.column.value)) ?? panic("Visible Kanban cell has no column order");
|
|
15
|
+
};
|
|
16
|
+
return cells.filter((cell) => orderByValue.has(optionValueKey(cell.coordinate.column.value))).toSorted((left, right) => getColumnOrder(left) - getColumnOrder(right));
|
|
17
|
+
};
|
|
18
|
+
const cellKey = ({ column, lane }) => `${optionValueKey(column.value)}|${lane.type === "none" ? "none" : optionValueKey(lane.group.value)}`;
|
|
19
|
+
const groupContainsValue = (groups, value) => groups.some((group) => group.value === value);
|
|
20
|
+
const normalizeGroupValue = (groups, value) => groupContainsValue(groups, value) ? value : null;
|
|
21
|
+
const getRenderableGroups = (grouping, uncategorizedLabel) => {
|
|
22
|
+
if (!isKanbanGroupingRenderable(grouping)) return [];
|
|
23
|
+
return getKanbanGroups(resolveKanbanGroupOptions(grouping), uncategorizedLabel);
|
|
24
|
+
};
|
|
25
|
+
const makeLanes = (subgroup, uncategorizedLabel) => {
|
|
26
|
+
if (subgroup.type === "none") return [{ type: "none" }];
|
|
27
|
+
return getRenderableGroups(subgroup, uncategorizedLabel).map((group) => ({
|
|
28
|
+
group,
|
|
29
|
+
type: "group"
|
|
30
|
+
}));
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the board's one source of placement truth.
|
|
34
|
+
*
|
|
35
|
+
* A subgroup never filters the primary board scope. A row outside a subgroup's
|
|
36
|
+
* declared values goes to its explicit No value lane, rather than disappearing.
|
|
37
|
+
*/
|
|
38
|
+
const buildKanbanBoardMatrix = ({ group, subgroup, rows, uncategorizedLabel, resolveGroupValue }) => {
|
|
39
|
+
if (!isKanbanGroupingRenderable(group)) return {
|
|
40
|
+
cells: [],
|
|
41
|
+
columns: [],
|
|
42
|
+
lanes: [],
|
|
43
|
+
rows: []
|
|
44
|
+
};
|
|
45
|
+
const columns = getRenderableGroups(group, uncategorizedLabel);
|
|
46
|
+
const scopedRows = selectKanbanRows(rows, group);
|
|
47
|
+
const hasRenderableSubgroup = isKanbanGroupingRenderable(subgroup);
|
|
48
|
+
const lanes = hasRenderableSubgroup ? makeLanes(subgroup, uncategorizedLabel) : [{ type: "none" }];
|
|
49
|
+
const cells = [];
|
|
50
|
+
const cellsByKey = /* @__PURE__ */ new Map();
|
|
51
|
+
for (const lane of lanes) for (const column of columns) {
|
|
52
|
+
const coordinate = {
|
|
53
|
+
column,
|
|
54
|
+
lane
|
|
55
|
+
};
|
|
56
|
+
const cell = {
|
|
57
|
+
coordinate,
|
|
58
|
+
rows: []
|
|
59
|
+
};
|
|
60
|
+
cells.push(cell);
|
|
61
|
+
cellsByKey.set(cellKey(coordinate), cell);
|
|
62
|
+
}
|
|
63
|
+
for (const row of scopedRows) {
|
|
64
|
+
const columnValue = normalizeGroupValue(columns, resolveGroupValue({
|
|
65
|
+
grouping: group,
|
|
66
|
+
row
|
|
67
|
+
}));
|
|
68
|
+
const lane = !hasRenderableSubgroup ? { type: "none" } : {
|
|
69
|
+
group: {
|
|
70
|
+
value: normalizeGroupValue(lanes.filter((candidate) => candidate.type === "group").map((candidate) => candidate.group), resolveGroupValue({
|
|
71
|
+
grouping: subgroup,
|
|
72
|
+
row
|
|
73
|
+
})),
|
|
74
|
+
label: ""
|
|
75
|
+
},
|
|
76
|
+
type: "group"
|
|
77
|
+
};
|
|
78
|
+
const column = columns.find((candidate) => candidate.value === columnValue);
|
|
79
|
+
const resolvedLane = lane.type === "none" ? lane : lanes.find((candidate) => candidate.type === "group" && candidate.group.value === lane.group.value);
|
|
80
|
+
if (column === void 0 || resolvedLane === void 0) return panic("Kanban matrix cannot place a row in a declared cell");
|
|
81
|
+
const cell = cellsByKey.get(cellKey({
|
|
82
|
+
column,
|
|
83
|
+
lane: resolvedLane
|
|
84
|
+
}));
|
|
85
|
+
if (cell === void 0) return panic("Kanban matrix cell declaration is incomplete");
|
|
86
|
+
cell.rows.push(row);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
cells,
|
|
90
|
+
columns,
|
|
91
|
+
lanes,
|
|
92
|
+
rows: scopedRows
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Builds a single mutation payload for a pointer, touch, or keyboard drop.
|
|
97
|
+
* Diagonal drops carry both changes together; an adapter must commit this
|
|
98
|
+
* intent atomically or reject it as a whole.
|
|
99
|
+
*/
|
|
100
|
+
const createKanbanDropIntent = ({ cardId, group, source, subgroup, target }) => {
|
|
101
|
+
const groupBy = getKanbanGroupingPropertyId(group);
|
|
102
|
+
const subgroupBy = getKanbanGroupingPropertyId(subgroup);
|
|
103
|
+
if (groupBy === null || subgroupBy !== null && subgroupBy === groupBy) return null;
|
|
104
|
+
const changes = [];
|
|
105
|
+
if (source.column.value !== target.column.value) changes.push({
|
|
106
|
+
groupBy,
|
|
107
|
+
value: target.column.value
|
|
108
|
+
});
|
|
109
|
+
if (subgroupBy !== null && source.lane.type === "group" && target.lane.type === "group" && source.lane.group.value !== target.lane.group.value) changes.push({
|
|
110
|
+
groupBy: subgroupBy,
|
|
111
|
+
value: target.lane.group.value
|
|
112
|
+
});
|
|
113
|
+
if (changes.length === 0) return null;
|
|
114
|
+
return {
|
|
115
|
+
cardId,
|
|
116
|
+
changes,
|
|
117
|
+
type: "move"
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
//#endregion
|
|
121
|
+
export { KANBAN_BOARD_AXES, buildKanbanBoardMatrix, createKanbanDropIntent, orderKanbanCellsByColumns };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { KanbanGroup } from "./grouping.js";
|
|
2
|
+
import { KanbanBoardCell, KanbanBoardMatrix } from "./matrix.js";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
//#region src/kanban/subgroup-board.d.ts
|
|
5
|
+
type KanbanSubgroupColumnHeaderContext = {
|
|
6
|
+
column: KanbanGroup;
|
|
7
|
+
count: number;
|
|
8
|
+
};
|
|
9
|
+
type KanbanSubgroupLaneIdentityContext = {
|
|
10
|
+
group: KanbanGroup;
|
|
11
|
+
count: number;
|
|
12
|
+
};
|
|
13
|
+
type KanbanSubgroupCellContext<TRow> = {
|
|
14
|
+
cell: KanbanBoardCell<TRow>;
|
|
15
|
+
laneValue: string | null;
|
|
16
|
+
};
|
|
17
|
+
type KanbanSubgroupCollapseControl = {
|
|
18
|
+
isLaneCollapsed?: undefined;
|
|
19
|
+
onLaneCollapsedChange?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
isLaneCollapsed: (group: KanbanGroup, count: number) => boolean;
|
|
22
|
+
onLaneCollapsedChange: (group: KanbanGroup, collapsed: boolean) => void;
|
|
23
|
+
};
|
|
24
|
+
type KanbanSubgroupBoardProps<TRow> = {
|
|
25
|
+
matrix: KanbanBoardMatrix<TRow>;
|
|
26
|
+
renderColumnHeader: (context: KanbanSubgroupColumnHeaderContext) => ReactNode;
|
|
27
|
+
renderLaneIdentity: (context: KanbanSubgroupLaneIdentityContext) => ReactNode;
|
|
28
|
+
renderCell: (context: KanbanSubgroupCellContext<TRow>) => ReactNode;
|
|
29
|
+
formatCount?: ((count: number) => ReactNode) | undefined;
|
|
30
|
+
footer?: ReactNode;
|
|
31
|
+
className?: string | undefined;
|
|
32
|
+
} & KanbanSubgroupCollapseControl;
|
|
33
|
+
/** Reusable swimlane layout over the canonical two-axis Kanban matrix. */
|
|
34
|
+
declare const KanbanSubgroupBoard: <TRow>({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, formatCount, isLaneCollapsed, onLaneCollapsedChange, footer, className }: KanbanSubgroupBoardProps<TRow>) => import("react").JSX.Element;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext };
|
|
@@ -0,0 +1,115 @@
|
|
|
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
|
+
import { useMemo, useState } from "react";
|
|
6
|
+
//#region src/kanban/subgroup-board.tsx
|
|
7
|
+
const groupValueKey = (value) => value === null ? "null" : `value:${value.length}:${value}`;
|
|
8
|
+
/** Reusable swimlane layout over the canonical two-axis Kanban matrix. */
|
|
9
|
+
const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, renderCell, formatCount = String, isLaneCollapsed, onLaneCollapsedChange, footer, className }) => {
|
|
10
|
+
const [collapsedLaneValues, setCollapsedLaneValues] = useState(() => /* @__PURE__ */ new Set());
|
|
11
|
+
const [expandedEmptyLaneValues, setExpandedEmptyLaneValues] = useState(() => /* @__PURE__ */ new Set());
|
|
12
|
+
const { cellsByLaneValue, countByColumnValue } = useMemo(() => {
|
|
13
|
+
const laneCells = /* @__PURE__ */ new Map();
|
|
14
|
+
const columnCounts = /* @__PURE__ */ new Map();
|
|
15
|
+
for (const cell of matrix.cells) {
|
|
16
|
+
columnCounts.set(cell.coordinate.column.value, (columnCounts.get(cell.coordinate.column.value) ?? 0) + cell.rows.length);
|
|
17
|
+
if (cell.coordinate.lane.type === "none") continue;
|
|
18
|
+
const laneValue = cell.coordinate.lane.group.value;
|
|
19
|
+
const currentLaneCells = laneCells.get(laneValue);
|
|
20
|
+
if (currentLaneCells) currentLaneCells.push(cell);
|
|
21
|
+
else laneCells.set(laneValue, [cell]);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
cellsByLaneValue: laneCells,
|
|
25
|
+
countByColumnValue: columnCounts
|
|
26
|
+
};
|
|
27
|
+
}, [matrix.cells]);
|
|
28
|
+
const setLaneCollapsed = (group, count, collapsed) => {
|
|
29
|
+
if (onLaneCollapsedChange) {
|
|
30
|
+
onLaneCollapsedChange(group, collapsed);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const value = group.value;
|
|
34
|
+
if (count === 0) {
|
|
35
|
+
setExpandedEmptyLaneValues((current) => {
|
|
36
|
+
const next = new Set(current);
|
|
37
|
+
if (collapsed) next.delete(value);
|
|
38
|
+
else next.add(value);
|
|
39
|
+
return next;
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
setCollapsedLaneValues((current) => {
|
|
44
|
+
const next = new Set(current);
|
|
45
|
+
if (collapsed) next.add(value);
|
|
46
|
+
else next.delete(value);
|
|
47
|
+
return next;
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
return /* @__PURE__ */ jsx("div", {
|
|
51
|
+
className: cn("h-full overflow-auto px-4 pb-4", className),
|
|
52
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
53
|
+
className: "min-w-max",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ jsx("div", {
|
|
56
|
+
className: "bg-background sticky top-0 z-20 flex gap-3 pt-4 pb-3",
|
|
57
|
+
children: matrix.columns.map((column) => /* @__PURE__ */ jsx("div", {
|
|
58
|
+
className: "w-[300px] shrink-0",
|
|
59
|
+
children: renderColumnHeader({
|
|
60
|
+
column,
|
|
61
|
+
count: countByColumnValue.get(column.value) ?? 0
|
|
62
|
+
})
|
|
63
|
+
}, groupValueKey(column.value)))
|
|
64
|
+
}),
|
|
65
|
+
matrix.lanes.map((lane) => {
|
|
66
|
+
if (lane.type === "none") return null;
|
|
67
|
+
const { group } = lane;
|
|
68
|
+
const cells = cellsByLaneValue.get(group.value) ?? [];
|
|
69
|
+
const count = cells.reduce((sum, cell) => sum + cell.rows.length, 0);
|
|
70
|
+
const defaultCollapsed = count === 0 ? !expandedEmptyLaneValues.has(group.value) : collapsedLaneValues.has(group.value);
|
|
71
|
+
const collapsed = isLaneCollapsed ? isLaneCollapsed(group, count) : defaultCollapsed;
|
|
72
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
73
|
+
className: "border-border/60 border-b py-2 first:pt-0 last:border-b-0",
|
|
74
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
75
|
+
className: "bg-background/95 sticky start-0 z-10 flex min-h-11 items-center backdrop-blur-sm",
|
|
76
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
77
|
+
"aria-expanded": !collapsed,
|
|
78
|
+
className: "hover:bg-muted/60 flex min-h-11 items-center gap-2 rounded-lg px-2 text-start transition-[background-color]",
|
|
79
|
+
onClick: () => setLaneCollapsed(group, count, !collapsed),
|
|
80
|
+
type: "button",
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ jsx(DirectionalIcon, {
|
|
83
|
+
className: cn("text-muted-foreground size-4 shrink-0 transition-transform", collapsed && "-rotate-90"),
|
|
84
|
+
flip: collapsed,
|
|
85
|
+
icon: ChevronDownIcon
|
|
86
|
+
}),
|
|
87
|
+
renderLaneIdentity({
|
|
88
|
+
group,
|
|
89
|
+
count
|
|
90
|
+
}),
|
|
91
|
+
/* @__PURE__ */ jsx("span", {
|
|
92
|
+
className: "text-muted-foreground text-xs tabular-nums",
|
|
93
|
+
children: formatCount(count)
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
})
|
|
97
|
+
}), !collapsed && /* @__PURE__ */ jsx("div", {
|
|
98
|
+
className: "flex gap-3 pb-1",
|
|
99
|
+
children: cells.map((cell) => /* @__PURE__ */ jsx("div", {
|
|
100
|
+
className: "w-[300px] shrink-0",
|
|
101
|
+
children: renderCell({
|
|
102
|
+
cell,
|
|
103
|
+
laneValue: group.value
|
|
104
|
+
})
|
|
105
|
+
}, groupValueKey(cell.coordinate.column.value)))
|
|
106
|
+
})]
|
|
107
|
+
}, groupValueKey(group.value));
|
|
108
|
+
}),
|
|
109
|
+
footer
|
|
110
|
+
]
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
//#endregion
|
|
115
|
+
export { KanbanSubgroupBoard };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Key, ReactNode, RefObject } from "react";
|
|
2
|
+
//#region src/kanban/virtual-cell.d.ts
|
|
3
|
+
declare const KANBAN_VIRTUAL_CELL_PAGINATION: {
|
|
4
|
+
readonly NONE: "none";
|
|
5
|
+
readonly CURSOR: "cursor";
|
|
6
|
+
};
|
|
7
|
+
type KanbanVirtualCellPagination = {
|
|
8
|
+
type: "none";
|
|
9
|
+
} | {
|
|
10
|
+
type: "cursor";
|
|
11
|
+
hasMore: boolean;
|
|
12
|
+
loading: boolean;
|
|
13
|
+
pageKey: string | number;
|
|
14
|
+
onRequestMore: () => void;
|
|
15
|
+
};
|
|
16
|
+
type KanbanVirtualCellProps<TRow> = {
|
|
17
|
+
rows: readonly TRow[];
|
|
18
|
+
getRowKey: (row: TRow) => Key;
|
|
19
|
+
renderRow: (row: TRow) => ReactNode;
|
|
20
|
+
pagination: KanbanVirtualCellPagination;
|
|
21
|
+
containerRef?: RefObject<HTMLDivElement | null> | undefined;
|
|
22
|
+
active?: boolean | undefined;
|
|
23
|
+
backgroundColor?: string | undefined;
|
|
24
|
+
footer?: ReactNode;
|
|
25
|
+
estimateSize?: number | undefined;
|
|
26
|
+
overscan?: number | undefined;
|
|
27
|
+
loadMoreThreshold?: number | undefined;
|
|
28
|
+
className?: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
/** Bounded, virtualized Kanban cell with cursor-page request deduplication. */
|
|
31
|
+
declare const KanbanVirtualCell: <TRow>({ rows, getRowKey, renderRow, pagination, containerRef, active, backgroundColor, footer, estimateSize, overscan, loadMoreThreshold, className }: KanbanVirtualCellProps<TRow>) => import("react").JSX.Element;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { cn } from "../lib/utils.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef } from "react";
|
|
4
|
+
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
5
|
+
//#region src/kanban/virtual-cell.tsx
|
|
6
|
+
const DEFAULT_ESTIMATE_SIZE_PX = 128;
|
|
7
|
+
const DEFAULT_OVERSCAN = 8;
|
|
8
|
+
const DEFAULT_LOAD_MORE_THRESHOLD_PX = 200;
|
|
9
|
+
const KANBAN_VIRTUAL_CELL_PAGINATION = {
|
|
10
|
+
NONE: "none",
|
|
11
|
+
CURSOR: "cursor"
|
|
12
|
+
};
|
|
13
|
+
/** Bounded, virtualized Kanban cell with cursor-page request deduplication. */
|
|
14
|
+
const KanbanVirtualCell = ({ rows, getRowKey, renderRow, pagination, containerRef, active = false, backgroundColor, footer, estimateSize = DEFAULT_ESTIMATE_SIZE_PX, overscan = DEFAULT_OVERSCAN, loadMoreThreshold = DEFAULT_LOAD_MORE_THRESHOLD_PX, className }) => {
|
|
15
|
+
const internalRef = useRef(null);
|
|
16
|
+
const scrollRef = containerRef ?? internalRef;
|
|
17
|
+
const requestedPageKeyRef = useRef(null);
|
|
18
|
+
const virtualizer = useVirtualizer({
|
|
19
|
+
count: rows.length,
|
|
20
|
+
estimateSize: () => estimateSize,
|
|
21
|
+
getItemKey: (index) => {
|
|
22
|
+
const row = rows.at(index);
|
|
23
|
+
return row === void 0 ? index : getRowKey(row);
|
|
24
|
+
},
|
|
25
|
+
getScrollElement: () => scrollRef.current,
|
|
26
|
+
overscan
|
|
27
|
+
});
|
|
28
|
+
const handleScroll = ({ currentTarget }) => {
|
|
29
|
+
if (pagination.type !== "cursor" || !pagination.hasMore || pagination.loading) return;
|
|
30
|
+
if (currentTarget.scrollHeight - currentTarget.scrollTop - currentTarget.clientHeight > loadMoreThreshold) return;
|
|
31
|
+
if (requestedPageKeyRef.current === pagination.pageKey) return;
|
|
32
|
+
requestedPageKeyRef.current = pagination.pageKey;
|
|
33
|
+
pagination.onRequestMore();
|
|
34
|
+
};
|
|
35
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
36
|
+
className: cn("bg-muted/20 max-h-[min(60vh,40rem)] min-h-20 overflow-y-auto overscroll-y-contain rounded-xl p-2 transition-[background-color,outline-color]", active && "bg-primary/5 ring-primary/50 ring-2", className),
|
|
37
|
+
onScroll: handleScroll,
|
|
38
|
+
ref: scrollRef,
|
|
39
|
+
style: backgroundColor ? { backgroundColor } : void 0,
|
|
40
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
41
|
+
className: "relative",
|
|
42
|
+
style: { height: virtualizer.getTotalSize() },
|
|
43
|
+
children: virtualizer.getVirtualItems().map((virtualRow) => {
|
|
44
|
+
const row = rows.at(virtualRow.index);
|
|
45
|
+
if (row === void 0) return null;
|
|
46
|
+
return /* @__PURE__ */ jsx("div", {
|
|
47
|
+
className: "absolute inset-x-0 top-0 pb-2",
|
|
48
|
+
"data-index": virtualRow.index,
|
|
49
|
+
ref: virtualizer.measureElement,
|
|
50
|
+
style: { transform: `translateY(${virtualRow.start}px)` },
|
|
51
|
+
children: renderRow(row)
|
|
52
|
+
}, getRowKey(row));
|
|
53
|
+
})
|
|
54
|
+
}), footer]
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
export { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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",
|
|
@@ -557,6 +557,7 @@
|
|
|
557
557
|
"prepack": "bun run build"
|
|
558
558
|
},
|
|
559
559
|
"dependencies": {
|
|
560
|
+
"better-result": "3.0.0",
|
|
560
561
|
"class-variance-authority": "^0.7.1",
|
|
561
562
|
"clsx": "^2.1.1",
|
|
562
563
|
"input-otp": "^1.5.0",
|
|
@@ -571,6 +572,7 @@
|
|
|
571
572
|
"@dnd-kit/sortable": "^10.0.0",
|
|
572
573
|
"@playwright/test": "^1.62.0",
|
|
573
574
|
"@stll/typescript-config": "0.0.0",
|
|
575
|
+
"@tanstack/react-virtual": "^3.14.10",
|
|
574
576
|
"@types/react": "^19.2.17",
|
|
575
577
|
"@types/react-dom": "^19.2.3",
|
|
576
578
|
"bun-types": "1.4.0",
|
|
@@ -586,6 +588,7 @@
|
|
|
586
588
|
"@base-ui/react": "^1.7.0",
|
|
587
589
|
"@dnd-kit/core": "^6.3.1",
|
|
588
590
|
"@dnd-kit/sortable": "^10.0.0",
|
|
591
|
+
"@tanstack/react-virtual": "^3.14.10",
|
|
589
592
|
"react": ">=19",
|
|
590
593
|
"react-dom": ">=19",
|
|
591
594
|
"tailwindcss": "^4.3.0"
|