@ahrowe/ui 0.44.0 → 0.46.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +1 -1
  3. package/dist/cjs-types/common/button/button.types.d.ts +1 -1
  4. package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +2 -0
  5. package/dist/cjs-types/common/kanbanBoard/KanbanBoard.d.ts +1 -1
  6. package/dist/cjs-types/common/kanbanBoard/KanbanColumn.d.ts +21 -12
  7. package/dist/cjs-types/common/kanbanBoard/KanbanItem.d.ts +1 -1
  8. package/dist/cjs-types/common/kanbanBoard/kanbanBoard.types.d.ts +23 -17
  9. package/dist/cjs-types/common/kanbanBoard/kanbanBoard.utils.d.ts +47 -1
  10. package/dist/cjs-types/common/stepper/stepper.d.ts +1 -1
  11. package/dist/cjs-types/common/stepper/stepper.types.d.ts +28 -12
  12. package/dist/cjs-types/common/themeProvider/theme.types.d.ts +0 -12
  13. package/dist/esm/common/button/button.mjs +1 -1
  14. package/dist/esm/common/button/button.mjs.map +1 -1
  15. package/dist/esm/common/button/button.module.mjs +1 -1
  16. package/dist/esm/common/button/button.module.mjs.map +1 -1
  17. package/dist/esm/common/button/button.types.mjs +1 -1
  18. package/dist/esm/common/button/button.types.mjs.map +1 -1
  19. package/dist/esm/common/kanbanBoard/KanbanBoard.mjs +3 -2
  20. package/dist/esm/common/kanbanBoard/KanbanBoard.mjs.map +1 -1
  21. package/dist/esm/common/kanbanBoard/KanbanColumn.mjs +1 -1
  22. package/dist/esm/common/kanbanBoard/KanbanColumn.mjs.map +1 -1
  23. package/dist/esm/common/kanbanBoard/KanbanItem.mjs +1 -1
  24. package/dist/esm/common/kanbanBoard/KanbanItem.mjs.map +1 -1
  25. package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs +1 -1
  26. package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs.map +1 -1
  27. package/dist/esm/common/kanbanBoard/kanbanBoard.utils.mjs +1 -1
  28. package/dist/esm/common/kanbanBoard/kanbanBoard.utils.mjs.map +1 -1
  29. package/dist/esm/common/splitButton/splitButton.mjs +1 -1
  30. package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
  31. package/dist/esm/common/stepper/stepper.mjs +1 -1
  32. package/dist/esm/common/stepper/stepper.mjs.map +1 -1
  33. package/dist/esm/common/stepper/stepper.module.mjs +1 -1
  34. package/dist/esm/common/stepper/stepper.module.mjs.map +1 -1
  35. package/dist/esm/common/stepper/stepper.types.mjs +1 -1
  36. package/dist/esm/common/stepper/stepper.types.mjs.map +1 -1
  37. package/dist/esm/index.mjs +1 -1
  38. package/dist/index.cjs +4 -3
  39. package/dist/index.cjs.map +1 -1
  40. package/dist/style.css +1 -1
  41. package/dist/types/common/button/button.types.d.ts +1 -1
  42. package/dist/types/common/configProvider/configProvider.types.d.ts +2 -0
  43. package/dist/types/common/kanbanBoard/KanbanBoard.d.ts +1 -1
  44. package/dist/types/common/kanbanBoard/KanbanColumn.d.ts +21 -12
  45. package/dist/types/common/kanbanBoard/KanbanItem.d.ts +1 -1
  46. package/dist/types/common/kanbanBoard/kanbanBoard.types.d.ts +23 -17
  47. package/dist/types/common/kanbanBoard/kanbanBoard.utils.d.ts +47 -1
  48. package/dist/types/common/stepper/stepper.d.ts +1 -1
  49. package/dist/types/common/stepper/stepper.types.d.ts +28 -12
  50. package/dist/types/common/themeProvider/theme.types.d.ts +0 -12
  51. package/docs/Button.md +8 -2
  52. package/docs/CLAUDE.md +1 -1
  53. package/docs/ConfigProvider.md +1 -1
  54. package/docs/KanbanBoard.md +36 -18
  55. package/docs/SplitButton.md +1 -1
  56. package/docs/Stepper.md +57 -29
  57. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # @ahrowe/ui
2
2
 
3
+ ## 0.46.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c3be3c5: Arrow keys move focus between `KanbanBoard` cards, and between column titles with `reorderableColumns`, while nothing is picked up, and both draw the library's focus ring
8
+ - c3be3c5: `KanbanBoard` no longer collapses empty columns by default; pass `collapseEmptyColumns` to keep shrinking them to a narrow strip
9
+ - c3be3c5: With `dragHandle`, a `KanbanBoard` card's `data-drag-handle` element is also its keyboard handle, focusable and named with `getItemLabel` unless it has a name, and the card itself is no longer a button wrapped around its own controls
10
+ - c3be3c5: A `KanbanBoard` given a height, such as `style={{ height: '100%' }}` in a parent with one, fills it and scrolls each column on its own, with `onLoadMore` working there as well as with `columnMaxHeight`
11
+
12
+ ### Patch Changes
13
+
14
+ - c3be3c5: Space and Enter pressed in a control inside a `KanbanBoard` card, such as a button or an input, reach that control instead of picking the card up
15
+ - c3be3c5: A collapsed `KanbanBoard` column shows its whole title, with the count and header actions wrapping below it instead of cutting the title to a single letter
16
+ - c3be3c5: A `KanbanBoard` column being dragged shows its whole header, count and actions included, instead of a shorter bar with only the title
17
+ - c3be3c5: `KanbanBoard`'s `dragHandle` restricts mouse and touch drags to the handle again; a press anywhere on the card started one
18
+ - ef88ada: Fixed a `KanbanBoard` card staying behind when a column auto-scrolls under a pointer that holds still, and then dropping there instead of where the board showed it
19
+ - c3be3c5: `KanbanBoard` columns stretch to the height of the tallest one, so a card dropped in the empty space below a column's cards lands in that column instead of the one beside it
20
+ - c3be3c5: With `reorderableColumns`, a `KanbanBoard` header's own buttons answer Enter and Space instead of picking the column up: the column's title is now its keyboard handle, so the handle no longer wraps those buttons
21
+ - ef88ada: Fixed `KanbanBoard` losing the cards `onLoadMore` loaded during a drag, and asking for more pages over and over until the drop
22
+ - c3be3c5: Dragging a `KanbanBoard` card near the bottom of the window scrolls the page only toward a part of the board that is out of view, instead of on past the board until it was off screen
23
+ - c3be3c5: A card dragged on a `KanbanBoard` lands in the column under the pointer, including a collapsed column narrower than the card
24
+ - c3be3c5: `KanbanBoard` with `collapseEmptyColumns` keeps every column's width still during a drag, instead of widening each collapsed column the moment a card is picked up; a column the drag empties or fills changes width after the drop
25
+
26
+ ## 0.45.0
27
+
28
+ ### Minor Changes
29
+
30
+ - d77399e: Removed `ButtonSize.Default`, which was the same size as `ButtonSize.Medium`; `Medium` is now the default for Button and SplitButton
31
+ - c5e5b97: Stepper takes a `color` like the rest of the library; the six `--stepper-*` colour variables are removed, and upcoming steps use the theme's `--border-color` and `--text-dark`, which meet contrast in both built-in themes (see "Migration" in Stepper.md)
32
+ - c5e5b97: `StepperStyleType.Default` is now `StepperStyleType.Filled`, the name the other components use for the same look
33
+ - c5e5b97: Stepper's `hideLabels` hides the text visually only, so screen readers still read it, and no longer hides vertical step `content`
34
+ - c5e5b97: Stepper takes `labels` for its "Optional" hint and its screen-reader statuses, and its props can be set app-wide through `ConfigProvider`
35
+ - c5e5b97: Stepper: `alignment` and `StepperAlignment` are now `orientation` and `StepperOrientation`, as on ButtonGroup, RadioGroup and Divider, and the `'horizontal'`/`'vertical'` strings are gone
36
+
37
+ ### Patch Changes
38
+
39
+ - c5e5b97: Stepper is an ordered list that reads out each step's status, clickable steps are real buttons with a focus ring that keep focus once activated, and a collapsed step body can no longer be tabbed into
40
+ - c5e5b97: Text in a vertical Stepper's step content can be selected again, and the checkmark scales with `--stepper-marker-size`
41
+ - c5e5b97: Fixed horizontal Stepper labels spilling past the stepper's edges and overlapping the content below it: every step now takes an equal column and its label wraps within it
42
+
3
43
  ## 0.44.0
4
44
 
5
45
  ### Minor Changes
package/README.md CHANGED
@@ -182,7 +182,7 @@ runs where `@ahrowe/ui` is installed.
182
182
  | `Skeleton`, `SkeletonVariant`, `SkeletonAnimation` | Content-shaped loading placeholder, shown while real content is being fetched — more polished than a Loader for content-heavy pages (lists, cards, profile headers) |
183
183
  | `Slider` | Let the user pick a number from a continuous or stepped range by dragging a thumb: volume, brightness, price ranges, zoom, quality presets |
184
184
  | `SplitButton` | A primary action button with a small attached dropdown for closely related secondary actions, e.g. "Save ▾" opening "Save as draft" / "Save and close" |
185
- | `Stepper` | Step progress indicator for multi-step forms, onboarding flows, and checkout wizards |
185
+ | `Stepper`, `StepperOrientation`, `StepperStyleType`, `StepperCollapse`, `StepperLabelPlacement`, `ThemeColor` | Step progress indicator for multi-step forms, onboarding flows, and checkout wizards |
186
186
  | `Sticky` | Pin a piece of content to the top of the viewport once the page scrolls past it — section headers, toolbars, filter bars, table headers |
187
187
  | `Switch` | Sliding boolean toggle — settings panels, feature flags, preference lists |
188
188
  | `TabHeader` | A horizontal row of tabs to switch between sibling views or sections — settings panels, dashboards, detail pages |
@@ -14,8 +14,8 @@ export declare enum ButtonStyleType {
14
14
  Plain = "plain"
15
15
  }
16
16
  export declare enum ButtonSize {
17
- Default = "default",
18
17
  Small = "small",
18
+ /** The default. */
19
19
  Medium = "medium",
20
20
  Large = "large",
21
21
  /** Square, padding-free button for a lone icon. Give it its own width/height. */
@@ -48,6 +48,7 @@ import { RoomDrawerProps } from '../roomDrawer/roomDrawer.types.js';
48
48
  import { RoomViewerProps } from '../roomViewer/roomViewer.types.js';
49
49
  import { PopoverProps } from '../popover/popover.types.js';
50
50
  import { ModalProps } from '../modal/modal.types.js';
51
+ import { StepperProps } from '../stepper/stepper.types.js';
51
52
  import { Presentation } from '../configProvider/presentation.types.js';
52
53
  /**
53
54
  * Global default props keyed by component name.
@@ -131,6 +132,7 @@ export interface ComponentDefaults {
131
132
  Modal?: Partial<ModalProps>;
132
133
  CommandPalette?: Partial<CommandPaletteProps>;
133
134
  WeatherIcon?: Partial<WeatherIconProps>;
135
+ Stepper?: Partial<StepperProps>;
134
136
  }
135
137
  export interface ConfigProviderProps {
136
138
  children: React.ReactNode;
@@ -1,3 +1,3 @@
1
1
  import { KanbanBoardProps } from './kanbanBoard.types.js';
2
- declare function KanbanBoard<T = unknown>({ columns, items, renderItem, onChange, dragHandle, getItemLabel, getItemDisabled, renderEmptyColumn, renderColumnActions, reorderableColumns, collapseEmptyColumns, columnMaxHeight, onLoadMore, loadMoreThreshold, className, style, classNames, styles: slotStyles, ...rest }: KanbanBoardProps<T>): import("react").JSX.Element;
2
+ declare function KanbanBoard<T = unknown>({ columns, items, renderItem, onChange, dragHandle, getItemLabel, getItemDisabled, renderEmptyColumn, renderColumnActions, reorderableColumns, collapseEmptyColumns, columnMaxHeight, onLoadMore, loadMoreThreshold, onKeyDown, className, style, classNames, styles: slotStyles, ...rest }: KanbanBoardProps<T>): import("react").JSX.Element;
3
3
  export default KanbanBoard;
@@ -1,25 +1,21 @@
1
- import { ReactNode } from 'react';
2
- import { KanbanColumnProps } from './kanbanBoard.types.js';
1
+ import { HTMLAttributes, ReactNode, Ref } from 'react';
2
+ import { DataProps, SlotClassNames, SlotStyles } from '../types/slots.types.js';
3
+ import { KanbanColumnProps, KanbanColumnSlots } from './kanbanBoard.types.js';
3
4
  interface KanbanColumnInternalProps<T> extends KanbanColumnProps {
4
5
  itemIds: string[];
5
6
  items: Record<string, T>;
6
7
  renderItem: (item: T, id: string) => ReactNode;
7
8
  dragHandle?: boolean;
8
- /**
9
- * Keep the column at its normal flex width even when `itemIds` is empty. Used while a drag
10
- * is in progress: the empty-column collapse is driven by transient shadow state during a
11
- * drag, and letting the column shrink mid-drag shifts every column's layout underneath the
12
- * pointer, which can flip the collision target back and forth forever.
13
- */
14
- preserveSizeWhileEmpty?: boolean;
15
- /** Shrink to a narrow strip when empty — see `KanbanBoardProps.collapseEmptyColumns`. Defaults to `true`. */
16
- collapseEmptyColumns?: boolean;
9
+ /** Shrink to a narrow strip. The board decides when, see `KanbanBoardProps.collapseEmptyColumns`. */
10
+ collapsed?: boolean;
17
11
  /** Work-in-progress limit — see `KanbanColumnDef.maxItems`. Display-only. */
18
12
  maxItems?: number;
19
13
  /** Freezes the column — see `KanbanColumnDef.disabled`. */
20
14
  disabled?: boolean;
21
15
  /** Returns whether a specific card can't be picked up — see `KanbanBoardProps.getItemDisabled`. */
22
16
  getItemDisabled?: (item: T, id: string) => boolean;
17
+ /** Names a card's drag handle — see `KanbanBoardProps.getItemLabel`. */
18
+ getItemLabel?: (item: T, id: string) => string;
23
19
  /** Custom content shown when the column has no cards — see `KanbanBoardProps.renderEmptyColumn`. */
24
20
  emptyPlaceholder?: ReactNode;
25
21
  /** Custom header actions — see `KanbanBoardProps.renderColumnActions`. */
@@ -41,5 +37,18 @@ interface KanbanColumnInternalProps<T> extends KanbanColumnProps {
41
37
  /** Scroll distance from the bottom that triggers `onLoadMore` — see `KanbanBoardProps.loadMoreThreshold`. */
42
38
  loadMoreThreshold?: number;
43
39
  }
44
- declare function KanbanColumn<T>({ id, title, itemIds, items, renderItem, dragHandle, preserveSizeWhileEmpty, collapseEmptyColumns, maxItems, disabled, getItemDisabled, emptyPlaceholder, actions, reorderable, activeIsColumn, columnMaxHeight, hasMore, onLoadMore, loadMoreThreshold, className, style, classNames, styles: slotStyles, ...rest }: KanbanColumnInternalProps<T>): import("react").JSX.Element;
40
+ interface ColumnHeaderContentProps {
41
+ title: string;
42
+ count: number;
43
+ maxItems?: number;
44
+ actions?: ReactNode;
45
+ /** Makes the title the column's keyboard drag handle. */
46
+ titleProps?: HTMLAttributes<HTMLSpanElement> & DataProps & {
47
+ ref?: Ref<HTMLSpanElement>;
48
+ };
49
+ classNames?: SlotClassNames<KanbanColumnSlots>;
50
+ styles?: SlotStyles<KanbanColumnSlots>;
51
+ }
52
+ export declare function ColumnHeaderContent({ title, count, maxItems, actions, titleProps, classNames, styles: slotStyles, }: ColumnHeaderContentProps): import("react").JSX.Element;
53
+ declare function KanbanColumn<T>({ id, title, itemIds, items, renderItem, dragHandle, collapsed, maxItems, disabled, getItemDisabled, getItemLabel, emptyPlaceholder, actions, reorderable, activeIsColumn, columnMaxHeight, hasMore, onLoadMore, loadMoreThreshold, className, style, classNames, styles: slotStyles, ...rest }: KanbanColumnInternalProps<T>): import("react").JSX.Element;
45
54
  export default KanbanColumn;
@@ -1,3 +1,3 @@
1
1
  import { KanbanItemProps } from './kanbanBoard.types.js';
2
- declare function KanbanItem({ id, dragHandle, disabled, preventAsDropTarget, children }: KanbanItemProps): import("react").JSX.Element;
2
+ declare function KanbanItem({ id, label, dragHandle, disabled, preventAsDropTarget, children }: KanbanItemProps): import("react").JSX.Element;
3
3
  export default KanbanItem;
@@ -38,14 +38,17 @@ export interface KanbanBoardProps<T = unknown> extends Omit<HtmlProps, 'onChange
38
38
  */
39
39
  onChange: (columns: KanbanColumnDef[]) => void;
40
40
  /**
41
- * Restrict drag initiation to elements marked `data-drag-handle` within a card,
42
- * instead of the whole card. Use when `renderItem` includes interactive content
43
- * (buttons, inputs) that would otherwise have its clicks swallowed by the drag listener.
41
+ * Drag a card only by the element marked `data-drag-handle` inside it, with the mouse, touch
42
+ * and the keyboard, instead of by the whole card. The handle is made focusable and named with
43
+ * `getItemLabel` unless it has a name, and the card stops being a button. Use when `renderItem`
44
+ * includes controls (buttons, inputs): inside a card that is itself the button, a screen reader
45
+ * reads them as plain text.
44
46
  */
45
47
  dragHandle?: boolean;
46
48
  /**
47
49
  * Produce an accessible label for a card, announced to screen-reader users while dragging
48
- * (e.g. "Picked up <label>."). Defaults to the card's id when omitted.
50
+ * (e.g. "Picked up <label>."), and naming a `dragHandle` handle that has no name of its own.
51
+ * Defaults to the card's id when omitted.
49
52
  */
50
53
  getItemLabel?: (item: T, id: string) => string;
51
54
  /**
@@ -70,27 +73,28 @@ export interface KanbanBoardProps<T = unknown> extends Omit<HtmlProps, 'onChange
70
73
  */
71
74
  reorderableColumns?: boolean;
72
75
  /**
73
- * Shrink a column to a narrow strip once it has no cards, instead of keeping it at the same
74
- * width as every other column. Defaults to `true`. Set `false` to keep every column the same
75
- * width regardless of card count. The collapsed width itself is set via the
76
- * `--kanban-empty-column-width` CSS variable (falls back to `140px`) — override it theme-wide
77
- * via `ThemeProvider`'s `variables`, or per board via `style`.
76
+ * Shrink a column to a narrow strip while it has no cards. Defaults to `false`. Widths hold
77
+ * still during a drag: a column the drag empties or fills changes width after the drop. The
78
+ * collapsed width is set via the `--kanban-empty-column-width` CSS variable (falls back to
79
+ * `140px`): override it theme-wide via `ThemeProvider`'s `variables`, or per board via `style`.
78
80
  */
79
81
  collapseEmptyColumns?: boolean;
80
82
  /**
81
- * Bounds each column's height (any CSS length, e.g. `'70vh'`, `'600px'`) and makes its card
82
- * list scroll independently once content overflows, instead of growing the whole page. Leave
83
- * unset for the default unbounded height. Required for `onLoadMore` to ever trigger, since an
84
- * unbounded column never scrolls.
83
+ * Caps each column's card list at a length (any CSS length, e.g. `'70vh'`, `'600px'`), so a
84
+ * long column scrolls on its own instead of growing the page. To fill the space your layout
85
+ * gives the board instead, give the board a height (`style={{ height: '100%' }}` in a parent
86
+ * with one): its columns then scroll the same way.
85
87
  */
86
88
  columnMaxHeight?: string;
87
89
  /**
88
90
  * Called with a column's `id` when that column has `hasMore` set and its card list is scrolled
89
- * within `loadMoreThreshold` of the bottom — fetch and append the next page of items for it.
91
+ * within `loadMoreThreshold` of the bottom: fetch and append the next page of items for it.
90
92
  * `KanbanColumn` tracks its own in-flight state per column (shown as a spinner at the bottom of
91
- * the list), so overlapping calls for the same column are never made concurrently. Also
92
- * retried automatically if a loaded batch doesn't fill the column's visible height, since a
93
- * column shorter than its own viewport never generates a scroll event to trigger a next page.
93
+ * the list), so overlapping calls for the same column are never made concurrently. Also called
94
+ * while the column's cards leave empty space below them, since a column that doesn't overflow
95
+ * can't be scrolled. Paging all the way needs a column that scrolls: `columnMaxHeight`, or a
96
+ * board with a height. On a board that grows with its cards, a short column only fills up to
97
+ * the tallest one.
94
98
  */
95
99
  onLoadMore?: (columnId: string) => void | Promise<void>;
96
100
  /**
@@ -115,6 +119,8 @@ export interface KanbanColumnProps extends HtmlProps {
115
119
  }
116
120
  export interface KanbanItemProps {
117
121
  id: string;
122
+ /** Names the card's `[data-drag-handle]` when it has no `aria-label` of its own. */
123
+ label?: string;
118
124
  dragHandle?: boolean;
119
125
  /** Whether this card can't be picked up (column frozen, or the card itself is pinned). */
120
126
  disabled?: boolean;
@@ -20,8 +20,28 @@ export declare function moveColumn(columns: KanbanColumnDef[], activeColumnId: s
20
20
  * which reads as needing to "wiggle it around" before the right drop target lights up. This
21
21
  * restricts the candidates to only the same kind as whatever is being dragged: a column drag only
22
22
  * considers other columns, a card drag only considers cards and card lists.
23
+ *
24
+ * A card drag also lets the pointer pick the column, and `closestCorners` only the position within
25
+ * it. Corners alone compare the dragged card's whole rect, so a wide card over a collapsed column
26
+ * had its corners nearer the neighbours' cards, and landed beside the column under the pointer.
27
+ * Without a pointer (the keyboard) or between columns, every column is a candidate as before.
23
28
  */
24
29
  export declare const kanbanCollisionDetection: CollisionDetection;
30
+ /**
31
+ * Whether the auto-scroll may move `scroller`, an ancestor of the board such as the page, while
32
+ * something is dragged: only toward a part of the board that is out of view. Nothing beyond the
33
+ * board takes a drop, and a page left free to scroll carried the whole board off screen.
34
+ */
35
+ export declare function scrollsTowardBoard(scroller: {
36
+ top: number;
37
+ bottom: number;
38
+ }, board: {
39
+ top: number;
40
+ bottom: number;
41
+ }, dragged: {
42
+ top: number;
43
+ height: number;
44
+ }): boolean;
25
45
  /** Extracts the column id from a column droppable's `column-<id>` identifier, or `null` for a card id. */
26
46
  export declare function resolveColumnDropId(overId: string): string | null;
27
47
  export interface DragGeometry {
@@ -40,9 +60,35 @@ export interface DragGeometry {
40
60
  * position (see the two branches below for what each one decides).
41
61
  */
42
62
  export declare function moveItem(columns: KanbanColumnDef[], activeItemId: string, overId: string, geometry: DragGeometry): KanbanColumnDef[];
63
+ /**
64
+ * Where a drag has put the dragged card or column so far. The board keeps this rather than a copy
65
+ * of `columns`, so a change the consumer makes mid-drag (a page appended by `onLoadMore`) still
66
+ * shows, and is still there in what `onChange` receives on drop.
67
+ */
68
+ export interface DragPlacement {
69
+ /** The dragged card's or column's id. */
70
+ id: string;
71
+ /** The column the card sits in, or `null` while a whole column is dragged. */
72
+ columnId: string | null;
73
+ index: number;
74
+ }
75
+ /** The position `id` holds in `columns`, as a placement to lay over a later `columns`. */
76
+ export declare function findPlacement(columns: KanbanColumnDef[], id: string, isColumn: boolean): DragPlacement | null;
77
+ /**
78
+ * Moves the dragged card or column to its placement in `columns`. Returns `columns` itself when
79
+ * there is no placement, or when the card, the column, or its destination is no longer there.
80
+ */
81
+ export declare function applyPlacement(columns: KanbanColumnDef[], placement: DragPlacement | null): KanbanColumnDef[];
82
+ /**
83
+ * Where an arrow key moves focus from a focused card or column handle while nothing is picked up.
84
+ * It mirrors what the same keys do to a picked-up card: Up/Down within the column, Left/Right to
85
+ * the nearest card in the next column with anything to focus, or from a handle to the next handle.
86
+ * Returns `null` when `from` is not a card or handle, or there is nowhere to go.
87
+ */
88
+ export declare function findArrowFocusTarget(board: HTMLElement, from: HTMLElement, key: string): HTMLElement | null;
43
89
  /**
44
90
  * Builds screen-reader drag announcements against the columns layout as currently understood
45
- * (the live shadow layout while a drag is in progress, or the settled `columns` prop otherwise).
91
+ * (the live layout while a drag is in progress, or the settled `columns` prop otherwise).
46
92
  */
47
93
  export declare function buildAnnouncements<T>(columns: KanbanColumnDef[], items: Record<string, T>, getItemLabel: (item: T, id: string) => string): Announcements;
48
94
  /**
@@ -1,3 +1,3 @@
1
1
  import { default as React } from 'react';
2
2
  import { StepperProps } from './stepper.types.js';
3
- export default function Stepper({ steps, currentStep, alignment, onStepClicked, nonLinear, hideLabels, styleType, collapse, labelPlacement, className, style, classNames, styles: slotStyles, ...rest }: StepperProps): React.JSX.Element;
3
+ export default function Stepper(props: StepperProps): React.JSX.Element;
@@ -1,16 +1,17 @@
1
1
  import { default as React } from 'react';
2
2
  import { IconContent } from '../types/icon.types.js';
3
3
  import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types.js';
4
- /** Layout direction of the stepper. */
5
- export declare enum StepperAlignment {
4
+ import { ColorValue } from '../themeProvider/color.types.js';
5
+ /** Direction the steps run in. */
6
+ export declare enum StepperOrientation {
6
7
  Horizontal = "horizontal",
7
8
  Vertical = "vertical"
8
9
  }
9
- /** Visual preset for the step markers and connectors. */
10
+ /** How the step markers are drawn. */
10
11
  export declare enum StepperStyleType {
11
- /** Numbered markers, filled solid on completion (the default look). */
12
- Default = "default",
13
- /** Numbered markers that stay ringed when completed (a coloured check, no solid fill). */
12
+ /** Numbered markers, filled solid on completion. The default. */
13
+ Filled = "filled",
14
+ /** Numbered markers that stay ringed when completed, with a check in the colour. */
14
15
  Outlined = "outlined",
15
16
  /** Minimal dots without numbers, for a compact onboarding or carousel style. */
16
17
  Dots = "dots"
@@ -39,6 +40,16 @@ export declare enum StepperLabelPlacement {
39
40
  Right = "right"
40
41
  }
41
42
  export type StepperSlots = 'root' | 'entry' | 'entryNumber' | 'entryLabel' | 'connector' | 'description' | 'content' | 'optional' | 'icon';
43
+ export interface StepperLabels {
44
+ /** Hint under the label of a step with `optional: true`. */
45
+ optional?: string;
46
+ /** Status of a completed step, read out by screen readers. */
47
+ completed?: string;
48
+ /** Status of a step not reached yet, read out by screen readers. */
49
+ notCompleted?: string;
50
+ /** Status of a step with `error`, read out by screen readers. */
51
+ error?: string;
52
+ }
42
53
  export interface StepperStep {
43
54
  /** Primary label for the step. */
44
55
  label: React.ReactNode;
@@ -48,28 +59,33 @@ export interface StepperStep {
48
59
  content?: React.ReactNode;
49
60
  /** Icon shown in the marker instead of the step number — a FontAwesome icon or any node. */
50
61
  icon?: IconContent;
51
- /** Marks the step as errored, recolouring the marker with `--stepper-error-color`. */
62
+ /** Marks the step as errored, drawing its marker in the theme's `--error-color`. */
52
63
  error?: boolean;
53
- /** `true` renders an "Optional" hint; a node renders custom hint text. */
64
+ /** `true` renders the `optional` label as a hint; a node renders custom hint text. */
54
65
  optional?: boolean | React.ReactNode;
55
66
  /** Disables this step: never clickable, dimmed. */
56
67
  disabled?: boolean;
57
68
  }
58
- export interface StepperProps extends HtmlProps {
69
+ export interface StepperProps extends HtmlProps<HTMLOListElement> {
59
70
  steps?: StepperStep[];
71
+ /** Zero-based index of the current step. `steps.length` marks every step completed. */
60
72
  currentStep?: number;
61
- alignment?: StepperAlignment | 'horizontal' | 'vertical';
73
+ /** Direction the steps run in (default `Horizontal`). */
74
+ orientation?: StepperOrientation;
62
75
  onStepClicked?: ((index: number) => void) | null;
63
76
  /** Allow clicking any step, not just completed ones. */
64
77
  nonLinear?: boolean;
65
- /** Hide the label text (and description) beneath each step entry. */
78
+ /** Hide each step's label, description and hint visually. Screen readers still read them. */
66
79
  hideLabels?: boolean;
67
- /** Visual preset for markers and connectors (default `Default`). */
80
+ /** How the markers are drawn (default `Filled`). */
68
81
  styleType?: StepperStyleType;
82
+ /** A `ThemeColor` (default `Primary`) or any CSS colour, such as `'var(--brand)'`. */
83
+ color?: ColorValue;
69
84
  /** Which step bodies are expanded. Vertical `content` only (default `None`). */
70
85
  collapse?: StepperCollapse;
71
86
  /** Label position relative to the marker (default: horizontal `Bottom`, vertical `Right`). */
72
87
  labelPlacement?: StepperLabelPlacement;
88
+ labels?: StepperLabels;
73
89
  className?: string;
74
90
  style?: React.CSSProperties;
75
91
  classNames?: SlotClassNames<StepperSlots>;
@@ -125,24 +125,12 @@ export interface ThemeVariables {
125
125
  '--stepper-marker-size'?: string;
126
126
  /** Step marker corner radius. Falls back to --default-border-radius. */
127
127
  '--stepper-marker-radius'?: string;
128
- /** Idle (upcoming) marker/connector colour. Falls back to --primary-lighter. */
129
- '--stepper-idle-color'?: string;
130
- /** Current-step marker colour. Falls back to --primary-color. */
131
- '--stepper-active-color'?: string;
132
- /** Completed-step marker fill/colour. Falls back to --primary-color. */
133
- '--stepper-done-color'?: string;
134
- /** Errored-step marker colour. Falls back to --error-color. */
135
- '--stepper-error-color'?: string;
136
- /** Completed connector colour. Falls back to --primary-color. */
137
- '--stepper-connector-color'?: string;
138
128
  /** Completed connector thickness. Falls back to 3px. */
139
129
  '--stepper-connector-thickness'?: string;
140
130
  /** Not-yet-reached connector thickness. Falls back to 1px. */
141
131
  '--stepper-connector-idle-thickness'?: string;
142
132
  /** Gap between marker and label, and grid column gap. Falls back to 12px. */
143
133
  '--stepper-gap'?: string;
144
- /** Text/check colour on a filled marker. Falls back to --text-on-primary. */
145
- '--stepper-text-on-marker'?: string;
146
134
  /** Timer ring track (unfilled) colour. Falls back to --background-accent-light. */
147
135
  '--timer-track-color'?: string;
148
136
  /** Timer ring progress (remaining time) colour. Falls back to --primary-color. */
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{ThemeColor as t}from"../themeProvider/color.types.mjs";import{toneProps as n,useToneCheck as r}from"../styles/tone.mjs";import i from"./button.module.mjs";import a from"../loader/loader.mjs";import{ButtonSize as o,ButtonStyleType as s,ButtonType as c}from"./button.types.mjs";import l from"../ripple/ripple.mjs";import{renderIcon as u}from"../utils/renderIcon.mjs";import{useRef as d}from"react";import f from"classnames";import{jsx as p,jsxs as m}from"react/jsx-runtime";var h={filled:i.buttonStyleFilled,light:i.buttonStyleLight,outlined:i.buttonStyleOutlined,plain:i.buttonStylePlain},g={default:i.buttonSizeDefault,small:i.buttonSizeSmall,medium:i.buttonSizeMedium,large:i.buttonSizeLarge,icon:i.buttonSizeIcon},_=`color-mix(in srgb, currentcolor 20%, transparent)`;function v(v){let{className:y,style:b,type:x=c.Button,styleType:S=s.Outlined,color:C=t.Primary,size:w=o.Default,onClick:T=()=>{},children:E,icon:D,isLoading:O=!1,disabled:k=!1,title:A=void 0,ref:j,classNames:M,styles:N,...P}=e(`Button`,v),F=d(null),I=n(C);r(`Button`,[C]);function L(e){return e.detail===0&&F.current?.addRipple(),T(e)}return p(`button`,{...P,className:f(i.button,h[S],I.className,g[w],{[i.buttonNotAllowed]:O||k,[i.buttonDisabled]:k},y),style:{...I.style,...b},type:x,onClick:L,disabled:k||O,title:A,ref:j,children:p(l,{ref:F,className:i.buttonRipple,disabled:O||k,rippleBackground:_,children:p(`div`,{className:f(i.buttonBackground,M?.background),style:N?.background,children:m(`div`,{className:f(i.buttonContent,M?.content),style:N?.content,children:[O?p(`div`,{className:f(i.buttonLoadingContainer,M?.loadingContainer),style:N?.loadingContainer,children:p(a,{size:`1.2em`,color:t.Neutral})}):null,m(`div`,{className:f(M?.label,{[i.buttonLoading]:O,[i.buttonWithIcon]:!!D}),style:N?.label,children:[D?u(D):null,E]})]})})})})}v.StyleType=s,v.Size=o,v.Type=c;export{v as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{ThemeColor as t}from"../themeProvider/color.types.mjs";import{toneProps as n,useToneCheck as r}from"../styles/tone.mjs";import i from"./button.module.mjs";import a from"../loader/loader.mjs";import{ButtonSize as o,ButtonStyleType as s,ButtonType as c}from"./button.types.mjs";import l from"../ripple/ripple.mjs";import{renderIcon as u}from"../utils/renderIcon.mjs";import{useRef as d}from"react";import f from"classnames";import{jsx as p,jsxs as m}from"react/jsx-runtime";var h={filled:i.buttonStyleFilled,light:i.buttonStyleLight,outlined:i.buttonStyleOutlined,plain:i.buttonStylePlain},g={small:i.buttonSizeSmall,medium:i.buttonSizeMedium,large:i.buttonSizeLarge,icon:i.buttonSizeIcon},_=`color-mix(in srgb, currentcolor 20%, transparent)`;function v(v){let{className:y,style:b,type:x=c.Button,styleType:S=s.Outlined,color:C=t.Primary,size:w=o.Medium,onClick:T=()=>{},children:E,icon:D,isLoading:O=!1,disabled:k=!1,title:A=void 0,ref:j,classNames:M,styles:N,...P}=e(`Button`,v),F=d(null),I=n(C);r(`Button`,[C]);function L(e){return e.detail===0&&F.current?.addRipple(),T(e)}return p(`button`,{...P,className:f(i.button,h[S],I.className,g[w],{[i.buttonNotAllowed]:O||k,[i.buttonDisabled]:k},y),style:{...I.style,...b},type:x,onClick:L,disabled:k||O,title:A,ref:j,children:p(l,{ref:F,className:i.buttonRipple,disabled:O||k,rippleBackground:_,children:p(`div`,{className:f(i.buttonBackground,M?.background),style:N?.background,children:m(`div`,{className:f(i.buttonContent,M?.content),style:N?.content,children:[O?p(`div`,{className:f(i.buttonLoadingContainer,M?.loadingContainer),style:N?.loadingContainer,children:p(a,{size:`1.2em`,color:t.Neutral})}):null,m(`div`,{className:f(M?.label,{[i.buttonLoading]:O,[i.buttonWithIcon]:!!D}),style:N?.label,children:[D?u(D):null,E]})]})})})})}v.StyleType=s,v.Size=o,v.Type=c;export{v as default};
2
2
  //# sourceMappingURL=button.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.mjs","names":[],"sources":["../../../../package/common/button/button.tsx"],"sourcesContent":["import cx from 'classnames';\nimport { useRef, type ReactElement } from 'react';\n\nimport styles from './button.module.pcss';\nimport Loader from '../loader';\nimport { ButtonStyleType, ButtonSize, ButtonType } from './button.types';\nimport { ThemeColor } from '../themeProvider/color.types';\nimport type { ButtonProps } from './button.types';\nimport Ripple from '../ripple';\nimport type { RippleHandle } from '../ripple';\nimport { useComponentDefaults } from '../configProvider';\nimport { renderIcon } from '../utils/renderIcon';\nimport { toneProps, useToneCheck } from '../styles/tone';\n\nconst CLASS_BY_STYLE: Record<ButtonStyleType, string> = {\n filled: styles.buttonStyleFilled,\n light: styles.buttonStyleLight,\n outlined: styles.buttonStyleOutlined,\n plain: styles.buttonStylePlain,\n};\n\nconst CLASS_BY_SIZE: Record<ButtonSize, string> = {\n default: styles.buttonSizeDefault,\n small: styles.buttonSizeSmall,\n medium: styles.buttonSizeMedium,\n large: styles.buttonSizeLarge,\n icon: styles.buttonSizeIcon,\n};\n\n// Ripple's own default is white, which vanishes on a transparent button over a light page.\nconst RIPPLE_BACKGROUND = 'color-mix(in srgb, currentcolor 20%, transparent)';\n\nfunction Button(props: ButtonProps): ReactElement {\n const {\n className,\n style,\n type = ButtonType.Button,\n styleType = ButtonStyleType.Outlined,\n color = ThemeColor.Primary,\n size = ButtonSize.Default,\n onClick = (): void => {},\n children,\n icon,\n isLoading = false,\n disabled = false,\n title = undefined,\n ref,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Button', props);\n\n const rippleRef = useRef<RippleHandle>(null);\n const tone = toneProps(color);\n useToneCheck('Button', [color]);\n\n function handleClick(event: React.MouseEvent<HTMLButtonElement>) {\n if (event.detail === 0) rippleRef.current?.addRipple();\n return onClick(event);\n }\n\n return (\n <button\n {...rest}\n className={cx(\n styles.button,\n CLASS_BY_STYLE[styleType],\n tone.className,\n CLASS_BY_SIZE[size],\n {\n [styles.buttonNotAllowed]: isLoading || disabled,\n [styles.buttonDisabled]: disabled,\n },\n className,\n )}\n style={{ ...tone.style, ...style }}\n type={type}\n onClick={handleClick}\n disabled={disabled || isLoading}\n title={title}\n ref={ref}\n >\n <Ripple\n ref={rippleRef}\n className={styles.buttonRipple}\n disabled={isLoading || disabled}\n rippleBackground={RIPPLE_BACKGROUND}\n >\n <div className={cx(styles.buttonBackground, classNames?.background)} style={slotStyles?.background}>\n <div className={cx(styles.buttonContent, classNames?.content)} style={slotStyles?.content}>\n {isLoading ? (\n <div\n className={cx(styles.buttonLoadingContainer, classNames?.loadingContainer)}\n style={slotStyles?.loadingContainer}\n >\n <Loader size='1.2em' color={ThemeColor.Neutral} />\n </div>\n ) : null}\n <div\n className={cx(classNames?.label, {\n [styles.buttonLoading]: isLoading,\n [styles.buttonWithIcon]: !!icon,\n })}\n style={slotStyles?.label}\n >\n {icon ? renderIcon(icon) : null}\n {children}\n </div>\n </div>\n </div>\n </Ripple>\n </button>\n );\n}\n\nButton.StyleType = ButtonStyleType;\nButton.Size = ButtonSize;\nButton.Type = ButtonType;\n\nexport default Button;\n"],"mappings":"8jBAcA,IAAM,EAAkD,CACtD,OAAQ,EAAO,kBACf,MAAO,EAAO,iBACd,SAAU,EAAO,oBACjB,MAAO,EAAO,gBAChB,EAEM,EAA4C,CAChD,QAAS,EAAO,kBAChB,MAAO,EAAO,gBACd,OAAQ,EAAO,iBACf,MAAO,EAAO,gBACd,KAAM,EAAO,cACf,EAGM,EAAoB,oDAE1B,SAAS,EAAO,EAAkC,CAChD,GAAM,CACJ,YACA,QACA,OAAO,EAAW,OAClB,YAAY,EAAgB,SAC5B,QAAQ,EAAW,QACnB,OAAO,EAAW,QAClB,cAAsB,CAAC,EACvB,WACA,OACA,YAAY,GACZ,WAAW,GACX,QAAQ,IAAA,GACR,MACA,aACA,OAAQ,EACR,GAAG,GACD,EAAqB,SAAU,CAAK,EAElC,EAAY,EAAqB,IAAI,EACrC,EAAO,EAAU,CAAK,EAC5B,EAAa,SAAU,CAAC,CAAK,CAAC,EAE9B,SAAS,EAAY,EAA4C,CAE/D,OADI,EAAM,SAAW,GAAG,EAAU,SAAS,UAAU,EAC9C,EAAQ,CAAK,CACtB,CAEA,OACE,EAAC,SAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,OACP,EAAe,GACf,EAAK,UACL,EAAc,GACd,EACG,EAAO,kBAAmB,GAAa,GACvC,EAAO,gBAAiB,CAC3B,EACA,CACF,EACA,MAAO,CAAE,GAAG,EAAK,MAAO,GAAG,CAAM,EAC3B,OACN,QAAS,EACT,SAAU,GAAY,EACf,QACF,MAEL,SAAA,EAAC,EAAD,CACE,IAAK,EACL,UAAW,EAAO,aAClB,SAAU,GAAa,EACvB,iBAAkB,EAElB,SAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,iBAAkB,GAAY,UAAU,EAAG,MAAO,GAAY,WACtF,SAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,cAAe,GAAY,OAAO,EAAG,MAAO,GAAY,QAAlF,SAAA,CACG,EACC,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,uBAAwB,GAAY,gBAAgB,EACzE,MAAO,GAAY,iBAEnB,SAAA,EAAC,EAAD,CAAQ,KAAK,QAAQ,MAAO,EAAW,OAAU,CAAA,CAC9C,CAAA,EACH,KACJ,EAAC,MAAD,CACE,UAAW,EAAG,GAAY,MAAO,EAC9B,EAAO,eAAgB,GACvB,EAAO,gBAAiB,CAAC,CAAC,CAC7B,CAAC,EACD,MAAO,GAAY,MALrB,SAAA,CAOG,EAAO,EAAW,CAAI,EAAI,KAC1B,CACE,CACF,CAAA,CAAA,GACF,CAAA,CACC,CAAA,CACF,CAAA,CAEZ,CAEA,EAAO,UAAY,EACnB,EAAO,KAAO,EACd,EAAO,KAAO"}
1
+ {"version":3,"file":"button.mjs","names":[],"sources":["../../../../package/common/button/button.tsx"],"sourcesContent":["import cx from 'classnames';\nimport { useRef, type ReactElement } from 'react';\n\nimport styles from './button.module.pcss';\nimport Loader from '../loader';\nimport { ButtonStyleType, ButtonSize, ButtonType } from './button.types';\nimport { ThemeColor } from '../themeProvider/color.types';\nimport type { ButtonProps } from './button.types';\nimport Ripple from '../ripple';\nimport type { RippleHandle } from '../ripple';\nimport { useComponentDefaults } from '../configProvider';\nimport { renderIcon } from '../utils/renderIcon';\nimport { toneProps, useToneCheck } from '../styles/tone';\n\nconst CLASS_BY_STYLE: Record<ButtonStyleType, string> = {\n filled: styles.buttonStyleFilled,\n light: styles.buttonStyleLight,\n outlined: styles.buttonStyleOutlined,\n plain: styles.buttonStylePlain,\n};\n\nconst CLASS_BY_SIZE: Record<ButtonSize, string> = {\n small: styles.buttonSizeSmall,\n medium: styles.buttonSizeMedium,\n large: styles.buttonSizeLarge,\n icon: styles.buttonSizeIcon,\n};\n\n// Ripple's own default is white, which vanishes on a transparent button over a light page.\nconst RIPPLE_BACKGROUND = 'color-mix(in srgb, currentcolor 20%, transparent)';\n\nfunction Button(props: ButtonProps): ReactElement {\n const {\n className,\n style,\n type = ButtonType.Button,\n styleType = ButtonStyleType.Outlined,\n color = ThemeColor.Primary,\n size = ButtonSize.Medium,\n onClick = (): void => {},\n children,\n icon,\n isLoading = false,\n disabled = false,\n title = undefined,\n ref,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Button', props);\n\n const rippleRef = useRef<RippleHandle>(null);\n const tone = toneProps(color);\n useToneCheck('Button', [color]);\n\n function handleClick(event: React.MouseEvent<HTMLButtonElement>) {\n if (event.detail === 0) rippleRef.current?.addRipple();\n return onClick(event);\n }\n\n return (\n <button\n {...rest}\n className={cx(\n styles.button,\n CLASS_BY_STYLE[styleType],\n tone.className,\n CLASS_BY_SIZE[size],\n {\n [styles.buttonNotAllowed]: isLoading || disabled,\n [styles.buttonDisabled]: disabled,\n },\n className,\n )}\n style={{ ...tone.style, ...style }}\n type={type}\n onClick={handleClick}\n disabled={disabled || isLoading}\n title={title}\n ref={ref}\n >\n <Ripple\n ref={rippleRef}\n className={styles.buttonRipple}\n disabled={isLoading || disabled}\n rippleBackground={RIPPLE_BACKGROUND}\n >\n <div className={cx(styles.buttonBackground, classNames?.background)} style={slotStyles?.background}>\n <div className={cx(styles.buttonContent, classNames?.content)} style={slotStyles?.content}>\n {isLoading ? (\n <div\n className={cx(styles.buttonLoadingContainer, classNames?.loadingContainer)}\n style={slotStyles?.loadingContainer}\n >\n <Loader size='1.2em' color={ThemeColor.Neutral} />\n </div>\n ) : null}\n <div\n className={cx(classNames?.label, {\n [styles.buttonLoading]: isLoading,\n [styles.buttonWithIcon]: !!icon,\n })}\n style={slotStyles?.label}\n >\n {icon ? renderIcon(icon) : null}\n {children}\n </div>\n </div>\n </div>\n </Ripple>\n </button>\n );\n}\n\nButton.StyleType = ButtonStyleType;\nButton.Size = ButtonSize;\nButton.Type = ButtonType;\n\nexport default Button;\n"],"mappings":"8jBAcA,IAAM,EAAkD,CACtD,OAAQ,EAAO,kBACf,MAAO,EAAO,iBACd,SAAU,EAAO,oBACjB,MAAO,EAAO,gBAChB,EAEM,EAA4C,CAChD,MAAO,EAAO,gBACd,OAAQ,EAAO,iBACf,MAAO,EAAO,gBACd,KAAM,EAAO,cACf,EAGM,EAAoB,oDAE1B,SAAS,EAAO,EAAkC,CAChD,GAAM,CACJ,YACA,QACA,OAAO,EAAW,OAClB,YAAY,EAAgB,SAC5B,QAAQ,EAAW,QACnB,OAAO,EAAW,OAClB,cAAsB,CAAC,EACvB,WACA,OACA,YAAY,GACZ,WAAW,GACX,QAAQ,IAAA,GACR,MACA,aACA,OAAQ,EACR,GAAG,GACD,EAAqB,SAAU,CAAK,EAElC,EAAY,EAAqB,IAAI,EACrC,EAAO,EAAU,CAAK,EAC5B,EAAa,SAAU,CAAC,CAAK,CAAC,EAE9B,SAAS,EAAY,EAA4C,CAE/D,OADI,EAAM,SAAW,GAAG,EAAU,SAAS,UAAU,EAC9C,EAAQ,CAAK,CACtB,CAEA,OACE,EAAC,SAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,OACP,EAAe,GACf,EAAK,UACL,EAAc,GACd,EACG,EAAO,kBAAmB,GAAa,GACvC,EAAO,gBAAiB,CAC3B,EACA,CACF,EACA,MAAO,CAAE,GAAG,EAAK,MAAO,GAAG,CAAM,EAC3B,OACN,QAAS,EACT,SAAU,GAAY,EACf,QACF,MAEL,SAAA,EAAC,EAAD,CACE,IAAK,EACL,UAAW,EAAO,aAClB,SAAU,GAAa,EACvB,iBAAkB,EAElB,SAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,iBAAkB,GAAY,UAAU,EAAG,MAAO,GAAY,WACtF,SAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,cAAe,GAAY,OAAO,EAAG,MAAO,GAAY,QAAlF,SAAA,CACG,EACC,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,uBAAwB,GAAY,gBAAgB,EACzE,MAAO,GAAY,iBAEnB,SAAA,EAAC,EAAD,CAAQ,KAAK,QAAQ,MAAO,EAAW,OAAU,CAAA,CAC9C,CAAA,EACH,KACJ,EAAC,MAAD,CACE,UAAW,EAAG,GAAY,MAAO,EAC9B,EAAO,eAAgB,GACvB,EAAO,gBAAiB,CAAC,CAAC,CAC7B,CAAC,EACD,MAAO,GAAY,MALrB,SAAA,CAOG,EAAO,EAAW,CAAI,EAAI,KAC1B,CACE,CACF,CAAA,CAAA,GACF,CAAA,CACC,CAAA,CACF,CAAA,CAEZ,CAEA,EAAO,UAAY,EACnB,EAAO,KAAO,EACd,EAAO,KAAO"}
@@ -1,2 +1,2 @@
1
- "use client";var e=`button_wYLPJ`,t=`button-notAllowed_xGT-E`,n=`button-disabled_XDm5w`,r=`button-content_Q-0-4`,i=`button-loading_TY6y7`,a=`button-loading-container_pMSta`,o=`button-withIcon_IXEKA`,s=`button-style-filled_gsaJ4`,c=`button-style-light_HBi34`,l=`button-style-outlined_OSfMq`,u=`button-style-plain_CUtTy`,d=`button-background_9Vfo5`,f=`button-size-default_N4HG9`,p=`button-size-small_mn6jE`,m=`button-size-medium_gNVDM`,h=`button-size-large_xSIcS`,g=`button-size-icon_pkqwl`,_=`button-ripple_UGtt8`,v={button:e,"button-notAllowed":`button-notAllowed_xGT-E`,buttonNotAllowed:t,"button-disabled":`button-disabled_XDm5w`,buttonDisabled:n,"button-content":`button-content_Q-0-4`,buttonContent:r,"button-loading":`button-loading_TY6y7`,buttonLoading:i,"button-loading-container":`button-loading-container_pMSta`,buttonLoadingContainer:a,"button-withIcon":`button-withIcon_IXEKA`,buttonWithIcon:o,"button-style-filled":`button-style-filled_gsaJ4`,buttonStyleFilled:s,"button-style-light":`button-style-light_HBi34`,buttonStyleLight:c,"button-style-outlined":`button-style-outlined_OSfMq`,buttonStyleOutlined:l,"button-style-plain":`button-style-plain_CUtTy`,buttonStylePlain:u,"button-background":`button-background_9Vfo5`,buttonBackground:d,"button-size-default":`button-size-default_N4HG9`,buttonSizeDefault:f,"button-size-small":`button-size-small_mn6jE`,buttonSizeSmall:p,"button-size-medium":`button-size-medium_gNVDM`,buttonSizeMedium:m,"button-size-large":`button-size-large_xSIcS`,buttonSizeLarge:h,"button-size-icon":`button-size-icon_pkqwl`,buttonSizeIcon:g,"button-ripple":`button-ripple_UGtt8`,buttonRipple:_};export{e as button,d as buttonBackground,r as buttonContent,n as buttonDisabled,i as buttonLoading,a as buttonLoadingContainer,t as buttonNotAllowed,_ as buttonRipple,f as buttonSizeDefault,g as buttonSizeIcon,h as buttonSizeLarge,m as buttonSizeMedium,p as buttonSizeSmall,s as buttonStyleFilled,c as buttonStyleLight,l as buttonStyleOutlined,u as buttonStylePlain,o as buttonWithIcon,v as default};
1
+ "use client";var e=`button_wYLPJ`,t=`button-notAllowed_xGT-E`,n=`button-disabled_XDm5w`,r=`button-content_Q-0-4`,i=`button-loading_TY6y7`,a=`button-loading-container_pMSta`,o=`button-withIcon_IXEKA`,s=`button-style-filled_gsaJ4`,c=`button-style-light_HBi34`,l=`button-style-outlined_OSfMq`,u=`button-style-plain_CUtTy`,d=`button-background_9Vfo5`,f=`button-size-small_mn6jE`,p=`button-size-medium_gNVDM`,m=`button-size-large_xSIcS`,h=`button-size-icon_pkqwl`,g=`button-ripple_UGtt8`,_={button:e,"button-notAllowed":`button-notAllowed_xGT-E`,buttonNotAllowed:t,"button-disabled":`button-disabled_XDm5w`,buttonDisabled:n,"button-content":`button-content_Q-0-4`,buttonContent:r,"button-loading":`button-loading_TY6y7`,buttonLoading:i,"button-loading-container":`button-loading-container_pMSta`,buttonLoadingContainer:a,"button-withIcon":`button-withIcon_IXEKA`,buttonWithIcon:o,"button-style-filled":`button-style-filled_gsaJ4`,buttonStyleFilled:s,"button-style-light":`button-style-light_HBi34`,buttonStyleLight:c,"button-style-outlined":`button-style-outlined_OSfMq`,buttonStyleOutlined:l,"button-style-plain":`button-style-plain_CUtTy`,buttonStylePlain:u,"button-background":`button-background_9Vfo5`,buttonBackground:d,"button-size-small":`button-size-small_mn6jE`,buttonSizeSmall:f,"button-size-medium":`button-size-medium_gNVDM`,buttonSizeMedium:p,"button-size-large":`button-size-large_xSIcS`,buttonSizeLarge:m,"button-size-icon":`button-size-icon_pkqwl`,buttonSizeIcon:h,"button-ripple":`button-ripple_UGtt8`,buttonRipple:g};export{e as button,d as buttonBackground,r as buttonContent,n as buttonDisabled,i as buttonLoading,a as buttonLoadingContainer,t as buttonNotAllowed,g as buttonRipple,h as buttonSizeIcon,m as buttonSizeLarge,p as buttonSizeMedium,f as buttonSizeSmall,s as buttonStyleFilled,c as buttonStyleLight,l as buttonStyleOutlined,u as buttonStylePlain,o as buttonWithIcon,_ as default};
2
2
  //# sourceMappingURL=button.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.module.mjs","names":[],"sources":["../../../../package/common/button/button.module.pcss"],"sourcesContent":[".button {\n appearance: none;\n -webkit-appearance: none;\n box-sizing: border-box;\n font-size: var(--default-font-size);\n background: transparent;\n border: 1px solid transparent;\n padding: 0;\n font-family: var(--default-font);\n border-radius: var(--default-border-radius);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n position: relative;\n overflow: hidden;\n min-width: min-content;\n\n /* Hover and press layer in currentcolor, so one rule fits every style. On the root, which a\n stretched button's inner element would not fill; under the Ripple wrapper, which comes later. */\n &::before {\n content: '';\n position: absolute;\n inset: 0;\n background: currentcolor;\n opacity: 0;\n transition: opacity 0.15s;\n pointer-events: none;\n }\n\n &-notAllowed {\n cursor: not-allowed;\n }\n\n /* Disabled only, not loading: a faded spinner would read as disabled rather than working. */\n &-disabled {\n opacity: 0.5;\n }\n\n /* Inside the edge: outside, a ButtonGroup neighbour with the same fill swallows the ring. A\n Filled button draws it in its text colour instead, as Pagination's active item does. */\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -4px;\n }\n\n /* (hover: hover) because on touch a tap latches :hover until the next tap elsewhere. */\n @media (hover: hover) {\n &:hover:not(:disabled)::before {\n opacity: 0.08;\n }\n }\n\n /* After the hover rule, which it ties on specificity: a press is a hover too. */\n &:active:not(:disabled)::before {\n opacity: 0.16;\n }\n\n &-content {\n position: relative;\n white-space: break-spaces;\n }\n\n &-loading {\n visibility: hidden;\n\n &-container {\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n }\n\n &-withIcon {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n }\n\n &-style {\n &-filled {\n background: var(--tone-fill);\n\n /* Must follow the shorthand above, which resets background-image. */\n background-image: var(--tone-gradient);\n color: var(--tone-contrast);\n\n /* After the base :focus-visible rule, which it ties on specificity. */\n &:focus-visible {\n outline-color: currentcolor;\n }\n }\n\n &-light {\n background: var(--tone-light);\n color: var(--tone-text);\n }\n\n &-outlined {\n color: var(--tone-text);\n border-color: var(--tone-outline);\n }\n\n &-plain {\n color: var(--tone-text);\n }\n }\n\n &-background {\n display: block;\n padding: 0.5em 0.75em;\n }\n\n /* Multiples of the theme's base, not em: an em on font-size resolves against the parent,\n so these would follow whatever the button sits in rather than the theme. */\n &-size {\n &-default {\n font-size: var(--default-font-size);\n }\n\n &-small {\n font-size: calc(var(--default-font-size) * 0.75);\n }\n\n &-medium {\n /* Medium button is same as default for now */\n font-size: var(--default-font-size);\n }\n\n &-large {\n font-size: calc(var(--default-font-size) * 1.25);\n }\n\n /* Square, padding-free button for a lone icon; the caller sets the box size. */\n &-icon {\n display: inline-flex;\n\n /* Inherits, unlike the other sizes: a hardcoded px value would have to be out-specified\n from another stylesheet, a specificity tie decided only by bundle order. */\n font-size: inherit;\n\n .button-ripple,\n .button-background,\n .button-content {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n padding: 0;\n }\n }\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"button.module.mjs","names":[],"sources":["../../../../package/common/button/button.module.pcss"],"sourcesContent":[".button {\n appearance: none;\n -webkit-appearance: none;\n box-sizing: border-box;\n font-size: var(--default-font-size);\n background: transparent;\n border: 1px solid transparent;\n padding: 0;\n font-family: var(--default-font);\n border-radius: var(--default-border-radius);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n position: relative;\n overflow: hidden;\n min-width: min-content;\n\n /* Hover and press layer in currentcolor, so one rule fits every style. On the root, which a\n stretched button's inner element would not fill; under the Ripple wrapper, which comes later. */\n &::before {\n content: '';\n position: absolute;\n inset: 0;\n background: currentcolor;\n opacity: 0;\n transition: opacity 0.15s;\n pointer-events: none;\n }\n\n &-notAllowed {\n cursor: not-allowed;\n }\n\n /* Disabled only, not loading: a faded spinner would read as disabled rather than working. */\n &-disabled {\n opacity: 0.5;\n }\n\n /* Inside the edge: outside, a ButtonGroup neighbour with the same fill swallows the ring. A\n Filled button draws it in its text colour instead, as Pagination's active item does. */\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -4px;\n }\n\n /* (hover: hover) because on touch a tap latches :hover until the next tap elsewhere. */\n @media (hover: hover) {\n &:hover:not(:disabled)::before {\n opacity: 0.08;\n }\n }\n\n /* After the hover rule, which it ties on specificity: a press is a hover too. */\n &:active:not(:disabled)::before {\n opacity: 0.16;\n }\n\n &-content {\n position: relative;\n white-space: break-spaces;\n }\n\n &-loading {\n visibility: hidden;\n\n &-container {\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n }\n\n &-withIcon {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5em;\n }\n\n &-style {\n &-filled {\n background: var(--tone-fill);\n\n /* Must follow the shorthand above, which resets background-image. */\n background-image: var(--tone-gradient);\n color: var(--tone-contrast);\n\n /* After the base :focus-visible rule, which it ties on specificity. */\n &:focus-visible {\n outline-color: currentcolor;\n }\n }\n\n &-light {\n background: var(--tone-light);\n color: var(--tone-text);\n }\n\n &-outlined {\n color: var(--tone-text);\n border-color: var(--tone-outline);\n }\n\n &-plain {\n color: var(--tone-text);\n }\n }\n\n &-background {\n display: block;\n padding: 0.5em 0.75em;\n }\n\n /* Multiples of the theme's base, not em: an em on font-size resolves against the parent,\n so these would follow whatever the button sits in rather than the theme. */\n &-size {\n &-small {\n font-size: calc(var(--default-font-size) * 0.75);\n }\n\n &-medium {\n font-size: var(--default-font-size);\n }\n\n &-large {\n font-size: calc(var(--default-font-size) * 1.25);\n }\n\n /* Square, padding-free button for a lone icon; the caller sets the box size. */\n &-icon {\n display: inline-flex;\n\n /* Inherits, unlike the other sizes: a hardcoded px value would have to be out-specified\n from another stylesheet, a specificity tie decided only by bundle order. */\n font-size: inherit;\n\n .button-ripple,\n .button-background,\n .button-content {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n padding: 0;\n }\n }\n }\n}\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- "use client";var e=function(e){return e.Filled=`filled`,e.Light=`light`,e.Outlined=`outlined`,e.Plain=`plain`,e}({}),t=function(e){return e.Default=`default`,e.Small=`small`,e.Medium=`medium`,e.Large=`large`,e.Icon=`icon`,e}({}),n=function(e){return e.Button=`button`,e.Reset=`reset`,e.Submit=`submit`,e}({});export{t as ButtonSize,e as ButtonStyleType,n as ButtonType};
1
+ "use client";var e=function(e){return e.Filled=`filled`,e.Light=`light`,e.Outlined=`outlined`,e.Plain=`plain`,e}({}),t=function(e){return e.Small=`small`,e.Medium=`medium`,e.Large=`large`,e.Icon=`icon`,e}({}),n=function(e){return e.Button=`button`,e.Reset=`reset`,e.Submit=`submit`,e}({});export{t as ButtonSize,e as ButtonStyleType,n as ButtonType};
2
2
  //# sourceMappingURL=button.types.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.types.mjs","names":[],"sources":["../../../../package/common/button/button.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { CSSProperties } from 'react';\nimport type { IconContent } from '../types/icon.types';\nimport type { SlotClassNames, SlotStyles, DataProps } from '../types/slots.types';\nimport type { ColorValue } from '../themeProvider/color.types';\n\n/** How much the button stands out. Independent of its colour. */\nexport enum ButtonStyleType {\n /** Solid fill, for the one main action. */\n Filled = 'filled',\n /** A light tint of the colour behind text in the colour. */\n Light = 'light',\n /** Border and text in the colour, no fill. The default. */\n Outlined = 'outlined',\n /** Text in the colour, no fill and no border. For toolbar, icon and close buttons. */\n Plain = 'plain',\n}\n\nexport enum ButtonSize {\n Default = 'default',\n Small = 'small',\n Medium = 'medium',\n Large = 'large',\n /** Square, padding-free button for a lone icon. Give it its own width/height. */\n Icon = 'icon',\n}\n\nexport enum ButtonType {\n Button = 'button',\n Reset = 'reset',\n Submit = 'submit',\n}\n\nexport type ButtonSlots = 'background' | 'content' | 'loadingContainer' | 'label';\n\n/**\n * `DataProps` supplies the `data-*` index signature, which `ButtonHTMLAttributes` doesn't cover.\n * `type`, `color` and `onClick` below deliberately narrow their inherited counterparts.\n */\nexport interface ButtonProps extends DataProps, React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n style?: CSSProperties;\n type?: ButtonType;\n /** Emphasis: `Filled`, `Light`, `Outlined` (default) or `Plain`. */\n styleType?: ButtonStyleType;\n /** A `ThemeColor` (default `Primary`) or any CSS colour, such as `'var(--brand)'`. */\n color?: ColorValue;\n size?: ButtonSize;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n children?: React.ReactNode;\n icon?: IconContent;\n isLoading?: boolean;\n disabled?: boolean;\n title?: string;\n ref?: React.Ref<HTMLButtonElement>;\n classNames?: SlotClassNames<ButtonSlots>;\n styles?: SlotStyles<ButtonSlots>;\n}\n"],"mappings":"aAOA,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,OAAA,SAEA,EAAA,MAAA,QAEA,EAAA,SAAA,WAEA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA,EAEY,EAAL,SAAA,EAAA,OACL,GAAA,QAAA,UACA,EAAA,MAAA,QACA,EAAA,OAAA,SACA,EAAA,MAAA,QAEA,EAAA,KAAA,QACF,EAAA,CAAA,CAAA,EAEY,EAAL,SAAA,EAAA,OACL,GAAA,OAAA,SACA,EAAA,MAAA,QACA,EAAA,OAAA,UACF,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"button.types.mjs","names":[],"sources":["../../../../package/common/button/button.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { CSSProperties } from 'react';\nimport type { IconContent } from '../types/icon.types';\nimport type { SlotClassNames, SlotStyles, DataProps } from '../types/slots.types';\nimport type { ColorValue } from '../themeProvider/color.types';\n\n/** How much the button stands out. Independent of its colour. */\nexport enum ButtonStyleType {\n /** Solid fill, for the one main action. */\n Filled = 'filled',\n /** A light tint of the colour behind text in the colour. */\n Light = 'light',\n /** Border and text in the colour, no fill. The default. */\n Outlined = 'outlined',\n /** Text in the colour, no fill and no border. For toolbar, icon and close buttons. */\n Plain = 'plain',\n}\n\nexport enum ButtonSize {\n Small = 'small',\n /** The default. */\n Medium = 'medium',\n Large = 'large',\n /** Square, padding-free button for a lone icon. Give it its own width/height. */\n Icon = 'icon',\n}\n\nexport enum ButtonType {\n Button = 'button',\n Reset = 'reset',\n Submit = 'submit',\n}\n\nexport type ButtonSlots = 'background' | 'content' | 'loadingContainer' | 'label';\n\n/**\n * `DataProps` supplies the `data-*` index signature, which `ButtonHTMLAttributes` doesn't cover.\n * `type`, `color` and `onClick` below deliberately narrow their inherited counterparts.\n */\nexport interface ButtonProps extends DataProps, React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n style?: CSSProperties;\n type?: ButtonType;\n /** Emphasis: `Filled`, `Light`, `Outlined` (default) or `Plain`. */\n styleType?: ButtonStyleType;\n /** A `ThemeColor` (default `Primary`) or any CSS colour, such as `'var(--brand)'`. */\n color?: ColorValue;\n size?: ButtonSize;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => Promise<void> | void;\n children?: React.ReactNode;\n icon?: IconContent;\n isLoading?: boolean;\n disabled?: boolean;\n title?: string;\n ref?: React.Ref<HTMLButtonElement>;\n classNames?: SlotClassNames<ButtonSlots>;\n styles?: SlotStyles<ButtonSlots>;\n}\n"],"mappings":"aAOA,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,OAAA,SAEA,EAAA,MAAA,QAEA,EAAA,SAAA,WAEA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA,EAEY,EAAL,SAAA,EAAA,OACL,GAAA,MAAA,QAEA,EAAA,OAAA,SACA,EAAA,MAAA,QAEA,EAAA,KAAA,QACF,EAAA,CAAA,CAAA,EAEY,EAAL,SAAA,EAAA,OACL,GAAA,OAAA,SACA,EAAA,MAAA,QACA,EAAA,OAAA,UACF,EAAA,CAAA,CAAA"}
@@ -1,7 +1,8 @@
1
- "use client";import e from"./kanbanBoard.module.mjs";import t from"./KanbanColumn.mjs";import{buildAnnouncements as n,columnsEqual as r,isColumnDragData as i,kanbanCollisionDetection as a,kanbanKeyboardCoordinateGetter as o,moveColumn as s,moveItem as c}from"./kanbanBoard.utils.mjs";import{useMemo as l,useRef as u,useState as d}from"react";import f from"classnames";import{jsx as p,jsxs as m}from"react/jsx-runtime";import{DndContext as h,DragOverlay as g,KeyboardSensor as _,MouseSensor as v,TouchSensor as y,useSensor as b,useSensors as x}from"@dnd-kit/core";import{SortableContext as S,horizontalListSortingStrategy as C}from"@dnd-kit/sortable";var ee=(e,t)=>t,te={activationConstraint:{distance:8}},ne={activationConstraint:{delay:250,tolerance:5}},re={coordinateGetter:o},w={draggable:`
1
+ "use client";import e from"./kanbanBoard.module.mjs";import t,{ColumnHeaderContent as n}from"./KanbanColumn.mjs";import{applyPlacement as r,buildAnnouncements as i,columnsEqual as a,findArrowFocusTarget as o,findPlacement as s,isColumnDragData as c,kanbanCollisionDetection as ee,kanbanKeyboardCoordinateGetter as l,moveColumn as te,moveItem as ne,scrollsTowardBoard as re}from"./kanbanBoard.utils.mjs";import{useCallback as ie,useEffect as ae,useMemo as u,useRef as d,useState as f}from"react";import p from"classnames";import{jsx as m,jsxs as oe}from"react/jsx-runtime";import{DndContext as h,DragOverlay as g,KeyboardSensor as _,MouseSensor as v,TouchSensor as se,useSensor as y,useSensors as ce}from"@dnd-kit/core";import{SortableContext as le,horizontalListSortingStrategy as ue}from"@dnd-kit/sortable";var de=(e,t)=>t,fe={activationConstraint:{distance:8}},pe={activationConstraint:{delay:250,tolerance:5}},me={coordinateGetter:l},he={draggable:`
2
2
  To pick up a card or column, press space or enter.
3
+ Use the arrow keys to move between cards and columns.
3
4
  While dragging, use the arrow keys to move it — for a card, between positions and columns;
4
5
  for a column, left/right to reorder it.
5
6
  Press space or enter again to drop it, or press escape to cancel.
6
- `};function T({columns:o,items:T,renderItem:E,onChange:D,dragHandle:O,getItemLabel:k=ee,getItemDisabled:A,renderEmptyColumn:j,renderColumnActions:M,reorderableColumns:N,collapseEmptyColumns:P,columnMaxHeight:F,onLoadMore:I,loadMoreThreshold:L,className:R,style:z,classNames:ie,styles:B,...V}){let[H,U]=d(null),[W,G]=d(!1),[K,q]=d(null),J=u(null),Y=x(b(v,te),b(y,ne),b(_,re)),X=K??o,ae=l(()=>X.map(e=>e.id),[X]),Z=l(()=>n(X,T,k),[X,T,k]),oe=l(()=>({announcements:Z,screenReaderInstructions:w}),[Z]);function se({active:e}){U(String(e.id)),G(i(e.data.current)),q(o),J.current=null}function Q({active:e,over:t}){if(!t)return;if(i(e.data.current)){let n=String(e.id),r=String(t.id);q(e=>{let t=e??o,i=s(t,n,r);return i===t?e:i});return}let n=String(e.id),r=String(t.id),a=e.rect.current.translated??e.rect.current.initial,l=a?`${a.top}:${a.left}`:null;(l===null||l!==J.current)&&(J.current=l,q(e=>{let i=e??o,s=c(i,n,r,{activeRect:a,overRect:t.rect});return s===i?e:s}))}function ce({over:e}){if(U(null),G(!1),!e||!K){q(null);return}r(K,o)||D(K),q(null)}function le(){U(null),G(!1),q(null)}let $=H&&W?X.find(e=>e.id===H):void 0;return m(h,{sensors:Y,collisionDetection:a,onDragStart:se,onDragOver:Q,onDragEnd:ce,onDragCancel:le,accessibility:oe,children:[p(S,{id:`kanban-columns`,items:ae,strategy:C,children:p(`div`,{...V,className:f(e.board,R),style:z,children:X.map(e=>p(t,{id:e.id,title:e.title,itemIds:e.itemIds,maxItems:e.maxItems,disabled:e.disabled,getItemDisabled:A,emptyPlaceholder:j?.(e),actions:M?.(e),reorderable:N,activeIsColumn:H!==null&&W,collapseEmptyColumns:P,columnMaxHeight:F,hasMore:e.hasMore,onLoadMore:I?()=>I(e.id):void 0,loadMoreThreshold:L,items:T,renderItem:E,dragHandle:O,preserveSizeWhileEmpty:H!==null},e.id))})}),p(g,{children:$?p(`div`,{className:f(e.column,e.columnDragOverlay),children:p(`div`,{className:e.columnHeader,children:p(`span`,{className:e.columnHeaderTitle,children:$.title})})}):H&&!W&&T[H]!==void 0?p(`div`,{className:f(e.dragOverlay,ie?.dragOverlay),style:B?.dragOverlay,children:E(T[H],H)}):null})]})}export{T as default};
7
+ `};function b({columns:l,items:b,renderItem:x,onChange:ge,dragHandle:S,getItemLabel:C=de,getItemDisabled:w,renderEmptyColumn:T,renderColumnActions:E,reorderableColumns:D,collapseEmptyColumns:O=!1,columnMaxHeight:k,onLoadMore:A,loadMoreThreshold:j,onKeyDown:M,className:N,style:P,classNames:F,styles:I,...L}){let[R,z]=f(null),[B,V]=f(!1),[H,U]=f(null),W=d(null),G=d(null),K=d(null),q=ie(e=>{let t=G.current,n=K.current?.current.translated;if(!t||!n||t.contains(e))return!0;let r=e===document.scrollingElement?{top:0,bottom:window.innerHeight}:e.getBoundingClientRect();return re(r,t.getBoundingClientRect(),n)},[]),[,_e]=f(0),J=R!==null;ae(()=>{if(!J)return;let e=({target:e})=>{let t=G.current;if(!t||!(e instanceof Node)||!(e.contains(t)||t.contains(e)))return;W.current=null;let n=e===document?document.scrollingElement:e;n instanceof Element&&!q(n)&&_e(e=>e+1)};return window.addEventListener(`scroll`,e,{capture:!0,passive:!0}),()=>window.removeEventListener(`scroll`,e,{capture:!0})},[J,q]);let Y=ce(y(v,fe),y(se,pe),y(_,me)),X=u(()=>r(l,H),[l,H]),ve=u(()=>X.map(e=>e.id),[X]),ye=u(()=>new Set(O?l.filter(e=>e.itemIds.length===0).map(e=>e.id):[]),[l,O]),Z=u(()=>i(X,b,C),[X,b,C]),be=u(()=>({announcements:Z,screenReaderInstructions:he}),[Z]);function xe(e){if(M?.(e),e.defaultPrevented||R!==null||!G.current||!(e.target instanceof HTMLElement)||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)return;let t=o(G.current,e.target,e.key);t&&(e.preventDefault(),t.focus())}function Se({active:e}){z(String(e.id)),V(c(e.data.current)),K.current=e.rect,W.current=null}function Ce({active:e,over:t}){if(!t)return;if(c(e.data.current)){let n=String(e.id),i=String(t.id);U(e=>{let t=r(l,e),a=te(t,n,i);return a===t?e:s(a,n,!0)});return}let n=String(e.id),i=String(t.id),a=e.rect.current.translated??e.rect.current.initial,o=a?`${a.top}:${a.left}`:null;(o===null||o!==W.current)&&(W.current=o,U(e=>{let o=r(l,e),c=ne(o,n,i,{activeRect:a,overRect:t.rect});return c===o?e:s(c,n,!1)}))}function we({over:e}){Q(),e&&!a(X,l)&&ge(X)}function Q(){z(null),V(!1),U(null)}let $=R&&B?X.find(e=>e.id===R):void 0;return oe(h,{sensors:Y,collisionDetection:ee,onDragStart:Se,onDragOver:Ce,onDragEnd:we,onDragCancel:Q,accessibility:be,autoScroll:{canScroll:e=>q(e)},children:[m(le,{id:`kanban-columns`,items:ve,strategy:ue,children:m(`div`,{...L,ref:G,className:p(e.board,N),style:P,onKeyDown:xe,children:X.map(e=>m(t,{id:e.id,title:e.title,itemIds:e.itemIds,maxItems:e.maxItems,disabled:e.disabled,getItemDisabled:w,getItemLabel:C,emptyPlaceholder:T?.(e),actions:E?.(e),reorderable:D,activeIsColumn:R!==null&&B,collapsed:ye.has(e.id),columnMaxHeight:k,hasMore:e.hasMore,onLoadMore:A?()=>A(e.id):void 0,loadMoreThreshold:j,items:b,renderItem:x,dragHandle:S},e.id))})}),m(g,{children:$?m(`div`,{className:p(e.column,e.columnDragOverlay),inert:!0,children:m(`div`,{className:e.columnHeader,children:m(n,{title:$.title,count:$.itemIds.length,maxItems:$.maxItems,actions:E?.($)})})}):R&&!B&&b[R]!==void 0?m(`div`,{className:p(e.dragOverlay,F?.dragOverlay),style:I?.dragOverlay,children:x(b[R],R)}):null})]})}export{b as default};
7
8
  //# sourceMappingURL=KanbanBoard.mjs.map