@countermeasure-platform/web-components 1.3.5-dev.36.1 → 1.3.6-dev.37.1
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/{component-D5sRm1fq.js → component-D_asjmrt.js} +5 -3
- package/dist/component-D_asjmrt.js.map +1 -0
- package/dist/components/brand/index.d.ts.map +1 -1
- package/dist/components/brand/index.js +11 -5
- package/dist/components/brand/index.js.map +1 -1
- package/dist/components/brand/types.d.ts +2 -0
- package/dist/components/brand/types.d.ts.map +1 -1
- package/dist/icons/index.d.ts +7 -2
- package/dist/icons/index.d.ts.map +1 -1
- package/dist/icons/index.js +7 -2
- package/dist/icons/index.js.map +1 -1
- package/dist/icons/lucide.d.ts +3 -0
- package/dist/icons/lucide.d.ts.map +1 -1
- package/dist/icons/lucide.js +3 -0
- package/dist/icons/lucide.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +126 -125
- package/dist/layout/app-shell.d.ts +7 -0
- package/dist/layout/app-shell.d.ts.map +1 -1
- package/dist/layout/app-shell.js +24 -6
- package/dist/layout/app-shell.js.map +1 -1
- package/dist/layout/core-app-chrome.d.ts.map +1 -1
- package/dist/layout/core-app-chrome.js +8 -5
- package/dist/layout/core-app-chrome.js.map +1 -1
- package/dist/layout/core-app-library-dashboard.d.ts +72 -0
- package/dist/layout/core-app-library-dashboard.d.ts.map +1 -0
- package/dist/layout/core-app-library-dashboard.js +160 -0
- package/dist/layout/core-app-library-dashboard.js.map +1 -0
- package/dist/layout/index.d.ts +2 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +38 -37
- package/dist/layout/index.js.map +1 -1
- package/dist/react/brand/index.d.ts +3 -1
- package/dist/react/brand/index.d.ts.map +1 -1
- package/dist/react/brand.js +19 -13
- package/dist/react/brand.js.map +1 -1
- package/dist/react/layout/core-app-library-dashboard.d.ts +13 -0
- package/dist/react/layout/core-app-library-dashboard.d.ts.map +1 -0
- package/dist/react/layout/core-app-library-dashboard.js +27 -0
- package/dist/react/layout/core-app-library-dashboard.js.map +1 -0
- package/dist/react/layout/index.d.ts +1 -0
- package/dist/react/layout/index.d.ts.map +1 -1
- package/dist/react/layout/index.js +3 -2
- package/dist/react/primitives/alert.d.ts +1 -1
- package/dist/react/primitives/toast.d.ts +1 -1
- package/dist/react/sidebar.js +1 -1
- package/dist/react.js +97 -96
- package/dist/sidebar/component.d.ts.map +1 -1
- package/dist/sidebar/index.js +1 -1
- package/dist/sidebar/types.d.ts +7 -0
- package/dist/sidebar/types.d.ts.map +1 -1
- package/dist/styles/components/brand.css +22 -0
- package/dist/styles/layout.css +577 -0
- package/dist/styles/sidebar.css +26 -0
- package/package.json +11 -1
- package/src/components/brand/index.ts +22 -4
- package/src/components/brand/types.ts +2 -0
- package/src/icons/icons.test.ts +1 -1
- package/src/icons/index.ts +7 -2
- package/src/icons/lucide.ts +4 -0
- package/src/index.ts +2 -0
- package/src/layout/app-shell.test.ts +76 -0
- package/src/layout/app-shell.ts +38 -7
- package/src/layout/core-app-chrome.test.ts +17 -5
- package/src/layout/core-app-chrome.ts +8 -3
- package/src/layout/core-app-library-dashboard.test.ts +397 -0
- package/src/layout/core-app-library-dashboard.ts +519 -0
- package/src/layout/index.ts +18 -0
- package/src/react/brand/index.test.tsx +10 -0
- package/src/react/brand/index.tsx +25 -4
- package/src/react/layout/core-app-chrome.test.tsx +2 -2
- package/src/react/layout/core-app-library-dashboard.test.tsx +42 -0
- package/src/react/layout/core-app-library-dashboard.tsx +56 -0
- package/src/react/layout/index.ts +6 -0
- package/src/sidebar/component.test.ts +21 -1
- package/src/sidebar/component.ts +14 -8
- package/src/sidebar/types.ts +7 -0
- package/src/styles/components/brand.css +22 -0
- package/src/styles/layout.css +577 -0
- package/src/styles/sidebar.css +26 -0
- package/dist/component-D5sRm1fq.js.map +0 -1
package/dist/layout/index.js
CHANGED
|
@@ -2,34 +2,35 @@ import { n as e } from "../sanitize-uWpY18N9.js";
|
|
|
2
2
|
import { t } from "../navigation-DihI8dfX.js";
|
|
3
3
|
import { AppShell as n, TopMenuBar as r, createAppShell as i, createProductShell as a, createTopMenuBar as o } from "./app-shell.js";
|
|
4
4
|
import { CORE_APP_ROUTE_LABELS as s, createCoreAppChromePreset as c, createCoreAppSidebarConfig as l, createCoreAppSidebarSections as u, createCoreAppTopbarActions as d, createCoreAppTopbarConfig as f, getCoreAppRouteLabel as p, mountCoreAppChrome as m, mountCoreAppChromeFromDom as h } from "./core-app-chrome.js";
|
|
5
|
-
import {
|
|
5
|
+
import { mountCoreAppLibraryDashboard as g, mountCoreAppLibraryDashboardFromDom as _ } from "./core-app-library-dashboard.js";
|
|
6
|
+
import { PageHeader as v, createPageHeader as y } from "./page-header.js";
|
|
6
7
|
//#region src/layout/index.ts
|
|
7
|
-
var
|
|
8
|
+
var b = () => {
|
|
8
9
|
if (typeof window > "u") return null;
|
|
9
10
|
try {
|
|
10
11
|
return window.localStorage;
|
|
11
12
|
} catch {
|
|
12
13
|
return console.warn("Unable to access localStorage"), null;
|
|
13
14
|
}
|
|
14
|
-
},
|
|
15
|
+
}, x = (e) => {
|
|
15
16
|
try {
|
|
16
17
|
return new URL(e, window.location.href).origin === window.location.origin;
|
|
17
18
|
} catch {
|
|
18
19
|
return !1;
|
|
19
20
|
}
|
|
20
|
-
},
|
|
21
|
+
}, S = {
|
|
21
22
|
storageKey: "cmm-sidebar-state",
|
|
22
23
|
desktopBreakpoint: "(min-width: 1024px)",
|
|
23
24
|
collapsedClass: "cmm-shell--sidebar-collapsed",
|
|
24
25
|
openClass: "cmm-shell--sidebar-open"
|
|
25
26
|
};
|
|
26
|
-
function
|
|
27
|
+
function C(e = {}) {
|
|
27
28
|
let t = {
|
|
28
|
-
...
|
|
29
|
+
...S,
|
|
29
30
|
...e
|
|
30
31
|
}, n = document.querySelector("[data-shell-layout]"), r = document.querySelector("[data-shell-sidebar]");
|
|
31
32
|
if (!n || !r) return () => {};
|
|
32
|
-
let i =
|
|
33
|
+
let i = b(), a = window.matchMedia(t.desktopBreakpoint), o = Array.from(document.querySelectorAll("[data-sidebar-toggle]")), s = Array.from(document.querySelectorAll("[data-sidebar-dismiss]")), c = r.id || "shell-sidebar";
|
|
33
34
|
r.id = c;
|
|
34
35
|
let l = () => i?.getItem(t.storageKey) === "collapsed", u = () => {
|
|
35
36
|
let e = a.matches ? !n.classList.contains(t.collapsedClass) : n.classList.contains(t.openClass);
|
|
@@ -61,7 +62,7 @@ function x(e = {}) {
|
|
|
61
62
|
}), document.removeEventListener("keydown", g), a.removeEventListener("change", p);
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
|
-
function
|
|
65
|
+
function w(e = {}) {
|
|
65
66
|
let t = e.triggerSelector ?? "[data-user-trigger]", n = e.dropdownSelector ?? "[data-user-dropdown]", r = document.querySelector("[data-user-menu]"), i = document.querySelector(t), a = document.querySelector(n);
|
|
66
67
|
if (!r || !i || !a) return () => {};
|
|
67
68
|
let o = (e) => {
|
|
@@ -84,17 +85,17 @@ function S(e = {}) {
|
|
|
84
85
|
i.removeEventListener("click", c), document.removeEventListener("click", l), document.removeEventListener("keydown", u), a.removeEventListener("keydown", f), i.removeEventListener("keydown", p);
|
|
85
86
|
};
|
|
86
87
|
}
|
|
87
|
-
var
|
|
88
|
-
e.classList.toggle("hidden", !t), e.classList.toggle(
|
|
89
|
-
},
|
|
88
|
+
var T = (e) => e.dataset.collapsibleOpen === "true" || !e.classList.contains("hidden"), E = "cmm-collapsible--hidden", D = (e, t) => {
|
|
89
|
+
e.classList.toggle("hidden", !t), e.classList.toggle(E, !t), e.dataset.collapsibleOpen = t.toString(), e.setAttribute("aria-hidden", t ? "false" : "true");
|
|
90
|
+
}, O = (e, t) => {
|
|
90
91
|
document.querySelectorAll(`[data-toggle-target='${e}']`).forEach((e) => {
|
|
91
92
|
e.setAttribute("aria-expanded", t.toString());
|
|
92
93
|
});
|
|
93
94
|
};
|
|
94
|
-
function
|
|
95
|
+
function k(e = {}) {
|
|
95
96
|
let { scrollIntoView: t = !0, scrollBehavior: n = "smooth", hiddenClass: r = "cmm-collapsible--hidden" } = e;
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
E = r, document.querySelectorAll("[data-collapsible]").forEach((e) => {
|
|
98
|
+
D(e, e.dataset.collapsibleOpen === "true" || !e.classList.contains("hidden"));
|
|
98
99
|
});
|
|
99
100
|
let i = [];
|
|
100
101
|
document.querySelectorAll("[data-toggle-target]").forEach((e) => {
|
|
@@ -103,11 +104,11 @@ function D(e = {}) {
|
|
|
103
104
|
let a = document.querySelector(r);
|
|
104
105
|
if (!a) return;
|
|
105
106
|
let o = a.id || r.replace(/^#/, "");
|
|
106
|
-
e.setAttribute("aria-controls", o), e.setAttribute("aria-expanded",
|
|
107
|
+
e.setAttribute("aria-controls", o), e.setAttribute("aria-expanded", T(a).toString());
|
|
107
108
|
let s = (e) => {
|
|
108
109
|
e.preventDefault();
|
|
109
|
-
let i = !
|
|
110
|
-
|
|
110
|
+
let i = !T(a);
|
|
111
|
+
D(a, i), O(r, i), i && t && a.scrollIntoView({
|
|
111
112
|
behavior: n,
|
|
112
113
|
block: "start"
|
|
113
114
|
});
|
|
@@ -122,7 +123,7 @@ function D(e = {}) {
|
|
|
122
123
|
let n = document.querySelector(t);
|
|
123
124
|
if (!n) return;
|
|
124
125
|
let r = (e) => {
|
|
125
|
-
e.preventDefault(),
|
|
126
|
+
e.preventDefault(), D(n, !1), O(t, !1);
|
|
126
127
|
};
|
|
127
128
|
e.addEventListener("click", r), i.push({
|
|
128
129
|
element: e,
|
|
@@ -132,7 +133,7 @@ function D(e = {}) {
|
|
|
132
133
|
let a = window.location.hash;
|
|
133
134
|
if (a) {
|
|
134
135
|
let e = document.querySelector(a);
|
|
135
|
-
e?.dataset.collapsible !== void 0 && (
|
|
136
|
+
e?.dataset.collapsible !== void 0 && (D(e, !0), O(a, !0));
|
|
136
137
|
}
|
|
137
138
|
return () => {
|
|
138
139
|
i.forEach(({ element: e, handler: t }) => {
|
|
@@ -140,12 +141,12 @@ function D(e = {}) {
|
|
|
140
141
|
});
|
|
141
142
|
};
|
|
142
143
|
}
|
|
143
|
-
var
|
|
144
|
-
function
|
|
144
|
+
var A = "\n <div class=\"cmm-sheet__loading\">\n <div class=\"cmm-spinner\"></div>\n </div>\n", j = "\n <div class=\"cmm-sheet__error\">\n <p>Failed to load content. Please try the full page.</p>\n </div>\n";
|
|
145
|
+
function M(t, n) {
|
|
145
146
|
t.replaceChildren(e(n, { allowSvg: !0 }));
|
|
146
147
|
}
|
|
147
|
-
function
|
|
148
|
-
let { openClass: n = "cmm-sheet--open", hiddenClass: r = "cmm-sheet--hidden", backdropVisibleClass: i = "cmm-sheet__backdrop--visible", backdropHiddenClass: a = "cmm-sheet__backdrop--hidden", spinnerHtml: o =
|
|
148
|
+
function N(e = {}) {
|
|
149
|
+
let { openClass: n = "cmm-sheet--open", hiddenClass: r = "cmm-sheet--hidden", backdropVisibleClass: i = "cmm-sheet__backdrop--visible", backdropHiddenClass: a = "cmm-sheet__backdrop--hidden", spinnerHtml: o = A, errorHtml: s = j, allowCrossOriginFetch: c = !1 } = e, l = /* @__PURE__ */ new Map();
|
|
149
150
|
if (document.querySelectorAll("[data-sheet]").forEach((e) => {
|
|
150
151
|
let t = e.dataset.sheet;
|
|
151
152
|
if (!t) return;
|
|
@@ -167,19 +168,19 @@ function j(e = {}) {
|
|
|
167
168
|
}, p = async (e, n) => {
|
|
168
169
|
u && u.key !== e.key && f(u), u = e, d(e, !0);
|
|
169
170
|
let r = n?.dataset.sheetUrl ?? e.sheet.dataset.sheetUrl, i = n?.dataset.sheetFocus ?? e.focusSelector, a = n?.dataset.sheetFullpage ?? e.sheet.dataset.sheetFullpage, l = n?.dataset.sheetExpand ?? e.sheet.dataset.sheetExpand;
|
|
170
|
-
if (e.fullPageLink && a && (e.fullPageLink.href = a), e.expandLink && l && (e.expandLink.href = l), !r || !c && !
|
|
171
|
-
|
|
171
|
+
if (e.fullPageLink && a && (e.fullPageLink.href = a), e.expandLink && l && (e.expandLink.href = l), !r || !c && !x(r)) {
|
|
172
|
+
M(e.content, s);
|
|
172
173
|
return;
|
|
173
174
|
}
|
|
174
|
-
|
|
175
|
+
M(e.content, o);
|
|
175
176
|
try {
|
|
176
177
|
let n = await fetch(r);
|
|
177
178
|
if (n.ok) {
|
|
178
179
|
let t = await n.text();
|
|
179
|
-
|
|
180
|
-
} else a ? t(a) :
|
|
180
|
+
M(e.content, t), i && e.content.querySelector(i)?.focus();
|
|
181
|
+
} else a ? t(a) : M(e.content, s);
|
|
181
182
|
} catch {
|
|
182
|
-
a ? t(a) :
|
|
183
|
+
a ? t(a) : M(e.content, s);
|
|
183
184
|
}
|
|
184
185
|
}, m = [];
|
|
185
186
|
l.forEach((e) => {
|
|
@@ -226,7 +227,7 @@ function j(e = {}) {
|
|
|
226
227
|
}), document.removeEventListener("keydown", h);
|
|
227
228
|
};
|
|
228
229
|
}
|
|
229
|
-
function
|
|
230
|
+
function P() {
|
|
230
231
|
let e = document.querySelector("[data-nav-list]");
|
|
231
232
|
if (!e) return () => {};
|
|
232
233
|
let t = () => Array.from(e.querySelectorAll("[data-nav-item]")), n = (e) => {
|
|
@@ -237,13 +238,13 @@ function M() {
|
|
|
237
238
|
e.removeEventListener("keydown", n);
|
|
238
239
|
};
|
|
239
240
|
}
|
|
240
|
-
function
|
|
241
|
+
function F(e = {}) {
|
|
241
242
|
let t = [
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
243
|
+
C(e.sidebar),
|
|
244
|
+
w(e.userMenu),
|
|
245
|
+
k(e.collapsibles),
|
|
246
|
+
N(e.sheets),
|
|
247
|
+
P()
|
|
247
248
|
];
|
|
248
249
|
return () => {
|
|
249
250
|
t.forEach((e) => {
|
|
@@ -252,6 +253,6 @@ function N(e = {}) {
|
|
|
252
253
|
};
|
|
253
254
|
}
|
|
254
255
|
//#endregion
|
|
255
|
-
export { n as AppShell, s as CORE_APP_ROUTE_LABELS,
|
|
256
|
+
export { n as AppShell, s as CORE_APP_ROUTE_LABELS, v as PageHeader, r as TopMenuBar, i as createAppShell, c as createCoreAppChromePreset, l as createCoreAppSidebarConfig, u as createCoreAppSidebarSections, d as createCoreAppTopbarActions, f as createCoreAppTopbarConfig, y as createPageHeader, a as createProductShell, o as createTopMenuBar, p as getCoreAppRouteLabel, F as initLayout, m as mountCoreAppChrome, h as mountCoreAppChromeFromDom, g as mountCoreAppLibraryDashboard, _ as mountCoreAppLibraryDashboardFromDom, k as setupCollapsibles, P as setupNavKeyboard, N as setupSheets, C as setupSidebar, w as setupUserMenu };
|
|
256
257
|
|
|
257
258
|
//# sourceMappingURL=index.js.map
|
package/dist/layout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/layout/index.ts"],"sourcesContent":["/**\n * Layout Components\n * @countermeasure/web-components\n *\n * Shared layout utilities for sidebar, user menu, collapsibles, and sheets.\n */\n\nimport { createSafeMarkupFragment } from '../utils/sanitize'\nimport { navigateDocumentTo } from '../utils/navigation'\nexport {\n AppShell,\n TopMenuBar,\n createAppShell,\n createProductShell,\n createTopMenuBar,\n} from './app-shell'\nexport type {\n AppShellConfig,\n TopMenuBarAction,\n TopMenuBarActionInput,\n TopMenuBarBreadcrumb,\n TopMenuBarConfig,\n TopMenuBarUser,\n} from './app-shell'\nexport {\n CORE_APP_ROUTE_LABELS,\n createCoreAppChromePreset,\n createCoreAppSidebarConfig,\n createCoreAppSidebarSections,\n createCoreAppTopbarActions,\n createCoreAppTopbarConfig,\n getCoreAppRouteLabel,\n mountCoreAppChrome,\n mountCoreAppChromeFromDom,\n} from './core-app-chrome'\nexport type {\n CoreAppChromePreset,\n CoreAppChromeDomMountOptions,\n CoreAppChromeMount,\n CoreAppChromeMountOptions,\n CoreAppChromePresetOptions,\n CoreAppRouteLabel,\n CoreAppSidebarPresetOptions,\n CoreAppTopbarPresetOptions,\n} from './core-app-chrome'\nexport { PageHeader, createPageHeader } from './page-header'\nexport type { PageHeaderConfig, PageHeaderMetadata } from './page-header'\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface SidebarConfig {\n storageKey?: string\n desktopBreakpoint?: string\n collapsedClass?: string\n openClass?: string\n}\n\nexport interface UserMenuConfig {\n triggerSelector?: string\n dropdownSelector?: string\n dropdownItemSelector?: string\n}\n\nexport interface CollapsibleConfig {\n scrollIntoView?: boolean\n scrollBehavior?: ScrollBehavior\n hiddenClass?: string\n}\n\nexport interface SheetConfig {\n key: string\n sheet: HTMLElement\n backdrop: HTMLElement\n content: HTMLElement\n fullPageLink?: HTMLAnchorElement | null | undefined\n expandLink?: HTMLAnchorElement | null | undefined\n focusSelector?: string | undefined\n}\n\nexport interface SheetSetupConfig {\n openClass?: string\n hiddenClass?: string\n backdropVisibleClass?: string\n backdropHiddenClass?: string\n spinnerHtml?: string\n errorHtml?: string\n /** Allow fetching sheet content from non-same-origin URLs. Default: false. */\n allowCrossOriginFetch?: boolean\n}\n\n// ============================================================================\n// STORAGE HELPERS\n// ============================================================================\n\nconst resolveStorage = (): Storage | null => {\n if (typeof window === 'undefined') {\n return null\n }\n try {\n return window.localStorage\n } catch {\n console.warn('Unable to access localStorage')\n return null\n }\n}\n\nconst isSameOriginUrl = (url: string): boolean => {\n try {\n return new URL(url, window.location.href).origin === window.location.origin\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// SIDEBAR\n// ============================================================================\n\nconst DEFAULT_SIDEBAR_CONFIG: Required<SidebarConfig> = {\n storageKey: 'cmm-sidebar-state',\n desktopBreakpoint: '(min-width: 1024px)',\n collapsedClass: 'cmm-shell--sidebar-collapsed',\n openClass: 'cmm-shell--sidebar-open',\n}\n\n/**\n * Setup responsive sidebar with collapse/expand functionality.\n */\nexport function setupSidebar(config: SidebarConfig = {}): () => void {\n const options = { ...DEFAULT_SIDEBAR_CONFIG, ...config }\n const layout = document.querySelector<HTMLElement>('[data-shell-layout]')\n const sidebar = document.querySelector<HTMLElement>('[data-shell-sidebar]')\n\n if (!layout || !sidebar) {\n return () => {\n /* noop */\n }\n }\n\n const storage = resolveStorage()\n const mediaQuery = window.matchMedia(options.desktopBreakpoint)\n const toggles = Array.from(document.querySelectorAll<HTMLElement>('[data-sidebar-toggle]'))\n const dismissors = Array.from(document.querySelectorAll<HTMLElement>('[data-sidebar-dismiss]'))\n\n const sidebarId = sidebar.id || 'shell-sidebar'\n sidebar.id = sidebarId\n\n const readStoredCollapsed = () => storage?.getItem(options.storageKey) === 'collapsed'\n\n const syncToggleAria = () => {\n const expanded = mediaQuery.matches\n ? !layout.classList.contains(options.collapsedClass)\n : layout.classList.contains(options.openClass)\n\n toggles.forEach(toggle => {\n toggle.setAttribute('aria-expanded', expanded.toString())\n toggle.setAttribute('aria-controls', sidebarId)\n })\n }\n\n const applyCollapsed = (collapsed: boolean, persist = true) => {\n layout.classList.toggle(options.collapsedClass, collapsed)\n if (persist && mediaQuery.matches) {\n storage?.setItem(options.storageKey, collapsed ? 'collapsed' : 'expanded')\n }\n syncToggleAria()\n }\n\n const setOpen = (open: boolean) => {\n layout.classList.toggle(options.openClass, open)\n syncToggleAria()\n }\n\n const syncForViewport = () => {\n if (mediaQuery.matches) {\n setOpen(false)\n applyCollapsed(readStoredCollapsed(), false)\n } else {\n setOpen(false)\n applyCollapsed(false, false)\n }\n }\n\n const handleToggleClick = () => {\n if (mediaQuery.matches) {\n const collapsed = layout.classList.contains(options.collapsedClass)\n applyCollapsed(!collapsed)\n } else {\n const open = layout.classList.contains(options.openClass)\n setOpen(!open)\n }\n }\n\n const handleDismissClick = () => {\n setOpen(false)\n }\n\n const handleKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !mediaQuery.matches) {\n setOpen(false)\n }\n }\n\n // Attach listeners\n toggles.forEach(toggle => {\n toggle.addEventListener('click', handleToggleClick)\n })\n dismissors.forEach(dismiss => {\n dismiss.addEventListener('click', handleDismissClick)\n })\n document.addEventListener('keydown', handleKeydown)\n mediaQuery.addEventListener('change', syncForViewport)\n\n // Initialize\n syncForViewport()\n\n // Return cleanup function\n return () => {\n toggles.forEach(toggle => {\n toggle.removeEventListener('click', handleToggleClick)\n })\n dismissors.forEach(dismiss => {\n dismiss.removeEventListener('click', handleDismissClick)\n })\n document.removeEventListener('keydown', handleKeydown)\n mediaQuery.removeEventListener('change', syncForViewport)\n }\n}\n\n// ============================================================================\n// USER MENU\n// ============================================================================\n\n/**\n * Setup user menu dropdown with keyboard navigation.\n */\nexport function setupUserMenu(config: UserMenuConfig = {}): () => void {\n const triggerSelector = config.triggerSelector ?? '[data-user-trigger]'\n const dropdownSelector = config.dropdownSelector ?? '[data-user-dropdown]'\n\n const userMenu = document.querySelector<HTMLElement>('[data-user-menu]')\n const trigger = document.querySelector<HTMLButtonElement>(triggerSelector)\n const dropdown = document.querySelector<HTMLElement>(dropdownSelector)\n\n if (!userMenu || !trigger || !dropdown) {\n return () => {\n /* noop */\n }\n }\n\n const setExpanded = (expanded: boolean) => {\n trigger.setAttribute('aria-expanded', expanded.toString())\n userMenu.setAttribute('aria-expanded', expanded.toString())\n }\n\n const isExpanded = () => trigger.getAttribute('aria-expanded') === 'true'\n\n const handleTriggerClick = (event: Event) => {\n event.stopPropagation()\n setExpanded(!isExpanded())\n }\n\n const handleDocumentClick = (event: Event) => {\n if (!userMenu.contains(event.target as Node)) {\n setExpanded(false)\n }\n }\n\n const handleKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isExpanded()) {\n setExpanded(false)\n trigger.focus()\n }\n }\n\n const dropdownItemSelector = config.dropdownItemSelector ?? '.cmm-user-menu__dropdown-item'\n\n const handleDropdownKeydown = (event: KeyboardEvent) => {\n const items = Array.from(dropdown.querySelectorAll<HTMLAnchorElement>(dropdownItemSelector))\n const currentIndex = items.indexOf(document.activeElement as HTMLAnchorElement)\n\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0\n items[nextIndex]?.focus()\n } else if (event.key === 'ArrowUp') {\n event.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1\n items[prevIndex]?.focus()\n } else if (event.key === 'Tab' && !event.shiftKey && currentIndex === items.length - 1) {\n setExpanded(false)\n } else if (event.key === 'Tab' && event.shiftKey && currentIndex === 0) {\n setExpanded(false)\n }\n }\n\n const handleTriggerKeydown = (event: KeyboardEvent) => {\n if (\n (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') &&\n !isExpanded()\n ) {\n event.preventDefault()\n setExpanded(true)\n setTimeout(() => {\n const firstItem = dropdown.querySelector<HTMLAnchorElement>(dropdownItemSelector)\n firstItem?.focus()\n }, 50)\n }\n }\n\n // Attach listeners\n trigger.addEventListener('click', handleTriggerClick)\n document.addEventListener('click', handleDocumentClick)\n document.addEventListener('keydown', handleKeydown)\n dropdown.addEventListener('keydown', handleDropdownKeydown)\n trigger.addEventListener('keydown', handleTriggerKeydown)\n\n // Return cleanup function\n return () => {\n trigger.removeEventListener('click', handleTriggerClick)\n document.removeEventListener('click', handleDocumentClick)\n document.removeEventListener('keydown', handleKeydown)\n dropdown.removeEventListener('keydown', handleDropdownKeydown)\n trigger.removeEventListener('keydown', handleTriggerKeydown)\n }\n}\n\n// ============================================================================\n// COLLAPSIBLES\n// ============================================================================\n\nconst isCollapsibleExpanded = (section: HTMLElement) =>\n section.dataset.collapsibleOpen === 'true' || !section.classList.contains('hidden')\n\nlet collapsibleHiddenClass = 'cmm-collapsible--hidden'\n\nconst updateCollapsibleState = (section: HTMLElement, expanded: boolean) => {\n section.classList.toggle('hidden', !expanded)\n section.classList.toggle(collapsibleHiddenClass, !expanded)\n section.dataset.collapsibleOpen = expanded.toString()\n section.setAttribute('aria-hidden', expanded ? 'false' : 'true')\n}\n\nconst syncCollapsibleToggles = (selector: string, expanded: boolean) => {\n document.querySelectorAll<HTMLElement>(`[data-toggle-target='${selector}']`).forEach(toggle => {\n toggle.setAttribute('aria-expanded', expanded.toString())\n })\n}\n\n/**\n * Setup collapsible sections with toggle buttons.\n */\nexport function setupCollapsibles(config: CollapsibleConfig = {}): () => void {\n const {\n scrollIntoView = true,\n scrollBehavior = 'smooth',\n hiddenClass = 'cmm-collapsible--hidden',\n } = config\n collapsibleHiddenClass = hiddenClass\n\n // Initialize all collapsible sections\n document.querySelectorAll<HTMLElement>('[data-collapsible]').forEach(section => {\n const expanded =\n section.dataset.collapsibleOpen === 'true' || !section.classList.contains('hidden')\n updateCollapsibleState(section, expanded)\n })\n\n const handlers: { element: HTMLElement; handler: (e: Event) => void }[] = []\n\n // Setup toggle triggers\n document.querySelectorAll<HTMLElement>('[data-toggle-target]').forEach(toggle => {\n const selector = toggle.dataset.toggleTarget\n if (!selector) {\n return\n }\n\n const target = document.querySelector<HTMLElement>(selector)\n if (!target) {\n return\n }\n\n const ariaTarget = target.id || selector.replace(/^#/, '')\n toggle.setAttribute('aria-controls', ariaTarget)\n toggle.setAttribute('aria-expanded', isCollapsibleExpanded(target).toString())\n\n const handler = (event: Event) => {\n event.preventDefault()\n const expanded = !isCollapsibleExpanded(target)\n updateCollapsibleState(target, expanded)\n syncCollapsibleToggles(selector, expanded)\n\n if (expanded && scrollIntoView) {\n target.scrollIntoView({ behavior: scrollBehavior, block: 'start' })\n }\n }\n\n toggle.addEventListener('click', handler)\n handlers.push({ element: toggle, handler })\n })\n\n // Setup collapse triggers (close only)\n document.querySelectorAll<HTMLElement>('[data-collapse-target]').forEach(toggle => {\n const selector = toggle.dataset.collapseTarget\n if (!selector) {\n return\n }\n\n const target = document.querySelector<HTMLElement>(selector)\n if (!target) {\n return\n }\n\n const handler = (event: Event) => {\n event.preventDefault()\n updateCollapsibleState(target, false)\n syncCollapsibleToggles(selector, false)\n }\n\n toggle.addEventListener('click', handler)\n handlers.push({ element: toggle, handler })\n })\n\n // Handle URL hash for deep linking\n const hash = window.location.hash\n if (hash) {\n const target = document.querySelector<HTMLElement>(hash)\n if (target?.dataset.collapsible !== undefined) {\n updateCollapsibleState(target, true)\n syncCollapsibleToggles(hash, true)\n }\n }\n\n // Return cleanup function\n return () => {\n handlers.forEach(({ element, handler }) => {\n element.removeEventListener('click', handler)\n })\n }\n}\n\n// ============================================================================\n// SHEETS / SIDE PANELS\n// ============================================================================\n\nconst SHEET_SPINNER_HTML = `\n <div class=\"cmm-sheet__loading\">\n <div class=\"cmm-spinner\"></div>\n </div>\n`\n\nconst SHEET_ERROR_HTML = `\n <div class=\"cmm-sheet__error\">\n <p>Failed to load content. Please try the full page.</p>\n </div>\n`\n\nfunction replaceSheetMarkup(element: HTMLElement, markup: string): void {\n element.replaceChildren(createSafeMarkupFragment(markup, { allowSvg: true }))\n}\n\n/**\n * Setup side sheet/drawer components.\n */\nexport function setupSheets(setupConfig: SheetSetupConfig = {}): () => void {\n const {\n openClass = 'cmm-sheet--open',\n hiddenClass = 'cmm-sheet--hidden',\n backdropVisibleClass = 'cmm-sheet__backdrop--visible',\n backdropHiddenClass = 'cmm-sheet__backdrop--hidden',\n spinnerHtml: spinnerMarkup = SHEET_SPINNER_HTML,\n errorHtml: errorMarkup = SHEET_ERROR_HTML,\n allowCrossOriginFetch = false,\n } = setupConfig\n\n const sheetMap = new Map<string, SheetConfig>()\n\n document.querySelectorAll<HTMLElement>('[data-sheet]').forEach(sheet => {\n const key = sheet.dataset.sheet\n if (!key) {\n return\n }\n\n const backdrop = document.querySelector<HTMLElement>(`[data-sheet-backdrop='${key}']`)\n const content = sheet.querySelector<HTMLElement>('[data-sheet-content]')\n if (!backdrop || !content) {\n return\n }\n\n sheetMap.set(key, {\n key,\n sheet,\n backdrop,\n content,\n fullPageLink: sheet.querySelector<HTMLAnchorElement>('[data-sheet-fullpage]'),\n expandLink: sheet.querySelector<HTMLAnchorElement>('[data-sheet-expand]'),\n focusSelector: sheet.dataset.sheetFocus,\n })\n })\n\n if (sheetMap.size === 0) {\n return () => {\n /* noop */\n }\n }\n\n let activeSheet: SheetConfig | null = null\n\n const setOpenState = (config: SheetConfig, open: boolean) => {\n config.sheet.classList.toggle(openClass, open)\n config.sheet.classList.toggle(hiddenClass, !open)\n config.backdrop.classList.toggle(backdropVisibleClass, open)\n config.backdrop.classList.toggle(backdropHiddenClass, !open)\n config.sheet.setAttribute('aria-hidden', open ? 'false' : 'true')\n }\n\n const closeSheet = (config: SheetConfig) => {\n if (activeSheet?.key === config.key) {\n activeSheet = null\n }\n setOpenState(config, false)\n }\n\n const openSheet = async (config: SheetConfig, trigger?: HTMLElement) => {\n if (activeSheet && activeSheet.key !== config.key) {\n closeSheet(activeSheet)\n }\n\n activeSheet = config\n setOpenState(config, true)\n\n const url = trigger?.dataset.sheetUrl ?? config.sheet.dataset.sheetUrl\n const focusSelector = trigger?.dataset.sheetFocus ?? config.focusSelector\n const fullPageHref = trigger?.dataset.sheetFullpage ?? config.sheet.dataset.sheetFullpage\n const expandHref = trigger?.dataset.sheetExpand ?? config.sheet.dataset.sheetExpand\n\n if (config.fullPageLink && fullPageHref) {\n config.fullPageLink.href = fullPageHref\n }\n\n if (config.expandLink && expandHref) {\n config.expandLink.href = expandHref\n }\n\n if (!url || (!allowCrossOriginFetch && !isSameOriginUrl(url))) {\n replaceSheetMarkup(config.content, errorMarkup)\n return\n }\n\n replaceSheetMarkup(config.content, spinnerMarkup)\n\n try {\n const response = await fetch(url)\n if (response.ok) {\n const markup = await response.text()\n replaceSheetMarkup(config.content, markup)\n if (focusSelector) {\n const focusTarget = config.content.querySelector<HTMLElement>(focusSelector)\n focusTarget?.focus()\n }\n } else if (fullPageHref) {\n navigateDocumentTo(fullPageHref)\n } else {\n replaceSheetMarkup(config.content, errorMarkup)\n }\n } catch {\n if (fullPageHref) {\n navigateDocumentTo(fullPageHref)\n } else {\n replaceSheetMarkup(config.content, errorMarkup)\n }\n }\n }\n\n const handlers: { element: HTMLElement; event: string; handler: (e: Event) => void }[] = []\n\n sheetMap.forEach(config => {\n const closeHandler = (event: Event) => {\n const target = event.target as HTMLElement\n if (target.closest('[data-sheet-close]')) {\n event.preventDefault()\n closeSheet(config)\n }\n }\n\n const backdropHandler = () => {\n closeSheet(config)\n }\n\n const expandHandler = () => {\n closeSheet(config)\n }\n\n config.sheet.addEventListener('click', closeHandler)\n config.backdrop.addEventListener('click', backdropHandler)\n handlers.push({ element: config.sheet, event: 'click', handler: closeHandler })\n handlers.push({ element: config.backdrop, event: 'click', handler: backdropHandler })\n\n if (config.expandLink) {\n config.expandLink.addEventListener('click', expandHandler)\n handlers.push({ element: config.expandLink, event: 'click', handler: expandHandler })\n }\n })\n\n // Setup triggers\n document.querySelectorAll<HTMLElement>('[data-sheet-trigger]').forEach(trigger => {\n const key = trigger.dataset.sheetTrigger\n if (!key) {\n return\n }\n\n const config = sheetMap.get(key)\n if (!config) {\n return\n }\n\n const handler = (event: Event) => {\n event.preventDefault()\n void openSheet(config, trigger)\n }\n\n trigger.addEventListener('click', handler)\n handlers.push({ element: trigger, event: 'click', handler })\n })\n\n // Escape key handler\n const escapeHandler = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && activeSheet) {\n closeSheet(activeSheet)\n }\n }\n\n document.addEventListener('keydown', escapeHandler)\n\n // Return cleanup function\n return () => {\n handlers.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler)\n })\n document.removeEventListener('keydown', escapeHandler)\n }\n}\n\n// ============================================================================\n// NAVIGATION KEYBOARD SUPPORT\n// ============================================================================\n\n/**\n * Setup keyboard navigation for sidebar nav items.\n */\nexport function setupNavKeyboard(): () => void {\n const navList = document.querySelector<HTMLElement>('[data-nav-list]')\n if (!navList) {\n return () => {\n /* noop */\n }\n }\n\n const getNavItems = () =>\n Array.from(navList.querySelectorAll<HTMLAnchorElement>('[data-nav-item]'))\n\n const handler = (event: KeyboardEvent) => {\n const items = getNavItems()\n const currentIndex = items.indexOf(document.activeElement as HTMLAnchorElement)\n\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0\n items[nextIndex]?.focus()\n } else if (event.key === 'ArrowUp') {\n event.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1\n items[prevIndex]?.focus()\n } else if (event.key === 'Home') {\n event.preventDefault()\n items[0]?.focus()\n } else if (event.key === 'End') {\n event.preventDefault()\n items[items.length - 1]?.focus()\n }\n }\n\n navList.addEventListener('keydown', handler)\n\n return () => {\n navList.removeEventListener('keydown', handler)\n }\n}\n\n// ============================================================================\n// BOOTSTRAP\n// ============================================================================\n\n/**\n * Initialize all layout components.\n */\nexport function initLayout(\n config: {\n sidebar?: SidebarConfig\n userMenu?: UserMenuConfig\n collapsibles?: CollapsibleConfig\n sheets?: SheetSetupConfig\n } = {}\n): () => void {\n const cleanups = [\n setupSidebar(config.sidebar),\n setupUserMenu(config.userMenu),\n setupCollapsibles(config.collapsibles),\n setupSheets(config.sheets),\n setupNavKeyboard(),\n ]\n\n return () => {\n cleanups.forEach(cleanup => {\n cleanup()\n })\n }\n}\n"],"mappings":";;;;;;AAgGA,IAAM,UAAuC;CAC3C,IAAI,OAAO,SAAW,KACpB,OAAO;CAET,IAAI;EACF,OAAO,OAAO;CAChB,QAAQ;EAEN,OADA,QAAQ,KAAK,+BAA+B,GACrC;CACT;AACF,GAEM,KAAmB,MAAyB;CAChD,IAAI;EACF,OAAO,IAAI,IAAI,GAAK,OAAO,SAAS,IAAI,EAAE,WAAW,OAAO,SAAS;CACvE,QAAQ;EACN,OAAO;CACT;AACF,GAMM,IAAkD;CACtD,YAAY;CACZ,mBAAmB;CACnB,gBAAgB;CAChB,WAAW;AACb;AAKA,SAAgB,EAAa,IAAwB,CAAC,GAAe;CACnE,IAAM,IAAU;EAAE,GAAG;EAAwB,GAAG;CAAO,GACjD,IAAS,SAAS,cAA2B,qBAAqB,GAClE,IAAU,SAAS,cAA2B,sBAAsB;CAE1E,IAAI,CAAC,KAAU,CAAC,GACd,aAAa,CAEb;CAGF,IAAM,IAAU,EAAe,GACzB,IAAa,OAAO,WAAW,EAAQ,iBAAiB,GACxD,IAAU,MAAM,KAAK,SAAS,iBAA8B,uBAAuB,CAAC,GACpF,IAAa,MAAM,KAAK,SAAS,iBAA8B,wBAAwB,CAAC,GAExF,IAAY,EAAQ,MAAM;CAChC,EAAQ,KAAK;CAEb,IAAM,UAA4B,GAAS,QAAQ,EAAQ,UAAU,MAAM,aAErE,UAAuB;EAC3B,IAAM,IAAW,EAAW,UACxB,CAAC,EAAO,UAAU,SAAS,EAAQ,cAAc,IACjD,EAAO,UAAU,SAAS,EAAQ,SAAS;EAE/C,EAAQ,SAAQ,MAAU;GAExB,AADA,EAAO,aAAa,iBAAiB,EAAS,SAAS,CAAC,GACxD,EAAO,aAAa,iBAAiB,CAAS;EAChD,CAAC;CACH,GAEM,KAAkB,GAAoB,IAAU,OAAS;EAK7D,AAJA,EAAO,UAAU,OAAO,EAAQ,gBAAgB,CAAS,GACrD,KAAW,EAAW,WACxB,GAAS,QAAQ,EAAQ,YAAY,IAAY,cAAc,UAAU,GAE3E,EAAe;CACjB,GAEM,KAAW,MAAkB;EAEjC,AADA,EAAO,UAAU,OAAO,EAAQ,WAAW,CAAI,GAC/C,EAAe;CACjB,GAEM,UAAwB;EAC5B,AAAI,EAAW,WACb,EAAQ,EAAK,GACb,EAAe,EAAoB,GAAG,EAAK,MAE3C,EAAQ,EAAK,GACb,EAAe,IAAO,EAAK;CAE/B,GAEM,UAA0B;EAC9B,AAAI,EAAW,UAEb,EAAe,CADG,EAAO,UAAU,SAAS,EAAQ,cACpC,CAAS,IAGzB,EAAQ,CADK,EAAO,UAAU,SAAS,EAAQ,SACtC,CAAI;CAEjB,GAEM,UAA2B;EAC/B,EAAQ,EAAK;CACf,GAEM,KAAiB,MAAyB;EAC9C,AAAI,EAAM,QAAQ,YAAY,CAAC,EAAW,WACxC,EAAQ,EAAK;CAEjB;CAgBA,OAbA,EAAQ,SAAQ,MAAU;EACxB,EAAO,iBAAiB,SAAS,CAAiB;CACpD,CAAC,GACD,EAAW,SAAQ,MAAW;EAC5B,EAAQ,iBAAiB,SAAS,CAAkB;CACtD,CAAC,GACD,SAAS,iBAAiB,WAAW,CAAa,GAClD,EAAW,iBAAiB,UAAU,CAAe,GAGrD,EAAgB,SAGH;EAQX,AAPA,EAAQ,SAAQ,MAAU;GACxB,EAAO,oBAAoB,SAAS,CAAiB;EACvD,CAAC,GACD,EAAW,SAAQ,MAAW;GAC5B,EAAQ,oBAAoB,SAAS,CAAkB;EACzD,CAAC,GACD,SAAS,oBAAoB,WAAW,CAAa,GACrD,EAAW,oBAAoB,UAAU,CAAe;CAC1D;AACF;AASA,SAAgB,EAAc,IAAyB,CAAC,GAAe;CACrE,IAAM,IAAkB,EAAO,mBAAmB,uBAC5C,IAAmB,EAAO,oBAAoB,wBAE9C,IAAW,SAAS,cAA2B,kBAAkB,GACjE,IAAU,SAAS,cAAiC,CAAe,GACnE,IAAW,SAAS,cAA2B,CAAgB;CAErE,IAAI,CAAC,KAAY,CAAC,KAAW,CAAC,GAC5B,aAAa,CAEb;CAGF,IAAM,KAAe,MAAsB;EAEzC,AADA,EAAQ,aAAa,iBAAiB,EAAS,SAAS,CAAC,GACzD,EAAS,aAAa,iBAAiB,EAAS,SAAS,CAAC;CAC5D,GAEM,UAAmB,EAAQ,aAAa,eAAe,MAAM,QAE7D,KAAsB,MAAiB;EAE3C,AADA,EAAM,gBAAgB,GACtB,EAAY,CAAC,EAAW,CAAC;CAC3B,GAEM,KAAuB,MAAiB;EAC5C,AAAK,EAAS,SAAS,EAAM,MAAc,KACzC,EAAY,EAAK;CAErB,GAEM,KAAiB,MAAyB;EAC9C,AAAI,EAAM,QAAQ,YAAY,EAAW,MACvC,EAAY,EAAK,GACjB,EAAQ,MAAM;CAElB,GAEM,IAAuB,EAAO,wBAAwB,iCAEtD,KAAyB,MAAyB;EACtD,IAAM,IAAQ,MAAM,KAAK,EAAS,iBAAoC,CAAoB,CAAC,GACrF,IAAe,EAAM,QAAQ,SAAS,aAAkC;EAE9E,AAAI,EAAM,QAAQ,eAChB,EAAM,eAAe,GAErB,EADkB,IAAe,EAAM,SAAS,IAAI,IAAe,IAAI,IACrD,MAAM,KACf,EAAM,QAAQ,aACvB,EAAM,eAAe,GAErB,EADkB,IAAe,IAAI,IAAe,IAAI,EAAM,SAAS,IACrD,MAAM,MACf,EAAM,QAAQ,SAAS,CAAC,EAAM,YAAY,MAAiB,EAAM,SAAS,KAE1E,EAAM,QAAQ,SAAS,EAAM,YAAY,MAAiB,MADnE,EAAY,EAAK;CAIrB,GAEM,KAAwB,MAAyB;EACrD,CACG,EAAM,QAAQ,WAAW,EAAM,QAAQ,OAAO,EAAM,QAAQ,gBAC7D,CAAC,EAAW,MAEZ,EAAM,eAAe,GACrB,EAAY,EAAI,GAChB,iBAAiB;GAEf,EAD2B,cAAiC,CAC5D,GAAW,MAAM;EACnB,GAAG,EAAE;CAET;CAUA,OAPA,EAAQ,iBAAiB,SAAS,CAAkB,GACpD,SAAS,iBAAiB,SAAS,CAAmB,GACtD,SAAS,iBAAiB,WAAW,CAAa,GAClD,EAAS,iBAAiB,WAAW,CAAqB,GAC1D,EAAQ,iBAAiB,WAAW,CAAoB,SAG3C;EAKX,AAJA,EAAQ,oBAAoB,SAAS,CAAkB,GACvD,SAAS,oBAAoB,SAAS,CAAmB,GACzD,SAAS,oBAAoB,WAAW,CAAa,GACrD,EAAS,oBAAoB,WAAW,CAAqB,GAC7D,EAAQ,oBAAoB,WAAW,CAAoB;CAC7D;AACF;AAMA,IAAM,KAAyB,MAC7B,EAAQ,QAAQ,oBAAoB,UAAU,CAAC,EAAQ,UAAU,SAAS,QAAQ,GAEhF,IAAyB,2BAEvB,KAA0B,GAAsB,MAAsB;CAI1E,AAHA,EAAQ,UAAU,OAAO,UAAU,CAAC,CAAQ,GAC5C,EAAQ,UAAU,OAAO,GAAwB,CAAC,CAAQ,GAC1D,EAAQ,QAAQ,kBAAkB,EAAS,SAAS,GACpD,EAAQ,aAAa,eAAe,IAAW,UAAU,MAAM;AACjE,GAEM,KAA0B,GAAkB,MAAsB;CACtE,SAAS,iBAA8B,wBAAwB,EAAS,GAAG,EAAE,SAAQ,MAAU;EAC7F,EAAO,aAAa,iBAAiB,EAAS,SAAS,CAAC;CAC1D,CAAC;AACH;AAKA,SAAgB,EAAkB,IAA4B,CAAC,GAAe;CAC5E,IAAM,EACJ,oBAAiB,IACjB,oBAAiB,UACjB,iBAAc,8BACZ;CAIJ,AAHA,IAAyB,GAGzB,SAAS,iBAA8B,oBAAoB,EAAE,SAAQ,MAAW;EAG9E,EAAuB,GADrB,EAAQ,QAAQ,oBAAoB,UAAU,CAAC,EAAQ,UAAU,SAAS,QAAQ,CAC5C;CAC1C,CAAC;CAED,IAAM,IAAoE,CAAC;CAkC3E,AA/BA,SAAS,iBAA8B,sBAAsB,EAAE,SAAQ,MAAU;EAC/E,IAAM,IAAW,EAAO,QAAQ;EAChC,IAAI,CAAC,GACH;EAGF,IAAM,IAAS,SAAS,cAA2B,CAAQ;EAC3D,IAAI,CAAC,GACH;EAGF,IAAM,IAAa,EAAO,MAAM,EAAS,QAAQ,MAAM,EAAE;EAEzD,AADA,EAAO,aAAa,iBAAiB,CAAU,GAC/C,EAAO,aAAa,iBAAiB,EAAsB,CAAM,EAAE,SAAS,CAAC;EAE7E,IAAM,KAAW,MAAiB;GAChC,EAAM,eAAe;GACrB,IAAM,IAAW,CAAC,EAAsB,CAAM;GAI9C,AAHA,EAAuB,GAAQ,CAAQ,GACvC,EAAuB,GAAU,CAAQ,GAErC,KAAY,KACd,EAAO,eAAe;IAAE,UAAU;IAAgB,OAAO;GAAQ,CAAC;EAEtE;EAGA,AADA,EAAO,iBAAiB,SAAS,CAAO,GACxC,EAAS,KAAK;GAAE,SAAS;GAAQ;EAAQ,CAAC;CAC5C,CAAC,GAGD,SAAS,iBAA8B,wBAAwB,EAAE,SAAQ,MAAU;EACjF,IAAM,IAAW,EAAO,QAAQ;EAChC,IAAI,CAAC,GACH;EAGF,IAAM,IAAS,SAAS,cAA2B,CAAQ;EAC3D,IAAI,CAAC,GACH;EAGF,IAAM,KAAW,MAAiB;GAGhC,AAFA,EAAM,eAAe,GACrB,EAAuB,GAAQ,EAAK,GACpC,EAAuB,GAAU,EAAK;EACxC;EAGA,AADA,EAAO,iBAAiB,SAAS,CAAO,GACxC,EAAS,KAAK;GAAE,SAAS;GAAQ;EAAQ,CAAC;CAC5C,CAAC;CAGD,IAAM,IAAO,OAAO,SAAS;CAC7B,IAAI,GAAM;EACR,IAAM,IAAS,SAAS,cAA2B,CAAI;EACvD,AAAI,GAAQ,QAAQ,gBAAgB,KAAA,MAClC,EAAuB,GAAQ,EAAI,GACnC,EAAuB,GAAM,EAAI;CAErC;CAGA,aAAa;EACX,EAAS,SAAS,EAAE,YAAS,iBAAc;GACzC,EAAQ,oBAAoB,SAAS,CAAO;EAC9C,CAAC;CACH;AACF;AAMA,IAAM,IAAqB,6FAMrB,IAAmB;AAMzB,SAAS,EAAmB,GAAsB,GAAsB;CACtE,EAAQ,gBAAgB,EAAyB,GAAQ,EAAE,UAAU,GAAK,CAAC,CAAC;AAC9E;AAKA,SAAgB,EAAY,IAAgC,CAAC,GAAe;CAC1E,IAAM,EACJ,eAAY,mBACZ,iBAAc,qBACd,0BAAuB,gCACvB,yBAAsB,+BACtB,aAAa,IAAgB,GAC7B,WAAW,IAAc,GACzB,2BAAwB,OACtB,GAEE,oBAAW,IAAI,IAAyB;CAyB9C,IAvBA,SAAS,iBAA8B,cAAc,EAAE,SAAQ,MAAS;EACtE,IAAM,IAAM,EAAM,QAAQ;EAC1B,IAAI,CAAC,GACH;EAGF,IAAM,IAAW,SAAS,cAA2B,yBAAyB,EAAI,GAAG,GAC/E,IAAU,EAAM,cAA2B,sBAAsB;EACnE,CAAC,KAAY,CAAC,KAIlB,EAAS,IAAI,GAAK;GAChB;GACA;GACA;GACA;GACA,cAAc,EAAM,cAAiC,uBAAuB;GAC5E,YAAY,EAAM,cAAiC,qBAAqB;GACxE,eAAe,EAAM,QAAQ;EAC/B,CAAC;CACH,CAAC,GAEG,EAAS,SAAS,GACpB,aAAa,CAEb;CAGF,IAAI,IAAkC,MAEhC,KAAgB,GAAqB,MAAkB;EAK3D,AAJA,EAAO,MAAM,UAAU,OAAO,GAAW,CAAI,GAC7C,EAAO,MAAM,UAAU,OAAO,GAAa,CAAC,CAAI,GAChD,EAAO,SAAS,UAAU,OAAO,GAAsB,CAAI,GAC3D,EAAO,SAAS,UAAU,OAAO,GAAqB,CAAC,CAAI,GAC3D,EAAO,MAAM,aAAa,eAAe,IAAO,UAAU,MAAM;CAClE,GAEM,KAAc,MAAwB;EAI1C,AAHI,GAAa,QAAQ,EAAO,QAC9B,IAAc,OAEhB,EAAa,GAAQ,EAAK;CAC5B,GAEM,IAAY,OAAO,GAAqB,MAA0B;EAMtE,AALI,KAAe,EAAY,QAAQ,EAAO,OAC5C,EAAW,CAAW,GAGxB,IAAc,GACd,EAAa,GAAQ,EAAI;EAEzB,IAAM,IAAM,GAAS,QAAQ,YAAY,EAAO,MAAM,QAAQ,UACxD,IAAgB,GAAS,QAAQ,cAAc,EAAO,eACtD,IAAe,GAAS,QAAQ,iBAAiB,EAAO,MAAM,QAAQ,eACtE,IAAa,GAAS,QAAQ,eAAe,EAAO,MAAM,QAAQ;EAUxE,IARI,EAAO,gBAAgB,MACzB,EAAO,aAAa,OAAO,IAGzB,EAAO,cAAc,MACvB,EAAO,WAAW,OAAO,IAGvB,CAAC,KAAQ,CAAC,KAAyB,CAAC,EAAgB,CAAG,GAAI;GAC7D,EAAmB,EAAO,SAAS,CAAW;GAC9C;EACF;EAEA,EAAmB,EAAO,SAAS,CAAa;EAEhD,IAAI;GACF,IAAM,IAAW,MAAM,MAAM,CAAG;GAChC,IAAI,EAAS,IAAI;IACf,IAAM,IAAS,MAAM,EAAS,KAAK;IAEnC,AADA,EAAmB,EAAO,SAAS,CAAM,GACrC,KAEF,EAD2B,QAAQ,cAA2B,CAC9D,GAAa,MAAM;GAEvB,OAAO,AAAI,IACT,EAAmB,CAAY,IAE/B,EAAmB,EAAO,SAAS,CAAW;EAElD,QAAQ;GACN,AAAI,IACF,EAAmB,CAAY,IAE/B,EAAmB,EAAO,SAAS,CAAW;EAElD;CACF,GAEM,IAAmF,CAAC;CA+B1F,AA7BA,EAAS,SAAQ,MAAU;EACzB,IAAM,KAAgB,MAAiB;GAErC,AADe,EAAM,OACV,QAAQ,oBAAoB,MACrC,EAAM,eAAe,GACrB,EAAW,CAAM;EAErB,GAEM,UAAwB;GAC5B,EAAW,CAAM;EACnB,GAEM,UAAsB;GAC1B,EAAW,CAAM;EACnB;EAOA,AALA,EAAO,MAAM,iBAAiB,SAAS,CAAY,GACnD,EAAO,SAAS,iBAAiB,SAAS,CAAe,GACzD,EAAS,KAAK;GAAE,SAAS,EAAO;GAAO,OAAO;GAAS,SAAS;EAAa,CAAC,GAC9E,EAAS,KAAK;GAAE,SAAS,EAAO;GAAU,OAAO;GAAS,SAAS;EAAgB,CAAC,GAEhF,EAAO,eACT,EAAO,WAAW,iBAAiB,SAAS,CAAa,GACzD,EAAS,KAAK;GAAE,SAAS,EAAO;GAAY,OAAO;GAAS,SAAS;EAAc,CAAC;CAExF,CAAC,GAGD,SAAS,iBAA8B,sBAAsB,EAAE,SAAQ,MAAW;EAChF,IAAM,IAAM,EAAQ,QAAQ;EAC5B,IAAI,CAAC,GACH;EAGF,IAAM,IAAS,EAAS,IAAI,CAAG;EAC/B,IAAI,CAAC,GACH;EAGF,IAAM,KAAW,MAAiB;GAEhC,AADA,EAAM,eAAe,GACrB,EAAe,GAAQ,CAAO;EAChC;EAGA,AADA,EAAQ,iBAAiB,SAAS,CAAO,GACzC,EAAS,KAAK;GAAE,SAAS;GAAS,OAAO;GAAS;EAAQ,CAAC;CAC7D,CAAC;CAGD,IAAM,KAAiB,MAAyB;EAC9C,AAAI,EAAM,QAAQ,YAAY,KAC5B,EAAW,CAAW;CAE1B;CAKA,OAHA,SAAS,iBAAiB,WAAW,CAAa,SAGrC;EAIX,AAHA,EAAS,SAAS,EAAE,YAAS,UAAO,iBAAc;GAChD,EAAQ,oBAAoB,GAAO,CAAO;EAC5C,CAAC,GACD,SAAS,oBAAoB,WAAW,CAAa;CACvD;AACF;AASA,SAAgB,IAA+B;CAC7C,IAAM,IAAU,SAAS,cAA2B,iBAAiB;CACrE,IAAI,CAAC,GACH,aAAa,CAEb;CAGF,IAAM,UACJ,MAAM,KAAK,EAAQ,iBAAoC,iBAAiB,CAAC,GAErE,KAAW,MAAyB;EACxC,IAAM,IAAQ,EAAY,GACpB,IAAe,EAAM,QAAQ,SAAS,aAAkC;EAE9E,AAAI,EAAM,QAAQ,eAChB,EAAM,eAAe,GAErB,EADkB,IAAe,EAAM,SAAS,IAAI,IAAe,IAAI,IACrD,MAAM,KACf,EAAM,QAAQ,aACvB,EAAM,eAAe,GAErB,EADkB,IAAe,IAAI,IAAe,IAAI,EAAM,SAAS,IACrD,MAAM,KACf,EAAM,QAAQ,UACvB,EAAM,eAAe,GACrB,EAAM,IAAI,MAAM,KACP,EAAM,QAAQ,UACvB,EAAM,eAAe,GACrB,EAAM,EAAM,SAAS,IAAI,MAAM;CAEnC;CAIA,OAFA,EAAQ,iBAAiB,WAAW,CAAO,SAE9B;EACX,EAAQ,oBAAoB,WAAW,CAAO;CAChD;AACF;AASA,SAAgB,EACd,IAKI,CAAC,GACO;CACZ,IAAM,IAAW;EACf,EAAa,EAAO,OAAO;EAC3B,EAAc,EAAO,QAAQ;EAC7B,EAAkB,EAAO,YAAY;EACrC,EAAY,EAAO,MAAM;EACzB,EAAiB;CACnB;CAEA,aAAa;EACX,EAAS,SAAQ,MAAW;GAC1B,EAAQ;EACV,CAAC;CACH;AACF"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/layout/index.ts"],"sourcesContent":["/**\n * Layout Components\n * @countermeasure/web-components\n *\n * Shared layout utilities for sidebar, user menu, collapsibles, and sheets.\n */\n\nimport { createSafeMarkupFragment } from '../utils/sanitize'\nimport { navigateDocumentTo } from '../utils/navigation'\nexport {\n AppShell,\n TopMenuBar,\n createAppShell,\n createProductShell,\n createTopMenuBar,\n} from './app-shell'\nexport type {\n AppShellConfig,\n TopMenuBarAction,\n TopMenuBarActionInput,\n TopMenuBarBreadcrumb,\n TopMenuBarConfig,\n TopMenuBarUser,\n} from './app-shell'\nexport {\n CORE_APP_ROUTE_LABELS,\n createCoreAppChromePreset,\n createCoreAppSidebarConfig,\n createCoreAppSidebarSections,\n createCoreAppTopbarActions,\n createCoreAppTopbarConfig,\n getCoreAppRouteLabel,\n mountCoreAppChrome,\n mountCoreAppChromeFromDom,\n} from './core-app-chrome'\nexport type {\n CoreAppChromePreset,\n CoreAppChromeDomMountOptions,\n CoreAppChromeMount,\n CoreAppChromeMountOptions,\n CoreAppChromePresetOptions,\n CoreAppRouteLabel,\n CoreAppSidebarPresetOptions,\n CoreAppTopbarPresetOptions,\n} from './core-app-chrome'\nexport {\n mountCoreAppLibraryDashboard,\n mountCoreAppLibraryDashboardFromDom,\n} from './core-app-library-dashboard'\nexport type {\n CoreAppLibraryConnector,\n CoreAppLibraryConnectorStatus,\n CoreAppLibraryDashboardData,\n CoreAppLibraryDashboardDomMountOptions,\n CoreAppLibraryDashboardError,\n CoreAppLibraryDashboardMount,\n CoreAppLibraryDashboardMountOptions,\n CoreAppLibraryFreshnessBucket,\n CoreAppLibraryMetric,\n CoreAppLibraryMetricTone,\n CoreAppLibraryPipelineSummary,\n CoreAppLibraryTacticDepth,\n} from './core-app-library-dashboard'\nexport { PageHeader, createPageHeader } from './page-header'\nexport type { PageHeaderConfig, PageHeaderMetadata } from './page-header'\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface SidebarConfig {\n storageKey?: string\n desktopBreakpoint?: string\n collapsedClass?: string\n openClass?: string\n}\n\nexport interface UserMenuConfig {\n triggerSelector?: string\n dropdownSelector?: string\n dropdownItemSelector?: string\n}\n\nexport interface CollapsibleConfig {\n scrollIntoView?: boolean\n scrollBehavior?: ScrollBehavior\n hiddenClass?: string\n}\n\nexport interface SheetConfig {\n key: string\n sheet: HTMLElement\n backdrop: HTMLElement\n content: HTMLElement\n fullPageLink?: HTMLAnchorElement | null | undefined\n expandLink?: HTMLAnchorElement | null | undefined\n focusSelector?: string | undefined\n}\n\nexport interface SheetSetupConfig {\n openClass?: string\n hiddenClass?: string\n backdropVisibleClass?: string\n backdropHiddenClass?: string\n spinnerHtml?: string\n errorHtml?: string\n /** Allow fetching sheet content from non-same-origin URLs. Default: false. */\n allowCrossOriginFetch?: boolean\n}\n\n// ============================================================================\n// STORAGE HELPERS\n// ============================================================================\n\nconst resolveStorage = (): Storage | null => {\n if (typeof window === 'undefined') {\n return null\n }\n try {\n return window.localStorage\n } catch {\n console.warn('Unable to access localStorage')\n return null\n }\n}\n\nconst isSameOriginUrl = (url: string): boolean => {\n try {\n return new URL(url, window.location.href).origin === window.location.origin\n } catch {\n return false\n }\n}\n\n// ============================================================================\n// SIDEBAR\n// ============================================================================\n\nconst DEFAULT_SIDEBAR_CONFIG: Required<SidebarConfig> = {\n storageKey: 'cmm-sidebar-state',\n desktopBreakpoint: '(min-width: 1024px)',\n collapsedClass: 'cmm-shell--sidebar-collapsed',\n openClass: 'cmm-shell--sidebar-open',\n}\n\n/**\n * Setup responsive sidebar with collapse/expand functionality.\n */\nexport function setupSidebar(config: SidebarConfig = {}): () => void {\n const options = { ...DEFAULT_SIDEBAR_CONFIG, ...config }\n const layout = document.querySelector<HTMLElement>('[data-shell-layout]')\n const sidebar = document.querySelector<HTMLElement>('[data-shell-sidebar]')\n\n if (!layout || !sidebar) {\n return () => {\n /* noop */\n }\n }\n\n const storage = resolveStorage()\n const mediaQuery = window.matchMedia(options.desktopBreakpoint)\n const toggles = Array.from(document.querySelectorAll<HTMLElement>('[data-sidebar-toggle]'))\n const dismissors = Array.from(document.querySelectorAll<HTMLElement>('[data-sidebar-dismiss]'))\n\n const sidebarId = sidebar.id || 'shell-sidebar'\n sidebar.id = sidebarId\n\n const readStoredCollapsed = () => storage?.getItem(options.storageKey) === 'collapsed'\n\n const syncToggleAria = () => {\n const expanded = mediaQuery.matches\n ? !layout.classList.contains(options.collapsedClass)\n : layout.classList.contains(options.openClass)\n\n toggles.forEach(toggle => {\n toggle.setAttribute('aria-expanded', expanded.toString())\n toggle.setAttribute('aria-controls', sidebarId)\n })\n }\n\n const applyCollapsed = (collapsed: boolean, persist = true) => {\n layout.classList.toggle(options.collapsedClass, collapsed)\n if (persist && mediaQuery.matches) {\n storage?.setItem(options.storageKey, collapsed ? 'collapsed' : 'expanded')\n }\n syncToggleAria()\n }\n\n const setOpen = (open: boolean) => {\n layout.classList.toggle(options.openClass, open)\n syncToggleAria()\n }\n\n const syncForViewport = () => {\n if (mediaQuery.matches) {\n setOpen(false)\n applyCollapsed(readStoredCollapsed(), false)\n } else {\n setOpen(false)\n applyCollapsed(false, false)\n }\n }\n\n const handleToggleClick = () => {\n if (mediaQuery.matches) {\n const collapsed = layout.classList.contains(options.collapsedClass)\n applyCollapsed(!collapsed)\n } else {\n const open = layout.classList.contains(options.openClass)\n setOpen(!open)\n }\n }\n\n const handleDismissClick = () => {\n setOpen(false)\n }\n\n const handleKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && !mediaQuery.matches) {\n setOpen(false)\n }\n }\n\n // Attach listeners\n toggles.forEach(toggle => {\n toggle.addEventListener('click', handleToggleClick)\n })\n dismissors.forEach(dismiss => {\n dismiss.addEventListener('click', handleDismissClick)\n })\n document.addEventListener('keydown', handleKeydown)\n mediaQuery.addEventListener('change', syncForViewport)\n\n // Initialize\n syncForViewport()\n\n // Return cleanup function\n return () => {\n toggles.forEach(toggle => {\n toggle.removeEventListener('click', handleToggleClick)\n })\n dismissors.forEach(dismiss => {\n dismiss.removeEventListener('click', handleDismissClick)\n })\n document.removeEventListener('keydown', handleKeydown)\n mediaQuery.removeEventListener('change', syncForViewport)\n }\n}\n\n// ============================================================================\n// USER MENU\n// ============================================================================\n\n/**\n * Setup user menu dropdown with keyboard navigation.\n */\nexport function setupUserMenu(config: UserMenuConfig = {}): () => void {\n const triggerSelector = config.triggerSelector ?? '[data-user-trigger]'\n const dropdownSelector = config.dropdownSelector ?? '[data-user-dropdown]'\n\n const userMenu = document.querySelector<HTMLElement>('[data-user-menu]')\n const trigger = document.querySelector<HTMLButtonElement>(triggerSelector)\n const dropdown = document.querySelector<HTMLElement>(dropdownSelector)\n\n if (!userMenu || !trigger || !dropdown) {\n return () => {\n /* noop */\n }\n }\n\n const setExpanded = (expanded: boolean) => {\n trigger.setAttribute('aria-expanded', expanded.toString())\n userMenu.setAttribute('aria-expanded', expanded.toString())\n }\n\n const isExpanded = () => trigger.getAttribute('aria-expanded') === 'true'\n\n const handleTriggerClick = (event: Event) => {\n event.stopPropagation()\n setExpanded(!isExpanded())\n }\n\n const handleDocumentClick = (event: Event) => {\n if (!userMenu.contains(event.target as Node)) {\n setExpanded(false)\n }\n }\n\n const handleKeydown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && isExpanded()) {\n setExpanded(false)\n trigger.focus()\n }\n }\n\n const dropdownItemSelector = config.dropdownItemSelector ?? '.cmm-user-menu__dropdown-item'\n\n const handleDropdownKeydown = (event: KeyboardEvent) => {\n const items = Array.from(dropdown.querySelectorAll<HTMLAnchorElement>(dropdownItemSelector))\n const currentIndex = items.indexOf(document.activeElement as HTMLAnchorElement)\n\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0\n items[nextIndex]?.focus()\n } else if (event.key === 'ArrowUp') {\n event.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1\n items[prevIndex]?.focus()\n } else if (event.key === 'Tab' && !event.shiftKey && currentIndex === items.length - 1) {\n setExpanded(false)\n } else if (event.key === 'Tab' && event.shiftKey && currentIndex === 0) {\n setExpanded(false)\n }\n }\n\n const handleTriggerKeydown = (event: KeyboardEvent) => {\n if (\n (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') &&\n !isExpanded()\n ) {\n event.preventDefault()\n setExpanded(true)\n setTimeout(() => {\n const firstItem = dropdown.querySelector<HTMLAnchorElement>(dropdownItemSelector)\n firstItem?.focus()\n }, 50)\n }\n }\n\n // Attach listeners\n trigger.addEventListener('click', handleTriggerClick)\n document.addEventListener('click', handleDocumentClick)\n document.addEventListener('keydown', handleKeydown)\n dropdown.addEventListener('keydown', handleDropdownKeydown)\n trigger.addEventListener('keydown', handleTriggerKeydown)\n\n // Return cleanup function\n return () => {\n trigger.removeEventListener('click', handleTriggerClick)\n document.removeEventListener('click', handleDocumentClick)\n document.removeEventListener('keydown', handleKeydown)\n dropdown.removeEventListener('keydown', handleDropdownKeydown)\n trigger.removeEventListener('keydown', handleTriggerKeydown)\n }\n}\n\n// ============================================================================\n// COLLAPSIBLES\n// ============================================================================\n\nconst isCollapsibleExpanded = (section: HTMLElement) =>\n section.dataset.collapsibleOpen === 'true' || !section.classList.contains('hidden')\n\nlet collapsibleHiddenClass = 'cmm-collapsible--hidden'\n\nconst updateCollapsibleState = (section: HTMLElement, expanded: boolean) => {\n section.classList.toggle('hidden', !expanded)\n section.classList.toggle(collapsibleHiddenClass, !expanded)\n section.dataset.collapsibleOpen = expanded.toString()\n section.setAttribute('aria-hidden', expanded ? 'false' : 'true')\n}\n\nconst syncCollapsibleToggles = (selector: string, expanded: boolean) => {\n document.querySelectorAll<HTMLElement>(`[data-toggle-target='${selector}']`).forEach(toggle => {\n toggle.setAttribute('aria-expanded', expanded.toString())\n })\n}\n\n/**\n * Setup collapsible sections with toggle buttons.\n */\nexport function setupCollapsibles(config: CollapsibleConfig = {}): () => void {\n const {\n scrollIntoView = true,\n scrollBehavior = 'smooth',\n hiddenClass = 'cmm-collapsible--hidden',\n } = config\n collapsibleHiddenClass = hiddenClass\n\n // Initialize all collapsible sections\n document.querySelectorAll<HTMLElement>('[data-collapsible]').forEach(section => {\n const expanded =\n section.dataset.collapsibleOpen === 'true' || !section.classList.contains('hidden')\n updateCollapsibleState(section, expanded)\n })\n\n const handlers: { element: HTMLElement; handler: (e: Event) => void }[] = []\n\n // Setup toggle triggers\n document.querySelectorAll<HTMLElement>('[data-toggle-target]').forEach(toggle => {\n const selector = toggle.dataset.toggleTarget\n if (!selector) {\n return\n }\n\n const target = document.querySelector<HTMLElement>(selector)\n if (!target) {\n return\n }\n\n const ariaTarget = target.id || selector.replace(/^#/, '')\n toggle.setAttribute('aria-controls', ariaTarget)\n toggle.setAttribute('aria-expanded', isCollapsibleExpanded(target).toString())\n\n const handler = (event: Event) => {\n event.preventDefault()\n const expanded = !isCollapsibleExpanded(target)\n updateCollapsibleState(target, expanded)\n syncCollapsibleToggles(selector, expanded)\n\n if (expanded && scrollIntoView) {\n target.scrollIntoView({ behavior: scrollBehavior, block: 'start' })\n }\n }\n\n toggle.addEventListener('click', handler)\n handlers.push({ element: toggle, handler })\n })\n\n // Setup collapse triggers (close only)\n document.querySelectorAll<HTMLElement>('[data-collapse-target]').forEach(toggle => {\n const selector = toggle.dataset.collapseTarget\n if (!selector) {\n return\n }\n\n const target = document.querySelector<HTMLElement>(selector)\n if (!target) {\n return\n }\n\n const handler = (event: Event) => {\n event.preventDefault()\n updateCollapsibleState(target, false)\n syncCollapsibleToggles(selector, false)\n }\n\n toggle.addEventListener('click', handler)\n handlers.push({ element: toggle, handler })\n })\n\n // Handle URL hash for deep linking\n const hash = window.location.hash\n if (hash) {\n const target = document.querySelector<HTMLElement>(hash)\n if (target?.dataset.collapsible !== undefined) {\n updateCollapsibleState(target, true)\n syncCollapsibleToggles(hash, true)\n }\n }\n\n // Return cleanup function\n return () => {\n handlers.forEach(({ element, handler }) => {\n element.removeEventListener('click', handler)\n })\n }\n}\n\n// ============================================================================\n// SHEETS / SIDE PANELS\n// ============================================================================\n\nconst SHEET_SPINNER_HTML = `\n <div class=\"cmm-sheet__loading\">\n <div class=\"cmm-spinner\"></div>\n </div>\n`\n\nconst SHEET_ERROR_HTML = `\n <div class=\"cmm-sheet__error\">\n <p>Failed to load content. Please try the full page.</p>\n </div>\n`\n\nfunction replaceSheetMarkup(element: HTMLElement, markup: string): void {\n element.replaceChildren(createSafeMarkupFragment(markup, { allowSvg: true }))\n}\n\n/**\n * Setup side sheet/drawer components.\n */\nexport function setupSheets(setupConfig: SheetSetupConfig = {}): () => void {\n const {\n openClass = 'cmm-sheet--open',\n hiddenClass = 'cmm-sheet--hidden',\n backdropVisibleClass = 'cmm-sheet__backdrop--visible',\n backdropHiddenClass = 'cmm-sheet__backdrop--hidden',\n spinnerHtml: spinnerMarkup = SHEET_SPINNER_HTML,\n errorHtml: errorMarkup = SHEET_ERROR_HTML,\n allowCrossOriginFetch = false,\n } = setupConfig\n\n const sheetMap = new Map<string, SheetConfig>()\n\n document.querySelectorAll<HTMLElement>('[data-sheet]').forEach(sheet => {\n const key = sheet.dataset.sheet\n if (!key) {\n return\n }\n\n const backdrop = document.querySelector<HTMLElement>(`[data-sheet-backdrop='${key}']`)\n const content = sheet.querySelector<HTMLElement>('[data-sheet-content]')\n if (!backdrop || !content) {\n return\n }\n\n sheetMap.set(key, {\n key,\n sheet,\n backdrop,\n content,\n fullPageLink: sheet.querySelector<HTMLAnchorElement>('[data-sheet-fullpage]'),\n expandLink: sheet.querySelector<HTMLAnchorElement>('[data-sheet-expand]'),\n focusSelector: sheet.dataset.sheetFocus,\n })\n })\n\n if (sheetMap.size === 0) {\n return () => {\n /* noop */\n }\n }\n\n let activeSheet: SheetConfig | null = null\n\n const setOpenState = (config: SheetConfig, open: boolean) => {\n config.sheet.classList.toggle(openClass, open)\n config.sheet.classList.toggle(hiddenClass, !open)\n config.backdrop.classList.toggle(backdropVisibleClass, open)\n config.backdrop.classList.toggle(backdropHiddenClass, !open)\n config.sheet.setAttribute('aria-hidden', open ? 'false' : 'true')\n }\n\n const closeSheet = (config: SheetConfig) => {\n if (activeSheet?.key === config.key) {\n activeSheet = null\n }\n setOpenState(config, false)\n }\n\n const openSheet = async (config: SheetConfig, trigger?: HTMLElement) => {\n if (activeSheet && activeSheet.key !== config.key) {\n closeSheet(activeSheet)\n }\n\n activeSheet = config\n setOpenState(config, true)\n\n const url = trigger?.dataset.sheetUrl ?? config.sheet.dataset.sheetUrl\n const focusSelector = trigger?.dataset.sheetFocus ?? config.focusSelector\n const fullPageHref = trigger?.dataset.sheetFullpage ?? config.sheet.dataset.sheetFullpage\n const expandHref = trigger?.dataset.sheetExpand ?? config.sheet.dataset.sheetExpand\n\n if (config.fullPageLink && fullPageHref) {\n config.fullPageLink.href = fullPageHref\n }\n\n if (config.expandLink && expandHref) {\n config.expandLink.href = expandHref\n }\n\n if (!url || (!allowCrossOriginFetch && !isSameOriginUrl(url))) {\n replaceSheetMarkup(config.content, errorMarkup)\n return\n }\n\n replaceSheetMarkup(config.content, spinnerMarkup)\n\n try {\n const response = await fetch(url)\n if (response.ok) {\n const markup = await response.text()\n replaceSheetMarkup(config.content, markup)\n if (focusSelector) {\n const focusTarget = config.content.querySelector<HTMLElement>(focusSelector)\n focusTarget?.focus()\n }\n } else if (fullPageHref) {\n navigateDocumentTo(fullPageHref)\n } else {\n replaceSheetMarkup(config.content, errorMarkup)\n }\n } catch {\n if (fullPageHref) {\n navigateDocumentTo(fullPageHref)\n } else {\n replaceSheetMarkup(config.content, errorMarkup)\n }\n }\n }\n\n const handlers: { element: HTMLElement; event: string; handler: (e: Event) => void }[] = []\n\n sheetMap.forEach(config => {\n const closeHandler = (event: Event) => {\n const target = event.target as HTMLElement\n if (target.closest('[data-sheet-close]')) {\n event.preventDefault()\n closeSheet(config)\n }\n }\n\n const backdropHandler = () => {\n closeSheet(config)\n }\n\n const expandHandler = () => {\n closeSheet(config)\n }\n\n config.sheet.addEventListener('click', closeHandler)\n config.backdrop.addEventListener('click', backdropHandler)\n handlers.push({ element: config.sheet, event: 'click', handler: closeHandler })\n handlers.push({ element: config.backdrop, event: 'click', handler: backdropHandler })\n\n if (config.expandLink) {\n config.expandLink.addEventListener('click', expandHandler)\n handlers.push({ element: config.expandLink, event: 'click', handler: expandHandler })\n }\n })\n\n // Setup triggers\n document.querySelectorAll<HTMLElement>('[data-sheet-trigger]').forEach(trigger => {\n const key = trigger.dataset.sheetTrigger\n if (!key) {\n return\n }\n\n const config = sheetMap.get(key)\n if (!config) {\n return\n }\n\n const handler = (event: Event) => {\n event.preventDefault()\n void openSheet(config, trigger)\n }\n\n trigger.addEventListener('click', handler)\n handlers.push({ element: trigger, event: 'click', handler })\n })\n\n // Escape key handler\n const escapeHandler = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && activeSheet) {\n closeSheet(activeSheet)\n }\n }\n\n document.addEventListener('keydown', escapeHandler)\n\n // Return cleanup function\n return () => {\n handlers.forEach(({ element, event, handler }) => {\n element.removeEventListener(event, handler)\n })\n document.removeEventListener('keydown', escapeHandler)\n }\n}\n\n// ============================================================================\n// NAVIGATION KEYBOARD SUPPORT\n// ============================================================================\n\n/**\n * Setup keyboard navigation for sidebar nav items.\n */\nexport function setupNavKeyboard(): () => void {\n const navList = document.querySelector<HTMLElement>('[data-nav-list]')\n if (!navList) {\n return () => {\n /* noop */\n }\n }\n\n const getNavItems = () =>\n Array.from(navList.querySelectorAll<HTMLAnchorElement>('[data-nav-item]'))\n\n const handler = (event: KeyboardEvent) => {\n const items = getNavItems()\n const currentIndex = items.indexOf(document.activeElement as HTMLAnchorElement)\n\n if (event.key === 'ArrowDown') {\n event.preventDefault()\n const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0\n items[nextIndex]?.focus()\n } else if (event.key === 'ArrowUp') {\n event.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1\n items[prevIndex]?.focus()\n } else if (event.key === 'Home') {\n event.preventDefault()\n items[0]?.focus()\n } else if (event.key === 'End') {\n event.preventDefault()\n items[items.length - 1]?.focus()\n }\n }\n\n navList.addEventListener('keydown', handler)\n\n return () => {\n navList.removeEventListener('keydown', handler)\n }\n}\n\n// ============================================================================\n// BOOTSTRAP\n// ============================================================================\n\n/**\n * Initialize all layout components.\n */\nexport function initLayout(\n config: {\n sidebar?: SidebarConfig\n userMenu?: UserMenuConfig\n collapsibles?: CollapsibleConfig\n sheets?: SheetSetupConfig\n } = {}\n): () => void {\n const cleanups = [\n setupSidebar(config.sidebar),\n setupUserMenu(config.userMenu),\n setupCollapsibles(config.collapsibles),\n setupSheets(config.sheets),\n setupNavKeyboard(),\n ]\n\n return () => {\n cleanups.forEach(cleanup => {\n cleanup()\n })\n }\n}\n"],"mappings":"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"}
|
|
@@ -23,10 +23,12 @@ export declare function Wordmark({ className, size, variant, subtitle, label, de
|
|
|
23
23
|
export interface BrandLockupProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
24
24
|
markSize?: BrandSize | number;
|
|
25
25
|
label?: string;
|
|
26
|
+
subtitle?: string;
|
|
27
|
+
wordmarkCase?: BrandLockupConfig['wordmarkCase'];
|
|
26
28
|
decorative?: boolean;
|
|
27
29
|
showWordmark?: boolean;
|
|
28
30
|
}
|
|
29
|
-
export declare function BrandLockup({ className, markSize, label, decorative, showWordmark, ...props }: BrandLockupProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare function BrandLockup({ className, markSize, label, subtitle, wordmarkCase, decorative, showWordmark, ...props }: BrandLockupProps): import("react/jsx-runtime").JSX.Element;
|
|
30
32
|
export interface ConnectorLogoProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
31
33
|
name: string;
|
|
32
34
|
src?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/brand/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAA;AAG/B,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC;IACtE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EACT,IAAS,EACT,KAAgC,EAChC,UAAiB,EACjB,GAAG,KAAK,EACT,EAAE,YAAY,2CA6Cd;AAED,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACzE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACzB,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,IAAS,EACT,OAAgB,EAChB,QAAQ,EACR,KAAwB,EACxB,UAAkB,EAClB,GAAG,KAAK,EACT,EAAE,aAAa,2CAgEf;AAED,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IAC7E,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAa,EACb,KAAwB,EACxB,UAAkB,EAClB,YAAmB,EACnB,GAAG,KAAK,EACT,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/brand/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAA;AAG/B,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC;IACtE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,OAAO,CAAC,EACtB,SAAS,EACT,IAAS,EACT,KAAgC,EAChC,UAAiB,EACjB,GAAG,KAAK,EACT,EAAE,YAAY,2CA6Cd;AAED,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACzE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACzB,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,IAAS,EACT,OAAgB,EAChB,QAAQ,EACR,KAAwB,EACxB,UAAkB,EAClB,GAAG,KAAK,EACT,EAAE,aAAa,2CAgEf;AAED,MAAM,WAAW,gBAAiB,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IAC7E,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAA;IAChD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,WAAW,CAAC,EAC1B,SAAS,EACT,QAAa,EACb,KAAwB,EACxB,QAAQ,EACR,YAA0B,EAC1B,UAAkB,EAClB,YAAmB,EACnB,GAAG,KAAK,EACT,EAAE,gBAAgB,2CAiClB;AAED,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;IAC/E,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,iBAAiB,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,IAAI,EACJ,GAAG,EACH,IAAS,EACT,KAAK,EACL,UAAkB,EAClB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,kBAAkB,2CA6BpB;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAA;AAClD,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAA;AAClD,MAAM,MAAM,2BAA2B,GAAG,aAAa,CAAA;AACvD,MAAM,MAAM,2BAA2B,GAAG,aAAa,CAAA;AACvD,MAAM,MAAM,8BAA8B,GAAG,gBAAgB,CAAA;AAC7D,MAAM,MAAM,8BAA8B,GAAG,gBAAgB,CAAA;AAC7D,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAEjC,eAAO,MAAM,kBAAkB,gBAAU,CAAA;AACzC,eAAO,MAAM,kBAAkB,gBAAU,CAAA;AACzC,eAAO,MAAM,sBAAsB,iBAAW,CAAA;AAC9C,eAAO,MAAM,sBAAsB,iBAAW,CAAA;AAC9C,eAAO,MAAM,yBAAyB,oBAAc,CAAA;AACpD,eAAO,MAAM,yBAAyB,oBAAc,CAAA"}
|
package/dist/react/brand.js
CHANGED
|
@@ -110,27 +110,33 @@ function c({ className: e, size: t = 32, variant: n = "auto", subtitle: r, label
|
|
|
110
110
|
})]
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
function l({ className: e, markSize: t = 22, label: n = "CounterMeasure",
|
|
114
|
-
let
|
|
113
|
+
function l({ className: e, markSize: t = 22, label: n = "CounterMeasure", subtitle: r, wordmarkCase: c = "uppercase", decorative: l = !1, showWordmark: u = !0, ...d }) {
|
|
114
|
+
let f = l ? { "aria-hidden": !0 } : {
|
|
115
115
|
role: "img",
|
|
116
116
|
"aria-label": n
|
|
117
117
|
};
|
|
118
118
|
return /* @__PURE__ */ o("span", {
|
|
119
|
-
className: i("cmm-brand-lockup", e),
|
|
120
|
-
...
|
|
121
|
-
...
|
|
119
|
+
className: i("cmm-brand-lockup", c === "title" && "cmm-brand-lockup--title", e),
|
|
120
|
+
...f,
|
|
121
|
+
...d,
|
|
122
122
|
children: [/* @__PURE__ */ a(s, {
|
|
123
123
|
size: t,
|
|
124
124
|
decorative: !0
|
|
125
|
-
}),
|
|
126
|
-
className: "cmm-brand-
|
|
125
|
+
}), u ? /* @__PURE__ */ o("span", {
|
|
126
|
+
className: "cmm-brand-lockup__copy",
|
|
127
127
|
"aria-hidden": "true",
|
|
128
|
-
children: [/* @__PURE__ */
|
|
129
|
-
className: "cmm-brand-
|
|
130
|
-
children: "
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
128
|
+
children: [/* @__PURE__ */ o("span", {
|
|
129
|
+
className: "cmm-brand-lockup__wordmark",
|
|
130
|
+
children: [/* @__PURE__ */ a("span", {
|
|
131
|
+
className: "cmm-brand-lockup__counter",
|
|
132
|
+
children: c === "title" ? "Counter" : "COUNTER"
|
|
133
|
+
}), /* @__PURE__ */ a("span", {
|
|
134
|
+
className: "cmm-brand-lockup__measure",
|
|
135
|
+
children: c === "title" ? "Measure" : "MEASURE"
|
|
136
|
+
})]
|
|
137
|
+
}), r === void 0 ? null : /* @__PURE__ */ a("span", {
|
|
138
|
+
className: "cmm-brand-lockup__subtitle",
|
|
139
|
+
children: r
|
|
134
140
|
})]
|
|
135
141
|
}) : null]
|
|
136
142
|
});
|
package/dist/react/brand.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brand.js","names":[],"sources":["../../src/react/brand/index.tsx"],"sourcesContent":["/**\n * CounterMeasure brand wrappers.\n *\n * React wrappers render the same semantic SVGs and CSS classes as the vanilla\n * brand helpers in `src/components/brand`.\n */\n\nimport * as React from 'react'\n\nimport {\n getBrandSizeClass,\n getConnectorLogoInitial,\n getConnectorLogoSizeClass,\n getConnectorLogoTone,\n type BrandSize,\n type BrandLockupConfig,\n type ConnectorLogoSize,\n type WordmarkVariant,\n} from '../../components/brand'\nimport { cn } from '../primitives/utils'\n\nexport interface DiamondProps extends React.SVGAttributes<SVGSVGElement> {\n size?: BrandSize | number\n label?: string\n decorative?: boolean\n}\n\nexport function Diamond({\n className,\n size = 24,\n label = 'CounterMeasure diamond',\n decorative = true,\n ...props\n}: DiamondProps) {\n const sizeClass = getBrandSizeClass('cmm-diamond', size)\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label }\n\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 46.64 46.64\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn('cmm-diamond', sizeClass, className)}\n {...accessibilityProps}\n {...props}\n >\n <rect\n x=\"2.62\"\n y=\"16.42\"\n width=\"13.8\"\n height=\"13.8\"\n rx=\"0.57\"\n transform=\"translate(-13.7 13.56) rotate(-45)\"\n className=\"cmm-diamond__foreground\"\n />\n <rect\n x=\"16.42\"\n y=\"30.22\"\n width=\"13.8\"\n height=\"13.8\"\n rx=\"0.57\"\n transform=\"translate(-19.42 27.36) rotate(-45)\"\n className=\"cmm-diamond__slate\"\n />\n <rect\n x=\"16.42\"\n y=\"2.62\"\n width=\"13.8\"\n height=\"13.8\"\n rx=\"0.57\"\n transform=\"translate(0.1 19.28) rotate(-45)\"\n className=\"cmm-diamond__orange\"\n />\n </svg>\n )\n}\n\nexport interface WordmarkProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: BrandSize | number\n variant?: WordmarkVariant\n subtitle?: string\n label?: string\n decorative?: boolean\n}\n\nexport function Wordmark({\n className,\n size = 32,\n variant = 'auto',\n subtitle,\n label = 'CounterMeasure',\n decorative = false,\n ...props\n}: WordmarkProps) {\n const width = Math.round(size * (220 / 32) * 100) / 100\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label }\n\n return (\n <div\n className={cn('cmm-wordmark', `cmm-wordmark--${variant}`, className)}\n {...accessibilityProps}\n {...props}\n >\n <svg\n width={width}\n height={size}\n viewBox=\"0 0 220 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"cmm-wordmark__svg\"\n aria-hidden=\"true\"\n >\n <g transform=\"translate(0,3)\">\n <rect\n x=\"1.78\"\n y=\"11.16\"\n width=\"9.4\"\n height=\"9.4\"\n rx=\"0.4\"\n transform=\"translate(-9.32 9.22) rotate(-45)\"\n className=\"cmm-wordmark__foreground\"\n />\n <rect\n x=\"11.16\"\n y=\"20.54\"\n width=\"9.4\"\n height=\"9.4\"\n rx=\"0.4\"\n transform=\"translate(-13.21 18.6) rotate(-45)\"\n className=\"cmm-wordmark__slate\"\n />\n <rect\n x=\"11.16\"\n y=\"1.78\"\n width=\"9.4\"\n height=\"9.4\"\n rx=\"0.4\"\n transform=\"translate(0.07 13.11) rotate(-45)\"\n className=\"cmm-wordmark__orange\"\n />\n </g>\n <text\n x=\"42\"\n y=\"22\"\n className=\"cmm-wordmark__text\"\n fontFamily=\"Outfit, sans-serif\"\n fontSize=\"18\"\n fontWeight=\"600\"\n letterSpacing=\"-0.01em\"\n >\n CounterMeasure\n </text>\n </svg>\n {subtitle !== undefined ? <span className=\"cmm-wordmark__subtitle\">{subtitle}</span> : null}\n </div>\n )\n}\n\nexport interface BrandLockupProps extends React.HTMLAttributes<HTMLSpanElement> {\n markSize?: BrandSize | number\n label?: string\n decorative?: boolean\n showWordmark?: boolean\n}\n\nexport function BrandLockup({\n className,\n markSize = 22,\n label = 'CounterMeasure',\n decorative = false,\n showWordmark = true,\n ...props\n}: BrandLockupProps) {\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label }\n\n return (\n <span className={cn('cmm-brand-lockup', className)} {...accessibilityProps} {...props}>\n <Diamond size={markSize} decorative />\n {showWordmark ? (\n <span className=\"cmm-brand-lockup__wordmark\" aria-hidden=\"true\">\n <span className=\"cmm-brand-lockup__counter\">COUNTER</span>\n <span className=\"cmm-brand-lockup__measure\">MEASURE</span>\n </span>\n ) : null}\n </span>\n )\n}\n\nexport interface ConnectorLogoProps extends React.HTMLAttributes<HTMLSpanElement> {\n name: string\n src?: string\n size?: ConnectorLogoSize\n label?: string\n decorative?: boolean\n}\n\nexport function ConnectorLogo({\n className,\n name,\n src,\n size = 32,\n label,\n decorative = false,\n children,\n ...props\n}: ConnectorLogoProps) {\n const hasAsset = src !== undefined || children !== undefined\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label ?? `${name} connector` }\n\n return (\n <span\n className={cn(\n 'cmm-connector-logo',\n getConnectorLogoSizeClass(size),\n `cmm-connector-logo--vendor-${getConnectorLogoTone(name)}`,\n hasAsset && 'cmm-connector-logo--asset',\n className\n )}\n {...accessibilityProps}\n {...props}\n >\n {src !== undefined ? (\n <img className=\"cmm-connector-logo__asset\" src={src} alt=\"\" aria-hidden=\"true\" />\n ) : children !== undefined ? (\n <span className=\"cmm-connector-logo__asset\" aria-hidden=\"true\">\n {children}\n </span>\n ) : (\n getConnectorLogoInitial(name)\n )}\n </span>\n )\n}\n\nexport type CountermeasureLogoProps = DiamondProps\nexport type CounterMeasureLogoProps = DiamondProps\nexport type CountermeasureWordmarkProps = WordmarkProps\nexport type CounterMeasureWordmarkProps = WordmarkProps\nexport type CountermeasureBrandLockupProps = BrandLockupProps\nexport type CounterMeasureBrandLockupProps = BrandLockupProps\nexport type { BrandLockupConfig }\n\nexport const CountermeasureLogo = Diamond\nexport const CounterMeasureLogo = Diamond\nexport const CountermeasureWordmark = Wordmark\nexport const CounterMeasureWordmark = Wordmark\nexport const CountermeasureBrandLockup = BrandLockup\nexport const CounterMeasureBrandLockup = BrandLockup\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"brand.js","names":[],"sources":["../../src/react/brand/index.tsx"],"sourcesContent":["/**\n * CounterMeasure brand wrappers.\n *\n * React wrappers render the same semantic SVGs and CSS classes as the vanilla\n * brand helpers in `src/components/brand`.\n */\n\nimport * as React from 'react'\n\nimport {\n getBrandSizeClass,\n getConnectorLogoInitial,\n getConnectorLogoSizeClass,\n getConnectorLogoTone,\n type BrandSize,\n type BrandLockupConfig,\n type ConnectorLogoSize,\n type WordmarkVariant,\n} from '../../components/brand'\nimport { cn } from '../primitives/utils'\n\nexport interface DiamondProps extends React.SVGAttributes<SVGSVGElement> {\n size?: BrandSize | number\n label?: string\n decorative?: boolean\n}\n\nexport function Diamond({\n className,\n size = 24,\n label = 'CounterMeasure diamond',\n decorative = true,\n ...props\n}: DiamondProps) {\n const sizeClass = getBrandSizeClass('cmm-diamond', size)\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label }\n\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 46.64 46.64\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={cn('cmm-diamond', sizeClass, className)}\n {...accessibilityProps}\n {...props}\n >\n <rect\n x=\"2.62\"\n y=\"16.42\"\n width=\"13.8\"\n height=\"13.8\"\n rx=\"0.57\"\n transform=\"translate(-13.7 13.56) rotate(-45)\"\n className=\"cmm-diamond__foreground\"\n />\n <rect\n x=\"16.42\"\n y=\"30.22\"\n width=\"13.8\"\n height=\"13.8\"\n rx=\"0.57\"\n transform=\"translate(-19.42 27.36) rotate(-45)\"\n className=\"cmm-diamond__slate\"\n />\n <rect\n x=\"16.42\"\n y=\"2.62\"\n width=\"13.8\"\n height=\"13.8\"\n rx=\"0.57\"\n transform=\"translate(0.1 19.28) rotate(-45)\"\n className=\"cmm-diamond__orange\"\n />\n </svg>\n )\n}\n\nexport interface WordmarkProps extends React.HTMLAttributes<HTMLDivElement> {\n size?: BrandSize | number\n variant?: WordmarkVariant\n subtitle?: string\n label?: string\n decorative?: boolean\n}\n\nexport function Wordmark({\n className,\n size = 32,\n variant = 'auto',\n subtitle,\n label = 'CounterMeasure',\n decorative = false,\n ...props\n}: WordmarkProps) {\n const width = Math.round(size * (220 / 32) * 100) / 100\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label }\n\n return (\n <div\n className={cn('cmm-wordmark', `cmm-wordmark--${variant}`, className)}\n {...accessibilityProps}\n {...props}\n >\n <svg\n width={width}\n height={size}\n viewBox=\"0 0 220 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"cmm-wordmark__svg\"\n aria-hidden=\"true\"\n >\n <g transform=\"translate(0,3)\">\n <rect\n x=\"1.78\"\n y=\"11.16\"\n width=\"9.4\"\n height=\"9.4\"\n rx=\"0.4\"\n transform=\"translate(-9.32 9.22) rotate(-45)\"\n className=\"cmm-wordmark__foreground\"\n />\n <rect\n x=\"11.16\"\n y=\"20.54\"\n width=\"9.4\"\n height=\"9.4\"\n rx=\"0.4\"\n transform=\"translate(-13.21 18.6) rotate(-45)\"\n className=\"cmm-wordmark__slate\"\n />\n <rect\n x=\"11.16\"\n y=\"1.78\"\n width=\"9.4\"\n height=\"9.4\"\n rx=\"0.4\"\n transform=\"translate(0.07 13.11) rotate(-45)\"\n className=\"cmm-wordmark__orange\"\n />\n </g>\n <text\n x=\"42\"\n y=\"22\"\n className=\"cmm-wordmark__text\"\n fontFamily=\"Outfit, sans-serif\"\n fontSize=\"18\"\n fontWeight=\"600\"\n letterSpacing=\"-0.01em\"\n >\n CounterMeasure\n </text>\n </svg>\n {subtitle !== undefined ? <span className=\"cmm-wordmark__subtitle\">{subtitle}</span> : null}\n </div>\n )\n}\n\nexport interface BrandLockupProps extends React.HTMLAttributes<HTMLSpanElement> {\n markSize?: BrandSize | number\n label?: string\n subtitle?: string\n wordmarkCase?: BrandLockupConfig['wordmarkCase']\n decorative?: boolean\n showWordmark?: boolean\n}\n\nexport function BrandLockup({\n className,\n markSize = 22,\n label = 'CounterMeasure',\n subtitle,\n wordmarkCase = 'uppercase',\n decorative = false,\n showWordmark = true,\n ...props\n}: BrandLockupProps) {\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label }\n\n return (\n <span\n className={cn(\n 'cmm-brand-lockup',\n wordmarkCase === 'title' && 'cmm-brand-lockup--title',\n className\n )}\n {...accessibilityProps}\n {...props}\n >\n <Diamond size={markSize} decorative />\n {showWordmark ? (\n <span className=\"cmm-brand-lockup__copy\" aria-hidden=\"true\">\n <span className=\"cmm-brand-lockup__wordmark\">\n <span className=\"cmm-brand-lockup__counter\">\n {wordmarkCase === 'title' ? 'Counter' : 'COUNTER'}\n </span>\n <span className=\"cmm-brand-lockup__measure\">\n {wordmarkCase === 'title' ? 'Measure' : 'MEASURE'}\n </span>\n </span>\n {subtitle !== undefined ? (\n <span className=\"cmm-brand-lockup__subtitle\">{subtitle}</span>\n ) : null}\n </span>\n ) : null}\n </span>\n )\n}\n\nexport interface ConnectorLogoProps extends React.HTMLAttributes<HTMLSpanElement> {\n name: string\n src?: string\n size?: ConnectorLogoSize\n label?: string\n decorative?: boolean\n}\n\nexport function ConnectorLogo({\n className,\n name,\n src,\n size = 32,\n label,\n decorative = false,\n children,\n ...props\n}: ConnectorLogoProps) {\n const hasAsset = src !== undefined || children !== undefined\n const accessibilityProps = decorative\n ? { 'aria-hidden': true }\n : { role: 'img', 'aria-label': label ?? `${name} connector` }\n\n return (\n <span\n className={cn(\n 'cmm-connector-logo',\n getConnectorLogoSizeClass(size),\n `cmm-connector-logo--vendor-${getConnectorLogoTone(name)}`,\n hasAsset && 'cmm-connector-logo--asset',\n className\n )}\n {...accessibilityProps}\n {...props}\n >\n {src !== undefined ? (\n <img className=\"cmm-connector-logo__asset\" src={src} alt=\"\" aria-hidden=\"true\" />\n ) : children !== undefined ? (\n <span className=\"cmm-connector-logo__asset\" aria-hidden=\"true\">\n {children}\n </span>\n ) : (\n getConnectorLogoInitial(name)\n )}\n </span>\n )\n}\n\nexport type CountermeasureLogoProps = DiamondProps\nexport type CounterMeasureLogoProps = DiamondProps\nexport type CountermeasureWordmarkProps = WordmarkProps\nexport type CounterMeasureWordmarkProps = WordmarkProps\nexport type CountermeasureBrandLockupProps = BrandLockupProps\nexport type CounterMeasureBrandLockupProps = BrandLockupProps\nexport type { BrandLockupConfig }\n\nexport const CountermeasureLogo = Diamond\nexport const CounterMeasureLogo = Diamond\nexport const CountermeasureWordmark = Wordmark\nexport const CounterMeasureWordmark = Wordmark\nexport const CountermeasureBrandLockup = BrandLockup\nexport const CounterMeasureBrandLockup = BrandLockup\n"],"mappings":";;;;;AA2BA,SAAgB,EAAQ,EACtB,cACA,UAAO,IACP,WAAQ,0BACR,gBAAa,IACb,GAAG,KACY;CACf,IAAM,IAAY,EAAkB,eAAe,CAAI,GACjD,IAAqB,IACvB,EAAE,eAAe,GAAK,IACtB;EAAE,MAAM;EAAO,cAAc;CAAM;CAEvC,OACE,kBAAC,OAAD;EACE,OAAO;EACP,QAAQ;EACR,SAAQ;EACR,OAAM;EACN,WAAW,EAAG,eAAe,GAAW,CAAS;EACjD,GAAI;EACJ,GAAI;YAPN;GASE,kBAAC,QAAD;IACE,GAAE;IACF,GAAE;IACF,OAAM;IACN,QAAO;IACP,IAAG;IACH,WAAU;IACV,WAAU;GACX,CAAA;GACD,kBAAC,QAAD;IACE,GAAE;IACF,GAAE;IACF,OAAM;IACN,QAAO;IACP,IAAG;IACH,WAAU;IACV,WAAU;GACX,CAAA;GACD,kBAAC,QAAD;IACE,GAAE;IACF,GAAE;IACF,OAAM;IACN,QAAO;IACP,IAAG;IACH,WAAU;IACV,WAAU;GACX,CAAA;EACE;;AAET;AAUA,SAAgB,EAAS,EACvB,cACA,UAAO,IACP,aAAU,QACV,aACA,WAAQ,kBACR,gBAAa,IACb,GAAG,KACa;CAChB,IAAM,IAAQ,KAAK,MAAc,MAAM,KAAd,IAAoB,GAAG,IAAI,KAC9C,IAAqB,IACvB,EAAE,eAAe,GAAK,IACtB;EAAE,MAAM;EAAO,cAAc;CAAM;CAEvC,OACE,kBAAC,OAAD;EACE,WAAW,EAAG,gBAAgB,iBAAiB,KAAW,CAAS;EACnE,GAAI;EACJ,GAAI;YAHN,CAKE,kBAAC,OAAD;GACS;GACP,QAAQ;GACR,SAAQ;GACR,OAAM;GACN,WAAU;GACV,eAAY;aANd,CAQE,kBAAC,KAAD;IAAG,WAAU;cAAb;KACE,kBAAC,QAAD;MACE,GAAE;MACF,GAAE;MACF,OAAM;MACN,QAAO;MACP,IAAG;MACH,WAAU;MACV,WAAU;KACX,CAAA;KACD,kBAAC,QAAD;MACE,GAAE;MACF,GAAE;MACF,OAAM;MACN,QAAO;MACP,IAAG;MACH,WAAU;MACV,WAAU;KACX,CAAA;KACD,kBAAC,QAAD;MACE,GAAE;MACF,GAAE;MACF,OAAM;MACN,QAAO;MACP,IAAG;MACH,WAAU;MACV,WAAU;KACX,CAAA;IACA;OACH,kBAAC,QAAD;IACE,GAAE;IACF,GAAE;IACF,WAAU;IACV,YAAW;IACX,UAAS;IACT,YAAW;IACX,eAAc;cACf;GAEK,CAAA,CACH;MACJ,MAAa,KAAA,IAAyE,OAA7D,kBAAC,QAAD;GAAM,WAAU;aAA0B;EAAe,CAAA,CAChF;;AAET;AAWA,SAAgB,EAAY,EAC1B,cACA,cAAW,IACX,WAAQ,kBACR,aACA,kBAAe,aACf,gBAAa,IACb,kBAAe,IACf,GAAG,KACgB;CACnB,IAAM,IAAqB,IACvB,EAAE,eAAe,GAAK,IACtB;EAAE,MAAM;EAAO,cAAc;CAAM;CAEvC,OACE,kBAAC,QAAD;EACE,WAAW,EACT,oBACA,MAAiB,WAAW,2BAC5B,CACF;EACA,GAAI;EACJ,GAAI;YAPN,CASE,kBAAC,GAAD;GAAS,MAAM;GAAU,YAAA;EAAY,CAAA,GACpC,IACC,kBAAC,QAAD;GAAM,WAAU;GAAyB,eAAY;aAArD,CACE,kBAAC,QAAD;IAAM,WAAU;cAAhB,CACE,kBAAC,QAAD;KAAM,WAAU;eACb,MAAiB,UAAU,YAAY;IACpC,CAAA,GACN,kBAAC,QAAD;KAAM,WAAU;eACb,MAAiB,UAAU,YAAY;IACpC,CAAA,CACF;OACL,MAAa,KAAA,IAEV,OADF,kBAAC,QAAD;IAAM,WAAU;cAA8B;GAAe,CAAA,CAE3D;OACJ,IACA;;AAEV;AAUA,SAAgB,EAAc,EAC5B,cACA,SACA,QACA,UAAO,IACP,UACA,gBAAa,IACb,aACA,GAAG,KACkB;CACrB,IAAM,IAAW,MAAQ,KAAA,KAAa,MAAa,KAAA,GAC7C,IAAqB,IACvB,EAAE,eAAe,GAAK,IACtB;EAAE,MAAM;EAAO,cAAc,KAAS,GAAG,EAAK;CAAY;CAE9D,OACE,kBAAC,QAAD;EACE,WAAW,EACT,sBACA,EAA0B,CAAI,GAC9B,8BAA8B,EAAqB,CAAI,KACvD,KAAY,6BACZ,CACF;EACA,GAAI;EACJ,GAAI;YAEH,MAAQ,KAAA,IAEL,MAAa,KAAA,IAKf,EAAwB,CAAI,IAJ5B,kBAAC,QAAD;GAAM,WAAU;GAA4B,eAAY;GACrD;EACG,CAAA,IAJN,kBAAC,OAAD;GAAK,WAAU;GAAiC;GAAK,KAAI;GAAG,eAAY;EAAQ,CAAA;CAQ9E,CAAA;AAEV;AAUA,IAAa,IAAqB,GACrB,IAAqB,GACrB,IAAyB,GACzB,IAAyB,GACzB,IAA4B,GAC5B,IAA4B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CoreAppLibraryDashboardData, CoreAppLibraryDashboardMount } from '../../layout/core-app-library-dashboard';
|
|
2
|
+
export interface CoreAppLibraryDashboardProps {
|
|
3
|
+
data?: CoreAppLibraryDashboardData;
|
|
4
|
+
className?: string;
|
|
5
|
+
dashboardClassName?: string;
|
|
6
|
+
}
|
|
7
|
+
export type { CoreAppLibraryDashboardData, CoreAppLibraryDashboardMount };
|
|
8
|
+
declare function CoreAppLibraryDashboard({ data, className, dashboardClassName, }: CoreAppLibraryDashboardProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
declare namespace CoreAppLibraryDashboard {
|
|
10
|
+
var displayName: string;
|
|
11
|
+
}
|
|
12
|
+
export { CoreAppLibraryDashboard };
|
|
13
|
+
//# sourceMappingURL=core-app-library-dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-app-library-dashboard.d.ts","sourceRoot":"","sources":["../../../src/react/layout/core-app-library-dashboard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EAElC,MAAM,yCAAyC,CAAA;AAGhD,MAAM,WAAW,4BAA4B;IAC3C,IAAI,CAAC,EAAE,2BAA2B,CAAA;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,YAAY,EAAE,2BAA2B,EAAE,4BAA4B,EAAE,CAAA;AAEzE,iBAAS,uBAAuB,CAAC,EAC/B,IAAI,EACJ,SAAS,EACT,kBAAkB,GACnB,EAAE,4BAA4B,2CA6B9B;kBAjCQ,uBAAuB;;;AAqChC,OAAO,EAAE,uBAAuB,EAAE,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { mountCoreAppLibraryDashboard as e } from "../../layout/core-app-library-dashboard.js";
|
|
2
|
+
import { t } from "../../utils-BC9GT6Pr.js";
|
|
3
|
+
import * as n from "react";
|
|
4
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
5
|
+
//#region src/react/layout/core-app-library-dashboard.tsx
|
|
6
|
+
function i({ data: i, className: a, dashboardClassName: o }) {
|
|
7
|
+
let s = n.useRef(null), c = n.useRef(null), l = n.useRef(i);
|
|
8
|
+
return l.current = i, n.useEffect(() => {
|
|
9
|
+
let t = s.current;
|
|
10
|
+
if (t === null) return;
|
|
11
|
+
let n = { container: t };
|
|
12
|
+
return l.current !== void 0 && (n.data = l.current), o !== void 0 && (n.className = o), c.current = e(n), () => {
|
|
13
|
+
c.current?.destroy(), c.current = null;
|
|
14
|
+
};
|
|
15
|
+
}, [o]), n.useEffect(() => {
|
|
16
|
+
c.current?.update(i ?? {});
|
|
17
|
+
}, [i]), /* @__PURE__ */ r("div", {
|
|
18
|
+
ref: s,
|
|
19
|
+
"data-slot": "core-app-library-dashboard",
|
|
20
|
+
className: t(a)
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
i.displayName = "CoreAppLibraryDashboard";
|
|
24
|
+
//#endregion
|
|
25
|
+
export { i as CoreAppLibraryDashboard };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=core-app-library-dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-app-library-dashboard.js","names":[],"sources":["../../../src/react/layout/core-app-library-dashboard.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {\n mountCoreAppLibraryDashboard,\n type CoreAppLibraryDashboardData,\n type CoreAppLibraryDashboardMount,\n type CoreAppLibraryDashboardMountOptions,\n} from '../../layout/core-app-library-dashboard'\nimport { cn } from '../primitives/utils'\n\nexport interface CoreAppLibraryDashboardProps {\n data?: CoreAppLibraryDashboardData\n className?: string\n dashboardClassName?: string\n}\n\nexport type { CoreAppLibraryDashboardData, CoreAppLibraryDashboardMount }\n\nfunction CoreAppLibraryDashboard({\n data,\n className,\n dashboardClassName,\n}: CoreAppLibraryDashboardProps) {\n const containerRef = React.useRef<HTMLDivElement>(null)\n const mountRef = React.useRef<CoreAppLibraryDashboardMount | null>(null)\n const latestDataRef = React.useRef<CoreAppLibraryDashboardData | undefined>(data)\n latestDataRef.current = data\n\n React.useEffect(() => {\n const container = containerRef.current\n if (container === null) {\n return\n }\n\n const mountOptions: CoreAppLibraryDashboardMountOptions = { container }\n if (latestDataRef.current !== undefined) mountOptions.data = latestDataRef.current\n if (dashboardClassName !== undefined) mountOptions.className = dashboardClassName\n\n mountRef.current = mountCoreAppLibraryDashboard(mountOptions)\n\n return () => {\n mountRef.current?.destroy()\n mountRef.current = null\n }\n }, [dashboardClassName])\n\n React.useEffect(() => {\n mountRef.current?.update(data ?? {})\n }, [data])\n\n return <div ref={containerRef} data-slot=\"core-app-library-dashboard\" className={cn(className)} />\n}\n\nCoreAppLibraryDashboard.displayName = 'CoreAppLibraryDashboard'\n\nexport { CoreAppLibraryDashboard }\n"],"mappings":";;;;;AAkBA,SAAS,EAAwB,EAC/B,SACA,cACA,yBAC+B;CAC/B,IAAM,IAAe,EAAM,OAAuB,IAAI,GAChD,IAAW,EAAM,OAA4C,IAAI,GACjE,IAAgB,EAAM,OAAgD,CAAI;CAyBhF,OAxBA,EAAc,UAAU,GAExB,EAAM,gBAAgB;EACpB,IAAM,IAAY,EAAa;EAC/B,IAAI,MAAc,MAChB;EAGF,IAAM,IAAoD,EAAE,aAAU;EAMtE,OALI,EAAc,YAAY,KAAA,MAAW,EAAa,OAAO,EAAc,UACvE,MAAuB,KAAA,MAAW,EAAa,YAAY,IAE/D,EAAS,UAAU,EAA6B,CAAY,SAE/C;GAEX,AADA,EAAS,SAAS,QAAQ,GAC1B,EAAS,UAAU;EACrB;CACF,GAAG,CAAC,CAAkB,CAAC,GAEvB,EAAM,gBAAgB;EACpB,EAAS,SAAS,OAAO,KAAQ,CAAC,CAAC;CACrC,GAAG,CAAC,CAAI,CAAC,GAEF,kBAAC,OAAD;EAAK,KAAK;EAAc,aAAU;EAA6B,WAAW,EAAG,CAAS;CAAI,CAAA;AACnG;AAEA,EAAwB,cAAc"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { AppShell, type AppShellProps } from './app-shell';
|
|
2
2
|
export { BrowserLayout, type BrowserLayoutProps } from './browser-layout';
|
|
3
3
|
export { CoreAppChrome, type CoreAppChromeMount, type CoreAppChromeProps, type CoreAppSidebarPresetOptions, type CoreAppTopbarPresetOptions, } from './core-app-chrome';
|
|
4
|
+
export { CoreAppLibraryDashboard, type CoreAppLibraryDashboardData, type CoreAppLibraryDashboardMount, type CoreAppLibraryDashboardProps, } from './core-app-library-dashboard';
|
|
4
5
|
export { DetailHeader, type DetailHeaderProps } from './detail-header';
|
|
5
6
|
export { PageHeader, type PageHeaderProps } from './page-header';
|
|
6
7
|
export { SubNav, type SubNavItem, type SubNavProps } from './sub-nav';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/react/layout/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,uBAAuB,EACvB,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,GAClC,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AppShell as e } from "./app-shell.js";
|
|
2
2
|
import { i as t, n, r, t as i } from "../../layout-64M2la9A.js";
|
|
3
3
|
import { CoreAppChrome as a } from "./core-app-chrome.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import { CoreAppLibraryDashboard as o } from "./core-app-library-dashboard.js";
|
|
5
|
+
import { PageHeader as s } from "./page-header.js";
|
|
6
|
+
export { e as AppShell, t as BrowserLayout, a as CoreAppChrome, o as CoreAppLibraryDashboard, r as DetailHeader, i as PageFrame, s as PageHeader, n as SubNav };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VariantProps } from 'class-variance-authority';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
declare const alertVariants: (props?: ({
|
|
4
|
-
variant?: "error" | "warning" | "
|
|
4
|
+
variant?: "error" | "warning" | "success" | "info" | null | undefined;
|
|
5
5
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
6
6
|
/**
|
|
7
7
|
* Variants emitted by the alert today. The `AlertProps['variant']` shape
|
|
@@ -12,7 +12,7 @@ export interface ToastData {
|
|
|
12
12
|
persistent?: boolean;
|
|
13
13
|
}
|
|
14
14
|
declare const toastVariants: (props?: ({
|
|
15
|
-
level?: "error" | "warning" | "
|
|
15
|
+
level?: "error" | "warning" | "success" | "info" | null | undefined;
|
|
16
16
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
17
17
|
interface ToastContextValue {
|
|
18
18
|
toasts: ToastData[];
|
package/dist/react/sidebar.js
CHANGED