@countermeasure-platform/web-components 1.3.3-dev.33.1 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +31 -0
  2. package/dist/component-D5sRm1fq.js +389 -0
  3. package/dist/component-D5sRm1fq.js.map +1 -0
  4. package/dist/components/index.js +27 -27
  5. package/dist/icons/index.d.ts +12 -0
  6. package/dist/icons/index.d.ts.map +1 -1
  7. package/dist/icons/index.js +12 -0
  8. package/dist/icons/index.js.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +127 -126
  12. package/dist/layout/app-shell.d.ts +50 -3
  13. package/dist/layout/app-shell.d.ts.map +1 -1
  14. package/dist/layout/app-shell.js +142 -13
  15. package/dist/layout/app-shell.js.map +1 -1
  16. package/dist/layout/core-app-chrome.d.ts +81 -0
  17. package/dist/layout/core-app-chrome.d.ts.map +1 -0
  18. package/dist/layout/core-app-chrome.js +349 -0
  19. package/dist/layout/core-app-chrome.js.map +1 -0
  20. package/dist/layout/index.d.ts +4 -2
  21. package/dist/layout/index.d.ts.map +1 -1
  22. package/dist/layout/index.js +88 -87
  23. package/dist/layout/index.js.map +1 -1
  24. package/dist/react/primitives/badge.d.ts +1 -1
  25. package/dist/react/primitives/button.d.ts +2 -2
  26. package/dist/react/primitives/copy-button.d.ts +1 -1
  27. package/dist/react/primitives/stat-card.d.ts +1 -1
  28. package/dist/react/primitives/toggle.d.ts +1 -1
  29. package/dist/react/sidebar.d.ts +4 -4
  30. package/dist/react/sidebar.d.ts.map +1 -1
  31. package/dist/react/sidebar.js +18 -16
  32. package/dist/react/sidebar.js.map +1 -1
  33. package/dist/sidebar/component.d.ts +24 -2
  34. package/dist/sidebar/component.d.ts.map +1 -1
  35. package/dist/sidebar/enhance.d.ts +8 -0
  36. package/dist/sidebar/enhance.d.ts.map +1 -1
  37. package/dist/sidebar/index.d.ts +3 -0
  38. package/dist/sidebar/index.d.ts.map +1 -1
  39. package/dist/sidebar/index.js +81 -28
  40. package/dist/sidebar/index.js.map +1 -1
  41. package/dist/sidebar/types.d.ts +126 -4
  42. package/dist/sidebar/types.d.ts.map +1 -1
  43. package/dist/styles/layout.css +252 -0
  44. package/dist/styles/sidebar.css +313 -5
  45. package/package.json +6 -1
  46. package/src/icons/icons.test.ts +9 -0
  47. package/src/icons/index.ts +12 -0
  48. package/src/index.ts +11 -0
  49. package/src/layout/app-shell.test.ts +204 -0
  50. package/src/layout/app-shell.ts +362 -3
  51. package/src/layout/core-app-chrome.test.ts +507 -0
  52. package/src/layout/core-app-chrome.ts +662 -0
  53. package/src/layout/index.ts +36 -2
  54. package/src/react/sidebar.test.tsx +104 -3
  55. package/src/react/sidebar.tsx +26 -4
  56. package/src/sidebar/component.test.ts +395 -1
  57. package/src/sidebar/component.ts +661 -86
  58. package/src/sidebar/enhance.ts +118 -0
  59. package/src/sidebar/index.ts +144 -0
  60. package/src/sidebar/types.ts +143 -4
  61. package/src/styles/layout.css +252 -0
  62. package/src/styles/sidebar.css +313 -5
  63. package/dist/component-Bxhxf21c.js +0 -167
  64. package/dist/component-Bxhxf21c.js.map +0 -1
@@ -1,14 +1,59 @@
1
- /**
2
- * AppShell - Lightweight layout composition for app chrome.
3
- */
1
+ import { IconSet } from '../icons/index';
2
+ export interface TopMenuBarBreadcrumb {
3
+ label: string;
4
+ href?: string;
5
+ }
6
+ export interface TopMenuBarAction {
7
+ id: string;
8
+ label: string;
9
+ icon?: string;
10
+ href?: string;
11
+ target?: string;
12
+ badge?: boolean | string | number;
13
+ className?: string;
14
+ showLabel?: boolean;
15
+ attributes?: Record<string, string | number | boolean | null | undefined>;
16
+ onClick?: () => void;
17
+ }
18
+ export type TopMenuBarActionInput = TopMenuBarAction | HTMLElement;
19
+ export interface TopMenuBarUser {
20
+ name: string;
21
+ detail?: string;
22
+ initials?: string;
23
+ avatarUrl?: string;
24
+ menuLabel?: string;
25
+ actions?: TopMenuBarAction[];
26
+ }
27
+ export interface TopMenuBarConfig {
28
+ container?: HTMLElement | string;
29
+ product?: string;
30
+ current?: string;
31
+ breadcrumbs?: TopMenuBarBreadcrumb[];
32
+ beforeActions?: HTMLElement | HTMLElement[];
33
+ actions?: TopMenuBarActionInput[];
34
+ afterActions?: HTMLElement | HTMLElement[];
35
+ user?: TopMenuBarUser;
36
+ iconSet?: IconSet;
37
+ className?: string;
38
+ }
4
39
  export interface AppShellConfig {
5
40
  container?: HTMLElement | string;
6
41
  sidebar?: HTMLElement;
7
42
  header?: HTMLElement;
43
+ topbar?: HTMLElement | TopMenuBarConfig;
8
44
  content?: HTMLElement;
9
45
  metrics?: HTMLElement;
46
+ variant?: 'default' | 'product';
47
+ sidebarCollapsed?: boolean;
10
48
  className?: string;
11
49
  }
50
+ export declare class TopMenuBar {
51
+ readonly el: HTMLElement;
52
+ private readonly cleanupFns;
53
+ constructor(config?: TopMenuBarConfig);
54
+ destroy(): void;
55
+ private createUserMenu;
56
+ }
12
57
  export declare class AppShell {
13
58
  readonly el: HTMLElement;
14
59
  readonly mainEl: HTMLElement;
@@ -16,4 +61,6 @@ export declare class AppShell {
16
61
  constructor(config?: AppShellConfig);
17
62
  }
18
63
  export declare function createAppShell(config?: AppShellConfig): HTMLElement;
64
+ export declare function createTopMenuBar(config?: TopMenuBarConfig): HTMLElement;
65
+ export declare function createProductShell(config?: AppShellConfig): HTMLElement;
19
66
  //# sourceMappingURL=app-shell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/layout/app-shell.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;IAChC,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,QAAQ;IACnB,SAAgB,EAAE,EAAE,WAAW,CAAA;IAC/B,SAAgB,MAAM,EAAE,WAAW,CAAA;IACnC,SAAgB,SAAS,EAAE,WAAW,CAAA;gBAE1B,MAAM,GAAE,cAAmB;CAuCxC;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,cAAmB,GAAG,WAAW,CAEvE"}
1
+ {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/layout/app-shell.ts"],"names":[],"mappings":"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"}
@@ -1,25 +1,154 @@
1
- import { t as e } from "../utils-CSEWuKHo.js";
1
+ import { getIconSvgInner as e } from "../icons/index.js";
2
+ import { o as t } from "../sanitize-uWpY18N9.js";
3
+ import { t as n } from "../utils-CSEWuKHo.js";
2
4
  //#region src/layout/app-shell.ts
3
- var t = class {
5
+ function r(n, r) {
6
+ let i = "http://www.w3.org/2000/svg", a = document.createElementNS(i, "svg");
7
+ a.setAttribute("xmlns", i), a.setAttribute("width", "16"), a.setAttribute("height", "16"), a.setAttribute("viewBox", "0 0 24 24"), a.setAttribute("fill", "none"), a.setAttribute("stroke", "currentColor"), a.setAttribute("stroke-width", "2"), a.setAttribute("stroke-linecap", "round"), a.setAttribute("stroke-linejoin", "round"), a.setAttribute("aria-hidden", "true");
8
+ let o = e(n, r);
9
+ return o && t(a, o), a;
10
+ }
11
+ function i(e) {
12
+ let t = e.trim().split(/\s+/).filter(Boolean);
13
+ return t.length >= 2 ? `${t[0]?.charAt(0) ?? ""}${t[t.length - 1]?.charAt(0) ?? ""}`.toUpperCase() : e.slice(0, 2).toUpperCase();
14
+ }
15
+ function a(e, t) {
16
+ if (t === void 0) return;
17
+ let n = Array.isArray(t) ? t : [t];
18
+ for (let t of n) e.appendChild(t);
19
+ }
20
+ function o(e, t) {
21
+ if (t !== void 0) for (let [n, r] of Object.entries(t)) r == null || r === !1 || e.setAttribute(n, r === !0 ? "" : String(r));
22
+ }
23
+ function s(e, t) {
24
+ if (e instanceof HTMLElement) return e;
25
+ let n = e.href === void 0 ? document.createElement("button") : document.createElement("a");
26
+ if (n.classList.add("cmm-topbar__action"), e.className !== void 0 && n.classList.add(...e.className.split(/\s+/).filter(Boolean)), n.setAttribute("aria-label", e.label), n.setAttribute("title", e.label), n.setAttribute("data-action-id", e.id), o(n, e.attributes), n instanceof HTMLAnchorElement ? (n.href = e.href ?? "#", e.target !== void 0 && (n.target = e.target), e.target === "_blank" && (n.rel = "noreferrer noopener")) : n instanceof HTMLButtonElement && (n.type = "button"), e.onClick !== void 0 && n.addEventListener("click", e.onClick), e.icon !== void 0 && n.appendChild(r(t, e.icon)), e.showLabel === !0 || e.icon === void 0) {
27
+ let t = document.createElement("span");
28
+ t.classList.add("cmm-topbar__action-label"), t.textContent = e.label, n.appendChild(t);
29
+ }
30
+ if (e.badge !== void 0 && e.badge !== !1) {
31
+ let t = document.createElement("span");
32
+ t.classList.add("cmm-topbar__action-badge"), t.textContent = e.badge === !0 ? "" : String(e.badge), n.appendChild(t);
33
+ }
34
+ return n;
35
+ }
36
+ var c = class {
37
+ el;
38
+ cleanupFns = [];
39
+ constructor(e = {}) {
40
+ let t = e.iconSet ?? "lucide";
41
+ this.el = document.createElement("header"), this.el.className = ["cmm-topbar", e.className].filter(Boolean).join(" ");
42
+ let r = document.createElement("div");
43
+ r.classList.add("cmm-topbar__breadcrumbs");
44
+ let i = e.product ?? e.breadcrumbs?.[0]?.label;
45
+ if (i !== void 0) {
46
+ let e = document.createElement("span");
47
+ e.classList.add("cmm-topbar__product"), e.textContent = i, r.appendChild(e);
48
+ }
49
+ let o = e.breadcrumbs ?? [], c = +(e.product === void 0 && i !== void 0);
50
+ for (let e of o.slice(c)) {
51
+ let t = document.createElement("span");
52
+ t.classList.add("cmm-topbar__separator"), t.setAttribute("aria-hidden", "true"), t.textContent = "•", r.appendChild(t);
53
+ let n = e.href === void 0 ? document.createElement("span") : document.createElement("a");
54
+ n.classList.add("cmm-topbar__breadcrumb"), n.textContent = e.label, n instanceof HTMLAnchorElement && (n.href = e.href ?? "#"), r.appendChild(n);
55
+ }
56
+ if (e.current !== void 0) {
57
+ let t = document.createElement("span");
58
+ t.classList.add("cmm-topbar__separator"), t.setAttribute("aria-hidden", "true"), t.textContent = "•", r.appendChild(t);
59
+ let n = document.createElement("span");
60
+ n.classList.add("cmm-topbar__current"), n.textContent = e.current, r.appendChild(n);
61
+ }
62
+ let l = document.createElement("div");
63
+ l.classList.add("cmm-topbar__actions"), a(l, e.beforeActions);
64
+ for (let n of e.actions ?? []) l.appendChild(s(n, t));
65
+ e.user !== void 0 && l.appendChild(this.createUserMenu(e.user, t)), a(l, e.afterActions), this.el.appendChild(r), this.el.appendChild(l), e.container !== void 0 && n(e.container).appendChild(this.el);
66
+ }
67
+ destroy() {
68
+ for (let e of this.cleanupFns.splice(0)) e();
69
+ this.el.remove();
70
+ }
71
+ createUserMenu(e, t) {
72
+ let n = document.createElement("div");
73
+ n.classList.add("cmm-topbar__user");
74
+ let a = document.createElement("button");
75
+ a.type = "button", a.classList.add("cmm-topbar__user-trigger"), a.setAttribute("aria-haspopup", "menu"), a.setAttribute("aria-expanded", "false"), a.setAttribute("aria-label", e.menuLabel ?? `User menu for ${e.name}`);
76
+ let o = document.createElement("span");
77
+ if (o.classList.add("cmm-topbar__avatar"), e.avatarUrl !== void 0) {
78
+ let t = document.createElement("img");
79
+ t.src = e.avatarUrl, t.alt = "", o.appendChild(t);
80
+ } else o.textContent = e.initials ?? i(e.name);
81
+ a.appendChild(o), a.appendChild(r(t, "chevron-down"));
82
+ let c = document.createElement("div");
83
+ c.classList.add("cmm-topbar__user-menu"), c.setAttribute("role", "menu"), c.hidden = !0;
84
+ let l = document.createElement("div");
85
+ l.classList.add("cmm-topbar__user-profile");
86
+ let u = document.createElement("span");
87
+ if (u.classList.add("cmm-topbar__user-name"), u.textContent = e.name, l.appendChild(u), e.detail !== void 0) {
88
+ let t = document.createElement("span");
89
+ t.classList.add("cmm-topbar__user-detail"), t.textContent = e.detail, l.appendChild(t);
90
+ }
91
+ c.appendChild(l);
92
+ for (let n of e.actions ?? []) {
93
+ let e = s(n, t);
94
+ if (e.classList.remove("cmm-topbar__action"), e.classList.add("cmm-topbar__menu-item"), e.setAttribute("role", "menuitem"), e.querySelector(".cmm-topbar__action-label") === null) {
95
+ let t = document.createElement("span");
96
+ t.classList.add("cmm-topbar__action-label"), t.textContent = n.label, e.appendChild(t);
97
+ }
98
+ c.appendChild(e);
99
+ }
100
+ let d = (e) => {
101
+ c.hidden = !e, a.setAttribute("aria-expanded", String(e));
102
+ };
103
+ a.addEventListener("click", () => {
104
+ d(c.hidden === !0);
105
+ });
106
+ let f = (e) => {
107
+ n.contains(e.target) || d(!1);
108
+ }, p = (e) => {
109
+ e.key === "Escape" && d(!1);
110
+ };
111
+ return document.addEventListener("pointerdown", f), document.addEventListener("keydown", p), this.cleanupFns.push(() => {
112
+ document.removeEventListener("pointerdown", f), document.removeEventListener("keydown", p);
113
+ }), n.appendChild(a), n.appendChild(c), n;
114
+ }
115
+ }, l = class {
4
116
  el;
5
117
  mainEl;
6
118
  contentEl;
7
- constructor(t = {}) {
8
- if (this.el = document.createElement("div"), this.el.className = ["cmm-app-shell", t.className].filter(Boolean).join(" "), t.sidebar !== void 0) {
9
- let e = document.createElement("aside");
10
- e.className = "cmm-app-shell__sidebar", e.appendChild(t.sidebar), this.el.appendChild(e);
119
+ constructor(e = {}) {
120
+ if (this.el = document.createElement("div"), this.el.className = [
121
+ "cmm-app-shell",
122
+ e.variant === "product" && "cmm-app-shell--product",
123
+ e.className
124
+ ].filter(Boolean).join(" "), this.el.setAttribute("data-shell-layout", ""), e.sidebarCollapsed !== void 0 && this.el.setAttribute("data-sidebar-collapsed", String(e.sidebarCollapsed)), e.sidebar !== void 0) {
125
+ let t = document.createElement("aside");
126
+ t.className = "cmm-app-shell__sidebar", t.setAttribute("data-shell-sidebar", ""), t.appendChild(e.sidebar), this.el.appendChild(t);
11
127
  }
12
- if (this.mainEl = document.createElement("div"), this.mainEl.className = "cmm-app-shell__main", t.header !== void 0 && this.mainEl.appendChild(t.header), this.contentEl = document.createElement("main"), this.contentEl.className = "cmm-app-shell__content", t.metrics !== void 0) {
13
- let e = document.createElement("div");
14
- e.className = "cmm-app-shell__metric-strip", e.appendChild(t.metrics), this.contentEl.appendChild(e);
128
+ if (this.mainEl = document.createElement("div"), this.mainEl.className = "cmm-app-shell__main", e.topbar !== void 0) {
129
+ let t = e.topbar instanceof HTMLElement ? e.topbar : new c(e.topbar).el;
130
+ this.mainEl.appendChild(t);
131
+ } else e.header !== void 0 && this.mainEl.appendChild(e.header);
132
+ if (this.contentEl = document.createElement("main"), this.contentEl.className = "cmm-app-shell__content", e.metrics !== void 0) {
133
+ let t = document.createElement("div");
134
+ t.className = "cmm-app-shell__metric-strip", t.appendChild(e.metrics), this.contentEl.appendChild(t);
15
135
  }
16
- t.content !== void 0 && this.contentEl.appendChild(t.content), this.mainEl.appendChild(this.contentEl), this.el.appendChild(this.mainEl), t.container !== void 0 && e(t.container).appendChild(this.el);
136
+ e.content !== void 0 && this.contentEl.appendChild(e.content), this.mainEl.appendChild(this.contentEl), this.el.appendChild(this.mainEl), e.container !== void 0 && n(e.container).appendChild(this.el);
17
137
  }
18
138
  };
19
- function n(e = {}) {
20
- return new t(e).el;
139
+ function u(e = {}) {
140
+ return new l(e).el;
141
+ }
142
+ function d(e = {}) {
143
+ return new c(e).el;
144
+ }
145
+ function f(e = {}) {
146
+ return new l({
147
+ ...e,
148
+ variant: "product"
149
+ }).el;
21
150
  }
22
151
  //#endregion
23
- export { t as AppShell, n as createAppShell };
152
+ export { l as AppShell, c as TopMenuBar, u as createAppShell, f as createProductShell, d as createTopMenuBar };
24
153
 
25
154
  //# sourceMappingURL=app-shell.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-shell.js","names":[],"sources":["../../src/layout/app-shell.ts"],"sourcesContent":["/**\n * AppShell - Lightweight layout composition for app chrome.\n */\n\nimport { resolveContainer } from '../primitives/utils'\n\nexport interface AppShellConfig {\n container?: HTMLElement | string\n sidebar?: HTMLElement\n header?: HTMLElement\n content?: HTMLElement\n metrics?: HTMLElement\n className?: string\n}\n\nexport class AppShell {\n public readonly el: HTMLElement\n public readonly mainEl: HTMLElement\n public readonly contentEl: HTMLElement\n\n constructor(config: AppShellConfig = {}) {\n this.el = document.createElement('div')\n this.el.className = ['cmm-app-shell', config.className].filter(Boolean).join(' ')\n\n if (config.sidebar !== undefined) {\n const sidebarSlot = document.createElement('aside')\n sidebarSlot.className = 'cmm-app-shell__sidebar'\n sidebarSlot.appendChild(config.sidebar)\n this.el.appendChild(sidebarSlot)\n }\n\n this.mainEl = document.createElement('div')\n this.mainEl.className = 'cmm-app-shell__main'\n\n if (config.header !== undefined) {\n this.mainEl.appendChild(config.header)\n }\n\n this.contentEl = document.createElement('main')\n this.contentEl.className = 'cmm-app-shell__content'\n\n if (config.metrics !== undefined) {\n const metrics = document.createElement('div')\n metrics.className = 'cmm-app-shell__metric-strip'\n metrics.appendChild(config.metrics)\n this.contentEl.appendChild(metrics)\n }\n\n if (config.content !== undefined) {\n this.contentEl.appendChild(config.content)\n }\n\n this.mainEl.appendChild(this.contentEl)\n this.el.appendChild(this.mainEl)\n\n if (config.container !== undefined) {\n resolveContainer(config.container).appendChild(this.el)\n }\n }\n}\n\nexport function createAppShell(config: AppShellConfig = {}): HTMLElement {\n return new AppShell(config).el\n}\n"],"mappings":";;AAeA,IAAa,IAAb,MAAsB;CACpB;CACA;CACA;CAEA,YAAY,IAAyB,CAAC,GAAG;EAIvC,IAHA,KAAK,KAAK,SAAS,cAAc,KAAK,GACtC,KAAK,GAAG,YAAY,CAAC,iBAAiB,EAAO,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAE5E,EAAO,YAAY,KAAA,GAAW;GAChC,IAAM,IAAc,SAAS,cAAc,OAAO;GAGlD,AAFA,EAAY,YAAY,0BACxB,EAAY,YAAY,EAAO,OAAO,GACtC,KAAK,GAAG,YAAY,CAAW;EACjC;EAYA,IAVA,KAAK,SAAS,SAAS,cAAc,KAAK,GAC1C,KAAK,OAAO,YAAY,uBAEpB,EAAO,WAAW,KAAA,KACpB,KAAK,OAAO,YAAY,EAAO,MAAM,GAGvC,KAAK,YAAY,SAAS,cAAc,MAAM,GAC9C,KAAK,UAAU,YAAY,0BAEvB,EAAO,YAAY,KAAA,GAAW;GAChC,IAAM,IAAU,SAAS,cAAc,KAAK;GAG5C,AAFA,EAAQ,YAAY,+BACpB,EAAQ,YAAY,EAAO,OAAO,GAClC,KAAK,UAAU,YAAY,CAAO;EACpC;EASA,AAPI,EAAO,YAAY,KAAA,KACrB,KAAK,UAAU,YAAY,EAAO,OAAO,GAG3C,KAAK,OAAO,YAAY,KAAK,SAAS,GACtC,KAAK,GAAG,YAAY,KAAK,MAAM,GAE3B,EAAO,cAAc,KAAA,KACvB,EAAiB,EAAO,SAAS,EAAE,YAAY,KAAK,EAAE;CAE1D;AACF;AAEA,SAAgB,EAAe,IAAyB,CAAC,GAAgB;CACvE,OAAO,IAAI,EAAS,CAAM,EAAE;AAC9B"}
1
+ {"version":3,"file":"app-shell.js","names":[],"sources":["../../src/layout/app-shell.ts"],"sourcesContent":["/**\n * AppShell - Layout composition for app chrome.\n */\n\nimport { getIconSvgInner, type IconSet } from '../icons/index'\nimport { resolveContainer } from '../primitives/utils'\nimport { setSafeIconHtml } from '../utils/sanitize'\n\nexport interface TopMenuBarBreadcrumb {\n label: string\n href?: string\n}\n\nexport interface TopMenuBarAction {\n id: string\n label: string\n icon?: string\n href?: string\n target?: string\n badge?: boolean | string | number\n className?: string\n showLabel?: boolean\n attributes?: Record<string, string | number | boolean | null | undefined>\n onClick?: () => void\n}\n\nexport type TopMenuBarActionInput = TopMenuBarAction | HTMLElement\n\nexport interface TopMenuBarUser {\n name: string\n detail?: string\n initials?: string\n avatarUrl?: string\n menuLabel?: string\n actions?: TopMenuBarAction[]\n}\n\nexport interface TopMenuBarConfig {\n container?: HTMLElement | string\n product?: string\n current?: string\n breadcrumbs?: TopMenuBarBreadcrumb[]\n beforeActions?: HTMLElement | HTMLElement[]\n actions?: TopMenuBarActionInput[]\n afterActions?: HTMLElement | HTMLElement[]\n user?: TopMenuBarUser\n iconSet?: IconSet\n className?: string\n}\n\nexport interface AppShellConfig {\n container?: HTMLElement | string\n sidebar?: HTMLElement\n header?: HTMLElement\n topbar?: HTMLElement | TopMenuBarConfig\n content?: HTMLElement\n metrics?: HTMLElement\n variant?: 'default' | 'product'\n sidebarCollapsed?: boolean\n className?: string\n}\n\nfunction createIconSvg(iconSet: IconSet, name: string): SVGElement {\n const svgNs = 'http://www.w3.org/2000/svg'\n const svg = document.createElementNS(svgNs, 'svg')\n svg.setAttribute('xmlns', svgNs)\n svg.setAttribute('width', '16')\n svg.setAttribute('height', '16')\n svg.setAttribute('viewBox', '0 0 24 24')\n svg.setAttribute('fill', 'none')\n svg.setAttribute('stroke', 'currentColor')\n svg.setAttribute('stroke-width', '2')\n svg.setAttribute('stroke-linecap', 'round')\n svg.setAttribute('stroke-linejoin', 'round')\n svg.setAttribute('aria-hidden', 'true')\n\n const inner = getIconSvgInner(iconSet, name)\n if (inner) {\n setSafeIconHtml(svg, inner)\n }\n\n return svg\n}\n\nfunction toInitials(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean)\n\n if (parts.length >= 2) {\n return `${parts[0]?.charAt(0) ?? ''}${parts[parts.length - 1]?.charAt(0) ?? ''}`.toUpperCase()\n }\n\n return name.slice(0, 2).toUpperCase()\n}\n\nfunction appendElements(\n parent: HTMLElement,\n elementOrElements: HTMLElement | HTMLElement[] | undefined\n): void {\n if (elementOrElements === undefined) {\n return\n }\n\n const elements = Array.isArray(elementOrElements) ? elementOrElements : [elementOrElements]\n for (const element of elements) {\n parent.appendChild(element)\n }\n}\n\nfunction applyAttributes(\n element: HTMLElement,\n attributes: TopMenuBarAction['attributes'] | undefined\n): void {\n if (attributes === undefined) {\n return\n }\n\n for (const [name, value] of Object.entries(attributes)) {\n if (value === undefined || value === null || value === false) {\n continue\n }\n\n element.setAttribute(name, value === true ? '' : String(value))\n }\n}\n\nfunction createActionElement(action: TopMenuBarActionInput, iconSet: IconSet): HTMLElement {\n if (action instanceof HTMLElement) {\n return action\n }\n\n const element =\n action.href !== undefined ? document.createElement('a') : document.createElement('button')\n\n element.classList.add('cmm-topbar__action')\n if (action.className !== undefined) {\n element.classList.add(...action.className.split(/\\s+/).filter(Boolean))\n }\n element.setAttribute('aria-label', action.label)\n element.setAttribute('title', action.label)\n element.setAttribute('data-action-id', action.id)\n applyAttributes(element, action.attributes)\n\n if (element instanceof HTMLAnchorElement) {\n element.href = action.href ?? '#'\n if (action.target !== undefined) {\n element.target = action.target\n }\n if (action.target === '_blank') {\n element.rel = 'noreferrer noopener'\n }\n } else if (element instanceof HTMLButtonElement) {\n element.type = 'button'\n }\n\n if (action.onClick !== undefined) {\n element.addEventListener('click', action.onClick)\n }\n\n if (action.icon !== undefined) {\n element.appendChild(createIconSvg(iconSet, action.icon))\n }\n\n if (action.showLabel === true || action.icon === undefined) {\n const label = document.createElement('span')\n label.classList.add('cmm-topbar__action-label')\n label.textContent = action.label\n element.appendChild(label)\n }\n\n if (action.badge !== undefined && action.badge !== false) {\n const badge = document.createElement('span')\n badge.classList.add('cmm-topbar__action-badge')\n badge.textContent = action.badge === true ? '' : String(action.badge)\n element.appendChild(badge)\n }\n\n return element\n}\n\nexport class TopMenuBar {\n public readonly el: HTMLElement\n private readonly cleanupFns: (() => void)[] = []\n\n constructor(config: TopMenuBarConfig = {}) {\n const iconSet = config.iconSet ?? 'lucide'\n this.el = document.createElement('header')\n this.el.className = ['cmm-topbar', config.className].filter(Boolean).join(' ')\n\n const crumbWrap = document.createElement('div')\n crumbWrap.classList.add('cmm-topbar__breadcrumbs')\n\n const product = config.product ?? config.breadcrumbs?.[0]?.label\n if (product !== undefined) {\n const productEl = document.createElement('span')\n productEl.classList.add('cmm-topbar__product')\n productEl.textContent = product\n crumbWrap.appendChild(productEl)\n }\n\n const crumbs = config.breadcrumbs ?? []\n const crumbStart = config.product === undefined && product !== undefined ? 1 : 0\n for (const crumb of crumbs.slice(crumbStart)) {\n const separator = document.createElement('span')\n separator.classList.add('cmm-topbar__separator')\n separator.setAttribute('aria-hidden', 'true')\n separator.textContent = '•'\n crumbWrap.appendChild(separator)\n\n const crumbEl =\n crumb.href !== undefined ? document.createElement('a') : document.createElement('span')\n crumbEl.classList.add('cmm-topbar__breadcrumb')\n crumbEl.textContent = crumb.label\n if (crumbEl instanceof HTMLAnchorElement) {\n crumbEl.href = crumb.href ?? '#'\n }\n crumbWrap.appendChild(crumbEl)\n }\n\n if (config.current !== undefined) {\n const separator = document.createElement('span')\n separator.classList.add('cmm-topbar__separator')\n separator.setAttribute('aria-hidden', 'true')\n separator.textContent = '•'\n crumbWrap.appendChild(separator)\n\n const current = document.createElement('span')\n current.classList.add('cmm-topbar__current')\n current.textContent = config.current\n crumbWrap.appendChild(current)\n }\n\n const actions = document.createElement('div')\n actions.classList.add('cmm-topbar__actions')\n\n appendElements(actions, config.beforeActions)\n\n for (const action of config.actions ?? []) {\n actions.appendChild(createActionElement(action, iconSet))\n }\n\n if (config.user !== undefined) {\n actions.appendChild(this.createUserMenu(config.user, iconSet))\n }\n\n appendElements(actions, config.afterActions)\n\n this.el.appendChild(crumbWrap)\n this.el.appendChild(actions)\n\n if (config.container !== undefined) {\n resolveContainer(config.container).appendChild(this.el)\n }\n }\n\n destroy(): void {\n for (const cleanup of this.cleanupFns.splice(0)) {\n cleanup()\n }\n this.el.remove()\n }\n\n private createUserMenu(user: TopMenuBarUser, iconSet: IconSet): HTMLElement {\n const root = document.createElement('div')\n root.classList.add('cmm-topbar__user')\n\n const trigger = document.createElement('button')\n trigger.type = 'button'\n trigger.classList.add('cmm-topbar__user-trigger')\n trigger.setAttribute('aria-haspopup', 'menu')\n trigger.setAttribute('aria-expanded', 'false')\n trigger.setAttribute('aria-label', user.menuLabel ?? `User menu for ${user.name}`)\n\n const avatar = document.createElement('span')\n avatar.classList.add('cmm-topbar__avatar')\n if (user.avatarUrl !== undefined) {\n const image = document.createElement('img')\n image.src = user.avatarUrl\n image.alt = ''\n avatar.appendChild(image)\n } else {\n avatar.textContent = user.initials ?? toInitials(user.name)\n }\n trigger.appendChild(avatar)\n trigger.appendChild(createIconSvg(iconSet, 'chevron-down'))\n\n const menu = document.createElement('div')\n menu.classList.add('cmm-topbar__user-menu')\n menu.setAttribute('role', 'menu')\n menu.hidden = true\n\n const profile = document.createElement('div')\n profile.classList.add('cmm-topbar__user-profile')\n const name = document.createElement('span')\n name.classList.add('cmm-topbar__user-name')\n name.textContent = user.name\n profile.appendChild(name)\n if (user.detail !== undefined) {\n const detail = document.createElement('span')\n detail.classList.add('cmm-topbar__user-detail')\n detail.textContent = user.detail\n profile.appendChild(detail)\n }\n menu.appendChild(profile)\n\n for (const action of user.actions ?? []) {\n const item = createActionElement(action, iconSet)\n item.classList.remove('cmm-topbar__action')\n item.classList.add('cmm-topbar__menu-item')\n item.setAttribute('role', 'menuitem')\n if (item.querySelector('.cmm-topbar__action-label') === null) {\n const label = document.createElement('span')\n label.classList.add('cmm-topbar__action-label')\n label.textContent = action.label\n item.appendChild(label)\n }\n menu.appendChild(item)\n }\n\n const setOpen = (open: boolean): void => {\n menu.hidden = !open\n trigger.setAttribute('aria-expanded', String(open))\n }\n\n trigger.addEventListener('click', () => {\n setOpen(menu.hidden === true)\n })\n\n const closeOnOutsidePointer = (event: PointerEvent): void => {\n if (!root.contains(event.target as Node)) {\n setOpen(false)\n }\n }\n const closeOnEscape = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') {\n setOpen(false)\n }\n }\n\n document.addEventListener('pointerdown', closeOnOutsidePointer)\n document.addEventListener('keydown', closeOnEscape)\n this.cleanupFns.push(() => {\n document.removeEventListener('pointerdown', closeOnOutsidePointer)\n document.removeEventListener('keydown', closeOnEscape)\n })\n\n root.appendChild(trigger)\n root.appendChild(menu)\n return root\n }\n}\n\nexport class AppShell {\n public readonly el: HTMLElement\n public readonly mainEl: HTMLElement\n public readonly contentEl: HTMLElement\n\n constructor(config: AppShellConfig = {}) {\n this.el = document.createElement('div')\n this.el.className = [\n 'cmm-app-shell',\n config.variant === 'product' && 'cmm-app-shell--product',\n config.className,\n ]\n .filter(Boolean)\n .join(' ')\n this.el.setAttribute('data-shell-layout', '')\n if (config.sidebarCollapsed !== undefined) {\n this.el.setAttribute('data-sidebar-collapsed', String(config.sidebarCollapsed))\n }\n\n if (config.sidebar !== undefined) {\n const sidebarSlot = document.createElement('aside')\n sidebarSlot.className = 'cmm-app-shell__sidebar'\n sidebarSlot.setAttribute('data-shell-sidebar', '')\n sidebarSlot.appendChild(config.sidebar)\n this.el.appendChild(sidebarSlot)\n }\n\n this.mainEl = document.createElement('div')\n this.mainEl.className = 'cmm-app-shell__main'\n\n if (config.topbar !== undefined) {\n const topbar =\n config.topbar instanceof HTMLElement ? config.topbar : new TopMenuBar(config.topbar).el\n this.mainEl.appendChild(topbar)\n } else if (config.header !== undefined) {\n this.mainEl.appendChild(config.header)\n }\n\n this.contentEl = document.createElement('main')\n this.contentEl.className = 'cmm-app-shell__content'\n\n if (config.metrics !== undefined) {\n const metrics = document.createElement('div')\n metrics.className = 'cmm-app-shell__metric-strip'\n metrics.appendChild(config.metrics)\n this.contentEl.appendChild(metrics)\n }\n\n if (config.content !== undefined) {\n this.contentEl.appendChild(config.content)\n }\n\n this.mainEl.appendChild(this.contentEl)\n this.el.appendChild(this.mainEl)\n\n if (config.container !== undefined) {\n resolveContainer(config.container).appendChild(this.el)\n }\n }\n}\n\nexport function createAppShell(config: AppShellConfig = {}): HTMLElement {\n return new AppShell(config).el\n}\n\nexport function createTopMenuBar(config: TopMenuBarConfig = {}): HTMLElement {\n return new TopMenuBar(config).el\n}\n\nexport function createProductShell(config: AppShellConfig = {}): HTMLElement {\n return new AppShell({ ...config, variant: 'product' }).el\n}\n"],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import { SidebarComponentConfig, SidebarFooterAction, SidebarScopeConfig, SidebarSection, SidebarUser } from '../sidebar/types';
2
+ import { SidebarComponent } from '../sidebar/component';
3
+ import { TopMenuBar, TopMenuBarActionInput, TopMenuBarConfig, TopMenuBarUser } from './app-shell';
4
+ export interface CoreAppRouteLabel {
5
+ pattern: RegExp;
6
+ label: string;
7
+ }
8
+ export interface CoreAppSidebarPresetOptions extends Omit<SidebarComponentConfig, 'container' | 'sections'> {
9
+ basePath?: string;
10
+ sections?: SidebarSection[];
11
+ }
12
+ export interface CoreAppTopbarPresetOptions extends Omit<TopMenuBarConfig, 'actions' | 'current' | 'product'> {
13
+ basePath?: string;
14
+ pathname?: string;
15
+ product?: string;
16
+ current?: string;
17
+ actions?: TopMenuBarActionInput[];
18
+ includeSearchAction?: boolean;
19
+ includeFeedbackAction?: boolean;
20
+ includeHelpAction?: boolean;
21
+ }
22
+ export interface CoreAppChromePreset {
23
+ sidebar: Omit<SidebarComponentConfig, 'container'>;
24
+ topbar: TopMenuBarConfig;
25
+ }
26
+ export interface CoreAppChromePresetOptions {
27
+ basePath?: string;
28
+ pathname?: string;
29
+ scope?: SidebarScopeConfig;
30
+ sidebarUser?: SidebarUser;
31
+ sidebarFooterActions?: SidebarFooterAction[];
32
+ topbarUser?: TopMenuBarUser;
33
+ topbarActions?: TopMenuBarActionInput[];
34
+ }
35
+ export interface CoreAppChromeMountOptions extends CoreAppChromePresetOptions {
36
+ sidebarContainer: HTMLElement | string;
37
+ topbarContainer?: HTMLElement | string;
38
+ sidebar?: CoreAppSidebarPresetOptions;
39
+ topbar?: CoreAppTopbarPresetOptions;
40
+ /**
41
+ * Move explicitly marked server-rendered topbar action nodes into the new topbar.
42
+ * Useful for native hooks that are initialized outside the chrome mount.
43
+ * @default true
44
+ */
45
+ preserveTopbarActions?: boolean;
46
+ /**
47
+ * Selector for preserved action nodes inside the topbar container.
48
+ * @default '[data-core-app-topbar-action]'
49
+ */
50
+ topbarActionSelector?: string;
51
+ /**
52
+ * Remove existing placeholder/server-rendered children before mounting.
53
+ * @default true
54
+ */
55
+ clearContainers?: boolean;
56
+ }
57
+ export interface CoreAppChromeDomMountOptions extends CoreAppChromePresetOptions {
58
+ root?: ParentNode;
59
+ sidebarSelector?: string;
60
+ topbarSelector?: string;
61
+ sidebar?: CoreAppSidebarPresetOptions;
62
+ topbar?: CoreAppTopbarPresetOptions;
63
+ preserveTopbarActions?: boolean;
64
+ topbarActionSelector?: string;
65
+ clearContainers?: boolean;
66
+ }
67
+ export interface CoreAppChromeMount {
68
+ sidebar: SidebarComponent;
69
+ topbar?: TopMenuBar;
70
+ destroy: () => void;
71
+ }
72
+ export declare const CORE_APP_ROUTE_LABELS: CoreAppRouteLabel[];
73
+ export declare function createCoreAppSidebarSections(basePath?: string): SidebarSection[];
74
+ export declare function getCoreAppRouteLabel(pathname: string, basePath?: string): string;
75
+ export declare function createCoreAppSidebarConfig(options?: CoreAppSidebarPresetOptions): Omit<SidebarComponentConfig, 'container'>;
76
+ export declare function createCoreAppTopbarActions(options?: Pick<CoreAppTopbarPresetOptions, 'includeSearchAction' | 'includeFeedbackAction' | 'includeHelpAction'>): TopMenuBarActionInput[];
77
+ export declare function createCoreAppTopbarConfig(options?: CoreAppTopbarPresetOptions): TopMenuBarConfig;
78
+ export declare function createCoreAppChromePreset(options?: CoreAppChromePresetOptions): CoreAppChromePreset;
79
+ export declare function mountCoreAppChrome(options: CoreAppChromeMountOptions): CoreAppChromeMount;
80
+ export declare function mountCoreAppChromeFromDom(options?: CoreAppChromeDomMountOptions): CoreAppChromeMount | null;
81
+ //# sourceMappingURL=core-app-chrome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-app-chrome.d.ts","sourceRoot":"","sources":["../../src/layout/core-app-chrome.ts"],"names":[],"mappings":"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"}