@ng-prism/core 22.0.1 → 22.1.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.
Files changed (31) hide show
  1. package/dist/app/controls/json-control.component.d.ts +2 -1
  2. package/dist/app/controls/json-control.component.d.ts.map +1 -1
  3. package/dist/app/controls/json-control.component.js +17 -11
  4. package/dist/app/panels/controls/non-editable-input-types.d.ts +3 -0
  5. package/dist/app/panels/controls/non-editable-input-types.d.ts.map +1 -0
  6. package/dist/app/panels/controls/non-editable-input-types.js +20 -0
  7. package/dist/app/panels/controls/prism-controls-panel.component.d.ts +1 -0
  8. package/dist/app/panels/controls/prism-controls-panel.component.d.ts.map +1 -1
  9. package/dist/app/panels/controls/prism-controls-panel.component.js +54 -33
  10. package/dist/app/renderer/known-inputs.d.ts +9 -0
  11. package/dist/app/renderer/known-inputs.d.ts.map +1 -0
  12. package/dist/app/renderer/known-inputs.js +13 -0
  13. package/dist/app/renderer/prism-renderer.component.d.ts.map +1 -1
  14. package/dist/app/renderer/prism-renderer.component.js +4 -3
  15. package/dist/app/renderer/snippet-generator.d.ts.map +1 -1
  16. package/dist/app/renderer/snippet-generator.js +12 -4
  17. package/dist/app/services/prism-navigation.service.d.ts +13 -2
  18. package/dist/app/services/prism-navigation.service.d.ts.map +1 -1
  19. package/dist/app/services/prism-navigation.service.js +79 -44
  20. package/dist/app/sidebar/prism-sidebar.component.d.ts +11 -3
  21. package/dist/app/sidebar/prism-sidebar.component.d.ts.map +1 -1
  22. package/dist/app/sidebar/prism-sidebar.component.js +101 -86
  23. package/dist/builder/manifest/host-parser.d.ts +1 -0
  24. package/dist/builder/manifest/host-parser.d.ts.map +1 -1
  25. package/dist/builder/manifest/host-parser.js +17 -6
  26. package/dist/builder/manifest/runtime-manifest.generator.d.ts.map +1 -1
  27. package/dist/builder/manifest/runtime-manifest.generator.js +3 -1
  28. package/dist/builder/scanner/component.scanner.js +5 -0
  29. package/dist/decorator/showcase.types.d.ts +12 -0
  30. package/dist/decorator/showcase.types.d.ts.map +1 -1
  31. package/package.json +1 -1
@@ -2,6 +2,30 @@ import { computed, inject, Injectable, signal } from '@angular/core';
2
2
  import { PrismManifestService } from './prism-manifest.service.js';
3
3
  import { PrismSearchService } from './prism-search.service.js';
4
4
  import * as i0 from "@angular/core";
5
+ const DEFAULT_SECTION_ORDER = {
6
+ Components: 0,
7
+ Directives: 10,
8
+ };
9
+ const SECTION_TIEBREAK = ['Components', 'Directives'];
10
+ export function resolveSection(c) {
11
+ if (c.showcaseConfig.section)
12
+ return c.showcaseConfig.section;
13
+ return c.componentMeta.isDirective ? 'Directives' : 'Components';
14
+ }
15
+ function defaultSectionOrder(name) {
16
+ return DEFAULT_SECTION_ORDER[name] ?? 100;
17
+ }
18
+ function sectionTiebreak(a, b) {
19
+ const ia = SECTION_TIEBREAK.indexOf(a);
20
+ const ib = SECTION_TIEBREAK.indexOf(b);
21
+ if (ia !== -1 && ib !== -1)
22
+ return ia - ib;
23
+ if (ia !== -1)
24
+ return -1;
25
+ if (ib !== -1)
26
+ return 1;
27
+ return a.localeCompare(b);
28
+ }
5
29
  export class PrismNavigationService {
6
30
  searchService = inject(PrismSearchService);
7
31
  manifestService = inject(PrismManifestService);
@@ -25,55 +49,66 @@ export class PrismNavigationService {
25
49
  return relinked ?? null;
26
50
  }, /* @ts-ignore */
27
51
  ...(ngDevMode ? [{ debugName: "activePage" }] : /* istanbul ignore next */ []));
28
- categoryTree = computed(() => {
29
- const map = new Map();
30
- for (const comp of this.searchService.filteredComponents()) {
31
- const cat = comp.meta.showcaseConfig.category ?? 'Uncategorized';
32
- const list = map.get(cat) ?? [];
33
- list.push({ kind: 'component', data: comp });
34
- map.set(cat, list);
35
- }
36
- for (const page of this.searchService.filteredPages()) {
37
- const cat = page.category ?? 'Uncategorized';
38
- const list = map.get(cat) ?? [];
39
- list.push({ kind: 'page', data: page });
40
- map.set(cat, list);
52
+ sectionTree = computed(() => {
53
+ const comps = this.searchService.filteredComponents();
54
+ const sections = new Map();
55
+ const sectionOrders = new Map();
56
+ for (const comp of comps) {
57
+ const section = resolveSection(comp.meta);
58
+ const category = comp.meta.showcaseConfig.category ?? 'Uncategorized';
59
+ const catMap = sections.get(section) ?? new Map();
60
+ const items = catMap.get(category) ?? [];
61
+ items.push({ kind: 'component', data: comp });
62
+ catMap.set(category, items);
63
+ sections.set(section, catMap);
64
+ const explicit = comp.meta.showcaseConfig.sectionOrder;
65
+ const current = sectionOrders.get(section);
66
+ if (explicit !== undefined) {
67
+ sectionOrders.set(section, current === undefined ? explicit : Math.min(current, explicit));
68
+ }
41
69
  }
42
- for (const items of map.values()) {
43
- items.sort((a, b) => {
44
- const orderA = a.kind === 'component'
45
- ? a.data.meta.showcaseConfig.componentOrder ?? Infinity
46
- : a.data.order ?? Infinity;
47
- const orderB = b.kind === 'component'
48
- ? b.data.meta.showcaseConfig.componentOrder ?? Infinity
49
- : b.data.order ?? Infinity;
50
- if (orderA !== orderB)
51
- return orderA - orderB;
52
- const labelA = a.kind === 'component'
53
- ? a.data.meta.showcaseConfig.title
54
- : a.data.title;
55
- const labelB = b.kind === 'component'
56
- ? b.data.meta.showcaseConfig.title
57
- : b.data.title;
58
- return labelA.localeCompare(labelB);
70
+ const result = [];
71
+ for (const [name, catMap] of sections.entries()) {
72
+ const order = sectionOrders.get(name) ?? defaultSectionOrder(name);
73
+ const categories = [];
74
+ for (const [catName, items] of catMap.entries()) {
75
+ items.sort((a, b) => {
76
+ const oa = a.kind === 'component'
77
+ ? a.data.meta.showcaseConfig.componentOrder ?? Infinity
78
+ : Infinity;
79
+ const ob = b.kind === 'component'
80
+ ? b.data.meta.showcaseConfig.componentOrder ?? Infinity
81
+ : Infinity;
82
+ if (oa !== ob)
83
+ return oa - ob;
84
+ const la = a.kind === 'component' ? a.data.meta.showcaseConfig.title : '';
85
+ const lb = b.kind === 'component' ? b.data.meta.showcaseConfig.title : '';
86
+ return la.localeCompare(lb);
87
+ });
88
+ categories.push({ name: catName, items });
89
+ }
90
+ categories.sort((a, b) => {
91
+ const oa = Math.min(...a.items.map((i) => i.kind === 'component'
92
+ ? i.data.meta.showcaseConfig.categoryOrder ?? Infinity
93
+ : Infinity));
94
+ const ob = Math.min(...b.items.map((i) => i.kind === 'component'
95
+ ? i.data.meta.showcaseConfig.categoryOrder ?? Infinity
96
+ : Infinity));
97
+ if (oa !== ob)
98
+ return oa - ob;
99
+ return a.name.localeCompare(b.name);
59
100
  });
101
+ const totalCount = categories.reduce((sum, c) => sum + c.items.length, 0);
102
+ result.push({ name, order, totalCount, categories });
60
103
  }
61
- const sorted = [...map.entries()].sort(([catA, itemsA], [catB, itemsB]) => {
62
- const catOrders = itemsA.map((i) => i.kind === 'component'
63
- ? i.data.meta.showcaseConfig.categoryOrder ?? Infinity
64
- : i.data.categoryOrder ?? Infinity);
65
- const orderA = Math.min(...catOrders);
66
- const catOrdersB = itemsB.map((i) => i.kind === 'component'
67
- ? i.data.meta.showcaseConfig.categoryOrder ?? Infinity
68
- : i.data.categoryOrder ?? Infinity);
69
- const orderB = Math.min(...catOrdersB);
70
- if (orderA !== orderB)
71
- return orderA - orderB;
72
- return catA.localeCompare(catB);
104
+ result.sort((a, b) => {
105
+ if (a.order !== b.order)
106
+ return a.order - b.order;
107
+ return sectionTiebreak(a.name, b.name);
73
108
  });
74
- return new Map(sorted);
109
+ return result;
75
110
  }, /* @ts-ignore */
76
- ...(ngDevMode ? [{ debugName: "categoryTree" }] : /* istanbul ignore next */ []));
111
+ ...(ngDevMode ? [{ debugName: "sectionTree" }] : /* istanbul ignore next */ []));
77
112
  select(comp) {
78
113
  this.activeItem.set({ kind: 'component', data: comp });
79
114
  }
@@ -11,14 +11,22 @@ interface SidebarCategory {
11
11
  export declare class PrismSidebarComponent {
12
12
  protected readonly navigationService: PrismNavigationService;
13
13
  protected readonly searchService: PrismSearchService;
14
- private readonly manifestService;
15
14
  private readonly filterInput;
16
15
  protected onGlobalKey(e: KeyboardEvent): void;
17
16
  private readonly collapsedSet;
18
17
  protected readonly totalPages: import("@angular/core").Signal<number>;
19
18
  protected readonly pageCategories: import("@angular/core").Signal<SidebarCategory[]>;
20
- protected readonly componentCategories: import("@angular/core").Signal<SidebarCategory[]>;
21
- protected readonly totalComponents: import("@angular/core").Signal<number>;
19
+ protected readonly componentSections: import("@angular/core").Signal<{
20
+ name: string;
21
+ icon: string;
22
+ color: string;
23
+ totalCount: number;
24
+ categories: {
25
+ name: string;
26
+ color: string;
27
+ items: NavigationItem[];
28
+ }[];
29
+ }[]>;
22
30
  protected isCollapsed(key: string): boolean;
23
31
  protected toggleCollapse(key: string): void;
24
32
  protected itemKey(item: NavigationItem): string;
@@ -1 +1 @@
1
- {"version":3,"file":"prism-sidebar.component.d.ts","sourceRoot":"","sources":["../../../src/app/sidebar/prism-sidebar.component.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;;AAuBzE,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,qBAkTa,qBAAqB;IAChC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,yBAAkC;IACtE,SAAS,CAAC,QAAQ,CAAC,aAAa,qBAA8B;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA0D;IAGtF,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI;IAQ7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6C;IAE1E,SAAS,CAAC,QAAQ,CAAC,UAAU,yCAE1B;IAEH,SAAS,CAAC,QAAQ,CAAC,cAAc,oDAc9B;IAEH,SAAS,CAAC,QAAQ,CAAC,mBAAmB,oDAanC;IAEH,SAAS,CAAC,QAAQ,CAAC,eAAe,yCAEhC;IAEF,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI3C,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAU3C,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAM/C,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAMjD,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,SAAS;IAMvE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAO1D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IAWjD,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQ9C,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;yCA3HV,qBAAqB;2CAArB,qBAAqB;CAgIjC"}
1
+ {"version":3,"file":"prism-sidebar.component.d.ts","sourceRoot":"","sources":["../../../src/app/sidebar/prism-sidebar.component.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;;AAiCzE,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,qBA0Ta,qBAAqB;IAChC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,yBAAkC;IACtE,SAAS,CAAC,QAAQ,CAAC,aAAa,qBAA8B;IAC9D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAC6B;IAGzD,SAAS,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI;IAa7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6C;IAE1E,SAAS,CAAC,QAAQ,CAAC,UAAU,yCAE1B;IAEH,SAAS,CAAC,QAAQ,CAAC,cAAc,oDAc9B;IAEH,SAAS,CAAC,QAAQ,CAAC,iBAAiB;;;;;;;;;;SAYjC;IAEH,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI3C,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAU3C,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAM/C,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM;IAMjD,SAAS,CAAC,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,GAAG,SAAS;IAMvE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;IAO1D,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IAWjD,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAQ9C,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;yCA3HV,qBAAqB;2CAArB,qBAAqB;CAgIjC"}
@@ -2,7 +2,6 @@ import { Component, computed, inject, signal, viewChild, HostListener, ChangeDet
2
2
  import { PrismIconComponent } from '../icons/prism-icon.component.js';
3
3
  import { PrismNavigationService } from '../services/prism-navigation.service.js';
4
4
  import { PrismSearchService } from '../services/prism-search.service.js';
5
- import { PrismManifestService } from '../services/prism-manifest.service.js';
6
5
  import * as i0 from "@angular/core";
7
6
  const _c0 = ["filterInput"];
8
7
  const _forTrack0 = ($index, $item) => $item.name;
@@ -10,9 +9,9 @@ function _forTrack1($index, $item) { /* @ts-ignore */
10
9
  return this.itemKey($item); }
11
10
  function PrismSidebarComponent_Conditional_8_For_8_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
12
11
  const _r4 = i0.ɵɵgetCurrentView();
13
- i0.ɵɵelementStart(0, "button", 18);
12
+ i0.ɵɵelementStart(0, "button", 17);
14
13
  i0.ɵɵlistener("click", function PrismSidebarComponent_Conditional_8_For_8_Conditional_5_For_2_Template_button_click_0_listener() { const item_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onSelect(item_r5)); });
15
- i0.ɵɵelementStart(1, "span", 19);
14
+ i0.ɵɵelementStart(1, "span", 18);
16
15
  i0.ɵɵtext(2);
17
16
  i0.ɵɵelementEnd()();
18
17
  } if (rf & 2) {
@@ -23,8 +22,8 @@ function PrismSidebarComponent_Conditional_8_For_8_Conditional_5_For_2_Template(
23
22
  i0.ɵɵtextInterpolate(ctx_r2.itemLabel(item_r5));
24
23
  } }
25
24
  function PrismSidebarComponent_Conditional_8_For_8_Conditional_5_Template(rf, ctx) { if (rf & 1) {
26
- i0.ɵɵelementStart(0, "div", 16);
27
- i0.ɵɵrepeaterCreate(1, PrismSidebarComponent_Conditional_8_For_8_Conditional_5_For_2_Template, 3, 3, "button", 17, _forTrack1, true);
25
+ i0.ɵɵelementStart(0, "div", 15);
26
+ i0.ɵɵrepeaterCreate(1, PrismSidebarComponent_Conditional_8_For_8_Conditional_5_For_2_Template, 3, 3, "button", 16, _forTrack1, true);
28
27
  i0.ɵɵelementEnd();
29
28
  } if (rf & 2) {
30
29
  const cat_r2 = i0.ɵɵnextContext().$implicit;
@@ -33,12 +32,12 @@ function PrismSidebarComponent_Conditional_8_For_8_Conditional_5_Template(rf, ct
33
32
  } }
34
33
  function PrismSidebarComponent_Conditional_8_For_8_Template(rf, ctx) { if (rf & 1) {
35
34
  const _r1 = i0.ɵɵgetCurrentView();
36
- i0.ɵɵelementStart(0, "div", 12)(1, "button", 13);
35
+ i0.ɵɵelementStart(0, "div", 11)(1, "button", 12);
37
36
  i0.ɵɵlistener("click", function PrismSidebarComponent_Conditional_8_For_8_Template_button_click_1_listener() { const cat_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleCollapse("page:" + cat_r2.name)); });
38
- i0.ɵɵelement(2, "prism-icon", 14)(3, "span", 15);
37
+ i0.ɵɵelement(2, "prism-icon", 13)(3, "span", 14);
39
38
  i0.ɵɵtext(4);
40
39
  i0.ɵɵelementEnd();
41
- i0.ɵɵconditionalCreate(5, PrismSidebarComponent_Conditional_8_For_8_Conditional_5_Template, 3, 0, "div", 16);
40
+ i0.ɵɵconditionalCreate(5, PrismSidebarComponent_Conditional_8_For_8_Conditional_5_Template, 3, 0, "div", 15);
42
41
  i0.ɵɵelementEnd();
43
42
  } if (rf & 2) {
44
43
  const cat_r2 = ctx.$implicit;
@@ -56,14 +55,14 @@ function PrismSidebarComponent_Conditional_8_For_8_Template(rf, ctx) { if (rf &
56
55
  i0.ɵɵconditional(!ctx_r2.isCollapsed("page:" + cat_r2.name) ? 5 : -1);
57
56
  } }
58
57
  function PrismSidebarComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
59
- i0.ɵɵelementStart(0, "div", 6)(1, "div", 9)(2, "span", 10);
60
- i0.ɵɵelement(3, "prism-icon", 11);
58
+ i0.ɵɵelementStart(0, "div", 6)(1, "div", 7)(2, "span", 8);
59
+ i0.ɵɵelement(3, "prism-icon", 9);
61
60
  i0.ɵɵtext(4, " Pages ");
62
61
  i0.ɵɵelementEnd();
63
62
  i0.ɵɵelementStart(5, "span");
64
63
  i0.ɵɵtext(6);
65
64
  i0.ɵɵelementEnd()();
66
- i0.ɵɵrepeaterCreate(7, PrismSidebarComponent_Conditional_8_For_8_Template, 6, 8, "div", 8, _forTrack0);
65
+ i0.ɵɵrepeaterCreate(7, PrismSidebarComponent_Conditional_8_For_8_Template, 6, 8, "div", 10, _forTrack0);
67
66
  i0.ɵɵelementEnd();
68
67
  } if (rf & 2) {
69
68
  const ctx_r2 = i0.ɵɵnextContext();
@@ -74,74 +73,60 @@ function PrismSidebarComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
74
73
  i0.ɵɵadvance();
75
74
  i0.ɵɵrepeater(ctx_r2.pageCategories());
76
75
  } }
77
- function PrismSidebarComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
78
- i0.ɵɵelementStart(0, "div", 7)(1, "span", 20);
79
- i0.ɵɵelement(2, "prism-icon", 21);
80
- i0.ɵɵtext(3, " Components ");
81
- i0.ɵɵelementEnd();
82
- i0.ɵɵelementStart(4, "span");
83
- i0.ɵɵtext(5);
84
- i0.ɵɵelementEnd()();
85
- } if (rf & 2) {
86
- const ctx_r2 = i0.ɵɵnextContext();
87
- i0.ɵɵadvance(2);
88
- i0.ɵɵproperty("size", 10);
89
- i0.ɵɵadvance(3);
90
- i0.ɵɵtextInterpolate(ctx_r2.totalComponents());
91
- } }
92
- function PrismSidebarComponent_For_11_Conditional_7_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
76
+ function PrismSidebarComponent_For_10_For_7_Conditional_7_For_2_Conditional_4_Template(rf, ctx) { if (rf & 1) {
93
77
  i0.ɵɵelementStart(0, "span", 25);
94
78
  i0.ɵɵelement(1, "span", 26);
95
79
  i0.ɵɵelementEnd();
96
80
  } }
97
- function PrismSidebarComponent_For_11_Conditional_7_For_2_Template(rf, ctx) { if (rf & 1) {
98
- const _r8 = i0.ɵɵgetCurrentView();
99
- i0.ɵɵelementStart(0, "button", 18);
100
- i0.ɵɵlistener("click", function PrismSidebarComponent_For_11_Conditional_7_For_2_Template_button_click_0_listener() { const item_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onSelect(item_r9)); });
81
+ function PrismSidebarComponent_For_10_For_7_Conditional_7_For_2_Template(rf, ctx) { if (rf & 1) {
82
+ const _r9 = i0.ɵɵgetCurrentView();
83
+ i0.ɵɵelementStart(0, "button", 17);
84
+ i0.ɵɵlistener("click", function PrismSidebarComponent_For_10_For_7_Conditional_7_For_2_Template_button_click_0_listener() { const item_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.onSelect(item_r10)); });
101
85
  i0.ɵɵelement(1, "prism-icon", 24);
102
- i0.ɵɵelementStart(2, "span", 19);
86
+ i0.ɵɵelementStart(2, "span", 18);
103
87
  i0.ɵɵtext(3);
104
88
  i0.ɵɵelementEnd();
105
- i0.ɵɵconditionalCreate(4, PrismSidebarComponent_For_11_Conditional_7_For_2_Conditional_4_Template, 2, 0, "span", 25);
89
+ i0.ɵɵconditionalCreate(4, PrismSidebarComponent_For_10_For_7_Conditional_7_For_2_Conditional_4_Template, 2, 0, "span", 25);
106
90
  i0.ɵɵelementEnd();
107
91
  } if (rf & 2) {
108
- const item_r9 = ctx.$implicit;
109
- const ctx_r2 = i0.ɵɵnextContext(3);
110
- i0.ɵɵclassProp("sb-item--active", ctx_r2.isActive(item_r9))("sb-item--deprecated", ctx_r2.itemStatus(item_r9) === "deprecated");
111
- i0.ɵɵattribute("title", ctx_r2.itemTooltip(item_r9));
92
+ const item_r10 = ctx.$implicit;
93
+ const ctx_r2 = i0.ɵɵnextContext(4);
94
+ i0.ɵɵclassProp("sb-item--active", ctx_r2.isActive(item_r10))("sb-item--deprecated", ctx_r2.itemStatus(item_r10) === "deprecated");
95
+ i0.ɵɵattribute("title", ctx_r2.itemTooltip(item_r10));
112
96
  i0.ɵɵadvance();
113
97
  i0.ɵɵproperty("size", 12);
114
98
  i0.ɵɵadvance(2);
115
- i0.ɵɵtextInterpolate(ctx_r2.itemLabel(item_r9));
99
+ i0.ɵɵtextInterpolate(ctx_r2.itemLabel(item_r10));
116
100
  i0.ɵɵadvance();
117
- i0.ɵɵconditional(ctx_r2.itemStatus(item_r9) === "wip" ? 4 : -1);
101
+ i0.ɵɵconditional(ctx_r2.itemStatus(item_r10) === "wip" ? 4 : -1);
118
102
  } }
119
- function PrismSidebarComponent_For_11_Conditional_7_Template(rf, ctx) { if (rf & 1) {
120
- i0.ɵɵelementStart(0, "div", 16);
121
- i0.ɵɵrepeaterCreate(1, PrismSidebarComponent_For_11_Conditional_7_For_2_Template, 5, 8, "button", 23, _forTrack1, true);
103
+ function PrismSidebarComponent_For_10_For_7_Conditional_7_Template(rf, ctx) { if (rf & 1) {
104
+ i0.ɵɵelementStart(0, "div", 15);
105
+ i0.ɵɵrepeaterCreate(1, PrismSidebarComponent_For_10_For_7_Conditional_7_For_2_Template, 5, 8, "button", 23, _forTrack1, true);
122
106
  i0.ɵɵelementEnd();
123
107
  } if (rf & 2) {
124
108
  const cat_r7 = i0.ɵɵnextContext().$implicit;
125
109
  i0.ɵɵadvance();
126
110
  i0.ɵɵrepeater(cat_r7.items);
127
111
  } }
128
- function PrismSidebarComponent_For_11_Template(rf, ctx) { if (rf & 1) {
112
+ function PrismSidebarComponent_For_10_For_7_Template(rf, ctx) { if (rf & 1) {
129
113
  const _r6 = i0.ɵɵgetCurrentView();
130
- i0.ɵɵelementStart(0, "div", 12)(1, "button", 13);
131
- i0.ɵɵlistener("click", function PrismSidebarComponent_For_11_Template_button_click_1_listener() { const cat_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleCollapse("comp:" + cat_r7.name)); });
132
- i0.ɵɵelement(2, "prism-icon", 14)(3, "span", 15);
114
+ i0.ɵɵelementStart(0, "div", 11)(1, "button", 12);
115
+ i0.ɵɵlistener("click", function PrismSidebarComponent_For_10_For_7_Template_button_click_1_listener() { const cat_r7 = i0.ɵɵrestoreView(_r6).$implicit; const section_r8 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.toggleCollapse("sec:" + section_r8.name + ":" + cat_r7.name)); });
116
+ i0.ɵɵelement(2, "prism-icon", 13)(3, "span", 14);
133
117
  i0.ɵɵtext(4);
134
118
  i0.ɵɵelementStart(5, "span", 22);
135
119
  i0.ɵɵtext(6);
136
120
  i0.ɵɵelementEnd()();
137
- i0.ɵɵconditionalCreate(7, PrismSidebarComponent_For_11_Conditional_7_Template, 3, 0, "div", 16);
121
+ i0.ɵɵconditionalCreate(7, PrismSidebarComponent_For_10_For_7_Conditional_7_Template, 3, 0, "div", 15);
138
122
  i0.ɵɵelementEnd();
139
123
  } if (rf & 2) {
140
124
  const cat_r7 = ctx.$implicit;
125
+ const section_r8 = i0.ɵɵnextContext().$implicit;
141
126
  const ctx_r2 = i0.ɵɵnextContext();
142
- i0.ɵɵclassProp("sb-group--collapsed", ctx_r2.isCollapsed("comp:" + cat_r7.name));
127
+ i0.ɵɵclassProp("sb-group--collapsed", ctx_r2.isCollapsed("sec:" + section_r8.name + ":" + cat_r7.name));
143
128
  i0.ɵɵadvance();
144
- i0.ɵɵattribute("aria-expanded", !ctx_r2.isCollapsed("comp:" + cat_r7.name));
129
+ i0.ɵɵattribute("aria-expanded", !ctx_r2.isCollapsed("sec:" + section_r8.name + ":" + cat_r7.name));
145
130
  i0.ɵɵadvance();
146
131
  i0.ɵɵproperty("size", 10);
147
132
  i0.ɵɵadvance();
@@ -151,7 +136,27 @@ function PrismSidebarComponent_For_11_Template(rf, ctx) { if (rf & 1) {
151
136
  i0.ɵɵadvance(2);
152
137
  i0.ɵɵtextInterpolate(cat_r7.items.length);
153
138
  i0.ɵɵadvance();
154
- i0.ɵɵconditional(!ctx_r2.isCollapsed("comp:" + cat_r7.name) ? 7 : -1);
139
+ i0.ɵɵconditional(!ctx_r2.isCollapsed("sec:" + section_r8.name + ":" + cat_r7.name) ? 7 : -1);
140
+ } }
141
+ function PrismSidebarComponent_For_10_Template(rf, ctx) { if (rf & 1) {
142
+ i0.ɵɵelementStart(0, "div", 19)(1, "span", 20);
143
+ i0.ɵɵelement(2, "prism-icon", 21);
144
+ i0.ɵɵtext(3);
145
+ i0.ɵɵelementEnd();
146
+ i0.ɵɵelementStart(4, "span");
147
+ i0.ɵɵtext(5);
148
+ i0.ɵɵelementEnd()();
149
+ i0.ɵɵrepeaterCreate(6, PrismSidebarComponent_For_10_For_7_Template, 8, 9, "div", 10, _forTrack0);
150
+ } if (rf & 2) {
151
+ const section_r8 = ctx.$implicit;
152
+ i0.ɵɵadvance(2);
153
+ i0.ɵɵproperty("name", section_r8.icon)("size", 10);
154
+ i0.ɵɵadvance();
155
+ i0.ɵɵtextInterpolate1(" ", section_r8.name, " ");
156
+ i0.ɵɵadvance(2);
157
+ i0.ɵɵtextInterpolate(section_r8.totalCount);
158
+ i0.ɵɵadvance();
159
+ i0.ɵɵrepeater(section_r8.categories);
155
160
  } }
156
161
  const STORAGE_KEY = 'ng-prism-sidebar-collapsed';
157
162
  const CATEGORY_COLORS = {
@@ -163,6 +168,14 @@ const CATEGORY_COLORS = {
163
168
  Overlay: '#c084fc',
164
169
  Directives: '#ec4899',
165
170
  };
171
+ const SECTION_ICONS = {
172
+ Components: 'box',
173
+ Directives: 'zap',
174
+ };
175
+ const DEFAULT_SECTION_ICON = 'box-select';
176
+ function sectionIcon(name) {
177
+ return SECTION_ICONS[name] ?? DEFAULT_SECTION_ICON;
178
+ }
166
179
  function categoryColor(name) {
167
180
  if (CATEGORY_COLORS[name])
168
181
  return CATEGORY_COLORS[name];
@@ -175,14 +188,15 @@ function categoryColor(name) {
175
188
  export class PrismSidebarComponent {
176
189
  navigationService = inject(PrismNavigationService);
177
190
  searchService = inject(PrismSearchService);
178
- manifestService = inject(PrismManifestService);
179
191
  filterInput = viewChild('filterInput', /* @ts-ignore */
180
192
  ...(ngDevMode ? [{ debugName: "filterInput" }] : /* istanbul ignore next */ []));
181
193
  onGlobalKey(e) {
182
194
  if (e.key !== '/' || e.ctrlKey || e.metaKey || e.altKey)
183
195
  return;
184
196
  const tag = e.target.tagName;
185
- if (tag === 'INPUT' || tag === 'TEXTAREA' || e.target.isContentEditable)
197
+ if (tag === 'INPUT' ||
198
+ tag === 'TEXTAREA' ||
199
+ e.target.isContentEditable)
186
200
  return;
187
201
  e.preventDefault();
188
202
  this.filterInput()?.nativeElement.focus();
@@ -209,24 +223,20 @@ export class PrismSidebarComponent {
209
223
  }));
210
224
  }, /* @ts-ignore */
211
225
  ...(ngDevMode ? [{ debugName: "pageCategories" }] : /* istanbul ignore next */ []));
212
- componentCategories = computed(() => {
213
- const tree = this.navigationService.categoryTree();
214
- const result = [];
215
- for (const [catName, items] of tree.entries()) {
216
- const compItems = items.filter((i) => i.kind === 'component');
217
- if (compItems.length === 0)
218
- continue;
219
- result.push({
220
- name: catName,
221
- color: categoryColor(catName),
222
- items: compItems,
223
- });
224
- }
225
- return result;
226
+ componentSections = computed(() => {
227
+ return this.navigationService.sectionTree().map((section) => ({
228
+ name: section.name,
229
+ icon: sectionIcon(section.name),
230
+ color: categoryColor(section.name),
231
+ totalCount: section.totalCount,
232
+ categories: section.categories.map((cat) => ({
233
+ name: cat.name,
234
+ color: categoryColor(cat.name),
235
+ items: cat.items,
236
+ })),
237
+ }));
226
238
  }, /* @ts-ignore */
227
- ...(ngDevMode ? [{ debugName: "componentCategories" }] : /* istanbul ignore next */ []));
228
- totalComponents = computed(() => this.manifestService.manifest().components.length, /* @ts-ignore */
229
- ...(ngDevMode ? [{ debugName: "totalComponents" }] : /* istanbul ignore next */ []));
239
+ ...(ngDevMode ? [{ debugName: "componentSections" }] : /* istanbul ignore next */ []));
230
240
  isCollapsed(key) {
231
241
  return this.collapsedSet().has(key);
232
242
  }
@@ -303,7 +313,7 @@ export class PrismSidebarComponent {
303
313
  i0.ɵɵqueryAdvance();
304
314
  } }, hostBindings: function PrismSidebarComponent_HostBindings(rf, ctx) { if (rf & 1) {
305
315
  i0.ɵɵlistener("keydown", function PrismSidebarComponent_keydown_HostBindingHandler($event) { return ctx.onGlobalKey($event); }, i0.ɵɵresolveDocument);
306
- } }, decls: 12, vars: 4, consts: [["filterInput", ""], [1, "prism-sidebar"], [1, "sb-filter"], ["name", "search", 3, "size"], ["placeholder", "Filter components\u2026", 3, "input", "value"], [1, "sb-scroll"], [1, "sb-pinned"], [1, "sb-section-head"], [1, "sb-group", 3, "sb-group--collapsed"], [1, "sb-pinned-head"], [1, "sb-pinned-head-l"], ["name", "pin", 1, "sb-pinned-pin", 3, "size"], [1, "sb-group"], [1, "sb-group-head", 3, "click"], ["name", "chevron-down", 3, "size"], [1, "sb-group-chip"], [1, "sb-group-body"], [1, "sb-item", 3, "sb-item--active"], [1, "sb-item", 3, "click"], [1, "sb-item-name"], [1, "sb-section-head-l"], ["name", "box", 1, "sb-section-icon", 3, "size"], [1, "sb-group-count"], [1, "sb-item", 3, "sb-item--active", "sb-item--deprecated"], ["name", "box", 1, "sb-item-icon", 3, "size"], ["title", "Work in progress", 1, "sb-item-status"], [1, "sb-item-status-dot"]], template: function PrismSidebarComponent_Template(rf, ctx) { if (rf & 1) {
316
+ } }, decls: 11, vars: 3, consts: [["filterInput", ""], [1, "prism-sidebar"], [1, "sb-filter"], ["name", "search", 3, "size"], ["placeholder", "Filter components\u2026", 3, "input", "value"], [1, "sb-scroll"], [1, "sb-pinned"], [1, "sb-pinned-head"], [1, "sb-pinned-head-l"], ["name", "pin", 1, "sb-pinned-pin", 3, "size"], [1, "sb-group", 3, "sb-group--collapsed"], [1, "sb-group"], [1, "sb-group-head", 3, "click"], ["name", "chevron-down", 3, "size"], [1, "sb-group-chip"], [1, "sb-group-body"], [1, "sb-item", 3, "sb-item--active"], [1, "sb-item", 3, "click"], [1, "sb-item-name"], [1, "sb-section-head"], [1, "sb-section-head-l"], [1, "sb-section-icon", 3, "name", "size"], [1, "sb-group-count"], [1, "sb-item", 3, "sb-item--active", "sb-item--deprecated"], ["name", "box", 1, "sb-item-icon", 3, "size"], ["title", "Work in progress", 1, "sb-item-status"], [1, "sb-item-status-dot"]], template: function PrismSidebarComponent_Template(rf, ctx) { if (rf & 1) {
307
317
  i0.ɵɵelementStart(0, "nav", 1)(1, "div", 2);
308
318
  i0.ɵɵelement(2, "prism-icon", 3);
309
319
  i0.ɵɵelementStart(3, "input", 4, 0);
@@ -314,8 +324,7 @@ export class PrismSidebarComponent {
314
324
  i0.ɵɵelementEnd()();
315
325
  i0.ɵɵelementStart(7, "div", 5);
316
326
  i0.ɵɵconditionalCreate(8, PrismSidebarComponent_Conditional_8_Template, 9, 2, "div", 6);
317
- i0.ɵɵconditionalCreate(9, PrismSidebarComponent_Conditional_9_Template, 6, 2, "div", 7);
318
- i0.ɵɵrepeaterCreate(10, PrismSidebarComponent_For_11_Template, 8, 9, "div", 8, _forTrack0);
327
+ i0.ɵɵrepeaterCreate(9, PrismSidebarComponent_For_10_Template, 8, 4, null, null, _forTrack0);
319
328
  i0.ɵɵelementEnd()();
320
329
  } if (rf & 2) {
321
330
  i0.ɵɵadvance(2);
@@ -325,9 +334,7 @@ export class PrismSidebarComponent {
325
334
  i0.ɵɵadvance(5);
326
335
  i0.ɵɵconditional(ctx.pageCategories().length > 0 ? 8 : -1);
327
336
  i0.ɵɵadvance();
328
- i0.ɵɵconditional(ctx.componentCategories().length > 0 ? 9 : -1);
329
- i0.ɵɵadvance();
330
- i0.ɵɵrepeater(ctx.componentCategories());
337
+ i0.ɵɵrepeater(ctx.componentSections());
331
338
  } }, dependencies: [PrismIconComponent], styles: [".prism-sidebar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n }\n\n .sb-filter[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 12px;\n padding: 0 10px;\n height: 30px;\n background: var(--prism-input-bg);\n border: 1px solid var(--prism-border);\n border-radius: 6px;\n color: var(--prism-text-muted);\n }\n .sb-filter[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n background: transparent;\n border: 0;\n outline: none;\n font-size: var(--fs-md);\n color: var(--prism-text);\n font-family: var(--font-sans);\n }\n .sb-filter[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder { color: var(--prism-text-muted); }\n .sb-filter[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n font-family: var(--font-mono);\n font-size: 10px;\n color: var(--prism-text-ghost);\n padding: 1px 5px;\n border: 1px solid var(--prism-border);\n border-radius: 3px;\n }\n\n .sb-scroll[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 10px 0 16px;\n padding-top: 0;\n }\n .sb-scroll[_ngcontent-%COMP%]::-webkit-scrollbar { width: 8px; }\n .sb-scroll[_ngcontent-%COMP%]::-webkit-scrollbar-thumb { background: var(--prism-border-strong); border-radius: 4px; }\n .sb-scroll[_ngcontent-%COMP%]::-webkit-scrollbar-track { background: transparent; }\n\n .sb-pinned[_ngcontent-%COMP%] {\n padding: 0 0 10px;\n margin-bottom: 4px;\n border-bottom: 1px solid var(--prism-border);\n border-top: 1px solid var(--prism-border);\n }\n .sb-section-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px 6px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n color: var(--prism-text-ghost);\n margin-top: 6px;\n }\n .sb-section-head-l[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 6px; }\n .sb-section-icon[_ngcontent-%COMP%] { color: var(--prism-primary); }\n .sb-pinned-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px 6px;\n margin-top: 6px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n color: var(--prism-text-ghost);\n }\n .sb-pinned-head-l[_ngcontent-%COMP%] { display: flex; align-items: center; gap: 6px; }\n .sb-pinned-pin[_ngcontent-%COMP%] { color: var(--prism-accent); }\n\n .sb-group[_ngcontent-%COMP%] { margin-bottom: 4px; }\n .sb-group-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 8px 14px 6px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n color: var(--prism-text-ghost);\n cursor: pointer;\n user-select: none;\n background: none;\n border: none;\n text-align: left;\n font-family: var(--font-sans);\n }\n .sb-group-head[_ngcontent-%COMP%] prism-icon[_ngcontent-%COMP%] {\n transition: transform var(--dur-fast);\n color: var(--prism-text-ghost);\n }\n .sb-group--collapsed[_ngcontent-%COMP%] .sb-group-head[_ngcontent-%COMP%] prism-icon[_ngcontent-%COMP%] { transform: rotate(-90deg); }\n\n .sb-group-chip[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: 2px;\n background: var(--chip, var(--prism-primary));\n box-shadow: 0 0 6px var(--chip, var(--prism-primary));\n }\n .sb-group-count[_ngcontent-%COMP%] {\n margin-left: auto;\n font-family: var(--font-mono);\n font-size: 10px;\n color: var(--prism-text-ghost);\n font-weight: 500;\n }\n\n .sb-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n height: 30px;\n padding: 0 14px 0 28px;\n font-size: 13px;\n color: var(--prism-text-2);\n cursor: pointer;\n border: none;\n border-left: 2px solid transparent;\n background: none;\n position: relative;\n transition: background var(--dur-fast), color var(--dur-fast);\n text-align: left;\n font-family: var(--font-sans);\n }\n .sb-item[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--prism-primary) 5%, transparent);\n color: var(--prism-text);\n }\n .sb-item--active[_ngcontent-%COMP%] {\n border-left-color: var(--prism-primary);\n background: color-mix(in srgb, var(--prism-primary) 12%, transparent);\n color: var(--prism-text);\n font-weight: 500;\n }\n .sb-item--active[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n left: -1px;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(180deg, var(--prism-primary-from), var(--prism-primary-to));\n }\n .sb-item-icon[_ngcontent-%COMP%] { flex: 0 0 12px; opacity: 0.7; }\n .sb-item-name[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .sb-item-status[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n margin-left: auto;\n display: flex;\n align-items: center;\n }\n .sb-item-status-dot[_ngcontent-%COMP%] {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--prism-warn);\n }\n\n .sb-item--deprecated[_ngcontent-%COMP%] .sb-item-name[_ngcontent-%COMP%] {\n text-decoration: line-through;\n text-decoration-thickness: 1px;\n color: var(--prism-text-ghost);\n opacity: 0.7;\n }\n\n\n [_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n }"] });
332
339
  }
333
340
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismSidebarComponent, [{
@@ -385,30 +392,38 @@ export class PrismSidebarComponent {
385
392
  </div>
386
393
  }
387
394
  </div>
388
- } @if (componentCategories().length > 0) {
395
+ } @for (section of componentSections(); track section.name) {
389
396
  <div class="sb-section-head">
390
397
  <span class="sb-section-head-l">
391
- <prism-icon name="box" [size]="10" class="sb-section-icon" />
392
- Components
398
+ <prism-icon
399
+ [name]="section.icon"
400
+ [size]="10"
401
+ class="sb-section-icon"
402
+ />
403
+ {{ section.name }}
393
404
  </span>
394
- <span>{{ totalComponents() }}</span>
405
+ <span>{{ section.totalCount }}</span>
395
406
  </div>
396
- } @for (cat of componentCategories(); track cat.name) {
407
+ @for (cat of section.categories; track cat.name) {
397
408
  <div
398
409
  class="sb-group"
399
- [class.sb-group--collapsed]="isCollapsed('comp:' + cat.name)"
410
+ [class.sb-group--collapsed]="
411
+ isCollapsed('sec:' + section.name + ':' + cat.name)
412
+ "
400
413
  >
401
414
  <button
402
415
  class="sb-group-head"
403
- (click)="toggleCollapse('comp:' + cat.name)"
404
- [attr.aria-expanded]="!isCollapsed('comp:' + cat.name)"
416
+ (click)="toggleCollapse('sec:' + section.name + ':' + cat.name)"
417
+ [attr.aria-expanded]="
418
+ !isCollapsed('sec:' + section.name + ':' + cat.name)
419
+ "
405
420
  >
406
421
  <prism-icon name="chevron-down" [size]="10" />
407
422
  <span class="sb-group-chip" [style.--chip]="cat.color"></span>
408
423
  {{ cat.name }}
409
424
  <span class="sb-group-count">{{ cat.items.length }}</span>
410
425
  </button>
411
- @if (!isCollapsed('comp:' + cat.name)) {
426
+ @if (!isCollapsed('sec:' + section.name + ':' + cat.name)) {
412
427
  <div class="sb-group-body">
413
428
  @for (item of cat.items; track itemKey(item)) {
414
429
  <button
@@ -430,7 +445,7 @@ export class PrismSidebarComponent {
430
445
  </div>
431
446
  }
432
447
  </div>
433
- }
448
+ } }
434
449
  </div>
435
450
  </nav>
436
451
  `, styles: ["\n .prism-sidebar {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n }\n\n .sb-filter {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 12px;\n padding: 0 10px;\n height: 30px;\n background: var(--prism-input-bg);\n border: 1px solid var(--prism-border);\n border-radius: 6px;\n color: var(--prism-text-muted);\n }\n .sb-filter input {\n flex: 1;\n min-width: 0;\n background: transparent;\n border: 0;\n outline: none;\n font-size: var(--fs-md);\n color: var(--prism-text);\n font-family: var(--font-sans);\n }\n .sb-filter input::placeholder { color: var(--prism-text-muted); }\n .sb-filter kbd {\n font-family: var(--font-mono);\n font-size: 10px;\n color: var(--prism-text-ghost);\n padding: 1px 5px;\n border: 1px solid var(--prism-border);\n border-radius: 3px;\n }\n\n .sb-scroll {\n flex: 1;\n overflow-y: auto;\n padding: 10px 0 16px;\n padding-top: 0;\n }\n .sb-scroll::-webkit-scrollbar { width: 8px; }\n .sb-scroll::-webkit-scrollbar-thumb { background: var(--prism-border-strong); border-radius: 4px; }\n .sb-scroll::-webkit-scrollbar-track { background: transparent; }\n\n .sb-pinned {\n padding: 0 0 10px;\n margin-bottom: 4px;\n border-bottom: 1px solid var(--prism-border);\n border-top: 1px solid var(--prism-border);\n }\n .sb-section-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px 6px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n color: var(--prism-text-ghost);\n margin-top: 6px;\n }\n .sb-section-head-l { display: flex; align-items: center; gap: 6px; }\n .sb-section-icon { color: var(--prism-primary); }\n .sb-pinned-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px 6px;\n margin-top: 6px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n color: var(--prism-text-ghost);\n }\n .sb-pinned-head-l { display: flex; align-items: center; gap: 6px; }\n .sb-pinned-pin { color: var(--prism-accent); }\n\n .sb-group { margin-bottom: 4px; }\n .sb-group-head {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 8px 14px 6px;\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: 0.09em;\n text-transform: uppercase;\n color: var(--prism-text-ghost);\n cursor: pointer;\n user-select: none;\n background: none;\n border: none;\n text-align: left;\n font-family: var(--font-sans);\n }\n .sb-group-head prism-icon {\n transition: transform var(--dur-fast);\n color: var(--prism-text-ghost);\n }\n .sb-group--collapsed .sb-group-head prism-icon { transform: rotate(-90deg); }\n\n .sb-group-chip {\n width: 6px;\n height: 6px;\n border-radius: 2px;\n background: var(--chip, var(--prism-primary));\n box-shadow: 0 0 6px var(--chip, var(--prism-primary));\n }\n .sb-group-count {\n margin-left: auto;\n font-family: var(--font-mono);\n font-size: 10px;\n color: var(--prism-text-ghost);\n font-weight: 500;\n }\n\n .sb-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n height: 30px;\n padding: 0 14px 0 28px;\n font-size: 13px;\n color: var(--prism-text-2);\n cursor: pointer;\n border: none;\n border-left: 2px solid transparent;\n background: none;\n position: relative;\n transition: background var(--dur-fast), color var(--dur-fast);\n text-align: left;\n font-family: var(--font-sans);\n }\n .sb-item:hover {\n background: color-mix(in srgb, var(--prism-primary) 5%, transparent);\n color: var(--prism-text);\n }\n .sb-item--active {\n border-left-color: var(--prism-primary);\n background: color-mix(in srgb, var(--prism-primary) 12%, transparent);\n color: var(--prism-text);\n font-weight: 500;\n }\n .sb-item--active::before {\n content: '';\n position: absolute;\n left: -1px;\n top: 0;\n bottom: 0;\n width: 3px;\n background: linear-gradient(180deg, var(--prism-primary-from), var(--prism-primary-to));\n }\n .sb-item-icon { flex: 0 0 12px; opacity: 0.7; }\n .sb-item-name {\n flex: 1;\n min-width: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .sb-item-status {\n flex: 0 0 auto;\n margin-left: auto;\n display: flex;\n align-items: center;\n }\n .sb-item-status-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--prism-warn);\n }\n\n .sb-item--deprecated .sb-item-name {\n text-decoration: line-through;\n text-decoration-thickness: 1px;\n color: var(--prism-text-ghost);\n opacity: 0.7;\n }\n\n\n :focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n }\n "] }]
@@ -438,4 +453,4 @@ export class PrismSidebarComponent {
438
453
  type: HostListener,
439
454
  args: ['document:keydown', ['$event']]
440
455
  }] }); })();
441
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismSidebarComponent, { className: "PrismSidebarComponent", filePath: "app/sidebar/prism-sidebar.component.ts", lineNumber: 351 }); })();
456
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismSidebarComponent, { className: "PrismSidebarComponent", filePath: "app/sidebar/prism-sidebar.component.ts", lineNumber: 368 }); })();
@@ -1,6 +1,7 @@
1
1
  export interface ParsedHost {
2
2
  tag: string;
3
3
  attrs: string;
4
+ content?: string;
4
5
  }
5
6
  export declare function parseHostString(host: string): ParsedHost | null;
6
7
  //# sourceMappingURL=host-parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-parser.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/host-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAS/D"}
1
+ {"version":3,"file":"host-parser.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/host-parser.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA4B/D"}
@@ -1,9 +1,20 @@
1
1
  export function parseHostString(host) {
2
2
  const trimmed = host.trim();
3
- const match = trimmed.match(/^<\s*([a-zA-Z][a-zA-Z0-9-]*)((?:\s+[^>]*?)?)\s*\/?\s*>$/);
4
- if (!match)
5
- return null;
6
- const tag = match[1];
7
- const attrs = match[2].trim();
8
- return { tag, attrs };
3
+ const open = trimmed.match(/^<\s*([a-zA-Z][a-zA-Z0-9-]*)((?:\s+[^>]*?)?)\s*\/?\s*>$/);
4
+ if (open) {
5
+ return { tag: open[1], attrs: open[2].trim() };
6
+ }
7
+ const wrapped = trimmed.match(/^<\s*([a-zA-Z][a-zA-Z0-9-]*)((?:\s+[^>]*?)?)\s*>([\s\S]*?)<\/\s*\1\s*>$/);
8
+ if (wrapped) {
9
+ return {
10
+ tag: wrapped[1],
11
+ attrs: wrapped[2].trim(),
12
+ content: wrapped[3],
13
+ };
14
+ }
15
+ if (trimmed.length > 0) {
16
+ console.warn(`[ng-prism] @Showcase host="${host}" could not be parsed and will fall back to <div>. ` +
17
+ `Supported forms: "<tag>", "<tag attrs>", "<tag />", or "<tag>text</tag>".`);
18
+ }
19
+ return null;
9
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-manifest.generator.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/runtime-manifest.generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAIjE,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAiID,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAmFR"}
1
+ {"version":3,"file":"runtime-manifest.generator.d.ts","sourceRoot":"","sources":["../../../src/builder/manifest/runtime-manifest.generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,8BAA8B,CAAC;AAChF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAIjE,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAqID,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,sBAAsB,GAC9B,MAAM,CAmFR"}
@@ -51,10 +51,12 @@ function generateWrapperClass(comp) {
51
51
  let tag;
52
52
  let attrs;
53
53
  let importsArray;
54
+ let hostContentDefault = '';
54
55
  if (typeof host === 'string') {
55
56
  const parsed = parseHostString(host);
56
57
  tag = parsed?.tag ?? 'div';
57
58
  attrs = parsed?.attrs ? ` ${parsed.attrs}` : '';
59
+ hostContentDefault = parsed?.content ?? '';
58
60
  importsArray = `[${comp.className}]`;
59
61
  }
60
62
  else if (host && typeof host === 'object') {
@@ -85,7 +87,7 @@ function generateWrapperClass(comp) {
85
87
  for (const o of comp.outputs) {
86
88
  members.push(` ${o.name} = output();`);
87
89
  }
88
- members.push(` __prismContent__ = input('');`);
90
+ members.push(` __prismContent__ = input(${JSON.stringify(hostContentDefault)});`);
89
91
  const lines = [
90
92
  `@Component({`,
91
93
  ` standalone: true,`,