@dbcdk/react-components 0.0.97 → 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.
package/dist/index.cjs CHANGED
@@ -1867,6 +1867,7 @@ var Tabs_default = {
1867
1867
  label: "Tabs_label",
1868
1868
  badge: "Tabs_badge",
1869
1869
  tabContent: "Tabs_tabContent",
1870
+ loadingContent: "Tabs_loadingContent",
1870
1871
  filled: "Tabs_filled",
1871
1872
  outlined: "Tabs_outlined",
1872
1873
  panelStyle: "Tabs_panelStyle"
@@ -1981,1610 +1982,1693 @@ function Chip({
1981
1982
  }
1982
1983
  );
1983
1984
  }
1984
- var TabsItem = (_props) => {
1985
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
1986
- };
1987
- TabsItem.__TABS_SLOT__ = "Item";
1988
- function getFirstEnabledId(items) {
1989
- var _a;
1990
- return (_a = items.find((t) => !t.hidden && !t.disabled)) == null ? void 0 : _a.id;
1991
- }
1992
- function normalizeFromChildren(children) {
1993
- const items = [];
1994
- React20.Children.forEach(children, (child) => {
1995
- if (!React20.isValidElement(child)) return;
1996
- const t = child.type;
1997
- if ((t == null ? void 0 : t.__TABS_SLOT__) !== "Item") return;
1998
- const props = child.props;
1999
- items.push({
2000
- id: props.id,
2001
- header: props.header,
2002
- headerIcon: props.headerIcon,
2003
- disabled: props.disabled,
2004
- hidden: props.hidden,
2005
- badge: props.badge,
2006
- content: props.children
2007
- });
2008
- });
2009
- return items;
2010
- }
2011
- function Tabs({
2012
- header,
2013
- subheader,
2014
- variant,
2015
- panelStyle = false,
2016
- tabs,
2017
- value,
2018
- defaultValue,
2019
- onValueChange,
2020
- addition,
2021
- disableTopPadding,
2022
- children
1985
+ function SkeletonLoader({
1986
+ type,
1987
+ rows = 3,
1988
+ columns = 3,
1989
+ variant = "default",
1990
+ speedSec = 3
2023
1991
  }) {
2024
- const uid = React20.useId();
2025
- const sourceTabs = React20.useMemo(() => {
2026
- if (tabs && tabs.length) return tabs;
2027
- return normalizeFromChildren(children);
2028
- }, [tabs, children]);
2029
- const visibleTabs = React20.useMemo(() => sourceTabs.filter((t) => !t.hidden), [sourceTabs]);
2030
- const isControlled = value !== void 0;
2031
- const [internalValue, setInternalValue] = React20.useState(() => {
2032
- return defaultValue != null ? defaultValue : getFirstEnabledId(visibleTabs);
2033
- });
2034
- const currentValue = isControlled ? value : internalValue;
2035
- const activeIndex = React20.useMemo(() => {
2036
- if (!visibleTabs.length) return -1;
2037
- const idx = visibleTabs.findIndex((t) => t.id === currentValue);
2038
- return idx >= 0 ? idx : 0;
2039
- }, [visibleTabs, currentValue]);
2040
- const activeTab = activeIndex >= 0 ? visibleTabs[activeIndex] : void 0;
2041
- const setValue = React20.useCallback(
2042
- (nextId) => {
2043
- const idx = visibleTabs.findIndex((t) => t.id === nextId);
2044
- const tab = idx >= 0 ? visibleTabs[idx] : void 0;
2045
- if (!tab || tab.disabled) return;
2046
- if (!isControlled) setInternalValue(nextId);
2047
- onValueChange == null ? void 0 : onValueChange(nextId, tab, idx);
1992
+ const resolvedRows = type === "dataPage" ? rows || 12 : rows;
1993
+ const resolvedColumns = type === "dataPage" ? columns || 4 : columns;
1994
+ const line = (width, height = 14, radius = 6) => /* @__PURE__ */ jsxRuntime.jsx(
1995
+ SkeletonLoaderItem,
1996
+ {
1997
+ width,
1998
+ height,
1999
+ radius,
2000
+ variant,
2001
+ speedSec
2048
2002
  },
2049
- [visibleTabs, isControlled, onValueChange]
2003
+ `${String(width)}-${height}-${String(radius)}-${Math.random()}`
2050
2004
  );
2051
- React20.useEffect(() => {
2052
- if (!visibleTabs.length) return;
2053
- const current = currentValue;
2054
- const stillValid = visibleTabs.some((t) => t.id === current && !t.disabled);
2055
- if (stillValid) return;
2056
- const next = getFirstEnabledId(visibleTabs);
2057
- if (next === void 0) return;
2058
- setValue(next);
2059
- }, [visibleTabs, currentValue, setValue]);
2060
- const onKeyDownTab = React20.useCallback(
2061
- (e, index) => {
2062
- var _a;
2063
- const enabled = visibleTabs.filter((t) => !t.disabled);
2064
- if (!enabled.length) return;
2065
- const currentId = (_a = visibleTabs[index]) == null ? void 0 : _a.id;
2066
- const currentEnabledIndex = enabled.findIndex((t) => t.id === currentId);
2067
- const focusAndSelect = (enabledIndex) => {
2068
- const nextTab = enabled[enabledIndex];
2069
- if (!nextTab) return;
2070
- const btn = document.getElementById(
2071
- `${uid}-tab-${String(nextTab.id)}`
2072
- );
2073
- btn == null ? void 0 : btn.focus();
2074
- setValue(nextTab.id);
2075
- };
2076
- if (e.key === "ArrowRight") {
2077
- e.preventDefault();
2078
- focusAndSelect((currentEnabledIndex + 1) % enabled.length);
2079
- } else if (e.key === "ArrowLeft") {
2080
- e.preventDefault();
2081
- focusAndSelect((currentEnabledIndex - 1 + enabled.length) % enabled.length);
2082
- } else if (e.key === "Home") {
2083
- e.preventDefault();
2084
- focusAndSelect(0);
2085
- } else if (e.key === "End") {
2086
- e.preventDefault();
2087
- focusAndSelect(enabled.length - 1);
2088
- }
2005
+ const pills = (count) => Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
2006
+ SkeletonLoaderItem,
2007
+ {
2008
+ width: 80 + i % 3 * 30,
2009
+ height: 30,
2010
+ radius: 6,
2011
+ variant,
2012
+ speedSec,
2013
+ ariaLabel: "Loading filter"
2089
2014
  },
2090
- [uid, visibleTabs, setValue]
2015
+ `pill-${i}`
2016
+ ));
2017
+ const textBlock = (count) => Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
2018
+ SkeletonLoaderItem,
2019
+ {
2020
+ width: i === count - 1 ? "60%" : `${90 - i % 3 * 10}%`,
2021
+ height: 12,
2022
+ radius: 4,
2023
+ variant,
2024
+ speedSec,
2025
+ ariaLabel: "Loading text line"
2026
+ },
2027
+ `text-${i}`
2028
+ ));
2029
+ const tableHeaderRow = () => /* @__PURE__ */ jsxRuntime.jsx(
2030
+ "div",
2031
+ {
2032
+ style: {
2033
+ display: "grid",
2034
+ gridTemplateColumns: `repeat(${resolvedColumns}, minmax(0, 1fr))`,
2035
+ gap: 12,
2036
+ alignItems: "center",
2037
+ width: "100%"
2038
+ },
2039
+ children: Array.from({ length: resolvedColumns }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
2040
+ SkeletonLoaderItem,
2041
+ {
2042
+ height: 20,
2043
+ width: "90%",
2044
+ radius: 6,
2045
+ variant,
2046
+ speedSec,
2047
+ ariaLabel: "Loading table header"
2048
+ },
2049
+ `thead-${i}`
2050
+ ))
2051
+ }
2091
2052
  );
2092
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Tabs_default.root, children: [
2093
- header ? /* @__PURE__ */ jsxRuntime.jsx(
2053
+ const tableBodyRow = (rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2054
+ "div",
2055
+ {
2056
+ style: {
2057
+ display: "grid",
2058
+ gridTemplateColumns: `repeat(${resolvedColumns}, minmax(0, 1fr))`,
2059
+ gap: 12,
2060
+ alignItems: "center",
2061
+ width: "100%"
2062
+ },
2063
+ children: Array.from({ length: resolvedColumns }).map((_, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
2064
+ SkeletonLoaderItem,
2065
+ {
2066
+ height: 20,
2067
+ width: colIndex % 3 === 0 ? "93%" : colIndex % 3 === 1 ? "98%" : "90%",
2068
+ radius: 4,
2069
+ variant,
2070
+ speedSec,
2071
+ ariaLabel: "Loading table cell"
2072
+ },
2073
+ `tcell-${rowIndex}-${colIndex}`
2074
+ ))
2075
+ },
2076
+ `trow-${rowIndex}`
2077
+ );
2078
+ const inputFieldRow = (i) => {
2079
+ const labelW = i % 3 === 0 ? "34%" : i % 3 === 1 ? "42%" : "28%";
2080
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2094
2081
  "div",
2095
2082
  {
2096
- className: [Tabs_default.headerContainer, disableTopPadding ? Tabs_default.disableTopPadding : ""].filter(Boolean).join(" "),
2097
- children: /* @__PURE__ */ jsxRuntime.jsx(Headline, { disableMargin: true, size: 2, subheader, addition, children: header })
2098
- }
2099
- ) : null,
2100
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${Tabs_default.tabs} ${Tabs_default[variant]} ${panelStyle ? Tabs_default.panelStyle : ""}`, children: [
2101
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: Tabs_default.tabList, role: "tablist", "aria-label": header != null ? header : "Tabs", children: visibleTabs.map((tab, index) => {
2102
- const selected = index === activeIndex;
2103
- const tabDomId = `${uid}-tab-${String(tab.id)}`;
2104
- const panelDomId = `${uid}-panel-${String(tab.id)}`;
2105
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Tabs_default.tab} ${selected ? Tabs_default.active : ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs(
2106
- "button",
2107
- {
2108
- id: tabDomId,
2109
- type: "button",
2110
- className: Tabs_default.tabButton,
2111
- role: "tab",
2112
- "aria-selected": selected,
2113
- "aria-controls": panelDomId,
2114
- tabIndex: selected ? 0 : -1,
2115
- disabled: tab.disabled,
2116
- onClick: () => setValue(tab.id),
2117
- onKeyDown: (e) => onKeyDownTab(e, index),
2118
- children: [
2119
- tab.headerIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: Tabs_default.icon, children: tab.headerIcon }) : null,
2120
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: Tabs_default.label, children: tab.header }),
2121
- tab.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: Tabs_default.badge, children: /* @__PURE__ */ jsxRuntime.jsx(Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
2122
- ]
2123
- }
2124
- ) }, tab.id);
2125
- }) }),
2126
- /* @__PURE__ */ jsxRuntime.jsx(
2127
- "div",
2128
- {
2129
- id: activeTab ? `${uid}-panel-${String(activeTab.id)}` : void 0,
2130
- role: "tabpanel",
2131
- "aria-labelledby": activeTab ? `${uid}-tab-${String(activeTab.id)}` : void 0,
2132
- className: Tabs_default.tabContent,
2133
- children: activeTab == null ? void 0 : activeTab.content
2134
- }
2135
- )
2136
- ] })
2137
- ] });
2138
- }
2139
- Tabs.Item = TabsItem;
2140
- function CollapsibleHeadline({
2141
- header,
2142
- expanded,
2143
- onToggle,
2144
- controls,
2145
- addition,
2146
- storageKey,
2147
- children,
2148
- size = 2,
2149
- variant = "muted",
2150
- weight = 400,
2151
- ...headlineProps
2152
- }) {
2153
- const generatedId = React20.useId();
2154
- const panelId = controls != null ? controls : generatedId;
2155
- const [internalExpanded, setInternalExpanded] = React20.useState(() => {
2156
- if (!storageKey || typeof window === "undefined") return expanded != null ? expanded : true;
2157
- const stored = localStorage.getItem(storageKey);
2158
- return stored !== null ? stored === "true" : expanded != null ? expanded : true;
2159
- });
2160
- const isExpanded = storageKey ? internalExpanded : expanded != null ? expanded : false;
2161
- const handleToggle = () => {
2162
- if (storageKey) {
2163
- const next = !internalExpanded;
2164
- setInternalExpanded(next);
2165
- localStorage.setItem(storageKey, String(next));
2166
- }
2167
- onToggle == null ? void 0 : onToggle();
2168
- };
2169
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Headline_default.collapsibleRoot, children: [
2170
- /* @__PURE__ */ jsxRuntime.jsxs(
2171
- Headline,
2172
- {
2173
- ...headlineProps,
2174
- variant,
2175
- weight,
2176
- size,
2177
- addition,
2083
+ style: { display: "flex", flexDirection: "column", gap: 8, width: "100%" },
2178
2084
  children: [
2179
- header,
2180
2085
  /* @__PURE__ */ jsxRuntime.jsx(
2181
- Button,
2086
+ "div",
2182
2087
  {
2183
- shape: "round",
2184
- type: "button",
2185
- variant: "inline",
2186
- "aria-expanded": isExpanded,
2187
- "aria-controls": panelId,
2188
- onClick: handleToggle,
2088
+ style: {
2089
+ display: "flex",
2090
+ alignItems: "center",
2091
+ justifyContent: "space-between",
2092
+ gap: 12
2093
+ },
2189
2094
  children: /* @__PURE__ */ jsxRuntime.jsx(
2190
- lucideReact.ChevronDown,
2095
+ SkeletonLoaderItem,
2191
2096
  {
2192
- "aria-hidden": true,
2193
- className: [Headline_default.toggleChevron, isExpanded ? Headline_default.toggleChevronExpanded : ""].filter(Boolean).join(" ")
2097
+ width: labelW,
2098
+ height: 10,
2099
+ radius: 4,
2100
+ variant,
2101
+ speedSec,
2102
+ ariaLabel: "Loading label"
2194
2103
  }
2195
2104
  )
2196
2105
  }
2106
+ ),
2107
+ /* @__PURE__ */ jsxRuntime.jsx(
2108
+ SkeletonLoaderItem,
2109
+ {
2110
+ width: "100%",
2111
+ height: 25,
2112
+ radius: 8,
2113
+ variant,
2114
+ speedSec,
2115
+ ariaLabel: "Loading input"
2116
+ }
2197
2117
  )
2198
2118
  ]
2199
- }
2200
- ),
2201
- isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { id: panelId, className: Headline_default.collapsiblePanel, children })
2202
- ] });
2203
- }
2204
-
2205
- // src/components/page-layout/components/page-layout-hero/PageLayoutHero.module.css
2206
- var PageLayoutHero_default = {
2207
- heroContainer: "PageLayoutHero_heroContainer",
2208
- splitWrapper: "PageLayoutHero_splitWrapper",
2209
- imageColumn: "PageLayoutHero_imageColumn",
2210
- textColumn: "PageLayoutHero_textColumn",
2211
- textInner: "PageLayoutHero_textInner",
2212
- metaHeadline: "PageLayoutHero_metaHeadline",
2213
- headline: "PageLayoutHero_headline"
2214
- };
2215
-
2216
- // src/components/page-layout/PageLayout.module.css
2217
- var PageLayout_default = {
2218
- root: "PageLayout_root",
2219
- containScrolling: "PageLayout_containScrolling",
2220
- documentScrolling: "PageLayout_documentScrolling",
2221
- vertical: "PageLayout_vertical",
2222
- horizontal: "PageLayout_horizontal",
2223
- sidebar: "PageLayout_sidebar",
2224
- mainColumn: "PageLayout_mainColumn",
2225
- header: "PageLayout_header",
2226
- hero: "PageLayout_hero",
2227
- mainScroll: "PageLayout_mainScroll",
2228
- content: "PageLayout_content",
2229
- footer: "PageLayout_footer",
2230
- headerContainer: "PageLayout_headerContainer",
2231
- headerContent: "PageLayout_headerContent",
2232
- footerContent: "PageLayout_footerContent",
2233
- maxWidthMd: "PageLayout_maxWidthMd",
2234
- maxWidthSm: "PageLayout_maxWidthSm",
2235
- contentInner: "PageLayout_contentInner"
2236
- };
2237
- function getMaxWidthClass(value) {
2238
- if (!value) return "";
2239
- if (value === "sm") return PageLayout_default.maxWidthSm;
2240
- return PageLayout_default.maxWidthMd;
2241
- }
2242
- var PageLayoutHero = ({
2243
- children,
2244
- link,
2245
- metaHeadline,
2246
- headline,
2247
- image,
2248
- maxWidth = "md",
2249
- textBgColor = "var(--color-primary-900)"
2250
- }) => {
2251
- const content = /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayoutHero_default.heroContainer} ${getMaxWidthClass(maxWidth)}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: PageLayoutHero_default.splitWrapper, children: [
2252
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayoutHero_default.imageColumn, children: image }),
2253
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayoutHero_default.textColumn, style: { backgroundColor: textBgColor }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: PageLayoutHero_default.textInner, children: [
2254
- metaHeadline && /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayoutHero_default.metaHeadline, children: metaHeadline }),
2255
- headline && /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayoutHero_default.headline, children: /* @__PURE__ */ jsxRuntime.jsx("h2", { children: headline }) }),
2256
- children
2257
- ] }) })
2258
- ] }) });
2259
- return link ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: link(content) }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: content });
2260
- };
2261
- function getMaxWidthClass2(value, styles) {
2262
- if (!value) return "";
2263
- if (value === "sm") return styles.maxWidthSm;
2264
- return styles.maxWidthMd;
2265
- }
2266
- function getSlotName(el) {
2267
- var _a;
2268
- const t = el.type;
2269
- return (_a = t == null ? void 0 : t.__PAGE_LAYOUT_SLOT__) != null ? _a : null;
2270
- }
2271
- function splitSlots(children) {
2272
- const slots = {};
2273
- const rest = [];
2274
- React20.Children.forEach(children, (child) => {
2275
- if (!React20.isValidElement(child)) {
2276
- if (child != null) rest.push(child);
2277
- return;
2278
- }
2279
- const slot = getSlotName(child);
2280
- if (!slot) {
2281
- rest.push(child);
2282
- return;
2283
- }
2284
- slots[slot] = child;
2285
- });
2286
- return { slots, rest };
2287
- }
2288
- var PageLayoutSidebar = ({
2289
- children
2290
- }) => {
2291
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2292
- };
2293
- PageLayoutSidebar.__PAGE_LAYOUT_SLOT__ = "Sidebar";
2294
- var PageLayoutHeader = ({
2295
- maxWidth = false,
2296
- children
2297
- }) => {
2298
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayout_default.headerContainer, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayout_default.headerContent} ${getMaxWidthClass2(maxWidth, PageLayout_default)}`, children }) });
2299
- };
2300
- PageLayoutHeader.__PAGE_LAYOUT_SLOT__ = "Header";
2301
- var PageLayoutContent = ({
2302
- maxWidth = false,
2303
- children
2304
- }) => {
2305
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayout_default.contentInner} ${getMaxWidthClass2(maxWidth, PageLayout_default)}`, children });
2306
- };
2307
- PageLayoutContent.__PAGE_LAYOUT_SLOT__ = "Content";
2308
- var PageLayoutFooter = ({
2309
- maxWidth = false,
2310
- children
2311
- }) => {
2312
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayout_default.footerContent} ${getMaxWidthClass2(maxWidth, PageLayout_default)}`, children });
2313
- };
2314
- PageLayoutFooter.__PAGE_LAYOUT_SLOT__ = "Footer";
2315
- PageLayoutHero.__PAGE_LAYOUT_SLOT__ = "Hero";
2316
- var PageLayoutBase = ({
2317
- children,
2318
- containScrolling = false,
2319
- orientation = "vertical"
2320
- }) => {
2321
- var _a, _b;
2322
- const { slots, rest } = splitSlots(children);
2323
- const content = (_a = slots.Content) != null ? _a : rest.length ? /* @__PURE__ */ jsxRuntime.jsx(PageLayoutContent, { maxWidth: "md", children: rest }) : void 0;
2324
- const rootClass = [
2325
- PageLayout_default.root,
2326
- orientation === "vertical" ? PageLayout_default.vertical : PageLayout_default.horizontal,
2327
- containScrolling ? PageLayout_default.containScrolling : PageLayout_default.documentScrolling
2328
- ].filter(Boolean).join(" ");
2329
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rootClass, children: [
2330
- slots.Sidebar ? /* @__PURE__ */ jsxRuntime.jsx("aside", { className: PageLayout_default.sidebar, "aria-label": (_b = slots.Sidebar.props) == null ? void 0 : _b.ariaLabel, children: slots.Sidebar }) : null,
2331
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: PageLayout_default.mainColumn, children: [
2332
- slots.Header ? /* @__PURE__ */ jsxRuntime.jsx("header", { className: PageLayout_default.header, children: slots.Header }) : null,
2333
- slots.Hero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayout_default.hero, children: slots.Hero }) : null,
2334
- content || slots.Footer ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: PageLayout_default.mainScroll, children: [
2335
- content ? /* @__PURE__ */ jsxRuntime.jsx("main", { className: PageLayout_default.content, children: content }) : null,
2336
- slots.Footer ? /* @__PURE__ */ jsxRuntime.jsx("footer", { className: PageLayout_default.footer, children: slots.Footer }) : null
2337
- ] }) : null
2119
+ },
2120
+ `if-${i}`
2121
+ );
2122
+ };
2123
+ const inputFieldList = (count) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 16, width: "100%" }, children: [
2124
+ Array.from({ length: count }).map((_, i) => inputFieldRow(i)),
2125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 12, justifyContent: "flex-end", marginTop: 8 }, children: [
2126
+ /* @__PURE__ */ jsxRuntime.jsx(
2127
+ SkeletonLoaderItem,
2128
+ {
2129
+ width: 110,
2130
+ height: 30,
2131
+ radius: 8,
2132
+ variant,
2133
+ speedSec,
2134
+ ariaLabel: "Loading action"
2135
+ }
2136
+ ),
2137
+ /* @__PURE__ */ jsxRuntime.jsx(
2138
+ SkeletonLoaderItem,
2139
+ {
2140
+ width: 90,
2141
+ height: 30,
2142
+ radius: 8,
2143
+ variant,
2144
+ speedSec,
2145
+ ariaLabel: "Loading action"
2146
+ }
2147
+ )
2338
2148
  ] })
2339
2149
  ] });
2340
- };
2341
- var PageLayout = Object.assign(PageLayoutBase, {
2342
- Sidebar: PageLayoutSidebar,
2343
- Header: PageLayoutHeader,
2344
- Hero: PageLayoutHero,
2345
- Content: PageLayoutContent,
2346
- Footer: PageLayoutFooter
2347
- });
2348
-
2349
- // src/components/hyperlink/Hyperlink.module.css
2350
- var Hyperlink_default = {
2351
- link: "Hyperlink_link",
2352
- secondary: "Hyperlink_secondary",
2353
- primary: "Hyperlink_primary",
2354
- block: "Hyperlink_block",
2355
- content: "Hyperlink_content",
2356
- icon: "Hyperlink_icon"
2357
- };
2358
- function cx2(...parts) {
2359
- return parts.filter(Boolean).join(" ");
2360
- }
2361
- function renderInner(children, icon) {
2362
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2363
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: Hyperlink_default.content, children }),
2364
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Hyperlink_default.icon, children: icon })
2365
- ] });
2366
- }
2367
- function Hyperlink(props) {
2368
- var _a;
2369
- const {
2370
- children,
2371
- icon,
2372
- className,
2373
- asChild,
2374
- as = "a",
2375
- variant = "primary",
2376
- inline = true,
2377
- ...rest
2378
- } = props;
2379
- const linkClassName = cx2(
2380
- Hyperlink_default.link,
2381
- className,
2382
- variant === "secondary" ? Hyperlink_default.secondary : Hyperlink_default.primary,
2383
- inline ? "" : Hyperlink_default.block
2384
- );
2385
- if (asChild) {
2386
- const child = React20__namespace.Children.only(children);
2387
- if (!React20__namespace.isValidElement(child)) {
2388
- throw new Error("Hyperlink with asChild expects a single valid React element as its child.");
2389
- }
2390
- const childProps = (_a = child.props) != null ? _a : {};
2391
- return React20__namespace.cloneElement(child, {
2392
- ...childProps,
2393
- ...rest,
2394
- className: cx2(childProps.className, linkClassName),
2395
- children: renderInner(childProps.children, icon),
2396
- onClick: (e) => {
2397
- e.stopPropagation();
2398
- if (childProps.onClick) {
2399
- childProps.onClick(e);
2400
- }
2401
- }
2402
- });
2403
- }
2404
- if (as === "button") {
2150
+ const squares = () => {
2151
+ const gap = 12;
2152
+ const squareSize = `min(calc((100% - ${(resolvedColumns - 1) * gap}px) / ${resolvedColumns}), calc((100% - ${(resolvedRows - 1) * gap}px) / ${resolvedRows}))`;
2153
+ const gridTemplateColumns = resolvedColumns === 1 ? "repeat(1, 100%)" : `repeat(${resolvedColumns}, ${squareSize})`;
2405
2154
  return /* @__PURE__ */ jsxRuntime.jsx(
2406
- "button",
2155
+ "div",
2407
2156
  {
2408
- type: "button",
2409
- className: linkClassName,
2410
- ...rest,
2411
- children: renderInner(children, icon)
2157
+ style: {
2158
+ display: "grid",
2159
+ gridTemplateColumns,
2160
+ gridTemplateRows: `repeat(${resolvedRows}, ${squareSize})`,
2161
+ gap,
2162
+ justifyContent: "center",
2163
+ alignContent: "center",
2164
+ width: "100%",
2165
+ height: "100%",
2166
+ minHeight: 0,
2167
+ flexGrow: 1
2168
+ },
2169
+ children: Array.from({ length: resolvedRows * resolvedColumns }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
2170
+ SkeletonLoaderItem,
2171
+ {
2172
+ width: "100%",
2173
+ height: "100%",
2174
+ radius: 8,
2175
+ variant,
2176
+ speedSec,
2177
+ ariaLabel: "Loading square"
2178
+ },
2179
+ `square-${i}`
2180
+ ))
2412
2181
  }
2413
2182
  );
2414
- }
2415
- return /* @__PURE__ */ jsxRuntime.jsx(
2416
- "a",
2183
+ };
2184
+ const filterbar = () => /* @__PURE__ */ jsxRuntime.jsxs(
2185
+ "div",
2417
2186
  {
2418
- onClick: (e) => e.stopPropagation(),
2419
- className: linkClassName,
2420
- ...rest,
2421
- children: renderInner(children, icon)
2187
+ style: {
2188
+ display: "flex",
2189
+ alignItems: "center",
2190
+ justifyContent: "space-between",
2191
+ gap: 12,
2192
+ flexWrap: "wrap",
2193
+ width: "100%"
2194
+ },
2195
+ children: [
2196
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: 12, flexWrap: "wrap" }, children: pills(resolvedColumns) }),
2197
+ /* @__PURE__ */ jsxRuntime.jsx(
2198
+ SkeletonLoaderItem,
2199
+ {
2200
+ width: 240,
2201
+ height: 30,
2202
+ variant,
2203
+ speedSec,
2204
+ ariaLabel: "Loading"
2205
+ }
2206
+ )
2207
+ ]
2422
2208
  }
2423
2209
  );
2424
- }
2425
-
2426
- // src/components/page-layout/components/layout-footer/LayoutFooter.module.css
2427
- var LayoutFooter_default = {
2428
- footer: "LayoutFooter_footer",
2429
- inner: "LayoutFooter_inner",
2430
- brand: "LayoutFooter_brand",
2431
- logoRow: "LayoutFooter_logoRow",
2432
- meta: "LayoutFooter_meta",
2433
- part: "LayoutFooter_part",
2434
- links: "LayoutFooter_links"};
2435
- var DEFAULT_META_PARTS = [
2436
- "Tempovej 7-11",
2437
- "DK-2750 Ballerup",
2438
- "+45 44 86 77 11",
2439
- `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} DBC DIGITAL A/S`
2440
- ];
2441
- var DEFAULT_LINKS = [
2442
- {
2443
- label: "Kundeservice",
2444
- href: "https://kundeservice.dbc.dk",
2445
- external: true
2446
- },
2447
- {
2448
- label: "Cookies",
2449
- href: "/cookies"
2450
- }
2451
- ];
2452
- function LayoutFooter({
2453
- links = DEFAULT_LINKS,
2454
- metaParts = DEFAULT_META_PARTS,
2455
- extraLinks
2456
- }) {
2457
- return /* @__PURE__ */ jsxRuntime.jsx("footer", { className: LayoutFooter_default.footer, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: LayoutFooter_default.inner, children: [
2458
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: LayoutFooter_default.brand, children: [
2459
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: LayoutFooter_default.logoRow, children: /* @__PURE__ */ jsxRuntime.jsx(Logo, {}) }),
2460
- /* @__PURE__ */ jsxRuntime.jsx("address", { className: LayoutFooter_default.meta, children: metaParts.map((part) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: LayoutFooter_default.part, children: part }, part)) })
2461
- ] }),
2462
- /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: LayoutFooter_default.links, "aria-label": "Footer navigation", children: [
2463
- extraLinks && extraLinks.length > 0 && (extraLinks == null ? void 0 : extraLinks.map((link, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: link }, index))),
2464
- links.map((link) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(
2465
- Hyperlink,
2466
- {
2467
- href: link.href,
2468
- ...link.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
2469
- children: link.label
2470
- }
2471
- ) }, link.label))
2472
- ] })
2473
- ] }) });
2474
- }
2475
-
2476
- // src/components/clear-button/ClearButton.module.css
2477
- var ClearButton_default = {
2478
- clearButton: "ClearButton_clearButton",
2479
- button: "ClearButton_button",
2480
- absolute: "ClearButton_absolute"
2481
- };
2482
- function ClearButton({ onClick, absolute }) {
2483
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${ClearButton_default.clearButton} ${absolute ? ClearButton_default.absolute : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(
2484
- "button",
2210
+ const table = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12, width: "100%" }, children: [
2211
+ tableHeaderRow(),
2212
+ Array.from({ length: resolvedRows }).map((_, r) => tableBodyRow(r))
2213
+ ] });
2214
+ const dataPageHeader = () => /* @__PURE__ */ jsxRuntime.jsxs(
2215
+ "div",
2485
2216
  {
2486
- className: ClearButton_default.button,
2487
- type: "button",
2488
- "data-input-role": "clear",
2489
- onMouseDown: (e) => {
2490
- e.preventDefault();
2491
- e.stopPropagation();
2492
- },
2493
- onClick: (e) => {
2494
- e.preventDefault();
2495
- e.stopPropagation();
2496
- onClick == null ? void 0 : onClick(e);
2217
+ style: {
2218
+ display: "flex",
2219
+ alignItems: "center",
2220
+ justifyContent: "space-between",
2221
+ gap: 16,
2222
+ flexWrap: "wrap",
2223
+ width: "100%"
2497
2224
  },
2498
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 16 })
2499
- }
2500
- ) });
2501
- }
2502
-
2503
- // src/components/forms/input/Input.module.css
2504
- var Input_default = {
2505
- container: "Input_container",
2506
- fullWidth: "Input_fullWidth",
2507
- field: "Input_field",
2508
- input: "Input_input",
2509
- withButton: "Input_withButton",
2510
- withClear: "Input_withClear",
2511
- withInlineClear: "Input_withInlineClear",
2512
- outlined: "Input_outlined",
2513
- surface: "Input_surface",
2514
- subtle: "Input_subtle",
2515
- embedded: "Input_embedded",
2516
- standalone: "Input_standalone",
2517
- modified: "Input_modified",
2518
- xs: "Input_xs",
2519
- sm: "Input_sm",
2520
- md: "Input_md",
2521
- lg: "Input_lg",
2522
- fieldWithIcon: "Input_fieldWithIcon",
2523
- icon: "Input_icon",
2524
- withTrailingLabel: "Input_withTrailingLabel",
2525
- trailingLabel: "Input_trailingLabel",
2526
- trailingButton: "Input_trailingButton",
2527
- startAdornment: "Input_startAdornment",
2528
- endAdornment: "Input_endAdornment",
2529
- clearSlot: "Input_clearSlot"
2530
- };
2531
- function mergeRefs2(...refs) {
2532
- return (node) => {
2533
- for (const ref of refs) {
2534
- if (!ref) continue;
2535
- if (typeof ref === "function") ref(node);
2536
- else ref.current = node;
2225
+ children: [
2226
+ /* @__PURE__ */ jsxRuntime.jsx(
2227
+ SkeletonLoaderItem,
2228
+ {
2229
+ width: "32%",
2230
+ height: 24,
2231
+ radius: 6,
2232
+ variant,
2233
+ speedSec,
2234
+ ariaLabel: "Loading page header"
2235
+ }
2236
+ ),
2237
+ /* @__PURE__ */ jsxRuntime.jsxs(
2238
+ "div",
2239
+ {
2240
+ style: { display: "flex", gap: 12, justifyContent: "flex-end", marginInlineStart: "auto" },
2241
+ children: [
2242
+ /* @__PURE__ */ jsxRuntime.jsx(
2243
+ SkeletonLoaderItem,
2244
+ {
2245
+ width: 110,
2246
+ height: 36,
2247
+ radius: 8,
2248
+ variant,
2249
+ speedSec,
2250
+ ariaLabel: "Loading action"
2251
+ }
2252
+ ),
2253
+ /* @__PURE__ */ jsxRuntime.jsx(
2254
+ SkeletonLoaderItem,
2255
+ {
2256
+ width: 96,
2257
+ height: 36,
2258
+ radius: 8,
2259
+ variant,
2260
+ speedSec,
2261
+ ariaLabel: "Loading action"
2262
+ }
2263
+ )
2264
+ ]
2265
+ }
2266
+ )
2267
+ ]
2537
2268
  }
2538
- };
2539
- }
2540
- var Input = React20.forwardRef(function Input2({
2541
- label,
2542
- error,
2543
- helpText,
2544
- orientation = "vertical",
2545
- labelWidth = "160px",
2546
- fullWidth = false,
2547
- required,
2548
- tooltip,
2549
- tooltipPlacement = "right",
2550
- modified = false,
2551
- icon,
2552
- autoFocus,
2553
- minWidth,
2554
- width,
2555
- maxWidth,
2556
- inputSize = "md",
2557
- variant = "outlined",
2558
- onClear,
2559
- onButtonClick,
2560
- buttonDisabled = false,
2561
- buttonLabel,
2562
- buttonIcon,
2563
- trailingLabel,
2564
- id,
2565
- tooltipOpenOnFocus = true,
2566
- style,
2567
- className,
2568
- fieldClassName,
2569
- inputClassName,
2570
- startAdornment,
2571
- endAdornment,
2572
- ...inputProps
2573
- }, ref) {
2574
- const inputRef = React20.useRef(null);
2575
- const reactId = React20.useId();
2576
- const inputId = id != null ? id : `input-${reactId}`;
2577
- React20.useEffect(() => {
2578
- var _a;
2579
- if (autoFocus) (_a = inputRef.current) == null ? void 0 : _a.focus();
2580
- }, [autoFocus]);
2581
- const hasButton = Boolean(onButtonClick || buttonLabel || buttonIcon);
2582
- const hasTrailingLabel = Boolean(trailingLabel);
2583
- const hasValue = Boolean(inputProps.value);
2584
- const hasVisibleClear = Boolean(onClear && hasValue);
2585
- const hasEndAdornment = Boolean(endAdornment);
2586
- const reservesInlineClearSlot = Boolean(onClear);
2587
- const hasInlineClear = Boolean(hasVisibleClear && hasEndAdornment);
2588
- const rootStyle = {
2589
- ...style != null ? style : {},
2590
- ...minWidth ? { ["--input-min-width"]: minWidth } : null,
2591
- ...width ? { ["--input-width"]: width } : null,
2592
- ...maxWidth ? { ["--input-max-width"]: maxWidth } : null
2593
- };
2594
- const { triggerProps } = useTooltipTrigger({
2595
- content: tooltip,
2596
- placement: tooltipPlacement,
2597
- offset: 8,
2598
- delayOpenMs: 0,
2599
- focusOpenMode: tooltipOpenOnFocus ? "any" : "focus-visible",
2600
- closeOnPointerDown: false
2601
- });
2602
- const trailingButtonVariant = variant === "outlined" || variant === "standalone" ? "outlined" : "default";
2603
- return /* @__PURE__ */ jsxRuntime.jsx(
2604
- InputContainer,
2605
- {
2606
- label,
2607
- labelAction: inputProps.labelAction,
2608
- htmlFor: inputId,
2609
- fullWidth,
2610
- error,
2611
- helpText,
2612
- orientation,
2613
- labelWidth,
2614
- required,
2615
- modified,
2616
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2617
- "div",
2618
- {
2619
- style: rootStyle,
2620
- className: [
2621
- Input_default.container,
2622
- fullWidth ? Input_default.fullWidth : "",
2623
- onClear ? Input_default.withClear : "",
2624
- hasInlineClear ? Input_default.withInlineClear : "",
2625
- hasButton ? Input_default.withButton : "",
2626
- hasTrailingLabel ? Input_default.withTrailingLabel : "",
2627
- className != null ? className : ""
2628
- ].filter(Boolean).join(" "),
2629
- children: [
2630
- /* @__PURE__ */ jsxRuntime.jsxs(
2631
- "div",
2632
- {
2633
- className: [
2634
- Input_default.field,
2635
- Input_default[variant],
2636
- icon ? Input_default.fieldWithIcon : "",
2637
- inputSize ? Input_default[inputSize] : "",
2638
- modified ? Input_default.modified : "",
2639
- fieldClassName != null ? fieldClassName : ""
2640
- ].filter(Boolean).join(" "),
2641
- "data-forminput": "field",
2642
- "data-modified": modified ? "true" : void 0,
2643
- "aria-disabled": inputProps.disabled ? "true" : void 0,
2644
- ...tooltip ? triggerProps : {},
2645
- children: [
2646
- icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Input_default.icon, "data-input-role": "icon", children: icon }),
2647
- startAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Input_default.startAdornment, "data-input-role": "start-adornment", children: startAdornment }),
2648
- /* @__PURE__ */ jsxRuntime.jsx(
2649
- "input",
2650
- {
2651
- ...inputProps,
2652
- id: inputId,
2653
- ref: mergeRefs2(inputRef, ref),
2654
- className: [Input_default.input, inputSize ? Input_default[inputSize] : "", inputClassName != null ? inputClassName : ""].filter(Boolean).join(" ")
2655
- }
2656
- ),
2657
- (reservesInlineClearSlot || hasEndAdornment) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: Input_default.endAdornment, "data-input-role": "end-adornment", children: [
2658
- reservesInlineClearSlot ? /* @__PURE__ */ jsxRuntime.jsx(
2659
- "span",
2660
- {
2661
- className: Input_default.clearSlot,
2662
- "aria-hidden": hasVisibleClear ? void 0 : "true",
2663
- children: hasVisibleClear && onClear ? /* @__PURE__ */ jsxRuntime.jsx(ClearButton, { onClick: onClear }) : null
2664
- }
2665
- ) : null,
2666
- endAdornment
2667
- ] }),
2668
- hasVisibleClear && !hasEndAdornment && onClear ? /* @__PURE__ */ jsxRuntime.jsx(ClearButton, { onClick: onClear, absolute: true }) : null
2669
- ]
2670
- }
2671
- ),
2672
- hasTrailingLabel && /* @__PURE__ */ jsxRuntime.jsx(
2673
- "span",
2269
+ );
2270
+ const getSkeletonItems = () => {
2271
+ switch (type) {
2272
+ case "button": {
2273
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2274
+ "div",
2275
+ {
2276
+ style: {
2277
+ display: "flex",
2278
+ gap: 12,
2279
+ alignItems: "center",
2280
+ justifyContent: "flex-start",
2281
+ width: "100%",
2282
+ flexWrap: "wrap"
2283
+ },
2284
+ children: [
2285
+ /* @__PURE__ */ jsxRuntime.jsx(
2286
+ SkeletonLoaderItem,
2287
+ {
2288
+ width: 120,
2289
+ height: 40,
2290
+ radius: 8,
2291
+ variant,
2292
+ speedSec,
2293
+ ariaLabel: "Loading button"
2294
+ }
2295
+ ),
2296
+ /* @__PURE__ */ jsxRuntime.jsx(
2297
+ SkeletonLoaderItem,
2298
+ {
2299
+ width: 96,
2300
+ height: 40,
2301
+ radius: 8,
2302
+ variant,
2303
+ speedSec,
2304
+ ariaLabel: "Loading button"
2305
+ }
2306
+ )
2307
+ ]
2308
+ }
2309
+ );
2310
+ }
2311
+ case "card": {
2312
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12, width: "100%" }, children: [
2313
+ /* @__PURE__ */ jsxRuntime.jsx(
2314
+ SkeletonLoaderItem,
2315
+ {
2316
+ width: "100%",
2317
+ height: 160,
2318
+ radius: 12,
2319
+ variant,
2320
+ speedSec,
2321
+ ariaLabel: "Loading card media"
2322
+ }
2323
+ ),
2324
+ line("60%", 16, 6),
2325
+ textBlock(3),
2326
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 12, justifyContent: "flex-start" }, children: [
2327
+ /* @__PURE__ */ jsxRuntime.jsx(
2328
+ SkeletonLoaderItem,
2674
2329
  {
2675
- className: [Input_default.trailingLabel, inputSize ? Input_default[inputSize] : ""].filter(Boolean).join(" "),
2676
- children: trailingLabel
2330
+ width: 100,
2331
+ height: 30,
2332
+ variant,
2333
+ speedSec,
2334
+ ariaLabel: "Loading action"
2677
2335
  }
2678
2336
  ),
2679
- hasButton && /* @__PURE__ */ jsxRuntime.jsxs(
2680
- Button,
2337
+ /* @__PURE__ */ jsxRuntime.jsx(
2338
+ SkeletonLoaderItem,
2681
2339
  {
2682
- onClick: onButtonClick,
2683
- disabled: buttonDisabled,
2684
- className: Input_default.trailingButton,
2685
- type: "button",
2686
- variant: trailingButtonVariant,
2687
- size: inputSize,
2688
- children: [
2689
- buttonIcon != null ? buttonIcon : null,
2690
- buttonLabel != null ? buttonLabel : null
2691
- ]
2340
+ width: 72,
2341
+ height: 30,
2342
+ variant,
2343
+ speedSec,
2344
+ ariaLabel: "Loading action"
2692
2345
  }
2693
2346
  )
2694
- ]
2695
- }
2696
- )
2347
+ ] })
2348
+ ] });
2349
+ }
2350
+ case "avatar": {
2351
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 12, alignItems: "center", width: "100%" }, children: [
2352
+ /* @__PURE__ */ jsxRuntime.jsx(
2353
+ SkeletonLoaderItem,
2354
+ {
2355
+ width: 48,
2356
+ height: 48,
2357
+ radius: "50%",
2358
+ variant,
2359
+ speedSec,
2360
+ ariaLabel: "Loading avatar"
2361
+ }
2362
+ ),
2363
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, flex: 1 }, children: [
2364
+ line("40%", 14),
2365
+ line("25%", 12)
2366
+ ] })
2367
+ ] });
2368
+ }
2369
+ case "text": {
2370
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 10, width: "100%" }, children: textBlock(resolvedRows) });
2371
+ }
2372
+ case "table": {
2373
+ return table();
2374
+ }
2375
+ case "filterbar": {
2376
+ return filterbar();
2377
+ }
2378
+ case "inputFieldList": {
2379
+ return inputFieldList(resolvedRows);
2380
+ }
2381
+ case "squares": {
2382
+ return squares();
2383
+ }
2384
+ case "dataPage": {
2385
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 24, width: "100%" }, children: [
2386
+ /* @__PURE__ */ jsxRuntime.jsx(
2387
+ "div",
2388
+ {
2389
+ style: {
2390
+ paddingBottom: 16,
2391
+ borderBottom: "var(--border-width-thin) solid var(--color-border-subtle)"
2392
+ },
2393
+ children: dataPageHeader()
2394
+ }
2395
+ ),
2396
+ table()
2397
+ ] });
2398
+ }
2399
+ default:
2400
+ return null;
2401
+ }
2402
+ };
2403
+ return /* @__PURE__ */ jsxRuntime.jsx(
2404
+ "div",
2405
+ {
2406
+ role: "status",
2407
+ "aria-label": "Loading content",
2408
+ style: {
2409
+ display: "flex",
2410
+ flexGrow: 1,
2411
+ flexDirection: "column",
2412
+ gap: 16,
2413
+ width: "100%",
2414
+ height: type === "squares" ? "100%" : void 0
2415
+ },
2416
+ children: getSkeletonItems()
2697
2417
  }
2698
2418
  );
2699
- });
2700
- Input.displayName = "Input";
2701
-
2702
- // src/components/search-box/SearchBox.module.css
2703
- var SearchBox_default = {
2704
- resultContainer: "SearchBox_resultContainer",
2705
- suggestionTable: "SearchBox_suggestionTable",
2706
- suggestionRow: "SearchBox_suggestionRow",
2707
- suggestionCell: "SearchBox_suggestionCell",
2708
- suggestionRowActive: "SearchBox_suggestionRowActive"
2419
+ }
2420
+ var TabsItem = (_props) => {
2421
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
2709
2422
  };
2710
- var SearchBox = React20.forwardRef(function SearchBoxInner({
2711
- inputWidth,
2712
- maxWidth,
2713
- inputSize,
2423
+ TabsItem.__TABS_SLOT__ = "Item";
2424
+ function getFirstEnabledId(items) {
2425
+ var _a;
2426
+ return (_a = items.find((t) => !t.hidden && !t.disabled)) == null ? void 0 : _a.id;
2427
+ }
2428
+ function normalizeFromChildren(children) {
2429
+ const items = [];
2430
+ React20.Children.forEach(children, (child) => {
2431
+ if (!React20.isValidElement(child)) return;
2432
+ const t = child.type;
2433
+ if ((t == null ? void 0 : t.__TABS_SLOT__) !== "Item") return;
2434
+ const props = child.props;
2435
+ items.push({
2436
+ id: props.id,
2437
+ header: props.header,
2438
+ headerIcon: props.headerIcon,
2439
+ disabled: props.disabled,
2440
+ hidden: props.hidden,
2441
+ badge: props.badge,
2442
+ content: props.children
2443
+ });
2444
+ });
2445
+ return items;
2446
+ }
2447
+ function Tabs({
2448
+ header,
2449
+ subheader,
2714
2450
  variant,
2715
- result,
2716
- debounce = true,
2717
- debounceMs = 800,
2718
- onSearch,
2719
- onSelect,
2720
- displayPopover,
2721
- resultKeys,
2722
- resultTemplate,
2723
- initialTemplate,
2724
- popoverMinWidth = "500px",
2725
- noResultText = "Ingen resultater",
2726
- loading,
2727
- enableHotkey = true,
2728
- onButtonClick,
2729
- buttonLabel,
2730
- buttonIcon,
2731
- fullWidth = false,
2451
+ panelStyle = false,
2452
+ tabs,
2732
2453
  value,
2733
- onChange,
2734
- ...rest
2735
- }, ref) {
2454
+ defaultValue,
2455
+ onValueChange,
2456
+ addition,
2457
+ disableTopPadding,
2458
+ loading = false,
2459
+ children
2460
+ }) {
2461
+ const uid = React20.useId();
2462
+ const sourceTabs = React20.useMemo(() => {
2463
+ if (tabs && tabs.length) return tabs;
2464
+ return normalizeFromChildren(children);
2465
+ }, [tabs, children]);
2466
+ const visibleTabs = React20.useMemo(() => sourceTabs.filter((t) => !t.hidden), [sourceTabs]);
2736
2467
  const isControlled = value !== void 0;
2737
- const [draft, setDraft] = React20.useState(() => isControlled ? String(value != null ? value : "") : "");
2738
- const [searchQuery, setSearchQuery] = React20.useState("");
2739
- const [activeIndex, setActiveIndex] = React20.useState(null);
2740
- const popoverRef = React20.useRef(null);
2741
- const internalInputRef = React20.useRef(null);
2742
- React20.useEffect(() => {
2743
- if (typeof ref === "function") {
2744
- ref(internalInputRef.current);
2745
- } else if (ref) {
2746
- ref.current = internalInputRef.current;
2747
- }
2748
- }, [ref]);
2749
- React20.useEffect(() => {
2750
- if (!isControlled) return;
2751
- const next = String(value != null ? value : "");
2752
- if (next !== draft) setDraft(next);
2753
- }, [value]);
2754
- React20.useEffect(() => {
2755
- if (!onSearch) return;
2756
- if (!debounce) {
2757
- setSearchQuery(draft);
2758
- onSearch(draft);
2759
- return;
2760
- }
2761
- const handler = setTimeout(() => {
2762
- setSearchQuery(draft);
2763
- onSearch(draft);
2764
- }, debounceMs);
2765
- return () => clearTimeout(handler);
2766
- }, [draft, onSearch, debounce, debounceMs]);
2468
+ const [internalValue, setInternalValue] = React20.useState(() => {
2469
+ return defaultValue != null ? defaultValue : getFirstEnabledId(visibleTabs);
2470
+ });
2471
+ const currentValue = isControlled ? value : internalValue;
2472
+ const activeIndex = React20.useMemo(() => {
2473
+ if (!visibleTabs.length) return -1;
2474
+ const idx = visibleTabs.findIndex((t) => t.id === currentValue);
2475
+ return idx >= 0 ? idx : 0;
2476
+ }, [visibleTabs, currentValue]);
2477
+ const activeTab = activeIndex >= 0 ? visibleTabs[activeIndex] : void 0;
2478
+ const setValue = React20.useCallback(
2479
+ (nextId) => {
2480
+ const idx = visibleTabs.findIndex((t) => t.id === nextId);
2481
+ const tab = idx >= 0 ? visibleTabs[idx] : void 0;
2482
+ if (!tab || tab.disabled) return;
2483
+ if (!isControlled) setInternalValue(nextId);
2484
+ onValueChange == null ? void 0 : onValueChange(nextId, tab, idx);
2485
+ },
2486
+ [visibleTabs, isControlled, onValueChange]
2487
+ );
2767
2488
  React20.useEffect(() => {
2768
- function handleKeyDown(event) {
2489
+ if (!visibleTabs.length) return;
2490
+ const current = currentValue;
2491
+ const stillValid = visibleTabs.some((t) => t.id === current && !t.disabled);
2492
+ if (stillValid) return;
2493
+ const next = getFirstEnabledId(visibleTabs);
2494
+ if (next === void 0) return;
2495
+ setValue(next);
2496
+ }, [visibleTabs, currentValue, setValue]);
2497
+ const onKeyDownTab = React20.useCallback(
2498
+ (e, index) => {
2769
2499
  var _a;
2770
- if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
2771
- event.preventDefault();
2772
- (_a = internalInputRef.current) == null ? void 0 : _a.focus();
2500
+ const enabled = visibleTabs.filter((t) => !t.disabled);
2501
+ if (!enabled.length) return;
2502
+ const currentId = (_a = visibleTabs[index]) == null ? void 0 : _a.id;
2503
+ const currentEnabledIndex = enabled.findIndex((t) => t.id === currentId);
2504
+ const focusAndSelect = (enabledIndex) => {
2505
+ const nextTab = enabled[enabledIndex];
2506
+ if (!nextTab) return;
2507
+ const btn = document.getElementById(
2508
+ `${uid}-tab-${String(nextTab.id)}`
2509
+ );
2510
+ btn == null ? void 0 : btn.focus();
2511
+ setValue(nextTab.id);
2512
+ };
2513
+ if (e.key === "ArrowRight") {
2514
+ e.preventDefault();
2515
+ focusAndSelect((currentEnabledIndex + 1) % enabled.length);
2516
+ } else if (e.key === "ArrowLeft") {
2517
+ e.preventDefault();
2518
+ focusAndSelect((currentEnabledIndex - 1 + enabled.length) % enabled.length);
2519
+ } else if (e.key === "Home") {
2520
+ e.preventDefault();
2521
+ focusAndSelect(0);
2522
+ } else if (e.key === "End") {
2523
+ e.preventDefault();
2524
+ focusAndSelect(enabled.length - 1);
2773
2525
  }
2774
- }
2775
- if (enableHotkey) {
2776
- window.addEventListener("keydown", handleKeyDown);
2777
- return () => window.removeEventListener("keydown", handleKeyDown);
2778
- }
2779
- }, [enableHotkey]);
2780
- const handleChange = React20__namespace.default.useCallback(
2781
- (e) => {
2782
- setDraft(e.target.value);
2783
- onChange == null ? void 0 : onChange(e);
2784
- },
2785
- [onChange]
2786
- );
2787
- const handleSelect = React20__namespace.default.useCallback(
2788
- (item) => {
2789
- onSelect == null ? void 0 : onSelect(item);
2790
- reset();
2791
2526
  },
2792
- [onSelect]
2527
+ [uid, visibleTabs, setValue]
2793
2528
  );
2794
- function reset() {
2795
- var _a;
2796
- setDraft("");
2797
- setSearchQuery("");
2798
- setActiveIndex(null);
2799
- (_a = popoverRef.current) == null ? void 0 : _a.close();
2800
- }
2801
- const handleClear = React20__namespace.default.useCallback(() => {
2802
- var _a;
2803
- reset();
2804
- onSearch == null ? void 0 : onSearch("");
2805
- (_a = internalInputRef.current) == null ? void 0 : _a.focus();
2806
- }, [onSearch]);
2807
- React20.useEffect(() => {
2808
- setActiveIndex(null);
2809
- }, [result]);
2810
- const inputField = React20.useMemo(() => {
2811
- var _a;
2812
- const inputProps = {
2813
- ...rest,
2814
- value: draft,
2815
- onChange: handleChange
2816
- };
2817
- const showInputIcon = !onButtonClick || !!buttonLabel || !!buttonIcon;
2818
- const trailingButtonIcon = onButtonClick && !buttonLabel && !buttonIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : buttonIcon;
2819
- if (displayPopover) {
2820
- return /* @__PURE__ */ jsxRuntime.jsx(
2821
- Popover,
2822
- {
2823
- ref: popoverRef,
2824
- minWidth: popoverMinWidth,
2825
- fullWidth,
2826
- trigger: (event) => {
2827
- var _a2;
2828
- return /* @__PURE__ */ jsxRuntime.jsx(
2829
- Input,
2830
- {
2831
- ref: internalInputRef,
2832
- onFocusCapture: event,
2833
- onClick: () => {
2834
- var _a3, _b;
2835
- if (!((_a3 = popoverRef.current) == null ? void 0 : _a3.isOpen())) (_b = popoverRef.current) == null ? void 0 : _b.open();
2836
- },
2837
- minWidth: fullWidth ? void 0 : inputWidth != null ? inputWidth : "300px",
2838
- width: fullWidth ? void 0 : inputWidth != null ? inputWidth : "300px",
2839
- fullWidth,
2840
- icon: showInputIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : void 0,
2841
- inputSize,
2842
- variant,
2843
- autoComplete: "off",
2844
- onClear: handleClear,
2845
- onButtonClick,
2846
- buttonLabel,
2847
- buttonIcon: trailingButtonIcon,
2848
- ...inputProps,
2849
- onKeyDown: (e) => {
2850
- var _a3;
2851
- if (result == null ? void 0 : result.length) {
2852
- if (e.key === "ArrowDown") {
2853
- e.preventDefault();
2854
- setActiveIndex(
2855
- (prev) => prev === null || prev === result.length - 1 ? 0 : prev + 1
2856
- );
2857
- } else if (e.key === "ArrowUp") {
2858
- e.preventDefault();
2859
- setActiveIndex(
2860
- (prev) => prev === null || prev === 0 ? result.length - 1 : prev - 1
2861
- );
2862
- } else if (e.key === "Enter") {
2863
- e.preventDefault();
2864
- if (activeIndex !== null) {
2865
- handleSelect(result[activeIndex]);
2866
- } else if (onButtonClick) {
2867
- onButtonClick();
2868
- }
2869
- } else if (e.key === "Escape") {
2870
- reset();
2871
- }
2872
- }
2873
- (_a3 = inputProps.onKeyDown) == null ? void 0 : _a3.call(inputProps, e);
2874
- },
2875
- placeholder: (_a2 = rest.placeholder) != null ? _a2 : "Indtast s\xF8geord"
2876
- }
2877
- );
2878
- },
2879
- children: resultTemplate ? resultTemplate : (result == null ? void 0 : result.length) ? /* @__PURE__ */ jsxRuntime.jsx(Menu, { children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: SearchBox_default.suggestionTable, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: result.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
2880
- "tr",
2881
- {
2882
- onClick: () => handleSelect(item),
2883
- role: "button",
2884
- tabIndex: 0,
2885
- className: `${SearchBox_default.suggestionRow}${index === activeIndex ? ` ${SearchBox_default.suggestionRowActive}` : ""}`,
2886
- children: resultKeys == null ? void 0 : resultKeys.map((key) => {
2887
- const raw = item[key];
2888
- const cell = raw != null ? String(raw) : "";
2889
- return /* @__PURE__ */ jsxRuntime.jsx(
2890
- "td",
2891
- {
2892
- className: SearchBox_default.suggestionCell,
2893
- style: { whiteSpace: cell.length < 10 ? "nowrap" : void 0 },
2894
- children: cell
2895
- },
2896
- key
2897
- );
2898
- })
2899
- },
2900
- index
2901
- )) }) }) }) : !searchQuery && !loading ? initialTemplate || /* @__PURE__ */ jsxRuntime.jsx("div", { className: SearchBox_default.resultContainer, children: "Indtast s\xF8geord" }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("table", { style: { width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("tr", { children: resultKeys == null ? void 0 : resultKeys.map((key) => /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "8px" }, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }, key)) }, index)) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: SearchBox_default.resultContainer, children: noResultText })
2902
- }
2903
- );
2904
- }
2905
- return /* @__PURE__ */ jsxRuntime.jsx(
2906
- Input,
2529
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Tabs_default.root, children: [
2530
+ header ? /* @__PURE__ */ jsxRuntime.jsx(
2531
+ "div",
2907
2532
  {
2908
- ref: internalInputRef,
2909
- icon: showInputIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : void 0,
2910
- minWidth: fullWidth ? void 0 : inputWidth != null ? inputWidth : "300px",
2911
- fullWidth,
2912
- inputSize,
2913
- variant,
2914
- onClear: handleClear,
2915
- onButtonClick,
2916
- buttonLabel,
2917
- buttonIcon: trailingButtonIcon,
2918
- ...inputProps,
2919
- placeholder: (_a = rest.placeholder) != null ? _a : "Indtast s\xF8geord"
2920
- }
2921
- );
2922
- }, [
2923
- rest,
2924
- draft,
2925
- handleChange,
2926
- handleClear,
2927
- displayPopover,
2928
- inputWidth,
2929
- inputSize,
2930
- variant,
2931
- popoverMinWidth,
2932
- resultTemplate,
2933
- result,
2934
- searchQuery,
2935
- loading,
2936
- initialTemplate,
2937
- noResultText,
2938
- resultKeys,
2939
- handleSelect,
2940
- activeIndex,
2941
- onButtonClick,
2942
- buttonLabel,
2943
- buttonIcon,
2944
- fullWidth
2945
- ]);
2946
- return /* @__PURE__ */ jsxRuntime.jsx(
2947
- "div",
2948
- {
2949
- style: {
2950
- ...fullWidth ? { width: "100%" } : void 0,
2951
- ...maxWidth !== void 0 ? { maxWidth } : void 0
2952
- },
2953
- children: inputField
2954
- }
2955
- );
2956
- });
2957
- var THEME_VARIANTS = ["light", "dark", "system"];
2958
- var STORAGE_KEY = "dbc_theme";
2959
- function isThemeVariant(x) {
2960
- return !!x && THEME_VARIANTS.includes(x);
2961
- }
2962
- function getCookie(name) {
2963
- const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
2964
- return match ? decodeURIComponent(match[1]) : null;
2965
- }
2966
- function persistTheme(id) {
2967
- try {
2968
- localStorage.setItem(STORAGE_KEY, id);
2969
- } catch {
2970
- console.error("Failed to access localStorage");
2971
- }
2972
- try {
2973
- document.cookie = `${STORAGE_KEY}=${encodeURIComponent(
2974
- id
2975
- )}; Path=/; Max-Age=${60 * 60 * 24 * 365}`;
2976
- } catch {
2977
- console.error("Failed to set theme cookie");
2978
- }
2979
- }
2980
- function getTheme() {
2981
- return document.documentElement.dataset.theme;
2982
- }
2983
- function applyTheme(id) {
2984
- document.documentElement.dataset.theme = id;
2985
- }
2986
- function useTheme(initialTheme = "system") {
2987
- const [theme, setTheme] = React20.useState(null);
2988
- React20.useEffect(() => {
2989
- const themeFromDataAttributes = getTheme();
2990
- let resolved = isThemeVariant(themeFromDataAttributes) ? themeFromDataAttributes : initialTheme;
2991
- const fromCookie = getCookie(STORAGE_KEY);
2992
- if (isThemeVariant(fromCookie)) {
2993
- resolved = fromCookie;
2994
- } else {
2995
- try {
2996
- const fromStorage = localStorage.getItem(STORAGE_KEY);
2997
- if (isThemeVariant(fromStorage)) resolved = fromStorage;
2998
- } catch {
2999
- console.error("Failed to access localStorage");
2533
+ className: [Tabs_default.headerContainer, disableTopPadding ? Tabs_default.disableTopPadding : ""].filter(Boolean).join(" "),
2534
+ children: /* @__PURE__ */ jsxRuntime.jsx(Headline, { disableMargin: true, size: 2, subheader, addition, children: header })
3000
2535
  }
3001
- }
3002
- applyTheme(resolved);
3003
- setTheme(resolved);
3004
- persistTheme(resolved);
3005
- }, [initialTheme]);
3006
- const switchTheme = React20.useCallback((id) => {
3007
- applyTheme(id);
3008
- setTheme(id);
3009
- persistTheme(id);
3010
- return id;
3011
- }, []);
3012
- return { theme, switchTheme };
2536
+ ) : null,
2537
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${Tabs_default.tabs} ${Tabs_default[variant]} ${panelStyle ? Tabs_default.panelStyle : ""}`, children: [
2538
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: Tabs_default.tabList, role: "tablist", "aria-label": header != null ? header : "Tabs", children: visibleTabs.map((tab, index) => {
2539
+ const selected = index === activeIndex;
2540
+ const tabDomId = `${uid}-tab-${String(tab.id)}`;
2541
+ const panelDomId = `${uid}-panel-${String(tab.id)}`;
2542
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Tabs_default.tab} ${selected ? Tabs_default.active : ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs(
2543
+ "button",
2544
+ {
2545
+ id: tabDomId,
2546
+ type: "button",
2547
+ className: Tabs_default.tabButton,
2548
+ role: "tab",
2549
+ "aria-selected": selected,
2550
+ "aria-controls": panelDomId,
2551
+ tabIndex: selected ? 0 : -1,
2552
+ disabled: tab.disabled,
2553
+ onClick: () => setValue(tab.id),
2554
+ onKeyDown: (e) => onKeyDownTab(e, index),
2555
+ children: [
2556
+ tab.headerIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: Tabs_default.icon, children: tab.headerIcon }) : null,
2557
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: Tabs_default.label, children: tab.header }),
2558
+ tab.badge ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: Tabs_default.badge, children: /* @__PURE__ */ jsxRuntime.jsx(Chip, { size: "sm", children: tab.badge.toLocaleString("da-DK") }) }) : null
2559
+ ]
2560
+ }
2561
+ ) }, tab.id);
2562
+ }) }),
2563
+ /* @__PURE__ */ jsxRuntime.jsx(
2564
+ "div",
2565
+ {
2566
+ id: activeTab ? `${uid}-panel-${String(activeTab.id)}` : void 0,
2567
+ role: "tabpanel",
2568
+ "aria-labelledby": activeTab ? `${uid}-tab-${String(activeTab.id)}` : void 0,
2569
+ className: Tabs_default.tabContent,
2570
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Tabs_default.loadingContent, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoader, { type: "squares", rows: 1, columns: 1 }) }) : activeTab == null ? void 0 : activeTab.content
2571
+ }
2572
+ )
2573
+ ] })
2574
+ ] });
3013
2575
  }
3014
-
3015
- // src/components/panel/Panel.module.css
3016
- var Panel_default = {
3017
- container: "Panel_container",
3018
- header: "Panel_header",
3019
- content: "Panel_content",
3020
- sm: "Panel_sm"
3021
- };
3022
- function Panel({
2576
+ Tabs.Item = TabsItem;
2577
+ function CollapsibleHeadline({
3023
2578
  header,
3024
- subheader,
3025
- headerIcon,
3026
- headerAddition,
2579
+ expanded,
2580
+ onToggle,
2581
+ controls,
2582
+ addition,
2583
+ storageKey,
3027
2584
  children,
3028
- severity,
3029
- size
2585
+ size = 2,
2586
+ variant = "muted",
2587
+ weight = 400,
2588
+ ...headlineProps
3030
2589
  }) {
3031
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: `${Panel_default.container} ${size ? Panel_default[size] : ""}`, children: [
3032
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: Panel_default.header, children: /* @__PURE__ */ jsxRuntime.jsx(
2590
+ const generatedId = React20.useId();
2591
+ const panelId = controls != null ? controls : generatedId;
2592
+ const [internalExpanded, setInternalExpanded] = React20.useState(() => {
2593
+ if (!storageKey || typeof window === "undefined") return expanded != null ? expanded : true;
2594
+ const stored = localStorage.getItem(storageKey);
2595
+ return stored !== null ? stored === "true" : expanded != null ? expanded : true;
2596
+ });
2597
+ const isExpanded = storageKey ? internalExpanded : expanded != null ? expanded : false;
2598
+ const handleToggle = () => {
2599
+ if (storageKey) {
2600
+ const next = !internalExpanded;
2601
+ setInternalExpanded(next);
2602
+ localStorage.setItem(storageKey, String(next));
2603
+ }
2604
+ onToggle == null ? void 0 : onToggle();
2605
+ };
2606
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Headline_default.collapsibleRoot, children: [
2607
+ /* @__PURE__ */ jsxRuntime.jsxs(
3033
2608
  Headline,
3034
2609
  {
3035
- disableMargin: true,
3036
- size: size === "sm" ? 4 : 3,
3037
- icon: headerIcon,
3038
- addition: headerAddition,
3039
- subheader,
3040
- severity,
3041
- children: header
2610
+ ...headlineProps,
2611
+ variant,
2612
+ weight,
2613
+ size,
2614
+ addition,
2615
+ children: [
2616
+ header,
2617
+ /* @__PURE__ */ jsxRuntime.jsx(
2618
+ Button,
2619
+ {
2620
+ shape: "round",
2621
+ type: "button",
2622
+ variant: "inline",
2623
+ "aria-expanded": isExpanded,
2624
+ "aria-controls": panelId,
2625
+ onClick: handleToggle,
2626
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2627
+ lucideReact.ChevronDown,
2628
+ {
2629
+ "aria-hidden": true,
2630
+ className: [Headline_default.toggleChevron, isExpanded ? Headline_default.toggleChevronExpanded : ""].filter(Boolean).join(" ")
2631
+ }
2632
+ )
2633
+ }
2634
+ )
2635
+ ]
3042
2636
  }
3043
- ) }),
3044
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: Panel_default.content, children })
2637
+ ),
2638
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsx("div", { id: panelId, className: Headline_default.collapsiblePanel, children })
3045
2639
  ] });
3046
2640
  }
3047
2641
 
3048
- // src/components/card/Card.module.css
3049
- var Card_default = {
3050
- outerContainer: "Card_outerContainer",
3051
- container: "Card_container",
3052
- variantDefault: "Card_variantDefault",
3053
- variantSubtle: "Card_variantSubtle",
3054
- sm: "Card_sm",
3055
- md: "Card_md",
3056
- content: "Card_content",
3057
- lg: "Card_lg",
3058
- inner: "Card_inner",
3059
- innerImgLeft: "Card_innerImgLeft",
3060
- innerImgRight: "Card_innerImgRight",
3061
- innerImgTop: "Card_innerImgTop",
3062
- media: "Card_media",
3063
- header: "Card_header",
3064
- headerMeta: "Card_headerMeta",
3065
- body: "Card_body",
3066
- actions: "Card_actions",
3067
- section: "Card_section",
3068
- sectionDivider: "Card_sectionDivider",
3069
- sectionTitle: "Card_sectionTitle",
3070
- loadingList: "Card_loadingList",
3071
- loadingRow: "Card_loadingRow"
3072
- };
3073
-
3074
- // src/components/card/components/CardMeta.module.css
3075
- var CardMeta_default = {
3076
- grid: "CardMeta_grid",
3077
- cols1: "CardMeta_cols1",
3078
- cols2: "CardMeta_cols2",
3079
- cols3: "CardMeta_cols3",
3080
- row: "CardMeta_row",
3081
- label: "CardMeta_label",
3082
- value: "CardMeta_value",
3083
- valueBold: "CardMeta_valueBold",
3084
- nowrap: "CardMeta_nowrap"
3085
- };
3086
- function getColsClass(columns) {
3087
- switch (columns) {
3088
- case 1:
3089
- return CardMeta_default.cols1;
3090
- case 3:
3091
- return CardMeta_default.cols3;
3092
- case 2:
3093
- default:
3094
- return CardMeta_default.cols2;
3095
- }
2642
+ // src/components/page-layout/PageLayout.module.css
2643
+ var PageLayout_default = {
2644
+ root: "PageLayout_root",
2645
+ containScrolling: "PageLayout_containScrolling",
2646
+ documentScrolling: "PageLayout_documentScrolling",
2647
+ vertical: "PageLayout_vertical",
2648
+ horizontal: "PageLayout_horizontal",
2649
+ sidebar: "PageLayout_sidebar",
2650
+ mainColumn: "PageLayout_mainColumn",
2651
+ header: "PageLayout_header",
2652
+ hero: "PageLayout_hero",
2653
+ mainScroll: "PageLayout_mainScroll",
2654
+ content: "PageLayout_content",
2655
+ footer: "PageLayout_footer",
2656
+ headerContainer: "PageLayout_headerContainer",
2657
+ headerContent: "PageLayout_headerContent",
2658
+ footerContent: "PageLayout_footerContent",
2659
+ maxWidthMd: "PageLayout_maxWidthMd",
2660
+ maxWidthSm: "PageLayout_maxWidthSm",
2661
+ contentInner: "PageLayout_contentInner"
2662
+ };
2663
+ function getMaxWidthClass(value, styles) {
2664
+ if (!value) return "";
2665
+ if (value === "sm") return styles.maxWidthSm;
2666
+ return styles.maxWidthMd;
3096
2667
  }
3097
- function CardMeta({
3098
- columns = 2,
3099
- className,
3100
- children,
3101
- ...rest
3102
- }) {
3103
- const colsClass = getColsClass(columns);
3104
- return /* @__PURE__ */ jsxRuntime.jsx("dl", { ...rest, className: [CardMeta_default.grid, colsClass, className].filter(Boolean).join(" "), children });
2668
+ function getSlotName(el) {
2669
+ var _a;
2670
+ const t = el.type;
2671
+ return (_a = t == null ? void 0 : t.__PAGE_LAYOUT_SLOT__) != null ? _a : null;
3105
2672
  }
3106
- function CardMetaRow({
3107
- label,
3108
- value,
3109
- className,
3110
- nowrapValue,
3111
- labelWidth,
3112
- boldValue = false
3113
- }) {
3114
- return /* @__PURE__ */ jsxRuntime.jsxs(
3115
- "div",
3116
- {
3117
- className: [CardMeta_default.row, className].filter(Boolean).join(" "),
3118
- style: labelWidth ? { ["--label-width"]: labelWidth } : void 0,
3119
- children: [
3120
- /* @__PURE__ */ jsxRuntime.jsx("dt", { className: CardMeta_default.label, children: label }),
3121
- /* @__PURE__ */ jsxRuntime.jsx(
3122
- "dd",
3123
- {
3124
- className: [
3125
- CardMeta_default.value,
3126
- !boldValue ? CardMeta_default.valueRegular : CardMeta_default.valueBold,
3127
- nowrapValue ? CardMeta_default.nowrap : ""
3128
- ].filter(Boolean).join(" "),
3129
- children: value
3130
- }
3131
- )
3132
- ]
2673
+ function splitSlots(children) {
2674
+ const slots = {};
2675
+ const rest = [];
2676
+ React20.Children.forEach(children, (child) => {
2677
+ if (!React20.isValidElement(child)) {
2678
+ if (child != null) rest.push(child);
2679
+ return;
3133
2680
  }
3134
- );
3135
- }
3136
- function getGapShare(width) {
3137
- switch (width) {
3138
- case 25:
3139
- return "calc(var(--card-container-gap, var(--spacing-md)) * 3 / 4)";
3140
- case 33:
3141
- return "calc(var(--card-container-gap, var(--spacing-md)) * 2 / 3)";
3142
- case 50:
3143
- return "calc(var(--card-container-gap, var(--spacing-md)) / 2)";
3144
- case 66:
3145
- return "calc(var(--card-container-gap, var(--spacing-md)) * 2 / 3)";
3146
- case 75:
3147
- return "calc(var(--card-container-gap, var(--spacing-md)) * 3 / 4)";
3148
- case 100:
3149
- default:
3150
- return "0px";
3151
- }
3152
- }
3153
- function getInnerPlacementClass(imgPlacement, s) {
3154
- switch (imgPlacement) {
3155
- case "top":
3156
- return s.innerImgTop;
3157
- case "right":
3158
- return s.innerImgRight;
3159
- case "left":
3160
- default:
3161
- return s.innerImgLeft;
3162
- }
3163
- }
3164
- function getVariantClass(variant, s) {
3165
- switch (variant) {
3166
- case "subtle":
3167
- return s.variantSubtle;
3168
- case "default":
3169
- default:
3170
- return s.variantDefault;
3171
- }
2681
+ const slot = getSlotName(child);
2682
+ if (!slot) {
2683
+ rest.push(child);
2684
+ return;
2685
+ }
2686
+ slots[slot] = child;
2687
+ });
2688
+ return { slots, rest };
3172
2689
  }
3173
- function CardImpl({
3174
- title,
3175
- subheader,
3176
- loading = false,
3177
- variant = "default",
3178
- size = "md",
3179
- headerMarker = true,
3180
- headerIcon,
3181
- headerAddition,
3182
- severity,
3183
- image,
3184
- imgPlacement = "left",
3185
- mediaWidth,
3186
- actions,
3187
- headerMeta,
3188
- sectionTitle,
3189
- showSectionDivider = false,
2690
+ var PageLayoutSidebar = ({
2691
+ children
2692
+ }) => {
2693
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
2694
+ };
2695
+ PageLayoutSidebar.__PAGE_LAYOUT_SLOT__ = "Sidebar";
2696
+ var PageLayoutHeader = ({
2697
+ maxWidth = false,
2698
+ children
2699
+ }) => {
2700
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayout_default.headerContainer, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayout_default.headerContent} ${getMaxWidthClass(maxWidth, PageLayout_default)}`, children }) });
2701
+ };
2702
+ PageLayoutHeader.__PAGE_LAYOUT_SLOT__ = "Header";
2703
+ var PageLayoutContent = ({
2704
+ maxWidth = false,
2705
+ children
2706
+ }) => {
2707
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayout_default.contentInner} ${getMaxWidthClass(maxWidth, PageLayout_default)}`, children });
2708
+ };
2709
+ PageLayoutContent.__PAGE_LAYOUT_SLOT__ = "Content";
2710
+ var PageLayoutFooter = ({
2711
+ maxWidth = false,
2712
+ children
2713
+ }) => {
2714
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${PageLayout_default.footerContent} ${getMaxWidthClass(maxWidth, PageLayout_default)}`, children });
2715
+ };
2716
+ PageLayoutFooter.__PAGE_LAYOUT_SLOT__ = "Footer";
2717
+ var PageLayoutBase = ({
3190
2718
  children,
3191
- link,
3192
- width,
3193
- headlineSize = 4
3194
- }) {
3195
- const outerStyle = width ? {
3196
- ["--width"]: `${width}%`,
3197
- ["--gap-share"]: getGapShare(width)
3198
- } : void 0;
3199
- const mediaStyle = mediaWidth ? { ["--card-media-width"]: `${mediaWidth}px` } : void 0;
3200
- const innerPlacementClass = getInnerPlacementClass(imgPlacement, Card_default);
3201
- const variantClass = getVariantClass(variant, Card_default);
3202
- const hasHeader = !!title || !!headerMeta;
3203
- const showSection = !loading && (showSectionDivider || !!sectionTitle);
3204
- const showBody = !loading && !!children;
3205
- const showActions = !loading && !!actions;
3206
- const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${Card_default.inner} ${innerPlacementClass}`, children: [
3207
- image ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.media, style: mediaStyle, children: image }) : null,
3208
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Card_default.content, children: [
3209
- hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs("header", { className: Card_default.header, children: [
3210
- title ? /* @__PURE__ */ jsxRuntime.jsx(
3211
- Headline,
3212
- {
3213
- severity,
3214
- marker: headerMarker,
3215
- icon: headerIcon,
3216
- addition: headerAddition,
3217
- subheader,
3218
- size: headlineSize,
3219
- weight: 500,
3220
- disableMargin: true,
3221
- children: title
3222
- }
3223
- ) : null,
3224
- headerMeta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.headerMeta, children: headerMeta }) : null
3225
- ] }) : null,
3226
- loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.loadingList, "aria-busy": "true", "aria-live": "polite", children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Card_default.loadingRow, children: [
3227
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, {}),
3228
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { width: "100%" })
3229
- ] }, index)) }) : null,
3230
- showSection ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Card_default.section, children: [
3231
- showSectionDivider ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.sectionDivider }) : null,
3232
- sectionTitle ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.sectionTitle, children: sectionTitle }) : null
3233
- ] }) : null,
3234
- showBody ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.body, children }) : null,
3235
- showActions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.actions, children: actions }) : null
2719
+ containScrolling = false,
2720
+ orientation = "vertical"
2721
+ }) => {
2722
+ var _a, _b;
2723
+ const { slots, rest } = splitSlots(children);
2724
+ const content = (_a = slots.Content) != null ? _a : rest.length ? /* @__PURE__ */ jsxRuntime.jsx(PageLayoutContent, { maxWidth: "md", children: rest }) : void 0;
2725
+ const rootClass = [
2726
+ PageLayout_default.root,
2727
+ orientation === "vertical" ? PageLayout_default.vertical : PageLayout_default.horizontal,
2728
+ containScrolling ? PageLayout_default.containScrolling : PageLayout_default.documentScrolling
2729
+ ].filter(Boolean).join(" ");
2730
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: rootClass, children: [
2731
+ slots.Sidebar ? /* @__PURE__ */ jsxRuntime.jsx("aside", { className: PageLayout_default.sidebar, "aria-label": (_b = slots.Sidebar.props) == null ? void 0 : _b.ariaLabel, children: slots.Sidebar }) : null,
2732
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: PageLayout_default.mainColumn, children: [
2733
+ slots.Header ? /* @__PURE__ */ jsxRuntime.jsx("header", { className: PageLayout_default.header, children: slots.Header }) : null,
2734
+ slots.Hero ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: PageLayout_default.hero, children: slots.Hero }) : null,
2735
+ content || slots.Footer ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: PageLayout_default.mainScroll, children: [
2736
+ content ? /* @__PURE__ */ jsxRuntime.jsx("main", { className: PageLayout_default.content, children: content }) : null,
2737
+ slots.Footer ? /* @__PURE__ */ jsxRuntime.jsx("footer", { className: PageLayout_default.footer, children: slots.Footer }) : null
2738
+ ] }) : null
3236
2739
  ] })
3237
2740
  ] });
3238
- const cardContent = link ? /* @__PURE__ */ jsxRuntime.jsx(Hyperlink, { children: link }) : inner;
3239
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Card_default.outerContainer} ${Card_default[size]}`, style: outerStyle, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Card_default.container} ${variantClass}`, children: cardContent }) });
3240
- }
3241
- var Card = Object.assign(CardImpl, {
3242
- Meta: CardMeta,
3243
- MetaRow: CardMetaRow
2741
+ };
2742
+ var PageLayout = Object.assign(PageLayoutBase, {
2743
+ Sidebar: PageLayoutSidebar,
2744
+ Header: PageLayoutHeader,
2745
+ Content: PageLayoutContent,
2746
+ Footer: PageLayoutFooter
3244
2747
  });
3245
2748
 
3246
- // src/components/card-container/CardContainer.module.css
3247
- var CardContainer_default = {
3248
- wrapper: "CardContainer_wrapper",
3249
- container: "CardContainer_container"};
3250
- function CardContainer({
3251
- children,
3252
- headline,
3253
- subheader,
3254
- expand,
3255
- severity,
3256
- displayHeaderMarker
3257
- }) {
3258
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: CardContainer_default.wrapper, children: [
3259
- headline && /* @__PURE__ */ jsxRuntime.jsx(
3260
- Headline,
3261
- {
3262
- marker: displayHeaderMarker,
3263
- severity,
3264
- disableMargin: true,
3265
- subheader,
3266
- children: headline
3267
- }
3268
- ),
3269
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: CardContainer_default.container, style: { ["--expand"]: expand ? "1" : "0" }, children })
2749
+ // src/components/hyperlink/Hyperlink.module.css
2750
+ var Hyperlink_default = {
2751
+ link: "Hyperlink_link",
2752
+ secondary: "Hyperlink_secondary",
2753
+ primary: "Hyperlink_primary",
2754
+ block: "Hyperlink_block",
2755
+ content: "Hyperlink_content",
2756
+ icon: "Hyperlink_icon"
2757
+ };
2758
+ function cx2(...parts) {
2759
+ return parts.filter(Boolean).join(" ");
2760
+ }
2761
+ function renderInner(children, icon) {
2762
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2763
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: Hyperlink_default.content, children }),
2764
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Hyperlink_default.icon, children: icon })
3270
2765
  ] });
3271
2766
  }
3272
- function SkeletonLoader({
3273
- type,
3274
- rows = 3,
3275
- columns = 3,
3276
- variant = "default",
3277
- speedSec = 3
3278
- }) {
3279
- const line = (width, height = 14, radius = 6) => /* @__PURE__ */ jsxRuntime.jsx(
3280
- SkeletonLoaderItem,
3281
- {
3282
- width,
3283
- height,
3284
- radius,
3285
- variant,
3286
- speedSec
3287
- },
3288
- `${String(width)}-${height}-${String(radius)}-${Math.random()}`
2767
+ function Hyperlink(props) {
2768
+ var _a;
2769
+ const {
2770
+ children,
2771
+ icon,
2772
+ className,
2773
+ asChild,
2774
+ as = "a",
2775
+ variant = "primary",
2776
+ inline = true,
2777
+ ...rest
2778
+ } = props;
2779
+ const linkClassName = cx2(
2780
+ Hyperlink_default.link,
2781
+ className,
2782
+ variant === "secondary" ? Hyperlink_default.secondary : Hyperlink_default.primary,
2783
+ inline ? "" : Hyperlink_default.block
3289
2784
  );
3290
- const pills = (count) => Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
3291
- SkeletonLoaderItem,
3292
- {
3293
- width: 80 + i % 3 * 30,
3294
- height: 30,
3295
- radius: 6,
3296
- variant,
3297
- speedSec,
3298
- ariaLabel: "Loading filter"
3299
- },
3300
- `pill-${i}`
3301
- ));
3302
- const textBlock = (count) => Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
3303
- SkeletonLoaderItem,
3304
- {
3305
- width: i === count - 1 ? "60%" : `${90 - i % 3 * 10}%`,
3306
- height: 12,
3307
- radius: 4,
3308
- variant,
3309
- speedSec,
3310
- ariaLabel: "Loading text line"
3311
- },
3312
- `text-${i}`
3313
- ));
3314
- const tableHeaderRow = () => /* @__PURE__ */ jsxRuntime.jsx(
3315
- "div",
2785
+ if (asChild) {
2786
+ const child = React20__namespace.Children.only(children);
2787
+ if (!React20__namespace.isValidElement(child)) {
2788
+ throw new Error("Hyperlink with asChild expects a single valid React element as its child.");
2789
+ }
2790
+ const childProps = (_a = child.props) != null ? _a : {};
2791
+ return React20__namespace.cloneElement(child, {
2792
+ ...childProps,
2793
+ ...rest,
2794
+ className: cx2(childProps.className, linkClassName),
2795
+ children: renderInner(childProps.children, icon),
2796
+ onClick: (e) => {
2797
+ e.stopPropagation();
2798
+ if (childProps.onClick) {
2799
+ childProps.onClick(e);
2800
+ }
2801
+ }
2802
+ });
2803
+ }
2804
+ if (as === "button") {
2805
+ return /* @__PURE__ */ jsxRuntime.jsx(
2806
+ "button",
2807
+ {
2808
+ type: "button",
2809
+ className: linkClassName,
2810
+ ...rest,
2811
+ children: renderInner(children, icon)
2812
+ }
2813
+ );
2814
+ }
2815
+ return /* @__PURE__ */ jsxRuntime.jsx(
2816
+ "a",
3316
2817
  {
3317
- style: {
3318
- display: "grid",
3319
- gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
3320
- gap: 12,
3321
- alignItems: "center",
3322
- width: "100%"
3323
- },
3324
- children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
3325
- SkeletonLoaderItem,
3326
- {
3327
- height: 20,
3328
- width: "90%",
3329
- radius: 6,
3330
- variant,
3331
- speedSec,
3332
- ariaLabel: "Loading table header"
3333
- },
3334
- `thead-${i}`
3335
- ))
2818
+ onClick: (e) => e.stopPropagation(),
2819
+ className: linkClassName,
2820
+ ...rest,
2821
+ children: renderInner(children, icon)
3336
2822
  }
3337
2823
  );
3338
- const tableBodyRow = (rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
3339
- "div",
2824
+ }
2825
+
2826
+ // src/components/page-layout/components/layout-footer/LayoutFooter.module.css
2827
+ var LayoutFooter_default = {
2828
+ footer: "LayoutFooter_footer",
2829
+ inner: "LayoutFooter_inner",
2830
+ brand: "LayoutFooter_brand",
2831
+ logoRow: "LayoutFooter_logoRow",
2832
+ meta: "LayoutFooter_meta",
2833
+ part: "LayoutFooter_part",
2834
+ links: "LayoutFooter_links"};
2835
+ var DEFAULT_META_PARTS = [
2836
+ "Tempovej 7-11",
2837
+ "DK-2750 Ballerup",
2838
+ "+45 44 86 77 11",
2839
+ `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} DBC DIGITAL A/S`
2840
+ ];
2841
+ var DEFAULT_LINKS = [
2842
+ {
2843
+ label: "Kundeservice",
2844
+ href: "https://kundeservice.dbc.dk",
2845
+ external: true
2846
+ },
2847
+ {
2848
+ label: "Cookies",
2849
+ href: "/cookies"
2850
+ }
2851
+ ];
2852
+ function LayoutFooter({
2853
+ links = DEFAULT_LINKS,
2854
+ metaParts = DEFAULT_META_PARTS,
2855
+ extraLinks
2856
+ }) {
2857
+ return /* @__PURE__ */ jsxRuntime.jsx("footer", { className: LayoutFooter_default.footer, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: LayoutFooter_default.inner, children: [
2858
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: LayoutFooter_default.brand, children: [
2859
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: LayoutFooter_default.logoRow, children: /* @__PURE__ */ jsxRuntime.jsx(Logo, {}) }),
2860
+ /* @__PURE__ */ jsxRuntime.jsx("address", { className: LayoutFooter_default.meta, children: metaParts.map((part) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: LayoutFooter_default.part, children: part }, part)) })
2861
+ ] }),
2862
+ /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: LayoutFooter_default.links, "aria-label": "Footer navigation", children: [
2863
+ extraLinks && extraLinks.length > 0 && (extraLinks == null ? void 0 : extraLinks.map((link, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: link }, index))),
2864
+ links.map((link) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: /* @__PURE__ */ jsxRuntime.jsx(
2865
+ Hyperlink,
2866
+ {
2867
+ href: link.href,
2868
+ ...link.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
2869
+ children: link.label
2870
+ }
2871
+ ) }, link.label))
2872
+ ] })
2873
+ ] }) });
2874
+ }
2875
+
2876
+ // src/components/clear-button/ClearButton.module.css
2877
+ var ClearButton_default = {
2878
+ clearButton: "ClearButton_clearButton",
2879
+ button: "ClearButton_button",
2880
+ absolute: "ClearButton_absolute"
2881
+ };
2882
+ function ClearButton({ onClick, absolute }) {
2883
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${ClearButton_default.clearButton} ${absolute ? ClearButton_default.absolute : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(
2884
+ "button",
3340
2885
  {
3341
- style: {
3342
- display: "grid",
3343
- gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
3344
- gap: 12,
3345
- alignItems: "center",
3346
- width: "100%"
2886
+ className: ClearButton_default.button,
2887
+ type: "button",
2888
+ "data-input-role": "clear",
2889
+ onMouseDown: (e) => {
2890
+ e.preventDefault();
2891
+ e.stopPropagation();
3347
2892
  },
3348
- children: Array.from({ length: columns }).map((_, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
3349
- SkeletonLoaderItem,
3350
- {
3351
- height: 20,
3352
- width: colIndex % 3 === 0 ? "93%" : colIndex % 3 === 1 ? "98%" : "90%",
3353
- radius: 4,
3354
- variant,
3355
- speedSec,
3356
- ariaLabel: "Loading table cell"
3357
- },
3358
- `tcell-${rowIndex}-${colIndex}`
3359
- ))
3360
- },
3361
- `trow-${rowIndex}`
3362
- );
3363
- const inputFieldRow = (i) => {
3364
- const labelW = i % 3 === 0 ? "34%" : i % 3 === 1 ? "42%" : "28%";
3365
- return /* @__PURE__ */ jsxRuntime.jsxs(
3366
- "div",
3367
- {
3368
- style: { display: "flex", flexDirection: "column", gap: 8, width: "100%" },
3369
- children: [
3370
- /* @__PURE__ */ jsxRuntime.jsx(
3371
- "div",
3372
- {
3373
- style: {
3374
- display: "flex",
3375
- alignItems: "center",
3376
- justifyContent: "space-between",
3377
- gap: 12
3378
- },
3379
- children: /* @__PURE__ */ jsxRuntime.jsx(
3380
- SkeletonLoaderItem,
3381
- {
3382
- width: labelW,
3383
- height: 10,
3384
- radius: 4,
3385
- variant,
3386
- speedSec,
3387
- ariaLabel: "Loading label"
3388
- }
3389
- )
3390
- }
3391
- ),
3392
- /* @__PURE__ */ jsxRuntime.jsx(
3393
- SkeletonLoaderItem,
3394
- {
3395
- width: "100%",
3396
- height: 25,
3397
- radius: 8,
3398
- variant,
3399
- speedSec,
3400
- ariaLabel: "Loading input"
3401
- }
3402
- )
3403
- ]
2893
+ onClick: (e) => {
2894
+ e.preventDefault();
2895
+ e.stopPropagation();
2896
+ onClick == null ? void 0 : onClick(e);
3404
2897
  },
3405
- `if-${i}`
3406
- );
2898
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 16 })
2899
+ }
2900
+ ) });
2901
+ }
2902
+
2903
+ // src/components/forms/input/Input.module.css
2904
+ var Input_default = {
2905
+ container: "Input_container",
2906
+ fullWidth: "Input_fullWidth",
2907
+ field: "Input_field",
2908
+ input: "Input_input",
2909
+ withButton: "Input_withButton",
2910
+ withClear: "Input_withClear",
2911
+ withInlineClear: "Input_withInlineClear",
2912
+ outlined: "Input_outlined",
2913
+ surface: "Input_surface",
2914
+ subtle: "Input_subtle",
2915
+ embedded: "Input_embedded",
2916
+ standalone: "Input_standalone",
2917
+ modified: "Input_modified",
2918
+ xs: "Input_xs",
2919
+ sm: "Input_sm",
2920
+ md: "Input_md",
2921
+ lg: "Input_lg",
2922
+ fieldWithIcon: "Input_fieldWithIcon",
2923
+ icon: "Input_icon",
2924
+ withTrailingLabel: "Input_withTrailingLabel",
2925
+ trailingLabel: "Input_trailingLabel",
2926
+ trailingButton: "Input_trailingButton",
2927
+ startAdornment: "Input_startAdornment",
2928
+ endAdornment: "Input_endAdornment",
2929
+ clearSlot: "Input_clearSlot"
2930
+ };
2931
+ function mergeRefs2(...refs) {
2932
+ return (node) => {
2933
+ for (const ref of refs) {
2934
+ if (!ref) continue;
2935
+ if (typeof ref === "function") ref(node);
2936
+ else ref.current = node;
2937
+ }
3407
2938
  };
3408
- const inputFieldList = (count) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 16, width: "100%" }, children: [
3409
- Array.from({ length: count }).map((_, i) => inputFieldRow(i)),
3410
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 12, justifyContent: "flex-end", marginTop: 8 }, children: [
3411
- /* @__PURE__ */ jsxRuntime.jsx(
3412
- SkeletonLoaderItem,
3413
- {
3414
- width: 110,
3415
- height: 30,
3416
- radius: 8,
3417
- variant,
3418
- speedSec,
3419
- ariaLabel: "Loading action"
3420
- }
3421
- ),
3422
- /* @__PURE__ */ jsxRuntime.jsx(
3423
- SkeletonLoaderItem,
2939
+ }
2940
+ var Input = React20.forwardRef(function Input2({
2941
+ label,
2942
+ error,
2943
+ helpText,
2944
+ orientation = "vertical",
2945
+ labelWidth = "160px",
2946
+ fullWidth = false,
2947
+ required,
2948
+ tooltip,
2949
+ tooltipPlacement = "right",
2950
+ modified = false,
2951
+ icon,
2952
+ autoFocus,
2953
+ minWidth,
2954
+ width,
2955
+ maxWidth,
2956
+ inputSize = "md",
2957
+ variant = "outlined",
2958
+ onClear,
2959
+ onButtonClick,
2960
+ buttonDisabled = false,
2961
+ buttonLabel,
2962
+ buttonIcon,
2963
+ trailingLabel,
2964
+ id,
2965
+ tooltipOpenOnFocus = true,
2966
+ style,
2967
+ className,
2968
+ fieldClassName,
2969
+ inputClassName,
2970
+ startAdornment,
2971
+ endAdornment,
2972
+ ...inputProps
2973
+ }, ref) {
2974
+ const inputRef = React20.useRef(null);
2975
+ const reactId = React20.useId();
2976
+ const inputId = id != null ? id : `input-${reactId}`;
2977
+ React20.useEffect(() => {
2978
+ var _a;
2979
+ if (autoFocus) (_a = inputRef.current) == null ? void 0 : _a.focus();
2980
+ }, [autoFocus]);
2981
+ const hasButton = Boolean(onButtonClick || buttonLabel || buttonIcon);
2982
+ const hasTrailingLabel = Boolean(trailingLabel);
2983
+ const hasValue = Boolean(inputProps.value);
2984
+ const hasVisibleClear = Boolean(onClear && hasValue);
2985
+ const hasEndAdornment = Boolean(endAdornment);
2986
+ const reservesInlineClearSlot = Boolean(onClear);
2987
+ const hasInlineClear = Boolean(hasVisibleClear && hasEndAdornment);
2988
+ const rootStyle = {
2989
+ ...style != null ? style : {},
2990
+ ...minWidth ? { ["--input-min-width"]: minWidth } : null,
2991
+ ...width ? { ["--input-width"]: width } : null,
2992
+ ...maxWidth ? { ["--input-max-width"]: maxWidth } : null
2993
+ };
2994
+ const { triggerProps } = useTooltipTrigger({
2995
+ content: tooltip,
2996
+ placement: tooltipPlacement,
2997
+ offset: 8,
2998
+ delayOpenMs: 0,
2999
+ focusOpenMode: tooltipOpenOnFocus ? "any" : "focus-visible",
3000
+ closeOnPointerDown: false
3001
+ });
3002
+ const trailingButtonVariant = variant === "outlined" || variant === "standalone" ? "outlined" : "default";
3003
+ return /* @__PURE__ */ jsxRuntime.jsx(
3004
+ InputContainer,
3005
+ {
3006
+ label,
3007
+ labelAction: inputProps.labelAction,
3008
+ htmlFor: inputId,
3009
+ fullWidth,
3010
+ error,
3011
+ helpText,
3012
+ orientation,
3013
+ labelWidth,
3014
+ required,
3015
+ modified,
3016
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
3017
+ "div",
3424
3018
  {
3425
- width: 90,
3426
- height: 30,
3427
- radius: 8,
3428
- variant,
3429
- speedSec,
3430
- ariaLabel: "Loading action"
3431
- }
3432
- )
3433
- ] })
3434
- ] });
3435
- const getSkeletonItems = () => {
3436
- switch (type) {
3437
- case "button": {
3438
- return /* @__PURE__ */ jsxRuntime.jsxs(
3439
- "div",
3440
- {
3441
- style: {
3442
- display: "flex",
3443
- gap: 12,
3444
- alignItems: "center",
3445
- justifyContent: "flex-start",
3446
- width: "100%",
3447
- flexWrap: "wrap"
3448
- },
3449
- children: [
3450
- /* @__PURE__ */ jsxRuntime.jsx(
3451
- SkeletonLoaderItem,
3452
- {
3453
- width: 120,
3454
- height: 40,
3455
- radius: 8,
3456
- variant,
3457
- speedSec,
3458
- ariaLabel: "Loading button"
3459
- }
3460
- ),
3461
- /* @__PURE__ */ jsxRuntime.jsx(
3462
- SkeletonLoaderItem,
3463
- {
3464
- width: 96,
3465
- height: 40,
3466
- radius: 8,
3467
- variant,
3468
- speedSec,
3469
- ariaLabel: "Loading button"
3470
- }
3471
- )
3472
- ]
3473
- }
3474
- );
3475
- }
3476
- case "card": {
3477
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12, width: "100%" }, children: [
3478
- /* @__PURE__ */ jsxRuntime.jsx(
3479
- SkeletonLoaderItem,
3480
- {
3481
- width: "100%",
3482
- height: 160,
3483
- radius: 12,
3484
- variant,
3485
- speedSec,
3486
- ariaLabel: "Loading card media"
3487
- }
3488
- ),
3489
- line("60%", 16, 6),
3490
- textBlock(3),
3491
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 12, justifyContent: "flex-start" }, children: [
3492
- /* @__PURE__ */ jsxRuntime.jsx(
3493
- SkeletonLoaderItem,
3019
+ style: rootStyle,
3020
+ className: [
3021
+ Input_default.container,
3022
+ fullWidth ? Input_default.fullWidth : "",
3023
+ onClear ? Input_default.withClear : "",
3024
+ hasInlineClear ? Input_default.withInlineClear : "",
3025
+ hasButton ? Input_default.withButton : "",
3026
+ hasTrailingLabel ? Input_default.withTrailingLabel : "",
3027
+ className != null ? className : ""
3028
+ ].filter(Boolean).join(" "),
3029
+ children: [
3030
+ /* @__PURE__ */ jsxRuntime.jsxs(
3031
+ "div",
3494
3032
  {
3495
- width: 100,
3496
- height: 30,
3497
- variant,
3498
- speedSec,
3499
- ariaLabel: "Loading action"
3033
+ className: [
3034
+ Input_default.field,
3035
+ Input_default[variant],
3036
+ icon ? Input_default.fieldWithIcon : "",
3037
+ inputSize ? Input_default[inputSize] : "",
3038
+ modified ? Input_default.modified : "",
3039
+ fieldClassName != null ? fieldClassName : ""
3040
+ ].filter(Boolean).join(" "),
3041
+ "data-forminput": "field",
3042
+ "data-modified": modified ? "true" : void 0,
3043
+ "aria-disabled": inputProps.disabled ? "true" : void 0,
3044
+ ...tooltip ? triggerProps : {},
3045
+ children: [
3046
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Input_default.icon, "data-input-role": "icon", children: icon }),
3047
+ startAdornment && /* @__PURE__ */ jsxRuntime.jsx("span", { className: Input_default.startAdornment, "data-input-role": "start-adornment", children: startAdornment }),
3048
+ /* @__PURE__ */ jsxRuntime.jsx(
3049
+ "input",
3050
+ {
3051
+ ...inputProps,
3052
+ id: inputId,
3053
+ ref: mergeRefs2(inputRef, ref),
3054
+ className: [Input_default.input, inputSize ? Input_default[inputSize] : "", inputClassName != null ? inputClassName : ""].filter(Boolean).join(" ")
3055
+ }
3056
+ ),
3057
+ (reservesInlineClearSlot || hasEndAdornment) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: Input_default.endAdornment, "data-input-role": "end-adornment", children: [
3058
+ reservesInlineClearSlot ? /* @__PURE__ */ jsxRuntime.jsx(
3059
+ "span",
3060
+ {
3061
+ className: Input_default.clearSlot,
3062
+ "aria-hidden": hasVisibleClear ? void 0 : "true",
3063
+ children: hasVisibleClear && onClear ? /* @__PURE__ */ jsxRuntime.jsx(ClearButton, { onClick: onClear }) : null
3064
+ }
3065
+ ) : null,
3066
+ endAdornment
3067
+ ] }),
3068
+ hasVisibleClear && !hasEndAdornment && onClear ? /* @__PURE__ */ jsxRuntime.jsx(ClearButton, { onClick: onClear, absolute: true }) : null
3069
+ ]
3500
3070
  }
3501
3071
  ),
3502
- /* @__PURE__ */ jsxRuntime.jsx(
3503
- SkeletonLoaderItem,
3072
+ hasTrailingLabel && /* @__PURE__ */ jsxRuntime.jsx(
3073
+ "span",
3074
+ {
3075
+ className: [Input_default.trailingLabel, inputSize ? Input_default[inputSize] : ""].filter(Boolean).join(" "),
3076
+ children: trailingLabel
3077
+ }
3078
+ ),
3079
+ hasButton && /* @__PURE__ */ jsxRuntime.jsxs(
3080
+ Button,
3081
+ {
3082
+ onClick: onButtonClick,
3083
+ disabled: buttonDisabled,
3084
+ className: Input_default.trailingButton,
3085
+ type: "button",
3086
+ variant: trailingButtonVariant,
3087
+ size: inputSize,
3088
+ children: [
3089
+ buttonIcon != null ? buttonIcon : null,
3090
+ buttonLabel != null ? buttonLabel : null
3091
+ ]
3092
+ }
3093
+ )
3094
+ ]
3095
+ }
3096
+ )
3097
+ }
3098
+ );
3099
+ });
3100
+ Input.displayName = "Input";
3101
+
3102
+ // src/components/search-box/SearchBox.module.css
3103
+ var SearchBox_default = {
3104
+ resultContainer: "SearchBox_resultContainer",
3105
+ suggestionTable: "SearchBox_suggestionTable",
3106
+ suggestionRow: "SearchBox_suggestionRow",
3107
+ suggestionCell: "SearchBox_suggestionCell",
3108
+ suggestionRowActive: "SearchBox_suggestionRowActive"
3109
+ };
3110
+ var SearchBox = React20.forwardRef(function SearchBoxInner({
3111
+ inputWidth,
3112
+ maxWidth,
3113
+ inputSize,
3114
+ variant,
3115
+ result,
3116
+ debounce = true,
3117
+ debounceMs = 800,
3118
+ onSearch,
3119
+ onSelect,
3120
+ displayPopover,
3121
+ resultKeys,
3122
+ resultTemplate,
3123
+ initialTemplate,
3124
+ popoverMinWidth = "500px",
3125
+ noResultText = "Ingen resultater",
3126
+ loading,
3127
+ enableHotkey = true,
3128
+ onButtonClick,
3129
+ buttonLabel,
3130
+ buttonIcon,
3131
+ fullWidth = false,
3132
+ value,
3133
+ onChange,
3134
+ ...rest
3135
+ }, ref) {
3136
+ const isControlled = value !== void 0;
3137
+ const [draft, setDraft] = React20.useState(() => isControlled ? String(value != null ? value : "") : "");
3138
+ const [searchQuery, setSearchQuery] = React20.useState("");
3139
+ const [activeIndex, setActiveIndex] = React20.useState(null);
3140
+ const popoverRef = React20.useRef(null);
3141
+ const internalInputRef = React20.useRef(null);
3142
+ React20.useEffect(() => {
3143
+ if (typeof ref === "function") {
3144
+ ref(internalInputRef.current);
3145
+ } else if (ref) {
3146
+ ref.current = internalInputRef.current;
3147
+ }
3148
+ }, [ref]);
3149
+ React20.useEffect(() => {
3150
+ if (!isControlled) return;
3151
+ const next = String(value != null ? value : "");
3152
+ if (next !== draft) setDraft(next);
3153
+ }, [value]);
3154
+ React20.useEffect(() => {
3155
+ if (!onSearch) return;
3156
+ if (!debounce) {
3157
+ setSearchQuery(draft);
3158
+ onSearch(draft);
3159
+ return;
3160
+ }
3161
+ const handler = setTimeout(() => {
3162
+ setSearchQuery(draft);
3163
+ onSearch(draft);
3164
+ }, debounceMs);
3165
+ return () => clearTimeout(handler);
3166
+ }, [draft, onSearch, debounce, debounceMs]);
3167
+ React20.useEffect(() => {
3168
+ function handleKeyDown(event) {
3169
+ var _a;
3170
+ if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
3171
+ event.preventDefault();
3172
+ (_a = internalInputRef.current) == null ? void 0 : _a.focus();
3173
+ }
3174
+ }
3175
+ if (enableHotkey) {
3176
+ window.addEventListener("keydown", handleKeyDown);
3177
+ return () => window.removeEventListener("keydown", handleKeyDown);
3178
+ }
3179
+ }, [enableHotkey]);
3180
+ const handleChange = React20__namespace.default.useCallback(
3181
+ (e) => {
3182
+ setDraft(e.target.value);
3183
+ onChange == null ? void 0 : onChange(e);
3184
+ },
3185
+ [onChange]
3186
+ );
3187
+ const handleSelect = React20__namespace.default.useCallback(
3188
+ (item) => {
3189
+ onSelect == null ? void 0 : onSelect(item);
3190
+ reset();
3191
+ },
3192
+ [onSelect]
3193
+ );
3194
+ function reset() {
3195
+ var _a;
3196
+ setDraft("");
3197
+ setSearchQuery("");
3198
+ setActiveIndex(null);
3199
+ (_a = popoverRef.current) == null ? void 0 : _a.close();
3200
+ }
3201
+ const handleClear = React20__namespace.default.useCallback(() => {
3202
+ var _a;
3203
+ reset();
3204
+ onSearch == null ? void 0 : onSearch("");
3205
+ (_a = internalInputRef.current) == null ? void 0 : _a.focus();
3206
+ }, [onSearch]);
3207
+ React20.useEffect(() => {
3208
+ setActiveIndex(null);
3209
+ }, [result]);
3210
+ const inputField = React20.useMemo(() => {
3211
+ var _a;
3212
+ const inputProps = {
3213
+ ...rest,
3214
+ value: draft,
3215
+ onChange: handleChange
3216
+ };
3217
+ const showInputIcon = !onButtonClick || !!buttonLabel || !!buttonIcon;
3218
+ const trailingButtonIcon = onButtonClick && !buttonLabel && !buttonIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : buttonIcon;
3219
+ if (displayPopover) {
3220
+ return /* @__PURE__ */ jsxRuntime.jsx(
3221
+ Popover,
3222
+ {
3223
+ ref: popoverRef,
3224
+ minWidth: popoverMinWidth,
3225
+ fullWidth,
3226
+ trigger: (event) => {
3227
+ var _a2;
3228
+ return /* @__PURE__ */ jsxRuntime.jsx(
3229
+ Input,
3504
3230
  {
3505
- width: 72,
3506
- height: 30,
3231
+ ref: internalInputRef,
3232
+ onFocusCapture: event,
3233
+ onClick: () => {
3234
+ var _a3, _b;
3235
+ if (!((_a3 = popoverRef.current) == null ? void 0 : _a3.isOpen())) (_b = popoverRef.current) == null ? void 0 : _b.open();
3236
+ },
3237
+ minWidth: fullWidth ? void 0 : inputWidth != null ? inputWidth : "300px",
3238
+ width: fullWidth ? void 0 : inputWidth != null ? inputWidth : "300px",
3239
+ fullWidth,
3240
+ icon: showInputIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : void 0,
3241
+ inputSize,
3507
3242
  variant,
3508
- speedSec,
3509
- ariaLabel: "Loading action"
3243
+ autoComplete: "off",
3244
+ onClear: handleClear,
3245
+ onButtonClick,
3246
+ buttonLabel,
3247
+ buttonIcon: trailingButtonIcon,
3248
+ ...inputProps,
3249
+ onKeyDown: (e) => {
3250
+ var _a3;
3251
+ if (result == null ? void 0 : result.length) {
3252
+ if (e.key === "ArrowDown") {
3253
+ e.preventDefault();
3254
+ setActiveIndex(
3255
+ (prev) => prev === null || prev === result.length - 1 ? 0 : prev + 1
3256
+ );
3257
+ } else if (e.key === "ArrowUp") {
3258
+ e.preventDefault();
3259
+ setActiveIndex(
3260
+ (prev) => prev === null || prev === 0 ? result.length - 1 : prev - 1
3261
+ );
3262
+ } else if (e.key === "Enter") {
3263
+ e.preventDefault();
3264
+ if (activeIndex !== null) {
3265
+ handleSelect(result[activeIndex]);
3266
+ } else if (onButtonClick) {
3267
+ onButtonClick();
3268
+ }
3269
+ } else if (e.key === "Escape") {
3270
+ reset();
3271
+ }
3272
+ }
3273
+ (_a3 = inputProps.onKeyDown) == null ? void 0 : _a3.call(inputProps, e);
3274
+ },
3275
+ placeholder: (_a2 = rest.placeholder) != null ? _a2 : "Indtast s\xF8geord"
3510
3276
  }
3511
- )
3512
- ] })
3513
- ] });
3514
- }
3515
- case "avatar": {
3516
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 12, alignItems: "center", width: "100%" }, children: [
3517
- /* @__PURE__ */ jsxRuntime.jsx(
3518
- SkeletonLoaderItem,
3277
+ );
3278
+ },
3279
+ children: resultTemplate ? resultTemplate : (result == null ? void 0 : result.length) ? /* @__PURE__ */ jsxRuntime.jsx(Menu, { children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: SearchBox_default.suggestionTable, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: result.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
3280
+ "tr",
3519
3281
  {
3520
- width: 48,
3521
- height: 48,
3522
- radius: "50%",
3523
- variant,
3524
- speedSec,
3525
- ariaLabel: "Loading avatar"
3526
- }
3527
- ),
3528
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, flex: 1 }, children: [
3529
- line("40%", 14),
3530
- line("25%", 12)
3531
- ] })
3532
- ] });
3533
- }
3534
- case "text": {
3535
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 10, width: "100%" }, children: textBlock(rows) });
3536
- }
3537
- case "table": {
3538
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 12, width: "100%" }, children: [
3539
- tableHeaderRow(),
3540
- Array.from({ length: rows }).map((_, r) => tableBodyRow(r))
3541
- ] });
3542
- }
3543
- case "filterbar": {
3544
- return /* @__PURE__ */ jsxRuntime.jsxs(
3545
- "div",
3546
- {
3547
- style: {
3548
- display: "flex",
3549
- alignItems: "center",
3550
- justifyContent: "space-between",
3551
- gap: 12,
3552
- flexWrap: "wrap",
3553
- width: "100%"
3282
+ onClick: () => handleSelect(item),
3283
+ role: "button",
3284
+ tabIndex: 0,
3285
+ className: `${SearchBox_default.suggestionRow}${index === activeIndex ? ` ${SearchBox_default.suggestionRowActive}` : ""}`,
3286
+ children: resultKeys == null ? void 0 : resultKeys.map((key) => {
3287
+ const raw = item[key];
3288
+ const cell = raw != null ? String(raw) : "";
3289
+ return /* @__PURE__ */ jsxRuntime.jsx(
3290
+ "td",
3291
+ {
3292
+ className: SearchBox_default.suggestionCell,
3293
+ style: { whiteSpace: cell.length < 10 ? "nowrap" : void 0 },
3294
+ children: cell
3295
+ },
3296
+ key
3297
+ );
3298
+ })
3554
3299
  },
3555
- children: [
3556
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: 12, flexWrap: "wrap" }, children: pills(columns) }),
3557
- /* @__PURE__ */ jsxRuntime.jsx(
3558
- SkeletonLoaderItem,
3559
- {
3560
- width: 240,
3561
- height: 30,
3562
- variant,
3563
- speedSec,
3564
- ariaLabel: "Loading"
3565
- }
3566
- )
3567
- ]
3568
- }
3569
- );
3300
+ index
3301
+ )) }) }) }) : !searchQuery && !loading ? initialTemplate || /* @__PURE__ */ jsxRuntime.jsx("div", { className: SearchBox_default.resultContainer, children: "Indtast s\xF8geord" }) : loading ? /* @__PURE__ */ jsxRuntime.jsx("table", { style: { width: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: Array.from({ length: 5 }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx("tr", { children: resultKeys == null ? void 0 : resultKeys.map((key) => /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "8px" }, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }, key)) }, index)) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: SearchBox_default.resultContainer, children: noResultText })
3302
+ }
3303
+ );
3304
+ }
3305
+ return /* @__PURE__ */ jsxRuntime.jsx(
3306
+ Input,
3307
+ {
3308
+ ref: internalInputRef,
3309
+ icon: showInputIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : void 0,
3310
+ minWidth: fullWidth ? void 0 : inputWidth != null ? inputWidth : "300px",
3311
+ fullWidth,
3312
+ inputSize,
3313
+ variant,
3314
+ onClear: handleClear,
3315
+ onButtonClick,
3316
+ buttonLabel,
3317
+ buttonIcon: trailingButtonIcon,
3318
+ ...inputProps,
3319
+ placeholder: (_a = rest.placeholder) != null ? _a : "Indtast s\xF8geord"
3570
3320
  }
3571
- case "inputFieldList": {
3572
- return inputFieldList(rows);
3321
+ );
3322
+ }, [
3323
+ rest,
3324
+ draft,
3325
+ handleChange,
3326
+ handleClear,
3327
+ displayPopover,
3328
+ inputWidth,
3329
+ inputSize,
3330
+ variant,
3331
+ popoverMinWidth,
3332
+ resultTemplate,
3333
+ result,
3334
+ searchQuery,
3335
+ loading,
3336
+ initialTemplate,
3337
+ noResultText,
3338
+ resultKeys,
3339
+ handleSelect,
3340
+ activeIndex,
3341
+ onButtonClick,
3342
+ buttonLabel,
3343
+ buttonIcon,
3344
+ fullWidth
3345
+ ]);
3346
+ return /* @__PURE__ */ jsxRuntime.jsx(
3347
+ "div",
3348
+ {
3349
+ style: {
3350
+ ...fullWidth ? { width: "100%" } : void 0,
3351
+ ...maxWidth !== void 0 ? { maxWidth } : void 0
3352
+ },
3353
+ children: inputField
3354
+ }
3355
+ );
3356
+ });
3357
+ var THEME_VARIANTS = ["light", "dark", "system"];
3358
+ var STORAGE_KEY = "dbc_theme";
3359
+ function isThemeVariant(x) {
3360
+ return !!x && THEME_VARIANTS.includes(x);
3361
+ }
3362
+ function getCookie(name) {
3363
+ const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
3364
+ return match ? decodeURIComponent(match[1]) : null;
3365
+ }
3366
+ function persistTheme(id) {
3367
+ try {
3368
+ localStorage.setItem(STORAGE_KEY, id);
3369
+ } catch {
3370
+ console.error("Failed to access localStorage");
3371
+ }
3372
+ try {
3373
+ document.cookie = `${STORAGE_KEY}=${encodeURIComponent(
3374
+ id
3375
+ )}; Path=/; Max-Age=${60 * 60 * 24 * 365}`;
3376
+ } catch {
3377
+ console.error("Failed to set theme cookie");
3378
+ }
3379
+ }
3380
+ function getTheme() {
3381
+ return document.documentElement.dataset.theme;
3382
+ }
3383
+ function applyTheme(id) {
3384
+ document.documentElement.dataset.theme = id;
3385
+ }
3386
+ function useTheme(initialTheme = "system") {
3387
+ const [theme, setTheme] = React20.useState(null);
3388
+ React20.useEffect(() => {
3389
+ const themeFromDataAttributes = getTheme();
3390
+ let resolved = isThemeVariant(themeFromDataAttributes) ? themeFromDataAttributes : initialTheme;
3391
+ const fromCookie = getCookie(STORAGE_KEY);
3392
+ if (isThemeVariant(fromCookie)) {
3393
+ resolved = fromCookie;
3394
+ } else {
3395
+ try {
3396
+ const fromStorage = localStorage.getItem(STORAGE_KEY);
3397
+ if (isThemeVariant(fromStorage)) resolved = fromStorage;
3398
+ } catch {
3399
+ console.error("Failed to access localStorage");
3400
+ }
3401
+ }
3402
+ applyTheme(resolved);
3403
+ setTheme(resolved);
3404
+ persistTheme(resolved);
3405
+ }, [initialTheme]);
3406
+ const switchTheme = React20.useCallback((id) => {
3407
+ applyTheme(id);
3408
+ setTheme(id);
3409
+ persistTheme(id);
3410
+ return id;
3411
+ }, []);
3412
+ return { theme, switchTheme };
3413
+ }
3414
+
3415
+ // src/components/panel/Panel.module.css
3416
+ var Panel_default = {
3417
+ container: "Panel_container",
3418
+ header: "Panel_header",
3419
+ content: "Panel_content",
3420
+ sm: "Panel_sm"
3421
+ };
3422
+ function Panel({
3423
+ header,
3424
+ subheader,
3425
+ headerIcon,
3426
+ headerAddition,
3427
+ children,
3428
+ severity,
3429
+ size
3430
+ }) {
3431
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: `${Panel_default.container} ${size ? Panel_default[size] : ""}`, children: [
3432
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: Panel_default.header, children: /* @__PURE__ */ jsxRuntime.jsx(
3433
+ Headline,
3434
+ {
3435
+ disableMargin: true,
3436
+ size: size === "sm" ? 4 : 3,
3437
+ icon: headerIcon,
3438
+ addition: headerAddition,
3439
+ subheader,
3440
+ severity,
3441
+ children: header
3573
3442
  }
3574
- default:
3575
- return null;
3576
- }
3577
- };
3578
- return /* @__PURE__ */ jsxRuntime.jsx(
3443
+ ) }),
3444
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: Panel_default.content, children })
3445
+ ] });
3446
+ }
3447
+
3448
+ // src/components/card/Card.module.css
3449
+ var Card_default = {
3450
+ outerContainer: "Card_outerContainer",
3451
+ container: "Card_container",
3452
+ variantDefault: "Card_variantDefault",
3453
+ variantSubtle: "Card_variantSubtle",
3454
+ sm: "Card_sm",
3455
+ md: "Card_md",
3456
+ content: "Card_content",
3457
+ lg: "Card_lg",
3458
+ inner: "Card_inner",
3459
+ innerImgLeft: "Card_innerImgLeft",
3460
+ innerImgRight: "Card_innerImgRight",
3461
+ innerImgTop: "Card_innerImgTop",
3462
+ media: "Card_media",
3463
+ header: "Card_header",
3464
+ headerMeta: "Card_headerMeta",
3465
+ body: "Card_body",
3466
+ actions: "Card_actions",
3467
+ section: "Card_section",
3468
+ sectionDivider: "Card_sectionDivider",
3469
+ sectionTitle: "Card_sectionTitle",
3470
+ loadingList: "Card_loadingList",
3471
+ loadingRow: "Card_loadingRow"
3472
+ };
3473
+
3474
+ // src/components/card/components/CardMeta.module.css
3475
+ var CardMeta_default = {
3476
+ grid: "CardMeta_grid",
3477
+ cols1: "CardMeta_cols1",
3478
+ cols2: "CardMeta_cols2",
3479
+ cols3: "CardMeta_cols3",
3480
+ row: "CardMeta_row",
3481
+ label: "CardMeta_label",
3482
+ value: "CardMeta_value",
3483
+ valueBold: "CardMeta_valueBold",
3484
+ nowrap: "CardMeta_nowrap"
3485
+ };
3486
+ function getColsClass(columns) {
3487
+ switch (columns) {
3488
+ case 1:
3489
+ return CardMeta_default.cols1;
3490
+ case 3:
3491
+ return CardMeta_default.cols3;
3492
+ case 2:
3493
+ default:
3494
+ return CardMeta_default.cols2;
3495
+ }
3496
+ }
3497
+ function CardMeta({
3498
+ columns = 2,
3499
+ className,
3500
+ children,
3501
+ ...rest
3502
+ }) {
3503
+ const colsClass = getColsClass(columns);
3504
+ return /* @__PURE__ */ jsxRuntime.jsx("dl", { ...rest, className: [CardMeta_default.grid, colsClass, className].filter(Boolean).join(" "), children });
3505
+ }
3506
+ function CardMetaRow({
3507
+ label,
3508
+ value,
3509
+ className,
3510
+ nowrapValue,
3511
+ labelWidth,
3512
+ boldValue = false
3513
+ }) {
3514
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3579
3515
  "div",
3580
3516
  {
3581
- role: "status",
3582
- "aria-label": "Loading content",
3583
- style: { display: "flex", flexDirection: "column", gap: 16, width: "100%" },
3584
- children: getSkeletonItems()
3517
+ className: [CardMeta_default.row, className].filter(Boolean).join(" "),
3518
+ style: labelWidth ? { ["--label-width"]: labelWidth } : void 0,
3519
+ children: [
3520
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: CardMeta_default.label, children: label }),
3521
+ /* @__PURE__ */ jsxRuntime.jsx(
3522
+ "dd",
3523
+ {
3524
+ className: [
3525
+ CardMeta_default.value,
3526
+ !boldValue ? CardMeta_default.valueRegular : CardMeta_default.valueBold,
3527
+ nowrapValue ? CardMeta_default.nowrap : ""
3528
+ ].filter(Boolean).join(" "),
3529
+ children: value
3530
+ }
3531
+ )
3532
+ ]
3585
3533
  }
3586
3534
  );
3587
3535
  }
3536
+ function getGapShare(width) {
3537
+ switch (width) {
3538
+ case 25:
3539
+ return "calc(var(--card-container-gap, var(--spacing-md)) * 3 / 4)";
3540
+ case 33:
3541
+ return "calc(var(--card-container-gap, var(--spacing-md)) * 2 / 3)";
3542
+ case 50:
3543
+ return "calc(var(--card-container-gap, var(--spacing-md)) / 2)";
3544
+ case 66:
3545
+ return "calc(var(--card-container-gap, var(--spacing-md)) * 2 / 3)";
3546
+ case 75:
3547
+ return "calc(var(--card-container-gap, var(--spacing-md)) * 3 / 4)";
3548
+ case 100:
3549
+ default:
3550
+ return "0px";
3551
+ }
3552
+ }
3553
+ function getInnerPlacementClass(imgPlacement, s) {
3554
+ switch (imgPlacement) {
3555
+ case "top":
3556
+ return s.innerImgTop;
3557
+ case "right":
3558
+ return s.innerImgRight;
3559
+ case "left":
3560
+ default:
3561
+ return s.innerImgLeft;
3562
+ }
3563
+ }
3564
+ function getVariantClass(variant, s) {
3565
+ switch (variant) {
3566
+ case "subtle":
3567
+ return s.variantSubtle;
3568
+ case "default":
3569
+ default:
3570
+ return s.variantDefault;
3571
+ }
3572
+ }
3573
+ function CardImpl({
3574
+ title,
3575
+ subheader,
3576
+ loading = false,
3577
+ variant = "default",
3578
+ size = "md",
3579
+ headerMarker = true,
3580
+ headerIcon,
3581
+ headerAddition,
3582
+ severity,
3583
+ image,
3584
+ imgPlacement = "left",
3585
+ mediaWidth,
3586
+ actions,
3587
+ headerMeta,
3588
+ sectionTitle,
3589
+ showSectionDivider = false,
3590
+ children,
3591
+ link,
3592
+ width,
3593
+ headlineSize = 4
3594
+ }) {
3595
+ const outerStyle = width ? {
3596
+ ["--width"]: `${width}%`,
3597
+ ["--gap-share"]: getGapShare(width)
3598
+ } : void 0;
3599
+ const mediaStyle = mediaWidth ? { ["--card-media-width"]: `${mediaWidth}px` } : void 0;
3600
+ const innerPlacementClass = getInnerPlacementClass(imgPlacement, Card_default);
3601
+ const variantClass = getVariantClass(variant, Card_default);
3602
+ const hasHeader = !!title || !!headerMeta;
3603
+ const showSection = !loading && (showSectionDivider || !!sectionTitle);
3604
+ const showBody = !loading && !!children;
3605
+ const showActions = !loading && !!actions;
3606
+ const inner = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${Card_default.inner} ${innerPlacementClass}`, children: [
3607
+ image ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.media, style: mediaStyle, children: image }) : null,
3608
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Card_default.content, children: [
3609
+ hasHeader ? /* @__PURE__ */ jsxRuntime.jsxs("header", { className: Card_default.header, children: [
3610
+ title ? /* @__PURE__ */ jsxRuntime.jsx(
3611
+ Headline,
3612
+ {
3613
+ severity,
3614
+ marker: headerMarker,
3615
+ icon: headerIcon,
3616
+ addition: headerAddition,
3617
+ subheader,
3618
+ size: headlineSize,
3619
+ weight: 500,
3620
+ disableMargin: true,
3621
+ children: title
3622
+ }
3623
+ ) : null,
3624
+ headerMeta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.headerMeta, children: headerMeta }) : null
3625
+ ] }) : null,
3626
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.loadingList, "aria-busy": "true", "aria-live": "polite", children: Array.from({ length: 4 }, (_, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Card_default.loadingRow, children: [
3627
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, {}),
3628
+ /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { width: "100%" })
3629
+ ] }, index)) }) : null,
3630
+ showSection ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: Card_default.section, children: [
3631
+ showSectionDivider ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.sectionDivider }) : null,
3632
+ sectionTitle ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.sectionTitle, children: sectionTitle }) : null
3633
+ ] }) : null,
3634
+ showBody ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.body, children }) : null,
3635
+ showActions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: Card_default.actions, children: actions }) : null
3636
+ ] })
3637
+ ] });
3638
+ const cardContent = link ? /* @__PURE__ */ jsxRuntime.jsx(Hyperlink, { children: link }) : inner;
3639
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Card_default.outerContainer} ${Card_default[size]}`, style: outerStyle, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Card_default.container} ${variantClass}`, children: cardContent }) });
3640
+ }
3641
+ var Card = Object.assign(CardImpl, {
3642
+ Meta: CardMeta,
3643
+ MetaRow: CardMetaRow
3644
+ });
3645
+
3646
+ // src/components/card-container/CardContainer.module.css
3647
+ var CardContainer_default = {
3648
+ wrapper: "CardContainer_wrapper",
3649
+ container: "CardContainer_container"};
3650
+ function CardContainer({
3651
+ children,
3652
+ headline,
3653
+ subheader,
3654
+ expand,
3655
+ severity,
3656
+ displayHeaderMarker
3657
+ }) {
3658
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: CardContainer_default.wrapper, children: [
3659
+ headline && /* @__PURE__ */ jsxRuntime.jsx(
3660
+ Headline,
3661
+ {
3662
+ marker: displayHeaderMarker,
3663
+ severity,
3664
+ disableMargin: true,
3665
+ subheader,
3666
+ children: headline
3667
+ }
3668
+ ),
3669
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: CardContainer_default.container, style: { ["--expand"]: expand ? "1" : "0" }, children })
3670
+ ] });
3671
+ }
3588
3672
 
3589
3673
  // src/components/page/Page.module.css
3590
3674
  var Page_default = {
@@ -3628,7 +3712,8 @@ function Page({
3628
3712
  disableTopPadding = true,
3629
3713
  maxWidth,
3630
3714
  containScrolling = false,
3631
- children
3715
+ children,
3716
+ loading = false
3632
3717
  }) {
3633
3718
  const maxWidthClass = maxWidth ? Page_default[`maxWidth${maxWidth.charAt(0).toUpperCase()}${maxWidth.slice(1)}`] : "";
3634
3719
  const hasHeadline = Boolean(header || subheader || headerAddition);
@@ -3652,7 +3737,7 @@ function Page({
3652
3737
  }
3653
3738
  ) : null
3654
3739
  ] }) }),
3655
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Page_default.content} ${disableContentBox ? Page_default.disableContentBox : ""}`, children })
3740
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${Page_default.content} ${disableContentBox ? Page_default.disableContentBox : ""}`, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoader, { type: "squares", rows: 1, columns: 1 }) : children })
3656
3741
  ]
3657
3742
  }
3658
3743
  );
@@ -4415,24 +4500,10 @@ function TableHeader({
4415
4500
  }
4416
4501
  );
4417
4502
  }
4418
- function getColumnWidth(column) {
4419
- if (typeof column.width === "number" && column.width < 150) {
4420
- return "100%";
4421
- }
4422
- if (typeof column.width === "string" && column.width.endsWith("px")) {
4423
- const px = parseInt(column.width, 10);
4424
- if (!isNaN(px) && px < 150) {
4425
- return "100%";
4426
- }
4427
- }
4428
- const percent = Math.floor(Math.random() * (90 - 50 + 1)) + 50;
4429
- return `${percent}%`;
4430
- }
4431
4503
  function TableLoadingBody({ rows, columns, hasSelection }) {
4432
- const widths = Array.from({ length: rows }, () => columns.map(getColumnWidth));
4433
4504
  return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: Table_default.body, children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: Table_default.row, children: [
4434
4505
  hasSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: cx3(Table_default.cell, Table_default.selectionCell), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: Table_default.cellContent, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { height: 20, width: 20 }) }) }) : null,
4435
- columns.map((column, columnIndex) => {
4506
+ columns.map((column) => {
4436
4507
  var _a;
4437
4508
  return /* @__PURE__ */ jsxRuntime.jsx(
4438
4509
  "td",
@@ -4444,7 +4515,7 @@ function TableLoadingBody({ rows, columns, hasSelection }) {
4444
4515
  ),
4445
4516
  "data-align": (_a = column.align) != null ? _a : "left",
4446
4517
  "data-divider": column.divider,
4447
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: Table_default.cellContent, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: Table_default.cellValueEllipsis, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { height: 16, width: widths[rowIndex][columnIndex] }) }) })
4518
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: Table_default.cellContent, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: Table_default.cellValueEllipsis, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }) })
4448
4519
  },
4449
4520
  column.id
4450
4521
  );
@@ -4647,6 +4718,14 @@ function Table({
4647
4718
  );
4648
4719
  }
4649
4720
 
4721
+ // src/constants/chart-colors.ts
4722
+ var ChartSemanticColorVar = {
4723
+ primary: "var(--color-chart-primary)",
4724
+ success: "var(--color-chart-success)",
4725
+ warning: "var(--color-chart-warning)",
4726
+ error: "var(--color-chart-error)"
4727
+ };
4728
+
4650
4729
  // src/components/forms/text-area/Textarea.module.css
4651
4730
  var Textarea_default = {
4652
4731
  container: "Textarea_container",
@@ -12669,6 +12748,7 @@ exports.Button = Button;
12669
12748
  exports.ButtonSelect = ButtonSelect;
12670
12749
  exports.Card = Card;
12671
12750
  exports.CardContainer = CardContainer;
12751
+ exports.ChartSemanticColorVar = ChartSemanticColorVar;
12672
12752
  exports.Checkbox = Checkbox;
12673
12753
  exports.CheckboxGroup = CheckboxGroup;
12674
12754
  exports.Chip = Chip;