@scattered-light/loomiere-base-ui 0.6.0 → 0.7.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 (100) hide show
  1. package/README.md +135 -5
  2. package/dist/chunk-JUUPOOQQ.js +3723 -0
  3. package/dist/chunk-JUUPOOQQ.js.map +1 -0
  4. package/dist/chunk-M7KJASGK.js +802 -0
  5. package/dist/chunk-M7KJASGK.js.map +1 -0
  6. package/dist/chunk-Y2CPBMFJ.js +147 -0
  7. package/dist/chunk-Y2CPBMFJ.js.map +1 -0
  8. package/dist/custom/collection/index.d.ts +534 -0
  9. package/dist/custom/collection/index.js +1471 -0
  10. package/dist/custom/collection/index.js.map +1 -0
  11. package/dist/custom/index.d.ts +5 -0
  12. package/dist/custom/index.js +4 -0
  13. package/dist/custom/index.js.map +1 -0
  14. package/dist/design-system/components/Badge/README.md +35 -0
  15. package/dist/design-system/components/Badge/preview.html +19 -0
  16. package/dist/design-system/components/Collection/README.md +14 -0
  17. package/dist/design-system/components/CollectionPagination/README.md +15 -0
  18. package/dist/design-system/components/CollectionToolbar/README.md +24 -0
  19. package/dist/design-system/components/DataList/README.md +39 -0
  20. package/dist/design-system/components/DataList/preview.html +475 -0
  21. package/dist/design-system/components/DataTable/README.md +41 -0
  22. package/dist/design-system/components/DataTable/preview.html +475 -0
  23. package/dist/design-system/components/DatePicker/README.md +55 -0
  24. package/dist/design-system/components/DatePicker/preview.html +475 -0
  25. package/dist/design-system/components/EditableList/README.md +33 -0
  26. package/dist/design-system/components/EditableList/preview.html +475 -0
  27. package/dist/design-system/components/EmptyState/README.md +60 -0
  28. package/dist/design-system/components/EmptyState/preview.html +475 -0
  29. package/dist/design-system/components/ListDetail/README.md +43 -0
  30. package/dist/design-system/components/ListDetail/preview.html +475 -0
  31. package/dist/design-system/components/MoneyField/README.md +52 -0
  32. package/dist/design-system/components/MoneyField/preview.html +475 -0
  33. package/dist/design-system/components/Splitter/README.md +42 -0
  34. package/dist/design-system/components/Splitter/preview.html +475 -0
  35. package/dist/design-system/components/Table/README.md +2 -1
  36. package/dist/design-system/components/Table/preview.html +1 -1
  37. package/dist/design-system/components/bundle.js +7 -5
  38. package/dist/design-system/components/index.d.ts +3 -21
  39. package/dist/design-system/components/styles.css +2266 -186
  40. package/dist/index-ChJXlxzq.d.ts +809 -0
  41. package/dist/index.d.ts +3 -21
  42. package/dist/index.js +176 -891
  43. package/dist/index.js.map +1 -1
  44. package/dist/styles/components/Accordion.css +1 -1
  45. package/dist/styles/components/AlertDialog.css +1 -1
  46. package/dist/styles/components/Autocomplete.css +1 -1
  47. package/dist/styles/components/Avatar.css +1 -1
  48. package/dist/styles/components/Button.css +1 -1
  49. package/dist/styles/components/Checkbox.css +1 -1
  50. package/dist/styles/components/CheckboxGroup.css +1 -1
  51. package/dist/styles/components/Collapsible.css +1 -1
  52. package/dist/styles/components/Combobox.css +1 -1
  53. package/dist/styles/components/ContextMenu.css +1 -1
  54. package/dist/styles/components/Dialog.css +1 -1
  55. package/dist/styles/components/Drawer.css +1 -1
  56. package/dist/styles/components/Field.css +1 -1
  57. package/dist/styles/components/Fieldset.css +1 -1
  58. package/dist/styles/components/Form.css +1 -1
  59. package/dist/styles/components/Input.css +1 -1
  60. package/dist/styles/components/Menu.css +1 -1
  61. package/dist/styles/components/Menubar.css +1 -1
  62. package/dist/styles/components/Meter.css +1 -1
  63. package/dist/styles/components/NavigationMenu.css +1 -1
  64. package/dist/styles/components/NumberField.css +1 -1
  65. package/dist/styles/components/OTPField.css +1 -1
  66. package/dist/styles/components/Popover.css +1 -1
  67. package/dist/styles/components/PreviewCard.css +1 -1
  68. package/dist/styles/components/Progress.css +1 -1
  69. package/dist/styles/components/Radio.css +1 -1
  70. package/dist/styles/components/ScrollArea.css +1 -1
  71. package/dist/styles/components/Select.css +1 -1
  72. package/dist/styles/components/Separator.css +1 -1
  73. package/dist/styles/components/Slider.css +1 -1
  74. package/dist/styles/components/Switch.css +1 -1
  75. package/dist/styles/components/Tabs.css +1 -1
  76. package/dist/styles/components/Toast.css +1 -1
  77. package/dist/styles/components/Toggle.css +1 -1
  78. package/dist/styles/components/ToggleGroup.css +1 -1
  79. package/dist/styles/components/Toolbar.css +1 -1
  80. package/dist/styles/components/Tooltip.css +1 -1
  81. package/dist/styles/custom/Badge.css +104 -0
  82. package/dist/styles/custom/Collection.css +15 -0
  83. package/dist/styles/custom/CollectionPagination.css +24 -0
  84. package/dist/styles/custom/CollectionToolbar.css +57 -0
  85. package/dist/styles/custom/DataList.css +123 -0
  86. package/dist/styles/custom/DataTable.css +120 -0
  87. package/dist/styles/custom/DatePicker.css +572 -0
  88. package/dist/styles/custom/EditableList.css +98 -0
  89. package/dist/styles/custom/EmptyState.css +255 -0
  90. package/dist/styles/custom/ListDetail.css +126 -0
  91. package/dist/styles/custom/MoneyField.css +344 -0
  92. package/dist/styles/custom/Splitter.css +207 -0
  93. package/dist/styles/{components → custom}/Table.css +31 -4
  94. package/dist/styles/index.css +12 -2
  95. package/dist/styles/reset/accessibility.css +1 -1
  96. package/dist/styles/reset/reset-accessibility.css +1 -1
  97. package/dist/styles/reset/reset-tailwind.css +1 -1
  98. package/dist/styles/reset/reset.css +1 -1
  99. package/dist/styles/tailwind.css +12 -2
  100. package/package.json +36 -8
@@ -0,0 +1,534 @@
1
+ import * as React from 'react';
2
+ import { ReactNode, MutableRefObject } from 'react';
3
+ import { ColumnDef, Table, Row, FilterFn } from '@tanstack/react-table';
4
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
+ import * as _tanstack_table_core from '@tanstack/table-core';
6
+
7
+ type CollectionKind = 'text' | 'number' | 'money' | 'percent' | 'date' | 'boolean';
8
+ type CollectionAlign = 'start' | 'end' | 'center';
9
+ type ListSlot = 'primary' | 'secondary' | 'meta' | 'amount' | 'status' | 'hidden';
10
+ type FilterKind = 'tabs' | 'select' | 'multi-select' | 'boolean';
11
+ interface FilterOption {
12
+ value: string;
13
+ label: string;
14
+ /** A tab with an empty value, or this flag, means no filter. Its count is the whole facet. */
15
+ all?: boolean;
16
+ }
17
+ interface CollectionFilter {
18
+ kind: FilterKind;
19
+ label?: string;
20
+ options?: FilterOption[];
21
+ }
22
+ interface CellContext {
23
+ view: 'table' | 'list';
24
+ selected: boolean;
25
+ active: boolean;
26
+ }
27
+ interface CollectionColumn<T> {
28
+ id: string;
29
+ header: string | {
30
+ label: string;
31
+ content: ReactNode;
32
+ };
33
+ value: (row: T) => unknown;
34
+ cell?: (row: T, ctx: CellContext) => ReactNode;
35
+ kind?: CollectionKind;
36
+ currency?: string | ((row: T) => string);
37
+ fractionDigits?: number;
38
+ negative?: 'minus' | 'parens';
39
+ /** True searches the formatted value. A function also searches text that is not shown. */
40
+ searchable?: boolean | ((row: T) => string | string[]);
41
+ sortable?: boolean;
42
+ filter?: CollectionFilter;
43
+ total?: 'sum' | 'count' | ((rows: T[]) => ReactNode);
44
+ /** The row's name. One column should set this. Its cell is the row header and the primary action. */
45
+ rowHeader?: boolean;
46
+ hidden?: boolean;
47
+ /** 'auto', 'min' (as wide as the content), or a size token path such as space.16. No pixel values. */
48
+ width?: 'auto' | 'min' | string;
49
+ align?: CollectionAlign;
50
+ list?: ListSlot;
51
+ dateFormat?: Intl.DateTimeFormatOptions;
52
+ /** When every row shares one currency, the header can say "Amount (USD)" and the cells drop the symbol. */
53
+ showCurrencyInHeader?: boolean;
54
+ /** Rare needs that the column shape does not cover. Merged into the TanStack column. */
55
+ tanstack?: Partial<ColumnDef<any, any>>;
56
+ }
57
+ declare function headerLabel<T>(column: CollectionColumn<T>): string;
58
+ declare function defineColumns<T>(columns: CollectionColumn<T>[]): CollectionColumn<T>[];
59
+
60
+ declare const collectionFeatures: {
61
+ rowSortingFeature: _tanstack_table_core.TableFeature;
62
+ columnFilteringFeature: _tanstack_table_core.TableFeature;
63
+ globalFilteringFeature: _tanstack_table_core.TableFeature;
64
+ columnFacetingFeature: _tanstack_table_core.TableFeature;
65
+ rowPaginationFeature: _tanstack_table_core.TableFeature;
66
+ rowSelectionFeature: _tanstack_table_core.TableFeature;
67
+ columnGroupingFeature: _tanstack_table_core.TableFeature;
68
+ rowExpandingFeature: _tanstack_table_core.TableFeature;
69
+ columnOrderingFeature: _tanstack_table_core.TableFeature;
70
+ columnVisibilityFeature: _tanstack_table_core.TableFeature;
71
+ sortedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
72
+ filteredRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
73
+ groupedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
74
+ expandedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
75
+ paginatedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
76
+ facetedRowModel: (table: Table<any, any>, columnId: string) => () => _tanstack_table_core.RowModel<any, any>;
77
+ facetedUniqueValues: (table: Table<_tanstack_table_core.TableFeatures, any>, columnId: string) => () => Map<any, number>;
78
+ };
79
+ type CollectionTable = Table<typeof collectionFeatures, any>;
80
+ type CollectionRow = Row<typeof collectionFeatures, any>;
81
+ interface CollectionModelInput<T> {
82
+ rows: readonly T[];
83
+ columns: CollectionColumn<T>[];
84
+ getRowId: (row: T) => string;
85
+ getSubRows?: (row: T) => readonly T[] | undefined;
86
+ locale: string;
87
+ state?: Record<string, unknown>;
88
+ initialState?: Record<string, unknown>;
89
+ onStateChange?: Record<string, (updater: unknown) => void>;
90
+ canSelect?: (row: T) => boolean;
91
+ }
92
+ declare function collectionTableOptions<T>(input: CollectionModelInput<T>): {
93
+ features: {
94
+ rowSortingFeature: _tanstack_table_core.TableFeature;
95
+ columnFilteringFeature: _tanstack_table_core.TableFeature;
96
+ globalFilteringFeature: _tanstack_table_core.TableFeature;
97
+ columnFacetingFeature: _tanstack_table_core.TableFeature;
98
+ rowPaginationFeature: _tanstack_table_core.TableFeature;
99
+ rowSelectionFeature: _tanstack_table_core.TableFeature;
100
+ columnGroupingFeature: _tanstack_table_core.TableFeature;
101
+ rowExpandingFeature: _tanstack_table_core.TableFeature;
102
+ columnOrderingFeature: _tanstack_table_core.TableFeature;
103
+ columnVisibilityFeature: _tanstack_table_core.TableFeature;
104
+ sortedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
105
+ filteredRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
106
+ groupedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
107
+ expandedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
108
+ paginatedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
109
+ facetedRowModel: (table: Table<any, any>, columnId: string) => () => _tanstack_table_core.RowModel<any, any>;
110
+ facetedUniqueValues: (table: Table<_tanstack_table_core.TableFeatures, any>, columnId: string) => () => Map<any, number>;
111
+ };
112
+ data: T[];
113
+ columns: ColumnDef<{
114
+ rowSortingFeature: _tanstack_table_core.TableFeature;
115
+ columnFilteringFeature: _tanstack_table_core.TableFeature;
116
+ globalFilteringFeature: _tanstack_table_core.TableFeature;
117
+ columnFacetingFeature: _tanstack_table_core.TableFeature;
118
+ rowPaginationFeature: _tanstack_table_core.TableFeature;
119
+ rowSelectionFeature: _tanstack_table_core.TableFeature;
120
+ columnGroupingFeature: _tanstack_table_core.TableFeature;
121
+ rowExpandingFeature: _tanstack_table_core.TableFeature;
122
+ columnOrderingFeature: _tanstack_table_core.TableFeature;
123
+ columnVisibilityFeature: _tanstack_table_core.TableFeature;
124
+ sortedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
125
+ filteredRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
126
+ groupedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
127
+ expandedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
128
+ paginatedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
129
+ facetedRowModel: (table: Table<any, any>, columnId: string) => () => _tanstack_table_core.RowModel<any, any>;
130
+ facetedUniqueValues: (table: Table<_tanstack_table_core.TableFeatures, any>, columnId: string) => () => Map<any, number>;
131
+ }, any>[];
132
+ getRowId: (row: T) => string;
133
+ getSubRows: ((row: T) => T[] | undefined) | undefined;
134
+ filterFromLeafRows: boolean;
135
+ getColumnCanGlobalFilter: (column: {
136
+ columnDef: {
137
+ meta?: CollectionColumn<T>;
138
+ };
139
+ }) => boolean;
140
+ enableRowSelection: boolean | ((row: {
141
+ original: T;
142
+ }) => boolean);
143
+ enableMultiRowSelection: boolean;
144
+ enableSubRowSelection: boolean;
145
+ globalFilterFn: FilterFn<{
146
+ rowSortingFeature: _tanstack_table_core.TableFeature;
147
+ columnFilteringFeature: _tanstack_table_core.TableFeature;
148
+ globalFilteringFeature: _tanstack_table_core.TableFeature;
149
+ columnFacetingFeature: _tanstack_table_core.TableFeature;
150
+ rowPaginationFeature: _tanstack_table_core.TableFeature;
151
+ rowSelectionFeature: _tanstack_table_core.TableFeature;
152
+ columnGroupingFeature: _tanstack_table_core.TableFeature;
153
+ rowExpandingFeature: _tanstack_table_core.TableFeature;
154
+ columnOrderingFeature: _tanstack_table_core.TableFeature;
155
+ columnVisibilityFeature: _tanstack_table_core.TableFeature;
156
+ sortedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
157
+ filteredRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
158
+ groupedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
159
+ expandedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
160
+ paginatedRowModel: (table: Table<any, any>) => () => _tanstack_table_core.RowModel<any, any>;
161
+ facetedRowModel: (table: Table<any, any>, columnId: string) => () => _tanstack_table_core.RowModel<any, any>;
162
+ facetedUniqueValues: (table: Table<_tanstack_table_core.TableFeatures, any>, columnId: string) => () => Map<any, number>;
163
+ }, any>;
164
+ meta: {
165
+ locale: string;
166
+ columns: CollectionColumn<T>[];
167
+ };
168
+ state: Record<string, unknown> | undefined;
169
+ initialState: Record<string, unknown> | undefined;
170
+ onGlobalFilterChange: ((updater: unknown) => void) | undefined;
171
+ onSortingChange: ((updater: unknown) => void) | undefined;
172
+ onColumnFiltersChange: ((updater: unknown) => void) | undefined;
173
+ onPaginationChange: ((updater: unknown) => void) | undefined;
174
+ onRowSelectionChange: ((updater: unknown) => void) | undefined;
175
+ onGroupingChange: ((updater: unknown) => void) | undefined;
176
+ onExpandedChange: ((updater: unknown) => void) | undefined;
177
+ onColumnOrderChange: ((updater: unknown) => void) | undefined;
178
+ onColumnVisibilityChange: ((updater: unknown) => void) | undefined;
179
+ autoResetPageIndex: boolean;
180
+ autoResetExpanded: boolean;
181
+ };
182
+
183
+ /**
184
+ * Search, sort, money and paging rules for a collection. No React: the hook and the
185
+ * tests both call these, and TanStack applies the comparators. It is not a second
186
+ * filter engine. Faceting, selection and the row models stay in TanStack.
187
+ */
188
+ type SortKind = 'text' | 'number' | 'money' | 'percent' | 'date' | 'boolean';
189
+ type NegativeStyle = 'minus' | 'parens';
190
+ type BalanceTone = 'balanced' | 'under' | 'over';
191
+ /**
192
+ * Exact decimal to integer minor units. Strings never pass through a float.
193
+ * A number is turned into its decimal text first. Multiplying by 10 ** digits rounds
194
+ * 1.005 down to 1.00, because the float is 1.004999….
195
+ */
196
+ declare function toMinor(value: number | string | null | undefined, digits: number): bigint | null;
197
+ declare function compareDecimal(a: number | string, b: number | string): number;
198
+ interface SortItem<T> {
199
+ value: unknown;
200
+ index: number;
201
+ row: T;
202
+ }
203
+ /**
204
+ * Empty values sort last in either direction. Ties keep the incoming order.
205
+ * `desc` flips only the real values, never the empty ones.
206
+ */
207
+ declare function sortRows<T>(items: SortItem<T>[], kind: SortKind, desc: boolean, locale: string): T[];
208
+ declare function formatMoney(value: number | string | null | undefined, options: {
209
+ locale: string;
210
+ currency: string;
211
+ fractionDigits?: number;
212
+ negative?: NegativeStyle;
213
+ }): string;
214
+ declare function formatDate(value: unknown, locale: string, dateFormat?: Intl.DateTimeFormatOptions): string;
215
+ /** Every word must match, in any order. An empty query matches everything. */
216
+ declare function searchMatches(query: string, haystack: string): boolean;
217
+ interface MoneySum {
218
+ currency: string | null;
219
+ minor: bigint | null;
220
+ mixed: boolean;
221
+ }
222
+ declare function sumMoney(values: Array<{
223
+ amount: number | string | null | undefined;
224
+ currency: string;
225
+ }>, fractionDigits?: number): MoneySum;
226
+ declare function balanceOf(amounts: Array<number | string | null | undefined>, control: number | string | null | undefined, currency: string): {
227
+ tone: BalanceTone;
228
+ allocated: bigint;
229
+ control: bigint;
230
+ delta: bigint;
231
+ digits: number;
232
+ };
233
+ interface PageBounds {
234
+ pageIndex: number;
235
+ pageCount: number;
236
+ start: number;
237
+ end: number;
238
+ }
239
+ /** `pageIndex` is zero-based. A page past the end clamps to the last page. An empty list is one blank page. */
240
+ declare function pageBounds(pageIndex: number, pageSize: number, total: number): PageBounds;
241
+ interface FlatEntry<T> {
242
+ kind: 'group' | 'leaf';
243
+ row: T;
244
+ groupId?: string;
245
+ }
246
+ /**
247
+ * Page by leaf rows. A group that starts before this page repeats, marked continued.
248
+ */
249
+ declare function pageFlat<T>(entries: FlatEntry<T>[], pageIndex: number, pageSize: number): {
250
+ entries: Array<FlatEntry<T> & {
251
+ continued?: boolean;
252
+ }>;
253
+ leafCount: number;
254
+ bounds: PageBounds;
255
+ };
256
+ /** Ids that match, plus every ancestor, so a match is never shown without its parent. */
257
+ declare function treeVisibleIds<T>(rows: readonly T[], getId: (row: T) => string, getChildren: (row: T) => readonly T[] | undefined, matches: (row: T) => boolean): Set<string>;
258
+ /** Counts of one column among rows that already satisfy the other filters. */
259
+ declare function countFacets<T>(rows: readonly T[], valueOf: (row: T) => unknown): Map<string, number>;
260
+ /** Drop ids whose row is gone, or that no longer pass canSelect. Children count too. */
261
+ declare function selectableIds<T>(ids: readonly string[], rows: readonly T[], getRowId: (row: T) => string, canSelect?: (row: T) => boolean, getSubRows?: (row: T) => readonly T[] | undefined): string[];
262
+ declare function hiddenSelectedCount(selectedIds: readonly string[], filteredIds: ReadonlySet<string>): number;
263
+ /** Ascending, then descending, then the system's default. Clicking the default itself starts at ascending. */
264
+ declare function nextSort(current: {
265
+ id: string;
266
+ desc: boolean;
267
+ } | null, columnId: string, initial: {
268
+ id: string;
269
+ desc: boolean;
270
+ } | null): {
271
+ id: string;
272
+ desc: boolean;
273
+ } | null;
274
+
275
+ interface CollectionSort {
276
+ id: string;
277
+ desc: boolean;
278
+ }
279
+ interface CollectionMessages {
280
+ selectAll: (count: number) => string;
281
+ actionsFor: (name: string) => string;
282
+ total: string;
283
+ selected: (count: number) => string;
284
+ hiddenByFilters: (count: number) => string;
285
+ noResults: string;
286
+ noResultsDescription: string;
287
+ clearFilters: string;
288
+ nothingHere: string;
289
+ previous: string;
290
+ next: string;
291
+ rowsPerPage: string;
292
+ selectionCleared: string;
293
+ loading: string;
294
+ }
295
+ interface UseCollectionOptions<T> {
296
+ rows: readonly T[];
297
+ columns: CollectionColumn<T>[];
298
+ getRowId: (row: T) => string;
299
+ initialSort?: CollectionSort;
300
+ initialFilters?: Record<string, unknown>;
301
+ /** Omit it and the table has no selection column. */
302
+ canSelect?: (row: T) => boolean;
303
+ /** Omit it and every filtered row is on one page. */
304
+ pageSize?: number;
305
+ groupBy?: string;
306
+ getSubRows?: (row: T) => readonly T[] | undefined;
307
+ /** Groups and tree parents start open. Pass false to start them closed. */
308
+ defaultExpanded?: boolean;
309
+ /** Page sizes the control offers. A stored size outside this list is dropped. */
310
+ pageSizeOptions?: number[];
311
+ /** Remember search, sort, filters, page size and grouping for this screen. Not the selection or the page. */
312
+ stateKey?: string;
313
+ messages?: Partial<CollectionMessages>;
314
+ storage?: Pick<Storage, 'getItem' | 'setItem'>;
315
+ locale?: string;
316
+ /** Dryden clears the selection when a refresh replaces the rows. Default keeps it. */
317
+ clearSelectionOnRowsChange?: boolean;
318
+ search?: string;
319
+ onSearchChange?: (value: string) => void;
320
+ sort?: CollectionSort | null;
321
+ onSortChange?: (sort: CollectionSort | null) => void;
322
+ filters?: Record<string, unknown>;
323
+ onFiltersChange?: (filters: Record<string, unknown>) => void;
324
+ selection?: string[];
325
+ onSelectionChange?: (ids: string[]) => void;
326
+ /** 1-based. */
327
+ page?: number;
328
+ onPageChange?: (page: number) => void;
329
+ grouping?: string | null;
330
+ onGroupingChange?: (grouping: string | null) => void;
331
+ columnOrder?: string[];
332
+ onColumnOrderChange?: (order: string[]) => void;
333
+ columnVisibility?: Record<string, boolean>;
334
+ onColumnVisibilityChange?: (visibility: Record<string, boolean>) => void;
335
+ }
336
+ interface CollectionApi<T> {
337
+ table: CollectionTable;
338
+ columns: CollectionColumn<T>[];
339
+ getRowId: (row: T) => string;
340
+ locale: string;
341
+ search: string;
342
+ setSearch: (value: string) => void;
343
+ sort: CollectionSort | null;
344
+ setSort: (sort: CollectionSort | null) => void;
345
+ cycleSort: (columnId: string) => void;
346
+ filters: Record<string, unknown>;
347
+ setFilter: (columnId: string, value: unknown) => void;
348
+ clearFilters: () => void;
349
+ facetCounts: (columnId: string) => Map<string, number>;
350
+ selection: string[];
351
+ selectedRows: T[];
352
+ selectAllFiltered: () => void;
353
+ clearSelection: () => void;
354
+ /** Drops the selection of rows the current filters still show. Hidden rows stay selected. */
355
+ clearFilteredSelection: () => void;
356
+ selectionSet: ReadonlySet<string>;
357
+ messages: CollectionMessages;
358
+ hiddenSelectedCount: number;
359
+ filteredRows: T[];
360
+ filteredCount: number;
361
+ totalCount: number;
362
+ totals: Record<string, string>;
363
+ page: number;
364
+ pageCount: number;
365
+ setPage: (page: number) => void;
366
+ pageSize?: number;
367
+ setPageSize: (size: number) => void;
368
+ isFiltered: boolean;
369
+ reset: () => void;
370
+ grouping: string | null;
371
+ setGrouping: (columnId: string | null) => void;
372
+ columnOrder: string[];
373
+ setColumnOrder: (order: string[]) => void;
374
+ columnVisibility: Record<string, boolean>;
375
+ setColumnVisibility: (visibility: Record<string, boolean>) => void;
376
+ canSelect?: (row: T) => boolean;
377
+ /** The rows of this page, with group headers repeated when a group continues. */
378
+ pageEntries: Array<FlatEntry<CollectionRow> & {
379
+ continued?: boolean;
380
+ }>;
381
+ rowHeaderId?: string;
382
+ registerRowFocus: (focus: (() => void) | null) => void;
383
+ focusFirstRow: () => void;
384
+ /** Set when the page changes. The view focuses the first row after that page has rendered. */
385
+ focusAfterPage: MutableRefObject<boolean>;
386
+ }
387
+ declare function useCollection<T>(options: UseCollectionOptions<T>): CollectionApi<T>;
388
+
389
+ interface CollectionViewProps<T> {
390
+ collection: CollectionApi<T>;
391
+ label: string;
392
+ onRowActivate?: (row: T) => void;
393
+ getRowHref?: (row: T) => string;
394
+ activeRowId?: string;
395
+ rowActions?: (row: T) => RowAction[];
396
+ /** Shown when the data itself is empty. A search with no matches uses the built-in no-results state. */
397
+ empty?: React.ReactNode;
398
+ loading?: boolean;
399
+ /**
400
+ * One tab stop for the rows. Defaults to on when a row can be activated.
401
+ * `data-no-activate` on a control inside a row keeps a click there from opening the row.
402
+ */
403
+ rowNavigation?: boolean;
404
+ size?: 'sm' | 'md';
405
+ className?: string;
406
+ }
407
+ interface RowAction {
408
+ label: string;
409
+ onSelect: () => void;
410
+ disabled?: boolean;
411
+ tone?: 'danger';
412
+ }
413
+
414
+ interface DataListProps<T> extends CollectionViewProps<T> {
415
+ /** 'rows' share one container, like the table body. 'cards' separates them when a queue should read as items. */
416
+ variant?: 'rows' | 'cards';
417
+ totals?: 'summary' | 'none';
418
+ renderItemExtra?: (row: T) => React.ReactNode;
419
+ }
420
+ /**
421
+ * The same rows as DataTable, read as a list. Sorting lives in the toolbar because a list has no headers.
422
+ */
423
+ declare function DataList<T>({ collection, label, onRowActivate, getRowHref, activeRowId, rowActions, empty, loading, rowNavigation, size, className, variant, totals, renderItemExtra, }: DataListProps<T>): react_jsx_runtime.JSX.Element;
424
+
425
+ interface DataTableProps<T> extends CollectionViewProps<T> {
426
+ /** Accessible name when there is no caption. */
427
+ label: string;
428
+ caption?: React.ReactNode;
429
+ stickyHeader?: boolean;
430
+ stickyRowHeader?: boolean;
431
+ /** 'scroll' keeps the table. 'list' swaps in DataList when the table is narrower than collection.narrow-width. */
432
+ narrow?: 'scroll' | 'list';
433
+ size?: 'sm' | 'md';
434
+ }
435
+ /**
436
+ * A data table, the APG pattern: one tab stop for the rows, headers announce sort, and it is
437
+ * not a grid. A grid would say this is a spreadsheet, and it is not. AG Grid is that tool.
438
+ */
439
+ declare function DataTable<T>({ collection, label, caption, onRowActivate, getRowHref, activeRowId, rowActions, empty, loading, stickyHeader, stickyRowHeader, narrow, size, rowNavigation, className, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
440
+
441
+ interface CollectionPaginationProps {
442
+ /** 1-based. */
443
+ page: number;
444
+ pageCount: number;
445
+ pageSize?: number;
446
+ total: number;
447
+ filtered?: boolean;
448
+ onPageChange: (page: number) => void;
449
+ onPageSizeChange?: (size: number) => void;
450
+ pageSizeOptions?: number[];
451
+ /** Used in the nav label: "Pagination for Transactions". */
452
+ label: string;
453
+ previousLabel?: string;
454
+ nextLabel?: string;
455
+ rowsPerPageLabel?: string;
456
+ className?: string;
457
+ }
458
+ /**
459
+ * Generic on purpose: page, pageCount, pageSize, total and onPageChange are enough
460
+ * to use it without a collection. A collection passes those through.
461
+ */
462
+ declare function CollectionPagination({ page, pageCount, pageSize, total, filtered, onPageChange, onPageSizeChange, pageSizeOptions, label, previousLabel, nextLabel, rowsPerPageLabel, className, }: CollectionPaginationProps): react_jsx_runtime.JSX.Element;
463
+
464
+ interface CollectionToolbarProps<T> {
465
+ collection: CollectionApi<T>;
466
+ /** Required when any column is searchable. */
467
+ searchLabel?: string;
468
+ searchLabelVisible?: boolean;
469
+ /** The table sorts from its headers. The list, and a table that asks, sorts from here. */
470
+ showSort?: boolean;
471
+ /** Adds a Group by select. The hook already holds the grouping. */
472
+ groupOptions?: Array<{
473
+ value: string;
474
+ label: string;
475
+ }>;
476
+ actions?: React.ReactNode;
477
+ bulkActions?: React.ReactNode;
478
+ className?: string;
479
+ }
480
+ /**
481
+ * Tabs and search stay put while rows are selected. The trailing controls swap for the
482
+ * selection bar, so the bar takes their place and the row does not grow.
483
+ */
484
+ declare function CollectionToolbarImpl<T>({ collection, searchLabel, searchLabelVisible, showSort, groupOptions, actions, bulkActions, className }: CollectionToolbarProps<T>): react_jsx_runtime.JSX.Element;
485
+ declare function ToolbarTabs<T>({ collection, column }: {
486
+ collection: CollectionApi<T>;
487
+ column: CollectionColumn<T>;
488
+ }): react_jsx_runtime.JSX.Element;
489
+ declare function SearchField({ label, visible, value, onChange }: {
490
+ label: string;
491
+ visible?: boolean;
492
+ value: string;
493
+ onChange: (value: string) => void;
494
+ }): react_jsx_runtime.JSX.Element;
495
+ declare function FilterControl<T>({ collection, column }: {
496
+ collection: CollectionApi<T>;
497
+ column: CollectionColumn<T>;
498
+ }): react_jsx_runtime.JSX.Element;
499
+ declare function SortControl<T>({ collection }: {
500
+ collection: CollectionApi<T>;
501
+ }): react_jsx_runtime.JSX.Element;
502
+ declare function ToolbarClear<T>({ collection }: {
503
+ collection: CollectionApi<T>;
504
+ }): react_jsx_runtime.JSX.Element | null;
505
+ declare function ToolbarActions({ children }: {
506
+ children?: React.ReactNode;
507
+ }): react_jsx_runtime.JSX.Element;
508
+ declare function ToolbarSelection<T>({ collection, children }: {
509
+ collection: CollectionApi<T>;
510
+ children?: React.ReactNode;
511
+ }): react_jsx_runtime.JSX.Element | null;
512
+ declare function ToolbarRoot({ className, children }: {
513
+ className?: string;
514
+ children?: React.ReactNode;
515
+ }): react_jsx_runtime.JSX.Element;
516
+ declare const CollectionToolbar: typeof CollectionToolbarImpl & {
517
+ Root: typeof ToolbarRoot;
518
+ Tabs: typeof ToolbarTabs;
519
+ Search: typeof SearchField;
520
+ Filter: typeof FilterControl;
521
+ Sort: typeof SortControl;
522
+ Clear: typeof ToolbarClear;
523
+ Actions: typeof ToolbarActions;
524
+ SelectionBar: typeof ToolbarSelection;
525
+ };
526
+
527
+ /**
528
+ * Totals add leaf rows. A tree parent's amount is the children already, so counting both would double it.
529
+ * Zero money rows use the column's currency. "Mixed currencies" is only when more than one currency is present.
530
+ * A number or percent sum is not money.
531
+ */
532
+ declare function totalText<T>(column: CollectionColumn<T>, rows: readonly T[], locale: string): string;
533
+
534
+ export { type CellContext, type CollectionAlign, type CollectionApi, type CollectionColumn, type CollectionFilter, type CollectionKind, CollectionPagination, type CollectionPaginationProps, type CollectionSort, CollectionToolbar, type CollectionToolbarProps, DataList, type DataListProps, DataTable, type DataTableProps, type FilterKind, type FilterOption, type ListSlot, type UseCollectionOptions, balanceOf, collectionTableOptions, compareDecimal, countFacets, defineColumns, formatDate, formatMoney, headerLabel, hiddenSelectedCount, nextSort, pageBounds, pageFlat, searchMatches, selectableIds, sortRows, sumMoney, toMinor, totalText, treeVisibleIds, useCollection };