@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,77 +0,0 @@
1
- 'use client';
2
- import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
3
- const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
4
- export function useViewportFill(ref, { bottomOffset = 0, min = 120, includeMarginTop = false, watchRef } = {}) {
5
- const [maxHeight, setMaxHeight] = useState(min);
6
- const raf = useRef(null);
7
- const measure = useCallback(() => {
8
- if (typeof window === 'undefined' || !ref.current)
9
- return;
10
- const el = ref.current;
11
- const rect = el.getBoundingClientRect();
12
- let top = rect.top;
13
- if (includeMarginTop) {
14
- const marginTop = parseFloat(window.getComputedStyle(el).marginTop || '0') || 0;
15
- top -= marginTop;
16
- }
17
- const next = Math.max(min, Math.floor(window.innerHeight - bottomOffset - top));
18
- setMaxHeight(prev => (prev === next ? prev : next));
19
- }, [ref, bottomOffset, min, includeMarginTop]);
20
- const scheduleMeasure = useCallback(() => {
21
- if (typeof window === 'undefined')
22
- return;
23
- if (raf.current != null) {
24
- cancelAnimationFrame(raf.current);
25
- }
26
- raf.current = window.requestAnimationFrame(() => {
27
- raf.current = null;
28
- measure();
29
- });
30
- }, [measure]);
31
- useIsomorphicLayoutEffect(() => {
32
- measure();
33
- }, [measure]);
34
- useEffect(() => {
35
- var _a;
36
- if (typeof window === 'undefined' || !ref.current)
37
- return;
38
- const target = ref.current;
39
- const extra = (_a = watchRef === null || watchRef === void 0 ? void 0 : watchRef.current) !== null && _a !== void 0 ? _a : null;
40
- const parent = target.parentElement;
41
- const onResize = () => scheduleMeasure();
42
- const onTransitionOrAnimationEnd = () => scheduleMeasure();
43
- window.addEventListener('resize', onResize);
44
- document.addEventListener('transitionend', onTransitionOrAnimationEnd, true);
45
- document.addEventListener('animationend', onTransitionOrAnimationEnd, true);
46
- let resizeObserver = null;
47
- if ('ResizeObserver' in window) {
48
- resizeObserver = new ResizeObserver(() => scheduleMeasure());
49
- resizeObserver.observe(target);
50
- if (parent && parent !== target) {
51
- resizeObserver.observe(parent);
52
- }
53
- if (extra && extra !== target && extra !== parent) {
54
- resizeObserver.observe(extra);
55
- }
56
- }
57
- return () => {
58
- window.removeEventListener('resize', onResize);
59
- document.removeEventListener('transitionend', onTransitionOrAnimationEnd, true);
60
- document.removeEventListener('animationend', onTransitionOrAnimationEnd, true);
61
- resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
62
- if (raf.current != null) {
63
- cancelAnimationFrame(raf.current);
64
- raf.current = null;
65
- }
66
- };
67
- }, [ref, watchRef, scheduleMeasure]);
68
- const style = useMemo(() => ({
69
- maxHeight,
70
- overflow: 'auto',
71
- }), [maxHeight]);
72
- return {
73
- maxHeight,
74
- style,
75
- recompute: measure,
76
- };
77
- }
@@ -1,5 +0,0 @@
1
- export const MOTION_MS = {
2
- panelSlide: 300,
3
- modal: 200,
4
- tooltipOpen: 300,
5
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,48 +0,0 @@
1
- const normalize = (s) => s.normalize('NFKC').toLowerCase().trim();
2
- const toTerms = (q) => (Array.isArray(q) ? q : q.split(/\s+/)).map(normalize).filter(Boolean);
3
- const valueToSearchable = (value) => typeof value === 'string'
4
- ? value
5
- : Array.isArray(value) || typeof value === 'object'
6
- ? JSON.stringify(value)
7
- : value == null
8
- ? ''
9
- : String(value);
10
- const itemMatches = (item, keys, terms, mode) => {
11
- if (terms.length === 0)
12
- return true;
13
- const haystack = keys
14
- .map(k => valueToSearchable(item[k]))
15
- .join(' ')
16
- .toString();
17
- const h = normalize(haystack);
18
- const hit = (t) => h.includes(t);
19
- return mode === 'AND' ? terms.every(hit) : terms.some(hit);
20
- };
21
- export function nestedFiltering(items, opts) {
22
- const { keys, query, includeParents = true, childrenKey, mode = 'AND' } = opts;
23
- const ck = (childrenKey !== null && childrenKey !== void 0 ? childrenKey : 'children');
24
- const terms = toTerms(query);
25
- const searchNested = (list) => {
26
- const out = [];
27
- for (const item of list) {
28
- const children = item[ck] || [];
29
- const filteredChildren = searchNested(children);
30
- const matchedSelf = itemMatches(item, keys, terms, mode);
31
- if (matchedSelf) {
32
- const clone = { ...item, [ck]: filteredChildren };
33
- out.push(clone);
34
- }
35
- else if (filteredChildren.length) {
36
- if (includeParents) {
37
- const clone = { ...item, [ck]: filteredChildren };
38
- out.push(clone);
39
- }
40
- else {
41
- out.push(...filteredChildren);
42
- }
43
- }
44
- }
45
- return out;
46
- };
47
- return searchNested(items);
48
- }
@@ -1,51 +0,0 @@
1
- /**
2
- * Formats a Date as "dd/mm/yyyy" or "dd/mm/yyyy hh:mm:ss".
3
- * Optionally returns user-friendly Danish labels like "I dag" or "I går".
4
- *
5
- * Examples:
6
- * - formatDate(new Date(), { userFriendlyLabel: true }) => "I dag"
7
- * - formatDate(new Date(), { userFriendlyLabel: true, showTime: true }) => "I dag, kl. 14:30"
8
- * - formatDate(date, { showTime: true }) => "10.03.2026 14:30"
9
- *
10
- * @param date - The Date or date-parsable value to format
11
- * @param options.showTime - If true, append time "hh:mm" or "hh:mm:ss"
12
- * @param options.showSeconds - If true, append seconds when showTime is enabled
13
- * @param options.userFriendlyLabel - If true, use "I dag" / "I går" when applicable
14
- * @returns A formatted string
15
- */
16
- export function formatDate(date, options = {}) {
17
- const d = date instanceof Date ? date : new Date(date);
18
- if (isNaN(d.getTime()))
19
- return '';
20
- const { showTime = false, showSeconds = false, userFriendlyLabel = false } = options;
21
- const pad = (n) => n.toString().padStart(2, '0');
22
- const formatTime = () => {
23
- const hours = pad(d.getHours());
24
- const minutes = pad(d.getMinutes());
25
- if (!showSeconds)
26
- return `${hours}:${minutes}`;
27
- const seconds = pad(d.getSeconds());
28
- return `${hours}:${minutes}:${seconds}`;
29
- };
30
- const isSameCalendarDay = (a, b) => a.getDate() === b.getDate() &&
31
- a.getMonth() === b.getMonth() &&
32
- a.getFullYear() === b.getFullYear();
33
- if (userFriendlyLabel) {
34
- const now = new Date();
35
- const yesterday = new Date(now);
36
- yesterday.setDate(now.getDate() - 1);
37
- if (isSameCalendarDay(d, now)) {
38
- return showTime ? `I dag, kl. ${formatTime()}` : 'I dag';
39
- }
40
- if (isSameCalendarDay(d, yesterday)) {
41
- return showTime ? `I går, kl. ${formatTime()}` : 'I går';
42
- }
43
- }
44
- const day = pad(d.getDate());
45
- const month = pad(d.getMonth() + 1);
46
- const year = d.getFullYear();
47
- const base = `${day}.${month}.${year}`;
48
- if (!showTime)
49
- return base;
50
- return `${base} ${formatTime()}`;
51
- }
@@ -1,78 +0,0 @@
1
- function isBrowser() {
2
- return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
3
- }
4
- /**
5
- * Safely read from localStorage.
6
- * - Returns undefined if not in browser
7
- * - Returns parsed JSON if value is JSON
8
- * - Returns plain string if not JSON
9
- * - Never throws
10
- */
11
- export function readLocalStorage(key) {
12
- if (!isBrowser())
13
- return undefined;
14
- try {
15
- const raw = window.localStorage.getItem(key);
16
- if (raw == null)
17
- return undefined;
18
- // Try parse once
19
- try {
20
- const parsed = JSON.parse(raw);
21
- // Handle double-stringified JSON
22
- if (typeof parsed === 'string') {
23
- try {
24
- return JSON.parse(parsed);
25
- }
26
- catch {
27
- return parsed;
28
- }
29
- }
30
- return parsed;
31
- }
32
- catch {
33
- // Not JSON — return as plain string
34
- return raw;
35
- }
36
- }
37
- catch {
38
- return undefined;
39
- }
40
- }
41
- /**
42
- * Safely write to localStorage.
43
- * - Automatically JSON.stringifies objects/arrays
44
- * - Stores plain strings as-is
45
- * - Never throws
46
- */
47
- export function writeLocalStorage(key, value) {
48
- if (!isBrowser())
49
- return;
50
- try {
51
- if (value === undefined) {
52
- window.localStorage.removeItem(key);
53
- return;
54
- }
55
- if (typeof value === 'string') {
56
- window.localStorage.setItem(key, value);
57
- }
58
- else {
59
- window.localStorage.setItem(key, JSON.stringify(value));
60
- }
61
- }
62
- catch {
63
- // ignore quota errors etc.
64
- }
65
- }
66
- /**
67
- * Remove key safely
68
- */
69
- export function removeLocalStorage(key) {
70
- if (!isBrowser())
71
- return;
72
- try {
73
- window.localStorage.removeItem(key);
74
- }
75
- catch {
76
- // ignore
77
- }
78
- }
@@ -1,46 +0,0 @@
1
- function normalizeTerms(query) {
2
- const terms = Array.isArray(query) ? query : [query];
3
- return [...new Set(terms.map(term => term.trim().toLowerCase()).filter(Boolean))].sort((a, b) => b.length - a.length);
4
- }
5
- export function getHighlightedSegments(text, query) {
6
- const terms = normalizeTerms(query);
7
- if (!text || terms.length === 0)
8
- return [{ text, matched: false }];
9
- const lower = text.toLowerCase();
10
- const ranges = [];
11
- for (const term of terms) {
12
- let startIndex = 0;
13
- while (startIndex < lower.length) {
14
- const matchIndex = lower.indexOf(term, startIndex);
15
- if (matchIndex === -1)
16
- break;
17
- ranges.push({ start: matchIndex, end: matchIndex + term.length });
18
- startIndex = matchIndex + term.length;
19
- }
20
- }
21
- if (ranges.length === 0)
22
- return [{ text, matched: false }];
23
- ranges.sort((a, b) => a.start - b.start || a.end - b.end);
24
- const mergedRanges = [];
25
- for (const range of ranges) {
26
- const previous = mergedRanges[mergedRanges.length - 1];
27
- if (!previous || range.start > previous.end) {
28
- mergedRanges.push({ ...range });
29
- continue;
30
- }
31
- previous.end = Math.max(previous.end, range.end);
32
- }
33
- const segments = [];
34
- let cursor = 0;
35
- for (const range of mergedRanges) {
36
- if (range.start > cursor) {
37
- segments.push({ text: text.slice(cursor, range.start), matched: false });
38
- }
39
- segments.push({ text: text.slice(range.start, range.end), matched: true });
40
- cursor = range.end;
41
- }
42
- if (cursor < text.length) {
43
- segments.push({ text: text.slice(cursor), matched: false });
44
- }
45
- return segments.length > 0 ? segments : [{ text, matched: false }];
46
- }