@lavalogic/scoria 0.37.44 → 0.37.46

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 (239) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +46 -46
  3. package/dist/Components/AccordionGroupButton.svelte +76 -76
  4. package/dist/Components/Action.svelte +136 -136
  5. package/dist/Components/ActionProps.d.ts +2 -6
  6. package/dist/Components/AlertModal.svelte +195 -183
  7. package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +702 -702
  8. package/dist/Components/Base/BaseModal.svelte +125 -125
  9. package/dist/Components/Base/ContextWrapper.svelte +72 -72
  10. package/dist/Components/Base/Pagination.svelte +198 -198
  11. package/dist/Components/Base/Snippets.svelte +36 -36
  12. package/dist/Components/BigRadioSet.svelte +38 -38
  13. package/dist/Components/Bubble.svelte +101 -101
  14. package/dist/Components/Button.svelte +209 -209
  15. package/dist/Components/ButtonProps.d.ts +2 -6
  16. package/dist/Components/Checkbox.svelte +86 -86
  17. package/dist/Components/CollapsibleCard.svelte +78 -78
  18. package/dist/Components/Contexts/ContextMenu.svelte +164 -164
  19. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  20. package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
  21. package/dist/Components/Contexts/Toast.svelte +86 -83
  22. package/dist/Components/Contexts/Toast.svelte.d.ts +8 -5
  23. package/dist/Components/Contexts/ToastContainer.svelte +65 -65
  24. package/dist/Components/Contexts/Tooltip.svelte +37 -37
  25. package/dist/Components/DataMatrixIcon.svelte +112 -112
  26. package/dist/Components/DataMatrixIconProps.d.ts +3 -13
  27. package/dist/Components/DateInput.svelte +148 -148
  28. package/dist/Components/DatePicker.svelte +300 -300
  29. package/dist/Components/DesktopModal.svelte +90 -90
  30. package/dist/Components/Dial.svelte +204 -204
  31. package/dist/Components/DialProps.d.ts +1 -18
  32. package/dist/Components/DimensionInput.svelte +170 -170
  33. package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
  34. package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
  35. package/dist/Components/FileCard.svelte +24 -24
  36. package/dist/Components/FileUpload.svelte +236 -236
  37. package/dist/Components/GridInput.svelte +196 -200
  38. package/dist/Components/GridInputSet.svelte +29 -29
  39. package/dist/Components/HorizontalTabGroup.svelte +82 -82
  40. package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
  41. package/dist/Components/Icon.svelte +128 -128
  42. package/dist/Components/IconProps.d.ts +2 -7
  43. package/dist/Components/Icons.js +357 -357
  44. package/dist/Components/LoadingAnimation.svelte +29 -29
  45. package/dist/Components/LoadingModal.svelte +45 -45
  46. package/dist/Components/LoadingOverlay.svelte +25 -25
  47. package/dist/Components/LoadingOverlayProps.d.ts +3 -7
  48. package/dist/Components/Modal.svelte +258 -258
  49. package/dist/Components/ModalProps.d.ts +0 -3
  50. package/dist/Components/MultiSelect.svelte +220 -220
  51. package/dist/Components/MultiSelectCommonProps.d.ts +6 -17
  52. package/dist/Components/Nav/Nav.svelte +110 -99
  53. package/dist/Components/Nav/NavProps.d.ts +4 -11
  54. package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
  55. package/dist/Components/Nav/NavTab.svelte +62 -62
  56. package/dist/Components/Nav/ServiceMenuItem.svelte +100 -100
  57. package/dist/Components/Nav/ServicesNav.svelte +80 -80
  58. package/dist/Components/NumberInput.svelte +157 -157
  59. package/dist/Components/PageHeading.svelte +25 -25
  60. package/dist/Components/PasswordInput.svelte +88 -88
  61. package/dist/Components/Portal.svelte +36 -36
  62. package/dist/Components/ProgressBubble.svelte +107 -108
  63. package/dist/Components/ProgressBubbleProps.d.ts +3 -3
  64. package/dist/Components/QuerySelect.svelte +366 -366
  65. package/dist/Components/QuerySelectProps.d.ts +4 -14
  66. package/dist/Components/SingleSelect.svelte +250 -250
  67. package/dist/Components/SingleSelectCommonProps.d.ts +3 -19
  68. package/dist/Components/StepButton.svelte +70 -70
  69. package/dist/Components/StepForm.svelte +140 -140
  70. package/dist/Components/Switch.svelte +69 -69
  71. package/dist/Components/Table/ARCHITECTURE.md +298 -0
  72. package/dist/Components/Table/Body/QuickSearchCell.svelte +683 -694
  73. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
  74. package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
  75. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +456 -478
  76. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
  77. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -188
  78. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
  79. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +120 -120
  80. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +230 -230
  81. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
  82. package/dist/Components/Table/Body/Rows/Columns/SelectColumn.d.ts +12 -9
  83. package/dist/Components/Table/Body/Rows/Columns/SelectTableCell.d.ts +5 -5
  84. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
  85. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
  86. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
  87. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
  88. package/dist/Components/Table/Body/Rows/Columns/TableDatePickerProps.d.ts +4 -4
  89. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
  90. package/dist/Components/Table/Body/Rows/Columns/TableQueryCell.d.ts +6 -5
  91. package/dist/Components/Table/Body/Rows/Columns/TableQueryColumn.d.ts +7 -6
  92. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -257
  93. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
  94. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -229
  95. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte.d.ts +11 -11
  96. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
  97. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
  98. package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
  99. package/dist/Components/Table/Body/TableBody.svelte +155 -155
  100. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +2 -3
  101. package/dist/Components/Table/ColumnFactory.svelte.d.ts +9 -11
  102. package/dist/Components/Table/ColumnFactory.svelte.js +110 -143
  103. package/dist/Components/Table/ColumnKindRegistry.d.ts +112 -0
  104. package/dist/Components/Table/ColumnKindRegistry.js +63 -0
  105. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
  106. package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
  107. package/dist/Components/Table/Headers/TableHead.svelte +415 -413
  108. package/dist/Components/Table/Misc/ColumnPanel.svelte +94 -94
  109. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +112 -112
  110. package/dist/Components/Table/Misc/FilterInput.svelte +620 -644
  111. package/dist/Components/Table/Misc/FilterInput.svelte.d.ts +12 -12
  112. package/dist/Components/Table/Misc/FilterInputProps.d.ts +2 -2
  113. package/dist/Components/Table/Misc/FilterPanel.svelte +257 -257
  114. package/dist/Components/Table/Misc/FilterPanelModal.svelte +30 -30
  115. package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
  116. package/dist/Components/Table/Misc/TableFooter.svelte +311 -311
  117. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +125 -125
  118. package/dist/Components/Table/Misc/TableSidebar.svelte +157 -157
  119. package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
  120. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
  121. package/dist/Components/Table/NestedTable.svelte +130 -133
  122. package/dist/Components/Table/SubApis.svelte.d.ts +1 -5
  123. package/dist/Components/Table/SubApis.svelte.js +33 -32
  124. package/dist/Components/Table/Table.svelte +692 -745
  125. package/dist/Components/Table/TableHelpers.svelte.d.ts +6 -19
  126. package/dist/Components/Table/TableHelpers.svelte.js +6 -14
  127. package/dist/Components/Table/Types/Columns/Column.d.ts +2 -2
  128. package/dist/Components/Table/Types/Columns/DateColumn.d.ts +3 -3
  129. package/dist/Components/Table/Types/Columns/DateTableCell.d.ts +7 -7
  130. package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.d.ts +7 -8
  131. package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.js +4 -5
  132. package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.d.ts +11 -14
  133. package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.js +3 -4
  134. package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.d.ts +7 -11
  135. package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.js +3 -3
  136. package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.d.ts +13 -18
  137. package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.js +4 -5
  138. package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.d.ts +5 -5
  139. package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.js +2 -2
  140. package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.d.ts +15 -12
  141. package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.js +4 -5
  142. package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.d.ts +8 -12
  143. package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.js +3 -3
  144. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.d.ts +6 -6
  145. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.js +3 -3
  146. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +49 -16
  147. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.js +27 -5
  148. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.d.ts +7 -7
  149. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js +4 -4
  150. package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.d.ts +5 -5
  151. package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.js +2 -2
  152. package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.d.ts +5 -5
  153. package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.js +2 -2
  154. package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.d.ts +5 -5
  155. package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.js +2 -2
  156. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.d.ts +5 -5
  157. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.js +2 -2
  158. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +11 -19
  159. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +4 -8
  160. package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.d.ts +6 -7
  161. package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.js +3 -4
  162. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.d.ts +9 -9
  163. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.js +4 -4
  164. package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +5 -5
  165. package/dist/Components/Table/Types/Columns/ProgressBarTableCell.d.ts +6 -6
  166. package/dist/Components/Table/Types/Columns/TableCell.d.ts +7 -6
  167. package/dist/Components/Table/Types/Context/ClipboardState.svelte.d.ts +98 -0
  168. package/dist/Components/Table/Types/Context/ClipboardState.svelte.js +290 -0
  169. package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.d.ts +17 -45
  170. package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.js +17 -45
  171. package/dist/Components/Table/Types/Context/FilteringState.svelte.d.ts +9 -20
  172. package/dist/Components/Table/Types/Context/FilteringState.svelte.js +9 -20
  173. package/dist/Components/Table/Types/Context/FocusState.svelte.d.ts +23 -42
  174. package/dist/Components/Table/Types/Context/FocusState.svelte.js +32 -59
  175. package/dist/Components/Table/Types/Context/ITable.d.ts +5 -8
  176. package/dist/Components/Table/Types/Context/PreferencesState.svelte.d.ts +29 -56
  177. package/dist/Components/Table/Types/Context/PreferencesState.svelte.js +28 -55
  178. package/dist/Components/Table/Types/Context/QueryValuesState.svelte.d.ts +50 -0
  179. package/dist/Components/Table/Types/Context/QueryValuesState.svelte.js +62 -0
  180. package/dist/Components/Table/Types/Context/SelectionState.svelte.d.ts +17 -28
  181. package/dist/Components/Table/Types/Context/SelectionState.svelte.js +17 -28
  182. package/dist/Components/Table/Types/Context/SortingState.svelte.d.ts +15 -29
  183. package/dist/Components/Table/Types/Context/SortingState.svelte.js +17 -31
  184. package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +212 -325
  185. package/dist/Components/Table/Types/Context/TableContext.svelte.js +292 -706
  186. package/dist/Components/Table/Types/Context/VirtualisationState.svelte.d.ts +62 -79
  187. package/dist/Components/Table/Types/Context/VirtualisationState.svelte.js +54 -73
  188. package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.d.ts +16 -27
  189. package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.js +16 -27
  190. package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +12 -15
  191. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +15 -30
  192. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +16 -28
  193. package/dist/Components/Table/Types/Header.d.ts +4 -4
  194. package/dist/Components/Table/Types/HeaderGroup.d.ts +5 -5
  195. package/dist/Components/Table/Types/Public/index.d.ts +2 -4
  196. package/dist/Components/Table/Types/Public/index.js +2 -4
  197. package/dist/Components/Table/clipboardEscape.d.ts +32 -0
  198. package/dist/Components/Table/clipboardEscape.js +45 -0
  199. package/dist/Components/Table/createTable.svelte.d.ts +8 -18
  200. package/dist/Components/Table/createTable.svelte.js +19 -47
  201. package/dist/Components/Test/TestContextConsumer.svelte +13 -13
  202. package/dist/Components/TextArea.svelte +130 -130
  203. package/dist/Components/TextInput.svelte +176 -176
  204. package/dist/Components/ThreeStateRadio.svelte +131 -131
  205. package/dist/Components/Touch/BoolCard.svelte +45 -45
  206. package/dist/Components/Touch/DateModal.svelte +209 -209
  207. package/dist/Components/Touch/EditCard.svelte +59 -59
  208. package/dist/Components/Touch/InfoCard.svelte +31 -31
  209. package/dist/Components/Touch/InfoTextCard.svelte +28 -28
  210. package/dist/Components/Touch/ModalExplanation.svelte +17 -17
  211. package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
  212. package/dist/Components/Touch/NumberModal.svelte +79 -79
  213. package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
  214. package/dist/Components/Touch/SelectModal.svelte +123 -123
  215. package/dist/Components/Touch/SummaryCard.svelte +93 -93
  216. package/dist/Components/Touch/TextAreaModal.svelte +95 -95
  217. package/dist/Components/Touch/TextModal.svelte +106 -106
  218. package/dist/Components/Touch/TouchCard.svelte +33 -33
  219. package/dist/Components/Touch/TouchModal.svelte +274 -274
  220. package/dist/Components/Touch/UtilityButton.svelte +109 -109
  221. package/dist/Components/VerticalTabGroup.svelte +79 -79
  222. package/dist/Components/VerticalTabGroupButton.svelte +58 -58
  223. package/dist/Contexts/ToastContext.svelte.js +3 -4
  224. package/dist/Helpers/Datamatrix.d.ts +19 -19
  225. package/dist/Helpers/Datamatrix.js +291 -291
  226. package/dist/Helpers/Helpers.svelte.d.ts +47 -4
  227. package/dist/Helpers/Helpers.svelte.js +97 -4
  228. package/dist/Helpers/dropdownPortal.d.ts +26 -41
  229. package/dist/Helpers/dropdownPortal.js +62 -116
  230. package/dist/Types/Examples/ExampleModal.svelte +35 -35
  231. package/dist/index.d.ts +1 -2
  232. package/dist/index.js +1 -1
  233. package/dist/scss/_basics.scss +12 -12
  234. package/dist/scss/_colours.scss +134 -134
  235. package/dist/scss/_mixins.scss +3358 -3360
  236. package/dist/scss/_motion.scss +57 -57
  237. package/dist/scss/_sizing.scss +85 -85
  238. package/dist/scss/_transitions.scss +8 -8
  239. package/package.json +8 -6
@@ -1,19 +1,17 @@
1
1
  /**
2
- * Runtime for the typed column builder closure consumers pass to
2
+ * Runtime for the typed column builder closure passed to
3
3
  * `createTable({ columns: (col) => [...] })`. Each method on the returned
4
- * `ColumnFactory<TRow>` wraps the matching existing `<Name>Def` constructor
5
- * and returns a `ColumnSpec<TRow, Kind>` whose internal payload (the
6
- * underlying `ColumnDef<TRow>` plus any per-column edit handler / reactive
7
- * dependencies) is hidden behind a symbol-keyed property.
4
+ * `ColumnFactory<TRow>` wraps the matching internal `<Name>Def` constructor
5
+ * and returns a `ColumnSpec<TRow, Kind>` whose underlying `ColumnDef` plus
6
+ * any per-column edit handler / reactive dependencies are hidden behind a
7
+ * symbol-keyed property (`InternalSpecPayload`).
8
8
  *
9
- * Phase 1 implementation note: this file is a thin facade. It maps the
10
- * consumer-friendly option shapes (with `accessor` instead of `accessorFn`,
11
- * `minWidth` instead of `minSize`, etc.) to the internal `<Name>Def` props
12
- * by spreading a `commonProps(...)` helper that returns the non-id common
13
- * fields, with `id` passed explicitly at each call site so its narrowed
14
- * type survives the spread.
9
+ * This file is a thin facade: it maps the consumer-friendly option names
10
+ * (`accessor`, `minWidth`, …) onto the internal Def field names (`accessorFn`,
11
+ * `minSize`, ) via the `commonProps(...)` helper. `id` is passed explicitly
12
+ * at each call site so its narrowed literal type survives the object spread.
15
13
  */
16
- import { generateUUID, syntheticColumnId } from '../../Helpers/Helpers.svelte.js';
14
+ import { formatDateTime, generateUUID, syntheticColumnId } from '../../Helpers/Helpers.svelte.js';
17
15
  import { CheckboxDef } from './Types/Columns/Definitions/Accessors/CheckboxDef.svelte.js';
18
16
  import { DateInputDef } from './Types/Columns/Definitions/Accessors/DateInputDef.svelte.js';
19
17
  import { NumberInputDef } from './Types/Columns/Definitions/Accessors/NumberInputDef.svelte.js';
@@ -54,6 +52,10 @@ export function unwrapColumnSpec(spec) {
54
52
  * `Object.keys` or JSON serialisation, while still being reachable via
55
53
  * `unwrapColumnSpec(...)`. */
56
54
  function makeSpec(kind, def, internals = {}) {
55
+ // Tag the def with its public-API kind. Drives the kind→filter map in
56
+ // `TableContext.setupDefaultColumnDefs` so the long instanceof cascade
57
+ // can be replaced by a single registry lookup.
58
+ def.kind = kind;
57
59
  const spec = {
58
60
  kind,
59
61
  id: def.id,
@@ -67,24 +69,20 @@ function makeSpec(kind, def, internals = {}) {
67
69
  });
68
70
  return Object.freeze(spec);
69
71
  }
70
- /** Sensible per-kind default widths so a freshly-built table without explicit
71
- * per-column `width` overrides ends up visually differentiated (rather than
72
- * every column collapsing to the shared `minSize` fallback of 48px and then
73
- * taking equal `1fr` shares of any remaining track space). Numbers chosen
74
- * to roughly match what the legacy `<table>` element produced via the
75
- * browser auto-layout algorithm for typical FloWMS column content. */
72
+ /** Sensible per-kind default widths so a freshly-built table without
73
+ * explicit per-column `width` overrides ends up visually differentiated
74
+ * (rather than every column collapsing to the shared `minSize` floor and
75
+ * taking equal `1fr` shares of leftover track space). Numbers roughly
76
+ * match what the legacy `<table>` auto-layout produced for typical
77
+ * FloWMS column content.
78
+ *
79
+ * - `number: 120` — fits 7-8 digit IDs alongside sort/filter affordances.
80
+ * - `date: 180` — fits the "DD/MM/YYYY HH:mm" format used across FloWMS;
81
+ * narrower widths truncated the time portion. */
76
82
  const KIND_DEFAULT_WIDTHS = {
77
83
  text: 180,
78
- // Bumped from 100 → 120 so 7-8 digit IDs / quantities (e.g. shipment
79
- // IDs, order IDs) fit cleanly alongside the sort / filter affordances
80
- // without forcing the value to truncate or wrap.
81
84
  number: 120,
82
85
  checkbox: 80,
83
- // Bumped from 140 → 180 so the formatted "DD/MM/YYYY HH:mm" string
84
- // fits inside the cell. The legacy 140px floor cut off the time
85
- // portion for the typical date format used across FloWMS pages and
86
- // forced every consumer to set a per-column `width` override (see
87
- // OrderManagement, which had to pin date columns at 210).
88
86
  date: 180,
89
87
  select: 160,
90
88
  query: 160,
@@ -108,22 +106,19 @@ function commonProps(opts, kind) {
108
106
  const defaultWidth = KIND_DEFAULT_WIDTHS[kind];
109
107
  return {
110
108
  header: opts.header,
111
- // Set minSize from the per-kind default too so
112
- // `TableContext.registerDefs` does NOT run the canvas-based
113
- // `measureHeaderWidth` fallback. That fallback floors every
114
- // accessor column to ~130px when quick-filtering is enabled
115
- // (it returns max(headerWidth, "Lorem Ipsum Dolor" width)),
116
- // which equalises every accessor column width and erases the
117
- // per-kind differentiation the factory just put in place.
109
+ // `minSize` mirrors the per-kind default so `TableContext.registerDefs`
110
+ // does NOT fall back to the canvas-based `measureHeaderWidth`, which
111
+ // floors every accessor column at ~130px when quick-filtering is
112
+ // enabled (it returns max(headerWidth, "Lorem Ipsum Dolor" width))
113
+ // and erases the per-kind differentiation.
118
114
  minSize: opts.minWidth ?? defaultWidth,
119
115
  width: opts.width ?? defaultWidth,
120
116
  maxWidth: opts.maxWidth,
121
117
  wrapValue: opts.wrapValue,
122
- // `widthIsFixed` is true only when the caller passed an explicit
123
- // `width`. The grid template uses this to render the track as
124
- // fixed `${W}px` for explicit widths, leaving the per-kind-default
125
- // columns on `minmax(W, 1fr)` so they absorb any horizontal space
126
- // the fixed columns leave behind.
118
+ // `widthIsFixed` is true only when the caller supplied an explicit
119
+ // `width`. The grid template renders those tracks as `${W}px` and
120
+ // leaves per-kind-default columns on `minmax(W, 1fr)` so they
121
+ // absorb any horizontal space the fixed columns leave behind.
127
122
  widthIsFixed: opts.width != null,
128
123
  allowSorting: opts.allowSorting,
129
124
  allowFiltering: opts.allowFiltering,
@@ -135,37 +130,28 @@ function commonProps(opts, kind) {
135
130
  filterGroup: opts.filterGroup,
136
131
  };
137
132
  }
138
- /** Generate a column id for a kind whose option type does not require
139
- * an `id` from the caller.
133
+ /** Generate a column id for a kind whose option type does not require an
134
+ * `id` from the caller.
140
135
  *
141
- * - When `hint` is provided, use it as the id verbatim. This is the
142
- * server-side-filtering contract: callers who pass an `idHint` are
143
- * indicating that the column maps to a real backend field (so the
144
- * filter row's `id` flows through `createRemoteRowSource` as the
145
- * query-string key the server expects). Adding a synthetic prefix
146
- * here would mean every `col.display({ idHint: 'outboundType_id' })`
147
- * serialised as `display-outboundType_id` and the server rejected
148
- * the request with "field does not exist".
149
- * - When no `hint` is provided, fall back to `${prefix}-${UUID}` so
150
- * the id is still unique within the table. Such columns cannot
151
- * participate in server-driven filtering anyway (the server would
152
- * not know the random suffix). */
136
+ * - With `hint`: used verbatim. `idHint` is the server-side-filtering
137
+ * contract; the column id flows through `createRemoteRowSource` as
138
+ * the query-string key the server expects, so a synthetic prefix
139
+ * would make every server reject the field as unknown.
140
+ * - Without `hint`: fall back to `${prefix}-${UUID}` so the id is unique
141
+ * within the table. Such columns cannot participate in server-driven
142
+ * filtering (the server has no way to know the random suffix). */
153
143
  function mintSyntheticId(prefix, hint) {
154
144
  if (hint != null) {
155
145
  return syntheticColumnId(hint);
156
146
  }
157
147
  return syntheticColumnId(`${prefix}-${generateUUID()}`);
158
148
  }
159
- /** Resolve an `options` field that may be a static array or an async
160
- * loader into the always-loader form the Def expects. Mutable arrays are
161
- * required by the Def's signature; we spread to drop readonly. */
149
+ /** Resolve an `options` field that may be a static array or an async loader
150
+ * into the always-loader form the Def expects. The spread drops the
151
+ * readonly modifier the Def's signature lacks. Loaders may return either
152
+ * a Promise or a plain array; `Promise.resolve` accepts both. */
162
153
  function normaliseOptionsLoader(options) {
163
154
  if (typeof options === 'function') {
164
- // `options()` may return either a Promise or a plain array - some
165
- // project helpers (e.g. flowms `ColumnDefRepository.getAccounts()`
166
- // vs. `getOutboundStatuses()`) settle on different conventions per
167
- // data source. `Promise.resolve` accepts both so the loader hands
168
- // the consumer a uniform Promise either way.
169
155
  return () => Promise.resolve(options()).then((res) => [...res]);
170
156
  }
171
157
  const snapshot = [...options];
@@ -186,29 +172,17 @@ function normaliseOptionsLoader(options) {
186
172
  * tests can exercise individual factory methods without round-tripping
187
173
  * through a full `createTable(...)` call.
188
174
  */
189
- /** Format a Date or ISO-8601 date string for display using the browser
190
- * locale. Returns null / empty input unchanged. Used by `col.display` when
191
- * the column declares `filterValueType: 'Date'` so backend timestamps
192
- * surface as a properly localised date+time string instead of the raw
193
- * ISO payload (`2026-04-16T09:44:11+01:00`). */
175
+ /** Format a Date / ISO-8601 string / epoch number for display. Used by
176
+ * `col.display` when the column declares `filterValueType: 'Date'`, so
177
+ * raw backend timestamps render as a localised date+time rather than the
178
+ * ISO payload. Delegates to the exported `formatDateTime` helper so table
179
+ * cells and non-table date surfaces format identically. Anything that is
180
+ * not a date-like value (the column was mis-declared) yields `''`. */
194
181
  function formatLocaleDate(value) {
195
- if (value == null || value === '') {
196
- return value;
197
- }
198
- let d;
199
- if (value instanceof Date) {
200
- d = value;
201
- }
202
- else if (typeof value === 'string' || typeof value === 'number') {
203
- const parsed = new Date(value);
204
- if (!Number.isNaN(parsed.getTime())) {
205
- d = parsed;
206
- }
182
+ if (value instanceof Date || typeof value === 'string' || typeof value === 'number') {
183
+ return formatDateTime(value);
207
184
  }
208
- if (d == null) {
209
- return value;
210
- }
211
- return d.toLocaleString();
185
+ return '';
212
186
  }
213
187
  export function createColumnFactory() {
214
188
  const factory = {
@@ -327,12 +301,11 @@ export function createColumnFactory() {
327
301
  ? normaliseOptionsLoader(opts.getOptions)
328
302
  : undefined;
329
303
  // Display columns have no intrinsic kind (the value comes from an
330
- // arbitrary `value: (row) => ...` thunk) so the generic 'display'
331
- // default (150px) is the fallback. When the consumer DOES pass a
332
- // `filterValueType`, treat it as a hint about the rendered shape
333
- // of the column and pick the matching per-kind default so a table
334
- // full of `col.display` columns ends up visually differentiated
335
- // instead of every column collapsing to the same 150px floor.
304
+ // arbitrary `value: (row) => ...` thunk). When the consumer passes
305
+ // a `filterValueType`, treat it as a hint about the rendered shape
306
+ // and pick the matching per-kind default width; otherwise fall
307
+ // back to the generic 'display' default so columns are visually
308
+ // differentiated instead of all collapsing to the same floor.
336
309
  const inferredKind = opts.filterValueType === 'Number'
337
310
  ? 'number'
338
311
  : opts.filterValueType === 'Date'
@@ -344,26 +317,19 @@ export function createColumnFactory() {
344
317
  : opts.filterValueType === 'String'
345
318
  ? 'text'
346
319
  : 'display';
347
- // For Date-typed display columns, leave the accessor returning
348
- // the raw Date / ISO string (filter / sort logic still operates
349
- // on the raw value) and surface the formatted local-time
350
- // string via `getDisplayValue`. The cell renders
351
- // `getDisplayValue` for visible text and reads the raw value
352
- // from `accessorFn` to compose the hover tooltip showing both
353
- // the local-time and UTC representations.
320
+ // For Date-typed display columns, the accessor returns the raw
321
+ // Date / ISO string (filter/sort operates on the raw value) and
322
+ // `getDisplayValue` surfaces the formatted local-time string.
323
+ // The cell renders `getDisplayValue` for visible text and uses
324
+ // the raw value to compose the hover tooltip (local + UTC).
354
325
  const rawValue = opts.value;
355
326
  const valueAccessor = rawValue;
356
327
  const dateDisplayValue = opts.filterValueType === 'Date'
357
328
  ? (row, index) => {
358
329
  const v = rawValue(row, index);
359
- if (v instanceof Promise) {
360
- return v.then((resolved) => {
361
- const formatted = formatLocaleDate(resolved);
362
- return formatted == null ? null : String(formatted);
363
- });
364
- }
365
- const formatted = formatLocaleDate(v);
366
- return formatted == null ? null : String(formatted);
330
+ return v instanceof Promise
331
+ ? v.then((resolved) => formatLocaleDate(resolved))
332
+ : formatLocaleDate(v);
367
333
  }
368
334
  : undefined;
369
335
  const def = new DisplayDef({
@@ -372,27 +338,20 @@ export function createColumnFactory() {
372
338
  accessorFn: valueAccessor,
373
339
  getDisplayValue: dateDisplayValue,
374
340
  modal: opts.modal,
375
- // Display columns have no implicit filter type (unlike the
376
- // typed kinds where the factory pins one based on the
377
- // column kind). Consumers opt in by passing the type they
378
- // want the filter input rendered as.
379
- // Default to string-typed filter when the caller did not specify
380
- // one, so a display column with no explicit `filterValueType`
381
- // still appears in the filter UI (matches the `DisplayDef →
382
- // stringFilter (undefined case)` mapping in
341
+ // Display columns have no implicit filter type. Consumers opt
342
+ // in by passing `filterValueType`; default to String so a
343
+ // column without one still appears in the filter UI (matches
344
+ // the `DisplayDef stringFilter` mapping in
383
345
  // `setupDefaultColumnDefs`).
384
346
  filterValueType: opts.filterValueType ?? FilterValueType.String,
385
347
  getSortingFn: opts.getSortingFn,
386
348
  getOptions: normalisedOptions,
387
- // Forward reactiveDependencies onto the def so
388
- // `makeRow.getValue` can read them synchronously before
389
- // calling the (possibly async) accessor. Without this,
390
- // reactive reads that happen only after `await` inside
391
- // the consumer's `value` callback are not tracked by the
392
- // cell's `$derived`, and downstream display cells never
393
- // refresh when a sibling field is edited (visible on the
394
- // Receipt pod table: Title / UoM did not reload after the
395
- // SKU select changed `item.receiptLineId`).
349
+ // `reactiveDependencies` is forwarded onto the def so that
350
+ // `makeRow.getValue` can read it synchronously before invoking
351
+ // a (possibly async) accessor. Without this, reads that only
352
+ // happen after `await` inside the consumer's `value` callback
353
+ // are not tracked by the cell's `$derived`, and downstream
354
+ // cells never refresh when a sibling field is edited.
396
355
  reactiveDependencies: opts.reactiveDependencies,
397
356
  });
398
357
  return makeSpec('display', def);
@@ -407,12 +366,18 @@ export function createColumnFactory() {
407
366
  ...commonProps(opts, 'bubble'),
408
367
  accessorFn: opts.value,
409
368
  maxBubbles: opts.maxBubbles,
369
+ // `opts.colour` is typed `(row, index, value: TValue) => ...`
370
+ // but `BubbleDef.getColour` expects `value: string` (one bubble's
371
+ // rendered text). The bridge from `TValue` to `string` happens
372
+ // at render time inside the bubble renderer (each value coerces
373
+ // to a string via `String(...)` for display). The cast is
374
+ // load-bearing because TS cannot prove `TValue` is `string`-
375
+ // compatible at this layer.
410
376
  getColour: opts.colour,
411
- // Default to a string-typed filter so bubble columns appear in
412
- // the quick-filter row and advanced filter panel by default
413
- // (matches the `BubbleDef stringFilter` mapping in
414
- // `setupDefaultColumnDefs`). Caller can override to any other
415
- // `filterValueType`, or pass `allowFiltering: false` to opt out.
377
+ // Default to String so bubble columns appear in the filter UI
378
+ // (matches `BubbleDef stringFilter` in setupDefaultColumnDefs).
379
+ // Caller can override with another `filterValueType` or pass
380
+ // `allowFiltering: false` to opt out.
416
381
  filterValueType: opts.filterValueType ?? FilterValueType.String,
417
382
  getOptions: normalisedOptions,
418
383
  });
@@ -443,9 +408,9 @@ export function createColumnFactory() {
443
408
  ...commonProps(opts, 'progress'),
444
409
  accessorFn: tupleAccessor,
445
410
  getColour,
446
- // Default to number-typed filter so progress columns appear in
447
- // the filter UI by default (matches `ProgressBarDef →
448
- // numberFilter` in `setupDefaultColumnDefs`).
411
+ // Default to Number so progress columns appear in the filter
412
+ // UI (matches `ProgressBarDef → numberFilter` in
413
+ // setupDefaultColumnDefs).
449
414
  filterValueType: opts.filterValueType ?? FilterValueType.Number,
450
415
  getOptions: progressOptions,
451
416
  });
@@ -473,9 +438,9 @@ export function createColumnFactory() {
473
438
  const def = new RowSelectionDef({
474
439
  isSelectable: opts?.isSelectable ?? (() => true),
475
440
  });
476
- // RowSelection has no public width option - apply the per-kind
477
- // default so the column does not collapse to the 48px ColumnDef
478
- // fallback and share equal `1fr` track space with wider columns.
441
+ // RowSelection has no public width option apply the per-kind
442
+ // default so the column does not fall back to the 48px ColumnDef
443
+ // floor and share equal `1fr` track space with wider columns.
479
444
  def.width = KIND_DEFAULT_WIDTHS.rowSelection;
480
445
  def.minSize = KIND_DEFAULT_WIDTHS.rowSelection;
481
446
  def.widthIsFixed = true;
@@ -484,8 +449,7 @@ export function createColumnFactory() {
484
449
  actions(opts) {
485
450
  const wrapped = opts.actions.map((action) => {
486
451
  // `label` may be a literal string or a `(row) => string |
487
- // Promise<string>` function. The internal Def expects a
488
- // `getLabel(item, index)` so wrap accordingly.
452
+ // Promise<string>` function; the Def needs the function form.
489
453
  const labelOption = action.label;
490
454
  const getLabel = typeof labelOption === 'function' ? (item) => labelOption(item) : () => labelOption;
491
455
  return {
@@ -501,17 +465,16 @@ export function createColumnFactory() {
501
465
  actions: wrapped,
502
466
  isEnabled: isEnabledFn ? (item) => isEnabledFn(item) : undefined,
503
467
  });
504
- // Actions has no public width option - apply the per-kind default.
468
+ // Actions has no public width option apply the per-kind default.
505
469
  def.width = KIND_DEFAULT_WIDTHS.actions;
506
470
  def.widthIsFixed = true;
507
471
  return makeSpec('actions', def);
508
472
  },
509
473
  expand(opts) {
510
- // `childRowId` may be either a function or a key string;
511
- // the inner `TableContext` expects a function form for
474
+ // `childRowId` may be a function or a key string; the inner
475
+ // `TableContext` expects the function form for
512
476
  // `selectionExtractor`. Normalise here so the nested table
513
- // never sees the raw string and `SelectionState.cachedKey`
514
- // can safely invoke the extractor.
477
+ // always receives a callable.
515
478
  const childRowIdFn = typeof opts.childRowId === 'function'
516
479
  ? opts.childRowId
517
480
  : (inner) => inner[opts.childRowId];
@@ -524,11 +487,9 @@ export function createColumnFactory() {
524
487
  headerIcon: opts.headerIcon ?? 'chevron-down',
525
488
  innerTableName: scoriaStorageKey(opts.name),
526
489
  getInnerColumnDefs: (row, index) => {
527
- // `childColumns` receives the outer row + index so the
528
- // inner column set may branch per row (pick-wave-subtype
529
- // drill-downs, for example). Outer-row args are optional
530
- // at the consumer site, so closures that ignore them
531
- // continue working unchanged.
490
+ // `childColumns` receives the outer row + index so the inner
491
+ // column set may branch per row (e.g. pick-wave-subtype
492
+ // drill-downs). Both args are optional at the consumer site.
532
493
  const innerFactory = createColumnFactory();
533
494
  const innerSpecs = opts.childColumns(innerFactory, row, index);
534
495
  const innerDefs = innerSpecs.map((spec) => unwrapColumnSpec(spec).def);
@@ -546,7 +507,7 @@ export function createColumnFactory() {
546
507
  allowCopy: opts.inner?.allowCopy,
547
508
  },
548
509
  });
549
- // Expand has no public width option - apply the per-kind default.
510
+ // Expand has no public width option apply the per-kind default.
550
511
  def.width = KIND_DEFAULT_WIDTHS.expand;
551
512
  def.minSize = KIND_DEFAULT_WIDTHS.expand;
552
513
  def.widthIsFixed = true;
@@ -554,6 +515,12 @@ export function createColumnFactory() {
554
515
  },
555
516
  filterOnly(opts) {
556
517
  const def = new FilterOnlyDef({
518
+ // `opts.id` is `K extends string`, which allows free-form
519
+ // dotted-path / camelCase ids (the public surface flowms
520
+ // relies on). The Def's `id` field is the branded
521
+ // `ColumnId<TRow>`; the brand is structural and the cast is
522
+ // safe because `FilterOnlyDef` never narrows back to
523
+ // `keyof TRow` at runtime.
557
524
  id: opts.id,
558
525
  header: opts.header,
559
526
  allowSorting: false,
@@ -0,0 +1,112 @@
1
+ import type { ColumnDef } from './Types/Columns/Definitions/ColumnDef.svelte.js';
2
+ /**
3
+ * Shape of the per-type filter function set `TableContext` owns. Each
4
+ * concrete `FilterFn<T, ValueType>` narrows its second generic to the
5
+ * value-type it accepts; the registry stays decoupled from that detail
6
+ * by reaching for these via a name lookup and returning `unknown` to the
7
+ * call site, which casts back to `ColumnDef.filterFn` at assignment.
8
+ */
9
+ export interface LocalFilterFns {
10
+ stringFilter: unknown;
11
+ numberFilter: unknown;
12
+ selectFilter: unknown;
13
+ boolFilter: unknown;
14
+ dateFilter: unknown;
15
+ }
16
+ /**
17
+ * Categorisation used by `setupDefaultColumnDefs`:
18
+ *
19
+ * - `accessor` — column has its own data accessor; the kind dictates the
20
+ * filter (text→string, number→number, etc.). MinSize falls back to the
21
+ * measured header width.
22
+ * - `display` — column has no accessor; the consumer's `filterValueType`
23
+ * on the def picks the filter at runtime via `resolveDisplayFilter`.
24
+ * - `structural` — row-selection / actions / expand / filterOnly etc. No
25
+ * default filter wiring.
26
+ */
27
+ export type ColumnKindCategory = 'accessor' | 'display' | 'structural';
28
+ export interface ColumnKindEntry {
29
+ readonly category: ColumnKindCategory;
30
+ /**
31
+ * For `accessor`-category kinds: the name of the filter function on
32
+ * `LocalFilterFns` that this kind defaults to.
33
+ *
34
+ * For `display`-category kinds whose filter is fixed (e.g. `bubble`
35
+ * always uses `stringFilter`, `progress` always uses `numberFilter`):
36
+ * same lookup.
37
+ *
38
+ * `undefined` for `structural` kinds and for `display` kinds whose
39
+ * filter follows `def.filterValueType` (handled by
40
+ * `resolveDisplayFilter` instead).
41
+ */
42
+ readonly defaultFilter?: keyof LocalFilterFns;
43
+ }
44
+ /** Registry literal. Kept in sync with the `ColumnKind` type by the
45
+ * `satisfies Record<ColumnKind, ColumnKindEntry>` check below. */
46
+ export declare const COLUMN_KIND_REGISTRY: {
47
+ readonly text: {
48
+ readonly category: "accessor";
49
+ readonly defaultFilter: "stringFilter";
50
+ };
51
+ readonly number: {
52
+ readonly category: "accessor";
53
+ readonly defaultFilter: "numberFilter";
54
+ };
55
+ readonly checkbox: {
56
+ readonly category: "accessor";
57
+ readonly defaultFilter: "boolFilter";
58
+ };
59
+ readonly date: {
60
+ readonly category: "accessor";
61
+ readonly defaultFilter: "dateFilter";
62
+ };
63
+ readonly select: {
64
+ readonly category: "accessor";
65
+ readonly defaultFilter: "selectFilter";
66
+ };
67
+ readonly query: {
68
+ readonly category: "accessor";
69
+ readonly defaultFilter: "stringFilter";
70
+ };
71
+ readonly display: {
72
+ readonly category: "display";
73
+ };
74
+ readonly bubble: {
75
+ readonly category: "display";
76
+ readonly defaultFilter: "stringFilter";
77
+ };
78
+ readonly progress: {
79
+ readonly category: "display";
80
+ readonly defaultFilter: "numberFilter";
81
+ };
82
+ readonly validity: {
83
+ readonly category: "structural";
84
+ };
85
+ readonly actions: {
86
+ readonly category: "structural";
87
+ };
88
+ readonly rowSelection: {
89
+ readonly category: "structural";
90
+ };
91
+ readonly expand: {
92
+ readonly category: "structural";
93
+ };
94
+ readonly filterOnly: {
95
+ readonly category: "structural";
96
+ };
97
+ };
98
+ /**
99
+ * Resolve a `display`-category def's filter from its `filterValueType`.
100
+ * Returns `undefined` when the value-type is unrecognised, so callers may
101
+ * fall through to a no-op or default.
102
+ */
103
+ export declare function resolveDisplayFilter<T extends object>(def: ColumnDef<T>, filters: LocalFilterFns): unknown;
104
+ /**
105
+ * Resolve the default filter function for a column given its `kind`.
106
+ * Returns `unknown` (the call site casts back to the def's local
107
+ * `FilterFn<T, ValueType>` shape on assignment). Returns `undefined`
108
+ * when the kind is structural, when the kind is unknown (e.g. a
109
+ * hand-constructed `ColumnDef` outside the factory), or when a
110
+ * `display` column has no recognised `filterValueType`.
111
+ */
112
+ export declare function resolveDefaultFilter<T extends object>(def: ColumnDef<T>, filters: LocalFilterFns): unknown;
@@ -0,0 +1,63 @@
1
+ /** Registry literal. Kept in sync with the `ColumnKind` type by the
2
+ * `satisfies Record<ColumnKind, ColumnKindEntry>` check below. */
3
+ export const COLUMN_KIND_REGISTRY = {
4
+ text: { category: 'accessor', defaultFilter: 'stringFilter' },
5
+ number: { category: 'accessor', defaultFilter: 'numberFilter' },
6
+ checkbox: { category: 'accessor', defaultFilter: 'boolFilter' },
7
+ date: { category: 'accessor', defaultFilter: 'dateFilter' },
8
+ select: { category: 'accessor', defaultFilter: 'selectFilter' },
9
+ query: { category: 'accessor', defaultFilter: 'stringFilter' },
10
+ display: { category: 'display' },
11
+ bubble: { category: 'display', defaultFilter: 'stringFilter' },
12
+ progress: { category: 'display', defaultFilter: 'numberFilter' },
13
+ validity: { category: 'structural' },
14
+ actions: { category: 'structural' },
15
+ rowSelection: { category: 'structural' },
16
+ expand: { category: 'structural' },
17
+ filterOnly: { category: 'structural' },
18
+ };
19
+ /**
20
+ * Resolve a `display`-category def's filter from its `filterValueType`.
21
+ * Returns `undefined` when the value-type is unrecognised, so callers may
22
+ * fall through to a no-op or default.
23
+ */
24
+ export function resolveDisplayFilter(def, filters) {
25
+ switch (def.filterValueType) {
26
+ case undefined:
27
+ case 'String':
28
+ return filters.stringFilter;
29
+ case 'Bool':
30
+ return filters.boolFilter;
31
+ case 'Date':
32
+ return filters.dateFilter;
33
+ case 'Number':
34
+ return filters.numberFilter;
35
+ case 'Select':
36
+ return filters.selectFilter;
37
+ }
38
+ }
39
+ /**
40
+ * Resolve the default filter function for a column given its `kind`.
41
+ * Returns `unknown` (the call site casts back to the def's local
42
+ * `FilterFn<T, ValueType>` shape on assignment). Returns `undefined`
43
+ * when the kind is structural, when the kind is unknown (e.g. a
44
+ * hand-constructed `ColumnDef` outside the factory), or when a
45
+ * `display` column has no recognised `filterValueType`.
46
+ */
47
+ export function resolveDefaultFilter(def, filters) {
48
+ if (def.kind == null) {
49
+ return undefined;
50
+ }
51
+ const entry = COLUMN_KIND_REGISTRY[def.kind];
52
+ if (entry.category === 'structural') {
53
+ return undefined;
54
+ }
55
+ if (entry.defaultFilter !== undefined) {
56
+ return filters[entry.defaultFilter];
57
+ }
58
+ // Plain `col.display` — filter follows the consumer's filterValueType.
59
+ if (entry.category === 'display') {
60
+ return resolveDisplayFilter(def, filters);
61
+ }
62
+ return undefined;
63
+ }