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