@ssa-ui-kit/core 3.26.4 → 3.27.1

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 (44) hide show
  1. package/dist/ai/source-map.md +107 -37
  2. package/dist/components/Calendar/Calendar.d.ts +11 -3
  3. package/dist/components/Calendar/CalendarContext.d.ts +12 -1
  4. package/dist/components/Calendar/components/CalendarToolbar.d.ts +5 -1
  5. package/dist/components/Calendar/components/DayView.d.ts +4 -2
  6. package/dist/components/Calendar/components/TimeZoneSelect.d.ts +14 -0
  7. package/dist/components/Calendar/consts.d.ts +14 -1
  8. package/dist/components/Calendar/styles.d.ts +37 -1
  9. package/dist/components/Calendar/types.d.ts +93 -5
  10. package/dist/components/Calendar/utils.d.ts +35 -5
  11. package/dist/components/DataTable/DataTable.d.ts +79 -0
  12. package/dist/components/DataTable/DataTableColumnPicker.d.ts +66 -0
  13. package/dist/components/DataTable/ExpanderCell.d.ts +10 -0
  14. package/dist/components/DataTable/SelectionCell.d.ts +25 -0
  15. package/dist/components/DataTable/index.d.ts +4 -0
  16. package/dist/components/DataTable/styles.d.ts +47 -0
  17. package/dist/components/DataTable/types.d.ts +378 -0
  18. package/dist/components/DataTable/useColumnReorder.d.ts +31 -0
  19. package/dist/components/DataTable/useDataTableModel.d.ts +36 -0
  20. package/dist/components/DataTable/utils.d.ts +82 -0
  21. package/dist/components/Dropdown/Dropdown.d.ts +1 -1
  22. package/dist/components/Dropdown/types.d.ts +34 -0
  23. package/dist/components/DropdownOption/DropdownOption.d.ts +5 -0
  24. package/dist/components/DropdownOptions/DropdownSearch.d.ts +25 -0
  25. package/dist/components/DropdownOptions/useToggleListKeys.d.ts +13 -7
  26. package/dist/components/DropdownOptions/utils.d.ts +7 -0
  27. package/dist/components/DropdownToggle/types.d.ts +2 -0
  28. package/dist/components/MultipleDropdown/types.d.ts +25 -0
  29. package/dist/components/NestedTable/WithNestedTableRow.d.ts +4 -0
  30. package/dist/components/NestedTable/components/NestedTable.d.ts +4 -0
  31. package/dist/components/NestedTable/components/NestedTableCell.d.ts +4 -0
  32. package/dist/components/NestedTable/components/NestedTableCellHeader.d.ts +4 -0
  33. package/dist/components/NestedTable/components/NestedTableRow.d.ts +4 -0
  34. package/dist/components/Table/ColumnFreezeMenu.d.ts +11 -1
  35. package/dist/components/Table/ColumnMenu.d.ts +30 -0
  36. package/dist/components/Table/Table.d.ts +4 -4
  37. package/dist/components/Table/types.d.ts +77 -6
  38. package/dist/components/TableCellHeader/TableCellHeader.d.ts +1 -1
  39. package/dist/components/TableCellHeader/types.d.ts +14 -5
  40. package/dist/components/index.d.ts +2 -0
  41. package/dist/index.js +2932 -600
  42. package/dist/index.mjs +2932 -601
  43. package/dist/tsbuildcache +1 -1
  44. package/package.json +6 -5
@@ -0,0 +1,378 @@
1
+ import { CSSProperties, KeyboardEvent, MouseEvent, ReactNode, Ref } from 'react';
2
+ import { ColumnResizeMode } from '../Table/types';
3
+ /** Direction of a {@link DataTableSort}. */
4
+ export type DataTableSortDirection = 'asc' | 'desc';
5
+ /**
6
+ * How many rows of a {@link DataTable} the user can select: `multiple` adds a
7
+ * checkbox column with a select-all checkbox, `single` a radio column.
8
+ */
9
+ export type DataTableSelectionMode = 'none' | 'single' | 'multiple';
10
+ /**
11
+ * Attributes a {@link DataTable} adds to one body row or cell, returned by
12
+ * `getRowProps` on the table or `getCellProps` on a column. For styling a row
13
+ * or cell from its data.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * getRowProps: (row) => ({
18
+ * className: row.excluded ? 'excluded' : undefined,
19
+ * background: row.awaitingReply ? 'rgba(242, 136, 142, 0.08)' : undefined,
20
+ * })
21
+ * ```
22
+ */
23
+ export interface DataTableElementProps {
24
+ /** Added to the element's class names. */
25
+ className?: string;
26
+ /**
27
+ * Inline style of the element. On a row, a `background` here is hidden by
28
+ * the cells, which paint their own; use the `background` field instead.
29
+ */
30
+ style?: CSSProperties;
31
+ /**
32
+ * A colour painted over the cells, such as a translucent tint. Laid over
33
+ * white, so frozen cells stay opaque. On a row, the hover and selected
34
+ * states show over it; on a cell, it stays.
35
+ */
36
+ background?: string;
37
+ /** `data-*` attributes, for CSS or tests. */
38
+ [dataAttribute: `data-${string}`]: string | number | boolean | undefined;
39
+ }
40
+ /**
41
+ * The column a {@link DataTable} is sorted by. One column at a time; `null`
42
+ * when the rows are in the order they were given.
43
+ */
44
+ export interface DataTableSort {
45
+ /** `id` of the sorted column. */
46
+ columnId: string;
47
+ direction: DataTableSortDirection;
48
+ }
49
+ /**
50
+ * One column of a {@link DataTable}.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * const columns: DataTableColumn<Employee>[] = [
55
+ * { id: 'name', header: 'Name', cell: (row) => row.name, sortable: true },
56
+ * { id: 'salary', header: 'Salary', cell: (row) => fmt(row.salary), align: 'right' },
57
+ * ];
58
+ * ```
59
+ */
60
+ export interface DataTableColumn<Row> {
61
+ /**
62
+ * Stable, unique id. Column state (order, widths, frozen, hidden) and the
63
+ * sort refer to columns by it, so it must not change between renders.
64
+ */
65
+ id: string;
66
+ /** Header cell content. */
67
+ header: ReactNode;
68
+ /**
69
+ * Body cell content for a row. `rowIndex` is the row's position as shown,
70
+ * after sorting, not its index in `data`.
71
+ */
72
+ cell: (row: Row, rowIndex: number) => ReactNode;
73
+ /**
74
+ * Text alignment of the header and body cells.
75
+ * @default 'left'
76
+ */
77
+ align?: 'left' | 'center' | 'right';
78
+ /**
79
+ * Whether clicking the header sorts by this column.
80
+ * @default false
81
+ */
82
+ sortable?: boolean;
83
+ /**
84
+ * The name the server knows this column by, when it differs from `id`.
85
+ * Handed to `onSortChange` as its second argument.
86
+ * @default id
87
+ */
88
+ sortKey?: string;
89
+ /**
90
+ * Sorts the rows in the browser while this column is the sorted one.
91
+ * Without it, sorting only reports the new sort through `onSortChange` and
92
+ * the rows are expected to arrive sorted, which is right for server data.
93
+ *
94
+ * Compare ascending; the table reverses the result for `desc`.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * sortFn: (a, b) => a.name.localeCompare(b.name)
99
+ * ```
100
+ */
101
+ sortFn?: (a: Row, b: Row) => number;
102
+ /**
103
+ * Starting width in pixels, used until the user resizes the column or
104
+ * `columnState.widths` says otherwise. Columns without one are measured on
105
+ * first layout.
106
+ */
107
+ width?: number;
108
+ /**
109
+ * Narrowest the user can resize this column to, in pixels. Overrides the
110
+ * table's `minColumnWidth`.
111
+ */
112
+ minWidth?: number;
113
+ /**
114
+ * Widest the user can resize this column to, in pixels. Overrides the
115
+ * table's `maxColumnWidth`.
116
+ */
117
+ maxWidth?: number;
118
+ /**
119
+ * Class name, style, background or data attributes for this column's body
120
+ * cell in a given row, such as colouring a cell by its value. Header cells
121
+ * are not affected.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * getCellProps: (row) => ({ background: heatColor(row.score) })
126
+ * ```
127
+ */
128
+ getCellProps?: (row: Row, rowIndex: number) => DataTableElementProps;
129
+ /**
130
+ * Whether the user can resize this column, in a table with
131
+ * `resizableColumns`. Turn it off for actions or checkbox columns.
132
+ * @default true
133
+ */
134
+ resizable?: boolean;
135
+ /**
136
+ * Whether the header offers the freeze menu, in a table with
137
+ * `freezeControls`. The column can still be frozen through `columnState`.
138
+ * @default true
139
+ */
140
+ freezable?: boolean;
141
+ /**
142
+ * Whether the user can move this column, in a table with
143
+ * `reorderableColumns`. A column that cannot move keeps its place, and the
144
+ * others move past it.
145
+ * @default true
146
+ */
147
+ reorderable?: boolean;
148
+ /**
149
+ * Whether the user can hide this column, from its header menu in a table
150
+ * with `hideableColumns`, or from `DataTableColumnPicker`. The column can
151
+ * still be hidden through `columnState`.
152
+ * @default true
153
+ */
154
+ hideable?: boolean;
155
+ }
156
+ /**
157
+ * Everything about a {@link DataTable}'s columns the user can change, keyed
158
+ * by column id, so it survives columns being added, removed or reordered.
159
+ * Store it whole to remember a user's layout.
160
+ */
161
+ export interface DataTableColumnState {
162
+ /**
163
+ * Column ids in display order. Columns missing from it follow, in the
164
+ * order of `columns`.
165
+ */
166
+ order: string[];
167
+ /** Width in pixels per column id. */
168
+ widths: Record<string, number>;
169
+ /** Column ids frozen to each edge. */
170
+ frozen: {
171
+ start: string[];
172
+ end: string[];
173
+ };
174
+ /** Ids of columns that are not shown. */
175
+ hidden: string[];
176
+ }
177
+ /**
178
+ * Props of {@link DataTable}.
179
+ *
180
+ * @example
181
+ * ```tsx
182
+ * <DataTable data={rows} columns={columns} />
183
+ * ```
184
+ */
185
+ export interface DataTableProps<Row> {
186
+ /** Rows to show, in the order to show them unless a column sorts them. */
187
+ data: Row[];
188
+ /**
189
+ * Column definitions. Every `id` must be unique. Need not be memoised:
190
+ * the table only rebuilds its model when the columns' ids or sort settings
191
+ * change, and always renders with the latest `header` and `cell`.
192
+ */
193
+ columns: DataTableColumn<Row>[];
194
+ /**
195
+ * Stable id of a row, for rows whose id is not in an `id` field, such as
196
+ * `employeeId` or a key built from several fields. Rows are keyed by it
197
+ * and selection and expanded state refer to it.
198
+ *
199
+ * Without it, a row's own `id` (string or number) is used. Rows without
200
+ * either are keyed by position, children under their parent (`"2.0"`),
201
+ * which remounts cells whenever the order changes.
202
+ * @default (row) => String(row.id)
203
+ */
204
+ getRowId?: (row: Row, index: number) => string;
205
+ /**
206
+ * Column layout, for the controlled case. Partial values are filled in
207
+ * with defaults. Hold it in state and update it from
208
+ * `onColumnStateChange`.
209
+ */
210
+ columnState?: Partial<DataTableColumnState>;
211
+ /** Starting column layout, for the uncontrolled case. */
212
+ defaultColumnState?: Partial<DataTableColumnState>;
213
+ /**
214
+ * Called whenever the user changes the layout: on every frame of a resize
215
+ * drag, when moving or hiding a column, and when freezing or unfreezing. Not called for widths the table
216
+ * measures itself on first layout.
217
+ */
218
+ onColumnStateChange?: (columnState: DataTableColumnState) => void;
219
+ /**
220
+ * Lets the user resize columns by dragging the right edge of the header.
221
+ * @default false
222
+ */
223
+ resizableColumns?: boolean;
224
+ /**
225
+ * How a resize spends width. `fit` keeps the table's width: the resizable
226
+ * columns to the right share the change, in proportion to their widths.
227
+ * `expand` grows or shrinks the table instead, so it scrolls sideways.
228
+ * @default 'fit'
229
+ */
230
+ columnResizeMode?: ColumnResizeMode;
231
+ /**
232
+ * Narrowest a column can be resized to, in pixels. A column's own
233
+ * `minWidth` wins.
234
+ * @default 64
235
+ */
236
+ minColumnWidth?: number;
237
+ /**
238
+ * Widest a column can be resized to, in pixels. A column's own `maxWidth`
239
+ * wins. Unbounded when omitted.
240
+ */
241
+ maxColumnWidth?: number;
242
+ /**
243
+ * Gives every header a menu to freeze its column to either edge.
244
+ * @default false
245
+ */
246
+ freezeControls?: boolean;
247
+ /**
248
+ * Lets the user move columns: by dragging the grip at the left of the
249
+ * header, or with "Move left" and "Move right" in the header menu. A column
250
+ * moves only among columns frozen to the same edge, or among the unfrozen
251
+ * ones. The order is kept in `columnState.order`.
252
+ * @default false
253
+ */
254
+ reorderableColumns?: boolean;
255
+ /**
256
+ * Adds "Hide column" to the header menu. The last visible column cannot be
257
+ * hidden. Hidden columns are kept in `columnState.hidden`; bring them back
258
+ * with `DataTableColumnPicker`.
259
+ * @default false
260
+ */
261
+ hideableColumns?: boolean;
262
+ /**
263
+ * Keeps the header in view while the rows scroll. Give the table a height
264
+ * limit through `maxHeight`.
265
+ * @default false
266
+ */
267
+ stickyHeader?: boolean;
268
+ /**
269
+ * Tallest the table gets before it scrolls vertically. Any CSS value.
270
+ * Unbounded when omitted, so only horizontal overflow scrolls.
271
+ */
272
+ maxHeight?: string | number;
273
+ /** Sorted column, for the controlled case. `null` for none. */
274
+ sort?: DataTableSort | null;
275
+ /** Starting sort, for the uncontrolled case. */
276
+ defaultSort?: DataTableSort | null;
277
+ /**
278
+ * Called when a sortable header is clicked. A column starts ascending and
279
+ * toggles between ascending and descending after that. The second argument
280
+ * is the column's `sortKey` (its `id` without one), ready for a request.
281
+ */
282
+ onSortChange?: (sort: DataTableSort | null, sortKey: string | null) => void;
283
+ /**
284
+ * Marks the table busy. Rows already shown stay, dimmed, so a re-fetch
285
+ * after sorting does not make the table jump; with no rows yet,
286
+ * `loadingState` is shown instead.
287
+ * @default false
288
+ */
289
+ isLoading?: boolean;
290
+ /**
291
+ * Shown in place of the rows while loading with none to show.
292
+ * @default 'Loading…'
293
+ */
294
+ loadingState?: ReactNode;
295
+ /**
296
+ * Shown in place of the rows when there are none.
297
+ * @default 'No results'
298
+ */
299
+ emptyState?: ReactNode;
300
+ /**
301
+ * Called when a row is clicked, or when Enter is pressed on a focused row;
302
+ * rows become focusable when this is set. Clicks on a button, link, input
303
+ * or menu inside the row keep their own behaviour.
304
+ *
305
+ * Screen readers do not announce a row as actionable, so also give the
306
+ * row a link or button in a cell when the action matters.
307
+ */
308
+ onRowClick?: (row: Row, event: MouseEvent<HTMLTableRowElement> | KeyboardEvent<HTMLTableRowElement>) => void;
309
+ /**
310
+ * Class name, style, background or data attributes for a body row, such as
311
+ * tinting rows that need attention. Each row also carries `data-row-id`.
312
+ *
313
+ * @example
314
+ * ```ts
315
+ * getRowProps: (row) => (row.excluded ? { className: 'excluded' } : {})
316
+ * ```
317
+ */
318
+ getRowProps?: (row: Row, rowIndex: number) => DataTableElementProps;
319
+ /**
320
+ * Children of a row, shown nested under it, to any depth. Rows with
321
+ * children get an expand button in a column at the start, and their own
322
+ * styling; children are indented. A sorted column sorts the children of
323
+ * each row among themselves.
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * getSubRows: (team) => team.members
328
+ * ```
329
+ */
330
+ getSubRows?: (row: Row) => Row[] | undefined;
331
+ /** Ids of the expanded rows, for the controlled case. */
332
+ expandedRowIds?: string[];
333
+ /**
334
+ * Which rows start expanded, for the uncontrolled case: `true` for all,
335
+ * including rows that arrive later, or a list of ids.
336
+ * @default false
337
+ */
338
+ defaultExpanded?: boolean | string[];
339
+ /** Called with the ids of the expanded rows whenever the user changes them. */
340
+ onExpandedChange?: (expandedRowIds: string[]) => void;
341
+ /**
342
+ * Lets the user select rows: `multiple` adds a checkbox column whose header
343
+ * checkbox selects or clears the rows shown, `single` a radio column.
344
+ * With `getSubRows`, selecting a row selects everything under it, and a
345
+ * row with some of its children selected shows a partial check.
346
+ * Selection is kept as row ids (see `getRowId`), so rows selected on
347
+ * another page stay selected.
348
+ * @default 'none'
349
+ */
350
+ selectionMode?: DataTableSelectionMode;
351
+ /** Ids of the selected rows, for the controlled case. */
352
+ selectedRowIds?: string[];
353
+ /** Ids of the rows selected at first, for the uncontrolled case. */
354
+ defaultSelectedRowIds?: string[];
355
+ /** Called with the ids of the selected rows whenever the user changes them. */
356
+ onSelectionChange?: (selectedRowIds: string[]) => void;
357
+ /**
358
+ * Whether a row can be selected. Rows that cannot get a disabled checkbox
359
+ * and are skipped by the header checkbox.
360
+ *
361
+ * With `getSubRows`, a row that cannot be selected but has rows below it
362
+ * that can keeps an enabled checkbox, which selects those rows. Its own id
363
+ * is never in the selection, even when its checkbox shows checked.
364
+ */
365
+ isRowSelectable?: (row: Row) => boolean;
366
+ /**
367
+ * Accessible name of a row's selection checkbox, such as the person's
368
+ * name. Without it the row is named by its position.
369
+ * @default (row, rowIndex) => `Select row ${rowIndex + 1}`
370
+ */
371
+ getRowLabel?: (row: Row, rowIndex: number) => string;
372
+ /** Rendered below the table, such as `Pagination`. */
373
+ footer?: ReactNode;
374
+ /** Class name of the outer container. */
375
+ className?: string;
376
+ /** Forwarded to the `table` element. */
377
+ ref?: Ref<HTMLTableElement>;
378
+ }
@@ -0,0 +1,31 @@
1
+ import { PointerEvent, RefObject } from 'react';
2
+ /** A drag in progress: the column held, and the column it would drop on. */
3
+ export interface ColumnDrag {
4
+ id: string;
5
+ overId: string | null;
6
+ }
7
+ interface UseColumnReorderOptions {
8
+ tableRef: RefObject<HTMLTableElement | null>;
9
+ /** Whether `id` may be dropped where `targetId` is. */
10
+ canDrop: (id: string, targetId: string) => boolean;
11
+ onDrop: (id: string, targetId: string) => void;
12
+ }
13
+ /**
14
+ * Drag-to-reorder for header grips. The pointer is captured by the grip, and
15
+ * the drop target is whichever header cell is under it horizontally, so the
16
+ * pointer can wander above or below the header. Escape cancels.
17
+ *
18
+ * State changes only when the target does, not on every move, so a drag
19
+ * re-renders the table a handful of times rather than once per frame.
20
+ */
21
+ export declare const useColumnReorder: ({ tableRef, canDrop, onDrop, }: UseColumnReorderOptions) => {
22
+ drag: ColumnDrag | null;
23
+ getGripProps: (id: string) => {
24
+ onPointerDown: (event: PointerEvent<HTMLElement>) => void;
25
+ onPointerMove: (event: PointerEvent<HTMLElement>) => void;
26
+ onPointerUp: () => void;
27
+ onPointerCancel: () => void;
28
+ onLostPointerCapture: () => void;
29
+ };
30
+ };
31
+ export {};
@@ -0,0 +1,36 @@
1
+ import { DataTableColumn, DataTableColumnState, DataTableSort } from './types';
2
+ interface UseDataTableModelOptions<Row> {
3
+ data: Row[];
4
+ columns: DataTableColumn<Row>[];
5
+ getRowId?: (row: Row, index: number) => string;
6
+ getSubRows?: (row: Row) => Row[] | undefined;
7
+ /** Ids of the expanded rows, or `true` for all of them. */
8
+ expanded: true | string[];
9
+ columnState: DataTableColumnState;
10
+ sort: DataTableSort | null;
11
+ }
12
+ /** A visible row, in display order, with what rendering needs. */
13
+ export interface DataTableModelRow<Row> {
14
+ id: string;
15
+ original: Row;
16
+ /** 0 for a top-level row, 1 for its children, and so on. */
17
+ depth: number;
18
+ hasChildren: boolean;
19
+ isExpanded: boolean;
20
+ }
21
+ /** Where a row sits in the tree, expanded or not. */
22
+ export interface DataTableTreeNode<Row> {
23
+ original: Row;
24
+ parentId?: string;
25
+ childIds: string[];
26
+ }
27
+ /**
28
+ * Turns the public props into rows and columns in display order. The only
29
+ * place TanStack Table is used, so it never reaches the public API.
30
+ */
31
+ export declare const useDataTableModel: <Row>({ data, columns, getRowId, getSubRows, expanded, columnState, sort, }: UseDataTableModelOptions<Row>) => {
32
+ visibleColumns: DataTableColumn<Row>[];
33
+ rows: DataTableModelRow<Row>[];
34
+ tree: Map<string, DataTableTreeNode<Row>>;
35
+ };
36
+ export {};
@@ -0,0 +1,82 @@
1
+ import { CSSProperties } from 'react';
2
+ import { DataTableColumn, DataTableColumnState, DataTableElementProps, DataTableSort } from './types';
3
+ /** Width of the checkbox or radio column, in pixels. */
4
+ export declare const SELECTION_COLUMN_WIDTH = 48;
5
+ /** Width of the expand/collapse column, in pixels. */
6
+ export declare const EXPANDER_COLUMN_WIDTH = 36;
7
+ /** Extra left padding of a nested row's first cell, per level. */
8
+ export declare const NESTED_INDENT = 24;
9
+ export declare const EMPTY_COLUMN_STATE: DataTableColumnState;
10
+ /** Fills a partial column state in with defaults. */
11
+ export declare const toColumnState: (value?: Partial<DataTableColumnState>) => DataTableColumnState;
12
+ /**
13
+ * What the TanStack model depends on. Header and cell renderers are left out
14
+ * on purpose: they are read from the latest `columns` at render time, so an
15
+ * inline `columns` array does not rebuild the model on every render.
16
+ */
17
+ export declare const getColumnsSignature: <Row>(columns: DataTableColumn<Row>[]) => string;
18
+ /**
19
+ * The sort after a click on a sortable header: the same column flips
20
+ * direction, another column starts ascending.
21
+ */
22
+ export declare const getNextSort: (current: DataTableSort | null, columnId: string) => DataTableSort;
23
+ /** Whether a click landed on something inside a row with its own behaviour. */
24
+ export declare const isInteractiveTarget: (target: EventTarget | null, row: HTMLElement) => boolean;
25
+ /**
26
+ * Every column id in display order: `order` first, skipping unknown ids, then
27
+ * the rest in the order of `columns`. The same rule TanStack applies.
28
+ */
29
+ export declare const getFullOrder: <Row>(columns: DataTableColumn<Row>[], order: string[]) => string[];
30
+ /** Where a column sits while scrolling: frozen to an edge, or not. */
31
+ export declare const getFreezeZone: (frozen: DataTableColumnState["frozen"], id: string) => "start" | "end" | "scroll";
32
+ /**
33
+ * Moves column `id` to where `targetId` is, shifting the columns between.
34
+ * Only the slots `canMoveTo` accepts take part, so every other column keeps
35
+ * its position. Returns `null` when the target is not one of those slots.
36
+ */
37
+ export declare const moveColumn: (order: string[], id: string, targetId: string, canMoveTo: (id: string) => boolean) => string[] | null;
38
+ /** The nearest slot `canMoveTo` accepts on one side of column `id`. */
39
+ export declare const getAdjacentColumn: (order: string[], id: string, side: "left" | "right", canMoveTo: (id: string) => boolean) => string | null;
40
+ /** How a row's checkbox shows. */
41
+ export type CheckState = 'checked' | 'partial' | 'unchecked';
42
+ /**
43
+ * Cascading selection over a tree of rows. A row with selectable
44
+ * descendants is not selected for itself: it follows the leaves below it,
45
+ * checked when all are, partly when some are. Its id is in the selection
46
+ * exactly when it is checked, so the ids still name every selected row —
47
+ * unless `canSelect` rejects it: its checkbox still selects the rows below,
48
+ * but its own id is never in the selection.
49
+ *
50
+ * Ids not in the tree, such as rows on another page, are left alone.
51
+ */
52
+ export declare const createSelectionTree: (tree: Map<string, {
53
+ parentId?: string;
54
+ childIds: string[];
55
+ }>, canSelect: (id: string) => boolean) => {
56
+ rowState: (id: string, selected: Set<string>) => CheckState;
57
+ /** Whether the row has anything to select, itself or below. */
58
+ isSelectable: (id: string) => boolean;
59
+ allState: (selected: Set<string>) => CheckState;
60
+ toggleRow: (ids: string[], id: string, on: boolean) => string[];
61
+ toggleAll: (ids: string[], on: boolean) => string[];
62
+ };
63
+ /**
64
+ * A row's own `id` field as a row id, when it has a string or number one.
65
+ * What a table without `getRowId` keys its rows by.
66
+ */
67
+ export declare const getOwnRowId: (row: unknown) => string | undefined;
68
+ /**
69
+ * Turns what `getRowProps` returned into props for the row element. The
70
+ * `background` travels as a custom property for the `tintedRow` style, so it
71
+ * reaches the cells, which paint their own background over the row's.
72
+ */
73
+ export declare const toRowElementProps: ({ background, style, ...rest }?: DataTableElementProps) => Omit<DataTableElementProps, "background"> & {
74
+ isTinted: boolean;
75
+ };
76
+ /**
77
+ * Turns what a column's `getCellProps` returned into props for the cell
78
+ * element. The table's own style, the nested indent, wins over the column's,
79
+ * so a cell style cannot flatten the tree. The `background` is inline, so it
80
+ * outlasts the row's hover and selected states.
81
+ */
82
+ export declare const toCellElementProps: ({ background, style, ...rest }?: DataTableElementProps, ownStyle?: CSSProperties) => Omit<DataTableElementProps, "background">;
@@ -94,5 +94,5 @@ import { DropdownProps } from './types';
94
94
  *
95
95
  * @see https://www.w3.org/WAI/ARIA/apg/example-index/combobox/combobox-select-only.html
96
96
  */
97
- declare const Dropdown: <T extends DropdownOptionProps>({ selectedItem, disabled, isDisabled, isOpen: isInitOpen, children, onChange: handleChange, className, placeholder, maxHeight, avatarBorder, label, labelBadge, helperText, errors, success, icon, width, dropdownProps: componentProps, }: DropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
97
+ declare const Dropdown: <T extends DropdownOptionProps>({ selectedItem, disabled, isDisabled, isOpen: isInitOpen, children, onChange: handleChange, className, placeholder, maxHeight, avatarBorder, label, labelBadge, helperText, errors, success, icon, width, searchable, searchPlaceholder, searchEmptyState, dropdownProps: componentProps, }: DropdownProps<T>) => import("@emotion/react/jsx-runtime").JSX.Element;
98
98
  export default Dropdown;
@@ -161,6 +161,36 @@ export interface DropdownProps<P extends DropdownOptionProps> extends CommonProp
161
161
  * ```
162
162
  */
163
163
  width?: string | number;
164
+ /**
165
+ * Adds a search box above the open list. Typing filters the options by
166
+ * their text (case-insensitive, anywhere in the text); a group stays while
167
+ * any of its options match. Options whose `children` is markup are matched
168
+ * by their `textValue`.
169
+ *
170
+ * Focus moves to the search box on open and keeps driving the list: arrows
171
+ * move the highlight, Enter picks, Escape clears the search, then closes.
172
+ * @default false
173
+ *
174
+ * @example
175
+ * ```tsx
176
+ * <Dropdown searchable searchPlaceholder="Search country" onChange={setCountry}>
177
+ * {countries.map((c) => (
178
+ * <DropdownOption key={c.code} value={c.code} label={c.name} />
179
+ * ))}
180
+ * </Dropdown>
181
+ * ```
182
+ */
183
+ searchable?: boolean;
184
+ /**
185
+ * Placeholder and accessible name of the search box.
186
+ * @default 'Search'
187
+ */
188
+ searchPlaceholder?: string;
189
+ /**
190
+ * Shown in the list when nothing matches the search.
191
+ * @default 'No results found'
192
+ */
193
+ searchEmptyState?: React.ReactNode;
164
194
  /**
165
195
  * Props object for sub-components
166
196
  * Allows fine-grained control over component parts
@@ -246,4 +276,8 @@ export interface DropdownContextType {
246
276
  activeValue?: string | number | null;
247
277
  /** Moves the highlight; called by the list on pointer moves. */
248
278
  setActiveValue?: (value: string | number | null) => void;
279
+ /** The list sits in the search card, which does the positioning. */
280
+ searchable?: boolean;
281
+ /** Shown when the list has no options. */
282
+ emptyState?: React.ReactNode;
249
283
  }
@@ -18,6 +18,11 @@ export interface DropdownItemProps extends CommonProps, Omit<React.LiHTMLAttribu
18
18
  children?: React.ReactNode;
19
19
  /** Avatar or icon to display before the option content (e.g. <Avatar size={20} image={url} />) */
20
20
  avatar?: React.ReactNode;
21
+ /**
22
+ * Plain text of the option, for search and type-to-find. Needed when
23
+ * `children` is markup rather than text; defaults to the text label.
24
+ */
25
+ textValue?: string;
21
26
  }
22
27
  /**
23
28
  * DropdownOption - A single selectable row inside `Dropdown` or
@@ -0,0 +1,25 @@
1
+ import { KeyboardEvent, ReactNode } from 'react';
2
+ /** Props of {@link DropdownSearch}. */
3
+ export interface DropdownSearchProps {
4
+ /** Typed text. */
5
+ query: string;
6
+ onQueryChange: (query: string) => void;
7
+ placeholder: string;
8
+ /** Id of the list the input drives. */
9
+ listId: string;
10
+ /** Opens upward or downward from the toggle. */
11
+ placement?: 'top' | 'bottom';
12
+ zIndex?: number;
13
+ /** The highlighted option's id. */
14
+ 'aria-activedescendant'?: string;
15
+ onKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
16
+ onKeyUp?: (event: KeyboardEvent<HTMLInputElement>) => void;
17
+ /** The options list. */
18
+ children: ReactNode;
19
+ }
20
+ /**
21
+ * The open list of a searchable `Dropdown` / `MultipleDropdown`: a search box,
22
+ * focused on open, above the options. The box is the combobox while the list
23
+ * is open — it keeps focus and points at the highlighted option.
24
+ */
25
+ export declare const DropdownSearch: ({ query, onQueryChange, placeholder, listId, placement, zIndex, children, ...inputProps }: DropdownSearchProps) => import("@emotion/react/jsx-runtime").JSX.Element;
@@ -2,7 +2,7 @@ import { KeyboardEvent } from 'react';
2
2
  import { ContextMenuEntry } from '../ContextMenu';
3
3
  import { OptionValue } from './utils';
4
4
  /** Options of {@link useToggleListKeys}. */
5
- export interface UseToggleListKeysOptions {
5
+ export interface UseToggleListKeysOptions<E extends HTMLElement = HTMLButtonElement> {
6
6
  /** Id of the ContextMenu the toggle controls. */
7
7
  listId: string;
8
8
  isOpen: boolean;
@@ -16,18 +16,24 @@ export interface UseToggleListKeysOptions {
16
16
  close: () => void;
17
17
  /** Enter or Space on the highlighted option. */
18
18
  onPick: (value: OptionValue) => void;
19
+ /**
20
+ * Keys go to a text input (the search box): Space types a space and
21
+ * Home / End move the caret instead of the highlight.
22
+ */
23
+ typing?: boolean;
19
24
  /** Consumer handlers, run first; `preventDefault()` skips the built-in keys. */
20
- onKeyDown?: (event: KeyboardEvent<HTMLButtonElement>) => void;
21
- onKeyUp?: (event: KeyboardEvent<HTMLButtonElement>) => void;
25
+ onKeyDown?: (event: KeyboardEvent<E>) => void;
26
+ onKeyUp?: (event: KeyboardEvent<E>) => void;
22
27
  }
23
28
  /**
24
29
  * Keyboard for a dropdown toggle that keeps focus while it drives its list:
25
30
  * arrows open it, then Arrow/Home/End move the highlight, Enter/Space pick,
26
31
  * Escape/Tab close. Returns the toggle's handlers and its
27
- * `aria-activedescendant`.
32
+ * `aria-activedescendant`. With `typing`, drives the list from a search input
33
+ * instead.
28
34
  */
29
- export declare const useToggleListKeys: ({ listId, isOpen, disabled, menuItems, activeValue, setActiveValue, open, close, onPick, onKeyDown, onKeyUp, }: UseToggleListKeysOptions) => {
30
- onKeyDown: (event: KeyboardEvent<HTMLButtonElement>) => void;
31
- onKeyUp: (event: KeyboardEvent<HTMLButtonElement>) => void;
35
+ export declare const useToggleListKeys: <E extends HTMLElement = HTMLButtonElement>({ listId, isOpen, disabled, menuItems, activeValue, setActiveValue, open, close, onPick, typing, onKeyDown, onKeyUp, }: UseToggleListKeysOptions<E>) => {
36
+ onKeyDown: (event: KeyboardEvent<E>) => void;
37
+ onKeyUp: (event: KeyboardEvent<E>) => void;
32
38
  'aria-activedescendant': string | undefined;
33
39
  };
@@ -14,3 +14,10 @@ export declare const flattenDropdownOptions: (children: React.ReactNode) => Reac
14
14
  * `children` → `label` → `value`, as it always has.
15
15
  */
16
16
  export declare const toDropdownMenuItems: (children: React.ReactNode) => ContextMenuEntry<OptionValue>[];
17
+ /**
18
+ * The `DropdownOption` children whose text contains `query` (case-insensitive),
19
+ * in display order. A `DropdownOptionGroup` is kept, holding only its matching
20
+ * options, while any of them match. An empty query returns the children as is.
21
+ * Options with no text (custom markup and no `textValue`) never match.
22
+ */
23
+ export declare const filterDropdownOptions: (children: React.ReactNode, query: string) => React.ReactElement[];