@countermeasure-platform/web-components 1.2.2-dev.7.1 → 1.2.2-dev.8.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.
@@ -20,36 +20,54 @@ var a = class {
20
20
  constructor(e) {
21
21
  this.config = e, this.container = t(e.container), this.iconSet = e.iconSet ?? "lucide", this.aside = document.createElement("aside");
22
22
  let n = e.variant ?? "app";
23
- this.aside.classList.add("sidebar", r(n)), this.aside.setAttribute("data-sidebar", n), this.render(), this.container.appendChild(this.aside);
23
+ this.aside.classList.add("sidebar", r(n)), this.aside.setAttribute("data-sidebar", n), e.collapsed === !0 && this.aside.classList.add("sidebar--collapsed"), this.render(), this.container.appendChild(this.aside);
24
24
  }
25
25
  render() {
26
26
  this.config.collapsible === !0 && this.renderCollapseButton(), this.renderHeader();
27
27
  let e = document.createElement("div");
28
28
  e.classList.add("sidebar__body");
29
- for (let t of this.config.sections) {
29
+ for (let t of this.config.sections) e.appendChild(this.buildSection(t));
30
+ this.aside.appendChild(e), this.renderFooter();
31
+ }
32
+ buildSection(e) {
33
+ let t = document.createElement("div");
34
+ t.classList.add("sidebar__section"), t.setAttribute("data-section-id", e.id);
35
+ let n = e.collapsible === !0, r = e.defaultExpanded !== !1;
36
+ if (n && e.label) {
37
+ t.classList.add("sidebar__section--collapsible"), r && t.classList.add("sidebar__section--expanded");
38
+ let n = document.createElement("button");
39
+ n.type = "button", n.classList.add("sidebar__group-header"), n.setAttribute("aria-expanded", String(r)), n.setAttribute("aria-controls", `sidebar-group-${e.id}`), e.icon && n.appendChild(i(this.iconSet, e.icon));
40
+ let a = document.createElement("span");
41
+ a.classList.add("sidebar__group-label"), a.textContent = e.label, n.appendChild(a);
42
+ let o = document.createElementNS("http://www.w3.org/2000/svg", "svg");
43
+ o.setAttribute("class", "sidebar__group-chevron"), o.setAttribute("viewBox", "0 0 24 24"), o.setAttribute("width", "14"), o.setAttribute("height", "14"), o.setAttribute("fill", "none"), o.setAttribute("stroke", "currentColor"), o.setAttribute("stroke-width", "2"), o.setAttribute("stroke-linecap", "round"), o.setAttribute("stroke-linejoin", "round"), o.setAttribute("aria-hidden", "true");
44
+ let s = document.createElementNS("http://www.w3.org/2000/svg", "path");
45
+ s.setAttribute("d", "m6 9 6 6 6-6"), o.appendChild(s), n.appendChild(o), n.addEventListener("click", () => {
46
+ let e = t.classList.toggle("sidebar__section--expanded");
47
+ n.setAttribute("aria-expanded", String(e));
48
+ }), t.appendChild(n);
49
+ } else if (e.label) {
30
50
  let n = document.createElement("div");
31
- if (n.classList.add("sidebar__section"), t.label) {
32
- let e = document.createElement("div");
33
- e.classList.add("sidebar__section-label"), e.textContent = t.label, n.appendChild(e);
51
+ n.classList.add("sidebar__section-label"), n.textContent = e.label, t.appendChild(n);
52
+ }
53
+ let a = document.createElement("div");
54
+ a.classList.add("sidebar__items"), a.id = `sidebar-group-${e.id}`;
55
+ for (let t of e.items) {
56
+ let e = document.createElement("a");
57
+ if (e.classList.add("sidebar__item"), e.setAttribute("data-item-id", t.id), e.setAttribute("title", t.label), t.icon) {
58
+ let n = i(this.iconSet, t.icon);
59
+ e.appendChild(n);
34
60
  }
35
- for (let e of t.items) {
36
- let t = document.createElement("a");
37
- if (t.classList.add("sidebar__item"), t.setAttribute("data-item-id", e.id), t.setAttribute("title", e.label), e.icon) {
38
- let n = i(this.iconSet, e.icon);
39
- t.appendChild(n);
40
- }
41
- let r = document.createElement("span");
42
- if (r.classList.add("sidebar__item-label"), r.textContent = e.label, t.appendChild(r), e.badge !== void 0 && e.badge > 0) {
43
- let n = document.createElement("span"), r = e.badgeTone ?? "primary";
44
- t.setAttribute("data-badge-visible", "true"), t.setAttribute("data-badge-tone", r), n.classList.add("sidebar__badge", `sidebar__badge--${r}`), n.setAttribute("data-badge", e.id), n.textContent = String(e.badge), t.appendChild(n);
45
- }
46
- t.addEventListener("click", () => {
47
- this.config.onNavigate && this.config.onNavigate(e), e.onClick && e.onClick();
48
- }), n.appendChild(t);
61
+ let n = document.createElement("span");
62
+ if (n.classList.add("sidebar__item-label"), n.textContent = t.label, e.appendChild(n), t.badge !== void 0 && t.badge > 0) {
63
+ let n = document.createElement("span"), r = t.badgeTone ?? "primary";
64
+ e.setAttribute("data-badge-visible", "true"), e.setAttribute("data-badge-tone", r), n.classList.add("sidebar__badge", `sidebar__badge--${r}`), n.setAttribute("data-badge", t.id), n.textContent = String(t.badge), e.appendChild(n);
49
65
  }
50
- e.appendChild(n);
66
+ e.addEventListener("click", () => {
67
+ this.config.onNavigate && this.config.onNavigate(t), t.onClick && t.onClick();
68
+ }), a.appendChild(e);
51
69
  }
52
- this.aside.appendChild(e), this.renderFooter();
70
+ return t.appendChild(a), t;
53
71
  }
54
72
  renderHeader() {
55
73
  let e = this.config.brand;
@@ -142,4 +160,4 @@ var a = class {
142
160
  //#endregion
143
161
  export { a as t };
144
162
 
145
- //# sourceMappingURL=component-Dye0I6sO.js.map
163
+ //# sourceMappingURL=component-CBXhVCNE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-CBXhVCNE.js","names":[],"sources":["../src/sidebar/component.ts"],"sourcesContent":["/**\n * SidebarComponent - Programmatic sidebar with sections, badges, and footer\n * @countermeasure/web-components/sidebar/component\n *\n * Unlike sidebar/enhance (which enhances server-rendered HTML), this module\n * builds the sidebar DOM from a config object. Use it when the sidebar\n * structure is driven entirely by client-side data.\n *\n * Usage:\n * import { SidebarComponent } from '@countermeasure/web-components/sidebar/component'\n *\n * const sidebar = new SidebarComponent({\n * container: '#sidebar-root',\n * sections: [{ id: 'main', label: 'Nav', items: [...] }],\n * user: { name: 'Alice' },\n * onNavigate: item => console.log(item.id),\n * })\n * sidebar.setActive('dashboard')\n */\n\nimport { createBrandLockupElement } from '../components/brand'\nimport { getIconSvgInner, type IconSet } from '../icons/index'\nimport { resolveContainer } from '../primitives/utils'\nimport { type SidebarComponentConfig, type SidebarSection } from './types'\n\nfunction toSidebarVariantClassName(variant: string): string {\n const normalized = variant.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n return `sidebar--${normalized || 'app'}`\n}\n\n/** Create an SVG element populated with icon content from the registry. */\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', '18')\n svg.setAttribute('height', '18')\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.classList.add('sidebar__item-icon')\n svg.setAttribute('data-icon', name)\n svg.setAttribute('aria-hidden', 'true')\n\n const inner = getIconSvgInner(iconSet, name)\n if (inner) {\n svg.innerHTML = inner\n }\n\n return svg\n}\n\nexport class SidebarComponent {\n private readonly container: HTMLElement\n private readonly aside: HTMLElement\n private readonly config: SidebarComponentConfig\n private readonly iconSet: IconSet\n private collapseButton: HTMLButtonElement | null = null\n\n constructor(config: SidebarComponentConfig) {\n this.config = config\n this.container = resolveContainer(config.container)\n this.iconSet = config.iconSet ?? 'lucide'\n\n this.aside = document.createElement('aside')\n const variant = config.variant ?? 'app'\n this.aside.classList.add('sidebar', toSidebarVariantClassName(variant))\n this.aside.setAttribute('data-sidebar', variant)\n if (config.collapsed === true) {\n this.aside.classList.add('sidebar--collapsed')\n }\n\n this.render()\n this.container.appendChild(this.aside)\n }\n\n private render(): void {\n if (this.config.collapsible === true) {\n this.renderCollapseButton()\n }\n\n this.renderHeader()\n\n const body = document.createElement('div')\n body.classList.add('sidebar__body')\n\n for (const section of this.config.sections) {\n body.appendChild(this.buildSection(section))\n }\n\n this.aside.appendChild(body)\n this.renderFooter()\n }\n\n private buildSection(section: SidebarSection): HTMLElement {\n const sectionEl = document.createElement('div')\n sectionEl.classList.add('sidebar__section')\n sectionEl.setAttribute('data-section-id', section.id)\n\n const collapsible = section.collapsible === true\n const expanded = section.defaultExpanded !== false\n\n if (collapsible && section.label) {\n sectionEl.classList.add('sidebar__section--collapsible')\n if (expanded) sectionEl.classList.add('sidebar__section--expanded')\n\n const header = document.createElement('button')\n header.type = 'button'\n header.classList.add('sidebar__group-header')\n header.setAttribute('aria-expanded', String(expanded))\n header.setAttribute('aria-controls', `sidebar-group-${section.id}`)\n\n if (section.icon) {\n header.appendChild(createIconSvg(this.iconSet, section.icon))\n }\n\n const labelSpan = document.createElement('span')\n labelSpan.classList.add('sidebar__group-label')\n labelSpan.textContent = section.label\n header.appendChild(labelSpan)\n\n const chevron = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n chevron.setAttribute('class', 'sidebar__group-chevron')\n chevron.setAttribute('viewBox', '0 0 24 24')\n chevron.setAttribute('width', '14')\n chevron.setAttribute('height', '14')\n chevron.setAttribute('fill', 'none')\n chevron.setAttribute('stroke', 'currentColor')\n chevron.setAttribute('stroke-width', '2')\n chevron.setAttribute('stroke-linecap', 'round')\n chevron.setAttribute('stroke-linejoin', 'round')\n chevron.setAttribute('aria-hidden', 'true')\n const chevronPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n chevronPath.setAttribute('d', 'm6 9 6 6 6-6')\n chevron.appendChild(chevronPath)\n header.appendChild(chevron)\n\n header.addEventListener('click', () => {\n const nowExpanded = sectionEl.classList.toggle('sidebar__section--expanded')\n header.setAttribute('aria-expanded', String(nowExpanded))\n })\n\n sectionEl.appendChild(header)\n } else if (section.label) {\n const labelEl = document.createElement('div')\n labelEl.classList.add('sidebar__section-label')\n labelEl.textContent = section.label\n sectionEl.appendChild(labelEl)\n }\n\n const itemsWrap = document.createElement('div')\n itemsWrap.classList.add('sidebar__items')\n itemsWrap.id = `sidebar-group-${section.id}`\n\n for (const item of section.items) {\n const link = document.createElement('a')\n link.classList.add('sidebar__item')\n link.setAttribute('data-item-id', item.id)\n link.setAttribute('title', item.label)\n\n if (item.icon) {\n const icon = createIconSvg(this.iconSet, item.icon)\n link.appendChild(icon)\n }\n\n const label = document.createElement('span')\n label.classList.add('sidebar__item-label')\n label.textContent = item.label\n link.appendChild(label)\n\n if (item.badge !== undefined && item.badge > 0) {\n const badge = document.createElement('span')\n const tone = item.badgeTone ?? 'primary'\n link.setAttribute('data-badge-visible', 'true')\n link.setAttribute('data-badge-tone', tone)\n badge.classList.add('sidebar__badge', `sidebar__badge--${tone}`)\n badge.setAttribute('data-badge', item.id)\n badge.textContent = String(item.badge)\n link.appendChild(badge)\n }\n\n link.addEventListener('click', () => {\n if (this.config.onNavigate) {\n this.config.onNavigate(item)\n }\n if (item.onClick) {\n item.onClick()\n }\n })\n\n itemsWrap.appendChild(link)\n }\n\n sectionEl.appendChild(itemsWrap)\n return sectionEl\n }\n\n private renderHeader(): void {\n const brand = this.config.brand\n if (brand === undefined) {\n return\n }\n\n const header = document.createElement('div')\n header.classList.add('sidebar__header')\n\n const row = document.createElement('div')\n row.classList.add('sidebar__header-row')\n\n const brandEl =\n brand.href !== undefined\n ? document.createElement('a')\n : brand.onClick !== undefined\n ? document.createElement('button')\n : document.createElement('span')\n\n brandEl.classList.add('sidebar__brand')\n\n if (brandEl instanceof HTMLAnchorElement) {\n brandEl.href = brand.href ?? '#'\n brandEl.setAttribute('aria-label', brand.label ?? 'CounterMeasure')\n }\n\n if (brandEl instanceof HTMLButtonElement) {\n brandEl.type = 'button'\n brandEl.setAttribute('aria-label', brand.label ?? 'CounterMeasure')\n }\n\n if (brand.onClick !== undefined) {\n brandEl.addEventListener('click', brand.onClick)\n }\n\n brandEl.appendChild(\n createBrandLockupElement({\n label: brand.label ?? 'CounterMeasure',\n markSize: brand.markSize ?? 22,\n showWordmark: brand.showWordmark ?? true,\n decorative: brand.decorative ?? false,\n })\n )\n\n row.appendChild(brandEl)\n header.appendChild(row)\n this.aside.appendChild(header)\n }\n\n private renderCollapseButton(): void {\n const button = document.createElement('button')\n button.type = 'button'\n button.classList.add('sidebar__collapse-btn', 'sidebar__collapse-btn--edge')\n button.setAttribute('data-sidebar-toggle', '')\n\n if (this.config.collapseButtonVisible === true) {\n button.setAttribute('data-visible', 'true')\n }\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('aria-hidden', 'true')\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\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n svg.appendChild(path)\n button.appendChild(svg)\n\n button.addEventListener('click', () => {\n this.toggleCollapse()\n })\n\n this.collapseButton = button\n this.updateCollapseButton()\n this.aside.appendChild(button)\n }\n\n private renderFooter(): void {\n const hasUser = this.config.user !== undefined\n const hasActions =\n this.config.footerActions !== undefined && this.config.footerActions.length > 0\n\n if (!hasUser && !hasActions) {\n return\n }\n\n const footer = document.createElement('div')\n footer.classList.add('sidebar__footer')\n\n const footerBar = document.createElement('div')\n footerBar.classList.add('sidebar__footer-bar')\n\n if (hasUser && this.config.user) {\n const userSpan = document.createElement('span')\n userSpan.classList.add('sidebar__footer-user')\n\n const nameSpan = document.createElement('span')\n nameSpan.classList.add('sidebar__footer-name')\n nameSpan.textContent = this.config.user.name\n userSpan.appendChild(nameSpan)\n\n footerBar.appendChild(userSpan)\n }\n\n if (hasActions && this.config.footerActions) {\n const iconsSpan = document.createElement('span')\n iconsSpan.classList.add('sidebar__footer-icons')\n\n for (const action of this.config.footerActions) {\n const button = document.createElement('button')\n button.classList.add('sidebar__footer-icon')\n if (action.danger === true) {\n button.classList.add('sidebar__footer-icon--danger')\n }\n button.setAttribute('aria-label', action.label)\n\n const icon = createIconSvg(this.iconSet, action.icon)\n button.appendChild(icon)\n\n if (action.onClick) {\n const handler = action.onClick\n button.addEventListener('click', () => {\n handler()\n })\n }\n\n iconsSpan.appendChild(button)\n }\n\n footerBar.appendChild(iconsSpan)\n }\n\n footer.appendChild(footerBar)\n this.aside.appendChild(footer)\n }\n\n /** Mark a nav item as active, removing active state from all others. */\n setActive(itemId: string): void {\n this.aside.querySelectorAll<HTMLElement>('.sidebar__item').forEach(el => {\n el.classList.remove('sidebar__item--active')\n })\n\n const target = this.aside.querySelector<HTMLElement>(`[data-item-id=\"${itemId}\"]`)\n if (target) {\n target.classList.add('sidebar__item--active')\n }\n }\n\n /** Update the badge count for a nav item (empty string when count is 0). */\n updateBadge(itemId: string, count: number): void {\n const badge = this.aside.querySelector<HTMLElement>(`[data-badge=\"${itemId}\"]`)\n if (badge) {\n badge.textContent = count > 0 ? String(count) : ''\n const item = badge.closest<HTMLElement>('.sidebar__item')\n item?.setAttribute('data-badge-visible', String(count > 0))\n }\n }\n\n /** Toggle the sidebar between collapsed and expanded states. */\n toggleCollapse(): void {\n const isCollapsed = this.aside.classList.toggle('sidebar--collapsed')\n this.updateCollapseButton()\n if (this.config.onCollapse) {\n this.config.onCollapse(isCollapsed)\n }\n }\n\n /** Collapse the sidebar. */\n collapse(): void {\n const wasCollapsed = this.aside.classList.contains('sidebar--collapsed')\n this.aside.classList.add('sidebar--collapsed')\n this.updateCollapseButton()\n if (!wasCollapsed && this.config.onCollapse) {\n this.config.onCollapse(true)\n }\n }\n\n /** Expand the sidebar. */\n expand(): void {\n const wasCollapsed = this.aside.classList.contains('sidebar--collapsed')\n this.aside.classList.remove('sidebar--collapsed')\n this.updateCollapseButton()\n if (wasCollapsed && this.config.onCollapse) {\n this.config.onCollapse(false)\n }\n }\n\n /** Remove the sidebar from the DOM. */\n destroy(): void {\n this.aside.remove()\n }\n\n private updateCollapseButton(): void {\n if (this.collapseButton === null) {\n return\n }\n\n const isCollapsed = this.aside.classList.contains('sidebar--collapsed')\n const label = isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'\n this.collapseButton.setAttribute('aria-label', label)\n this.collapseButton.setAttribute('aria-expanded', String(!isCollapsed))\n this.collapseButton.setAttribute('title', label)\n this.collapseButton.setAttribute('data-collapsed', String(isCollapsed))\n this.collapseButton\n .querySelector('path')\n ?.setAttribute('d', isCollapsed ? 'm9 18 6-6-6-6' : 'm15 18-6-6 6-6')\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  /**
2
- * Canonical Lucide path data from
3
- * `CounterMeasure Design System/assets/lucide-icons.json`.
2
+ * Canonical Lucide path data bundled with the package.
4
3
  */
5
4
  export declare const LUCIDE_ICON_PATHS: {
6
5
  readonly FileCode2: "M5 21V3a2 2 0 0 1 2-2h7l5 5v15a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2zM14 3v5h5M10 13l-2 2 2 2M14 13l2 2-2 2";
@@ -1 +1 @@
1
- {"version":3,"file":"lucide.d.ts","sourceRoot":"","sources":["../../src/icons/lucide.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEpB,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAE3D,eAAO,MAAM,iBAAiB,EAAqC,cAAc,EAAE,CAAA;AAEnF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,cAAc,CAErE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGtE"}
1
+ {"version":3,"file":"lucide.d.ts","sourceRoot":"","sources":["../../src/icons/lucide.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmEpB,CAAA;AAEV,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAE3D,eAAO,MAAM,iBAAiB,EAAqC,cAAc,EAAE,CAAA;AAEnF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,cAAc,CAErE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAElE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"lucide.js","names":[],"sources":["../../src/icons/lucide.ts"],"sourcesContent":["/**\n * Canonical Lucide path data from\n * `CounterMeasure Design System/assets/lucide-icons.json`.\n */\n\nexport const LUCIDE_ICON_PATHS = {\n FileCode2:\n 'M5 21V3a2 2 0 0 1 2-2h7l5 5v15a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2zM14 3v5h5M10 13l-2 2 2 2M14 13l2 2-2 2',\n Shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',\n ShieldCheck: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10zM9 12l2 2 4-4',\n Radar: 'M19.07 4.93A10 10 0 0 0 6.99 3.34M4 6h.01M22 12A10 10 0 1 1 12 2M12 12 4.93 4.93',\n Grid3X3: 'M3 3h18v18H3zM9 3v18M15 3v18M3 9h18M3 15h18',\n Globe:\n 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zM2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z',\n CircleCheck: 'M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3',\n TriangleAlert:\n 'm21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3zM12 9v4M12 17h.01',\n CircleX: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM15 9l-6 6M9 9l6 6',\n CircleAlert: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 8v4M12 16h.01',\n Lightbulb:\n 'M9 18h6M10 22h4M15 14a4 4 0 0 0 1-3 4 4 0 1 0-8 0 4 4 0 0 0 1 3 5 5 0 0 1 1 3h4a5 5 0 0 1 1-3z',\n Building2:\n 'M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18ZM6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2M10 6h4M10 10h4M10 14h4M10 18h4',\n History: 'M3 12a9 9 0 1 0 9-9 9.74 9.74 0 0 0-7 3M3 3v6h6M12 7v5l4 2',\n Clock: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2',\n Layers: 'M12 2 2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5',\n Plug: 'M12 22v-5M9 7V2M15 7V2M6 13h12M6 13a4 4 0 0 1-4-4V7h20v2a4 4 0 0 1-4 4H6z',\n Workflow: 'M3 4h6v6H3zM15 14h6v6h-6zM6 14v3a3 3 0 0 0 3 3h3M21 4h-6v6h6V4z',\n Network: 'M9 2h6v6H9zM3 16h6v6H3zM15 16h6v6h-6zM12 8v3M5 16v-3a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3',\n Server: 'M2 4h20v6H2zM2 14h20v6H2zM6 7h.01M6 17h.01',\n Cog: 'M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z',\n ListFilter: 'M3 6h18M7 12h10M10 18h4',\n BookOpen: 'M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2zM22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z',\n BarChart3: 'M3 3v18h18M7 16v-5M12 16v-9M17 16v-3',\n Activity: 'M22 12h-4l-3 9L9 3l-3 9H2',\n Siren: 'M7 18a5 5 0 1 1 10 0M5 21h14M21 12h1M3 12H2M5.6 5.6l-.7-.7M18.4 5.6l.7-.7M11 4h2v3h-2z',\n Users:\n 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75',\n LayoutGrid: 'M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z',\n Code2: 'm18 16 4-4-4-4M6 8l-4 4 4 4M14.5 4l-5 16',\n Settings:\n 'M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',\n PanelLeftClose: 'M3 3h18v18H3zM9 3v18M16 15l-3-3 3-3',\n LogOut: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9',\n Sun: 'M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10z',\n ChevronDown: 'm6 9 6 6 6-6',\n ChevronRight: 'm9 6 6 6-6 6',\n Search: 'M21 21l-4.3-4.3M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z',\n Plus: 'M12 5v14M5 12h14',\n X: 'M18 6 6 18M6 6l12 12',\n Maximize2: 'M21 3h-6M21 3v6M21 3l-7 7M3 21h6M3 21v-6M3 21l7-7',\n RefreshCw: 'M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5',\n Download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3',\n ArrowUpRight: 'M7 7h10v10M7 17 17 7',\n Sparkles:\n 'M9.94 14.34 12 20l2.06-5.66L20 12l-5.94-2.06L12 4l-2.06 5.94L4 12zM18 4l.5 1.5L20 6l-1.5.5L18 8l-.5-1.5L16 6l1.5-.5zM4 18l.5 1.5L6 20l-1.5.5L4 22l-.5-1.5L2 20l1.5-.5z',\n Lock: 'M5 11h14v10H5zM7 11V7a5 5 0 0 1 10 0v4M12 16v2',\n Eye: 'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',\n Boxes:\n 'M2.97 12.92 7 14.5v6L3 19v-5.5l-.03-.58zM7 14.5l4-1.5M7 14.5v6l4-1.5v-6L7 14.5zM3 7l4-1.5L11 7v5.5L7 14.03 3 12.5V7zM21 12.5V7l-4-1.5L13 7v5.5L17 14l4-1.5zM17 14v6l4-1.5V13l-4 1zM13 13l4 1.5v6L13 19v-6z',\n GitBranch:\n 'M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM18 9a9 9 0 0 1-9 9',\n Gauge: 'M12 14l4-4M3.34 19a10 10 0 1 1 17.32 0',\n Tag: 'M12.59 2.59A2 2 0 0 0 11.17 2H4a2 2 0 0 0-2 2v7.17a2 2 0 0 0 .59 1.42l9 9a2 2 0 0 0 2.83 0l7.17-7.17a2 2 0 0 0 0-2.83l-9-9zM7 7h.01',\n Folder: 'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z',\n FileText:\n 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zM14 2v6h6M8 13h8M8 17h8M8 9h2',\n Package:\n 'M16.5 9.4 7.55 4.24M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16zM3.27 6.96 12 12.01l8.73-5.05M12 22.08V12',\n Rocket:\n 'M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09zM12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22 22 0 0 1-4 2zM9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0M15 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2z',\n KeyRound: 'M2 18 1 22h4l1-1v-3h3v-3h3l3.5-3.5a5 5 0 1 0-3-3L2 18zM16.5 7.5h.01',\n} as const\n\nexport type LucideIconName = keyof typeof LUCIDE_ICON_PATHS\n\nexport const LUCIDE_ICON_NAMES = Object.keys(LUCIDE_ICON_PATHS) as LucideIconName[]\n\nexport function isLucideIconName(name: string): name is LucideIconName {\n return Object.prototype.hasOwnProperty.call(LUCIDE_ICON_PATHS, name)\n}\n\nexport function getLucideIconPath(name: string): string | undefined {\n return isLucideIconName(name) ? LUCIDE_ICON_PATHS[name] : undefined\n}\n\nexport function getLucideIconSvgInner(name: string): string | undefined {\n const path = getLucideIconPath(name)\n return path === undefined ? undefined : `<path d=\"${path}\"/>`\n}\n"],"mappings":";AAKA,IAAa,IAAoB;CAC/B,WACE;CACF,QAAQ;CACR,aAAa;CACb,OAAO;CACP,SAAS;CACT,OACE;CACF,aAAa;CACb,eACE;CACF,SAAS;CACT,aAAa;CACb,WACE;CACF,WACE;CACF,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,UAAU;CACV,SAAS;CACT,QAAQ;CACR,KAAK;CACL,YAAY;CACZ,UAAU;CACV,WAAW;CACX,UAAU;CACV,OAAO;CACP,OACE;CACF,YAAY;CACZ,OAAO;CACP,UACE;CACF,gBAAgB;CAChB,QAAQ;CACR,KAAK;CACL,aAAa;CACb,cAAc;CACd,QAAQ;CACR,MAAM;CACN,GAAG;CACH,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,UACE;CACF,MAAM;CACN,KAAK;CACL,OACE;CACF,WACE;CACF,OAAO;CACP,KAAK;CACL,QAAQ;CACR,UACE;CACF,SACE;CACF,QACE;CACF,UAAU;CACX,EAIY,IAAoB,OAAO,KAAK,EAAkB;AAE/D,SAAgB,EAAiB,GAAsC;AACrE,QAAO,OAAO,UAAU,eAAe,KAAK,GAAmB,EAAK;;AAGtE,SAAgB,EAAkB,GAAkC;AAClE,QAAO,EAAiB,EAAK,GAAG,EAAkB,KAAQ,KAAA;;AAG5D,SAAgB,EAAsB,GAAkC;CACtE,IAAM,IAAO,EAAkB,EAAK;AACpC,QAAO,MAAS,KAAA,IAAY,KAAA,IAAY,YAAY,EAAK"}
1
+ {"version":3,"file":"lucide.js","names":[],"sources":["../../src/icons/lucide.ts"],"sourcesContent":["/**\n * Canonical Lucide path data bundled with the package.\n */\n\nexport const LUCIDE_ICON_PATHS = {\n FileCode2:\n 'M5 21V3a2 2 0 0 1 2-2h7l5 5v15a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2zM14 3v5h5M10 13l-2 2 2 2M14 13l2 2-2 2',\n Shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',\n ShieldCheck: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10zM9 12l2 2 4-4',\n Radar: 'M19.07 4.93A10 10 0 0 0 6.99 3.34M4 6h.01M22 12A10 10 0 1 1 12 2M12 12 4.93 4.93',\n Grid3X3: 'M3 3h18v18H3zM9 3v18M15 3v18M3 9h18M3 15h18',\n Globe:\n 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zM2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z',\n CircleCheck: 'M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3',\n TriangleAlert:\n 'm21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3zM12 9v4M12 17h.01',\n CircleX: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM15 9l-6 6M9 9l6 6',\n CircleAlert: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 8v4M12 16h.01',\n Lightbulb:\n 'M9 18h6M10 22h4M15 14a4 4 0 0 0 1-3 4 4 0 1 0-8 0 4 4 0 0 0 1 3 5 5 0 0 1 1 3h4a5 5 0 0 1 1-3z',\n Building2:\n 'M6 22V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v18ZM6 12H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h2M18 9h2a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2h-2M10 6h4M10 10h4M10 14h4M10 18h4',\n History: 'M3 12a9 9 0 1 0 9-9 9.74 9.74 0 0 0-7 3M3 3v6h6M12 7v5l4 2',\n Clock: 'M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2',\n Layers: 'M12 2 2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5',\n Plug: 'M12 22v-5M9 7V2M15 7V2M6 13h12M6 13a4 4 0 0 1-4-4V7h20v2a4 4 0 0 1-4 4H6z',\n Workflow: 'M3 4h6v6H3zM15 14h6v6h-6zM6 14v3a3 3 0 0 0 3 3h3M21 4h-6v6h6V4z',\n Network: 'M9 2h6v6H9zM3 16h6v6H3zM15 16h6v6h-6zM12 8v3M5 16v-3a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v3',\n Server: 'M2 4h20v6H2zM2 14h20v6H2zM6 7h.01M6 17h.01',\n Cog: 'M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z',\n ListFilter: 'M3 6h18M7 12h10M10 18h4',\n BookOpen: 'M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2zM22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z',\n BarChart3: 'M3 3v18h18M7 16v-5M12 16v-9M17 16v-3',\n Activity: 'M22 12h-4l-3 9L9 3l-3 9H2',\n Siren: 'M7 18a5 5 0 1 1 10 0M5 21h14M21 12h1M3 12H2M5.6 5.6l-.7-.7M18.4 5.6l.7-.7M11 4h2v3h-2z',\n Users:\n 'M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75',\n LayoutGrid: 'M3 3h7v7H3zM14 3h7v7h-7zM14 14h7v7h-7zM3 14h7v7H3z',\n Code2: 'm18 16 4-4-4-4M6 8l-4 4 4 4M14.5 4l-5 16',\n Settings:\n 'M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',\n PanelLeftClose: 'M3 3h18v18H3zM9 3v18M16 15l-3-3 3-3',\n LogOut: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9',\n Sun: 'M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41M12 7a5 5 0 1 0 0 10 5 5 0 0 0 0-10z',\n ChevronDown: 'm6 9 6 6 6-6',\n ChevronRight: 'm9 6 6 6-6 6',\n Search: 'M21 21l-4.3-4.3M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z',\n Plus: 'M12 5v14M5 12h14',\n X: 'M18 6 6 18M6 6l12 12',\n Maximize2: 'M21 3h-6M21 3v6M21 3l-7 7M3 21h6M3 21v-6M3 21l7-7',\n RefreshCw: 'M3 12a9 9 0 0 1 15-6.7L21 8M21 3v5h-5M21 12a9 9 0 0 1-15 6.7L3 16M3 21v-5h5',\n Download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3',\n ArrowUpRight: 'M7 7h10v10M7 17 17 7',\n Sparkles:\n 'M9.94 14.34 12 20l2.06-5.66L20 12l-5.94-2.06L12 4l-2.06 5.94L4 12zM18 4l.5 1.5L20 6l-1.5.5L18 8l-.5-1.5L16 6l1.5-.5zM4 18l.5 1.5L6 20l-1.5.5L4 22l-.5-1.5L2 20l1.5-.5z',\n Lock: 'M5 11h14v10H5zM7 11V7a5 5 0 0 1 10 0v4M12 16v2',\n Eye: 'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',\n Boxes:\n 'M2.97 12.92 7 14.5v6L3 19v-5.5l-.03-.58zM7 14.5l4-1.5M7 14.5v6l4-1.5v-6L7 14.5zM3 7l4-1.5L11 7v5.5L7 14.03 3 12.5V7zM21 12.5V7l-4-1.5L13 7v5.5L17 14l4-1.5zM17 14v6l4-1.5V13l-4 1zM13 13l4 1.5v6L13 19v-6z',\n GitBranch:\n 'M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM18 9a9 9 0 0 1-9 9',\n Gauge: 'M12 14l4-4M3.34 19a10 10 0 1 1 17.32 0',\n Tag: 'M12.59 2.59A2 2 0 0 0 11.17 2H4a2 2 0 0 0-2 2v7.17a2 2 0 0 0 .59 1.42l9 9a2 2 0 0 0 2.83 0l7.17-7.17a2 2 0 0 0 0-2.83l-9-9zM7 7h.01',\n Folder: 'M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z',\n FileText:\n 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6zM14 2v6h6M8 13h8M8 17h8M8 9h2',\n Package:\n 'M16.5 9.4 7.55 4.24M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16zM3.27 6.96 12 12.01l8.73-5.05M12 22.08V12',\n Rocket:\n 'M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09zM12 15l-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22 22 0 0 1-4 2zM9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0M15 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2z',\n KeyRound: 'M2 18 1 22h4l1-1v-3h3v-3h3l3.5-3.5a5 5 0 1 0-3-3L2 18zM16.5 7.5h.01',\n} as const\n\nexport type LucideIconName = keyof typeof LUCIDE_ICON_PATHS\n\nexport const LUCIDE_ICON_NAMES = Object.keys(LUCIDE_ICON_PATHS) as LucideIconName[]\n\nexport function isLucideIconName(name: string): name is LucideIconName {\n return Object.prototype.hasOwnProperty.call(LUCIDE_ICON_PATHS, name)\n}\n\nexport function getLucideIconPath(name: string): string | undefined {\n return isLucideIconName(name) ? LUCIDE_ICON_PATHS[name] : undefined\n}\n\nexport function getLucideIconSvgInner(name: string): string | undefined {\n const path = getLucideIconPath(name)\n return path === undefined ? undefined : `<path d=\"${path}\"/>`\n}\n"],"mappings":";AAIA,IAAa,IAAoB;CAC/B,WACE;CACF,QAAQ;CACR,aAAa;CACb,OAAO;CACP,SAAS;CACT,OACE;CACF,aAAa;CACb,eACE;CACF,SAAS;CACT,aAAa;CACb,WACE;CACF,WACE;CACF,SAAS;CACT,OAAO;CACP,QAAQ;CACR,MAAM;CACN,UAAU;CACV,SAAS;CACT,QAAQ;CACR,KAAK;CACL,YAAY;CACZ,UAAU;CACV,WAAW;CACX,UAAU;CACV,OAAO;CACP,OACE;CACF,YAAY;CACZ,OAAO;CACP,UACE;CACF,gBAAgB;CAChB,QAAQ;CACR,KAAK;CACL,aAAa;CACb,cAAc;CACd,QAAQ;CACR,MAAM;CACN,GAAG;CACH,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,UACE;CACF,MAAM;CACN,KAAK;CACL,OACE;CACF,WACE;CACF,OAAO;CACP,KAAK;CACL,QAAQ;CACR,UACE;CACF,SACE;CACF,QACE;CACF,UAAU;CACX,EAIY,IAAoB,OAAO,KAAK,EAAkB;AAE/D,SAAgB,EAAiB,GAAsC;AACrE,QAAO,OAAO,UAAU,eAAe,KAAK,GAAmB,EAAK;;AAGtE,SAAgB,EAAkB,GAAkC;AAClE,QAAO,EAAiB,EAAK,GAAG,EAAkB,KAAQ,KAAA;;AAG5D,SAAgB,EAAsB,GAAkC;CACtE,IAAM,IAAO,EAAkB,EAAK;AACpC,QAAO,MAAS,KAAA,IAAY,KAAA,IAAY,YAAY,EAAK"}
@@ -1,4 +1,4 @@
1
- import { t as e } from "../component-Dye0I6sO.js";
1
+ import { t as e } from "../component-CBXhVCNE.js";
2
2
  import { t } from "../utils-DcOSDVkb.js";
3
3
  import * as n from "react";
4
4
  import { jsx as r } from "react/jsx-runtime";
@@ -7,6 +7,7 @@ export declare class SidebarComponent {
7
7
  private collapseButton;
8
8
  constructor(config: SidebarComponentConfig);
9
9
  private render;
10
+ private buildSection;
10
11
  private renderHeader;
11
12
  private renderCollapseButton;
12
13
  private renderFooter;
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/sidebar/component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAgCrD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,cAAc,CAAiC;gBAE3C,MAAM,EAAE,sBAAsB;IAc1C,OAAO,CAAC,MAAM;IAmEd,OAAO,CAAC,YAAY;IAiDpB,OAAO,CAAC,oBAAoB;IAgC5B,OAAO,CAAC,YAAY;IA2DpB,wEAAwE;IACxE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAW/B,4EAA4E;IAC5E,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAShD,gEAAgE;IAChE,cAAc,IAAI,IAAI;IAQtB,4BAA4B;IAC5B,QAAQ,IAAI,IAAI;IAShB,0BAA0B;IAC1B,MAAM,IAAI,IAAI;IASd,uCAAuC;IACvC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,oBAAoB;CAe7B"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/sidebar/component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAAE,KAAK,sBAAsB,EAAuB,MAAM,SAAS,CAAA;AAgC1E,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,cAAc,CAAiC;gBAE3C,MAAM,EAAE,sBAAsB;IAiB1C,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,YAAY;IAuGpB,OAAO,CAAC,YAAY;IAiDpB,OAAO,CAAC,oBAAoB;IAgC5B,OAAO,CAAC,YAAY;IA2DpB,wEAAwE;IACxE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAW/B,4EAA4E;IAC5E,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAShD,gEAAgE;IAChE,cAAc,IAAI,IAAI;IAQtB,4BAA4B;IAC5B,QAAQ,IAAI,IAAI;IAShB,0BAA0B;IAC1B,MAAM,IAAI,IAAI;IASd,uCAAuC;IACvC,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,oBAAoB;CAe7B"}
@@ -1,4 +1,4 @@
1
- import { t as e } from "../component-Dye0I6sO.js";
1
+ import { t as e } from "../component-CBXhVCNE.js";
2
2
  //#region src/sidebar/index.ts
3
3
  var t = {
4
4
  storageKey: "sidebar-collapsed",
@@ -24,6 +24,20 @@ export interface SidebarSection {
24
24
  label?: string;
25
25
  /** Nav items rendered within this section. */
26
26
  items: SidebarNavItem[];
27
+ /**
28
+ * Render the section as a collapsible accordion group with a clickable
29
+ * header instead of a flat label. When set, `label` is rendered as the
30
+ * toggle and items collapse/expand on click.
31
+ * @default false
32
+ */
33
+ collapsible?: boolean;
34
+ /**
35
+ * Initial expanded state when `collapsible` is true.
36
+ * @default true
37
+ */
38
+ defaultExpanded?: boolean;
39
+ /** Optional icon for the collapsible group header. */
40
+ icon?: string;
27
41
  }
28
42
  export interface SidebarUser {
29
43
  /** Display name shown in the footer. */
@@ -93,6 +107,12 @@ export interface SidebarComponentConfig {
93
107
  * @default 'lucide'
94
108
  */
95
109
  iconSet?: IconSet;
110
+ /**
111
+ * Initial collapsed state. When `collapsible` is true the collapse button
112
+ * starts pointing the matching direction.
113
+ * @default false
114
+ */
115
+ collapsed?: boolean;
96
116
  /** Called when a nav item is activated. */
97
117
  onNavigate?: (item: SidebarNavItem) => void;
98
118
  /** Called when the sidebar's collapsed state changes. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sidebar/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAE7C,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAA;IACV,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IACnF,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,KAAK,EAAE,cAAc,EAAE,CAAA;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uBAAuB;IACvB,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,SAAS,EAAE,WAAW,GAAG,MAAM,CAAA;IAC/B,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uCAAuC;IACvC,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,oDAAoD;IACpD,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3C,yDAAyD;IACzD,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;CAC1C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sidebar/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAE7C,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAA;IACV,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;IACnF,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uBAAuB;IACvB,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,SAAS,EAAE,WAAW,GAAG,MAAM,CAAA;IAC/B,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uCAAuC;IACvC,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,oDAAoD;IACpD,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAA;IAC3C,yDAAyD;IACzD,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;CAC1C"}
@@ -526,6 +526,79 @@ button.sidebar__brand {
526
526
  margin: 0;
527
527
  }
528
528
 
529
+ /* -----------------------------------------------------------------------------
530
+ Collapsible Section / Accordion Group
531
+ ----------------------------------------------------------------------------- */
532
+ .sidebar__group-header {
533
+ display: flex;
534
+ align-items: center;
535
+ gap: 0.5rem;
536
+ padding: 0.3125rem 0.75rem;
537
+ border-radius: 0.375rem;
538
+ color: var(--color-text);
539
+ font-size: 0.8125rem;
540
+ font-weight: 500;
541
+ cursor: pointer;
542
+ border: none;
543
+ background: none;
544
+ width: 100%;
545
+ text-align: left;
546
+ transition:
547
+ background 0.15s,
548
+ color 0.15s;
549
+ }
550
+
551
+ .sidebar__group-header:hover {
552
+ background: var(--color-surface-hover);
553
+ }
554
+
555
+ .sidebar__group-label {
556
+ flex: 1;
557
+ min-width: 0;
558
+ overflow: hidden;
559
+ text-overflow: ellipsis;
560
+ white-space: nowrap;
561
+ }
562
+
563
+ .sidebar__group-chevron {
564
+ flex-shrink: 0;
565
+ color: var(--color-text-muted);
566
+ transition: transform 0.2s ease;
567
+ }
568
+
569
+ .sidebar__section--expanded > .sidebar__group-header .sidebar__group-chevron {
570
+ transform: rotate(0deg);
571
+ }
572
+
573
+ .sidebar__section--collapsible:not(.sidebar__section--expanded)
574
+ > .sidebar__group-header
575
+ .sidebar__group-chevron {
576
+ transform: rotate(-90deg);
577
+ }
578
+
579
+ .sidebar__section--collapsible > .sidebar__items {
580
+ max-height: 0;
581
+ overflow: hidden;
582
+ transition: max-height 250ms ease;
583
+ }
584
+
585
+ .sidebar__section--collapsible.sidebar__section--expanded > .sidebar__items {
586
+ max-height: 2000px;
587
+ }
588
+
589
+ .sidebar--collapsed .sidebar__group-header {
590
+ justify-content: center;
591
+ }
592
+
593
+ .sidebar--collapsed .sidebar__group-label,
594
+ .sidebar--collapsed .sidebar__group-chevron {
595
+ display: none;
596
+ }
597
+
598
+ .sidebar--collapsed .sidebar__section--collapsible > .sidebar__items {
599
+ display: none;
600
+ }
601
+
529
602
  /* Badges */
530
603
  .sidebar__badge {
531
604
  display: inline-flex;
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * CounterMeasure Tenant UI product overlay.
3
3
  *
4
- * Generated from the WASM tenant UI implementation while adopting
5
- * /Users/wyattroersma/main/CounterMeasure Design System/ as the canonical
6
- * visual source. Keep Docker consumers independent from npm by syncing this
7
- * file into tenant-ui-wasm as a static CSS snapshot.
4
+ * Generated from the WASM tenant UI implementation. Keep Docker consumers
5
+ * independent from npm by syncing this file into tenant-ui-wasm as a static
6
+ * CSS snapshot.
8
7
  */
9
8
 
10
9
  @import "./no-fonts.css";
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * CounterMeasure Threat Library and platform console product overlay.
3
- * Source: CounterMeasure Design System/ui_kits/threat-library/styles.css.
4
3
  */
5
4
 
6
5
  @import "./no-fonts.css";
@@ -2,7 +2,6 @@
2
2
  * CounterMeasure Design System Tokens
3
3
  * @countermeasure-platform/web-components
4
4
  *
5
- * Canonical source: CounterMeasure Design System/colors_and_type.css.
6
5
  * The public design-system surface uses named --color-* variables while the
7
6
  * existing component and Tailwind plumbing continue to consume HSL triplets.
8
7
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@countermeasure-platform/web-components",
3
- "version": "1.2.2-dev.7.1",
3
+ "version": "1.2.2-dev.8.1",
4
4
  "description": "Shared web components for CounterMeasure applications - consolidates common frontend functionality across projects.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -154,6 +154,40 @@ describe('IconGalleryBrowser accessibility', () => {
154
154
 
155
155
  picker.destroy()
156
156
  })
157
+
158
+ it.each([
159
+ { iconSet: 'lucide', strokeWidth: '2', linecap: 'round', linejoin: 'round', heading: /All Icons — Lucide style/ },
160
+ { iconSet: 'heroicons', strokeWidth: '2.4', linecap: 'round', linejoin: 'round', heading: /All Icons — Heroicons style/ },
161
+ { iconSet: 'phosphor', strokeWidth: '1.5', linecap: 'round', linejoin: 'round', heading: /All Icons — Phosphor style/ },
162
+ { iconSet: 'material', strokeWidth: '2', linecap: 'square', linejoin: 'miter', heading: /All Icons — Material style/ },
163
+ {
164
+ iconSet: 'countermeasure',
165
+ strokeWidth: '1.75',
166
+ linecap: 'round',
167
+ linejoin: 'round',
168
+ heading: /CounterMeasure Brand Icons/,
169
+ },
170
+ ] as const)(
171
+ 'applies the $iconSet stroke and linecap to gallery cells',
172
+ ({ iconSet, strokeWidth, linecap, linejoin, heading }) => {
173
+ const picker = new IconGalleryBrowser()
174
+ document.body.appendChild(picker.el)
175
+
176
+ setThemePartial({ iconSet })
177
+ requireButton(picker.el, '.theme-studio-icon-gallery__toggle').click()
178
+
179
+ const heading_el = requireElement(picker.el, '.theme-studio-icon-gallery__heading')
180
+ expect(heading_el.textContent ?? '').toMatch(heading)
181
+
182
+ const svg = picker.el.querySelector('.theme-studio-icon-gallery__cell svg')
183
+ expect(svg).toBeTruthy()
184
+ expect(svg?.getAttribute('stroke-width')).toBe(strokeWidth)
185
+ expect(svg?.getAttribute('stroke-linecap')).toBe(linecap)
186
+ expect(svg?.getAttribute('stroke-linejoin')).toBe(linejoin)
187
+
188
+ picker.destroy()
189
+ }
190
+ )
157
191
  })
158
192
 
159
193
  describe('IconSetPicker event listener cleanup', () => {
@@ -1,6 +1,5 @@
1
1
  /**
2
- * Canonical Lucide path data from
3
- * `CounterMeasure Design System/assets/lucide-icons.json`.
2
+ * Canonical Lucide path data bundled with the package.
4
3
  */
5
4
 
6
5
  export const LUCIDE_ICON_PATHS = {
@@ -18,10 +18,10 @@
18
18
  * sidebar.setActive('dashboard')
19
19
  */
20
20
 
21
+ import { createBrandLockupElement } from '../components/brand'
21
22
  import { getIconSvgInner, type IconSet } from '../icons/index'
22
23
  import { resolveContainer } from '../primitives/utils'
23
- import { createBrandLockupElement } from '../components/brand'
24
- import { type SidebarComponentConfig } from './types'
24
+ import { type SidebarComponentConfig, type SidebarSection } from './types'
25
25
 
26
26
  function toSidebarVariantClassName(variant: string): string {
27
27
  const normalized = variant.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')
@@ -69,6 +69,9 @@ export class SidebarComponent {
69
69
  const variant = config.variant ?? 'app'
70
70
  this.aside.classList.add('sidebar', toSidebarVariantClassName(variant))
71
71
  this.aside.setAttribute('data-sidebar', variant)
72
+ if (config.collapsed === true) {
73
+ this.aside.classList.add('sidebar--collapsed')
74
+ }
72
75
 
73
76
  this.render()
74
77
  this.container.appendChild(this.aside)
@@ -85,60 +88,114 @@ export class SidebarComponent {
85
88
  body.classList.add('sidebar__body')
86
89
 
87
90
  for (const section of this.config.sections) {
88
- const sectionEl = document.createElement('div')
89
- sectionEl.classList.add('sidebar__section')
90
-
91
- if (section.label) {
92
- const labelEl = document.createElement('div')
93
- labelEl.classList.add('sidebar__section-label')
94
- labelEl.textContent = section.label
95
- sectionEl.appendChild(labelEl)
91
+ body.appendChild(this.buildSection(section))
92
+ }
93
+
94
+ this.aside.appendChild(body)
95
+ this.renderFooter()
96
+ }
97
+
98
+ private buildSection(section: SidebarSection): HTMLElement {
99
+ const sectionEl = document.createElement('div')
100
+ sectionEl.classList.add('sidebar__section')
101
+ sectionEl.setAttribute('data-section-id', section.id)
102
+
103
+ const collapsible = section.collapsible === true
104
+ const expanded = section.defaultExpanded !== false
105
+
106
+ if (collapsible && section.label) {
107
+ sectionEl.classList.add('sidebar__section--collapsible')
108
+ if (expanded) sectionEl.classList.add('sidebar__section--expanded')
109
+
110
+ const header = document.createElement('button')
111
+ header.type = 'button'
112
+ header.classList.add('sidebar__group-header')
113
+ header.setAttribute('aria-expanded', String(expanded))
114
+ header.setAttribute('aria-controls', `sidebar-group-${section.id}`)
115
+
116
+ if (section.icon) {
117
+ header.appendChild(createIconSvg(this.iconSet, section.icon))
96
118
  }
97
119
 
98
- for (const item of section.items) {
99
- const link = document.createElement('a')
100
- link.classList.add('sidebar__item')
101
- link.setAttribute('data-item-id', item.id)
102
- link.setAttribute('title', item.label)
120
+ const labelSpan = document.createElement('span')
121
+ labelSpan.classList.add('sidebar__group-label')
122
+ labelSpan.textContent = section.label
123
+ header.appendChild(labelSpan)
124
+
125
+ const chevron = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
126
+ chevron.setAttribute('class', 'sidebar__group-chevron')
127
+ chevron.setAttribute('viewBox', '0 0 24 24')
128
+ chevron.setAttribute('width', '14')
129
+ chevron.setAttribute('height', '14')
130
+ chevron.setAttribute('fill', 'none')
131
+ chevron.setAttribute('stroke', 'currentColor')
132
+ chevron.setAttribute('stroke-width', '2')
133
+ chevron.setAttribute('stroke-linecap', 'round')
134
+ chevron.setAttribute('stroke-linejoin', 'round')
135
+ chevron.setAttribute('aria-hidden', 'true')
136
+ const chevronPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')
137
+ chevronPath.setAttribute('d', 'm6 9 6 6 6-6')
138
+ chevron.appendChild(chevronPath)
139
+ header.appendChild(chevron)
140
+
141
+ header.addEventListener('click', () => {
142
+ const nowExpanded = sectionEl.classList.toggle('sidebar__section--expanded')
143
+ header.setAttribute('aria-expanded', String(nowExpanded))
144
+ })
103
145
 
104
- if (item.icon) {
105
- const icon = createIconSvg(this.iconSet, item.icon)
106
- link.appendChild(icon)
107
- }
146
+ sectionEl.appendChild(header)
147
+ } else if (section.label) {
148
+ const labelEl = document.createElement('div')
149
+ labelEl.classList.add('sidebar__section-label')
150
+ labelEl.textContent = section.label
151
+ sectionEl.appendChild(labelEl)
152
+ }
108
153
 
109
- const label = document.createElement('span')
110
- label.classList.add('sidebar__item-label')
111
- label.textContent = item.label
112
- link.appendChild(label)
113
-
114
- if (item.badge !== undefined && item.badge > 0) {
115
- const badge = document.createElement('span')
116
- const tone = item.badgeTone ?? 'primary'
117
- link.setAttribute('data-badge-visible', 'true')
118
- link.setAttribute('data-badge-tone', tone)
119
- badge.classList.add('sidebar__badge', `sidebar__badge--${tone}`)
120
- badge.setAttribute('data-badge', item.id)
121
- badge.textContent = String(item.badge)
122
- link.appendChild(badge)
123
- }
154
+ const itemsWrap = document.createElement('div')
155
+ itemsWrap.classList.add('sidebar__items')
156
+ itemsWrap.id = `sidebar-group-${section.id}`
157
+
158
+ for (const item of section.items) {
159
+ const link = document.createElement('a')
160
+ link.classList.add('sidebar__item')
161
+ link.setAttribute('data-item-id', item.id)
162
+ link.setAttribute('title', item.label)
124
163
 
125
- link.addEventListener('click', () => {
126
- if (this.config.onNavigate) {
127
- this.config.onNavigate(item)
128
- }
129
- if (item.onClick) {
130
- item.onClick()
131
- }
132
- })
164
+ if (item.icon) {
165
+ const icon = createIconSvg(this.iconSet, item.icon)
166
+ link.appendChild(icon)
167
+ }
133
168
 
134
- sectionEl.appendChild(link)
169
+ const label = document.createElement('span')
170
+ label.classList.add('sidebar__item-label')
171
+ label.textContent = item.label
172
+ link.appendChild(label)
173
+
174
+ if (item.badge !== undefined && item.badge > 0) {
175
+ const badge = document.createElement('span')
176
+ const tone = item.badgeTone ?? 'primary'
177
+ link.setAttribute('data-badge-visible', 'true')
178
+ link.setAttribute('data-badge-tone', tone)
179
+ badge.classList.add('sidebar__badge', `sidebar__badge--${tone}`)
180
+ badge.setAttribute('data-badge', item.id)
181
+ badge.textContent = String(item.badge)
182
+ link.appendChild(badge)
135
183
  }
136
184
 
137
- body.appendChild(sectionEl)
185
+ link.addEventListener('click', () => {
186
+ if (this.config.onNavigate) {
187
+ this.config.onNavigate(item)
188
+ }
189
+ if (item.onClick) {
190
+ item.onClick()
191
+ }
192
+ })
193
+
194
+ itemsWrap.appendChild(link)
138
195
  }
139
196
 
140
- this.aside.appendChild(body)
141
- this.renderFooter()
197
+ sectionEl.appendChild(itemsWrap)
198
+ return sectionEl
142
199
  }
143
200
 
144
201
  private renderHeader(): void {
@@ -31,6 +31,20 @@ export interface SidebarSection {
31
31
  label?: string
32
32
  /** Nav items rendered within this section. */
33
33
  items: SidebarNavItem[]
34
+ /**
35
+ * Render the section as a collapsible accordion group with a clickable
36
+ * header instead of a flat label. When set, `label` is rendered as the
37
+ * toggle and items collapse/expand on click.
38
+ * @default false
39
+ */
40
+ collapsible?: boolean
41
+ /**
42
+ * Initial expanded state when `collapsible` is true.
43
+ * @default true
44
+ */
45
+ defaultExpanded?: boolean
46
+ /** Optional icon for the collapsible group header. */
47
+ icon?: string
34
48
  }
35
49
 
36
50
  export interface SidebarUser {
@@ -104,6 +118,12 @@ export interface SidebarComponentConfig {
104
118
  * @default 'lucide'
105
119
  */
106
120
  iconSet?: IconSet
121
+ /**
122
+ * Initial collapsed state. When `collapsible` is true the collapse button
123
+ * starts pointing the matching direction.
124
+ * @default false
125
+ */
126
+ collapsed?: boolean
107
127
  /** Called when a nav item is activated. */
108
128
  onNavigate?: (item: SidebarNavItem) => void
109
129
  /** Called when the sidebar's collapsed state changes. */
@@ -526,6 +526,79 @@ button.sidebar__brand {
526
526
  margin: 0;
527
527
  }
528
528
 
529
+ /* -----------------------------------------------------------------------------
530
+ Collapsible Section / Accordion Group
531
+ ----------------------------------------------------------------------------- */
532
+ .sidebar__group-header {
533
+ display: flex;
534
+ align-items: center;
535
+ gap: 0.5rem;
536
+ padding: 0.3125rem 0.75rem;
537
+ border-radius: 0.375rem;
538
+ color: var(--color-text);
539
+ font-size: 0.8125rem;
540
+ font-weight: 500;
541
+ cursor: pointer;
542
+ border: none;
543
+ background: none;
544
+ width: 100%;
545
+ text-align: left;
546
+ transition:
547
+ background 0.15s,
548
+ color 0.15s;
549
+ }
550
+
551
+ .sidebar__group-header:hover {
552
+ background: var(--color-surface-hover);
553
+ }
554
+
555
+ .sidebar__group-label {
556
+ flex: 1;
557
+ min-width: 0;
558
+ overflow: hidden;
559
+ text-overflow: ellipsis;
560
+ white-space: nowrap;
561
+ }
562
+
563
+ .sidebar__group-chevron {
564
+ flex-shrink: 0;
565
+ color: var(--color-text-muted);
566
+ transition: transform 0.2s ease;
567
+ }
568
+
569
+ .sidebar__section--expanded > .sidebar__group-header .sidebar__group-chevron {
570
+ transform: rotate(0deg);
571
+ }
572
+
573
+ .sidebar__section--collapsible:not(.sidebar__section--expanded)
574
+ > .sidebar__group-header
575
+ .sidebar__group-chevron {
576
+ transform: rotate(-90deg);
577
+ }
578
+
579
+ .sidebar__section--collapsible > .sidebar__items {
580
+ max-height: 0;
581
+ overflow: hidden;
582
+ transition: max-height 250ms ease;
583
+ }
584
+
585
+ .sidebar__section--collapsible.sidebar__section--expanded > .sidebar__items {
586
+ max-height: 2000px;
587
+ }
588
+
589
+ .sidebar--collapsed .sidebar__group-header {
590
+ justify-content: center;
591
+ }
592
+
593
+ .sidebar--collapsed .sidebar__group-label,
594
+ .sidebar--collapsed .sidebar__group-chevron {
595
+ display: none;
596
+ }
597
+
598
+ .sidebar--collapsed .sidebar__section--collapsible > .sidebar__items {
599
+ display: none;
600
+ }
601
+
529
602
  /* Badges */
530
603
  .sidebar__badge {
531
604
  display: inline-flex;
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * CounterMeasure Tenant UI product overlay.
3
3
  *
4
- * Generated from the WASM tenant UI implementation while adopting
5
- * /Users/wyattroersma/main/CounterMeasure Design System/ as the canonical
6
- * visual source. Keep Docker consumers independent from npm by syncing this
7
- * file into tenant-ui-wasm as a static CSS snapshot.
4
+ * Generated from the WASM tenant UI implementation. Keep Docker consumers
5
+ * independent from npm by syncing this file into tenant-ui-wasm as a static
6
+ * CSS snapshot.
8
7
  */
9
8
 
10
9
  @import "./no-fonts.css";
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * CounterMeasure Threat Library and platform console product overlay.
3
- * Source: CounterMeasure Design System/ui_kits/threat-library/styles.css.
4
3
  */
5
4
 
6
5
  @import "./no-fonts.css";
@@ -2,7 +2,6 @@
2
2
  * CounterMeasure Design System Tokens
3
3
  * @countermeasure-platform/web-components
4
4
  *
5
- * Canonical source: CounterMeasure Design System/colors_and_type.css.
6
5
  * The public design-system surface uses named --color-* variables while the
7
6
  * existing component and Tailwind plumbing continue to consume HSL triplets.
8
7
  */
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-Dye0I6sO.js","names":[],"sources":["../src/sidebar/component.ts"],"sourcesContent":["/**\n * SidebarComponent - Programmatic sidebar with sections, badges, and footer\n * @countermeasure/web-components/sidebar/component\n *\n * Unlike sidebar/enhance (which enhances server-rendered HTML), this module\n * builds the sidebar DOM from a config object. Use it when the sidebar\n * structure is driven entirely by client-side data.\n *\n * Usage:\n * import { SidebarComponent } from '@countermeasure/web-components/sidebar/component'\n *\n * const sidebar = new SidebarComponent({\n * container: '#sidebar-root',\n * sections: [{ id: 'main', label: 'Nav', items: [...] }],\n * user: { name: 'Alice' },\n * onNavigate: item => console.log(item.id),\n * })\n * sidebar.setActive('dashboard')\n */\n\nimport { getIconSvgInner, type IconSet } from '../icons/index'\nimport { resolveContainer } from '../primitives/utils'\nimport { createBrandLockupElement } from '../components/brand'\nimport { type SidebarComponentConfig } from './types'\n\nfunction toSidebarVariantClassName(variant: string): string {\n const normalized = variant.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')\n return `sidebar--${normalized || 'app'}`\n}\n\n/** Create an SVG element populated with icon content from the registry. */\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', '18')\n svg.setAttribute('height', '18')\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.classList.add('sidebar__item-icon')\n svg.setAttribute('data-icon', name)\n svg.setAttribute('aria-hidden', 'true')\n\n const inner = getIconSvgInner(iconSet, name)\n if (inner) {\n svg.innerHTML = inner\n }\n\n return svg\n}\n\nexport class SidebarComponent {\n private readonly container: HTMLElement\n private readonly aside: HTMLElement\n private readonly config: SidebarComponentConfig\n private readonly iconSet: IconSet\n private collapseButton: HTMLButtonElement | null = null\n\n constructor(config: SidebarComponentConfig) {\n this.config = config\n this.container = resolveContainer(config.container)\n this.iconSet = config.iconSet ?? 'lucide'\n\n this.aside = document.createElement('aside')\n const variant = config.variant ?? 'app'\n this.aside.classList.add('sidebar', toSidebarVariantClassName(variant))\n this.aside.setAttribute('data-sidebar', variant)\n\n this.render()\n this.container.appendChild(this.aside)\n }\n\n private render(): void {\n if (this.config.collapsible === true) {\n this.renderCollapseButton()\n }\n\n this.renderHeader()\n\n const body = document.createElement('div')\n body.classList.add('sidebar__body')\n\n for (const section of this.config.sections) {\n const sectionEl = document.createElement('div')\n sectionEl.classList.add('sidebar__section')\n\n if (section.label) {\n const labelEl = document.createElement('div')\n labelEl.classList.add('sidebar__section-label')\n labelEl.textContent = section.label\n sectionEl.appendChild(labelEl)\n }\n\n for (const item of section.items) {\n const link = document.createElement('a')\n link.classList.add('sidebar__item')\n link.setAttribute('data-item-id', item.id)\n link.setAttribute('title', item.label)\n\n if (item.icon) {\n const icon = createIconSvg(this.iconSet, item.icon)\n link.appendChild(icon)\n }\n\n const label = document.createElement('span')\n label.classList.add('sidebar__item-label')\n label.textContent = item.label\n link.appendChild(label)\n\n if (item.badge !== undefined && item.badge > 0) {\n const badge = document.createElement('span')\n const tone = item.badgeTone ?? 'primary'\n link.setAttribute('data-badge-visible', 'true')\n link.setAttribute('data-badge-tone', tone)\n badge.classList.add('sidebar__badge', `sidebar__badge--${tone}`)\n badge.setAttribute('data-badge', item.id)\n badge.textContent = String(item.badge)\n link.appendChild(badge)\n }\n\n link.addEventListener('click', () => {\n if (this.config.onNavigate) {\n this.config.onNavigate(item)\n }\n if (item.onClick) {\n item.onClick()\n }\n })\n\n sectionEl.appendChild(link)\n }\n\n body.appendChild(sectionEl)\n }\n\n this.aside.appendChild(body)\n this.renderFooter()\n }\n\n private renderHeader(): void {\n const brand = this.config.brand\n if (brand === undefined) {\n return\n }\n\n const header = document.createElement('div')\n header.classList.add('sidebar__header')\n\n const row = document.createElement('div')\n row.classList.add('sidebar__header-row')\n\n const brandEl =\n brand.href !== undefined\n ? document.createElement('a')\n : brand.onClick !== undefined\n ? document.createElement('button')\n : document.createElement('span')\n\n brandEl.classList.add('sidebar__brand')\n\n if (brandEl instanceof HTMLAnchorElement) {\n brandEl.href = brand.href ?? '#'\n brandEl.setAttribute('aria-label', brand.label ?? 'CounterMeasure')\n }\n\n if (brandEl instanceof HTMLButtonElement) {\n brandEl.type = 'button'\n brandEl.setAttribute('aria-label', brand.label ?? 'CounterMeasure')\n }\n\n if (brand.onClick !== undefined) {\n brandEl.addEventListener('click', brand.onClick)\n }\n\n brandEl.appendChild(\n createBrandLockupElement({\n label: brand.label ?? 'CounterMeasure',\n markSize: brand.markSize ?? 22,\n showWordmark: brand.showWordmark ?? true,\n decorative: brand.decorative ?? false,\n })\n )\n\n row.appendChild(brandEl)\n header.appendChild(row)\n this.aside.appendChild(header)\n }\n\n private renderCollapseButton(): void {\n const button = document.createElement('button')\n button.type = 'button'\n button.classList.add('sidebar__collapse-btn', 'sidebar__collapse-btn--edge')\n button.setAttribute('data-sidebar-toggle', '')\n\n if (this.config.collapseButtonVisible === true) {\n button.setAttribute('data-visible', 'true')\n }\n\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n svg.setAttribute('aria-hidden', 'true')\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\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')\n svg.appendChild(path)\n button.appendChild(svg)\n\n button.addEventListener('click', () => {\n this.toggleCollapse()\n })\n\n this.collapseButton = button\n this.updateCollapseButton()\n this.aside.appendChild(button)\n }\n\n private renderFooter(): void {\n const hasUser = this.config.user !== undefined\n const hasActions =\n this.config.footerActions !== undefined && this.config.footerActions.length > 0\n\n if (!hasUser && !hasActions) {\n return\n }\n\n const footer = document.createElement('div')\n footer.classList.add('sidebar__footer')\n\n const footerBar = document.createElement('div')\n footerBar.classList.add('sidebar__footer-bar')\n\n if (hasUser && this.config.user) {\n const userSpan = document.createElement('span')\n userSpan.classList.add('sidebar__footer-user')\n\n const nameSpan = document.createElement('span')\n nameSpan.classList.add('sidebar__footer-name')\n nameSpan.textContent = this.config.user.name\n userSpan.appendChild(nameSpan)\n\n footerBar.appendChild(userSpan)\n }\n\n if (hasActions && this.config.footerActions) {\n const iconsSpan = document.createElement('span')\n iconsSpan.classList.add('sidebar__footer-icons')\n\n for (const action of this.config.footerActions) {\n const button = document.createElement('button')\n button.classList.add('sidebar__footer-icon')\n if (action.danger === true) {\n button.classList.add('sidebar__footer-icon--danger')\n }\n button.setAttribute('aria-label', action.label)\n\n const icon = createIconSvg(this.iconSet, action.icon)\n button.appendChild(icon)\n\n if (action.onClick) {\n const handler = action.onClick\n button.addEventListener('click', () => {\n handler()\n })\n }\n\n iconsSpan.appendChild(button)\n }\n\n footerBar.appendChild(iconsSpan)\n }\n\n footer.appendChild(footerBar)\n this.aside.appendChild(footer)\n }\n\n /** Mark a nav item as active, removing active state from all others. */\n setActive(itemId: string): void {\n this.aside.querySelectorAll<HTMLElement>('.sidebar__item').forEach(el => {\n el.classList.remove('sidebar__item--active')\n })\n\n const target = this.aside.querySelector<HTMLElement>(`[data-item-id=\"${itemId}\"]`)\n if (target) {\n target.classList.add('sidebar__item--active')\n }\n }\n\n /** Update the badge count for a nav item (empty string when count is 0). */\n updateBadge(itemId: string, count: number): void {\n const badge = this.aside.querySelector<HTMLElement>(`[data-badge=\"${itemId}\"]`)\n if (badge) {\n badge.textContent = count > 0 ? String(count) : ''\n const item = badge.closest<HTMLElement>('.sidebar__item')\n item?.setAttribute('data-badge-visible', String(count > 0))\n }\n }\n\n /** Toggle the sidebar between collapsed and expanded states. */\n toggleCollapse(): void {\n const isCollapsed = this.aside.classList.toggle('sidebar--collapsed')\n this.updateCollapseButton()\n if (this.config.onCollapse) {\n this.config.onCollapse(isCollapsed)\n }\n }\n\n /** Collapse the sidebar. */\n collapse(): void {\n const wasCollapsed = this.aside.classList.contains('sidebar--collapsed')\n this.aside.classList.add('sidebar--collapsed')\n this.updateCollapseButton()\n if (!wasCollapsed && this.config.onCollapse) {\n this.config.onCollapse(true)\n }\n }\n\n /** Expand the sidebar. */\n expand(): void {\n const wasCollapsed = this.aside.classList.contains('sidebar--collapsed')\n this.aside.classList.remove('sidebar--collapsed')\n this.updateCollapseButton()\n if (wasCollapsed && this.config.onCollapse) {\n this.config.onCollapse(false)\n }\n }\n\n /** Remove the sidebar from the DOM. */\n destroy(): void {\n this.aside.remove()\n }\n\n private updateCollapseButton(): void {\n if (this.collapseButton === null) {\n return\n }\n\n const isCollapsed = this.aside.classList.contains('sidebar--collapsed')\n const label = isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'\n this.collapseButton.setAttribute('aria-label', label)\n this.collapseButton.setAttribute('aria-expanded', String(!isCollapsed))\n this.collapseButton.setAttribute('title', label)\n this.collapseButton.setAttribute('data-collapsed', String(isCollapsed))\n this.collapseButton\n .querySelector('path')\n ?.setAttribute('d', isCollapsed ? 'm9 18 6-6-6-6' : 'm15 18-6-6 6-6')\n }\n}\n"],"mappings":"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"}