@dbcdk/react-components 0.0.95 → 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 (226) hide show
  1. package/dist/components/alert/Alert.d.ts +13 -0
  2. package/dist/components/forms/input/Input.d.ts +2 -1
  3. package/dist/components/forms/input-container/InputContainer.d.ts +3 -1
  4. package/dist/components/forms/text-area/Textarea.d.ts +1 -1
  5. package/dist/components/stack/Stack.d.ts +11 -3
  6. package/dist/components/table/Table.d.ts +1 -1
  7. package/dist/components/table/Table.types.d.ts +3 -0
  8. package/dist/components/table/components/TableHeader.d.ts +2 -1
  9. package/dist/index.cjs +12750 -0
  10. package/dist/index.css +7149 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +12641 -78
  13. package/dist/tanstack.cjs +2674 -0
  14. package/dist/tanstack.css +1267 -0
  15. package/dist/tanstack.js +2650 -3
  16. package/dist/themes/dbc.css +3 -0
  17. package/dist/themes/forfatterweb.css +2 -0
  18. package/package.json +11 -10
  19. package/dist/assets/logo.js +0 -2
  20. package/dist/components/__stories__/_data/table.d.ts +0 -15
  21. package/dist/components/__stories__/_data/table.js +0 -55
  22. package/dist/components/__stories__/_data/tabs.d.ts +0 -9
  23. package/dist/components/__stories__/_data/tabs.js +0 -31
  24. package/dist/components/__stories__/story-components/Colors.d.ts +0 -11
  25. package/dist/components/__stories__/story-components/Colors.js +0 -96
  26. package/dist/components/__stories__/story-components/Colors.module.css +0 -27
  27. package/dist/components/__stories__/story-components/ComponentSizes.d.ts +0 -2
  28. package/dist/components/__stories__/story-components/ComponentSizes.js +0 -26
  29. package/dist/components/__stories__/story-components/Elevation.d.ts +0 -2
  30. package/dist/components/__stories__/story-components/Elevation.js +0 -49
  31. package/dist/components/__stories__/story-components/Flex.d.ts +0 -2
  32. package/dist/components/__stories__/story-components/Flex.js +0 -177
  33. package/dist/components/__stories__/story-components/Flex.module.css +0 -317
  34. package/dist/components/__stories__/story-components/Spacing.d.ts +0 -6
  35. package/dist/components/__stories__/story-components/Spacing.js +0 -76
  36. package/dist/components/__stories__/story-components/Spacing.module.css +0 -154
  37. package/dist/components/accordion/Accordion.js +0 -70
  38. package/dist/components/accordion/Accordion.module.css +0 -28
  39. package/dist/components/accordion/components/AccordionRow.js +0 -53
  40. package/dist/components/accordion/components/AccordionRow.module.css +0 -90
  41. package/dist/components/app-header/AppHeader.js +0 -5
  42. package/dist/components/app-header/AppHeader.module.css +0 -74
  43. package/dist/components/attribute-chip/AttributeChip.js +0 -5
  44. package/dist/components/attribute-chip/AttributeChip.module.css +0 -65
  45. package/dist/components/avatar/Avatar.js +0 -48
  46. package/dist/components/avatar/Avatar.module.css +0 -91
  47. package/dist/components/breadcrumbs/Breadcrumbs.js +0 -6
  48. package/dist/components/breadcrumbs/Breadcrumbs.module.css +0 -80
  49. package/dist/components/button/Button.js +0 -81
  50. package/dist/components/button/Button.module.css +0 -249
  51. package/dist/components/button-select/ButtonSelect.js +0 -7
  52. package/dist/components/button-select/ButtonSelect.module.css +0 -40
  53. package/dist/components/card/Card.js +0 -71
  54. package/dist/components/card/Card.module.css +0 -160
  55. package/dist/components/card/components/CardMeta.js +0 -26
  56. package/dist/components/card/components/CardMeta.module.css +0 -55
  57. package/dist/components/card-container/CardContainer.js +0 -6
  58. package/dist/components/card-container/CardContainer.module.css +0 -61
  59. package/dist/components/chip/Chip.js +0 -31
  60. package/dist/components/chip/Chip.module.css +0 -236
  61. package/dist/components/circle/Circle.js +0 -5
  62. package/dist/components/circle/Circle.module.css +0 -128
  63. package/dist/components/clear-button/ClearButton.js +0 -13
  64. package/dist/components/clear-button/ClearButton.module.css +0 -26
  65. package/dist/components/code-block/CodeBlock.js +0 -58
  66. package/dist/components/code-block/CodeBlock.module.css +0 -124
  67. package/dist/components/copy-button/CopyButton.js +0 -78
  68. package/dist/components/copy-button/CopyButton.module.css +0 -22
  69. package/dist/components/datetime-picker/DateTimePicker.js +0 -403
  70. package/dist/components/datetime-picker/DateTimePicker.module.css +0 -155
  71. package/dist/components/datetime-picker/dateTimeHelpers.js +0 -248
  72. package/dist/components/divider/Divider.js +0 -12
  73. package/dist/components/filter-field/FilterField.js +0 -191
  74. package/dist/components/filter-field/FilterField.module.css +0 -379
  75. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.js +0 -52
  76. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.module.css +0 -59
  77. package/dist/components/forms/checkbox/Checkbox.js +0 -26
  78. package/dist/components/forms/checkbox/Checkbox.module.css +0 -99
  79. package/dist/components/forms/checkbox-group/CheckboxGroup.js +0 -75
  80. package/dist/components/forms/checkbox-group/CheckboxGroup.module.css +0 -115
  81. package/dist/components/forms/form-select/FormSelect.js +0 -86
  82. package/dist/components/forms/form-select/FormSelect.module.css +0 -236
  83. package/dist/components/forms/input/Input.js +0 -77
  84. package/dist/components/forms/input/Input.module.css +0 -468
  85. package/dist/components/forms/input-container/InputContainer.js +0 -15
  86. package/dist/components/forms/input-container/InputContainer.module.css +0 -56
  87. package/dist/components/forms/multi-select/MultiSelect.js +0 -122
  88. package/dist/components/forms/radio-buttons/RadioButton.js +0 -26
  89. package/dist/components/forms/radio-buttons/RadioButtonGroup.js +0 -19
  90. package/dist/components/forms/radio-buttons/RadioButtons.module.css +0 -118
  91. package/dist/components/forms/select/Select.js +0 -185
  92. package/dist/components/forms/select/Select.module.css +0 -32
  93. package/dist/components/forms/text-area/Textarea.js +0 -47
  94. package/dist/components/forms/text-area/Textarea.module.css +0 -70
  95. package/dist/components/forms/typeahead/Typeahead.js +0 -668
  96. package/dist/components/forms/typeahead/Typeahead.module.css +0 -38
  97. package/dist/components/grid/Grid.js +0 -23
  98. package/dist/components/grid/Grid.module.css +0 -35
  99. package/dist/components/headline/CollapsibleHeadline.js +0 -29
  100. package/dist/components/headline/Headline.js +0 -26
  101. package/dist/components/headline/Headline.module.css +0 -165
  102. package/dist/components/hyperlink/Hyperlink.js +0 -40
  103. package/dist/components/hyperlink/Hyperlink.module.css +0 -107
  104. package/dist/components/icon/Icon.js +0 -14
  105. package/dist/components/icon/Icon.module.css +0 -36
  106. package/dist/components/interval-select/IntervalSelect.js +0 -99
  107. package/dist/components/json-viewer/HighlightedText.js +0 -6
  108. package/dist/components/json-viewer/JsonNode.js +0 -30
  109. package/dist/components/json-viewer/JsonViewer.js +0 -68
  110. package/dist/components/json-viewer/JsonViewer.module.css +0 -346
  111. package/dist/components/json-viewer/types.js +0 -1
  112. package/dist/components/json-viewer/useClipboardStatus.js +0 -11
  113. package/dist/components/json-viewer/utils.js +0 -125
  114. package/dist/components/menu/Menu.js +0 -165
  115. package/dist/components/menu/Menu.module.css +0 -211
  116. package/dist/components/meta-bar/MetaBar.js +0 -9
  117. package/dist/components/meta-bar/MetaBar.module.css +0 -27
  118. package/dist/components/nav-bar/NavBar.js +0 -29
  119. package/dist/components/nav-bar/NavBar.module.css +0 -200
  120. package/dist/components/overlay/fade-overlay/FadeOverlay.js +0 -8
  121. package/dist/components/overlay/fade-overlay/FadeOverlay.module.css +0 -54
  122. package/dist/components/overlay/modal/Modal.js +0 -115
  123. package/dist/components/overlay/modal/Modal.module.css +0 -109
  124. package/dist/components/overlay/modal/provider/ModalProvider.js +0 -73
  125. package/dist/components/overlay/side-panel/SidePanel.js +0 -83
  126. package/dist/components/overlay/side-panel/SidePanel.module.css +0 -177
  127. package/dist/components/overlay/side-panel/useSidePanel.js +0 -11
  128. package/dist/components/overlay/tooltip/Tooltip.js +0 -17
  129. package/dist/components/overlay/tooltip/Tooltip.module.css +0 -104
  130. package/dist/components/overlay/tooltip/TooltipProvider.js +0 -255
  131. package/dist/components/overlay/tooltip/useTooltipTrigger.js +0 -118
  132. package/dist/components/page/Page.js +0 -11
  133. package/dist/components/page/Page.module.css +0 -76
  134. package/dist/components/page-layout/PageLayout.js +0 -76
  135. package/dist/components/page-layout/PageLayout.module.css +0 -236
  136. package/dist/components/page-layout/components/layout-footer/LayoutFooter.js +0 -27
  137. package/dist/components/page-layout/components/layout-footer/LayoutFooter.module.css +0 -89
  138. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.js +0 -14
  139. package/dist/components/page-layout/components/page-layout-hero/PageLayoutHero.module.css +0 -84
  140. package/dist/components/pagination/Pagination.js +0 -56
  141. package/dist/components/pagination/Pagination.module.css +0 -25
  142. package/dist/components/panel/Panel.js +0 -7
  143. package/dist/components/panel/Panel.module.css +0 -29
  144. package/dist/components/popover/Popover.js +0 -257
  145. package/dist/components/popover/Popover.module.css +0 -54
  146. package/dist/components/search-box/SearchBox.js +0 -170
  147. package/dist/components/search-box/SearchBox.module.css +0 -21
  148. package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +0 -48
  149. package/dist/components/segmented-progress-bar/SegmentedProgressBar.module.css +0 -167
  150. package/dist/components/sidebar/Sidebar.js +0 -6
  151. package/dist/components/sidebar/components/SidebarItem.js +0 -8
  152. package/dist/components/sidebar/components/SidebarItem.module.css +0 -0
  153. package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.js +0 -63
  154. package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css +0 -29
  155. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +0 -153
  156. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +0 -260
  157. package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.js +0 -18
  158. package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css +0 -106
  159. package/dist/components/sidebar/components/sidebar-items/SidebarItems.js +0 -26
  160. package/dist/components/sidebar/components/sidebar-items/SidebarItems.module.css +0 -20
  161. package/dist/components/sidebar/components/sidenav-filteirng/SidenavFiltering.js +0 -30
  162. package/dist/components/sidebar/providers/SidebarProvider.js +0 -229
  163. package/dist/components/skeleton-loader/SkeletonLoader.js +0 -73
  164. package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.js +0 -13
  165. package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.module.css +0 -51
  166. package/dist/components/split-button/SplitButton.js +0 -10
  167. package/dist/components/split-button/SplitButton.module.css +0 -32
  168. package/dist/components/split-pane/SplitPane.js +0 -107
  169. package/dist/components/split-pane/SplitPane.module.css +0 -111
  170. package/dist/components/split-pane/provider/SplitPaneContext.js +0 -124
  171. package/dist/components/stack/Stack.js +0 -19
  172. package/dist/components/state-page/StatePage.js +0 -20
  173. package/dist/components/state-page/StatePage.module.css +0 -9
  174. package/dist/components/state-page/empty.js +0 -2
  175. package/dist/components/state-page/error.js +0 -2
  176. package/dist/components/state-page/notFound.js +0 -2
  177. package/dist/components/sticky-footer-layout/StickyFooterLayout.js +0 -64
  178. package/dist/components/table/Table.js +0 -50
  179. package/dist/components/table/Table.module.css +0 -536
  180. package/dist/components/table/Table.types.js +0 -1
  181. package/dist/components/table/TanstackTable.js +0 -111
  182. package/dist/components/table/components/TableBody.js +0 -10
  183. package/dist/components/table/components/TableHeader.js +0 -7
  184. package/dist/components/table/components/TableHeaderCell.js +0 -24
  185. package/dist/components/table/components/TableLoadingBody.js +0 -26
  186. package/dist/components/table/components/TablePagination.js +0 -1
  187. package/dist/components/table/components/TableRow.js +0 -54
  188. package/dist/components/table/components/TableSelectionCell.js +0 -16
  189. package/dist/components/table/components/column-resizer/ColumnResizer.js +0 -5
  190. package/dist/components/table/components/column-resizer/ColumnResizer.module.css +0 -22
  191. package/dist/components/table/components/empty-state/EmptyState.js +0 -23
  192. package/dist/components/table/components/empty-state/EmptyState.module.css +0 -4
  193. package/dist/components/table/components/table-settings/TableSettings.js +0 -63
  194. package/dist/components/table/hooks/useTableRowInteractions.js +0 -30
  195. package/dist/components/table/table.classes.js +0 -23
  196. package/dist/components/table/table.utils.js +0 -47
  197. package/dist/components/table/tanstackTable.utils.js +0 -175
  198. package/dist/components/tabs/Tabs.js +0 -125
  199. package/dist/components/tabs/Tabs.module.css +0 -204
  200. package/dist/components/theme-button/ThemeButton.js +0 -23
  201. package/dist/components/toast/Toast.js +0 -20
  202. package/dist/components/toast/Toast.module.css +0 -161
  203. package/dist/components/toast/provider/ToastProvider.js +0 -70
  204. package/dist/components/user-display/UserDisplay.js +0 -6
  205. package/dist/components/user-display/UserDisplay.module.css +0 -25
  206. package/dist/constants/severity.js +0 -24
  207. package/dist/constants/severity.types.js +0 -1
  208. package/dist/constants/sizes.js +0 -7
  209. package/dist/hooks/useDeviceSize.js +0 -32
  210. package/dist/hooks/useListNavigation.js +0 -234
  211. package/dist/hooks/usePagination.js +0 -140
  212. package/dist/hooks/useSorting.js +0 -118
  213. package/dist/hooks/useTableData.js +0 -45
  214. package/dist/hooks/useTableSelection.js +0 -164
  215. package/dist/hooks/useTableSettings.js +0 -71
  216. package/dist/hooks/useTheme.js +0 -66
  217. package/dist/hooks/useTimeDuration.js +0 -68
  218. package/dist/hooks/useViewportFill.js +0 -77
  219. package/dist/styles/animation.js +0 -5
  220. package/dist/styles/themes/types.js +0 -1
  221. package/dist/types/a11y-props.types.js +0 -1
  222. package/dist/types/sizes.types.js +0 -1
  223. package/dist/utils/arrays/nested-filtering.js +0 -48
  224. package/dist/utils/date/formatDate.js +0 -51
  225. package/dist/utils/localStorage.utils.js +0 -78
  226. package/dist/utils/text/get-highlighted-segments.js +0 -46
@@ -1,32 +0,0 @@
1
- 'use client';
2
- import { useEffect, useState } from 'react';
3
- // Aligned with --bp-sm (640px), --bp-md (768px), --bp-lg (1024px) from base.css
4
- const BREAKPOINTS = {
5
- tablet: 640,
6
- desktop: 1024,
7
- };
8
- function getDeviceSize(width) {
9
- if (width < BREAKPOINTS.tablet)
10
- return 'mobile';
11
- if (width < BREAKPOINTS.desktop)
12
- return 'tablet';
13
- return 'desktop';
14
- }
15
- export function useDeviceSize() {
16
- const [deviceSize, setDeviceSize] = useState(() => {
17
- if (typeof window === 'undefined')
18
- return 'desktop';
19
- return getDeviceSize(window.innerWidth);
20
- });
21
- useEffect(() => {
22
- const mediaQueries = [
23
- window.matchMedia(`(max-width: ${BREAKPOINTS.tablet - 1}px)`),
24
- window.matchMedia(`(min-width: ${BREAKPOINTS.tablet}px) and (max-width: ${BREAKPOINTS.desktop - 1}px)`),
25
- window.matchMedia(`(min-width: ${BREAKPOINTS.desktop}px)`),
26
- ];
27
- const update = () => setDeviceSize(getDeviceSize(window.innerWidth));
28
- mediaQueries.forEach(mq => mq.addEventListener('change', update));
29
- return () => mediaQueries.forEach(mq => mq.removeEventListener('change', update));
30
- }, []);
31
- return deviceSize;
32
- }
@@ -1,234 +0,0 @@
1
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
- export function useListNavigation({ options, getLabel, isOpen, onOpenChange, searchInputRef, searchable = false, focusActiveOptionOnOpen = true, typeaheadTimeoutMs = 500, getInitialActiveIndex, }) {
3
- const optionRefs = useRef([]);
4
- const typeaheadRef = useRef('');
5
- const typeaheadTimeoutRef = useRef(null);
6
- const normalizedLabels = useMemo(() => options.map(option => getLabel(option).trim().toLocaleLowerCase()), [options, getLabel]);
7
- const getDefaultInitialIndex = useCallback((items) => {
8
- if (items.length === 0)
9
- return -1;
10
- if (getInitialActiveIndex) {
11
- const nextIndex = getInitialActiveIndex(items);
12
- if (nextIndex < 0)
13
- return -1;
14
- return Math.min(nextIndex, items.length - 1);
15
- }
16
- return searchable ? -1 : 0;
17
- }, [getInitialActiveIndex, searchable]);
18
- const [activeIndex, setActiveIndex] = useState(() => getDefaultInitialIndex(options));
19
- const clearTypeahead = useCallback(() => {
20
- typeaheadRef.current = '';
21
- if (typeaheadTimeoutRef.current) {
22
- clearTimeout(typeaheadTimeoutRef.current);
23
- typeaheadTimeoutRef.current = null;
24
- }
25
- }, []);
26
- const focusActiveOption = useCallback(() => {
27
- var _a;
28
- if (activeIndex < 0 || options.length === 0)
29
- return;
30
- (_a = optionRefs.current[activeIndex]) === null || _a === void 0 ? void 0 : _a.focus();
31
- }, [activeIndex, options.length]);
32
- const resetActiveIndex = useCallback(() => {
33
- setActiveIndex(getDefaultInitialIndex(options));
34
- }, [getDefaultInitialIndex, options]);
35
- useEffect(() => {
36
- return () => {
37
- if (typeaheadTimeoutRef.current)
38
- clearTimeout(typeaheadTimeoutRef.current);
39
- };
40
- }, []);
41
- useEffect(() => {
42
- setActiveIndex(current => {
43
- if (options.length === 0)
44
- return -1;
45
- if (current < 0)
46
- return current;
47
- return Math.min(current, options.length - 1);
48
- });
49
- }, [options]);
50
- useEffect(() => {
51
- optionRefs.current = optionRefs.current.slice(0, options.length);
52
- }, [options.length]);
53
- useEffect(() => {
54
- if (!isOpen || !focusActiveOptionOnOpen)
55
- return;
56
- if (searchable && document.activeElement === (searchInputRef === null || searchInputRef === void 0 ? void 0 : searchInputRef.current))
57
- return;
58
- focusActiveOption();
59
- }, [activeIndex, focusActiveOption, focusActiveOptionOnOpen, isOpen, searchable, searchInputRef]);
60
- const moveNext = useCallback(() => {
61
- if (options.length === 0)
62
- return;
63
- setActiveIndex(index => {
64
- if (index < 0)
65
- return 0;
66
- return Math.min(index + 1, options.length - 1);
67
- });
68
- }, [options.length]);
69
- const movePrev = useCallback(() => {
70
- if (options.length === 0)
71
- return;
72
- setActiveIndex(index => {
73
- if (index < 0)
74
- return options.length - 1;
75
- return Math.max(index - 1, 0);
76
- });
77
- }, [options.length]);
78
- const moveFirst = useCallback(() => {
79
- if (options.length === 0)
80
- return;
81
- setActiveIndex(0);
82
- }, [options.length]);
83
- const moveLast = useCallback(() => {
84
- if (options.length === 0)
85
- return;
86
- setActiveIndex(options.length - 1);
87
- }, [options.length]);
88
- const findTypeaheadMatch = useCallback((query, startIndex) => {
89
- if (!query || options.length === 0)
90
- return -1;
91
- const normalizedQuery = query.trim().toLocaleLowerCase();
92
- if (!normalizedQuery)
93
- return -1;
94
- const safeStartIndex = startIndex < 0 ? -1 : startIndex;
95
- for (let step = 1; step <= options.length; step += 1) {
96
- const index = (safeStartIndex + step + options.length) % options.length;
97
- const label = normalizedLabels[index];
98
- if (label === null || label === void 0 ? void 0 : label.startsWith(normalizedQuery))
99
- return index;
100
- }
101
- return -1;
102
- }, [normalizedLabels, options.length]);
103
- const handleTypeahead = useCallback((key) => {
104
- const nextBuffer = `${typeaheadRef.current}${key.toLocaleLowerCase()}`;
105
- const repeatedChar = new Set(nextBuffer).size === 1;
106
- let nextIndex = findTypeaheadMatch(nextBuffer, activeIndex);
107
- let appliedBuffer = nextBuffer;
108
- if (nextIndex < 0 && repeatedChar) {
109
- appliedBuffer = key.toLocaleLowerCase();
110
- nextIndex = findTypeaheadMatch(appliedBuffer, activeIndex);
111
- }
112
- if (typeaheadTimeoutRef.current)
113
- clearTimeout(typeaheadTimeoutRef.current);
114
- typeaheadRef.current = appliedBuffer;
115
- typeaheadTimeoutRef.current = setTimeout(() => {
116
- typeaheadRef.current = '';
117
- typeaheadTimeoutRef.current = null;
118
- }, typeaheadTimeoutMs);
119
- if (nextIndex < 0)
120
- return;
121
- setActiveIndex(nextIndex);
122
- if (!isOpen)
123
- onOpenChange(true);
124
- }, [activeIndex, findTypeaheadMatch, isOpen, onOpenChange, typeaheadTimeoutMs]);
125
- const handleKeyDown = useCallback((e) => {
126
- var _a;
127
- const isSearchInputTarget = searchable && e.target === (searchInputRef === null || searchInputRef === void 0 ? void 0 : searchInputRef.current);
128
- if (isSearchInputTarget) {
129
- switch (e.key) {
130
- case 'ArrowDown':
131
- e.preventDefault();
132
- if (!isOpen) {
133
- onOpenChange(true);
134
- return;
135
- }
136
- moveNext();
137
- return;
138
- case 'ArrowUp':
139
- e.preventDefault();
140
- if (!isOpen) {
141
- onOpenChange(true);
142
- return;
143
- }
144
- movePrev();
145
- return;
146
- case 'Home':
147
- if (!isOpen)
148
- return;
149
- e.preventDefault();
150
- moveFirst();
151
- return;
152
- case 'End':
153
- if (!isOpen)
154
- return;
155
- e.preventDefault();
156
- moveLast();
157
- return;
158
- case 'Escape':
159
- e.preventDefault();
160
- onOpenChange(false);
161
- return;
162
- }
163
- return;
164
- }
165
- if (e.key.length === 1 && !e.altKey && !e.ctrlKey && !e.metaKey && !/\s/.test(e.key)) {
166
- e.preventDefault();
167
- handleTypeahead(e.key);
168
- return;
169
- }
170
- switch (e.key) {
171
- case 'ArrowDown':
172
- e.preventDefault();
173
- if (!isOpen) {
174
- onOpenChange(true);
175
- return;
176
- }
177
- moveNext();
178
- break;
179
- case 'ArrowUp':
180
- e.preventDefault();
181
- if (!isOpen) {
182
- onOpenChange(true);
183
- return;
184
- }
185
- if (searchable &&
186
- activeIndex === 0 &&
187
- optionRefs.current[activeIndex] === document.activeElement) {
188
- (_a = searchInputRef === null || searchInputRef === void 0 ? void 0 : searchInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
189
- setActiveIndex(-1);
190
- return;
191
- }
192
- movePrev();
193
- break;
194
- case 'Home':
195
- if (!isOpen)
196
- return;
197
- e.preventDefault();
198
- moveFirst();
199
- break;
200
- case 'End':
201
- if (!isOpen)
202
- return;
203
- e.preventDefault();
204
- moveLast();
205
- break;
206
- case 'Escape':
207
- if (!isOpen)
208
- return;
209
- e.preventDefault();
210
- onOpenChange(false);
211
- break;
212
- }
213
- }, [
214
- activeIndex,
215
- handleTypeahead,
216
- isOpen,
217
- moveFirst,
218
- moveLast,
219
- moveNext,
220
- movePrev,
221
- onOpenChange,
222
- searchInputRef,
223
- searchable,
224
- ]);
225
- return {
226
- activeIndex,
227
- setActiveIndex,
228
- optionRefs,
229
- resetActiveIndex,
230
- clearTypeahead,
231
- handleKeyDown,
232
- focusActiveOption,
233
- };
234
- }
@@ -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
- }