@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,125 +0,0 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Children, isValidElement, useCallback, useEffect, useId, useMemo, useState, } from 'react';
3
- import styles from './Tabs.module.css';
4
- import { Chip } from '../chip/Chip';
5
- import { Headline } from '../headline/Headline';
6
- const TabsItem = (_props) => {
7
- // This never renders directly; parent consumes it.
8
- return _jsx(_Fragment, {});
9
- };
10
- TabsItem.__TABS_SLOT__ = 'Item';
11
- function getFirstEnabledId(items) {
12
- var _a;
13
- return (_a = items.find(t => !t.hidden && !t.disabled)) === null || _a === void 0 ? void 0 : _a.id;
14
- }
15
- function normalizeFromChildren(children) {
16
- const items = [];
17
- Children.forEach(children, child => {
18
- if (!isValidElement(child))
19
- return;
20
- const t = child.type;
21
- if ((t === null || t === void 0 ? void 0 : t.__TABS_SLOT__) !== 'Item')
22
- return;
23
- const props = child.props;
24
- items.push({
25
- id: props.id,
26
- header: props.header,
27
- headerIcon: props.headerIcon,
28
- disabled: props.disabled,
29
- hidden: props.hidden,
30
- badge: props.badge,
31
- content: props.children,
32
- });
33
- });
34
- return items;
35
- }
36
- export function Tabs({ header, subheader, variant, panelStyle = false, tabs, value, defaultValue, onValueChange, addition, disableTopPadding, children, }) {
37
- const uid = useId();
38
- // Data API wins if provided; otherwise parse <Tabs.Item>
39
- const sourceTabs = useMemo(() => {
40
- if (tabs && tabs.length)
41
- return tabs;
42
- return normalizeFromChildren(children);
43
- }, [tabs, children]);
44
- const visibleTabs = useMemo(() => sourceTabs.filter(t => !t.hidden), [sourceTabs]);
45
- const isControlled = value !== undefined;
46
- const [internalValue, setInternalValue] = useState(() => {
47
- return defaultValue !== null && defaultValue !== void 0 ? defaultValue : getFirstEnabledId(visibleTabs);
48
- });
49
- const currentValue = isControlled ? value : internalValue;
50
- const activeIndex = useMemo(() => {
51
- if (!visibleTabs.length)
52
- return -1;
53
- const idx = visibleTabs.findIndex(t => t.id === currentValue);
54
- return idx >= 0 ? idx : 0;
55
- }, [visibleTabs, currentValue]);
56
- const activeTab = activeIndex >= 0 ? visibleTabs[activeIndex] : undefined;
57
- const setValue = useCallback((nextId) => {
58
- const idx = visibleTabs.findIndex(t => t.id === nextId);
59
- const tab = idx >= 0 ? visibleTabs[idx] : undefined;
60
- if (!tab || tab.disabled)
61
- return;
62
- if (!isControlled)
63
- setInternalValue(nextId);
64
- onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(nextId, tab, idx);
65
- }, [visibleTabs, isControlled, onValueChange]);
66
- // If current tab disappears (hidden/removed) or becomes disabled, recover to first enabled.
67
- useEffect(() => {
68
- if (!visibleTabs.length)
69
- return;
70
- const current = currentValue;
71
- const stillValid = visibleTabs.some(t => t.id === current && !t.disabled);
72
- if (stillValid)
73
- return;
74
- const next = getFirstEnabledId(visibleTabs);
75
- if (next === undefined)
76
- return;
77
- setValue(next);
78
- // setValue already calls onValueChange; fine.
79
- // For controlled usage, parent should update `value` accordingly.
80
- // If parent doesn't, it will remain "stuck" by design.
81
- }, [visibleTabs, currentValue, setValue]);
82
- // Keyboard: roving tabindex + select-on-arrow
83
- const onKeyDownTab = useCallback((e, index) => {
84
- var _a;
85
- const enabled = visibleTabs.filter(t => !t.disabled);
86
- if (!enabled.length)
87
- return;
88
- // Map current index -> enabled index
89
- const currentId = (_a = visibleTabs[index]) === null || _a === void 0 ? void 0 : _a.id;
90
- const currentEnabledIndex = enabled.findIndex(t => t.id === currentId);
91
- const focusAndSelect = (enabledIndex) => {
92
- const nextTab = enabled[enabledIndex];
93
- if (!nextTab)
94
- return;
95
- const btn = document.getElementById(`${uid}-tab-${String(nextTab.id)}`);
96
- btn === null || btn === void 0 ? void 0 : btn.focus();
97
- setValue(nextTab.id);
98
- };
99
- if (e.key === 'ArrowRight') {
100
- e.preventDefault();
101
- focusAndSelect((currentEnabledIndex + 1) % enabled.length);
102
- }
103
- else if (e.key === 'ArrowLeft') {
104
- e.preventDefault();
105
- focusAndSelect((currentEnabledIndex - 1 + enabled.length) % enabled.length);
106
- }
107
- else if (e.key === 'Home') {
108
- e.preventDefault();
109
- focusAndSelect(0);
110
- }
111
- else if (e.key === 'End') {
112
- e.preventDefault();
113
- focusAndSelect(enabled.length - 1);
114
- }
115
- }, [uid, visibleTabs, setValue]);
116
- return (_jsxs("div", { className: styles.root, children: [header ? (_jsx("div", { className: [styles.headerContainer, disableTopPadding ? styles.disableTopPadding : '']
117
- .filter(Boolean)
118
- .join(' '), children: _jsx(Headline, { disableMargin: true, size: 2, subheader: subheader, addition: addition, children: header }) })) : null, _jsxs("div", { className: `${styles.tabs} ${styles[variant]} ${panelStyle ? styles.panelStyle : ''}`, children: [_jsx("div", { className: styles.tabList, role: "tablist", "aria-label": header !== null && header !== void 0 ? header : 'Tabs', children: visibleTabs.map((tab, index) => {
119
- const selected = index === activeIndex;
120
- const tabDomId = `${uid}-tab-${String(tab.id)}`;
121
- const panelDomId = `${uid}-panel-${String(tab.id)}`;
122
- return (_jsx("div", { className: `${styles.tab} ${selected ? styles.active : ''}`, children: _jsxs("button", { id: tabDomId, type: "button", className: styles.tabButton, role: "tab", "aria-selected": selected, "aria-controls": panelDomId, tabIndex: selected ? 0 : -1, disabled: tab.disabled, onClick: () => setValue(tab.id), onKeyDown: e => onKeyDownTab(e, index), children: [tab.headerIcon ? _jsx("span", { className: styles.icon, children: tab.headerIcon }) : null, _jsx("span", { className: styles.label, children: tab.header }), tab.badge ? (_jsx("span", { className: styles.badge, children: _jsx(Chip, { size: "sm", children: tab.badge.toLocaleString('da-DK') }) })) : null] }) }, tab.id));
123
- }) }), _jsx("div", { id: activeTab ? `${uid}-panel-${String(activeTab.id)}` : undefined, role: "tabpanel", "aria-labelledby": activeTab ? `${uid}-tab-${String(activeTab.id)}` : undefined, className: styles.tabContent, children: activeTab === null || activeTab === void 0 ? void 0 : activeTab.content })] })] }));
124
- }
125
- Tabs.Item = TabsItem;
@@ -1,204 +0,0 @@
1
- .root {
2
- display: flex;
3
- flex-direction: column;
4
- min-width: 0;
5
- overflow: auto;
6
- }
7
-
8
- .headerContainer {
9
- display: flex;
10
- justify-content: space-between;
11
- align-items: center;
12
- padding-block: var(--spacing-lg);
13
- gap: var(--spacing-md);
14
- }
15
-
16
- .headerContainer.disableTopPadding {
17
- padding-block-start: 0;
18
- }
19
-
20
- /* Outer wrapper for tablist + content */
21
- .tabs {
22
- display: flex;
23
- flex-direction: column;
24
- flex-grow: 1;
25
- overflow: hidden;
26
- min-height: 0;
27
- }
28
-
29
- /* Tablist */
30
- .tabList {
31
- display: flex;
32
- flex-wrap: wrap;
33
- min-width: 0;
34
- }
35
-
36
- /* Individual tab wrapper */
37
- .tab {
38
- display: flex;
39
- flex-direction: column;
40
- border-radius: 0;
41
- border-block-end: 2px solid var(--color-border-default);
42
- }
43
-
44
- .active {
45
- border-block-end-color: var(--color-brand);
46
- }
47
-
48
- /* Button */
49
- .tabButton {
50
- font-size: var(--font-size-sm);
51
- color: inherit;
52
-
53
- display: inline-flex;
54
- align-items: center;
55
- justify-content: center;
56
- gap: var(--spacing-xs);
57
-
58
- white-space: nowrap;
59
-
60
- background: none;
61
- border: 0;
62
- border-radius: 0;
63
-
64
- padding-block: var(--spacing-sm);
65
- padding-inline: var(--spacing-md);
66
-
67
- cursor: pointer;
68
-
69
- transition:
70
- color var(--transition-fast) var(--ease-standard),
71
- background-color var(--transition-fast) var(--ease-standard),
72
- border-color var(--transition-fast) var(--ease-standard);
73
- }
74
-
75
- .tabButton:focus-visible {
76
- outline: none;
77
- box-shadow: var(--focus-ring);
78
- }
79
-
80
- .tabButton:disabled {
81
- cursor: not-allowed;
82
- color: var(--color-disabled-fg);
83
- }
84
-
85
- /* Icon + label */
86
- .icon {
87
- display: inline-flex;
88
- align-items: center;
89
- color: inherit;
90
- }
91
-
92
- .icon svg {
93
- inline-size: var(--icon-size-md);
94
- block-size: var(--icon-size-md);
95
- }
96
-
97
- .label {
98
- display: inline-block;
99
- }
100
-
101
- .badge {
102
- display: inline-flex;
103
- align-items: center;
104
- }
105
-
106
- /* Content panel */
107
- .tabContent {
108
- flex: 1 1 auto;
109
- min-height: 0;
110
- overflow: auto;
111
- }
112
-
113
- /* =========================
114
- Filled variant
115
- ========================= */
116
-
117
- .filled {
118
- gap: 0;
119
- }
120
-
121
- .filled .tabList {
122
- border-start-start-radius: var(--border-radius-default);
123
- border-start-end-radius: var(--border-radius-default);
124
- inline-size: fit-content;
125
- }
126
-
127
- .filled .tab {
128
- border: var(--border-width-thin) solid transparent;
129
- border-block-end: 0;
130
- color: var(--color-fg-muted);
131
- z-index: 3;
132
- border-start-start-radius: var(--border-radius-default);
133
- border-start-end-radius: var(--border-radius-default);
134
- transition:
135
- background-color var(--transition-fast) var(--ease-standard),
136
- color var(--transition-fast) var(--ease-standard),
137
- border-color var(--transition-fast) var(--ease-standard);
138
- }
139
-
140
- .filled .tab:not(.active):hover {
141
- color: var(--color-brand);
142
- }
143
-
144
- .filled .tab.active {
145
- background: var(--opac-bg-brand);
146
- color: var(--color-brand);
147
- border-color: var(--opac-bg-dark);
148
- }
149
-
150
- .filled .tabContent {
151
- border: var(--border-width-thin) solid var(--opac-bg-dark);
152
- background: var(--color-bg-surface);
153
- padding: var(--spacing-lg);
154
- }
155
-
156
- /* =========================
157
- Outlined variant
158
- ========================= */
159
-
160
- .outlined {
161
- gap: var(--spacing-md);
162
- }
163
-
164
- .outlined .tab {
165
- color: var(--color-fg-muted);
166
- border-block-end: 2px solid var(--color-border-default);
167
- transition: color var(--transition-fast) var(--ease-standard);
168
- }
169
-
170
- .outlined .tab:not(.active):hover {
171
- color: var(--color-brand);
172
- }
173
-
174
- .outlined .tab.active {
175
- color: var(--color-brand);
176
- border-block-end-color: var(--color-brand);
177
- }
178
-
179
- .outlined .tabContent {
180
- background: transparent;
181
- padding: 0;
182
- }
183
-
184
- /* =========================
185
- Panel style modifier
186
- ========================= */
187
-
188
- .panelStyle .tabList {
189
- border: var(--border-width-thin) solid var(--color-border-default);
190
- border-block-end: 0;
191
- }
192
-
193
- /* When panelStyle is on, tabs look “embedded” (no bottom border indicators) */
194
- .panelStyle .tab {
195
- border-block-end: 0;
196
- }
197
-
198
- /* In filled mode, keep the filled content panel visuals (already handled above).
199
- In outlined mode with panelStyle, give the content a panel container too. */
200
- .panelStyle.outlined .tabContent {
201
- border: var(--border-width-thin) solid var(--color-border-default);
202
- background: var(--color-bg-surface);
203
- padding: var(--spacing-lg);
204
- }
@@ -1,23 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Monitor, Moon, Palette, Sun } from 'lucide-react';
4
- import { Button } from '../../components/button/Button';
5
- import { Menu } from '../../components/menu/Menu';
6
- import { Popover } from '../../components/popover/Popover';
7
- import { useTheme } from '../../hooks/useTheme';
8
- const THEME_OPTIONS = [
9
- { value: 'system', label: 'System', icon: _jsx(Monitor, { size: 16 }) },
10
- { value: 'light', label: 'Lyst', icon: _jsx(Sun, { size: 16 }) },
11
- { value: 'dark', label: 'Mørkt', icon: _jsx(Moon, { size: 16 }) },
12
- ];
13
- export function ThemeMenuSection() {
14
- const { theme, switchTheme } = useTheme();
15
- return (_jsxs(_Fragment, { children: [_jsx(Menu.Header, { children: "Udseende" }), THEME_OPTIONS.map(option => (_jsx(Menu.RadioItem, { name: "theme", value: option.value, checked: theme === option.value, label: option.label, onValueChange: value => switchTheme(value) }, option.value)))] }));
16
- }
17
- export function ThemeButton({ size, variant = 'outlined' }) {
18
- const { theme, switchTheme } = useTheme();
19
- return (_jsx(Popover, { matchTriggerWidth: false, minWidth: "140px", trigger: (handleClick, chevron) => (_jsxs(Button, { variant: variant, size: size, onClick: handleClick, "aria-label": "Skift tema", "aria-haspopup": "menu", children: [_jsx(Palette, {}), chevron] })), children: close => (_jsxs(Menu, { children: [_jsx(Menu.Header, { children: "Udseende" }), THEME_OPTIONS.map(option => (_jsx(Menu.Item, { active: theme === option.value, children: _jsxs("button", { onClick: () => {
20
- switchTheme(option.value);
21
- close();
22
- }, children: [option.icon, option.label] }) }, option.value)))] })) }));
23
- }
@@ -1,20 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { X } from 'lucide-react';
3
- import styles from './Toast.module.css';
4
- import { Button } from '../button/Button';
5
- import { Headline } from '../headline/Headline';
6
- export function Toast({ title, subheader, message, severity = 'info', action, onClose, }) {
7
- const showHeader = Boolean(title);
8
- const showMessage = Boolean(message);
9
- const canClose = severity !== 'neutral';
10
- const isDismissibleNeutral = severity === 'neutral' && Boolean(onClose);
11
- const CloseButton = onClose && canClose ? (_jsx(Button, { type: "button", variant: "inline", shape: "round", className: styles.closeButton, "aria-label": "Dismiss notification", onClick: onClose, children: _jsx(X, { className: styles.closeIcon, "aria-hidden": "true" }) })) : null;
12
- return (_jsxs("div", { className: `${styles.toast} ${styles[severity]} ${isDismissibleNeutral ? styles.dismissibleNeutral : ''}`, role: "status", onClick: isDismissibleNeutral ? onClose : undefined, onKeyDown: isDismissibleNeutral
13
- ? e => {
14
- if (e.key === 'Enter' || e.key === ' ') {
15
- e.preventDefault();
16
- onClose === null || onClose === void 0 ? void 0 : onClose();
17
- }
18
- }
19
- : undefined, tabIndex: isDismissibleNeutral ? 0 : undefined, "aria-label": isDismissibleNeutral ? 'Luk notifikation' : undefined, children: [_jsxs("div", { className: styles.content, children: [showHeader && (_jsxs("div", { className: styles.row, children: [_jsx(Headline, { size: 4, severity: severity, disableMargin: true, subheader: subheader, children: title }), CloseButton] })), showMessage && (_jsxs("div", { className: styles.row, children: [_jsx("div", { className: styles.message, children: message }), !showHeader && CloseButton] }))] }), action && (_jsx("div", { className: styles.actions, children: _jsx(Button, { type: "button", variant: "primary", onClick: action.onClick, children: action.label }) }))] }));
20
- }
@@ -1,161 +0,0 @@
1
- .container {
2
- position: fixed;
3
- inset-inline-end: var(--spacing-lg);
4
- inset-block-start: var(--spacing-lg);
5
- display: flex;
6
- flex-direction: column;
7
- gap: var(--spacing-xs);
8
- z-index: var(--z-toast);
9
- min-width: 280px;
10
- word-break: break-word;
11
- }
12
-
13
- @media (max-width: 640px) {
14
- .container {
15
- inset-inline: var(--spacing-md);
16
- inset-block-end: var(--spacing-md);
17
- }
18
- }
19
-
20
- .toast {
21
- display: flex;
22
- flex-direction: column;
23
- gap: var(--spacing-xs);
24
- padding: var(--spacing-xs) var(--spacing-md);
25
- border-radius: var(--border-radius-md);
26
- box-shadow: var(--shadow-md);
27
- background-color: var(--color-bg-surface);
28
- border: var(--border-width-thin) solid var(--color-border-default);
29
- font-family: var(--font-family);
30
- max-width: 360px;
31
- animation: toast-enter var(--transition-normal) var(--ease-standard);
32
- border-left-width: var(--border-width-thick);
33
- }
34
-
35
- /* Severity accents */
36
- .info {
37
- border-left-color: var(--color-status-info-border);
38
- }
39
-
40
- .brand {
41
- border-left-color: var(--color-brand);
42
- }
43
-
44
- .success {
45
- border-left-color: var(--color-status-success-border);
46
- }
47
-
48
- .warning {
49
- border-left-color: var(--color-status-warning-border);
50
- }
51
-
52
- .error {
53
- border-left-color: var(--color-status-error-border);
54
- }
55
-
56
- .neutral {
57
- background-color: var(--color-bg-inverse);
58
- color: var(--color-fg-inverse);
59
- border-left-width: 0;
60
- min-width: 50px;
61
- max-width: 200px;
62
- width: fit-content;
63
- align-self: flex-end;
64
- }
65
-
66
- .dismissibleNeutral {
67
- cursor: pointer;
68
- transition:
69
- background-color var(--transition-fast) var(--ease-standard),
70
- transform 60ms ease;
71
- }
72
-
73
- .dismissibleNeutral:hover {
74
- background-color: color-mix(in srgb, var(--color-bg-inverse) 92%, white);
75
- }
76
-
77
- .dismissibleNeutral:active {
78
- transform: translateY(1px);
79
- }
80
-
81
- .dismissibleNeutral:focus-visible {
82
- outline: 2px solid var(--color-fg-inverse);
83
- outline-offset: 2px;
84
- }
85
-
86
- /* Layout */
87
- .content {
88
- flex: 1;
89
- min-width: 0;
90
- display: flex;
91
- flex-direction: column;
92
- gap: var(--spacing-xxs);
93
- }
94
-
95
- .row {
96
- display: flex;
97
- align-items: center;
98
- gap: var(--spacing-xs);
99
- min-width: 0;
100
- }
101
-
102
- /* Long-text handling suitable for toasts */
103
- .title,
104
- .message {
105
- min-width: 0;
106
- overflow-wrap: anywhere;
107
- word-break: break-word;
108
- white-space: normal;
109
- }
110
-
111
- /* Optional: clamp to avoid giant toasts */
112
- .title {
113
- font-size: var(--font-size-sm);
114
- font-weight: var(--font-weight-semibold);
115
- line-height: var(--line-height-tight);
116
-
117
- display: -webkit-box;
118
- -webkit-box-orient: vertical;
119
- -webkit-line-clamp: 2;
120
- overflow: hidden;
121
- }
122
-
123
- .message {
124
- font-size: var(--font-size-sm);
125
- line-height: var(--line-height-normal);
126
-
127
- display: -webkit-box;
128
- -webkit-box-orient: vertical;
129
- -webkit-line-clamp: 4;
130
- overflow: hidden;
131
- }
132
-
133
- /* Close button stays aligned at the end of the row */
134
- .closeButton {
135
- margin-inline-start: auto;
136
- flex: 0 0 auto;
137
- align-self: flex-start;
138
- }
139
-
140
- .closeIcon {
141
- width: var(--icon-size-sm);
142
- height: var(--icon-size-sm);
143
- }
144
-
145
- .actions {
146
- display: flex;
147
- justify-content: flex-end;
148
- gap: var(--spacing-xs);
149
- }
150
-
151
- /* Simple enter animation */
152
- @keyframes toast-enter {
153
- from {
154
- opacity: 0;
155
- transform: translateY(6px);
156
- }
157
- to {
158
- opacity: 1;
159
- transform: translateY(0);
160
- }
161
- }
@@ -1,70 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { createContext, useCallback, useContext, useState, useRef, useEffect, } from 'react';
4
- import { Toast } from '../Toast';
5
- import styles from '../Toast.module.css';
6
- const ToastContext = createContext(undefined);
7
- export function ToastProvider({ children, defaultDuration = 4000, }) {
8
- const [toasts, setToasts] = useState([]);
9
- const timeouts = useRef(new Map());
10
- const clearTimeoutForId = (id) => {
11
- const timeoutId = timeouts.current.get(id);
12
- if (timeoutId) {
13
- window.clearTimeout(timeoutId);
14
- timeouts.current.delete(id);
15
- }
16
- };
17
- const hideToast = useCallback((id) => {
18
- clearTimeoutForId(id);
19
- setToasts(prev => prev.filter(t => t.id !== id));
20
- }, []);
21
- const scheduleAutoDismiss = useCallback((toast) => {
22
- var _a;
23
- const duration = (_a = toast.duration) !== null && _a !== void 0 ? _a : defaultDuration;
24
- if (!duration || duration <= 0)
25
- return;
26
- clearTimeoutForId(toast.id);
27
- const timeoutId = window.setTimeout(() => {
28
- hideToast(toast.id);
29
- }, duration);
30
- timeouts.current.set(toast.id, timeoutId);
31
- }, [defaultDuration, hideToast]);
32
- const showToast = useCallback((config) => {
33
- var _a, _b, _c;
34
- const id = (_c = (_a = config.id) !== null && _a !== void 0 ? _a : (_b = crypto.randomUUID) === null || _b === void 0 ? void 0 : _b.call(crypto)) !== null && _c !== void 0 ? _c : `${Date.now()}-${Math.random()}`;
35
- const toast = { ...config, id };
36
- setToasts(prev => [...prev, toast]);
37
- scheduleAutoDismiss(toast);
38
- return id;
39
- }, [scheduleAutoDismiss]);
40
- const clearToasts = useCallback(() => {
41
- timeouts.current.forEach(timeoutId => window.clearTimeout(timeoutId));
42
- timeouts.current.clear();
43
- setToasts([]);
44
- }, []);
45
- useEffect(() => () => {
46
- timeouts.current.forEach(timeoutId => window.clearTimeout(timeoutId));
47
- timeouts.current.clear();
48
- }, []);
49
- return (_jsxs(ToastContext.Provider, { value: { showToast, hideToast, clearToasts }, children: [children, toasts.length > 0 && (_jsx("div", { className: styles.container, "aria-live": "polite", "aria-atomic": "false", children: toasts.map(toast => {
50
- var _a;
51
- return (_jsx(Toast, { title: toast.title, message: toast.message, severity: (_a = toast.severity) !== null && _a !== void 0 ? _a : 'info', action: toast.action && {
52
- label: toast.action.label,
53
- onClick: () => {
54
- var _a, _b;
55
- (_b = (_a = toast.action) === null || _a === void 0 ? void 0 : _a.onClick) === null || _b === void 0 ? void 0 : _b.call(_a);
56
- hideToast(toast.id);
57
- },
58
- }, onClose: () => hideToast(toast.id) }, toast.id));
59
- }) }))] }));
60
- }
61
- export function useToast() {
62
- const ctx = useContext(ToastContext);
63
- if (!ctx) {
64
- throw new Error('useToast must be used within a ToastProvider');
65
- }
66
- return ctx;
67
- }
68
- export function useOptionalToast() {
69
- return useContext(ToastContext);
70
- }
@@ -1,6 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import styles from './UserDisplay.module.css';
3
- import { Avatar } from '../avatar/Avatar';
4
- export function UserDisplay({ name, email, role, avatarUrl }) {
5
- return (_jsxs("div", { className: styles.container, children: [_jsx("div", { children: _jsx(Avatar, { imgSrc: avatarUrl, imgAlt: name, fullName: name, size: "xl" }) }), _jsxs("div", { className: styles.userInfo, children: [_jsx("h4", { children: name }), _jsx("p", { children: email }), _jsx("p", { children: role })] })] }));
6
- }
@@ -1,25 +0,0 @@
1
- .container {
2
- display: flex;
3
- gap: var(--spacing-sm);
4
- align-items: center;
5
- padding: var(--spacing-xs);
6
- background-color: var(--opac-bg-light);
7
- }
8
-
9
- .userInfo {
10
- display: flex;
11
- flex-direction: column;
12
- justify-content: center;
13
- padding: var(--spacing-sm);
14
- flex-grow: 0;
15
- color: var(--color-fg-muted);
16
- }
17
-
18
- .userInfo h4 {
19
- color: var(--color-fg-default);
20
- margin: 0;
21
- }
22
-
23
- .userInfo p {
24
- margin: 0;
25
- }
@@ -1,24 +0,0 @@
1
- export const SeverityBgColor = {
2
- neutral: 'var(--color-neutral-strong)',
3
- brand: 'var(--color-brand)',
4
- success: 'var(--color-status-success)',
5
- error: 'var(--color-status-error)',
6
- info: 'var(--color-status-info)',
7
- warning: 'var(--color-status-warning)',
8
- };
9
- export const SeverityBorderColor = {
10
- neutral: 'var(--color-neutral-strong)',
11
- brand: 'var(--color-brand)',
12
- success: 'var(--color-status-success-border)',
13
- error: 'var(--color-status-error-border)',
14
- info: 'var(--color-status-info-border)',
15
- warning: 'var(--color-status-warning-border)',
16
- };
17
- export const SeverityTextColor = {
18
- neutral: 'var(--color-neutral-strong-fg)',
19
- brand: 'var(--color-fg-on-brand)',
20
- success: 'var(--color-status-success-fg)',
21
- error: 'var(--color-status-error-fg)',
22
- info: 'var(--color-status-info-fg)',
23
- warning: 'var(--color-status-warning-fg)',
24
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,7 +0,0 @@
1
- export const sizes = {
2
- xs: 'var(--component-size-xs)',
3
- sm: 'var(--component-size-sm)',
4
- md: 'var(--component-size-md)',
5
- lg: 'var(--component-size-lg)',
6
- xl: 'var(--component-size-xl)',
7
- };