@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,140 +0,0 @@
1
- 'use client';
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- function clamp(n, min, max) {
4
- return Math.max(min, Math.min(max, n));
5
- }
6
- function normalizePaginationState(next) {
7
- return {
8
- skip: Math.max(0, next.skip),
9
- take: Math.max(1, next.take),
10
- };
11
- }
12
- function safeParsePaginationState(raw) {
13
- if (!raw)
14
- return null;
15
- try {
16
- const parsed = JSON.parse(raw);
17
- if (typeof parsed !== 'object' ||
18
- parsed == null ||
19
- typeof parsed.skip !== 'number' ||
20
- typeof parsed.take !== 'number') {
21
- return null;
22
- }
23
- return normalizePaginationState({
24
- skip: parsed.skip,
25
- take: parsed.take,
26
- });
27
- }
28
- catch {
29
- return null;
30
- }
31
- }
32
- export function usePagination({ data = [], skip = 0, take = 10, state, onStateChange, resetOnDataChange = false, storageKey, }) {
33
- const isControlled = state != null;
34
- const [hydrated, setHydrated] = useState(() => !storageKey || isControlled);
35
- const [uncontrolled, setUncontrolled] = useState(() => {
36
- var _a;
37
- const initial = normalizePaginationState({
38
- skip,
39
- take,
40
- });
41
- if (typeof window === 'undefined' || !storageKey || isControlled) {
42
- return initial;
43
- }
44
- return (_a = safeParsePaginationState(window.localStorage.getItem(storageKey))) !== null && _a !== void 0 ? _a : initial;
45
- });
46
- // Hydrate from localStorage when key changes.
47
- useEffect(() => {
48
- if (typeof window === 'undefined')
49
- return;
50
- if (isControlled || !storageKey) {
51
- setHydrated(true);
52
- return;
53
- }
54
- const fallback = normalizePaginationState({ skip, take });
55
- const stored = safeParsePaginationState(window.localStorage.getItem(storageKey));
56
- setUncontrolled(stored !== null && stored !== void 0 ? stored : fallback);
57
- setHydrated(true);
58
- }, [isControlled, storageKey, skip, take]);
59
- // Keep initial props in sync ONLY for uncontrolled if props change.
60
- // Do not overwrite localStorage-hydrated state when storageKey is provided.
61
- const didInitRef = useRef(false);
62
- useEffect(() => {
63
- if (isControlled)
64
- return;
65
- if (storageKey)
66
- return;
67
- if (!didInitRef.current) {
68
- didInitRef.current = true;
69
- return;
70
- }
71
- setUncontrolled(prev => ({
72
- skip: prev.skip,
73
- take: Math.max(1, take),
74
- }));
75
- }, [isControlled, storageKey, take]);
76
- const paginationState = (isControlled ? state : uncontrolled);
77
- const totalCount = data.length;
78
- const safeTake = Math.max(1, paginationState.take);
79
- const maxSkip = Math.max(0, totalCount === 0 ? 0 : Math.floor((totalCount - 1) / safeTake) * safeTake);
80
- const safeSkip = clamp(Math.max(0, paginationState.skip), 0, maxSkip);
81
- const setPagination = useCallback((next) => {
82
- const normalized = normalizePaginationState(next);
83
- if (isControlled) {
84
- onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange(normalized);
85
- return;
86
- }
87
- setUncontrolled(normalized);
88
- }, [isControlled, onStateChange]);
89
- const onPageChange = useCallback((pageEvent) => {
90
- const nextTake = Math.max(1, pageEvent.take);
91
- const nextSkip = Math.max(0, (pageEvent.page - 1) * nextTake);
92
- setPagination({ skip: nextSkip, take: nextTake });
93
- }, [setPagination]);
94
- const resetPage = useCallback(() => {
95
- setPagination({ skip: 0, take: safeTake });
96
- }, [setPagination, safeTake]);
97
- // Optional: reset page when data reference changes (after sort/filter).
98
- useEffect(() => {
99
- if (!resetOnDataChange)
100
- return;
101
- if (!hydrated)
102
- return;
103
- resetPage();
104
- // eslint-disable-next-line react-hooks/exhaustive-deps
105
- }, [resetOnDataChange, data, hydrated]);
106
- const paginatedData = useMemo(() => {
107
- return data.slice(safeSkip, safeSkip + safeTake);
108
- }, [data, safeSkip, safeTake]);
109
- const page = useMemo(() => Math.floor(safeSkip / safeTake) + 1, [safeSkip, safeTake]);
110
- // If uncontrolled and data shrinks such that skip becomes invalid, clamp it once.
111
- useEffect(() => {
112
- if (isControlled)
113
- return;
114
- if (safeSkip !== paginationState.skip) {
115
- setUncontrolled(prev => ({ ...prev, skip: safeSkip }));
116
- }
117
- }, [isControlled, safeSkip, paginationState.skip]);
118
- // Persist uncontrolled state to localStorage when enabled.
119
- useEffect(() => {
120
- if (typeof window === 'undefined')
121
- return;
122
- if (isControlled || !storageKey)
123
- return;
124
- if (!hydrated)
125
- return;
126
- window.localStorage.setItem(storageKey, JSON.stringify({
127
- skip: paginationState.skip,
128
- take: paginationState.take,
129
- }));
130
- }, [hydrated, isControlled, paginationState.skip, paginationState.take, storageKey]);
131
- return {
132
- paginatedData,
133
- paginationState: { skip: safeSkip, take: safeTake },
134
- onPageChange,
135
- setPagination,
136
- resetPage,
137
- page,
138
- totalCount,
139
- };
140
- }
@@ -1,118 +0,0 @@
1
- 'use client';
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- function defaultCompare(a, b, dir, nulls) {
4
- const aNull = a == null;
5
- const bNull = b == null;
6
- if (aNull || bNull) {
7
- if (aNull && bNull)
8
- return 0;
9
- const order = nulls === 'first' ? -1 : 1;
10
- return aNull ? order : -order;
11
- }
12
- // Dates
13
- if (a instanceof Date && b instanceof Date) {
14
- const diff = a.getTime() - b.getTime();
15
- return dir === 'asc' ? diff : -diff;
16
- }
17
- // Numbers
18
- if (typeof a === 'number' && typeof b === 'number') {
19
- const diff = a - b;
20
- return dir === 'asc' ? diff : -diff;
21
- }
22
- // Booleans
23
- if (typeof a === 'boolean' && typeof b === 'boolean') {
24
- const diff = Number(a) - Number(b);
25
- return dir === 'asc' ? diff : -diff;
26
- }
27
- // Strings (locale-aware-ish)
28
- const aStr = String(a);
29
- const bStr = String(b);
30
- const diff = aStr.localeCompare(bStr, undefined, { numeric: true, sensitivity: 'base' });
31
- return dir === 'asc' ? diff : -diff;
32
- }
33
- // Stable sort (decorate-sort-undecorate)
34
- function stableSort(arr, cmp) {
35
- return arr
36
- .map((item, idx) => ({ item, idx }))
37
- .sort((x, y) => {
38
- const c = cmp(x.item, y.item);
39
- return c !== 0 ? c : x.idx - y.idx;
40
- })
41
- .map(x => x.item);
42
- }
43
- export function useSorting({ data = [], sortBy = null, sortDirection = 'asc', state, onStateChange, columnComparators = {}, nulls = 'last', allowUnsort = true, resetOnDataChange = false, }) {
44
- const isControlled = state != null;
45
- const [uncontrolled, setUncontrolled] = useState(() => ({
46
- sortBy,
47
- sortDirection,
48
- }));
49
- const sortState = (isControlled ? state : uncontrolled);
50
- const setSort = useCallback((next) => {
51
- var _a, _b;
52
- const normalized = {
53
- sortBy: (_a = next.sortBy) !== null && _a !== void 0 ? _a : null,
54
- sortDirection: (_b = next.sortDirection) !== null && _b !== void 0 ? _b : null,
55
- };
56
- if (isControlled)
57
- onStateChange === null || onStateChange === void 0 ? void 0 : onStateChange(normalized);
58
- else
59
- setUncontrolled(normalized);
60
- }, [isControlled, onStateChange]);
61
- const clearSort = useCallback(() => setSort({ sortBy: null, sortDirection: null }), [setSort]);
62
- const onSortChange = useCallback((e) => {
63
- var _a, _b;
64
- const nextSortBy = ((_a = e.sortBy) !== null && _a !== void 0 ? _a : null);
65
- setSort(sortState);
66
- const current = sortState;
67
- if (nextSortBy == null) {
68
- return clearSort();
69
- }
70
- // Same column toggling
71
- if (current.sortBy === nextSortBy) {
72
- const nextDir = current.sortDirection === 'asc' ? 'desc' : allowUnsort ? null : 'asc';
73
- return setSort({ sortBy: nextSortBy, sortDirection: nextDir });
74
- }
75
- // New column: default to provided direction or asc
76
- return setSort({
77
- sortBy: nextSortBy,
78
- sortDirection: (_b = e.sortDirection) !== null && _b !== void 0 ? _b : 'asc',
79
- });
80
- }, [allowUnsort, clearSort, setSort, sortState]);
81
- // Optional reset on data ref change
82
- const didInitRef = useRef(false);
83
- useEffect(() => {
84
- if (!resetOnDataChange)
85
- return;
86
- if (!didInitRef.current) {
87
- didInitRef.current = true;
88
- return;
89
- }
90
- clearSort();
91
- // eslint-disable-next-line react-hooks/exhaustive-deps
92
- }, [resetOnDataChange, data]);
93
- const sortedData = useMemo(() => {
94
- const { sortBy: sb, sortDirection: dir } = sortState;
95
- if (!sb || !dir)
96
- return data;
97
- const custom = columnComparators[sb];
98
- const cmp = (a, b) => {
99
- if (custom)
100
- return custom(a, b, dir);
101
- const av = a[sb];
102
- const bv = b[sb];
103
- return defaultCompare(av, bv, dir, nulls);
104
- };
105
- // Don’t mutate input
106
- return stableSort(data, cmp);
107
- }, [data, sortState, columnComparators, nulls]);
108
- // Helper: support functional updates in uncontrolled mode (optional nicety)
109
- const setSortRef = useRef(setSort);
110
- setSortRef.current = setSort;
111
- return {
112
- sortedData,
113
- sortState,
114
- onSortChange,
115
- setSort,
116
- clearSort,
117
- };
118
- }
@@ -1,45 +0,0 @@
1
- 'use client';
2
- import { useEffect, useMemo } from 'react';
3
- import { usePagination } from './usePagination';
4
- import { useSorting, } from './useSorting';
5
- export function useTableData({ data = [], pagination, sorting, resetPageOnSortChange = true, }) {
6
- var _a, _b, _c, _d, _e, _f;
7
- const s = useSorting({
8
- data,
9
- sortBy: (_a = sorting === null || sorting === void 0 ? void 0 : sorting.sortBy) !== null && _a !== void 0 ? _a : null,
10
- sortDirection: (_b = sorting === null || sorting === void 0 ? void 0 : sorting.direction) !== null && _b !== void 0 ? _b : null,
11
- state: sorting === null || sorting === void 0 ? void 0 : sorting.state,
12
- onStateChange: sorting === null || sorting === void 0 ? void 0 : sorting.onStateChange,
13
- columnComparators: sorting === null || sorting === void 0 ? void 0 : sorting.columnComparators,
14
- nulls: (_c = sorting === null || sorting === void 0 ? void 0 : sorting.nulls) !== null && _c !== void 0 ? _c : 'last',
15
- allowUnsort: (_d = sorting === null || sorting === void 0 ? void 0 : sorting.allowUnsort) !== null && _d !== void 0 ? _d : true,
16
- });
17
- const p = usePagination({
18
- data: s.sortedData,
19
- skip: (_e = pagination === null || pagination === void 0 ? void 0 : pagination.skip) !== null && _e !== void 0 ? _e : 0,
20
- take: (_f = pagination === null || pagination === void 0 ? void 0 : pagination.take) !== null && _f !== void 0 ? _f : 10,
21
- state: pagination === null || pagination === void 0 ? void 0 : pagination.state,
22
- onStateChange: pagination === null || pagination === void 0 ? void 0 : pagination.onStateChange,
23
- });
24
- useEffect(() => {
25
- if (!resetPageOnSortChange)
26
- return;
27
- p.resetPage();
28
- // eslint-disable-next-line react-hooks/exhaustive-deps
29
- }, [resetPageOnSortChange, s.sortState.sortBy, s.sortState.sortDirection]);
30
- const rows = useMemo(() => p.paginatedData, [p.paginatedData]);
31
- return {
32
- rows,
33
- totalCount: s.sortedData.length,
34
- pagination: {
35
- state: p.paginationState,
36
- onPageChange: p.onPageChange,
37
- resetPage: p.resetPage,
38
- },
39
- sorting: {
40
- state: s.sortState,
41
- onSortChange: s.onSortChange,
42
- clearSort: s.clearSort,
43
- },
44
- };
45
- }
@@ -1,164 +0,0 @@
1
- 'use client';
2
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
- const EMPTY_IDS = new Set();
4
- function safeParseIds(raw) {
5
- if (!raw)
6
- return null;
7
- try {
8
- const parsed = JSON.parse(raw);
9
- if (!Array.isArray(parsed))
10
- return null;
11
- return parsed.filter((v) => typeof v === 'string' || typeof v === 'number');
12
- }
13
- catch {
14
- return null;
15
- }
16
- }
17
- function serializeIds(ids) {
18
- return JSON.stringify(Array.from(ids));
19
- }
20
- function areSetsEqual(a, b) {
21
- if (a.size !== b.size)
22
- return false;
23
- for (const value of a) {
24
- if (!b.has(value))
25
- return false;
26
- }
27
- return true;
28
- }
29
- export function useTableSelection({ storageKey, items, getId, initialSelectedIds, onSelectionChange, selectionMode = 'single', pruneToItems = false, storage = 'session', }) {
30
- const resolvedInitialSelectedIds = initialSelectedIds !== null && initialSelectedIds !== void 0 ? initialSelectedIds : EMPTY_IDS;
31
- const [selectedIds, setSelectedIds] = useState(resolvedInitialSelectedIds);
32
- const [hydrated, setHydrated] = useState(false);
33
- const lastWrittenRef = useRef(null);
34
- const itemsById = useMemo(() => {
35
- const map = new Map();
36
- for (const item of items) {
37
- map.set(getId(item), item);
38
- }
39
- return map;
40
- }, [items, getId]);
41
- useEffect(() => {
42
- if (typeof window === 'undefined')
43
- return;
44
- const storageApi = storage === 'local' ? window.localStorage : window.sessionStorage;
45
- if (!storageKey) {
46
- setSelectedIds(prev => areSetsEqual(prev, resolvedInitialSelectedIds) ? prev : new Set(resolvedInitialSelectedIds));
47
- setHydrated(true);
48
- lastWrittenRef.current = null;
49
- return;
50
- }
51
- const parsed = safeParseIds(storageApi.getItem(storageKey));
52
- const next = new Set(parsed !== null && parsed !== void 0 ? parsed : Array.from(resolvedInitialSelectedIds));
53
- setSelectedIds(prev => (areSetsEqual(prev, next) ? prev : next));
54
- lastWrittenRef.current = serializeIds(next);
55
- setHydrated(true);
56
- }, [storage, storageKey, resolvedInitialSelectedIds]);
57
- useEffect(() => {
58
- if (!pruneToItems)
59
- return;
60
- const visibleIds = new Set(Array.from(itemsById.keys()));
61
- setSelectedIds(prev => {
62
- if (prev.size === 0)
63
- return prev;
64
- if (visibleIds.size === 0)
65
- return prev;
66
- const next = new Set();
67
- for (const id of prev) {
68
- if (visibleIds.has(id))
69
- next.add(id);
70
- }
71
- return areSetsEqual(prev, next) ? prev : next;
72
- });
73
- }, [pruneToItems, itemsById]);
74
- const selectedItemMap = useMemo(() => {
75
- const map = new Map();
76
- for (const id of selectedIds) {
77
- const item = itemsById.get(id);
78
- if (item !== undefined)
79
- map.set(id, item);
80
- }
81
- return map;
82
- }, [selectedIds, itemsById]);
83
- const selectedItems = useMemo(() => Array.from(selectedItemMap.values()), [selectedItemMap]);
84
- const allSelected = useMemo(() => {
85
- if (items.length === 0)
86
- return false;
87
- return items.every(item => selectedIds.has(getId(item)));
88
- }, [items, selectedIds, getId]);
89
- const anySelected = useMemo(() => selectedIds.size > 0, [selectedIds]);
90
- useEffect(() => {
91
- if (!hydrated)
92
- return;
93
- if (typeof window === 'undefined')
94
- return;
95
- if (storageKey) {
96
- const storageApi = storage === 'local' ? window.localStorage : window.sessionStorage;
97
- const nextStr = serializeIds(selectedIds);
98
- if (lastWrittenRef.current !== nextStr) {
99
- storageApi.setItem(storageKey, nextStr);
100
- lastWrittenRef.current = nextStr;
101
- }
102
- }
103
- onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange({ selectedIds, selectedItems });
104
- }, [hydrated, onSelectionChange, selectedIds, selectedItems, storage, storageKey]);
105
- const toggleId = useCallback((id, selected) => {
106
- setSelectedIds(prev => {
107
- const next = new Set(prev);
108
- const isSelected = next.has(id);
109
- const shouldSelect = selected === undefined ? !isSelected : selected;
110
- if (selectionMode === 'single') {
111
- next.clear();
112
- if (shouldSelect)
113
- next.add(id);
114
- return areSetsEqual(prev, next) ? prev : next;
115
- }
116
- if (shouldSelect)
117
- next.add(id);
118
- else
119
- next.delete(id);
120
- return areSetsEqual(prev, next) ? prev : next;
121
- });
122
- }, [selectionMode]);
123
- const toggleItem = useCallback((item) => {
124
- toggleId(getId(item));
125
- }, [toggleId, getId]);
126
- const selectOnly = useCallback((id) => {
127
- setSelectedIds(prev => {
128
- const next = new Set([id]);
129
- return areSetsEqual(prev, next) ? prev : next;
130
- });
131
- }, []);
132
- const clearSelection = useCallback(() => {
133
- setSelectedIds(prev => (prev.size === 0 ? prev : new Set()));
134
- }, []);
135
- const toggleAll = useCallback((selected) => {
136
- if (!selected) {
137
- clearSelection();
138
- return;
139
- }
140
- if (selectionMode === 'single') {
141
- const first = items[0];
142
- const next = first ? new Set([getId(first)]) : new Set();
143
- setSelectedIds(prev => (areSetsEqual(prev, next) ? prev : next));
144
- return;
145
- }
146
- const next = new Set();
147
- for (const item of items) {
148
- next.add(getId(item));
149
- }
150
- setSelectedIds(prev => (areSetsEqual(prev, next) ? prev : next));
151
- }, [clearSelection, getId, items, selectionMode]);
152
- return {
153
- selectedIds,
154
- selectedItems,
155
- selectedItemMap,
156
- toggleItem,
157
- toggleId,
158
- selectOnly,
159
- clearSelection,
160
- allSelected,
161
- anySelected,
162
- toggleAll,
163
- };
164
- }
@@ -1,71 +0,0 @@
1
- 'use client';
2
- import { useCallback, useEffect, useMemo, useState } from 'react';
3
- import { readLocalStorage, writeLocalStorage } from '../utils/localStorage.utils';
4
- function getDefaultVisibleIds(tableColumns) {
5
- var _a;
6
- return ((_a = tableColumns === null || tableColumns === void 0 ? void 0 : tableColumns.filter(c => { var _a; return !((_a = c.meta) === null || _a === void 0 ? void 0 : _a.hidden); }).map(c => c.id).filter(Boolean)) !== null && _a !== void 0 ? _a : []);
7
- }
8
- function mergeDefaults(stored, defaults) {
9
- const viewMode = (stored === null || stored === void 0 ? void 0 : stored.viewMode) === 'compact' || (stored === null || stored === void 0 ? void 0 : stored.viewMode) === 'wrapped'
10
- ? stored.viewMode
11
- : defaults.viewMode;
12
- const visibleColumnIds = Array.isArray(stored === null || stored === void 0 ? void 0 : stored.visibleColumnIds) && stored.visibleColumnIds.length > 0
13
- ? stored.visibleColumnIds
14
- : defaults.visibleColumnIds;
15
- return { viewMode, visibleColumnIds };
16
- }
17
- export const localStorageTableSettingsStorage = {
18
- get: key => {
19
- const v = readLocalStorage(key);
20
- return v && typeof v === 'object' ? v : undefined;
21
- },
22
- set: (key, next) => {
23
- writeLocalStorage(key, next);
24
- },
25
- };
26
- export function useTableSettings({ storageKey, tableColumns, defaultViewMode = 'compact', defaultVisibleColumnIds, storage = localStorageTableSettingsStorage, }) {
27
- const defaults = useMemo(() => {
28
- return {
29
- viewMode: defaultViewMode,
30
- visibleColumnIds: defaultVisibleColumnIds !== null && defaultVisibleColumnIds !== void 0 ? defaultVisibleColumnIds : getDefaultVisibleIds(tableColumns),
31
- };
32
- }, [defaultViewMode, defaultVisibleColumnIds, tableColumns]);
33
- const [state, setState] = useState(defaults);
34
- useEffect(() => {
35
- const stored = storage.get(storageKey);
36
- const next = mergeDefaults(stored, defaults);
37
- setState(next);
38
- }, [storageKey, storage, defaults]);
39
- const persist = useCallback((next) => storage.set(storageKey, next), [storage, storageKey]);
40
- const setViewMode = useCallback((mode) => {
41
- setState(prev => {
42
- if (prev.viewMode === mode)
43
- return prev;
44
- const next = { ...prev, viewMode: mode };
45
- persist(next);
46
- return next;
47
- });
48
- }, [persist]);
49
- const toggleViewMode = useCallback(() => {
50
- setState(prev => {
51
- const nextMode = prev.viewMode === 'wrapped' ? 'compact' : 'wrapped';
52
- const next = { ...prev, viewMode: nextMode };
53
- persist(next);
54
- return next;
55
- });
56
- }, [persist]);
57
- const setVisibleColumnIds = useCallback((ids) => {
58
- setState(prev => {
59
- const next = { ...prev, visibleColumnIds: ids };
60
- persist(next);
61
- return next;
62
- });
63
- }, [persist]);
64
- return {
65
- viewMode: state.viewMode,
66
- toggleViewMode,
67
- setViewMode,
68
- visibleColumnIds: state.visibleColumnIds,
69
- setVisibleColumnIds,
70
- };
71
- }
@@ -1,66 +0,0 @@
1
- 'use client';
2
- import { useCallback, useEffect, useState } from 'react';
3
- const THEME_VARIANTS = ['light', 'dark', 'system'];
4
- const STORAGE_KEY = 'dbc_theme';
5
- function isThemeVariant(x) {
6
- return !!x && THEME_VARIANTS.includes(x);
7
- }
8
- function getCookie(name) {
9
- const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
10
- return match ? decodeURIComponent(match[1]) : null;
11
- }
12
- function persistTheme(id) {
13
- try {
14
- localStorage.setItem(STORAGE_KEY, id);
15
- }
16
- catch {
17
- console.error('Failed to access localStorage');
18
- }
19
- try {
20
- document.cookie = `${STORAGE_KEY}=${encodeURIComponent(id)}; Path=/; Max-Age=${60 * 60 * 24 * 365}`;
21
- }
22
- catch {
23
- console.error('Failed to set theme cookie');
24
- }
25
- }
26
- function getTheme() {
27
- return document.documentElement.dataset.theme;
28
- }
29
- function applyTheme(id) {
30
- document.documentElement.dataset.theme = id;
31
- }
32
- export function useTheme(initialTheme = 'system') {
33
- const [theme, setTheme] = useState(null);
34
- useEffect(() => {
35
- const themeFromDataAttributes = getTheme();
36
- let resolved = isThemeVariant(themeFromDataAttributes)
37
- ? themeFromDataAttributes
38
- : initialTheme;
39
- // Prefer cookie (SSR + client consistency)
40
- const fromCookie = getCookie(STORAGE_KEY);
41
- if (isThemeVariant(fromCookie)) {
42
- resolved = fromCookie;
43
- }
44
- else {
45
- // fallback to localStorage
46
- try {
47
- const fromStorage = localStorage.getItem(STORAGE_KEY);
48
- if (isThemeVariant(fromStorage))
49
- resolved = fromStorage;
50
- }
51
- catch {
52
- console.error('Failed to access localStorage');
53
- }
54
- }
55
- applyTheme(resolved);
56
- setTheme(resolved);
57
- persistTheme(resolved);
58
- }, [initialTheme]);
59
- const switchTheme = useCallback((id) => {
60
- applyTheme(id);
61
- setTheme(id);
62
- persistTheme(id);
63
- return id;
64
- }, []);
65
- return { theme, switchTheme };
66
- }
@@ -1,68 +0,0 @@
1
- 'use client';
2
- import { useEffect, useMemo, useState } from 'react';
3
- function defaultDuration(ms) {
4
- if (!Number.isFinite(ms) || ms < 0)
5
- return '—';
6
- const sec = Math.floor(ms / 1000) % 60;
7
- const min = Math.floor(ms / (1000 * 60)) % 60;
8
- const hr = Math.floor(ms / (1000 * 60 * 60));
9
- if (hr > 0) {
10
- return `${hr}t ${min}m ${sec}s`;
11
- }
12
- if (min > 0) {
13
- return `${min}m ${sec}s`;
14
- }
15
- return `${sec}s`;
16
- }
17
- export function useTimeDuration({ start, end, dateFormat = {
18
- year: '2-digit',
19
- month: '2-digit',
20
- day: '2-digit',
21
- hour: '2-digit',
22
- minute: '2-digit',
23
- second: '2-digit',
24
- }, fallback = '—', liveUpdate = false, formatDuration = defaultDuration, }) {
25
- const [hydrated, setHydrated] = useState(false);
26
- const [tick, setTick] = useState(0);
27
- useEffect(() => setHydrated(true), []);
28
- useEffect(() => {
29
- if (!liveUpdate)
30
- return;
31
- if (end && end.getTime() <= Date.now())
32
- return;
33
- const timer = setInterval(() => {
34
- if (end && end.getTime() <= Date.now()) {
35
- clearInterval(timer);
36
- }
37
- setTick(tick => tick + 1);
38
- }, 1000);
39
- return () => clearInterval(timer);
40
- }, [liveUpdate, end]);
41
- const started = useMemo(() => {
42
- if (!start)
43
- return fallback;
44
- if (!hydrated)
45
- return fallback;
46
- return new Intl.DateTimeFormat('da-DK', dateFormat).format(start);
47
- }, [start, hydrated, fallback, dateFormat]);
48
- const ended = useMemo(() => {
49
- if (!end)
50
- return fallback;
51
- if (!hydrated)
52
- return fallback;
53
- return new Intl.DateTimeFormat('da-DK', dateFormat).format(end);
54
- }, [end, hydrated, fallback, dateFormat]);
55
- const duration = useMemo(() => {
56
- if (!start || !hydrated)
57
- return fallback;
58
- const now = Date.now();
59
- if (!end) {
60
- return formatDuration(now - start.getTime());
61
- }
62
- if (end.getTime() > now) {
63
- return formatDuration(end.getTime() - now);
64
- }
65
- return formatDuration(end.getTime() - start.getTime());
66
- }, [start, end, fallback, hydrated, formatDuration, tick]);
67
- return { started, ended, isFinished: !!start && !!end, duration, hydrated };
68
- }