@dbcdk/react-components 0.0.96 → 0.0.98

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 (235) hide show
  1. package/dist/components/page/Page.d.ts +2 -1
  2. package/dist/components/page-layout/PageLayout.d.ts +0 -2
  3. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.d.ts +1 -12
  4. package/dist/components/skeleton-loader/SkeletonLoader.d.ts +1 -1
  5. package/dist/components/table/Table.d.ts +1 -1
  6. package/dist/components/table/Table.types.d.ts +3 -0
  7. package/dist/components/table/components/TableHeader.d.ts +2 -1
  8. package/dist/components/tabs/Tabs.d.ts +2 -1
  9. package/dist/constants/chart-colors.d.ts +2 -0
  10. package/dist/constants/chart-colors.types.d.ts +3 -0
  11. package/dist/index.cjs +12830 -0
  12. package/dist/index.css +7084 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.js +12720 -79
  15. package/dist/styles/styles.css +6 -1
  16. package/dist/styles/themes/dbc/colors.css +14 -6
  17. package/dist/styles/themes/forfatterweb/light.css +17 -0
  18. package/dist/styles.css +6 -1
  19. package/dist/tanstack.cjs +2660 -0
  20. package/dist/tanstack.css +1267 -0
  21. package/dist/tanstack.js +2636 -3
  22. package/dist/themes/dbc.css +3 -0
  23. package/dist/themes/forfatterweb.css +2 -0
  24. package/package.json +11 -10
  25. package/dist/assets/logo.js +0 -2
  26. package/dist/components/__stories__/_data/table.d.ts +0 -15
  27. package/dist/components/__stories__/_data/table.js +0 -55
  28. package/dist/components/__stories__/_data/tabs.d.ts +0 -9
  29. package/dist/components/__stories__/_data/tabs.js +0 -31
  30. package/dist/components/__stories__/story-components/Colors.d.ts +0 -11
  31. package/dist/components/__stories__/story-components/Colors.js +0 -96
  32. package/dist/components/__stories__/story-components/Colors.module.css +0 -27
  33. package/dist/components/__stories__/story-components/ComponentSizes.d.ts +0 -2
  34. package/dist/components/__stories__/story-components/ComponentSizes.js +0 -26
  35. package/dist/components/__stories__/story-components/Elevation.d.ts +0 -2
  36. package/dist/components/__stories__/story-components/Elevation.js +0 -49
  37. package/dist/components/__stories__/story-components/Flex.d.ts +0 -2
  38. package/dist/components/__stories__/story-components/Flex.js +0 -177
  39. package/dist/components/__stories__/story-components/Flex.module.css +0 -317
  40. package/dist/components/__stories__/story-components/Spacing.d.ts +0 -6
  41. package/dist/components/__stories__/story-components/Spacing.js +0 -76
  42. package/dist/components/__stories__/story-components/Spacing.module.css +0 -154
  43. package/dist/components/accordion/Accordion.js +0 -70
  44. package/dist/components/accordion/Accordion.module.css +0 -28
  45. package/dist/components/accordion/components/AccordionRow.js +0 -53
  46. package/dist/components/accordion/components/AccordionRow.module.css +0 -90
  47. package/dist/components/alert/Alert.js +0 -17
  48. package/dist/components/alert/Alert.module.css +0 -98
  49. package/dist/components/app-header/AppHeader.js +0 -5
  50. package/dist/components/app-header/AppHeader.module.css +0 -74
  51. package/dist/components/attribute-chip/AttributeChip.js +0 -5
  52. package/dist/components/attribute-chip/AttributeChip.module.css +0 -65
  53. package/dist/components/avatar/Avatar.js +0 -48
  54. package/dist/components/avatar/Avatar.module.css +0 -91
  55. package/dist/components/breadcrumbs/Breadcrumbs.js +0 -6
  56. package/dist/components/breadcrumbs/Breadcrumbs.module.css +0 -80
  57. package/dist/components/button/Button.js +0 -81
  58. package/dist/components/button/Button.module.css +0 -249
  59. package/dist/components/button-select/ButtonSelect.js +0 -7
  60. package/dist/components/button-select/ButtonSelect.module.css +0 -40
  61. package/dist/components/card/Card.js +0 -71
  62. package/dist/components/card/Card.module.css +0 -160
  63. package/dist/components/card/components/CardMeta.js +0 -26
  64. package/dist/components/card/components/CardMeta.module.css +0 -55
  65. package/dist/components/card-container/CardContainer.js +0 -6
  66. package/dist/components/card-container/CardContainer.module.css +0 -61
  67. package/dist/components/chip/Chip.js +0 -31
  68. package/dist/components/chip/Chip.module.css +0 -236
  69. package/dist/components/circle/Circle.js +0 -5
  70. package/dist/components/circle/Circle.module.css +0 -128
  71. package/dist/components/clear-button/ClearButton.js +0 -13
  72. package/dist/components/clear-button/ClearButton.module.css +0 -26
  73. package/dist/components/code-block/CodeBlock.js +0 -58
  74. package/dist/components/code-block/CodeBlock.module.css +0 -124
  75. package/dist/components/copy-button/CopyButton.js +0 -78
  76. package/dist/components/copy-button/CopyButton.module.css +0 -22
  77. package/dist/components/datetime-picker/DateTimePicker.js +0 -403
  78. package/dist/components/datetime-picker/DateTimePicker.module.css +0 -155
  79. package/dist/components/datetime-picker/dateTimeHelpers.js +0 -248
  80. package/dist/components/divider/Divider.js +0 -12
  81. package/dist/components/filter-field/FilterField.js +0 -191
  82. package/dist/components/filter-field/FilterField.module.css +0 -379
  83. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.js +0 -52
  84. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.module.css +0 -59
  85. package/dist/components/forms/checkbox/Checkbox.js +0 -28
  86. package/dist/components/forms/checkbox/Checkbox.module.css +0 -103
  87. package/dist/components/forms/checkbox-group/CheckboxGroup.js +0 -75
  88. package/dist/components/forms/checkbox-group/CheckboxGroup.module.css +0 -115
  89. package/dist/components/forms/form-select/FormSelect.js +0 -86
  90. package/dist/components/forms/form-select/FormSelect.module.css +0 -236
  91. package/dist/components/forms/input/Input.js +0 -77
  92. package/dist/components/forms/input/Input.module.css +0 -468
  93. package/dist/components/forms/input-container/InputContainer.js +0 -15
  94. package/dist/components/forms/input-container/InputContainer.module.css +0 -60
  95. package/dist/components/forms/multi-select/MultiSelect.js +0 -122
  96. package/dist/components/forms/radio-buttons/RadioButton.js +0 -26
  97. package/dist/components/forms/radio-buttons/RadioButtonGroup.js +0 -19
  98. package/dist/components/forms/radio-buttons/RadioButtons.module.css +0 -118
  99. package/dist/components/forms/select/Select.js +0 -185
  100. package/dist/components/forms/select/Select.module.css +0 -32
  101. package/dist/components/forms/text-area/Textarea.js +0 -47
  102. package/dist/components/forms/text-area/Textarea.module.css +0 -70
  103. package/dist/components/forms/typeahead/Typeahead.js +0 -668
  104. package/dist/components/forms/typeahead/Typeahead.module.css +0 -38
  105. package/dist/components/grid/Grid.js +0 -23
  106. package/dist/components/grid/Grid.module.css +0 -35
  107. package/dist/components/headline/CollapsibleHeadline.js +0 -29
  108. package/dist/components/headline/Headline.js +0 -26
  109. package/dist/components/headline/Headline.module.css +0 -185
  110. package/dist/components/hyperlink/Hyperlink.js +0 -40
  111. package/dist/components/hyperlink/Hyperlink.module.css +0 -107
  112. package/dist/components/icon/Icon.js +0 -14
  113. package/dist/components/icon/Icon.module.css +0 -36
  114. package/dist/components/interval-select/IntervalSelect.js +0 -99
  115. package/dist/components/json-viewer/HighlightedText.js +0 -6
  116. package/dist/components/json-viewer/JsonNode.js +0 -30
  117. package/dist/components/json-viewer/JsonViewer.js +0 -68
  118. package/dist/components/json-viewer/JsonViewer.module.css +0 -346
  119. package/dist/components/json-viewer/types.js +0 -1
  120. package/dist/components/json-viewer/useClipboardStatus.js +0 -11
  121. package/dist/components/json-viewer/utils.js +0 -125
  122. package/dist/components/menu/Menu.js +0 -165
  123. package/dist/components/menu/Menu.module.css +0 -220
  124. package/dist/components/meta-bar/MetaBar.js +0 -9
  125. package/dist/components/meta-bar/MetaBar.module.css +0 -27
  126. package/dist/components/nav-bar/NavBar.js +0 -29
  127. package/dist/components/nav-bar/NavBar.module.css +0 -221
  128. package/dist/components/overlay/fade-overlay/FadeOverlay.js +0 -8
  129. package/dist/components/overlay/fade-overlay/FadeOverlay.module.css +0 -54
  130. package/dist/components/overlay/modal/Modal.js +0 -115
  131. package/dist/components/overlay/modal/Modal.module.css +0 -109
  132. package/dist/components/overlay/modal/provider/ModalProvider.js +0 -73
  133. package/dist/components/overlay/side-panel/SidePanel.js +0 -83
  134. package/dist/components/overlay/side-panel/SidePanel.module.css +0 -177
  135. package/dist/components/overlay/side-panel/useSidePanel.js +0 -11
  136. package/dist/components/overlay/tooltip/Tooltip.js +0 -17
  137. package/dist/components/overlay/tooltip/Tooltip.module.css +0 -104
  138. package/dist/components/overlay/tooltip/TooltipProvider.js +0 -255
  139. package/dist/components/overlay/tooltip/useTooltipTrigger.js +0 -118
  140. package/dist/components/page/Page.js +0 -11
  141. package/dist/components/page/Page.module.css +0 -89
  142. package/dist/components/page-layout/PageLayout.js +0 -76
  143. package/dist/components/page-layout/PageLayout.module.css +0 -236
  144. package/dist/components/page-layout/components/layout-footer/LayoutFooter.js +0 -27
  145. package/dist/components/page-layout/components/layout-footer/LayoutFooter.module.css +0 -89
  146. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.js +0 -14
  147. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.module.css +0 -84
  148. package/dist/components/pagination/Pagination.js +0 -56
  149. package/dist/components/pagination/Pagination.module.css +0 -25
  150. package/dist/components/panel/Panel.js +0 -7
  151. package/dist/components/panel/Panel.module.css +0 -29
  152. package/dist/components/popover/Popover.js +0 -257
  153. package/dist/components/popover/Popover.module.css +0 -54
  154. package/dist/components/search-box/SearchBox.js +0 -170
  155. package/dist/components/search-box/SearchBox.module.css +0 -21
  156. package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +0 -48
  157. package/dist/components/segmented-progress-bar/SegmentedProgressBar.module.css +0 -167
  158. package/dist/components/sidebar/Sidebar.js +0 -6
  159. package/dist/components/sidebar/components/SidebarItem.js +0 -8
  160. package/dist/components/sidebar/components/SidebarItem.module.css +0 -0
  161. package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.js +0 -63
  162. package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css +0 -29
  163. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +0 -153
  164. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +0 -260
  165. package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.js +0 -18
  166. package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css +0 -106
  167. package/dist/components/sidebar/components/sidebar-items/SidebarItems.js +0 -26
  168. package/dist/components/sidebar/components/sidebar-items/SidebarItems.module.css +0 -20
  169. package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.js +0 -30
  170. package/dist/components/sidebar/providers/SidebarProvider.js +0 -229
  171. package/dist/components/skeleton-loader/SkeletonLoader.js +0 -73
  172. package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.js +0 -13
  173. package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.module.css +0 -51
  174. package/dist/components/split-button/SplitButton.js +0 -10
  175. package/dist/components/split-button/SplitButton.module.css +0 -32
  176. package/dist/components/split-pane/SplitPane.js +0 -107
  177. package/dist/components/split-pane/SplitPane.module.css +0 -111
  178. package/dist/components/split-pane/provider/SplitPaneContext.js +0 -124
  179. package/dist/components/stack/Stack.js +0 -33
  180. package/dist/components/stack/Stack.module.css +0 -61
  181. package/dist/components/state-page/StatePage.js +0 -20
  182. package/dist/components/state-page/StatePage.module.css +0 -9
  183. package/dist/components/state-page/empty.js +0 -2
  184. package/dist/components/state-page/error.js +0 -2
  185. package/dist/components/state-page/notFound.js +0 -2
  186. package/dist/components/sticky-footer-layout/StickyFooterLayout.js +0 -64
  187. package/dist/components/table/Table.js +0 -50
  188. package/dist/components/table/Table.module.css +0 -536
  189. package/dist/components/table/Table.types.js +0 -1
  190. package/dist/components/table/TanstackTable.js +0 -111
  191. package/dist/components/table/components/TableBody.js +0 -10
  192. package/dist/components/table/components/TableHeader.js +0 -7
  193. package/dist/components/table/components/TableHeaderCell.js +0 -24
  194. package/dist/components/table/components/TableLoadingBody.js +0 -26
  195. package/dist/components/table/components/TablePagination.js +0 -1
  196. package/dist/components/table/components/TableRow.js +0 -54
  197. package/dist/components/table/components/TableSelectionCell.js +0 -16
  198. package/dist/components/table/components/column-resizer/ColumnResizer.js +0 -5
  199. package/dist/components/table/components/column-resizer/ColumnResizer.module.css +0 -22
  200. package/dist/components/table/components/empty-state/EmptyState.js +0 -23
  201. package/dist/components/table/components/empty-state/EmptyState.module.css +0 -4
  202. package/dist/components/table/components/table-settings/TableSettings.js +0 -63
  203. package/dist/components/table/hooks/useTableRowInteractions.js +0 -30
  204. package/dist/components/table/table.classes.js +0 -23
  205. package/dist/components/table/table.utils.js +0 -47
  206. package/dist/components/table/tanstackTable.utils.js +0 -175
  207. package/dist/components/tabs/Tabs.js +0 -125
  208. package/dist/components/tabs/Tabs.module.css +0 -233
  209. package/dist/components/theme-button/ThemeButton.js +0 -23
  210. package/dist/components/toast/Toast.js +0 -20
  211. package/dist/components/toast/Toast.module.css +0 -161
  212. package/dist/components/toast/provider/ToastProvider.js +0 -70
  213. package/dist/components/user-display/UserDisplay.js +0 -6
  214. package/dist/components/user-display/UserDisplay.module.css +0 -25
  215. package/dist/constants/severity.js +0 -24
  216. package/dist/constants/severity.types.js +0 -1
  217. package/dist/constants/sizes.js +0 -7
  218. package/dist/hooks/useDeviceSize.js +0 -32
  219. package/dist/hooks/useListNavigation.js +0 -234
  220. package/dist/hooks/usePagination.js +0 -140
  221. package/dist/hooks/useSorting.js +0 -118
  222. package/dist/hooks/useTableData.js +0 -45
  223. package/dist/hooks/useTableSelection.js +0 -164
  224. package/dist/hooks/useTableSettings.js +0 -71
  225. package/dist/hooks/useTheme.js +0 -66
  226. package/dist/hooks/useTimeDuration.js +0 -68
  227. package/dist/hooks/useViewportFill.js +0 -77
  228. package/dist/styles/animation.js +0 -5
  229. package/dist/styles/themes/types.js +0 -1
  230. package/dist/types/a11y-props.types.js +0 -1
  231. package/dist/types/sizes.types.js +0 -1
  232. package/dist/utils/arrays/nested-filtering.js +0 -48
  233. package/dist/utils/date/formatDate.js +0 -51
  234. package/dist/utils/localStorage.utils.js +0 -78
  235. 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
- }