@dbcdk/react-components 0.0.96 → 0.0.97

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 (223) hide show
  1. package/dist/components/table/Table.d.ts +1 -1
  2. package/dist/components/table/Table.types.d.ts +3 -0
  3. package/dist/components/table/components/TableHeader.d.ts +2 -1
  4. package/dist/index.cjs +12750 -0
  5. package/dist/index.css +7149 -0
  6. package/dist/index.js +12641 -79
  7. package/dist/tanstack.cjs +2674 -0
  8. package/dist/tanstack.css +1267 -0
  9. package/dist/tanstack.js +2650 -3
  10. package/dist/themes/dbc.css +3 -0
  11. package/dist/themes/forfatterweb.css +2 -0
  12. package/package.json +11 -10
  13. package/dist/assets/logo.js +0 -2
  14. package/dist/components/__stories__/_data/table.d.ts +0 -15
  15. package/dist/components/__stories__/_data/table.js +0 -55
  16. package/dist/components/__stories__/_data/tabs.d.ts +0 -9
  17. package/dist/components/__stories__/_data/tabs.js +0 -31
  18. package/dist/components/__stories__/story-components/Colors.d.ts +0 -11
  19. package/dist/components/__stories__/story-components/Colors.js +0 -96
  20. package/dist/components/__stories__/story-components/Colors.module.css +0 -27
  21. package/dist/components/__stories__/story-components/ComponentSizes.d.ts +0 -2
  22. package/dist/components/__stories__/story-components/ComponentSizes.js +0 -26
  23. package/dist/components/__stories__/story-components/Elevation.d.ts +0 -2
  24. package/dist/components/__stories__/story-components/Elevation.js +0 -49
  25. package/dist/components/__stories__/story-components/Flex.d.ts +0 -2
  26. package/dist/components/__stories__/story-components/Flex.js +0 -177
  27. package/dist/components/__stories__/story-components/Flex.module.css +0 -317
  28. package/dist/components/__stories__/story-components/Spacing.d.ts +0 -6
  29. package/dist/components/__stories__/story-components/Spacing.js +0 -76
  30. package/dist/components/__stories__/story-components/Spacing.module.css +0 -154
  31. package/dist/components/accordion/Accordion.js +0 -70
  32. package/dist/components/accordion/Accordion.module.css +0 -28
  33. package/dist/components/accordion/components/AccordionRow.js +0 -53
  34. package/dist/components/accordion/components/AccordionRow.module.css +0 -90
  35. package/dist/components/alert/Alert.js +0 -17
  36. package/dist/components/alert/Alert.module.css +0 -98
  37. package/dist/components/app-header/AppHeader.js +0 -5
  38. package/dist/components/app-header/AppHeader.module.css +0 -74
  39. package/dist/components/attribute-chip/AttributeChip.js +0 -5
  40. package/dist/components/attribute-chip/AttributeChip.module.css +0 -65
  41. package/dist/components/avatar/Avatar.js +0 -48
  42. package/dist/components/avatar/Avatar.module.css +0 -91
  43. package/dist/components/breadcrumbs/Breadcrumbs.js +0 -6
  44. package/dist/components/breadcrumbs/Breadcrumbs.module.css +0 -80
  45. package/dist/components/button/Button.js +0 -81
  46. package/dist/components/button/Button.module.css +0 -249
  47. package/dist/components/button-select/ButtonSelect.js +0 -7
  48. package/dist/components/button-select/ButtonSelect.module.css +0 -40
  49. package/dist/components/card/Card.js +0 -71
  50. package/dist/components/card/Card.module.css +0 -160
  51. package/dist/components/card/components/CardMeta.js +0 -26
  52. package/dist/components/card/components/CardMeta.module.css +0 -55
  53. package/dist/components/card-container/CardContainer.js +0 -6
  54. package/dist/components/card-container/CardContainer.module.css +0 -61
  55. package/dist/components/chip/Chip.js +0 -31
  56. package/dist/components/chip/Chip.module.css +0 -236
  57. package/dist/components/circle/Circle.js +0 -5
  58. package/dist/components/circle/Circle.module.css +0 -128
  59. package/dist/components/clear-button/ClearButton.js +0 -13
  60. package/dist/components/clear-button/ClearButton.module.css +0 -26
  61. package/dist/components/code-block/CodeBlock.js +0 -58
  62. package/dist/components/code-block/CodeBlock.module.css +0 -124
  63. package/dist/components/copy-button/CopyButton.js +0 -78
  64. package/dist/components/copy-button/CopyButton.module.css +0 -22
  65. package/dist/components/datetime-picker/DateTimePicker.js +0 -403
  66. package/dist/components/datetime-picker/DateTimePicker.module.css +0 -155
  67. package/dist/components/datetime-picker/dateTimeHelpers.js +0 -248
  68. package/dist/components/divider/Divider.js +0 -12
  69. package/dist/components/filter-field/FilterField.js +0 -191
  70. package/dist/components/filter-field/FilterField.module.css +0 -379
  71. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.js +0 -52
  72. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.module.css +0 -59
  73. package/dist/components/forms/checkbox/Checkbox.js +0 -28
  74. package/dist/components/forms/checkbox/Checkbox.module.css +0 -103
  75. package/dist/components/forms/checkbox-group/CheckboxGroup.js +0 -75
  76. package/dist/components/forms/checkbox-group/CheckboxGroup.module.css +0 -115
  77. package/dist/components/forms/form-select/FormSelect.js +0 -86
  78. package/dist/components/forms/form-select/FormSelect.module.css +0 -236
  79. package/dist/components/forms/input/Input.js +0 -77
  80. package/dist/components/forms/input/Input.module.css +0 -468
  81. package/dist/components/forms/input-container/InputContainer.js +0 -15
  82. package/dist/components/forms/input-container/InputContainer.module.css +0 -60
  83. package/dist/components/forms/multi-select/MultiSelect.js +0 -122
  84. package/dist/components/forms/radio-buttons/RadioButton.js +0 -26
  85. package/dist/components/forms/radio-buttons/RadioButtonGroup.js +0 -19
  86. package/dist/components/forms/radio-buttons/RadioButtons.module.css +0 -118
  87. package/dist/components/forms/select/Select.js +0 -185
  88. package/dist/components/forms/select/Select.module.css +0 -32
  89. package/dist/components/forms/text-area/Textarea.js +0 -47
  90. package/dist/components/forms/text-area/Textarea.module.css +0 -70
  91. package/dist/components/forms/typeahead/Typeahead.js +0 -668
  92. package/dist/components/forms/typeahead/Typeahead.module.css +0 -38
  93. package/dist/components/grid/Grid.js +0 -23
  94. package/dist/components/grid/Grid.module.css +0 -35
  95. package/dist/components/headline/CollapsibleHeadline.js +0 -29
  96. package/dist/components/headline/Headline.js +0 -26
  97. package/dist/components/headline/Headline.module.css +0 -185
  98. package/dist/components/hyperlink/Hyperlink.js +0 -40
  99. package/dist/components/hyperlink/Hyperlink.module.css +0 -107
  100. package/dist/components/icon/Icon.js +0 -14
  101. package/dist/components/icon/Icon.module.css +0 -36
  102. package/dist/components/interval-select/IntervalSelect.js +0 -99
  103. package/dist/components/json-viewer/HighlightedText.js +0 -6
  104. package/dist/components/json-viewer/JsonNode.js +0 -30
  105. package/dist/components/json-viewer/JsonViewer.js +0 -68
  106. package/dist/components/json-viewer/JsonViewer.module.css +0 -346
  107. package/dist/components/json-viewer/types.js +0 -1
  108. package/dist/components/json-viewer/useClipboardStatus.js +0 -11
  109. package/dist/components/json-viewer/utils.js +0 -125
  110. package/dist/components/menu/Menu.js +0 -165
  111. package/dist/components/menu/Menu.module.css +0 -220
  112. package/dist/components/meta-bar/MetaBar.js +0 -9
  113. package/dist/components/meta-bar/MetaBar.module.css +0 -27
  114. package/dist/components/nav-bar/NavBar.js +0 -29
  115. package/dist/components/nav-bar/NavBar.module.css +0 -221
  116. package/dist/components/overlay/fade-overlay/FadeOverlay.js +0 -8
  117. package/dist/components/overlay/fade-overlay/FadeOverlay.module.css +0 -54
  118. package/dist/components/overlay/modal/Modal.js +0 -115
  119. package/dist/components/overlay/modal/Modal.module.css +0 -109
  120. package/dist/components/overlay/modal/provider/ModalProvider.js +0 -73
  121. package/dist/components/overlay/side-panel/SidePanel.js +0 -83
  122. package/dist/components/overlay/side-panel/SidePanel.module.css +0 -177
  123. package/dist/components/overlay/side-panel/useSidePanel.js +0 -11
  124. package/dist/components/overlay/tooltip/Tooltip.js +0 -17
  125. package/dist/components/overlay/tooltip/Tooltip.module.css +0 -104
  126. package/dist/components/overlay/tooltip/TooltipProvider.js +0 -255
  127. package/dist/components/overlay/tooltip/useTooltipTrigger.js +0 -118
  128. package/dist/components/page/Page.js +0 -11
  129. package/dist/components/page/Page.module.css +0 -89
  130. package/dist/components/page-layout/PageLayout.js +0 -76
  131. package/dist/components/page-layout/PageLayout.module.css +0 -236
  132. package/dist/components/page-layout/components/layout-footer/LayoutFooter.js +0 -27
  133. package/dist/components/page-layout/components/layout-footer/LayoutFooter.module.css +0 -89
  134. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.js +0 -14
  135. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.module.css +0 -84
  136. package/dist/components/pagination/Pagination.js +0 -56
  137. package/dist/components/pagination/Pagination.module.css +0 -25
  138. package/dist/components/panel/Panel.js +0 -7
  139. package/dist/components/panel/Panel.module.css +0 -29
  140. package/dist/components/popover/Popover.js +0 -257
  141. package/dist/components/popover/Popover.module.css +0 -54
  142. package/dist/components/search-box/SearchBox.js +0 -170
  143. package/dist/components/search-box/SearchBox.module.css +0 -21
  144. package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +0 -48
  145. package/dist/components/segmented-progress-bar/SegmentedProgressBar.module.css +0 -167
  146. package/dist/components/sidebar/Sidebar.js +0 -6
  147. package/dist/components/sidebar/components/SidebarItem.js +0 -8
  148. package/dist/components/sidebar/components/SidebarItem.module.css +0 -0
  149. package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.js +0 -63
  150. package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css +0 -29
  151. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +0 -153
  152. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +0 -260
  153. package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.js +0 -18
  154. package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css +0 -106
  155. package/dist/components/sidebar/components/sidebar-items/SidebarItems.js +0 -26
  156. package/dist/components/sidebar/components/sidebar-items/SidebarItems.module.css +0 -20
  157. package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.js +0 -30
  158. package/dist/components/sidebar/providers/SidebarProvider.js +0 -229
  159. package/dist/components/skeleton-loader/SkeletonLoader.js +0 -73
  160. package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.js +0 -13
  161. package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.module.css +0 -51
  162. package/dist/components/split-button/SplitButton.js +0 -10
  163. package/dist/components/split-button/SplitButton.module.css +0 -32
  164. package/dist/components/split-pane/SplitPane.js +0 -107
  165. package/dist/components/split-pane/SplitPane.module.css +0 -111
  166. package/dist/components/split-pane/provider/SplitPaneContext.js +0 -124
  167. package/dist/components/stack/Stack.js +0 -33
  168. package/dist/components/stack/Stack.module.css +0 -61
  169. package/dist/components/state-page/StatePage.js +0 -20
  170. package/dist/components/state-page/StatePage.module.css +0 -9
  171. package/dist/components/state-page/empty.js +0 -2
  172. package/dist/components/state-page/error.js +0 -2
  173. package/dist/components/state-page/notFound.js +0 -2
  174. package/dist/components/sticky-footer-layout/StickyFooterLayout.js +0 -64
  175. package/dist/components/table/Table.js +0 -50
  176. package/dist/components/table/Table.module.css +0 -536
  177. package/dist/components/table/Table.types.js +0 -1
  178. package/dist/components/table/TanstackTable.js +0 -111
  179. package/dist/components/table/components/TableBody.js +0 -10
  180. package/dist/components/table/components/TableHeader.js +0 -7
  181. package/dist/components/table/components/TableHeaderCell.js +0 -24
  182. package/dist/components/table/components/TableLoadingBody.js +0 -26
  183. package/dist/components/table/components/TablePagination.js +0 -1
  184. package/dist/components/table/components/TableRow.js +0 -54
  185. package/dist/components/table/components/TableSelectionCell.js +0 -16
  186. package/dist/components/table/components/column-resizer/ColumnResizer.js +0 -5
  187. package/dist/components/table/components/column-resizer/ColumnResizer.module.css +0 -22
  188. package/dist/components/table/components/empty-state/EmptyState.js +0 -23
  189. package/dist/components/table/components/empty-state/EmptyState.module.css +0 -4
  190. package/dist/components/table/components/table-settings/TableSettings.js +0 -63
  191. package/dist/components/table/hooks/useTableRowInteractions.js +0 -30
  192. package/dist/components/table/table.classes.js +0 -23
  193. package/dist/components/table/table.utils.js +0 -47
  194. package/dist/components/table/tanstackTable.utils.js +0 -175
  195. package/dist/components/tabs/Tabs.js +0 -125
  196. package/dist/components/tabs/Tabs.module.css +0 -233
  197. package/dist/components/theme-button/ThemeButton.js +0 -23
  198. package/dist/components/toast/Toast.js +0 -20
  199. package/dist/components/toast/Toast.module.css +0 -161
  200. package/dist/components/toast/provider/ToastProvider.js +0 -70
  201. package/dist/components/user-display/UserDisplay.js +0 -6
  202. package/dist/components/user-display/UserDisplay.module.css +0 -25
  203. package/dist/constants/severity.js +0 -24
  204. package/dist/constants/severity.types.js +0 -1
  205. package/dist/constants/sizes.js +0 -7
  206. package/dist/hooks/useDeviceSize.js +0 -32
  207. package/dist/hooks/useListNavigation.js +0 -234
  208. package/dist/hooks/usePagination.js +0 -140
  209. package/dist/hooks/useSorting.js +0 -118
  210. package/dist/hooks/useTableData.js +0 -45
  211. package/dist/hooks/useTableSelection.js +0 -164
  212. package/dist/hooks/useTableSettings.js +0 -71
  213. package/dist/hooks/useTheme.js +0 -66
  214. package/dist/hooks/useTimeDuration.js +0 -68
  215. package/dist/hooks/useViewportFill.js +0 -77
  216. package/dist/styles/animation.js +0 -5
  217. package/dist/styles/themes/types.js +0 -1
  218. package/dist/types/a11y-props.types.js +0 -1
  219. package/dist/types/sizes.types.js +0 -1
  220. package/dist/utils/arrays/nested-filtering.js +0 -48
  221. package/dist/utils/date/formatDate.js +0 -51
  222. package/dist/utils/localStorage.utils.js +0 -78
  223. package/dist/utils/text/get-highlighted-segments.js +0 -46
@@ -1,248 +0,0 @@
1
- /* ---------- Range separator helpers ---------- */
2
- /**
3
- * IMPORTANT:
4
- * "-" is only treated as a range separator when surrounded by whitespace: " - "
5
- * so we don't split inside "DD-MM-YYYY".
6
- *
7
- * Supported separators:
8
- * - En dash: "–" (with optional surrounding spaces)
9
- * - Hyphen as range sep: " - " (spaces required)
10
- * - Words: "to", "til" (with optional surrounding spaces)
11
- *
12
- * COMPAT:
13
- * - Also supports digit-only ranges like "01022026-02022026" (no spaces),
14
- * because that cannot be confused with "DD-MM-YYYY".
15
- */
16
- const RANGE_SEP_RE = /\s*(?:–|\bto\b|\btil\b|\s-\s)\s*/i;
17
- function normalizeSpaces(s) {
18
- return s.trim().replace(/\s+/g, ' ');
19
- }
20
- /**
21
- * Special-case for digit-only ranges: 8 digits + '-' + 8 digits (optional spaces).
22
- * This keeps legacy UX working without reintroducing the DD-MM-YYYY split bug.
23
- */
24
- function splitDigitOnlyRangeParts(input) {
25
- const m = /^\s*(\d{8})\s*-\s*(\d{8})\s*$/.exec(input);
26
- if (!m)
27
- return null;
28
- return [m[1], m[2]];
29
- }
30
- function splitRangeParts(input) {
31
- var _a;
32
- // 1) digit-only fast path: 01022026-02022026
33
- const digitOnly = splitDigitOnlyRangeParts(input);
34
- if (digitOnly)
35
- return digitOnly;
36
- // 2) normal path: use safe separators (–, to, til, " - ")
37
- const txt = normalizeSpaces(input);
38
- const parts = txt.split(RANGE_SEP_RE);
39
- if (parts.length < 2)
40
- return null;
41
- const left = ((_a = parts[0]) !== null && _a !== void 0 ? _a : '').trim();
42
- const right = parts.slice(1).join(' ').trim();
43
- if (!left || !right)
44
- return null;
45
- return [left, right];
46
- }
47
- /* ---------- Mask helpers (no deps) ---------- */
48
- // Pull only 0-9
49
- export const digits = (s) => (s.match(/\d/g) || []).join('');
50
- // DD-MM-YYYY
51
- export function maskDateEU(text) {
52
- const d = digits(text).slice(0, 8);
53
- const dd = d.slice(0, 2);
54
- const mm = d.slice(2, 4);
55
- const yyyy = d.slice(4, 8);
56
- let out = dd;
57
- if (mm.length)
58
- out += (out ? '-' : '') + mm;
59
- if (yyyy.length)
60
- out += (out ? '-' : '') + yyyy;
61
- return out;
62
- }
63
- // HH:mm (24h)
64
- export function maskTimeHM(text) {
65
- const d = digits(text).slice(0, 4);
66
- const hh = d.slice(0, 2);
67
- const mm = d.slice(2, 4);
68
- return mm.length ? `${hh}:${mm}` : hh;
69
- }
70
- // Single: "DD-MM-YYYY" or "DD-MM-YYYY HH:mm"
71
- export function maskSingle(text, enableTime) {
72
- const t = normalizeSpaces(text);
73
- if (!enableTime)
74
- return maskDateEU(t);
75
- // split date + time by first space or 'T'
76
- const m = /^(.*?)[ T](.*)$/.exec(t);
77
- if (!m)
78
- return maskDateEU(t);
79
- const datePart = maskDateEU(m[1]);
80
- const timePart = maskTimeHM(m[2]);
81
- return timePart ? `${datePart} ${timePart}` : datePart;
82
- }
83
- // Range: mask both sides around common separators (–, " - ", to, til, or digit-only "01022026-02022026")
84
- export function maskRange(text, _enableTime) {
85
- // NOTE: range is date-only in the UI
86
- const parts = splitRangeParts(text);
87
- if (!parts)
88
- return maskSingle(text, false);
89
- const [left, right] = parts;
90
- const a = maskSingle(left, false);
91
- const b = maskSingle(right, false);
92
- return `${a} – ${b}`.trim();
93
- }
94
- // Pad helper
95
- export const pad2 = (n) => String(n).padStart(2, '0');
96
- export function isUtcIsoString(v) {
97
- return typeof v === 'string' && /Z$/.test(v) && !Number.isNaN(Date.parse(v));
98
- }
99
- export function isDateOnlyString(v) {
100
- if (typeof v !== 'string')
101
- return false;
102
- const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(v);
103
- if (!m)
104
- return false;
105
- const y = +m[1];
106
- const mo = +m[2];
107
- const d = +m[3];
108
- if (mo < 1 || mo > 12)
109
- return false;
110
- if (d < 1 || d > 31)
111
- return false;
112
- // Validate exact date (guard against 2026-02-31 etc.)
113
- const local = new Date(y, mo - 1, d, 0, 0, 0, 0);
114
- return local.getFullYear() === y && local.getMonth() === mo - 1 && local.getDate() === d;
115
- }
116
- export function utcMillisFromIso(iso) {
117
- return Date.parse(iso);
118
- }
119
- /** Convert a local DateTime to a UTC ISO string (Z). */
120
- export function isoFromLocalDate(dLocal) {
121
- return dLocal.toISOString();
122
- }
123
- /**
124
- * Build a *local* Date from y/m/d/hh/mm and return UTC ISO string (Z).
125
- * This keeps the UI meaning "local wall time", while emitting a stable UTC instant.
126
- *
127
- * DST NOTE:
128
- * If the requested local wall time does not exist (spring-forward), JS will auto-correct.
129
- * We detect that and return null so caller can handle it (e.g., show validation error).
130
- */
131
- export function isoFromLocalParts(y, m0, // 0-based
132
- d, hh = 0, mm = 0) {
133
- const local = new Date(y, m0, d, hh, mm, 0, 0);
134
- if (Number.isNaN(local.getTime()))
135
- return null;
136
- // Guard: JS autocorrects invalid dates/times; re-validate exact parts
137
- if (local.getFullYear() !== y ||
138
- local.getMonth() !== m0 ||
139
- local.getDate() !== d ||
140
- local.getHours() !== hh ||
141
- local.getMinutes() !== mm) {
142
- return null;
143
- }
144
- return local.toISOString();
145
- }
146
- /** For anchoring the calendar safely from a UTC ISO string. */
147
- export function localDateFromIso(iso) {
148
- const ms = Date.parse(iso);
149
- if (Number.isNaN(ms))
150
- return null;
151
- return new Date(ms); // local rendering
152
- }
153
- /** Date-only: build 'YYYY-MM-DD' from local parts */
154
- export function dateOnlyFromLocalParts(y, m0, d) {
155
- return `${String(y).padStart(4, '0')}-${pad2(m0 + 1)}-${pad2(d)}`;
156
- }
157
- /** Parse 'YYYY-MM-DD' into a local Date at midnight */
158
- export function localDateFromDateOnly(s) {
159
- if (!isDateOnlyString(s))
160
- return null;
161
- const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
162
- if (!m)
163
- return null;
164
- const y = +m[1];
165
- const mo0 = +m[2] - 1;
166
- const d = +m[3];
167
- const local = new Date(y, mo0, d, 0, 0, 0, 0);
168
- if (Number.isNaN(local.getTime()))
169
- return null;
170
- if (local.getFullYear() !== y || local.getMonth() !== mo0 || local.getDate() !== d)
171
- return null;
172
- return local;
173
- }
174
- /** Compare date-only strings by UTC date-only time (stable ordering) */
175
- export function compareDateOnly(a, b) {
176
- const da = localDateFromDateOnly(a);
177
- const db = localDateFromDateOnly(b);
178
- if (!da || !db)
179
- return 0;
180
- const ta = Date.UTC(da.getFullYear(), da.getMonth(), da.getDate());
181
- const tb = Date.UTC(db.getFullYear(), db.getMonth(), db.getDate());
182
- return ta - tb;
183
- }
184
- /* ---------- Formatting (UI shows local) ---------- */
185
- // From Date → "DD-MM-YYYY" or "DD-MM-YYYY HH:mm" (local time)
186
- export function toMaskedFromDate(d, enableTime) {
187
- const dd = pad2(d.getDate());
188
- const mm = pad2(d.getMonth() + 1);
189
- const yyyy = String(d.getFullYear());
190
- let out = `${dd}-${mm}-${yyyy}`;
191
- if (enableTime)
192
- out += ` ${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
193
- return out;
194
- }
195
- /* ---------- Parsing helpers (no deps) ---------- */
196
- // Accepts: YYYY-MM-DD, DD-MM-YYYY, DD/MM/YYYY, DD.MM.YYYY (+ optional HH:mm)
197
- export function parseLooseDateOrDateTime(input) {
198
- const txt = normalizeSpaces(input);
199
- const dateTimeMatch = /^(?<date>[\d./-]{8,10})(?:[ T](?<hh>\d{1,2}):(?<mm>\d{2}))?$/i.exec(txt);
200
- if (!(dateTimeMatch === null || dateTimeMatch === void 0 ? void 0 : dateTimeMatch.groups))
201
- return null;
202
- const raw = dateTimeMatch.groups.date;
203
- const hh = dateTimeMatch.groups.hh ? parseInt(dateTimeMatch.groups.hh, 10) : 0;
204
- const mm = dateTimeMatch.groups.mm ? parseInt(dateTimeMatch.groups.mm, 10) : 0;
205
- if (hh < 0 || hh > 23 || mm < 0 || mm > 59)
206
- return null;
207
- // Try YYYY-MM-DD first (still accepts 1-2 digits for month/day in ISO form)
208
- let y, m, d;
209
- const mIso = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(raw);
210
- if (mIso) {
211
- y = +mIso[1];
212
- m = +mIso[2] - 1;
213
- d = +mIso[3];
214
- }
215
- else {
216
- // EU formats must be strict DD-MM-YYYY / DD/MM/YYYY / DD.MM.YYYY
217
- const mEu = /^(\d{2})[./-](\d{2})[./-](\d{4})$/.exec(raw);
218
- if (!mEu)
219
- return null;
220
- d = +mEu[1];
221
- m = +mEu[2] - 1;
222
- y = +mEu[3];
223
- }
224
- const local = new Date(y, m, d, hh, mm, 0, 0);
225
- if (Number.isNaN(local.getTime()))
226
- return null;
227
- // Guard: JS autocorrects invalid dates; re-validate exact Y/M/D/H/M
228
- if (local.getFullYear() !== y ||
229
- local.getMonth() !== m ||
230
- local.getDate() !== d ||
231
- local.getHours() !== hh ||
232
- local.getMinutes() !== mm) {
233
- return null;
234
- }
235
- return local;
236
- }
237
- // Parse a range string with separators: "–", " - ", "to", "til", or digit-only "01022026-02022026"
238
- export function parseLooseRange(input) {
239
- const parts = splitRangeParts(input);
240
- if (!parts)
241
- return null;
242
- const [a, b] = parts;
243
- const s = parseLooseDateOrDateTime(a);
244
- const e = parseLooseDateOrDateTime(b);
245
- if (!s || !e)
246
- return null;
247
- return s <= e ? { start: s, end: e } : { start: e, end: s };
248
- }
@@ -1,12 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- const spacingMap = {
3
- sm: 'var(--spacing-sm)',
4
- md: 'var(--spacing-md)',
5
- lg: 'var(--spacing-lg)',
6
- };
7
- export const Divider = ({ spacing = 'md' }) => {
8
- return (_jsx("div", { style: {
9
- borderTop: '1px solid var(--color-border-subtle)',
10
- marginBlock: spacingMap[spacing],
11
- } }));
12
- };
@@ -1,191 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Check } from 'lucide-react';
4
- import { useMemo, useRef, useState, useEffect } from 'react';
5
- import { Input } from '../../components/forms/input/Input';
6
- import { Typeahead } from '../../components/forms/typeahead/Typeahead';
7
- import styles from './FilterField.module.css';
8
- import { Menu } from '../menu/Menu';
9
- import { Popover } from '../popover/Popover';
10
- const LABELS = {
11
- is: 'is',
12
- isNot: 'not',
13
- contains: 'contains',
14
- notContains: 'not contain',
15
- startsWith: 'starts with',
16
- endsWith: 'ends with',
17
- gt: '>',
18
- lt: '<',
19
- gte: '≥',
20
- lte: '≤',
21
- in: '',
22
- notIn: 'not in',
23
- isEmpty: 'empty',
24
- isNotEmpty: 'not empty',
25
- };
26
- const DEFAULT_TEXT_OPERATORS = [
27
- 'is',
28
- 'isNot',
29
- 'contains',
30
- 'notContains',
31
- 'startsWith',
32
- 'endsWith',
33
- 'isEmpty',
34
- 'isNotEmpty',
35
- ];
36
- export const NUMBER_OPERATORS = [
37
- 'is',
38
- 'isNot',
39
- 'gt',
40
- 'lt',
41
- 'gte',
42
- 'lte',
43
- 'isEmpty',
44
- 'isNotEmpty',
45
- ];
46
- const VALUELESS_OPERATORS = ['isEmpty', 'isNotEmpty'];
47
- const INPUT_DEBOUNCE_MS = 500;
48
- function OperatorDropdown({ value, onChange, operators, size = 'sm', disabled, }) {
49
- const popRef = useRef(null);
50
- const [activeIndex, setActiveIndex] = useState(() => Math.max(0, operators.indexOf(value)));
51
- useEffect(() => {
52
- setActiveIndex(Math.max(0, operators.indexOf(value)));
53
- }, [operators, value]);
54
- const handleSelect = (op) => {
55
- var _a;
56
- onChange(op);
57
- setActiveIndex(operators.indexOf(op));
58
- (_a = popRef.current) === null || _a === void 0 ? void 0 : _a.close();
59
- };
60
- return (_jsx(Popover, { ref: popRef, minWidth: "160px", trigger: (toggle, icon) => (_jsxs("button", { type: "button", onClick: toggle, disabled: disabled, "aria-label": "Skift operator", className: `${styles.operatorTrigger} ${styles[size]}`, children: [_jsx("span", { className: styles.operatorText, children: LABELS[value] }), icon] })), children: _jsx(Menu, { children: operators.map(op => {
61
- const selected = op === value;
62
- return (_jsx(Menu.Item, { active: selected, children: _jsxs("button", { type: "button", onClick: () => handleSelect(op), disabled: disabled, children: [_jsx("span", { style: { width: 16, display: 'inline-flex', justifyContent: 'center' }, children: selected ? _jsx(Check, { size: 16 }) : null }), LABELS[op]] }) }, op));
63
- }) }) }));
64
- }
65
- function isFilterActive(value) {
66
- if (Array.isArray(value))
67
- return value.length > 0;
68
- if (typeof value === 'string')
69
- return value.trim().length > 0;
70
- return value != null;
71
- }
72
- export function FilterField({ field, control, operator, value, onChange, operators, options = [], single = true, size = 'md', variant = 'surface', label, placeholder = 'Type value…', disabled, 'data-cy': dataCy, minWidth, width, maxWidth, popoverWidth, debounceTime = INPUT_DEBOUNCE_MS, ...inputProps }) {
73
- var _a, _b, _c, _d, _e, _f;
74
- const filterFieldRef = useRef(null);
75
- const ops = useMemo(() => operators !== null && operators !== void 0 ? operators : DEFAULT_TEXT_OPERATORS, [operators]);
76
- const shouldAutoFitTypeahead = control === 'select' && single && !width;
77
- const [selectedOperator, setSelectedOperator] = useState(operator);
78
- const active = isFilterActive(value);
79
- useEffect(() => {
80
- if (ops.includes(operator)) {
81
- // Keep the dropdown responsive to local selection immediately, but let the
82
- // controlled `operator` prop take back over once parent state catches up.
83
- // eslint-disable-next-line react-hooks/set-state-in-effect
84
- setSelectedOperator(operator);
85
- }
86
- }, [operator, ops]);
87
- const [localValue, setLocalValue] = useState((_a = value) !== null && _a !== void 0 ? _a : '');
88
- const debounceRef = useRef(null);
89
- /**
90
- * Holds the exact text value we most recently sent upward.
91
- * While waiting for that value to round-trip back through URL/provider state,
92
- * we ignore intermediate external churn so the input does not visually flicker.
93
- */
94
- const pendingValueRef = useRef(null);
95
- const emit = (next) => {
96
- var _a, _b;
97
- const nextOperator = (_a = next.operator) !== null && _a !== void 0 ? _a : selectedOperator;
98
- const nextValue = (_b = next.value) !== null && _b !== void 0 ? _b : value;
99
- if (next.operator) {
100
- setSelectedOperator(nextOperator);
101
- }
102
- onChange({
103
- field,
104
- operator: nextOperator,
105
- value: nextValue,
106
- });
107
- };
108
- const clearDebounce = () => {
109
- if (debounceRef.current) {
110
- clearTimeout(debounceRef.current);
111
- debounceRef.current = null;
112
- }
113
- };
114
- const scheduleEmitValue = (nextVal) => {
115
- clearDebounce();
116
- pendingValueRef.current = nextVal;
117
- debounceRef.current = setTimeout(() => {
118
- emit({ value: nextVal });
119
- }, debounceTime);
120
- };
121
- const flushPendingValue = () => {
122
- if (control !== 'input')
123
- return;
124
- clearDebounce();
125
- pendingValueRef.current = localValue;
126
- emit({ value: localValue });
127
- };
128
- const handleOperatorChange = (op) => {
129
- setSelectedOperator(op);
130
- if (!active && !VALUELESS_OPERATORS.includes(op))
131
- return;
132
- if (VALUELESS_OPERATORS.includes(op)) {
133
- clearDebounce();
134
- pendingValueRef.current = null;
135
- emit({ operator: op, value: null });
136
- return;
137
- }
138
- clearDebounce();
139
- pendingValueRef.current =
140
- control === 'input' ? localValue : typeof value === 'string' ? value : null;
141
- emit({ operator: op });
142
- };
143
- useEffect(() => {
144
- var _a;
145
- if (control !== 'input')
146
- return;
147
- const incoming = (_a = value) !== null && _a !== void 0 ? _a : '';
148
- const pending = pendingValueRef.current;
149
- if (pending !== null) {
150
- if (incoming === pending) {
151
- pendingValueRef.current = null;
152
- }
153
- return;
154
- }
155
- if (incoming !== localValue) {
156
- // Keep the embedded input responsive while debounced updates are in flight,
157
- // then resync to the controlled value once external state has settled.
158
- // eslint-disable-next-line react-hooks/set-state-in-effect
159
- setLocalValue(incoming);
160
- }
161
- }, [value, control, localValue]);
162
- useEffect(() => {
163
- return () => {
164
- clearDebounce();
165
- };
166
- }, []);
167
- return (_jsxs("div", { ref: filterFieldRef, ...(dataCy ? { 'data-cy': dataCy } : {}), className: [styles.filterField, styles[size], styles[variant], active ? styles.active : '']
168
- .filter(Boolean)
169
- .join(' '), children: [label ? _jsx("span", { className: `${styles.label} ${styles[size]}`, children: label }) : null, _jsx("div", { className: styles.operatorWrapper, children: _jsx(OperatorDropdown, { value: selectedOperator, onChange: handleOperatorChange, operators: ops, size: size, disabled: disabled }) }), _jsx("div", { className: [
170
- styles.valueWrapper,
171
- control === 'input' ? 'dbc-flex dbc-flex-grow' : '',
172
- shouldAutoFitTypeahead ? styles.autoWidth : '',
173
- ]
174
- .filter(Boolean)
175
- .join(' '), style: shouldAutoFitTypeahead ? (maxWidth ? { maxWidth } : undefined) : { width, maxWidth }, children: control === 'input' ? (_jsx(Input, { variant: "embedded", ...inputProps, fieldClassName: styles.embeddedInputField, inputClassName: styles.embeddedInputElement, value: localValue, onChange: e => {
176
- const next = e.currentTarget.value;
177
- setLocalValue(next);
178
- scheduleEmitValue(next);
179
- }, onBlur: () => {
180
- flushPendingValue();
181
- }, fullWidth: true, inputSize: size, placeholder: placeholder, disabled: disabled, autoComplete: (_b = inputProps.autoComplete) !== null && _b !== void 0 ? _b : 'off', autoCorrect: (_c = inputProps.autoCorrect) !== null && _c !== void 0 ? _c : 'off', autoCapitalize: (_d = inputProps.autoCapitalize) !== null && _d !== void 0 ? _d : 'none', spellCheck: (_e = inputProps.spellCheck) !== null && _e !== void 0 ? _e : false, onClear: () => {
182
- clearDebounce();
183
- pendingValueRef.current = '';
184
- setLocalValue('');
185
- emit({ value: '' });
186
- } })) : (_jsx(Typeahead, { options: options, mode: single ? 'single' : 'multi', selectedValue: single ? ((_f = value) !== null && _f !== void 0 ? _f : null) : Array.isArray(value) ? value : [], onChange: v => emit({ value: v }), minWidth: minWidth, popoverWidth: popoverWidth, popoverAnchorRef: filterFieldRef, placeholder: placeholder, variant: "embedded", inputProps: {
187
- inputSize: size,
188
- fieldClassName: styles.embeddedInputField,
189
- inputClassName: styles.embeddedInputElement,
190
- }, onClear: () => emit({ value: single ? '' : [] }), disabled: disabled, fullWidth: !shouldAutoFitTypeahead, fitContent: shouldAutoFitTypeahead })) })] }));
191
- }