@ibobbyts/svelte-ui-utils 0.4.7 → 0.5.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 (42) hide show
  1. package/README.md +74 -110
  2. package/dist/data-table/FilterControl.svelte +208 -27
  3. package/dist/data-table/FilterControl.svelte.d.ts.map +1 -1
  4. package/dist/data-table/filter.d.ts +3 -1
  5. package/dist/data-table/filter.d.ts.map +1 -1
  6. package/dist/data-table/filter.js +5 -1
  7. package/dist/data-table/index.d.ts +1 -1
  8. package/dist/data-table/index.d.ts.map +1 -1
  9. package/dist/data-table/types.d.ts +60 -3
  10. package/dist/data-table/types.d.ts.map +1 -1
  11. package/dist/dropdown/Dropdown.svelte +27 -11
  12. package/dist/dropdown/Dropdown.svelte.d.ts +1 -1
  13. package/dist/dropdown/Dropdown.svelte.d.ts.map +1 -1
  14. package/dist/dropdown/index.d.ts +3 -0
  15. package/dist/dropdown/index.d.ts.map +1 -1
  16. package/dist/dropdown/index.js +2 -0
  17. package/dist/dropdown/load-options.d.ts +65 -0
  18. package/dist/dropdown/load-options.d.ts.map +1 -0
  19. package/dist/dropdown/load-options.js +57 -0
  20. package/dist/dropdown/selection.d.ts +14 -0
  21. package/dist/dropdown/selection.d.ts.map +1 -0
  22. package/dist/dropdown/selection.js +16 -0
  23. package/dist/index.d.ts +0 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +0 -1
  26. package/dist/style.css +39 -282
  27. package/package.json +2 -11
  28. package/dist/dropdown-search/DropdownSearch.svelte +0 -725
  29. package/dist/dropdown-search/DropdownSearch.svelte.d.ts +0 -62
  30. package/dist/dropdown-search/DropdownSearch.svelte.d.ts.map +0 -1
  31. package/dist/dropdown-search/DropdownSearchMultiSelect.svelte +0 -94
  32. package/dist/dropdown-search/DropdownSearchMultiSelect.svelte.d.ts +0 -54
  33. package/dist/dropdown-search/DropdownSearchMultiSelect.svelte.d.ts.map +0 -1
  34. package/dist/dropdown-search/index.d.ts +0 -7
  35. package/dist/dropdown-search/index.d.ts.map +0 -1
  36. package/dist/dropdown-search/index.js +0 -4
  37. package/dist/dropdown-search/state.d.ts +0 -17
  38. package/dist/dropdown-search/state.d.ts.map +0 -1
  39. package/dist/dropdown-search/state.js +0 -51
  40. package/dist/dropdown-search/types.d.ts +0 -39
  41. package/dist/dropdown-search/types.d.ts.map +0 -1
  42. package/dist/dropdown-search/types.js +0 -1
package/README.md CHANGED
@@ -40,7 +40,6 @@ import '@ibobbyts/svelte-ui-utils/style.css';
40
40
  <script lang="ts">
41
41
  import { ToastManager, toast } from '@ibobbyts/svelte-ui-utils/toast';
42
42
  import { Dropdown } from '@ibobbyts/svelte-ui-utils/dropdown';
43
- import { DropdownSearch, DropdownSearchMultiSelect } from '@ibobbyts/svelte-ui-utils/dropdown-search';
44
43
  import { Dialog, ConfirmDialog, InputDialog, CsvUploadDialog, ImagePreviewDialog, PasswordCopyDialog } from '@ibobbyts/svelte-ui-utils/dialog';
45
44
  import { DataTable, DateRangeFilter, FilterTable, NumberRangeFilter } from '@ibobbyts/svelte-ui-utils/table';
46
45
  </script>
@@ -49,7 +48,7 @@ import '@ibobbyts/svelte-ui-utils/style.css';
49
48
  The package root also re-exports the public modules:
50
49
 
51
50
  ```ts
52
- import { ToastManager, Dropdown, DropdownSearch, Dialog, DataTable } from '@ibobbyts/svelte-ui-utils';
51
+ import { ToastManager, Dropdown, Dialog, DataTable } from '@ibobbyts/svelte-ui-utils';
53
52
  ```
54
53
 
55
54
  ## Toast
@@ -85,103 +84,6 @@ moves. Set `placement="up"` or `placement="down"` to force a direction. Use
85
84
  `fitViewport={false}` to disable the default panel-height constraint for the
86
85
  chosen side.
87
86
 
88
- ## DropdownSearch
89
-
90
- `DropdownSearch` is the free-text input entry with server-driven validation
91
- (`exactMatch`), input statuses, focus options, footer text, a clear button, and
92
- multiselect chips. For a trigger-style dropdown that combines single or multi
93
- select with async search and dynamic result groups, use the unified `Dropdown`
94
- search mode instead.
95
-
96
- ```svelte
97
- <script lang="ts">
98
- import { DropdownSearch } from '@ibobbyts/svelte-ui-utils/dropdown-search';
99
-
100
- async function loadOptions(query, { limit, signal }) {
101
- const response = await fetch(`/api/search?q=${encodeURIComponent(query)}&limit=${limit}`, { signal });
102
- return response.json();
103
- }
104
- </script>
105
-
106
- <DropdownSearch
107
- language="en_us"
108
- placeholder="Search"
109
- debounceMs={500}
110
- clearLabel="Clear search"
111
- width="24rem"
112
- maxWidth="100%"
113
- {loadOptions}
114
- searchOnExternalValueChange={true}
115
- closeOnValid={true}
116
- />
117
- ```
118
-
119
- `loadOptions` returns `{ options, exactMatch }`. An item uses this shape:
120
-
121
- ```ts
122
- {
123
- value: '123',
124
- label: 'Jane Doe',
125
- param_dict: { ID: 'M-123' }
126
- }
127
- ```
128
-
129
- `label` is the display text and `value` is the submitted string identifier;
130
- extra fields such as `param_dict` are preserved as business metadata. The
131
- free-text `value` prop and `onChange` detail stay the raw input text, so they
132
- never collide with the submitted `item.value`.
133
-
134
- The input is valid when the server returns one unique `exactMatch`, or when the
135
- user selects an item. Non-empty text without a unique match is invalid.
136
- Set `validate={false}` when the field should only show selectable options and
137
- stay visually neutral instead of turning green or red. In that mode the
138
- component ignores `exactMatch` for status and auto-selection.
139
- Use `searchOnExternalValueChange` for scanner or programmatic input workflows.
140
- Set `closeOnValid={true}` to hide the result list after validation finds a
141
- usable exact match. The default is `false`, so existing validated searches keep
142
- showing their current result list until the field closes or the user selects an
143
- option.
144
- Use `showOptionsOnFocus={true}` with `focusOptions` to show a controlled set of
145
- options as soon as the field receives focus, including when the current value is
146
- empty or already valid. Pass `footerText` to render a non-selectable note below
147
- the options, separated by a divider.
148
- When the input has text, `DropdownSearch` shows an internal clear button on the
149
- right side of the field. Use `clearLabel` to localize that button's accessible
150
- label, or use `language` to select the package default.
151
- Use `width`, `minWidth`, and `maxWidth` to size the control directly when a
152
- wrapper is not convenient.
153
- Server-side code and Node tests that only need pure helpers should import from
154
- `@ibobbyts/svelte-ui-utils/dropdown-search/state` so they do not load Svelte
155
- component files.
156
-
157
- Set `multiselect={true}` when the search box should collect multiple selected
158
- items as chips. `DropdownSearchMultiSelect` is a convenience wrapper with the
159
- same controlled contract:
160
-
161
- ```svelte
162
- <script lang="ts">
163
- import { DropdownSearchMultiSelect, type DropdownSearchItem } from '@ibobbyts/svelte-ui-utils/dropdown-search';
164
-
165
- let selectedMembers: DropdownSearchItem[] = [];
166
- </script>
167
-
168
- <DropdownSearchMultiSelect
169
- language="en_us"
170
- placeholder="Search members"
171
- selectedItems={selectedMembers}
172
- selectedItemsLabel="Selected members"
173
- removeSelectedItemLabel={(item) => `Remove ${item.label}`}
174
- {loadOptions}
175
- onSelectedItemsChange={(items) => {
176
- selectedMembers = items;
177
- }}
178
- />
179
- ```
180
-
181
- In multiselect mode, the text input remains a search query. Selecting an item
182
- adds or removes it from `selectedItems`, clears the query, and emits both
183
- `onChange` and `onSelectedItemsChange`.
184
-
185
87
  ## SortableList
186
88
 
187
89
  `SortableList` provides controlled vertical HTML5 drag-and-drop ordering. Each
@@ -417,8 +319,8 @@ the menu to its longest option while keeping the selected edge aligned.
417
319
  `DataTable` uses this same component for its page-size picker.
418
320
 
419
321
  Set `search={true}` with `loadOptions` to load remote options as the user
420
- types. The default `input_style="dropdown"` keeps the search field inside the
421
- expanded menu. Set `input_style="input"` to render a directly editable input;
322
+ types. The default `inputStyle="dropdown"` keeps the search field inside the
323
+ expanded menu. Set `inputStyle="input"` to render a directly editable input;
422
324
  results appear while it is focused and hide on blur. In input style, the
423
325
  optional `getItemLabel` callback controls the displayed label while `value`
424
326
  and `onChange` continue to represent submitted option values. The input style
@@ -603,6 +505,54 @@ render source and `loadOptions` is never called. Type the loader with
603
505
  `DropdownLoadOptions`/`DropdownLoadOptionsResult`, exported from the package
604
506
  root.
605
507
 
508
+ ### loadOptions factories
509
+
510
+ Most `loadOptions` implementations only differ in the item source: filter a
511
+ local array, or POST one JSON endpoint. The factories exported from
512
+ `@ibobbyts/svelte-ui-utils/dropdown` (and the package root) build loaders that
513
+ fit both the root `Dropdown` search mode and the data-table
514
+ `filter.dropdownSearch` control:
515
+
516
+ ```ts
517
+ import { createFetchLoadOptions, createLocalLoadOptions } from '@ibobbyts/svelte-ui-utils';
518
+
519
+ // Local list: filter, map to options, slice to the limit.
520
+ const loadFromRoster = createLocalLoadOptions(
521
+ () => rosterUsers,
522
+ {
523
+ toOption: (user) => ({ value: String(user.id), label: user.displayName }),
524
+ matches: (user, query) => matchesPinyin(user.displayName, query),
525
+ limit: 5
526
+ }
527
+ );
528
+
529
+ // JSON endpoint: URL, body builder, payload decoding, abort and error policy.
530
+ const loadFromApi = createFetchLoadOptions({
531
+ url: '/api/members/search',
532
+ buildBody: (query, limit) => ({ groupId, query, limit }),
533
+ mapOptions: (payload) => (payload as { options: MemberOption[] }).options ?? [],
534
+ throwOnError: true
535
+ });
536
+ ```
537
+
538
+ `createLocalLoadOptions(source, config?)` accepts a static array or a getter
539
+ re-evaluated on every search. `toOption` converts domain items (omit it when
540
+ the items already satisfy the `{ label, value }` contract); `matches` receives
541
+ the raw item and the trimmed query, and defaults to a case-insensitive
542
+ substring match over the converted option's `label`/`searchText`, where an
543
+ empty query matches everything. `limit` caps the context limit.
544
+
545
+ `createFetchLoadOptions(config)` skips the request for a blank query, posts
546
+ JSON (default body `{ query, limit }`), passes `context.signal` through, and
547
+ decodes the payload with `mapOptions` before slicing to the limit. HTTP and
548
+ network failures resolve with no options by default; `throwOnError: true`
549
+ rethrows them (aborted requests always resolve with no options) so wrappers
550
+ that surface errors keep working.
551
+
552
+ Multiselect handlers can also stop repeating the `string | string[]` narrowing:
553
+ `toMultiSelection(selection)` and `toSingleSelection(selection)` normalize a
554
+ `Dropdown` `onChange` argument to the shape the handler needs.
555
+
606
556
  ## DataTable
607
557
 
608
558
  ```svelte
@@ -766,10 +716,8 @@ for the left column and a controlled filter created with the `filter` helper:
766
716
  filter.dropdownSearch({
767
717
  value: searchValue,
768
718
  selectedItem,
769
- status: searchStatus,
770
719
  width: '24rem',
771
720
  maxWidth: '100%',
772
- clearLabel: 'Clear search',
773
721
  loadOptions,
774
722
  onChange: (detail) => updateSearch(detail)
775
723
  }),
@@ -786,6 +734,29 @@ for the left column and a controlled filter created with the `filter` helper:
786
734
  and `var(--suu-radius)` corner radius as a bordered `DataTable`. Set
787
735
  `bordered={false}` to remove both the border and outer corner radius.
788
736
 
737
+ `filter.text` renders a free-text search input for `keyword contains`-style
738
+ filtering. Unlike `filter.dropdownSearch` it has no selection semantics: the
739
+ value is the raw input text, and matching stays in the consuming app:
740
+
741
+ ```svelte
742
+ {
743
+ key: 'location',
744
+ title: 'Location',
745
+ filter: filter.text({
746
+ value: locationQuery,
747
+ placeholder: 'Search location',
748
+ ariaLabel: 'Location filter',
749
+ onChange: (value) => (locationQuery = value)
750
+ })
751
+ }
752
+ ```
753
+
754
+ Every keystroke reports by default; pass `debounceMs` to batch changes (Enter
755
+ flushes the pending draft immediately). The input stays a controlled input:
756
+ applying the new value from `onChange` keeps typing intact, and resetting
757
+ `value` clears the field. Width follows the `width`/`minWidth`/`maxWidth`
758
+ props when the full-row default is not what you want.
759
+
789
760
  `filter.select` uses the shared `Dropdown` component, so select filters keep the
790
761
  same menu, keyboard, and visual behavior as standalone dropdowns.
791
762
 
@@ -811,13 +782,6 @@ same menu, keyboard, and visual behavior as standalone dropdowns.
811
782
  }
812
783
  ```
813
784
 
814
- If a dropdown-style filter appears clipped, check the parent containers first.
815
- `DropdownSearch` renders its result list as an absolutely positioned child, so
816
- any ancestor with `overflow: hidden`, `overflow: auto`, or `overflow: scroll`
817
- can clip the menu even when the menu has a high `z-index`. Keep the nearest
818
- filter container at `overflow: visible`, or move the clipping/scrolling behavior
819
- to a parent that does not wrap the dropdown menu directly.
820
-
821
785
  `dateRange` renders two browser date inputs, preset buttons, and quick month/year
822
786
  selects. The presets are `last 24 hours`, `last 7 days`, `last 30 days`,
823
787
  `today`, `this week`, `this month`, and `this year`. Manual changes and quick
@@ -1,13 +1,19 @@
1
1
  <svelte:options runes={false} />
2
2
 
3
3
  <script lang="ts">
4
+ import { onDestroy } from 'svelte';
4
5
  import Dropdown from '../dropdown/Dropdown.svelte';
5
6
  import DropdownMultiSelect from '../dropdown/DropdownMultiSelect.svelte';
6
- import DropdownSearch from '../dropdown-search/DropdownSearch.svelte';
7
+ import type {
8
+ DropdownLoadContext,
9
+ DropdownLoadOptionsResult,
10
+ DropdownOption,
11
+ DropdownSelection
12
+ } from '../dropdown/types.js';
7
13
  import type { UiLanguage } from '../i18n.js';
8
14
  import DateRangeFilter from './DateRangeFilter.svelte';
9
15
  import NumberRangeFilter from './NumberRangeFilter.svelte';
10
- import type { FilterControl } from './types.js';
16
+ import type { DropdownSearchChangeDetail, DropdownSearchItem, FilterControl } from './types.js';
11
17
 
12
18
  export let control: FilterControl;
13
19
  export let language: UiLanguage = 'en_us';
@@ -32,6 +38,171 @@
32
38
  }
33
39
  }
34
40
 
41
+ // The removed DropdownSearch spoke free text in `value` while the root
42
+ // Dropdown reports option identifiers. This adapter keeps the legacy
43
+ // `{ value: label, selectedItem, selectedItems, status }` detail by resolving
44
+ // each identifier back to the item that loadOptions returned.
45
+ let dropdownSearchQuery = '';
46
+ const dropdownSearchItems = new Map<string, DropdownSearchItem>();
47
+
48
+ function resolveDropdownSearchItemLabel(item: DropdownSearchItem): string {
49
+ return control.type === 'dropdownSearch' && control.getItemLabel
50
+ ? control.getItemLabel(item)
51
+ : item.label;
52
+ }
53
+
54
+ // The root Dropdown types labels against its own option shape; the options it
55
+ // hands back are the very `DropdownSearchItem` objects we returned, so the
56
+ // structural widening is lossless for consumers' getItemLabel callbacks.
57
+ function dropdownSearchOptionLabel(option: DropdownOption): string {
58
+ return resolveDropdownSearchItemLabel(option as DropdownSearchItem);
59
+ }
60
+
61
+ function findDropdownSearchItem(identifier: string): DropdownSearchItem | undefined {
62
+ const cached = dropdownSearchItems.get(identifier);
63
+ if (cached !== undefined) {
64
+ return cached;
65
+ }
66
+ if (control.type === 'dropdownSearch' && control.selectedItem?.value === identifier) {
67
+ return control.selectedItem;
68
+ }
69
+ return undefined;
70
+ }
71
+
72
+ async function loadDropdownSearchOptions(
73
+ rawQuery: string,
74
+ context: DropdownLoadContext
75
+ ): Promise<DropdownLoadOptionsResult> {
76
+ if (control.type !== 'dropdownSearch') {
77
+ return { options: [] };
78
+ }
79
+
80
+ const query = rawQuery.trim();
81
+ // minLength has no root Dropdown counterpart, so the wrapper keeps the old
82
+ // "below threshold returns no options" contract itself.
83
+ if (query.length < (control.minLength ?? 1)) {
84
+ return { options: [] };
85
+ }
86
+
87
+ const result = await control.loadOptions(query, context);
88
+ // Stale responses must not seed the identifier cache either.
89
+ if (context.signal.aborted) {
90
+ return { options: [] };
91
+ }
92
+ const items = result?.options ?? [];
93
+ for (const item of items) {
94
+ dropdownSearchItems.set(item.value, item);
95
+ }
96
+
97
+ return { options: items };
98
+ }
99
+
100
+ function handleDropdownSearchQueryChange(query: string) {
101
+ dropdownSearchQuery = query;
102
+ }
103
+
104
+ function handleDropdownSearchChange(selection: DropdownSelection) {
105
+ if (control.type !== 'dropdownSearch') {
106
+ return;
107
+ }
108
+
109
+ const identifier = Array.isArray(selection) ? (selection[0] ?? '') : selection;
110
+ // The root Dropdown reports an empty identifier when the user types over a
111
+ // controlled selection (input/value divergence). That divergent-clear is
112
+ // dropped so `onChange` stays a selection-change (submit) event; a real
113
+ // selection always carries a non-empty identifier.
114
+ if (!identifier) {
115
+ return;
116
+ }
117
+ const item = findDropdownSearchItem(identifier);
118
+ const detail: DropdownSearchChangeDetail = {
119
+ value: item ? resolveDropdownSearchItemLabel(item) : identifier,
120
+ selectedItem: item ?? null,
121
+ selectedItems: [],
122
+ status: item ? 'valid' : dropdownSearchQuery.trim() ? 'invalid' : 'empty'
123
+ };
124
+ void control.onChange(detail);
125
+ }
126
+
127
+ // External value/selected-item changes rebuild the root Dropdown instance:
128
+ // controlled `value` resets its internal query, results, and draft, and
129
+ // `selectedOptions` then displays the new selection.
130
+ $: dropdownSearchKey = control.type === 'dropdownSearch'
131
+ ? `${control.value}\u0000${control.selectedItem?.value ?? ''}`
132
+ : '';
133
+ // A selected item displays through `selectedOptions`; a free-text external
134
+ // value has no option to resolve and falls back to the Dropdown value itself.
135
+ $: dropdownSearchValue = control.type === 'dropdownSearch'
136
+ ? control.selectedItem
137
+ ? control.selectedItem.value
138
+ : control.value
139
+ : '';
140
+ // The raw item is handed to the Dropdown untouched so its `getItemLabel` prop
141
+ // is the single label conversion on the display path.
142
+ $: dropdownSearchSelectedOptions = control.type === 'dropdownSearch' && control.selectedItem
143
+ ? [control.selectedItem]
144
+ : [];
145
+
146
+ // Free-text filter input: with debounceMs > 0 the draft lives here until the
147
+ // timer fires or Enter flushes it; the controlled `value` only catches up
148
+ // once the parent applies onChange, and Svelte leaves the DOM value alone
149
+ // until then so typing is never clobbered mid-draft.
150
+ let textInputTimer: ReturnType<typeof setTimeout> | null = null;
151
+ let textInputPending: string | null = null;
152
+
153
+ function flushTextInput() {
154
+ if (textInputTimer !== null) {
155
+ clearTimeout(textInputTimer);
156
+ textInputTimer = null;
157
+ }
158
+ if (textInputPending !== null && control.type === 'text') {
159
+ const value = textInputPending;
160
+ textInputPending = null;
161
+ void control.onChange(value);
162
+ }
163
+ }
164
+
165
+ function handleTextInput(value: string) {
166
+ if (control.type !== 'text') {
167
+ return;
168
+ }
169
+ const debounceMs = control.debounceMs ?? 0;
170
+ if (debounceMs <= 0) {
171
+ void control.onChange(value);
172
+ return;
173
+ }
174
+ textInputPending = value;
175
+ if (textInputTimer !== null) {
176
+ clearTimeout(textInputTimer);
177
+ }
178
+ textInputTimer = setTimeout(flushTextInput, debounceMs);
179
+ }
180
+
181
+ function handleTextKeydown(event: KeyboardEvent) {
182
+ if (event.key === 'Enter' && control.type === 'text') {
183
+ event.preventDefault();
184
+ flushTextInput();
185
+ }
186
+ }
187
+
188
+ $: textInputStyle = control.type === 'text'
189
+ ? [
190
+ control.width ? `width: ${control.width}` : '',
191
+ control.minWidth ? `min-width: ${control.minWidth}` : '',
192
+ control.maxWidth ? `max-width: ${control.maxWidth}` : ''
193
+ ]
194
+ .filter(Boolean)
195
+ .join('; ')
196
+ : '';
197
+
198
+ onDestroy(() => {
199
+ if (textInputTimer !== null) {
200
+ clearTimeout(textInputTimer);
201
+ textInputTimer = null;
202
+ }
203
+ textInputPending = null;
204
+ });
205
+
35
206
  </script>
36
207
 
37
208
  {#if control.type === 'container'}
@@ -110,31 +281,29 @@
110
281
  {/each}
111
282
  </div>
112
283
  {:else if control.type === 'dropdownSearch'}
113
- <DropdownSearch
114
- value={control.value}
115
- selectedItem={control.selectedItem}
116
- status={control.status}
117
- placeholder={control.placeholder ?? ''}
118
- ariaLabel={control.ariaLabel}
119
- debounceMs={control.debounceMs ?? 500}
120
- limit={control.limit ?? 10}
121
- minLength={control.minLength ?? 1}
122
- closeOnValid={control.closeOnValid ?? false}
123
- showOptionsOnFocus={control.showOptionsOnFocus ?? false}
124
- focusOptions={control.focusOptions ?? []}
125
- footerText={control.footerText}
126
- {language}
127
- noResultsText={control.noResultsText}
128
- loadingText={control.loadingText}
129
- clearLabel={control.clearLabel}
130
- searchOnExternalValueChange={control.searchOnExternalValueChange ?? false}
131
- width={control.width}
132
- minWidth={control.minWidth}
133
- maxWidth={control.maxWidth}
134
- getItemLabel={control.getItemLabel}
135
- loadOptions={control.loadOptions}
136
- onChange={(detail) => control.type === 'dropdownSearch' && void control.onChange(detail)}
137
- />
284
+ {#key dropdownSearchKey}
285
+ <Dropdown
286
+ value={dropdownSearchValue}
287
+ search
288
+ inputStyle="input"
289
+ portal
290
+ selectedOptions={dropdownSearchSelectedOptions}
291
+ loadOptions={loadDropdownSearchOptions}
292
+ searchDebounceMs={control.debounceMs ?? 500}
293
+ searchLimit={control.limit ?? 10}
294
+ placeholder={control.placeholder ?? ''}
295
+ ariaLabel={control.ariaLabel}
296
+ {language}
297
+ noResultsText={control.noResultsText}
298
+ loadingText={control.loadingText}
299
+ width={control.width}
300
+ minWidth={control.minWidth}
301
+ maxWidth={control.maxWidth}
302
+ getItemLabel={dropdownSearchOptionLabel}
303
+ onChange={handleDropdownSearchChange}
304
+ onSearchChange={handleDropdownSearchQueryChange}
305
+ />
306
+ {/key}
138
307
  {:else if control.type === 'dateRange'}
139
308
  <DateRangeFilter
140
309
  value={control.value}
@@ -264,4 +433,16 @@
264
433
  onChange={control.onChange}
265
434
  onTriggerClick={control.onTriggerClick}
266
435
  />
436
+ {:else if control.type === 'text'}
437
+ <input
438
+ class="suu-filter-table__text-input"
439
+ type="search"
440
+ value={control.value}
441
+ placeholder={control.placeholder ?? ''}
442
+ aria-label={control.ariaLabel}
443
+ disabled={control.disabled}
444
+ style={textInputStyle}
445
+ on:input={(event) => handleTextInput((event.currentTarget as HTMLInputElement).value)}
446
+ on:keydown={handleTextKeydown}
447
+ />
267
448
  {/if}
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControl.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/FilterControl.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6JhD,QAAA,MAAM,aAAa,KAA+E,CAAC;AACjF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"FilterControl.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/FilterControl.svelte.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAkD,aAAa,EAAE,MAAM,YAAY,CAAC;AAuUhG,QAAA,MAAM,aAAa,KAA+E,CAAC;AACjF,KAAK,aAAa,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,CAAC;AAC1D,eAAe,aAAa,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { CheckboxFilterControl, DateRangeFilterControl, DropdownFilterControl, DropdownMultiSelectFilterControl, DropdownSearchFilterControl, FilterButtonControl, FilterContainerControl, FilterControl, FilterLinkControl, FilterSelectControl, NumberRangeFilterControl, RadioFilterControl } from './types.js';
1
+ import type { CheckboxFilterControl, DateRangeFilterControl, DropdownFilterControl, DropdownMultiSelectFilterControl, DropdownSearchFilterControl, FilterButtonControl, FilterContainerControl, FilterControl, FilterLinkControl, FilterSelectControl, NumberRangeFilterControl, RadioFilterControl, TextInputFilterControl } from './types.js';
2
2
  declare function checkbox(options: Omit<CheckboxFilterControl, 'type'>): CheckboxFilterControl;
3
3
  declare function radio(options: Omit<RadioFilterControl, 'type'>): RadioFilterControl;
4
4
  declare function dropdownSearch(options: Omit<DropdownSearchFilterControl, 'type'>): DropdownSearchFilterControl;
@@ -10,6 +10,7 @@ declare function select(options: Omit<FilterSelectControl, 'type'>): FilterSelec
10
10
  declare function dropdown(options: Omit<DropdownFilterControl, 'type'>): DropdownFilterControl;
11
11
  declare function dropdownMultiSelect(options: Omit<DropdownMultiSelectFilterControl, 'type'>): DropdownMultiSelectFilterControl;
12
12
  declare function container(controls: FilterControl[]): FilterContainerControl;
13
+ declare function text(options: Omit<TextInputFilterControl, 'type'>): TextInputFilterControl;
13
14
  export declare const filter: {
14
15
  checkbox: typeof checkbox;
15
16
  radio: typeof radio;
@@ -22,6 +23,7 @@ export declare const filter: {
22
23
  dropdown: typeof dropdown;
23
24
  dropdownMultiSelect: typeof dropdownMultiSelect;
24
25
  container: typeof container;
26
+ text: typeof text;
25
27
  };
26
28
  export {};
27
29
  //# sourceMappingURL=filter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,gCAAgC,EAChC,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,iBAAS,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,qBAAqB,CAErF;AAED,iBAAS,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG,kBAAkB,CAE5E;AAED,iBAAS,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,MAAM,CAAC,GAAG,2BAA2B,CAEvG;AAED,iBAAS,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,GAAG,sBAAsB,CAExF;AAED,iBAAS,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,GAAG,wBAAwB,CAE9F;AAED,iBAAS,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAE/E;AAED,iBAAS,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAAG,iBAAiB,CAEzE;AAED,iBAAS,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAE/E;AAED,iBAAS,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,qBAAqB,CAErF;AAED,iBAAS,mBAAmB,CAC1B,OAAO,EAAE,IAAI,CAAC,gCAAgC,EAAE,MAAM,CAAC,GACtD,gCAAgC,CAElC;AAED,iBAAS,SAAS,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,sBAAsB,CAEpE;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;CAYlB,CAAC"}
1
+ {"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,gCAAgC,EAChC,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAEpB,iBAAS,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,qBAAqB,CAErF;AAED,iBAAS,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG,kBAAkB,CAE5E;AAED,iBAAS,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,2BAA2B,EAAE,MAAM,CAAC,GAAG,2BAA2B,CAEvG;AAED,iBAAS,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,GAAG,sBAAsB,CAExF;AAED,iBAAS,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,GAAG,wBAAwB,CAE9F;AAED,iBAAS,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAE/E;AAED,iBAAS,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAAG,iBAAiB,CAEzE;AAED,iBAAS,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GAAG,mBAAmB,CAE/E;AAED,iBAAS,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,qBAAqB,CAErF;AAED,iBAAS,mBAAmB,CAC1B,OAAO,EAAE,IAAI,CAAC,gCAAgC,EAAE,MAAM,CAAC,GACtD,gCAAgC,CAElC;AAED,iBAAS,SAAS,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,sBAAsB,CAEpE;AAED,iBAAS,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,GAAG,sBAAsB,CAEnF;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;CAalB,CAAC"}
@@ -31,6 +31,9 @@ function dropdownMultiSelect(options) {
31
31
  function container(controls) {
32
32
  return { type: 'container', controls };
33
33
  }
34
+ function text(options) {
35
+ return { type: 'text', ...options };
36
+ }
34
37
  export const filter = {
35
38
  checkbox,
36
39
  radio,
@@ -42,5 +45,6 @@ export const filter = {
42
45
  select,
43
46
  dropdown,
44
47
  dropdownMultiSelect,
45
- container
48
+ container,
49
+ text
46
50
  };
@@ -8,5 +8,5 @@ export { isDateRangePreset, resolveDateRangePreset } from './date-range.js';
8
8
  export { getUiMessages, resolveUiLanguage, uiLanguages } from '../i18n.js';
9
9
  export { getAriaSort, getCellValue, getPageCount, normalizePagination, setDataTableFilters, setDataTablePageSize, setDataTablePagination, setDataTableSort, toggleSort } from './state.js';
10
10
  export type { UiLanguage, UiMessages } from '../i18n.js';
11
- export type { CheckboxFilterDefinition, CheckboxFilterControl, CustomDateRangePreset, DataTableColumn, DataTableCellValue, DataTableClassValue, DataTableHorizontalAlign, DataTableLayout, DataTablePaginationQueryKey, DataTableServerPagination, DataTableVerticalAlign, DateRangeFilterDefinition, DateRangeFilterControl, DateRangeFilterValue, DateRangePreset, DateRangePresetContext, DateRangePresetEntry, DateRangePresetSelect, DataTableRowAttributes, DataTableRowKey, DataTableSortChangeHandler, DataTableState, DataTableStateChangeHandler, DropdownSearchFilterDefinition, DropdownSearchFilterControl, DropdownFilterDefinition, DropdownFilterControl, DropdownMultiSelectFilterDefinition, DropdownMultiSelectFilterControl, FilterDefinition, FilterButtonControl, FilterContainerControl, FilterControl, FilterLinkControl, FilterOption, FilterSelectControl, FilterState, FilterTableRow, FilterValue, NumberRangeFilterDefinition, NumberRangeFilterControl, NumberRangeFilterValue, PaginationState, PaginationChangeHandler, PaginationDropdownPlacement, RadioFilterDefinition, RadioFilterControl, SortDirection, SortState } from './types.js';
11
+ export type { CheckboxFilterDefinition, CheckboxFilterControl, CustomDateRangePreset, DataTableColumn, DataTableCellValue, DataTableClassValue, DataTableHorizontalAlign, DataTableLayout, DataTablePaginationQueryKey, DataTableServerPagination, DataTableVerticalAlign, DateRangeFilterDefinition, DateRangeFilterControl, DateRangeFilterValue, DateRangePreset, DateRangePresetContext, DateRangePresetEntry, DateRangePresetSelect, DataTableRowAttributes, DataTableRowKey, DataTableSortChangeHandler, DataTableState, DataTableStateChangeHandler, DropdownSearchFilterDefinition, DropdownSearchFilterControl, DropdownFilterDefinition, DropdownFilterControl, DropdownMultiSelectFilterDefinition, DropdownMultiSelectFilterControl, FilterDefinition, FilterButtonControl, FilterContainerControl, FilterControl, FilterLinkControl, FilterOption, FilterSelectControl, FilterState, FilterTableRow, FilterValue, NumberRangeFilterDefinition, NumberRangeFilterControl, NumberRangeFilterValue, PaginationState, PaginationChangeHandler, PaginationDropdownPlacement, RadioFilterDefinition, RadioFilterControl, SortDirection, SortState, TextInputFilterDefinition, TextInputFilterControl } from './types.js';
12
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,2BAA2B,EAC3B,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,wBAAwB,EACxB,qBAAqB,EACrB,mCAAmC,EACnC,gCAAgC,EAChC,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/data-table/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,2BAA2B,EAC3B,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,sBAAsB,EACtB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,EACd,2BAA2B,EAC3B,8BAA8B,EAC9B,2BAA2B,EAC3B,wBAAwB,EACxB,qBAAqB,EACrB,mCAAmC,EACnC,gCAAgC,EAChC,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACT,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,YAAY,CAAC"}
@@ -1,4 +1,3 @@
1
- import type { DropdownSearchChangeDetail, DropdownSearchItem, DropdownSearchItemLabelGetter, DropdownSearchLoadOptions, DropdownSearchStatus } from '../dropdown-search/types.js';
2
1
  import type { DropdownLoadOptions, DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelection, DropdownSelectionChangeHandler, DropdownTriggerClickHandler } from '../dropdown/types.js';
3
2
  export type SortDirection = 'asc' | 'desc';
4
3
  export type DataTableLayout = 'auto' | 'fixed';
@@ -187,6 +186,42 @@ export interface RadioFilterControl {
187
186
  options: FilterOption[];
188
187
  onChange: (value: string) => void | Promise<void>;
189
188
  }
189
+ /**
190
+ * Data-table-local copy of the structural types that the removed free-text
191
+ * search component family used to host. The `dropdownSearch` filter control
192
+ * contract is unchanged; only that module is gone.
193
+ */
194
+ export type DropdownSearchStatus = 'empty' | 'loading' | 'valid' | 'invalid' | 'error';
195
+ /**
196
+ * Search options and selected chips use the unified label/value contract:
197
+ * `label` is the display text, `value` is the submitted string identifier.
198
+ * Extra business fields (e.g. `param_dict`) are preserved as metadata.
199
+ */
200
+ export interface DropdownSearchItem {
201
+ label: string;
202
+ value: string;
203
+ param_dict?: Record<string, string | number | null>;
204
+ disabled?: boolean;
205
+ [key: string]: unknown;
206
+ }
207
+ export interface DropdownSearchLoadContext {
208
+ limit: number;
209
+ signal: AbortSignal;
210
+ }
211
+ export interface DropdownSearchResult {
212
+ options: DropdownSearchItem[];
213
+ exactMatch?: DropdownSearchItem | null;
214
+ }
215
+ export type DropdownSearchLoadOptions = (query: string, context: DropdownSearchLoadContext) => Promise<DropdownSearchResult> | DropdownSearchResult;
216
+ export interface DropdownSearchChangeDetail {
217
+ /** Free-text input content; distinct from the submitted `DropdownSearchItem.value`. */
218
+ value: string;
219
+ selectedItem: DropdownSearchItem | null;
220
+ selectedItems: DropdownSearchItem[];
221
+ status: DropdownSearchStatus;
222
+ }
223
+ /** Returns the input text shown for a selected item; defaults to the item label. */
224
+ export type DropdownSearchItemLabelGetter = (item: DropdownSearchItem) => string;
190
225
  export interface DropdownSearchFilterControl {
191
226
  type: 'dropdownSearch';
192
227
  value: string;
@@ -241,7 +276,25 @@ export interface FilterContainerControl {
241
276
  type: 'container';
242
277
  controls: FilterControl[];
243
278
  }
244
- export type FilterControl = CheckboxFilterControl | RadioFilterControl | DropdownSearchFilterControl | DateRangeFilterControl | NumberRangeFilterControl | FilterButtonControl | FilterLinkControl | FilterSelectControl | DropdownFilterControl | DropdownMultiSelectFilterControl | FilterContainerControl;
279
+ /**
280
+ * Free-text filter input for `keyword contains`-style filtering. Unlike
281
+ * `dropdownSearch` it has no selection semantics: every (debounced) change is
282
+ * the raw input text, so it pairs with consumer-side row matching.
283
+ */
284
+ export interface TextInputFilterControl {
285
+ type: 'text';
286
+ value: string;
287
+ placeholder?: string;
288
+ ariaLabel?: string;
289
+ /** Milliseconds to batch changes before `onChange` fires; 0 (default) reports every keystroke. */
290
+ debounceMs?: number;
291
+ width?: string;
292
+ minWidth?: string;
293
+ maxWidth?: string;
294
+ disabled?: boolean;
295
+ onChange: (value: string) => void | Promise<void>;
296
+ }
297
+ export type FilterControl = CheckboxFilterControl | RadioFilterControl | DropdownSearchFilterControl | DateRangeFilterControl | NumberRangeFilterControl | FilterButtonControl | FilterLinkControl | FilterSelectControl | DropdownFilterControl | DropdownMultiSelectFilterControl | FilterContainerControl | TextInputFilterControl;
245
298
  export interface FilterTableRow {
246
299
  key: string;
247
300
  title: string;
@@ -275,5 +328,9 @@ export type NumberRangeFilterDefinition = NumberRangeFilterControl & {
275
328
  key: string;
276
329
  label: string;
277
330
  };
278
- export type FilterDefinition = CheckboxFilterDefinition | RadioFilterDefinition | DropdownSearchFilterDefinition | DropdownFilterDefinition | DropdownMultiSelectFilterDefinition | DateRangeFilterDefinition | NumberRangeFilterDefinition;
331
+ export type TextInputFilterDefinition = TextInputFilterControl & {
332
+ key: string;
333
+ label: string;
334
+ };
335
+ export type FilterDefinition = CheckboxFilterDefinition | RadioFilterDefinition | DropdownSearchFilterDefinition | DropdownFilterDefinition | DropdownMultiSelectFilterDefinition | DateRangeFilterDefinition | NumberRangeFilterDefinition | TextInputFilterDefinition;
279
336
  //# sourceMappingURL=types.d.ts.map