@stll/ui 0.21.0 → 0.23.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
@@ -236,6 +236,41 @@ reachable, and the slot peeks open while a pointer rests on it. Pass
236
236
  />
237
237
  ```
238
238
 
239
+ ### Lane controls that survive a scroll
240
+
241
+ The board measures its sticky header block and publishes its height on the
242
+ scroll container as `KANBAN_STICKY_TOP_VAR` (`--kanban-sticky-top`), so a
243
+ lane's controls can rest just under the header and release where the lane
244
+ ends. `KanbanVirtualCell` takes `footerPlacement="sticky-start"` to pin its
245
+ `footer` above the rows instead of closing the cell with it, and
246
+ `KanbanCollapsedBandCaption` keeps a folded band's name and count in view down
247
+ a tall lane. A cell that keeps its own bounded scroll surface is its own
248
+ scroll container, where the board's header offset means nothing; reset the
249
+ variable on it so the action rests at the cell's own top.
250
+
251
+ ```tsx
252
+ <KanbanVirtualCell
253
+ className="[--kanban-sticky-top:0px]"
254
+ footer={<KanbanCellAction onClick={addCard}>New card</KanbanCellAction>}
255
+ footerPlacement="sticky-start"
256
+ getRowKey={(row) => row.id}
257
+ pagination={{ type: "none" }}
258
+ renderRow={(row) => <Card row={row} />}
259
+ rows={cell.rows}
260
+ />
261
+ ```
262
+
263
+ A host rendering its own collapsed band cell fills the slot and composes the
264
+ caption inside it:
265
+
266
+ ```tsx
267
+ renderCollapsedBandCell={({ band, cells, count }) => (
268
+ <FoldedDropTarget bandId={band.id} cells={cells}>
269
+ <KanbanCollapsedBandCaption label={band.label} meta={count} />
270
+ </FoldedDropTarget>
271
+ )}
272
+ ```
273
+
239
274
  ## Styles
240
275
 
241
276
  No compiled CSS ships. The components carry Tailwind class names, so the
@@ -53,7 +53,7 @@ const AlertDialogPanel = ({ className, ...props }) => /* @__PURE__ */ jsx("div",
53
53
  ...props
54
54
  });
55
55
  const AlertDialogTitle = ({ className, ...props }) => /* @__PURE__ */ jsx(AlertDialog$1.Title, {
56
- className: cn("font-heading text-xl leading-none font-semibold", className),
56
+ className: cn("text-xl leading-none font-semibold", className),
57
57
  "data-slot": "alert-dialog-title",
58
58
  ...props
59
59
  });
@@ -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" | "chip" | "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?: "default" | "xs" | "sm" | "icon" | "lg" | "chip" | "icon-lg" | "icon-sm" | "icon-xl" | "icon-xs" | "xl" | null | undefined;
14
+ variant?: "link" | "default" | "destructive" | "outline" | "destructive-outline" | "ghost" | "secondary" | null | undefined;
15
15
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
16
16
  //#endregion
17
17
  export { buttonAccessibleDisabledClass, buttonVariants };
@@ -71,7 +71,7 @@ const DialogFooter = ({ className, variant = "default", ...props }) => /* @__PUR
71
71
  ...props
72
72
  });
73
73
  const DialogTitle = ({ className, ...props }) => /* @__PURE__ */ jsx(Dialog$1.Title, {
74
- className: cn("font-heading text-xl leading-none font-semibold", className),
74
+ className: cn("text-xl leading-none font-semibold", className),
75
75
  "data-slot": "dialog-title",
76
76
  ...props
77
77
  });
@@ -5,7 +5,7 @@ import { VariantProps } from "class-variance-authority";
5
5
  //#region src/components/input-group.d.ts
6
6
  declare const InputGroup: ({ className, ...props }: React$1.ComponentProps<"div">) => React$1.JSX.Element;
7
7
  declare const inputGroupAddonVariants: (props?: ({
8
- align?: "inline-start" | "block-end" | "block-start" | "inline-end" | null | undefined;
8
+ align?: "inline-end" | "inline-start" | "block-end" | "block-start" | null | undefined;
9
9
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
10
10
  declare const InputGroupAddon: ({ className, align, ...props }: React$1.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) => React$1.JSX.Element;
11
11
  declare const InputGroupText: ({ className, ...props }: React$1.ComponentProps<"span">) => React$1.JSX.Element;
@@ -36,7 +36,7 @@ const InputGroupAddon = ({ className, align = "inline-start", ...props }) => /*
36
36
  ...props
37
37
  });
38
38
  const InputGroupText = ({ className, ...props }) => /* @__PURE__ */ jsx("span", {
39
- className: cn("text-muted-foreground line-clamp-1 flex items-center gap-2 leading-none [&_svg]:pointer-events-none [&_svg]:-mx-0.5 in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4.5 sm:in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4", className),
39
+ className: cn("text-muted-foreground flex items-center gap-2 truncate leading-none [&_svg]:pointer-events-none [&_svg]:-mx-0.5 in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4.5 sm:in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4", className),
40
40
  ...props
41
41
  });
42
42
  const InputGroupInput = ({ className, ...props }) => /* @__PURE__ */ jsx(Input, {
@@ -321,7 +321,7 @@ const OutlineRail = ({ items, scrollContainerRef, resolvePct, onJump, activeId,
321
321
  /* @__PURE__ */ jsx("button", {
322
322
  "aria-controls": panelId,
323
323
  "aria-expanded": panelOpen,
324
- className: "focus-visible:ring-ring bg-popover text-popover-foreground sr-only absolute end-0 top-2 z-30 w-max -translate-x-6 rounded-md border px-2 py-1 text-xs focus:not-sr-only focus-visible:ring-2 focus-visible:outline-none",
324
+ className: "focus-visible:ring-ring bg-popover text-popover-foreground sr-only end-0 top-2 z-30 -translate-x-6 text-xs focus:not-sr-only focus:absolute focus:w-max focus:rounded-md focus:border focus:px-2 focus:py-1 focus-visible:ring-2 focus-visible:outline-none",
325
325
  id: triggerId,
326
326
  onClick: () => {
327
327
  if (pinned) {
@@ -20,7 +20,8 @@ const PopoverPopup = ({ children, className, side = "bottom", align = "center",
20
20
  align,
21
21
  alignOffset,
22
22
  anchor,
23
- className: cn("h-(--positioner-height) w-(--positioner-width) max-w-(--available-width)", OVERLAY_LAYER_CLASS_NAMES[layer]),
23
+ className: cn("h-(--positioner-height) w-max max-w-(--available-width)", OVERLAY_LAYER_CLASS_NAMES[layer]),
24
+ collisionPadding: 8,
24
25
  "data-slot": "popover-positioner",
25
26
  side,
26
27
  sideOffset,
@@ -9,7 +9,7 @@ const ScrollArea = ({ className, children, scrollFade = false, scrollbarClassNam
9
9
  children: [
10
10
  /* @__PURE__ */ jsx(ScrollArea$1.Viewport, {
11
11
  ref: viewportRef,
12
- className: cn("transition-shadows focus-visible:ring-ring focus-visible:ring-offset-background h-full overscroll-contain rounded-[inherit] outline-none focus-visible:ring-2 focus-visible:ring-offset-1 data-has-overflow-x:overscroll-x-contain", scrollFade && "mask-t-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-start)))] mask-r-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-end)))] mask-b-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-end)))] mask-l-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-start)))] [--fade-size:1.5rem]", scrollbarGutter && "data-has-overflow-x:pb-2.5 data-has-overflow-y:pe-2.5"),
12
+ className: cn("focus-visible:ring-ring focus-visible:ring-offset-background h-full overscroll-contain rounded-[inherit] transition-shadow outline-none focus-visible:ring-2 focus-visible:ring-offset-1 data-has-overflow-x:overscroll-x-contain", scrollFade && "mask-t-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-start)))] mask-r-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-end)))] mask-b-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-end)))] mask-l-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-start)))] [--fade-size:1.5rem]", scrollbarGutter && "data-has-overflow-x:pb-2.5 data-has-overflow-y:pe-2.5"),
13
13
  "data-slot": "scroll-area-viewport",
14
14
  children
15
15
  }),
@@ -66,7 +66,7 @@ const SheetFooter = ({ className, variant = "default", ...props }) => /* @__PURE
66
66
  ...props
67
67
  });
68
68
  const SheetTitle = ({ className, ...props }) => /* @__PURE__ */ jsx(Dialog.Title, {
69
- className: cn("font-heading text-xl leading-none font-semibold", className),
69
+ className: cn("text-xl leading-none font-semibold", className),
70
70
  "data-slot": "sheet-title",
71
71
  ...props
72
72
  });
@@ -83,7 +83,7 @@ declare const SidebarMenu: ({ className, ...props }: React.ComponentProps<"ul">)
83
83
  declare const SidebarMenuItem: ({ className, ...props }: React.ComponentProps<"li">) => import("react").JSX.Element;
84
84
  declare const sidebarMenuButtonVariants: (props?: ({
85
85
  variant?: "default" | "outline" | null | undefined;
86
- size?: "default" | "lg" | "sm" | "rail" | null | undefined;
86
+ size?: "default" | "sm" | "lg" | "rail" | null | undefined;
87
87
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
88
88
  declare const SidebarMenuButton: ({ asChild, isActive, variant, size, tooltip, className, ...props }: React.ComponentProps<"button"> & {
89
89
  asChild?: boolean;
@@ -88,7 +88,7 @@ const Toasts = ({ position }) => {
88
88
  className: "truncate font-medium",
89
89
  "data-slot": "toast-title"
90
90
  }), /* @__PURE__ */ jsx(Toast.Description, {
91
- className: "text-muted-foreground break-words",
91
+ className: "text-muted-foreground wrap-break-word",
92
92
  "data-slot": "toast-description"
93
93
  })]
94
94
  })]
@@ -154,7 +154,7 @@ const AnchoredToasts = () => {
154
154
  className: "truncate font-medium",
155
155
  "data-slot": "toast-title"
156
156
  }), /* @__PURE__ */ jsx(Toast.Description, {
157
- className: "text-muted-foreground break-words",
157
+ className: "text-muted-foreground wrap-break-word",
158
158
  "data-slot": "toast-description"
159
159
  })]
160
160
  })]
@@ -13,7 +13,8 @@ const TooltipTrigger = (props) => /* @__PURE__ */ jsx(Tooltip$1.Trigger, {
13
13
  });
14
14
  const TooltipPopup = ({ className, align = "center", sideOffset = 4, side = "top", layer = "default", children, ...props }) => /* @__PURE__ */ jsx(Tooltip$1.Portal, { children: /* @__PURE__ */ jsx(Tooltip$1.Positioner, {
15
15
  align,
16
- className: cn("h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom,transform] data-instant:transition-none", OVERLAY_LAYER_CLASS_NAMES[layer]),
16
+ className: cn("h-(--positioner-height) w-max max-w-(--available-width) transition-[top,left,right,bottom,transform] data-instant:transition-none", OVERLAY_LAYER_CLASS_NAMES[layer]),
17
+ collisionPadding: 8,
17
18
  "data-slot": "tooltip-positioner",
18
19
  side,
19
20
  sideOffset,
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { CalendarDateRange, ResourceCalendarLaneLayout, ResourceCalendarLanePlac
3
3
  import { ResourceCalendar, ResourceCalendarColumn, ResourceCalendarEntry, ResourceCalendarEntryTone, ResourceCalendarResource } from "./calendar/resource-calendar.js";
4
4
  import "./calendar/index.js";
5
5
  import { Accordion, AccordionContent as AccordionPanel, AccordionItem, AccordionTrigger } from "./components/accordion.js";
6
- import { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_LAYER_CLASS_NAMES, OverlayLayer } from "./lib/overlay-layer.js";
6
+ import { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_COLLISION_PADDING, OVERLAY_LAYER_CLASS_NAMES, OverlayLayer } from "./lib/overlay-layer.js";
7
7
  import { AlertDialog, AlertDialogBackdrop, AlertDialogClose, AlertDialogContent as AlertDialogPopup, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPanel, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertDialogViewport } from "./components/alert-dialog.js";
8
8
  import { APPLICATION_RAIL_BUTTON_SIZE, APPLICATION_RAIL_ICON_SIZE, APPLICATION_RAIL_WIDTH, ApplicationRail, ApplicationRailButton, ApplicationRailContent, ApplicationRailFooter, ApplicationRailHeader, ApplicationRailMenu, ApplicationRailSeparator } from "./components/application-rail.js";
9
9
  import { Avatar, AvatarFallback, AvatarImage } from "./components/avatar.js";
@@ -85,6 +85,7 @@ import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KanbanDirection, KanbanHori
85
85
  import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_CARD_DRAG_MIME, RegisterKanbanBoardAutoScrollOptions, RegisterKanbanCardDragOptions, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./kanban/drag-interactions.js";
86
86
  import { KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupCollapsedBandCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./kanban/subgroup-board.js";
87
87
  import { KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS } from "./kanban/band-peek.js";
88
+ import { KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_VAR, KanbanCollapsedBandCaption, KanbanCollapsedBandCaptionProps } from "./kanban/sticky-lane.js";
88
89
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps, KanbanVirtualCellSortableContext } from "./kanban/virtual-cell.js";
89
90
  import "./kanban/index.js";
90
91
  import { getInitials } from "./lib/initials.js";
@@ -97,4 +98,4 @@ import { ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffSegment, ReviewDiffS
97
98
  import { ReviewOutOfDateNotice, ReviewOutOfDateReason, ReviewOutOfDateTone } from "./review/review-out-of-date-notice.js";
98
99
  import { ReviewStatusBadge, ReviewStatusSize, ReviewStatusTone, ReviewStatusVariant } from "./review/review-status-badge.js";
99
100
  import { ReviewSeverityDot, ReviewSeverityLevel, ReviewStatusDot, reviewSeverityTone } from "./review/review-severity-dot.js";
100
- 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, InspectorEntityTab, InspectorFacetBar, 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_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, 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 KanbanBandToggleActivation, 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, SIDEBAR_WIDTH_ICON_PX, SIDEBAR_WIDTH_PX, 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, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, 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, entityTabGlyph, 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, useSidebar, useSidebarInlineSize, useViewportWidth, visibleColumnIds };
101
+ 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, InspectorEntityTab, InspectorFacetBar, 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_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, KANBAN_CARD_STICKY_TOP_VAR, 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_STICKY_TOP_VAR, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBandToggleActivation, 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, KanbanCollapsedBandCaption, type KanbanCollapsedBandCaptionProps, 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_COLLISION_PADDING, 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, SIDEBAR_WIDTH_ICON_PX, SIDEBAR_WIDTH_PX, 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, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, 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, entityTabGlyph, 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, useSidebar, useSidebarInlineSize, useViewportWidth, visibleColumnIds };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { cn, composeRefs } from "./lib/utils.js";
2
2
  import { Accordion, AccordionContent as AccordionPanel, AccordionItem, AccordionTrigger } from "./components/accordion.js";
3
3
  import { PROPERTY_ROW_GRID, SIDE_RAIL_CONTAINER_CLASS, SIDE_RAIL_ICON_BUTTON_SIZE, SIDE_RAIL_TAB_ICON_SIZE, SIDE_RAIL_WIDTH, TOOLBAR_ROW_HEIGHT, TOOLBAR_ROW_HEIGHT_PX } from "./inspector/layout-tokens.js";
4
4
  import { APPLICATION_RAIL_BUTTON_SIZE, APPLICATION_RAIL_ICON_SIZE, APPLICATION_RAIL_WIDTH, ApplicationRail, ApplicationRailButton, ApplicationRailContent, ApplicationRailFooter, ApplicationRailHeader, ApplicationRailMenu, ApplicationRailSeparator } from "./components/application-rail.js";
5
- import { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_LAYER_CLASS_NAMES } from "./lib/overlay-layer.js";
5
+ import { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_COLLISION_PADDING, OVERLAY_LAYER_CLASS_NAMES } from "./lib/overlay-layer.js";
6
6
  import { Tooltip, TooltipContent as TooltipPopup, TooltipCreateHandle, TooltipProvider, TooltipTrigger } from "./components/tooltip.js";
7
7
  import { AlertDialog, AlertDialogBackdrop, AlertDialogClose, AlertDialogContent as AlertDialogPopup, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPanel, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertDialogViewport } from "./components/alert-dialog.js";
8
8
  import { useIsMobile } from "./hooks/use-mobile.js";
@@ -70,6 +70,7 @@ import { InspectorFacetBar } from "./inspector/facet-bar.js";
70
70
  import { InspectorTab, InspectorTabList, InspectorTabPanel, InspectorTabs } from "./inspector/tabs.js";
71
71
  import { INSPECTOR_PANE_KEYBOARD_PAGE_STEP, INSPECTOR_PANE_KEYBOARD_STEP, parsePersistedPaneWidth, resolveDragWidth, resolveKeyboardWidth, useInspectorPaneWidth } from "./inspector/use-pane-width.js";
72
72
  import { selectKanbanCardFieldIds } from "./kanban/card-properties.js";
73
+ import { KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_VAR, KanbanCollapsedBandCaption } from "./kanban/sticky-lane.js";
73
74
  import { KanbanCardShell } from "./kanban/card-shell.js";
74
75
  import { KanbanCellAction } from "./kanban/cell-action.js";
75
76
  import { KanbanColumnBandHeader } from "./kanban/column-band-header.js";
@@ -93,4 +94,4 @@ import { ReviewDiffDeletion, ReviewDiffInsertion, ReviewDiffText, TRACKED_DELETI
93
94
  import { ReviewOutOfDateNotice } from "./review/review-out-of-date-notice.js";
94
95
  import { ReviewSeverityDot, ReviewStatusDot, reviewSeverityTone } from "./review/review-severity-dot.js";
95
96
  import { ReviewStatusBadge } from "./review/review-status-badge.js";
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, 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, InspectorEntityTab, InspectorFacetBar, 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_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, 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, SIDEBAR_WIDTH_ICON_PX, SIDEBAR_WIDTH_PX, 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, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, 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, entityTabGlyph, 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, useSidebar, useSidebarInlineSize, useViewportWidth, visibleColumnIds };
97
+ 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, InspectorEntityTab, InspectorFacetBar, 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_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, KANBAN_CARD_STICKY_TOP_VAR, 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_STICKY_TOP_VAR, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardDragSurface, KanbanCardShell, KanbanCellAction, KanbanCollapsedBandCaption, KanbanColumnBandHeader, KanbanColumnHeader, KanbanDragHandle, KanbanSortableBoard, KanbanSortableColumns, KanbanSortableList, KanbanSubgroupBoard, KanbanVirtualCell, Label, MenuPreviewLayout, OVERLAY_COLLISION_PADDING, 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, SIDEBAR_WIDTH_ICON_PX, SIDEBAR_WIDTH_PX, 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, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, 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, entityTabGlyph, 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, useSidebar, useSidebarInlineSize, useViewportWidth, visibleColumnIds };
@@ -4,6 +4,17 @@ type KanbanCardShellProps = {
4
4
  children: ReactNode;
5
5
  /** Overlay slot pinned to the top-end corner (row actions). */
6
6
  actions?: ReactNode;
7
+ /**
8
+ * The card's identity row: whatever says which card this is, held at the top
9
+ * of the card while the card scrolls past under it, and released where the
10
+ * card ends. A card taller than the viewport otherwise loses its own name
11
+ * halfway down. Omit it and the card renders exactly as it did before.
12
+ *
13
+ * Booleans are excluded so `condition && <Row />` cannot reach the slot: a
14
+ * `false` React renders as nothing would still leave the row's divider and
15
+ * spacing behind. Write the absent case as `condition ? <Row /> : null`.
16
+ */
17
+ stickyHeader?: Exclude<ReactNode, boolean>;
7
18
  /** Marks the card whose detail is currently open. */
8
19
  active?: boolean | undefined;
9
20
  /**
@@ -26,7 +37,10 @@ type KanbanCardShellProps = {
26
37
  * three near-identical copies of this markup, differing only in whether the
27
38
  * card opened anything, which is why opening is a prop rather than a branch at
28
39
  * each call site.
40
+ *
41
+ * Nothing here clips its overflow: a pinned identity row stops sticking the
42
+ * moment anything between it and the scroll container clips.
29
43
  */
30
- declare const KanbanCardShell: ({ children, actions, active, onOpen, bodyRef, dragRef, className }: KanbanCardShellProps) => import("react").JSX.Element;
44
+ declare const KanbanCardShell: ({ children, actions, stickyHeader, active, onOpen, bodyRef, dragRef, className }: KanbanCardShellProps) => import("react").JSX.Element;
31
45
  //#endregion
32
46
  export { KanbanCardShell, KanbanCardShellProps };
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import { containedEventHandler } from "../hooks/use-contained-handler.js";
3
+ import { KANBAN_CARD_STICKY_TOP_CLASS } from "./sticky-lane.js";
3
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/kanban/card-shell.tsx
5
6
  /**
@@ -10,9 +11,20 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
11
  * three near-identical copies of this markup, differing only in whether the
11
12
  * card opened anything, which is why opening is a prop rather than a branch at
12
13
  * each call site.
14
+ *
15
+ * Nothing here clips its overflow: a pinned identity row stops sticking the
16
+ * moment anything between it and the scroll container clips.
13
17
  */
14
- const KanbanCardShell = ({ children, actions, active, onOpen, bodyRef, dragRef, className }) => {
15
- const body = /* @__PURE__ */ jsxs(Fragment, { children: [children, actions] });
18
+ const KanbanCardShell = ({ children, actions, stickyHeader, active, onOpen, bodyRef, dragRef, className }) => {
19
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
20
+ stickyHeader === void 0 || stickyHeader === null ? null : /* @__PURE__ */ jsx("div", {
21
+ className: cn(STICKY_HEADER_CLASS, KANBAN_CARD_STICKY_TOP_CLASS),
22
+ "data-kanban-card-sticky-header": "",
23
+ children: stickyHeader
24
+ }),
25
+ children,
26
+ actions
27
+ ] });
16
28
  if (!onOpen) return /* @__PURE__ */ jsx("div", {
17
29
  className: "group/card",
18
30
  ref: dragRef,
@@ -42,5 +54,16 @@ const KanbanCardShell = ({ children, actions, active, onOpen, bodyRef, dragRef,
42
54
  };
43
55
  const CARD_CLASS = "bg-card relative block w-full rounded-lg border p-3 text-start shadow-xs";
44
56
  const ACTIVE_CLASS = "ring-primary/30 ring-2";
57
+ /**
58
+ * The card's own surface repeated on the pinned row, so the rest of the card
59
+ * passes behind it instead of reading through it, ruled off with the card's own
60
+ * border weight.
61
+ *
62
+ * No `z-index`: being positioned is already enough to paint over the card's
63
+ * flow content, and taking a layer would put the row over the `actions`
64
+ * overlay, which callers anchor to the same corner with no layer of its own.
65
+ * Tree order settles the rest, and the row renders before `actions`.
66
+ */
67
+ const STICKY_HEADER_CLASS = "bg-card sticky mb-2 border-b pb-2";
45
68
  //#endregion
46
69
  export { KanbanCardShell };
@@ -12,5 +12,6 @@ import { KANBAN_DIRECTIONS, KANBAN_HORIZONTAL_EDGES, KanbanDirection, KanbanHori
12
12
  import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_CARD_DRAG_MIME, RegisterKanbanBoardAutoScrollOptions, RegisterKanbanCardDragOptions, registerKanbanBoardAutoScroll, registerKanbanCardDrag } from "./drag-interactions.js";
13
13
  import { KanbanSubgroupBandHeaderContext, KanbanSubgroupBoard, KanbanSubgroupBoardProps, KanbanSubgroupCellContext, KanbanSubgroupCollapsedBandCellContext, KanbanSubgroupColumnHeaderContext, KanbanSubgroupLaneIdentityContext } from "./subgroup-board.js";
14
14
  import { KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS } from "./band-peek.js";
15
+ import { KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_VAR, KanbanCollapsedBandCaption, KanbanCollapsedBandCaptionProps } from "./sticky-lane.js";
15
16
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps, KanbanVirtualCellSortableContext } from "./virtual-cell.js";
16
- export { type BuildKanbanBoardMatrixParams, type CreateKanbanDropIntentParams, KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, 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 KanbanBandToggleActivation, 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 };
17
+ export { type BuildKanbanBoardMatrixParams, type CreateKanbanDropIntentParams, KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, KANBAN_CARD_STICKY_TOP_VAR, 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_STICKY_TOP_VAR, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, type KanbanBandToggleActivation, 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, KanbanCollapsedBandCaption, type KanbanCollapsedBandCaptionProps, 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,4 +1,5 @@
1
1
  import { selectKanbanCardFieldIds } from "./card-properties.js";
2
+ import { KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_VAR, KanbanCollapsedBandCaption } from "./sticky-lane.js";
2
3
  import { KanbanCardShell } from "./card-shell.js";
3
4
  import { KanbanCellAction } from "./cell-action.js";
4
5
  import { KanbanColumnBandHeader } from "./column-band-header.js";
@@ -13,4 +14,4 @@ import { KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_CARD_DRAG_MIME, registerKanban
13
14
  import { KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS } from "./band-peek.js";
14
15
  import { KanbanSubgroupBoard } from "./subgroup-board.js";
15
16
  import { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell } from "./virtual-cell.js";
16
- export { KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, 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 };
17
+ export { KANBAN_BAND_PEEK_DELAY_MS, KANBAN_BAND_PEEK_LINGER_MS, KANBAN_BOARD_AUTO_SCROLL_OPTIONS, KANBAN_BOARD_AUTO_SCROLL_SOURCES, KANBAN_BOARD_AXES, KANBAN_BOARD_COLLISION_DETECTION, KANBAN_CARD_DRAG_MIME, KANBAN_CARD_STICKY_TOP_VAR, 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_STICKY_TOP_VAR, KANBAN_TOUCH_ACTIVATION_CONSTRAINT, KANBAN_VIRTUAL_CELL_PAGINATION, KanbanCardDragSurface, KanbanCardShell, KanbanCellAction, KanbanCollapsedBandCaption, 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 };
@@ -0,0 +1,74 @@
1
+ import { CSSProperties, ReactNode } from "react";
2
+ //#region src/kanban/sticky-lane.d.ts
3
+ /**
4
+ * A lane's controls while its cells scroll.
5
+ *
6
+ * A board's header block is sticky at the top of the board's scroll
7
+ * container, so anything else that must stay readable has to come to rest
8
+ * under it rather than behind it. The board publishes how far its header
9
+ * reaches in this custom property; a control sticks at that offset and
10
+ * releases where its lane ends, because the lane's own box is what bounds it.
11
+ */
12
+ declare const KANBAN_STICKY_TOP_VAR: "--kanban-sticky-top";
13
+ /**
14
+ * Sticks a lane control just under the board's header. The fallback keeps a
15
+ * control usable outside a board that publishes the offset, and inside a cell
16
+ * that keeps its own scroll surface, where the board's header is irrelevant.
17
+ */
18
+ declare const KANBAN_STICKY_TOP_CLASS = "top-(--kanban-sticky-top,0px)";
19
+ type KanbanStickyTopStyle = CSSProperties & {
20
+ [KANBAN_STICKY_TOP_VAR]?: string;
21
+ };
22
+ /**
23
+ * How far everything already pinned above a card reaches: the board's header
24
+ * block plus a cell's own pinned action, where the cell pins one. A card taller
25
+ * than the viewport keeps its identity row visible by sticking at this offset,
26
+ * so the row comes to rest under the action rather than behind it. The cell
27
+ * publishes it on each row it renders, because only the cell knows how tall its
28
+ * own pinned action turned out and how far it translated that row.
29
+ */
30
+ declare const KANBAN_CARD_STICKY_TOP_VAR: "--kanban-card-sticky-top";
31
+ /**
32
+ * Sticks a card's identity row under everything pinned above it. The fallback
33
+ * keeps the row usable inside a card rendered outside a cell that publishes the
34
+ * offset, where nothing is pinned above it at all.
35
+ */
36
+ declare const KANBAN_CARD_STICKY_TOP_CLASS = "top-(--kanban-card-sticky-top,0px)";
37
+ type KanbanCardStickyTopStyle = CSSProperties & {
38
+ [KANBAN_CARD_STICKY_TOP_VAR]?: string;
39
+ };
40
+ type ResolveKanbanCardStickyTopOptions = {
41
+ /** How far the cell's own pinned action reaches, in pixels. */
42
+ pinnedAbove: number;
43
+ /** How far the virtualizer translated the row the card sits in, in pixels. */
44
+ rowOffset: number;
45
+ };
46
+ /**
47
+ * The offset a card's identity row sticks at, in the row's own coordinates.
48
+ *
49
+ * A virtualized row is translated into place, and a transform between a sticky
50
+ * box and its scroll container is resolved in the translated space: asking for
51
+ * the board's offset there lands the row that far below its card, which parks
52
+ * it at the card's end instead. Subtracting the translation back out states the
53
+ * offset in the space the browser actually resolves it in, so every card pins
54
+ * where the chrome above it ends no matter how far down the lane it is.
55
+ */
56
+ declare const resolveKanbanCardStickyTop: ({ pinnedAbove, rowOffset }: ResolveKanbanCardStickyTopOptions) => string;
57
+ type KanbanCollapsedBandCaptionProps = {
58
+ label: string;
59
+ /** What the folded band stands in for: its count, already formatted. */
60
+ meta: ReactNode;
61
+ className?: string | undefined;
62
+ };
63
+ /**
64
+ * The name and count of a folded band, set vertically in its narrow slot.
65
+ *
66
+ * It stays under the board's header for as long as the lane lasts, so a
67
+ * folded band still says which band it is halfway down a tall lane. The slot
68
+ * has to give it room to travel: the element around it fills the slot's
69
+ * height (`h-full`), or a caption as tall as its own text can never move.
70
+ * A host rendering its own collapsed cell composes this inside that cell.
71
+ */
72
+ declare const KanbanCollapsedBandCaption: ({ className, label, meta }: KanbanCollapsedBandCaptionProps) => import("react").JSX.Element;
73
+ //#endregion
74
+ export { KANBAN_CARD_STICKY_TOP_CLASS, KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_CLASS, KANBAN_STICKY_TOP_VAR, KanbanCardStickyTopStyle, KanbanCollapsedBandCaption, KanbanCollapsedBandCaptionProps, KanbanStickyTopStyle, resolveKanbanCardStickyTop };
@@ -0,0 +1,70 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/kanban/sticky-lane.tsx
4
+ /**
5
+ * A lane's controls while its cells scroll.
6
+ *
7
+ * A board's header block is sticky at the top of the board's scroll
8
+ * container, so anything else that must stay readable has to come to rest
9
+ * under it rather than behind it. The board publishes how far its header
10
+ * reaches in this custom property; a control sticks at that offset and
11
+ * releases where its lane ends, because the lane's own box is what bounds it.
12
+ */
13
+ const KANBAN_STICKY_TOP_VAR = "--kanban-sticky-top";
14
+ /**
15
+ * Sticks a lane control just under the board's header. The fallback keeps a
16
+ * control usable outside a board that publishes the offset, and inside a cell
17
+ * that keeps its own scroll surface, where the board's header is irrelevant.
18
+ */
19
+ const KANBAN_STICKY_TOP_CLASS = "top-(--kanban-sticky-top,0px)";
20
+ /**
21
+ * How far everything already pinned above a card reaches: the board's header
22
+ * block plus a cell's own pinned action, where the cell pins one. A card taller
23
+ * than the viewport keeps its identity row visible by sticking at this offset,
24
+ * so the row comes to rest under the action rather than behind it. The cell
25
+ * publishes it on each row it renders, because only the cell knows how tall its
26
+ * own pinned action turned out and how far it translated that row.
27
+ */
28
+ const KANBAN_CARD_STICKY_TOP_VAR = "--kanban-card-sticky-top";
29
+ /**
30
+ * Sticks a card's identity row under everything pinned above it. The fallback
31
+ * keeps the row usable inside a card rendered outside a cell that publishes the
32
+ * offset, where nothing is pinned above it at all.
33
+ */
34
+ const KANBAN_CARD_STICKY_TOP_CLASS = "top-(--kanban-card-sticky-top,0px)";
35
+ /**
36
+ * The offset a card's identity row sticks at, in the row's own coordinates.
37
+ *
38
+ * A virtualized row is translated into place, and a transform between a sticky
39
+ * box and its scroll container is resolved in the translated space: asking for
40
+ * the board's offset there lands the row that far below its card, which parks
41
+ * it at the card's end instead. Subtracting the translation back out states the
42
+ * offset in the space the browser actually resolves it in, so every card pins
43
+ * where the chrome above it ends no matter how far down the lane it is.
44
+ */
45
+ const resolveKanbanCardStickyTop = ({ pinnedAbove, rowOffset }) => {
46
+ const offset = pinnedAbove - rowOffset;
47
+ return `calc(var(${KANBAN_STICKY_TOP_VAR}, 0px) ${offset < 0 ? "-" : "+"} ${String(Math.abs(offset))}px)`;
48
+ };
49
+ /**
50
+ * The name and count of a folded band, set vertically in its narrow slot.
51
+ *
52
+ * It stays under the board's header for as long as the lane lasts, so a
53
+ * folded band still says which band it is halfway down a tall lane. The slot
54
+ * has to give it room to travel: the element around it fills the slot's
55
+ * height (`h-full`), or a caption as tall as its own text can never move.
56
+ * A host rendering its own collapsed cell composes this inside that cell.
57
+ */
58
+ const KanbanCollapsedBandCaption = ({ className, label, meta }) => /* @__PURE__ */ jsxs("div", {
59
+ className: cn("text-muted-foreground sticky flex w-full flex-col items-center gap-2 self-start py-2 text-xs", KANBAN_STICKY_TOP_CLASS, className),
60
+ "data-kanban-collapsed-band-caption": "",
61
+ children: [/* @__PURE__ */ jsx("span", {
62
+ className: "max-h-40 truncate font-medium [writing-mode:vertical-rl]",
63
+ children: label
64
+ }), /* @__PURE__ */ jsx("span", {
65
+ className: "tabular-nums",
66
+ children: meta
67
+ })]
68
+ });
69
+ //#endregion
70
+ export { KANBAN_CARD_STICKY_TOP_CLASS, KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_CLASS, KANBAN_STICKY_TOP_VAR, KanbanCollapsedBandCaption, resolveKanbanCardStickyTop };
@@ -74,7 +74,9 @@ type KanbanSubgroupBoardProps<TRow> = {
74
74
  /**
75
75
  * A lane's slot while its band is collapsed. Defaults to the band's name
76
76
  * set vertically over the count; a host that accepts drops into a collapsed
77
- * band renders its target here.
77
+ * band renders its target here. Fill the slot's height (`h-full`) and
78
+ * compose `KanbanCollapsedBandCaption` inside, so the name still stays
79
+ * under the header halfway down a tall lane.
78
80
  */
79
81
  renderCollapsedBandCell?: ((context: KanbanSubgroupCollapsedBandCellContext<TRow>) => ReactNode) | undefined;
80
82
  /** Accessible name for a band's collapse toggle. */
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import { DirectionalIcon } from "../components/directional-icon.js";
3
+ import { KANBAN_STICKY_TOP_VAR, KanbanCollapsedBandCaption } from "./sticky-lane.js";
3
4
  import { KanbanColumnBandHeader } from "./column-band-header.js";
4
5
  import { KANBAN_COLLAPSED_BAND_WIDTH_CLASS, KANBAN_COLUMN_WIDTH_CLASS, resolveKanbanColumnBands } from "./column-bands.js";
5
6
  import { KANBAN_CARD_DRAG_MIME } from "./drag-interactions.js";
@@ -29,6 +30,17 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
29
30
  const [expandedEmptyLaneValues, setExpandedEmptyLaneValues] = useState(() => /* @__PURE__ */ new Set());
30
31
  const [collapsedBandIds, setCollapsedBandIds] = useState(() => /* @__PURE__ */ new Set());
31
32
  const [peekingBandId, setPeekingBandId] = useState(null);
33
+ const headerRef = useRef(null);
34
+ const [headerHeight, setHeaderHeight] = useState(0);
35
+ useEffect(() => {
36
+ const header = headerRef.current;
37
+ if (header === null) return;
38
+ const observer = new ResizeObserver(() => {
39
+ setHeaderHeight(header.getBoundingClientRect().height);
40
+ });
41
+ observer.observe(header);
42
+ return () => observer.disconnect();
43
+ }, []);
32
44
  const [peek] = useState(() => createBandPeekController({ onChange: setPeekingBandId }));
33
45
  useEffect(() => () => peek.dispose(), [peek]);
34
46
  useEffect(() => {
@@ -197,16 +209,13 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
197
209
  count,
198
210
  laneValue
199
211
  }) });
200
- return /* @__PURE__ */ jsxs("div", {
201
- className: "text-muted-foreground flex flex-col items-center gap-2 py-2 text-xs",
212
+ return /* @__PURE__ */ jsx("div", {
213
+ className: "flex h-full flex-col items-center",
202
214
  "data-kanban-collapsed-band-count": count,
203
- children: [/* @__PURE__ */ jsx("span", {
204
- className: "max-h-40 truncate font-medium [writing-mode:vertical-rl]",
205
- children: band.label
206
- }), /* @__PURE__ */ jsx("span", {
207
- className: "tabular-nums",
208
- children: formatCount(count)
209
- })]
215
+ children: /* @__PURE__ */ jsx(KanbanCollapsedBandCaption, {
216
+ label: band.label,
217
+ meta: formatCount(count)
218
+ })
210
219
  });
211
220
  };
212
221
  const foldedCount = (span, cells) => {
@@ -220,13 +229,17 @@ const KanbanSubgroupBoard = ({ matrix, renderColumnHeader, renderLaneIdentity, r
220
229
  })
221
230
  });
222
231
  };
232
+ const stickyTopStyle = { [KANBAN_STICKY_TOP_VAR]: `${String(headerHeight)}px` };
223
233
  return /* @__PURE__ */ jsx("div", {
224
234
  className: cn("h-full overflow-auto px-4 pb-4", className),
235
+ style: stickyTopStyle,
225
236
  children: /* @__PURE__ */ jsxs("div", {
226
237
  className: "min-w-max",
227
238
  children: [
228
239
  /* @__PURE__ */ jsxs("div", {
229
240
  className: "bg-background sticky top-0 z-20 pt-2 pb-2",
241
+ "data-kanban-board-header": "",
242
+ ref: headerRef,
230
243
  children: [hasBands ? /* @__PURE__ */ jsx("div", {
231
244
  className: "flex items-end gap-3 pb-1",
232
245
  "data-kanban-band-row": "",
@@ -48,12 +48,29 @@ type KanbanVirtualCellProps<TRow> = {
48
48
  */
49
49
  accent?: OptionColor | undefined;
50
50
  footer?: ReactNode;
51
+ /**
52
+ * Where the `footer` sits. `"end"` closes the cell after its rows.
53
+ * `"sticky-start"` puts it first and pins it to the top of the scroll
54
+ * container the cell lives in, so the action stays reachable through a
55
+ * lane hundreds of cards tall and releases where the lane ends.
56
+ *
57
+ * The offset comes from `KANBAN_STICKY_TOP_VAR`, which the board publishes
58
+ * for its own sticky header. A cell that keeps its bounded surface is its
59
+ * own scroll container, and the board's header means nothing inside it:
60
+ * reset the variable to `0px` on such a cell (`[--kanban-sticky-top:0px]`)
61
+ * so the action rests at the cell's own top.
62
+ *
63
+ * Either way the cell publishes the total reach of what is pinned above a
64
+ * card as `KANBAN_CARD_STICKY_TOP_VAR` on every row it renders, so a card's
65
+ * own sticky header comes to rest under the action rather than behind it.
66
+ */
67
+ footerPlacement?: "end" | "sticky-start" | undefined;
51
68
  estimateSize?: number | undefined;
52
69
  overscan?: number | undefined;
53
70
  loadMoreThreshold?: number | undefined;
54
71
  className?: string | undefined;
55
72
  };
56
73
  /** Bounded, virtualized Kanban cell with cursor-page request deduplication. */
57
- declare const KanbanVirtualCell: <TRow>({ rows, getRowKey, renderRow, pagination, sortable, containerRef, active, backgroundColor, accent, footer, estimateSize, overscan, loadMoreThreshold, className }: KanbanVirtualCellProps<TRow>) => import("react").JSX.Element;
74
+ declare const KanbanVirtualCell: <TRow>({ rows, getRowKey, renderRow, pagination, sortable, containerRef, active, backgroundColor, accent, footer, footerPlacement, estimateSize, overscan, loadMoreThreshold, className }: KanbanVirtualCellProps<TRow>) => import("react").JSX.Element;
58
75
  //#endregion
59
76
  export { KANBAN_VIRTUAL_CELL_PAGINATION, KanbanVirtualCell, KanbanVirtualCellPagination, KanbanVirtualCellProps, KanbanVirtualCellSortableContext };
@@ -1,8 +1,9 @@
1
1
  import { cn } from "../lib/utils.js";
2
+ import { KANBAN_CARD_STICKY_TOP_VAR, KANBAN_STICKY_TOP_CLASS, resolveKanbanCardStickyTop } from "./sticky-lane.js";
2
3
  import { useKanbanDropTarget } from "./sortable-interactions.js";
3
4
  import { resolveOptionColor } from "../lib/option-color.js";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
- import { useId, useRef } from "react";
6
+ import { useEffect, useId, useRef, useState } from "react";
6
7
  import { useDndContext } from "@dnd-kit/core";
7
8
  import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
8
9
  import { defaultRangeExtractor, useVirtualizer } from "@tanstack/react-virtual";
@@ -22,6 +23,12 @@ const KANBAN_CELL_ACCENT_ACTIVE_ALPHA = 22;
22
23
  /** Ring alpha for the active accent frame, well above the wash so the frame
23
24
  * still reads as the drag-over affordance rather than more background tint. */
24
25
  const KANBAN_CELL_ACCENT_ACTIVE_RING_ALPHA = 55;
26
+ /** The neutral resting surface, in one place: a pinned action repaints it
27
+ * over an opaque base, and the two must read as one surface. */
28
+ const KANBAN_CELL_SURFACE_CLASS = "bg-muted/20";
29
+ /** A caller's own surface (an explicit colour, or the accent wash), published
30
+ * so a pinned action can repaint that one instead. */
31
+ const KANBAN_CELL_SURFACE_VAR = "--kanban-cell-surface";
25
32
  const retainActiveSortableIndex = (range, activeIndex) => {
26
33
  const indexes = defaultRangeExtractor(range);
27
34
  if (activeIndex < 0 || indexes.includes(activeIndex)) return indexes;
@@ -34,7 +41,7 @@ const KANBAN_VIRTUAL_CELL_PAGINATION = {
34
41
  CURSOR: "cursor"
35
42
  };
36
43
  /** Bounded, virtualized Kanban cell with cursor-page request deduplication. */
37
- const KanbanVirtualCell = ({ rows, getRowKey, renderRow, pagination, sortable, containerRef, active = false, backgroundColor, accent, footer, estimateSize = DEFAULT_ESTIMATE_SIZE_PX, overscan = DEFAULT_OVERSCAN, loadMoreThreshold = DEFAULT_LOAD_MORE_THRESHOLD_PX, className }) => {
44
+ const KanbanVirtualCell = ({ rows, getRowKey, renderRow, pagination, sortable, containerRef, active = false, backgroundColor, accent, footer, footerPlacement = "end", estimateSize = DEFAULT_ESTIMATE_SIZE_PX, overscan = DEFAULT_OVERSCAN, loadMoreThreshold = DEFAULT_LOAD_MORE_THRESHOLD_PX, className }) => {
38
45
  const internalRef = useRef(null);
39
46
  const fallbackDropTargetId = useId();
40
47
  const scrollRef = internalRef;
@@ -85,33 +92,70 @@ const KanbanVirtualCell = ({ rows, getRowKey, renderRow, pagination, sortable, c
85
92
  const accentVariants = accent === void 0 ? void 0 : resolveOptionColor(accent);
86
93
  const accentBackground = accentVariants === void 0 ? void 0 : `color-mix(in srgb, var(${KANBAN_CELL_ACCENT_VAR}) ${active ? KANBAN_CELL_ACCENT_ACTIVE_ALPHA : KANBAN_CELL_ACCENT_RESTING_ALPHA}%, var(--background))`;
87
94
  const activeAccentRing = active && accentVariants !== void 0 ? `0 0 0 2px color-mix(in srgb, var(${KANBAN_CELL_ACCENT_VAR}) ${KANBAN_CELL_ACCENT_ACTIVE_RING_ALPHA}%, transparent)` : void 0;
88
- const style = backgroundColor === void 0 && accentVariants === void 0 ? void 0 : {
89
- backgroundColor: backgroundColor ?? accentBackground,
95
+ const surface = backgroundColor ?? accentBackground;
96
+ const style = surface === void 0 ? void 0 : {
97
+ backgroundColor: surface,
98
+ [KANBAN_CELL_SURFACE_VAR]: surface,
90
99
  ...activeAccentRing === void 0 ? void 0 : { boxShadow: activeAccentRing },
91
100
  ...accentVariants === void 0 ? void 0 : { [KANBAN_CELL_ACCENT_VAR]: accentVariants.color }
92
101
  };
102
+ const hasStickyFooter = footerPlacement === "sticky-start" && footer !== null && footer !== void 0;
103
+ const stickyFooterRef = useRef(null);
104
+ const [stickyFooterHeight, setStickyFooterHeight] = useState(0);
105
+ useEffect(() => {
106
+ const element = stickyFooterRef.current;
107
+ if (element === null) {
108
+ setStickyFooterHeight(0);
109
+ return;
110
+ }
111
+ const observer = new ResizeObserver(() => {
112
+ setStickyFooterHeight(element.getBoundingClientRect().height);
113
+ });
114
+ observer.observe(element);
115
+ return () => observer.disconnect();
116
+ }, [hasStickyFooter]);
117
+ const stickyFooter = hasStickyFooter ? /* @__PURE__ */ jsx("div", {
118
+ className: cn("bg-background sticky z-10", KANBAN_STICKY_TOP_CLASS),
119
+ "data-kanban-cell-footer": "sticky-start",
120
+ ref: stickyFooterRef,
121
+ children: /* @__PURE__ */ jsx("div", {
122
+ className: cn("pb-2", surface === void 0 ? KANBAN_CELL_SURFACE_CLASS : "bg-(--kanban-cell-surface)"),
123
+ children: footer
124
+ })
125
+ }) : null;
93
126
  const content = /* @__PURE__ */ jsxs("div", {
94
- 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 && accentVariants === void 0 && "bg-primary/5 ring-primary/50 ring-2", className),
127
+ className: cn(KANBAN_CELL_SURFACE_CLASS, "max-h-[min(60vh,40rem)] min-h-20 overflow-y-auto overscroll-y-contain rounded-xl p-2 transition-[background-color,outline-color]", active && accentVariants === void 0 && "bg-primary/5 ring-primary/50 ring-2", className),
95
128
  "data-kanban-cell": sortable?.dropTarget.id,
96
129
  "data-kanban-cell-accent": accentVariants === void 0 ? void 0 : "true",
97
130
  onScroll: handleScroll,
98
131
  ref: setScrollElement,
99
132
  style,
100
- children: [/* @__PURE__ */ jsx("div", {
101
- className: "relative",
102
- style: { height: virtualizer.getTotalSize() },
103
- children: virtualizer.getVirtualItems().map((virtualRow) => {
104
- const row = rows.at(virtualRow.index);
105
- if (row === void 0) return null;
106
- return /* @__PURE__ */ jsx("div", {
107
- className: "absolute inset-x-0 top-0 pb-2",
108
- "data-index": virtualRow.index,
109
- ref: virtualizer.measureElement,
110
- style: { transform: `translateY(${virtualRow.start}px)` },
111
- children: renderRow(row)
112
- }, getRowKey(row));
113
- })
114
- }), footer]
133
+ children: [
134
+ stickyFooter,
135
+ /* @__PURE__ */ jsx("div", {
136
+ className: "relative",
137
+ style: { height: virtualizer.getTotalSize() },
138
+ children: virtualizer.getVirtualItems().map((virtualRow) => {
139
+ const row = rows.at(virtualRow.index);
140
+ if (row === void 0) return null;
141
+ const rowStyle = {
142
+ transform: `translateY(${String(virtualRow.start)}px)`,
143
+ [KANBAN_CARD_STICKY_TOP_VAR]: resolveKanbanCardStickyTop({
144
+ pinnedAbove: stickyFooterHeight,
145
+ rowOffset: virtualRow.start
146
+ })
147
+ };
148
+ return /* @__PURE__ */ jsx("div", {
149
+ className: "absolute inset-x-0 top-0 pb-2",
150
+ "data-index": virtualRow.index,
151
+ ref: virtualizer.measureElement,
152
+ style: rowStyle,
153
+ children: renderRow(row)
154
+ }, getRowKey(row));
155
+ })
156
+ }),
157
+ footerPlacement === "end" ? footer : null
158
+ ]
115
159
  });
116
160
  if (sortable === void 0) return content;
117
161
  return /* @__PURE__ */ jsx(SortableContext, {
@@ -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 ("default" | "sm" | "lg")[];
9
9
  //#endregion
10
10
  export { CONTROL_SIZE, CONTROL_SIZES, type ControlSize };
@@ -19,5 +19,12 @@ declare const OVERLAY_LAYER_CLASS_NAMES: {
19
19
  readonly "search-child": "z-[100]";
20
20
  };
21
21
  type OverlayLayer = keyof typeof OVERLAY_LAYER_CLASS_NAMES;
22
+ /**
23
+ * Gap kept between a collision-shifted floating surface and its boundary, in
24
+ * pixels. Base UI's 5px default puts the popup shadow flush against the
25
+ * viewport edge once `shift()` has to move a popup that is wider than its
26
+ * anchor, which reads as a clipped surface rather than a repositioned one.
27
+ */
28
+ declare const OVERLAY_COLLISION_PADDING = 8;
22
29
  //#endregion
23
- export { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_LAYER_CLASS_NAMES, OverlayLayer };
30
+ export { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_COLLISION_PADDING, OVERLAY_LAYER_CLASS_NAMES, OverlayLayer };
@@ -18,5 +18,12 @@ const OVERLAY_LAYER_CLASS_NAMES = {
18
18
  /** Historical alias for `popup`; Search's own menus use the same band. */
19
19
  "search-child": "z-[100]"
20
20
  };
21
+ /**
22
+ * Gap kept between a collision-shifted floating surface and its boundary, in
23
+ * pixels. Base UI's 5px default puts the popup shadow flush against the
24
+ * viewport edge once `shift()` has to move a popup that is wider than its
25
+ * anchor, which reads as a clipped surface rather than a repositioned one.
26
+ */
27
+ const OVERLAY_COLLISION_PADDING = 8;
21
28
  //#endregion
22
- export { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_LAYER_CLASS_NAMES };
29
+ export { BOARD_DRAG_OVERLAY_Z_INDEX, OVERLAY_COLLISION_PADDING, OVERLAY_LAYER_CLASS_NAMES };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/ui",
3
- "version": "0.21.0",
3
+ "version": "0.23.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",