@ng-prism/core 22.4.1 → 22.6.0

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 (131) hide show
  1. package/README.md +2 -0
  2. package/dist/app/canvas/prism-canvas-toolbar.component.d.ts +33 -2
  3. package/dist/app/canvas/prism-canvas-toolbar.component.d.ts.map +1 -1
  4. package/dist/app/canvas/prism-canvas-toolbar.component.js +135 -28
  5. package/dist/app/canvas/state-chips.d.ts +50 -0
  6. package/dist/app/canvas/state-chips.d.ts.map +1 -0
  7. package/dist/app/canvas/state-chips.js +40 -0
  8. package/dist/app/component-head/prism-component-head.component.d.ts +1 -0
  9. package/dist/app/component-head/prism-component-head.component.d.ts.map +1 -1
  10. package/dist/app/component-head/prism-component-head.component.js +11 -6
  11. package/dist/app/component-head/prism-head-info.component.d.ts +2 -1
  12. package/dist/app/component-head/prism-head-info.component.d.ts.map +1 -1
  13. package/dist/app/component-head/prism-head-info.component.js +30 -7
  14. package/dist/app/directives/resize-value.d.ts +1 -1
  15. package/dist/app/directives/resize-value.js +1 -1
  16. package/dist/app/discovery-manifest.d.ts +2 -2
  17. package/dist/app/discovery-manifest.d.ts.map +1 -1
  18. package/dist/app/discovery-manifest.js +22 -4
  19. package/dist/app/overview/open-in-playground.d.ts +11 -0
  20. package/dist/app/overview/open-in-playground.d.ts.map +1 -0
  21. package/dist/app/overview/open-in-playground.js +12 -0
  22. package/dist/app/overview/overview-matrix.d.ts +79 -0
  23. package/dist/app/overview/overview-matrix.d.ts.map +1 -0
  24. package/dist/app/overview/overview-matrix.js +98 -0
  25. package/dist/app/overview/overview-visibility.d.ts +10 -2
  26. package/dist/app/overview/overview-visibility.d.ts.map +1 -1
  27. package/dist/app/overview/overview-visibility.js +14 -3
  28. package/dist/app/overview/prism-overview-cell.component.d.ts +29 -2
  29. package/dist/app/overview/prism-overview-cell.component.d.ts.map +1 -1
  30. package/dist/app/overview/prism-overview-cell.component.js +145 -27
  31. package/dist/app/overview/prism-overview-matrix.component.d.ts +29 -0
  32. package/dist/app/overview/prism-overview-matrix.component.d.ts.map +1 -0
  33. package/dist/app/overview/prism-overview-matrix.component.js +164 -0
  34. package/dist/app/overview/prism-overview.component.d.ts +4 -0
  35. package/dist/app/overview/prism-overview.component.d.ts.map +1 -1
  36. package/dist/app/overview/prism-overview.component.js +37 -14
  37. package/dist/app/panels/a11y/a11y-core.plugin.d.ts.map +1 -1
  38. package/dist/app/panels/a11y/a11y-core.plugin.js +0 -1
  39. package/dist/app/panels/controls/controls-plugin.d.ts.map +1 -1
  40. package/dist/app/panels/controls/controls-plugin.js +1 -2
  41. package/dist/app/panels/events/events-plugin.d.ts.map +1 -1
  42. package/dist/app/panels/events/events-plugin.js +1 -2
  43. package/dist/app/pseudo/pseudo-selector.d.ts +24 -0
  44. package/dist/app/pseudo/pseudo-selector.d.ts.map +1 -0
  45. package/dist/app/pseudo/pseudo-selector.js +136 -0
  46. package/dist/app/pseudo/pseudo-state-marker.d.ts +66 -0
  47. package/dist/app/pseudo/pseudo-state-marker.d.ts.map +1 -0
  48. package/dist/app/pseudo/pseudo-state-marker.js +165 -0
  49. package/dist/app/pseudo/pseudo-stylesheets.d.ts +49 -0
  50. package/dist/app/pseudo/pseudo-stylesheets.d.ts.map +1 -0
  51. package/dist/app/pseudo/pseudo-stylesheets.js +137 -0
  52. package/dist/app/pseudo/pseudo-targets.d.ts +11 -0
  53. package/dist/app/pseudo/pseudo-targets.d.ts.map +1 -0
  54. package/dist/app/pseudo/pseudo-targets.js +46 -0
  55. package/dist/app/pseudo/state-fit.d.ts +28 -0
  56. package/dist/app/pseudo/state-fit.d.ts.map +1 -0
  57. package/dist/app/pseudo/state-fit.js +97 -0
  58. package/dist/app/renderer/input-bindings.d.ts +16 -0
  59. package/dist/app/renderer/input-bindings.d.ts.map +1 -0
  60. package/dist/app/renderer/input-bindings.js +21 -0
  61. package/dist/app/renderer/known-inputs.d.ts +8 -1
  62. package/dist/app/renderer/known-inputs.d.ts.map +1 -1
  63. package/dist/app/renderer/known-inputs.js +13 -5
  64. package/dist/app/renderer/prism-renderer.component.d.ts +18 -1
  65. package/dist/app/renderer/prism-renderer.component.d.ts.map +1 -1
  66. package/dist/app/renderer/prism-renderer.component.js +68 -22
  67. package/dist/app/renderer/projectable-content.d.ts +8 -1
  68. package/dist/app/renderer/projectable-content.d.ts.map +1 -1
  69. package/dist/app/renderer/projectable-content.js +40 -29
  70. package/dist/app/renderer/rendered-key.d.ts +38 -0
  71. package/dist/app/renderer/rendered-key.d.ts.map +1 -0
  72. package/dist/app/renderer/rendered-key.js +34 -0
  73. package/dist/app/renderer/snippet-generator.js +7 -5
  74. package/dist/app/services/prism-capture.service.d.ts +2 -0
  75. package/dist/app/services/prism-capture.service.d.ts.map +1 -1
  76. package/dist/app/services/prism-capture.service.js +25 -0
  77. package/dist/app/services/prism-pseudo-state.service.d.ts +93 -0
  78. package/dist/app/services/prism-pseudo-state.service.d.ts.map +1 -0
  79. package/dist/app/services/prism-pseudo-state.service.js +155 -0
  80. package/dist/app/services/prism-renderer.service.d.ts +17 -0
  81. package/dist/app/services/prism-renderer.service.d.ts.map +1 -1
  82. package/dist/app/services/prism-renderer.service.js +37 -2
  83. package/dist/app/services/prism-url-state.service.d.ts.map +1 -1
  84. package/dist/app/services/prism-url-state.service.js +39 -8
  85. package/dist/app/theme/prism-default-theme.d.ts.map +1 -1
  86. package/dist/app/theme/prism-default-theme.js +6 -5
  87. package/dist/builder/config-loader/deprecated-options.d.ts +7 -0
  88. package/dist/builder/config-loader/deprecated-options.d.ts.map +1 -0
  89. package/dist/builder/config-loader/deprecated-options.js +23 -0
  90. package/dist/builder/manifest/runtime-manifest.generator.d.ts.map +1 -1
  91. package/dist/builder/manifest/runtime-manifest.generator.js +3 -2
  92. package/dist/builder/scanner/component.scanner.d.ts.map +1 -1
  93. package/dist/builder/scanner/component.scanner.js +27 -0
  94. package/dist/builder/scanner/entry-point-discovery.d.ts +5 -0
  95. package/dist/builder/scanner/entry-point-discovery.d.ts.map +1 -1
  96. package/dist/builder/scanner/entry-point-discovery.js +14 -0
  97. package/dist/builder/scanner/entry-point.scanner.d.ts +3 -1
  98. package/dist/builder/scanner/entry-point.scanner.d.ts.map +1 -1
  99. package/dist/builder/scanner/entry-point.scanner.js +7 -6
  100. package/dist/builder/scanner/input.extractor.d.ts.map +1 -1
  101. package/dist/builder/scanner/input.extractor.js +22 -3
  102. package/dist/builder/scanner/pseudo-states.d.ts +12 -0
  103. package/dist/builder/scanner/pseudo-states.d.ts.map +1 -0
  104. package/dist/builder/scanner/pseudo-states.js +58 -0
  105. package/dist/builder/scanner/scanner.d.ts +2 -2
  106. package/dist/builder/scanner/scanner.d.ts.map +1 -1
  107. package/dist/builder/scanner/scanner.js +16 -6
  108. package/dist/builder/scanner/showcase-diagnostics.js +9 -9
  109. package/dist/builder/scanner/showcase-states.d.ts +17 -0
  110. package/dist/builder/scanner/showcase-states.d.ts.map +1 -0
  111. package/dist/builder/scanner/showcase-states.js +58 -0
  112. package/dist/builder/scanner/source-file-cache.d.ts +26 -0
  113. package/dist/builder/scanner/source-file-cache.d.ts.map +1 -0
  114. package/dist/builder/scanner/source-file-cache.js +60 -0
  115. package/dist/builder/shared/prism-pipeline.d.ts.map +1 -1
  116. package/dist/builder/shared/prism-pipeline.js +28 -13
  117. package/dist/decorator/index.d.ts +1 -1
  118. package/dist/decorator/index.d.ts.map +1 -1
  119. package/dist/decorator/showcase.types.d.ts +33 -0
  120. package/dist/decorator/showcase.types.d.ts.map +1 -1
  121. package/dist/plugin/index.d.ts +3 -1
  122. package/dist/plugin/index.d.ts.map +1 -1
  123. package/dist/plugin/index.js +1 -0
  124. package/dist/plugin/plugin.types.d.ts +53 -7
  125. package/dist/plugin/plugin.types.d.ts.map +1 -1
  126. package/dist/shared/pseudo-state.type.d.ts +22 -0
  127. package/dist/shared/pseudo-state.type.d.ts.map +1 -0
  128. package/dist/shared/pseudo-state.type.js +2 -0
  129. package/package.json +1 -1
  130. package/src/builder/build/schema.json +6 -6
  131. package/src/builder/serve/schema.json +6 -6
@@ -1,11 +1,34 @@
1
- import { ChangeDetectionStrategy, Component, computed, DestroyRef, effect, inject, Injector, input, untracked, viewChild, ViewContainerRef } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, computed, DestroyRef, effect, inject, Injector, input, output, reflectComponentType, signal, untracked, viewChild, ViewContainerRef } from '@angular/core';
2
2
  import { resolveVariantBg } from '../../shared/variant-bg.js';
3
3
  import { CANVAS_BG_STYLES } from '../canvas/canvas-bg.styles.js';
4
- import { buildKnownInputs } from '../renderer/known-inputs.js';
4
+ import { buildInputBindings } from '../renderer/input-bindings.js';
5
5
  import { parseContentToNodes } from '../renderer/projectable-content.js';
6
- import { computeVariantState } from '../services/prism-renderer.service.js';
6
+ import { PrismPanelService } from '../services/prism-panel.service.js';
7
+ import { PrismPseudoStateService } from '../services/prism-pseudo-state.service.js';
8
+ import { computeVariantState, PrismRendererService } from '../services/prism-renderer.service.js';
9
+ import { openInPlayground } from './open-in-playground.js';
7
10
  import * as i0 from "@angular/core";
8
11
  const _c0 = ["outlet"];
12
+ function PrismOverviewCellComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
13
+ i0.ɵɵdomElementStart(0, "div", 3)(1, "span", 5);
14
+ i0.ɵɵtext(2, "\u2013");
15
+ i0.ɵɵdomElementEnd();
16
+ i0.ɵɵdomElementStart(3, "span", 6);
17
+ i0.ɵɵtext(4);
18
+ i0.ɵɵdomElementEnd()();
19
+ } if (rf & 2) {
20
+ i0.ɵɵadvance(4);
21
+ i0.ɵɵtextInterpolate(ctx);
22
+ } }
23
+ function PrismOverviewCellComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
24
+ i0.ɵɵdomElementStart(0, "span", 4);
25
+ i0.ɵɵtext(1);
26
+ i0.ɵɵdomElementEnd();
27
+ } if (rf & 2) {
28
+ const ctx_r0 = i0.ɵɵnextContext();
29
+ i0.ɵɵadvance();
30
+ i0.ɵɵtextInterpolate(ctx_r0.caption());
31
+ } }
9
32
  /**
10
33
  * One frame of the contact sheet: a stage painting the variant's declared
11
34
  * background, with the variant's own instance on it and a caption beneath.
@@ -16,14 +39,36 @@ const _c0 = ["outlet"];
16
39
  * writing to any of them would corrupt what they mean. `data-prism-rendered`
17
40
  * matters most: it is the selector external screenshot runners key on (see
18
41
  * `docs/guide/external-tooling.md`), and this component never emits it.
42
+ *
43
+ * Forced pseudo states are the variant's own, applied by a marker of the
44
+ * cell's own, so a hovered cell never hovers its neighbour. The tools menu's
45
+ * state toggle does not reach here: like every other control, it belongs to
46
+ * the Playground.
47
+ *
48
+ * A cell can combine its variant with one of the component's `states` (the
49
+ * matrix does). When the marker finds that the state does not fit the rendered
50
+ * component, or the variant opted out with `states: false`, the cell shows the
51
+ * reason in place of the component. Every cell, with or without a state, opens
52
+ * its exact combination in the Playground on click, Enter or Space.
19
53
  */
20
54
  export class PrismOverviewCellComponent {
21
55
  component = input.required(/* @ts-ignore */
22
56
  ...(ngDevMode ? [{ debugName: "component" }] : /* istanbul ignore next */ []));
23
57
  index = input.required(/* @ts-ignore */
24
58
  ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
59
+ /** Position of the component state in `ShowcaseConfig.states`, `null` for the variant alone. */
60
+ state = input(null, /* @ts-ignore */
61
+ ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
62
+ /** `matrix` leaves the caption and the grid span to the matrix around the cell. */
63
+ mode = input('sheet', /* @ts-ignore */
64
+ ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
65
+ /** Whether the state fits the rendered variant. Only emitted while `state` is not `null`. */
66
+ fitChange = output();
25
67
  injector = inject(Injector);
26
68
  destroyRef = inject(DestroyRef);
69
+ renderer = inject(PrismRendererService);
70
+ panels = inject(PrismPanelService);
71
+ pseudoMarker = inject(PrismPseudoStateService).createMarker();
27
72
  outlet = viewChild.required('outlet', { ...(ngDevMode ? { debugName: "outlet" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
28
73
  /** Never null: `resolveVariantBg` falls back to `DEFAULT_VARIANT_BG`. */
29
74
  bg = computed(() => resolveVariantBg(this.component().meta.showcaseConfig, this.index()), /* @ts-ignore */
@@ -39,19 +84,51 @@ export class PrismOverviewCellComponent {
39
84
  return variant ? `${number} ${variant.name}` : number;
40
85
  }, /* @ts-ignore */
41
86
  ...(ngDevMode ? [{ debugName: "caption" }] : /* istanbul ignore next */ []));
42
- isWide = computed(() => {
87
+ /** Why the state is not shown on this cell, `null` while the component is. */
88
+ unfitReason = signal(null, /* @ts-ignore */
89
+ ...(ngDevMode ? [{ debugName: "unfitReason" }] : /* istanbul ignore next */ []));
90
+ label = computed(() => {
91
+ const config = this.component().meta.showcaseConfig;
92
+ const variant = config.variants?.[this.index()]?.name ?? this.caption();
93
+ const stateIndex = this.state();
94
+ const state = stateIndex === null ? undefined : config.states?.[stateIndex];
95
+ return `Open ${variant}${state ? ` × ${state.name}` : ''} in the Playground`;
96
+ }, /* @ts-ignore */
97
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
98
+ stretches = computed(() => {
43
99
  const config = this.component().meta.showcaseConfig;
44
100
  const variant = config.variants?.[this.index()];
45
101
  return (variant?.canvasLayout ?? config.canvasLayout ?? 'fit') === 'stretch';
46
102
  }, /* @ts-ignore */
47
- ...(ngDevMode ? [{ debugName: "isWide" }] : /* istanbul ignore next */ []));
103
+ ...(ngDevMode ? [{ debugName: "stretches" }] : /* istanbul ignore next */ []));
48
104
  constructor() {
49
105
  effect(() => {
50
106
  const component = this.component();
51
107
  const index = this.index();
52
- untracked(() => this.mount(component, index));
108
+ const state = this.state();
109
+ untracked(() => {
110
+ const fit = this.mount(component, index, state);
111
+ // Outside `mount`'s try: a handler that throws is the parent's
112
+ // doing, not a variant that failed to render.
113
+ if (fit)
114
+ this.fitChange.emit(fit);
115
+ });
116
+ });
117
+ this.destroyRef.onDestroy(() => {
118
+ this.pseudoMarker.clear();
119
+ this.outlet().clear();
53
120
  });
54
- this.destroyRef.onDestroy(() => this.outlet().clear());
121
+ }
122
+ open() {
123
+ openInPlayground(this.renderer, this.panels, this.index(), this.state());
124
+ }
125
+ onKeydown(event) {
126
+ // Only for the cell itself: Enter and Space belong to a control inside the
127
+ // component while it has the focus.
128
+ if (event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' '))
129
+ return;
130
+ event.preventDefault();
131
+ this.open();
55
132
  }
56
133
  // The Playground lets a variant that throws on construction propagate: one
57
134
  // broken instance, and the user navigates away from it. The Overview
@@ -59,9 +136,20 @@ export class PrismOverviewCellComponent {
59
136
  // change-detection pass. An uncaught throw here would abort the refresh of
60
137
  // every cell after it, so one bad variant would take down the whole sheet
61
138
  // instead of just its own cell. Hence: contain here, propagate there.
62
- mount(component, index) {
139
+ //
140
+ // Returns the fit of the state on the rendered variant, `null` when the cell
141
+ // has no state or the variant failed to render.
142
+ mount(component, index, stateIndex) {
143
+ this.unfitReason.set(null);
63
144
  try {
64
145
  this.outlet().clear();
146
+ const variant = component.meta.showcaseConfig.variants?.[index];
147
+ // The matrix gives such a variant one cell without a state, so this is
148
+ // not asked for today. Nothing to mount, and nothing to evaluate.
149
+ if (stateIndex !== null && variant?.states === false) {
150
+ this.pseudoMarker.clear();
151
+ return this.unfit('states: false');
152
+ }
65
153
  // No `onUnknownInput` callback: the Playground already warns once per
66
154
  // component, and repeating that warning per cell would say the same thing
67
155
  // n times.
@@ -70,18 +158,30 @@ export class PrismOverviewCellComponent {
70
158
  providers: component.meta.showcaseConfig.providers ?? [],
71
159
  parent: this.injector
72
160
  });
73
- const projectableNodes = activeContent ? parseContentToNodes(activeContent) : undefined;
161
+ const projectableNodes = activeContent ? parseContentToNodes(activeContent, reflectComponentType(component.type)?.ngContentSelectors ?? []) : undefined;
74
162
  const ref = this.outlet().createComponent(component.type, {
75
163
  injector,
76
164
  projectableNodes
77
165
  });
78
- const knownInputs = buildKnownInputs(component);
166
+ const inputBindings = buildInputBindings(component);
79
167
  for (const [key, value] of Object.entries(values)) {
80
- if (!knownInputs.has(key))
81
- continue;
82
- ref.setInput(key, value);
168
+ const binding = inputBindings.get(key);
169
+ if (binding !== undefined)
170
+ ref.setInput(binding, value);
83
171
  }
84
172
  ref.changeDetectorRef.detectChanges();
173
+ const statePseudo = stateIndex === null ? null : (component.meta.showcaseConfig.states?.[stateIndex]?.pseudo ?? null);
174
+ this.pseudoMarker.apply(ref.location.nativeElement, variant?.pseudo, statePseudo);
175
+ const fit = this.pseudoMarker.applied()?.fit ?? null;
176
+ if (!fit || fit.fits)
177
+ return fit;
178
+ // The marker keeps a state that does not fit applied and forces nothing of
179
+ // it, the Playground wants that to show why. A cell has no use for the
180
+ // component then: it would be a picture of the variant under a label
181
+ // that says something else.
182
+ this.pseudoMarker.clear();
183
+ this.outlet().clear();
184
+ return this.unfit(fit.reason);
85
185
  }
86
186
  catch (error) {
87
187
  // `createComponent` attaches the host element and its structural DOM
@@ -92,37 +192,55 @@ export class PrismOverviewCellComponent {
92
192
  // a caught cell actually show an empty stage with its caption still in
93
193
  // place, which shows "this variant failed" instead of a broken grid
94
194
  // with no indication of which cell caused it.
195
+ this.pseudoMarker.clear();
95
196
  this.outlet().clear();
96
197
  console.error(`[ng-prism] Variant ${index} of ${component.meta.className} failed to render:`, error);
198
+ return null;
97
199
  }
98
200
  }
201
+ unfit(reason) {
202
+ this.unfitReason.set(reason);
203
+ return { fits: false, reason };
204
+ }
99
205
  static ɵfac = function PrismOverviewCellComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismOverviewCellComponent)(); };
100
206
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismOverviewCellComponent, selectors: [["prism-overview-cell"]], viewQuery: function PrismOverviewCellComponent_Query(rf, ctx) { if (rf & 1) {
101
207
  i0.ɵɵviewQuerySignal(ctx.outlet, _c0, 5, ViewContainerRef);
102
208
  } if (rf & 2) {
103
209
  i0.ɵɵqueryAdvance();
104
- } }, hostAttrs: ["role", "listitem"], hostVars: 1, hostBindings: function PrismOverviewCellComponent_HostBindings(rf, ctx) { if (rf & 2) {
105
- i0.ɵɵattribute("data-wide", ctx.isWide() ? "" : null);
106
- } }, inputs: { component: [1, "component"], index: [1, "index"] }, decls: 6, vars: 2, consts: [["outlet", ""], [1, "cell__stage"], [1, "cell__mount"], [1, "cell__caption"]], template: function PrismOverviewCellComponent_Template(rf, ctx) { if (rf & 1) {
210
+ } }, hostAttrs: ["role", "listitem", "tabindex", "0"], hostVars: 3, hostBindings: function PrismOverviewCellComponent_HostBindings(rf, ctx) { if (rf & 1) {
211
+ i0.ɵɵlistener("click", function PrismOverviewCellComponent_click_HostBindingHandler() { return ctx.open(); })("keydown", function PrismOverviewCellComponent_keydown_HostBindingHandler($event) { return ctx.onKeydown($event); });
212
+ } if (rf & 2) {
213
+ i0.ɵɵattribute("aria-label", ctx.label())("data-wide", ctx.mode() === "sheet" && ctx.stretches() ? "" : null)("data-stretch", ctx.mode() === "matrix" && ctx.stretches() ? "" : null);
214
+ } }, inputs: { component: [1, "component"], index: [1, "index"], state: [1, "state"], mode: [1, "mode"] }, outputs: { fitChange: "fitChange" }, decls: 6, vars: 4, consts: [["outlet", ""], [1, "cell__stage"], [1, "cell__mount"], [1, "cell__unfit"], [1, "cell__caption"], ["aria-hidden", "true", 1, "cell__unfit-mark"], [1, "cell__unfit-reason"]], template: function PrismOverviewCellComponent_Template(rf, ctx) { if (rf & 1) {
107
215
  i0.ɵɵdomElementStart(0, "div", 1)(1, "div", 2);
108
216
  i0.ɵɵdomElementContainer(2, null, 0);
109
- i0.ɵɵdomElementEnd()();
110
- i0.ɵɵdomElementStart(4, "span", 3);
111
- i0.ɵɵtext(5);
112
217
  i0.ɵɵdomElementEnd();
218
+ i0.ɵɵconditionalCreate(4, PrismOverviewCellComponent_Conditional_4_Template, 5, 1, "div", 3);
219
+ i0.ɵɵdomElementEnd();
220
+ i0.ɵɵconditionalCreate(5, PrismOverviewCellComponent_Conditional_5_Template, 2, 1, "span", 4);
113
221
  } if (rf & 2) {
114
- i0.ɵɵattribute("data-bg", ctx.bg());
115
- i0.ɵɵadvance(5);
116
- i0.ɵɵtextInterpolate(ctx.caption());
117
- } }, styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--%NS%sp-2);\n min-width: 0;\n}\n\n\n\n[data-wide][_nghost-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.cell__stage[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n padding: var(--%NS%sp-5);\n overflow: hidden;\n outline: 1px solid var(--%NS%prism-stage-edge);\n outline-offset: -1px;\n background-color: var(--%NS%prism-stage);\n border-radius: var(--%NS%radius-sm);\n}\n\n.cell__mount[_ngcontent-%COMP%] {\n display: inline-block;\n max-width: 100%;\n}\n\n[data-wide][_nghost-%COMP%] .cell__mount[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n}\n\n\n\n\n\n.cell__caption[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--%NS%prism-font-mono);\n font-size: var(--%NS%fs-xs);\n color: var(--%NS%prism-text-muted);\n white-space: nowrap;\n}", "[data-bg=\"dots\"][_ngcontent-%COMP%] {\n background-image: radial-gradient(circle, var(--%NS%prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n }\n\n [data-bg=\"plain\"][_ngcontent-%COMP%] {\n background-image: none;\n }\n\n \n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n [data-bg=\"light\"][_ngcontent-%COMP%] {\n background-color: var(--%NS%prism-void-light, #f7f5fc);\n background-image: none;\n --%NS%prism-measure: #ca00c1;\n --%NS%prism-measure-plate: var(--%NS%prism-void-light, #f7f5fc);\n }\n [data-bg=\"dark\"][_ngcontent-%COMP%] {\n background-color: var(--%NS%prism-void-dark, #07050f);\n background-image: none;\n --%NS%prism-measure: #f632ff;\n --%NS%prism-measure-plate: var(--%NS%prism-void-dark, #07050f);\n }\n\n \n\n\n [data-bg=\"checker\"][_ngcontent-%COMP%], \n [data-bg=\"transparent\"][_ngcontent-%COMP%] {\n background-image:\n linear-gradient(45deg, var(--%NS%prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--%NS%prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--%NS%prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--%NS%prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }"] });
222
+ let tmp_3_0;
223
+ i0.ɵɵattribute("data-bg", ctx.unfitReason() === null ? ctx.bg() : null)("data-unfit", ctx.unfitReason() === null ? null : "");
224
+ i0.ɵɵadvance(4);
225
+ i0.ɵɵconditional((tmp_3_0 = ctx.unfitReason()) ? 4 : -1, tmp_3_0);
226
+ i0.ɵɵadvance();
227
+ i0.ɵɵconditional(ctx.mode() === "sheet" ? 5 : -1);
228
+ } }, styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--%NS%sp-2);\n min-width: 0;\n cursor: pointer;\n}\n\n[_nghost-%COMP%]:focus-visible {\n outline: 2px solid var(--%NS%prism-primary);\n outline-offset: 2px;\n border-radius: var(--%NS%radius-sm);\n}\n\n\n\n[data-wide][_nghost-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.cell__stage[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n padding: var(--%NS%sp-5);\n overflow: hidden;\n outline: 1px solid var(--%NS%prism-stage-edge);\n outline-offset: -1px;\n background-color: var(--%NS%prism-stage);\n border-radius: var(--%NS%radius-sm);\n}\n\n.cell__mount[_ngcontent-%COMP%] {\n display: inline-block;\n max-width: 100%;\n}\n\n[data-wide][_nghost-%COMP%] .cell__mount[_ngcontent-%COMP%], \n[data-stretch][_nghost-%COMP%] .cell__mount[_ngcontent-%COMP%] {\n display: block;\n width: 100%;\n}\n\n\n\n.cell__stage[data-unfit][_ngcontent-%COMP%] {\n outline-style: dashed;\n background: none;\n}\n\n.cell__stage[data-unfit][_ngcontent-%COMP%] .cell__mount[_ngcontent-%COMP%] {\n display: none;\n}\n\n.cell__unfit[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: var(--%NS%sp-1);\n align-items: center;\n max-width: 100%;\n font-family: var(--%NS%prism-font-mono);\n font-size: var(--%NS%fs-xs);\n color: var(--%NS%prism-text-muted);\n text-align: center;\n}\n\n.cell__unfit-mark[_ngcontent-%COMP%] {\n font-size: var(--%NS%fs-md);\n line-height: 1;\n}\n\n\n\n\n\n.cell__caption[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--%NS%prism-font-mono);\n font-size: var(--%NS%fs-xs);\n color: var(--%NS%prism-text-muted);\n white-space: nowrap;\n}", "[data-bg=\"dots\"][_ngcontent-%COMP%] {\n background-image: radial-gradient(circle, var(--%NS%prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n }\n\n [data-bg=\"plain\"][_ngcontent-%COMP%] {\n background-image: none;\n }\n\n \n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n [data-bg=\"light\"][_ngcontent-%COMP%] {\n background-color: var(--%NS%prism-void-light, #f7f5fc);\n background-image: none;\n --%NS%prism-measure: #ca00c1;\n --%NS%prism-measure-plate: var(--%NS%prism-void-light, #f7f5fc);\n }\n [data-bg=\"dark\"][_ngcontent-%COMP%] {\n background-color: var(--%NS%prism-void-dark, #07050f);\n background-image: none;\n --%NS%prism-measure: #f632ff;\n --%NS%prism-measure-plate: var(--%NS%prism-void-dark, #07050f);\n }\n\n \n\n\n [data-bg=\"checker\"][_ngcontent-%COMP%], \n [data-bg=\"transparent\"][_ngcontent-%COMP%] {\n background-image:\n linear-gradient(45deg, var(--%NS%prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--%NS%prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--%NS%prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--%NS%prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }"] });
118
229
  }
119
230
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismOverviewCellComponent, [{
120
231
  type: Component,
121
232
  args: [{ selector: 'prism-overview-cell', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
122
233
  role: 'listitem',
123
- '[attr.data-wide]': "isWide() ? '' : null"
124
- }, template: "<div\n class=\"cell__stage\"\n [attr.data-bg]=\"bg()\">\n <div class=\"cell__mount\"><ng-container #outlet /></div>\n</div>\n<span class=\"cell__caption\">{{ caption() }}</span>\n", styles: [":host {\n display: flex;\n flex-direction: column;\n gap: var(--sp-2);\n min-width: 0;\n}\n\n/* A stretch variant has no intrinsic width to compare against its\n neighbours, so it takes the row rather than a column. */\n:host([data-wide]) {\n grid-column: 1 / -1;\n}\n\n.cell__stage {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n padding: var(--sp-5);\n overflow: hidden;\n outline: 1px solid var(--prism-stage-edge);\n outline-offset: -1px;\n background-color: var(--prism-stage);\n border-radius: var(--radius-sm);\n}\n\n.cell__mount {\n display: inline-block;\n max-width: 100%;\n}\n\n:host([data-wide]) .cell__mount {\n display: block;\n width: 100%;\n}\n\n/* The caption sits below the frame, not on it. Inside, it would have to\n invert against every background the cell can paint, and gaining a new\n contrast rule per CanvasBg value is the cost the sheet exists to\n avoid. */\n.cell__caption {\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--prism-font-mono);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n white-space: nowrap;\n}\n", "\n [data-bg=\"dots\"] {\n background-image: radial-gradient(circle, var(--prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n }\n\n [data-bg=\"plain\"] {\n background-image: none;\n }\n\n /* Flat, not dotted. \"light\" and \"dark\" name the surface a component was\n designed against, and their colour is absolute rather than a theme token,\n which makes them the values to declare for a screenshot baseline. Use\n \"dots\" for the grid. */\n /* These two also re-point --prism-measure. Other overlays use theme colours\n on theme surfaces, but these grounds ignore the theme: \"light\" stays\n near-white in the dark theme and \"dark\" stays near-black in the light one.\n The dark theme's magenta reaches only 2.85:1 on the light ground, under the\n 4.5:1 its 9px readout needs, so the measurement colour has to follow the\n ground, not the theme.\n\n --prism-measure-plate follows it for the same reason. It is the surface\n the measuring tool's value label paints itself on, so the label reads as a\n gap in the measurement line rather than a badge on top of it. At its\n --prism-stage fallback it would be the theme's stage under a re-pointed\n foreground: the light theme's magenta on the dark theme's stage reads\n 3.71:1, the dark theme's on white 3.08:1. Pinned to the ground the same way,\n the pairs reach 4.54:1 and 6.57:1. A color-mix against the ground would\n work too, but this file already states both grounds literally, and one\n mechanism per decision is enough.\n\n Literal values because this file is theme-independent, like the two\n grounds below. Keep them in step with --prism-measure in\n prism-default-theme.ts; semantic-colours.spec.ts fails if they drift. */\n [data-bg=\"light\"] {\n background-color: var(--prism-void-light, #f7f5fc);\n background-image: none;\n --prism-measure: #ca00c1;\n --prism-measure-plate: var(--prism-void-light, #f7f5fc);\n }\n [data-bg=\"dark\"] {\n background-color: var(--prism-void-dark, #07050f);\n background-image: none;\n --prism-measure: #f632ff;\n --prism-measure-plate: var(--prism-void-dark, #07050f);\n }\n\n /* \"transparent\" shares the checkerboard. In the app the checkerboard is\n already the UI's sign for \"no surface\", and a see-through stage would only\n show the shell behind it. Only CAPTURE_STYLES tells the two apart. */\n [data-bg=\"checker\"],\n [data-bg=\"transparent\"] {\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }\n"] }]
125
- }], () => [], { component: [{ type: i0.Input, args: [{ isSignal: true, alias: "component", required: true }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: true }] }], outlet: [{ type: i0.ViewChild, args: ['outlet', { ...{
234
+ tabindex: '0',
235
+ '[attr.aria-label]': 'label()',
236
+ // In the matrix the grid spans are the matrix's own. A stretch variant still
237
+ // fills its cell, so `canvasLayout` holds for the whole row.
238
+ '[attr.data-wide]': "mode() === 'sheet' && stretches() ? '' : null",
239
+ '[attr.data-stretch]': "mode() === 'matrix' && stretches() ? '' : null",
240
+ '(click)': 'open()',
241
+ '(keydown)': 'onKeydown($event)'
242
+ }, template: "<div\n class=\"cell__stage\"\n [attr.data-bg]=\"unfitReason() === null ? bg() : null\"\n [attr.data-unfit]=\"unfitReason() === null ? null : ''\">\n <div class=\"cell__mount\"><ng-container #outlet /></div>\n @if (unfitReason(); as reason) {\n <div class=\"cell__unfit\">\n <span\n class=\"cell__unfit-mark\"\n aria-hidden=\"true\"\n >\u2013</span\n >\n <span class=\"cell__unfit-reason\">{{ reason }}</span>\n </div>\n }\n</div>\n@if (mode() === 'sheet') {\n <span class=\"cell__caption\">{{ caption() }}</span>\n}\n", styles: [":host {\n display: flex;\n flex-direction: column;\n gap: var(--sp-2);\n min-width: 0;\n cursor: pointer;\n}\n\n:host(:focus-visible) {\n outline: 2px solid var(--prism-primary);\n outline-offset: 2px;\n border-radius: var(--radius-sm);\n}\n\n/* A stretch variant has no intrinsic width to compare against its\n neighbours, so it takes the row rather than a column. */\n:host([data-wide]) {\n grid-column: 1 / -1;\n}\n\n.cell__stage {\n display: flex;\n flex: 1;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n padding: var(--sp-5);\n overflow: hidden;\n outline: 1px solid var(--prism-stage-edge);\n outline-offset: -1px;\n background-color: var(--prism-stage);\n border-radius: var(--radius-sm);\n}\n\n.cell__mount {\n display: inline-block;\n max-width: 100%;\n}\n\n:host([data-wide]) .cell__mount,\n:host([data-stretch]) .cell__mount {\n display: block;\n width: 100%;\n}\n\n/* A state that does not fit shows no component and paints no ground: an\n empty frame with the reason, so it cannot pass for a rendering. */\n.cell__stage[data-unfit] {\n outline-style: dashed;\n background: none;\n}\n\n.cell__stage[data-unfit] .cell__mount {\n display: none;\n}\n\n.cell__unfit {\n display: flex;\n flex-direction: column;\n gap: var(--sp-1);\n align-items: center;\n max-width: 100%;\n font-family: var(--prism-font-mono);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n text-align: center;\n}\n\n.cell__unfit-mark {\n font-size: var(--fs-md);\n line-height: 1;\n}\n\n/* The caption sits below the frame, not on it. Inside, it would have to\n invert against every background the cell can paint, and gaining a new\n contrast rule per CanvasBg value is the cost the sheet exists to\n avoid. */\n.cell__caption {\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--prism-font-mono);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n white-space: nowrap;\n}\n", "\n [data-bg=\"dots\"] {\n background-image: radial-gradient(circle, var(--prism-dot) 1px, transparent 1px);\n background-size: 20px 20px;\n }\n\n [data-bg=\"plain\"] {\n background-image: none;\n }\n\n /* Flat, not dotted. \"light\" and \"dark\" name the surface a component was\n designed against, and their colour is absolute rather than a theme token,\n which makes them the values to declare for a screenshot baseline. Use\n \"dots\" for the grid. */\n /* These two also re-point --prism-measure. Other overlays use theme colours\n on theme surfaces, but these grounds ignore the theme: \"light\" stays\n near-white in the dark theme and \"dark\" stays near-black in the light one.\n The dark theme's magenta reaches only 2.85:1 on the light ground, under the\n 4.5:1 its 9px readout needs, so the measurement colour has to follow the\n ground, not the theme.\n\n --prism-measure-plate follows it for the same reason. It is the surface\n the measuring tool's value label paints itself on, so the label reads as a\n gap in the measurement line rather than a badge on top of it. At its\n --prism-stage fallback it would be the theme's stage under a re-pointed\n foreground: the light theme's magenta on the dark theme's stage reads\n 3.71:1, the dark theme's on white 3.08:1. Pinned to the ground the same way,\n the pairs reach 4.54:1 and 6.57:1. A color-mix against the ground would\n work too, but this file already states both grounds literally, and one\n mechanism per decision is enough.\n\n Literal values because this file is theme-independent, like the two\n grounds below. Keep them in step with --prism-measure in\n prism-default-theme.ts; semantic-colours.spec.ts fails if they drift. */\n [data-bg=\"light\"] {\n background-color: var(--prism-void-light, #f7f5fc);\n background-image: none;\n --prism-measure: #ca00c1;\n --prism-measure-plate: var(--prism-void-light, #f7f5fc);\n }\n [data-bg=\"dark\"] {\n background-color: var(--prism-void-dark, #07050f);\n background-image: none;\n --prism-measure: #f632ff;\n --prism-measure-plate: var(--prism-void-dark, #07050f);\n }\n\n /* \"transparent\" shares the checkerboard. In the app the checkerboard is\n already the UI's sign for \"no surface\", and a see-through stage would only\n show the shell behind it. Only CAPTURE_STYLES tells the two apart. */\n [data-bg=\"checker\"],\n [data-bg=\"transparent\"] {\n background-image:\n linear-gradient(45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(-45deg, var(--prism-border) 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, var(--prism-border) 75%),\n linear-gradient(-45deg, transparent 75%, var(--prism-border) 75%);\n background-size: 16px 16px;\n background-position: 0 0, 0 8px, 8px -8px, -8px 0;\n }\n"] }]
243
+ }], () => [], { component: [{ type: i0.Input, args: [{ isSignal: true, alias: "component", required: true }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: true }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], fitChange: [{ type: i0.Output, args: ["fitChange"] }], outlet: [{ type: i0.ViewChild, args: ['outlet', { ...{
126
244
  read: ViewContainerRef
127
245
  }, isSignal: true }] }] }); })();
128
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismOverviewCellComponent, { className: "PrismOverviewCellComponent", filePath: "app/overview/prism-overview-cell.component.ts", lineNumber: 32 }); })();
246
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismOverviewCellComponent, { className: "PrismOverviewCellComponent", filePath: "app/overview/prism-overview-cell.component.ts", lineNumber: 70 }); })();
@@ -0,0 +1,29 @@
1
+ import type { RuntimeComponent } from '../../plugin/plugin.types.js';
2
+ import type { StateFit } from '../pseudo/state-fit.js';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * The Overview of a component with `states`: variants down, Default and every
6
+ * state across, each intersection one `prism-overview-cell`.
7
+ *
8
+ * Whether a state fits a variant is something only the rendered cell knows, so
9
+ * the cells report it (`fitChange`) and this component keeps the answers. The
10
+ * column headers count them. A state that fits no variant at all is almost
11
+ * certainly a selector that matches nothing: its header is marked, and the
12
+ * console warns about it once.
13
+ *
14
+ * The first row and the first column stay in view while the matrix scrolls.
15
+ */
16
+ export declare class PrismOverviewMatrixComponent {
17
+ readonly component: import("@angular/core").InputSignal<RuntimeComponent>;
18
+ protected readonly matrix: import("@angular/core").Signal<import("./overview-matrix.js").OverviewMatrix>;
19
+ /** What each cell answered, by {@link fitKey}. Starts over with every component. */
20
+ private readonly fits;
21
+ /** The column titles with their fit counts (the Default column has none), and whether a state fits no variant. */
22
+ protected readonly headers: import("@angular/core").Signal<import("./overview-matrix.js").ColumnHeader[]>;
23
+ constructor();
24
+ protected onFit(variant: number, state: number | null, fit: StateFit): void;
25
+ private warnAbout;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<PrismOverviewMatrixComponent, never>;
27
+ static ɵcmp: i0.ɵɵComponentDeclaration<PrismOverviewMatrixComponent, "prism-overview-matrix", never, { "component": { "alias": "component"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
28
+ }
29
+ //# sourceMappingURL=prism-overview-matrix.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prism-overview-matrix.component.d.ts","sourceRoot":"","sources":["../../../src/app/overview/prism-overview-matrix.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;;AAWvD;;;;;;;;;;;GAWG;AACH,qBAQa,4BAA4B;IACrC,QAAQ,CAAC,SAAS,wDAAsC;IAExD,SAAS,CAAC,QAAQ,CAAC,MAAM,gFAA6E;IAEtG,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,IAAI,CAGlB;IAEH,kHAAkH;IAClH,SAAS,CAAC,QAAQ,CAAC,OAAO,gFAA6D;;IAWvF,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAK3E,OAAO,CAAC,SAAS;yCA5BR,4BAA4B;2CAA5B,4BAA4B;CA0CxC"}
@@ -0,0 +1,164 @@
1
+ import { ChangeDetectionStrategy, Component, computed, effect, input, linkedSignal, untracked } from '@angular/core';
2
+ import { buildOverviewMatrix, columnHeaders, fitKey, statesFittingNowhere } from './overview-matrix.js';
3
+ import { PrismOverviewCellComponent } from './prism-overview-cell.component.js';
4
+ import * as i0 from "@angular/core";
5
+ const _forTrack0 = ($index, $item) => $item.column.state;
6
+ const _forTrack1 = ($index, $item) => $item.variant;
7
+ const _forTrack2 = ($index, $item) => $item.state;
8
+ function PrismOverviewMatrixComponent_For_5_Conditional_5_Template(rf, ctx) { if (rf & 1) {
9
+ i0.ɵɵelementStart(0, "span", 6);
10
+ i0.ɵɵtext(1);
11
+ i0.ɵɵelementEnd();
12
+ } if (rf & 2) {
13
+ i0.ɵɵadvance();
14
+ i0.ɵɵtextInterpolate(ctx);
15
+ } }
16
+ function PrismOverviewMatrixComponent_For_5_Template(rf, ctx) { if (rf & 1) {
17
+ i0.ɵɵelementStart(0, "div", 3)(1, "span", 4);
18
+ i0.ɵɵtext(2);
19
+ i0.ɵɵelementEnd();
20
+ i0.ɵɵelementStart(3, "span", 5);
21
+ i0.ɵɵtext(4);
22
+ i0.ɵɵelementEnd();
23
+ i0.ɵɵconditionalCreate(5, PrismOverviewMatrixComponent_For_5_Conditional_5_Template, 2, 1, "span", 6);
24
+ i0.ɵɵelementEnd();
25
+ } if (rf & 2) {
26
+ let tmp_14_0;
27
+ const header_r1 = ctx.$implicit;
28
+ i0.ɵɵattribute("data-fits-nowhere", header_r1.fitsNowhere ? "" : null)("title", header_r1.fitsNowhere ? header_r1.column.title + " fits no variant; check its selectors" : null);
29
+ i0.ɵɵadvance(2);
30
+ i0.ɵɵtextInterpolate(header_r1.column.title);
31
+ i0.ɵɵadvance(2);
32
+ i0.ɵɵtextInterpolate(header_r1.column.signature);
33
+ i0.ɵɵadvance();
34
+ i0.ɵɵconditional((tmp_14_0 = header_r1.fit) ? 5 : -1, tmp_14_0);
35
+ } }
36
+ function PrismOverviewMatrixComponent_For_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelementStart(0, "span", 9);
38
+ i0.ɵɵtext(1);
39
+ i0.ɵɵelementEnd();
40
+ } if (rf & 2) {
41
+ i0.ɵɵadvance();
42
+ i0.ɵɵtextInterpolate(ctx);
43
+ } }
44
+ function PrismOverviewMatrixComponent_For_7_Conditional_5_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵelementStart(0, "div", 10)(1, "div", 11);
46
+ i0.ɵɵelement(2, "prism-overview-cell", 12);
47
+ i0.ɵɵelementEnd()();
48
+ } if (rf & 2) {
49
+ const row_r2 = i0.ɵɵnextContext().$implicit;
50
+ const ctx_r2 = i0.ɵɵnextContext();
51
+ i0.ɵɵadvance(2);
52
+ i0.ɵɵproperty("component", ctx_r2.component())("index", row_r2.variant);
53
+ } }
54
+ function PrismOverviewMatrixComponent_For_7_Conditional_6_For_1_Template(rf, ctx) { if (rf & 1) {
55
+ const _r4 = i0.ɵɵgetCurrentView();
56
+ i0.ɵɵelementStart(0, "div", 13)(1, "div", 11)(2, "prism-overview-cell", 14);
57
+ i0.ɵɵlistener("fitChange", function PrismOverviewMatrixComponent_For_7_Conditional_6_For_1_Template_prism_overview_cell_fitChange_2_listener($event) { const column_r5 = i0.ɵɵrestoreView(_r4).$implicit; const row_r2 = i0.ɵɵnextContext(2).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onFit(row_r2.variant, column_r5.state, $event)); });
58
+ i0.ɵɵelementEnd()()();
59
+ } if (rf & 2) {
60
+ const column_r5 = ctx.$implicit;
61
+ const row_r2 = i0.ɵɵnextContext(2).$implicit;
62
+ const ctx_r2 = i0.ɵɵnextContext();
63
+ i0.ɵɵadvance(2);
64
+ i0.ɵɵproperty("component", ctx_r2.component())("index", row_r2.variant)("state", column_r5.state);
65
+ } }
66
+ function PrismOverviewMatrixComponent_For_7_Conditional_6_Template(rf, ctx) { if (rf & 1) {
67
+ i0.ɵɵrepeaterCreate(0, PrismOverviewMatrixComponent_For_7_Conditional_6_For_1_Template, 3, 3, "div", 13, _forTrack2);
68
+ } if (rf & 2) {
69
+ const ctx_r2 = i0.ɵɵnextContext(2);
70
+ i0.ɵɵrepeater(ctx_r2.matrix().columns);
71
+ } }
72
+ function PrismOverviewMatrixComponent_For_7_Template(rf, ctx) { if (rf & 1) {
73
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 7)(2, "span", 8);
74
+ i0.ɵɵtext(3);
75
+ i0.ɵɵelementEnd();
76
+ i0.ɵɵconditionalCreate(4, PrismOverviewMatrixComponent_For_7_Conditional_4_Template, 2, 1, "span", 9);
77
+ i0.ɵɵelementEnd();
78
+ i0.ɵɵconditionalCreate(5, PrismOverviewMatrixComponent_For_7_Conditional_5_Template, 3, 2, "div", 10)(6, PrismOverviewMatrixComponent_For_7_Conditional_6_Template, 2, 0);
79
+ i0.ɵɵelementEnd();
80
+ } if (rf & 2) {
81
+ let tmp_11_0;
82
+ const row_r2 = ctx.$implicit;
83
+ i0.ɵɵadvance(3);
84
+ i0.ɵɵtextInterpolate(row_r2.title);
85
+ i0.ɵɵadvance();
86
+ i0.ɵɵconditional((tmp_11_0 = row_r2.note) ? 4 : -1, tmp_11_0);
87
+ i0.ɵɵadvance();
88
+ i0.ɵɵconditional(row_r2.optedOut ? 5 : 6);
89
+ } }
90
+ /**
91
+ * The states a component has been warned about, by index. Module-level and weak,
92
+ * so leaving the Overview and coming back does not repeat the warning, while a
93
+ * rebuilt component (HMR) has its own.
94
+ */
95
+ const warnedStates = new WeakMap();
96
+ /**
97
+ * The Overview of a component with `states`: variants down, Default and every
98
+ * state across, each intersection one `prism-overview-cell`.
99
+ *
100
+ * Whether a state fits a variant is something only the rendered cell knows, so
101
+ * the cells report it (`fitChange`) and this component keeps the answers. The
102
+ * column headers count them. A state that fits no variant at all is almost
103
+ * certainly a selector that matches nothing: its header is marked, and the
104
+ * console warns about it once.
105
+ *
106
+ * The first row and the first column stay in view while the matrix scrolls.
107
+ */
108
+ export class PrismOverviewMatrixComponent {
109
+ component = input.required(/* @ts-ignore */
110
+ ...(ngDevMode ? [{ debugName: "component" }] : /* istanbul ignore next */ []));
111
+ matrix = computed(() => buildOverviewMatrix(this.component().meta.showcaseConfig), /* @ts-ignore */
112
+ ...(ngDevMode ? [{ debugName: "matrix" }] : /* istanbul ignore next */ []));
113
+ /** What each cell answered, by {@link fitKey}. Starts over with every component. */
114
+ fits = linkedSignal({ ...(ngDevMode ? { debugName: "fits" } : /* istanbul ignore next */ {}), source: this.component,
115
+ computation: () => new Map() });
116
+ /** The column titles with their fit counts (the Default column has none), and whether a state fits no variant. */
117
+ headers = computed(() => columnHeaders(this.fits(), this.matrix()), /* @ts-ignore */
118
+ ...(ngDevMode ? [{ debugName: "headers" }] : /* istanbul ignore next */ []));
119
+ constructor() {
120
+ effect(() => {
121
+ const component = this.component();
122
+ const nowhere = statesFittingNowhere(this.fits(), this.matrix());
123
+ untracked(() => this.warnAbout(component, nowhere));
124
+ });
125
+ }
126
+ onFit(variant, state, fit) {
127
+ if (state === null)
128
+ return;
129
+ this.fits.update((fits) => new Map(fits).set(fitKey(variant, state), fit));
130
+ }
131
+ warnAbout(component, states) {
132
+ const warned = warnedStates.get(component) ?? new Set();
133
+ warnedStates.set(component, warned);
134
+ for (const state of states) {
135
+ if (warned.has(state))
136
+ continue;
137
+ const name = component.meta.showcaseConfig.states?.[state]?.name;
138
+ warned.add(state);
139
+ console.warn(`[ng-prism] State "${name}" of ${component.meta.className} fits no variant; check its selectors.`);
140
+ }
141
+ }
142
+ static ɵfac = function PrismOverviewMatrixComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismOverviewMatrixComponent)(); };
143
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismOverviewMatrixComponent, selectors: [["prism-overview-matrix"]], inputs: { component: [1, "component"] }, decls: 8, vars: 3, consts: [["role", "table", 1, "matrix"], ["role", "row", 1, "matrix__row"], ["role", "columnheader", 1, "matrix__corner"], ["role", "columnheader", 1, "matrix__head"], [1, "matrix__title"], [1, "matrix__signature"], [1, "matrix__fit"], ["role", "rowheader", 1, "matrix__variant"], [1, "matrix__name"], [1, "matrix__note"], ["role", "cell", 1, "matrix__slot", "matrix__slot--span"], ["role", "list", 1, "matrix__list"], ["mode", "matrix", 3, "component", "index"], ["role", "cell", 1, "matrix__slot"], ["mode", "matrix", 3, "fitChange", "component", "index", "state"]], template: function PrismOverviewMatrixComponent_Template(rf, ctx) { if (rf & 1) {
144
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
145
+ i0.ɵɵtext(3, " Variant ");
146
+ i0.ɵɵelementEnd();
147
+ i0.ɵɵrepeaterCreate(4, PrismOverviewMatrixComponent_For_5_Template, 6, 5, "div", 3, _forTrack0);
148
+ i0.ɵɵelementEnd();
149
+ i0.ɵɵrepeaterCreate(6, PrismOverviewMatrixComponent_For_7_Template, 7, 3, "div", 1, _forTrack1);
150
+ i0.ɵɵelementEnd();
151
+ } if (rf & 2) {
152
+ i0.ɵɵstyleProp("--%NS%matrix-columns", ctx.matrix().columns.length);
153
+ i0.ɵɵattribute("aria-label", ctx.component().meta.showcaseConfig.title + " variants by state");
154
+ i0.ɵɵadvance(4);
155
+ i0.ɵɵrepeater(ctx.headers());
156
+ i0.ɵɵadvance(2);
157
+ i0.ɵɵrepeater(ctx.matrix().rows);
158
+ } }, dependencies: [PrismOverviewCellComponent], styles: ["\n\n\n[_nghost-%COMP%] {\n display: flex;\n flex: 1 1 0;\n flex-direction: column;\n min-height: 0;\n}\n\n.matrix[_ngcontent-%COMP%] {\n --%NS%matrix-edge: var(--%NS%prism-border);\n\n display: grid;\n flex: 1 1 0;\n grid-template-columns: minmax(120px, max-content) repeat(var(--%NS%matrix-columns, 1), minmax(160px, 1fr));\n align-content: start;\n min-height: 0;\n overflow: auto;\n}\n\n\n\n.matrix__row[_ngcontent-%COMP%] {\n display: contents;\n}\n\n.matrix__corner[_ngcontent-%COMP%], \n.matrix__head[_ngcontent-%COMP%], \n.matrix__variant[_ngcontent-%COMP%] {\n position: sticky;\n display: flex;\n flex-direction: column;\n gap: var(--%NS%sp-1);\n min-width: 0;\n padding: var(--%NS%sp-3) var(--%NS%sp-4);\n background: var(--%NS%prism-bg-elevated);\n}\n\n.matrix__corner[_ngcontent-%COMP%], \n.matrix__head[_ngcontent-%COMP%] {\n top: 0;\n z-index: 2;\n justify-content: flex-end;\n border-bottom: 1px solid var(--%NS%matrix-edge);\n}\n\n.matrix__corner[_ngcontent-%COMP%], \n.matrix__variant[_ngcontent-%COMP%] {\n left: 0;\n z-index: 1;\n border-right: 1px solid var(--%NS%matrix-edge);\n}\n\n\n.matrix__corner[_ngcontent-%COMP%] {\n z-index: 3;\n font-family: var(--%NS%prism-font-mono);\n font-size: var(--%NS%fs-xs);\n color: var(--%NS%prism-text-muted);\n}\n\n.matrix__variant[_ngcontent-%COMP%] {\n justify-content: center;\n}\n\n.matrix__title[_ngcontent-%COMP%], \n.matrix__name[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: var(--%NS%fs-sm);\n font-weight: 600;\n color: var(--%NS%prism-text);\n white-space: nowrap;\n}\n\n.matrix__signature[_ngcontent-%COMP%], \n.matrix__fit[_ngcontent-%COMP%], \n.matrix__note[_ngcontent-%COMP%] {\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--%NS%prism-font-mono);\n font-size: var(--%NS%fs-xs);\n color: var(--%NS%prism-text-muted);\n white-space: nowrap;\n}\n\n\n.matrix__head[data-fits-nowhere][_ngcontent-%COMP%] {\n box-shadow: inset 0 -2px 0 var(--%NS%prism-mark-attention);\n}\n\n.matrix__head[data-fits-nowhere][_ngcontent-%COMP%] .matrix__fit[_ngcontent-%COMP%] {\n color: var(--%NS%prism-mark-attention);\n}\n\n.matrix__slot[_ngcontent-%COMP%] {\n display: flex;\n min-width: 0;\n padding: var(--%NS%sp-3);\n}\n\n\n\n.matrix__slot--span[_ngcontent-%COMP%] {\n grid-column: 2 / -1;\n}\n\n.matrix__list[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n min-width: 0;\n}\n\n.matrix__list[_ngcontent-%COMP%] > prism-overview-cell[_ngcontent-%COMP%] {\n flex: 1;\n}"] });
159
+ }
160
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismOverviewMatrixComponent, [{
161
+ type: Component,
162
+ args: [{ selector: 'prism-overview-matrix', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [PrismOverviewCellComponent], template: "<div\n class=\"matrix\"\n role=\"table\"\n [attr.aria-label]=\"component().meta.showcaseConfig.title + ' variants by state'\"\n [style.--matrix-columns]=\"matrix().columns.length\">\n <div\n class=\"matrix__row\"\n role=\"row\">\n <div\n class=\"matrix__corner\"\n role=\"columnheader\">\n Variant\n </div>\n @for (header of headers(); track header.column.state) {\n <div\n class=\"matrix__head\"\n role=\"columnheader\"\n [attr.data-fits-nowhere]=\"header.fitsNowhere ? '' : null\"\n [attr.title]=\"header.fitsNowhere ? header.column.title + ' fits no variant; check its selectors' : null\">\n <span class=\"matrix__title\">{{ header.column.title }}</span>\n <span class=\"matrix__signature\">{{ header.column.signature }}</span>\n @if (header.fit; as fit) {\n <span class=\"matrix__fit\">{{ fit }}</span>\n }\n </div>\n }\n </div>\n @for (row of matrix().rows; track row.variant) {\n <div\n class=\"matrix__row\"\n role=\"row\">\n <div\n class=\"matrix__variant\"\n role=\"rowheader\">\n <span class=\"matrix__name\">{{ row.title }}</span>\n @if (row.note; as note) {\n <span class=\"matrix__note\">{{ note }}</span>\n }\n </div>\n @if (row.optedOut) {\n <div\n class=\"matrix__slot matrix__slot--span\"\n role=\"cell\">\n <div\n class=\"matrix__list\"\n role=\"list\">\n <prism-overview-cell\n [component]=\"component()\"\n [index]=\"row.variant\"\n mode=\"matrix\" />\n </div>\n </div>\n } @else {\n @for (column of matrix().columns; track column.state) {\n <div\n class=\"matrix__slot\"\n role=\"cell\">\n <div\n class=\"matrix__list\"\n role=\"list\">\n <prism-overview-cell\n [component]=\"component()\"\n [index]=\"row.variant\"\n [state]=\"column.state\"\n mode=\"matrix\"\n (fitChange)=\"onFit(row.variant, column.state, $event)\" />\n </div>\n </div>\n }\n }\n </div>\n }\n</div>\n", styles: ["/* The host hands its height to the matrix, which scrolls on its own: the\n header row and the variant column stay in view only if the scrolling\n happens inside the grid that holds them. */\n:host {\n display: flex;\n flex: 1 1 0;\n flex-direction: column;\n min-height: 0;\n}\n\n.matrix {\n --matrix-edge: var(--prism-border);\n\n display: grid;\n flex: 1 1 0;\n grid-template-columns: minmax(120px, max-content) repeat(var(--matrix-columns, 1), minmax(160px, 1fr));\n align-content: start;\n min-height: 0;\n overflow: auto;\n}\n\n/* The rows only carry the roles. Their cells are the grid's, so the columns\n line up from the header down. */\n.matrix__row {\n display: contents;\n}\n\n.matrix__corner,\n.matrix__head,\n.matrix__variant {\n position: sticky;\n display: flex;\n flex-direction: column;\n gap: var(--sp-1);\n min-width: 0;\n padding: var(--sp-3) var(--sp-4);\n background: var(--prism-bg-elevated);\n}\n\n.matrix__corner,\n.matrix__head {\n top: 0;\n z-index: 2;\n justify-content: flex-end;\n border-bottom: 1px solid var(--matrix-edge);\n}\n\n.matrix__corner,\n.matrix__variant {\n left: 0;\n z-index: 1;\n border-right: 1px solid var(--matrix-edge);\n}\n\n/* Above the header row and the variant column both, where they cross. */\n.matrix__corner {\n z-index: 3;\n font-family: var(--prism-font-mono);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n}\n\n.matrix__variant {\n justify-content: center;\n}\n\n.matrix__title,\n.matrix__name {\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: var(--fs-sm);\n font-weight: 600;\n color: var(--prism-text);\n white-space: nowrap;\n}\n\n.matrix__signature,\n.matrix__fit,\n.matrix__note {\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: var(--prism-font-mono);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n white-space: nowrap;\n}\n\n/* A state that fits no variant at all: most likely a selector with a typo. */\n.matrix__head[data-fits-nowhere] {\n box-shadow: inset 0 -2px 0 var(--prism-mark-attention);\n}\n\n.matrix__head[data-fits-nowhere] .matrix__fit {\n color: var(--prism-mark-attention);\n}\n\n.matrix__slot {\n display: flex;\n min-width: 0;\n padding: var(--sp-3);\n}\n\n/* A variant that opted out has a single cell, over Default and every state:\n it is not combined with any of them. */\n.matrix__slot--span {\n grid-column: 2 / -1;\n}\n\n.matrix__list {\n display: flex;\n flex: 1;\n min-width: 0;\n}\n\n.matrix__list > prism-overview-cell {\n flex: 1;\n}\n"] }]
163
+ }], () => [], { component: [{ type: i0.Input, args: [{ isSignal: true, alias: "component", required: true }] }] }); })();
164
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismOverviewMatrixComponent, { className: "PrismOverviewMatrixComponent", filePath: "app/overview/prism-overview-matrix.component.ts", lineNumber: 34 }); })();
@@ -6,11 +6,15 @@ import * as i0 from "@angular/core";
6
6
  *
7
7
  * No controls of any kind: columns follow the window, and
8
8
  * everything else a cell shows is what the variant itself declared.
9
+ *
10
+ * A component that declares `states` gets the matrix instead, variants against
11
+ * states. Without states the sheet stays what it was.
9
12
  */
10
13
  export declare class PrismOverviewComponent {
11
14
  /** Input name fixed by `prism-view-panel-host`, which feeds every view panel. */
12
15
  readonly activeComponent: import("@angular/core").InputSignal<RuntimeComponent | null>;
13
16
  protected readonly variants: import("@angular/core").Signal<import("../../index.js").Variant<unknown>[]>;
17
+ protected readonly hasStates: import("@angular/core").Signal<boolean>;
14
18
  static ɵfac: i0.ɵɵFactoryDeclaration<PrismOverviewComponent, never>;
15
19
  static ɵcmp: i0.ɵɵComponentDeclaration<PrismOverviewComponent, "prism-overview", never, { "activeComponent": { "alias": "activeComponent"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
16
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prism-overview.component.d.ts","sourceRoot":"","sources":["../../../src/app/overview/prism-overview.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;;AAGrE;;;;;;GAMG;AACH,qBAQa,sBAAsB;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,eAAe,+DAAwC;IAEhE,SAAS,CAAC,QAAQ,CAAC,QAAQ,8EAA8E;yCAJhG,sBAAsB;2CAAtB,sBAAsB;CAKlC"}
1
+ {"version":3,"file":"prism-overview.component.d.ts","sourceRoot":"","sources":["../../../src/app/overview/prism-overview.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;;AAIrE;;;;;;;;;GASG;AACH,qBAYa,sBAAsB;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,eAAe,+DAAwC;IAEhE,SAAS,CAAC,QAAQ,CAAC,QAAQ,8EAA8E;IAEzG,SAAS,CAAC,QAAQ,CAAC,SAAS,0CAAyF;yCAN5G,sBAAsB;2CAAtB,sBAAsB;CAOlC"}
@@ -1,28 +1,44 @@
1
1
  import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
2
2
  import { PrismOverviewCellComponent } from './prism-overview-cell.component.js';
3
+ import { PrismOverviewMatrixComponent } from './prism-overview-matrix.component.js';
3
4
  import * as i0 from "@angular/core";
4
- function PrismOverviewComponent_Conditional_0_For_2_Template(rf, ctx) { if (rf & 1) {
5
- i0.ɵɵelement(0, "prism-overview-cell", 1);
5
+ function PrismOverviewComponent_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
6
+ i0.ɵɵelement(0, "prism-overview-matrix", 0);
6
7
  } if (rf & 2) {
7
- const $index_r1 = ctx.$index;
8
- const component_r2 = i0.ɵɵnextContext();
9
- i0.ɵɵproperty("component", component_r2)("index", $index_r1);
8
+ const component_r1 = i0.ɵɵnextContext();
9
+ i0.ɵɵproperty("component", component_r1);
10
10
  } }
11
- function PrismOverviewComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
12
- i0.ɵɵelementStart(0, "div", 0);
13
- i0.ɵɵrepeaterCreate(1, PrismOverviewComponent_Conditional_0_For_2_Template, 1, 2, "prism-overview-cell", 1, i0.ɵɵrepeaterTrackByIndex);
11
+ function PrismOverviewComponent_Conditional_0_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
12
+ i0.ɵɵelement(0, "prism-overview-cell", 2);
13
+ } if (rf & 2) {
14
+ const $index_r2 = ctx.$index;
15
+ const component_r1 = i0.ɵɵnextContext(2);
16
+ i0.ɵɵproperty("component", component_r1)("index", $index_r2);
17
+ } }
18
+ function PrismOverviewComponent_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelementStart(0, "div", 1);
20
+ i0.ɵɵrepeaterCreate(1, PrismOverviewComponent_Conditional_0_Conditional_1_For_2_Template, 1, 2, "prism-overview-cell", 2, i0.ɵɵrepeaterTrackByIndex);
14
21
  i0.ɵɵelementEnd();
15
22
  } if (rf & 2) {
16
- const ctx_r2 = i0.ɵɵnextContext();
23
+ const ctx_r2 = i0.ɵɵnextContext(2);
17
24
  i0.ɵɵadvance();
18
25
  i0.ɵɵrepeater(ctx_r2.variants());
19
26
  } }
27
+ function PrismOverviewComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
28
+ i0.ɵɵconditionalCreate(0, PrismOverviewComponent_Conditional_0_Conditional_0_Template, 1, 1, "prism-overview-matrix", 0)(1, PrismOverviewComponent_Conditional_0_Conditional_1_Template, 3, 0, "div", 1);
29
+ } if (rf & 2) {
30
+ const ctx_r2 = i0.ɵɵnextContext();
31
+ i0.ɵɵconditional(ctx_r2.hasStates() ? 0 : 1);
32
+ } }
20
33
  /**
21
34
  * All variants of one component at once: a contact sheet rather than a
22
35
  * viewfinder.
23
36
  *
24
37
  * No controls of any kind: columns follow the window, and
25
38
  * everything else a cell shows is what the variant itself declared.
39
+ *
40
+ * A component that declares `states` gets the matrix instead, variants against
41
+ * states. Without states the sheet stays what it was.
26
42
  */
27
43
  export class PrismOverviewComponent {
28
44
  /** Input name fixed by `prism-view-panel-host`, which feeds every view panel. */
@@ -30,16 +46,23 @@ export class PrismOverviewComponent {
30
46
  ...(ngDevMode ? [{ debugName: "activeComponent" }] : /* istanbul ignore next */ []));
31
47
  variants = computed(() => this.activeComponent()?.meta.showcaseConfig.variants ?? [], /* @ts-ignore */
32
48
  ...(ngDevMode ? [{ debugName: "variants" }] : /* istanbul ignore next */ []));
49
+ hasStates = computed(() => (this.activeComponent()?.meta.showcaseConfig.states?.length ?? 0) > 0, /* @ts-ignore */
50
+ ...(ngDevMode ? [{ debugName: "hasStates" }] : /* istanbul ignore next */ []));
33
51
  static ɵfac = function PrismOverviewComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismOverviewComponent)(); };
34
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismOverviewComponent, selectors: [["prism-overview"]], inputs: { activeComponent: [1, "activeComponent"] }, decls: 1, vars: 1, consts: [["role", "list", 1, "prism-overview"], [3, "component", "index"]], template: function PrismOverviewComponent_Template(rf, ctx) { if (rf & 1) {
35
- i0.ɵɵconditionalCreate(0, PrismOverviewComponent_Conditional_0_Template, 3, 0, "div", 0);
52
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismOverviewComponent, selectors: [["prism-overview"]], hostVars: 1, hostBindings: function PrismOverviewComponent_HostBindings(rf, ctx) { if (rf & 2) {
53
+ i0.ɵɵattribute("data-matrix", ctx.hasStates() ? "" : null);
54
+ } }, inputs: { activeComponent: [1, "activeComponent"] }, decls: 1, vars: 1, consts: [[3, "component"], ["role", "list", 1, "prism-overview"], [3, "component", "index"]], template: function PrismOverviewComponent_Template(rf, ctx) { if (rf & 1) {
55
+ i0.ɵɵconditionalCreate(0, PrismOverviewComponent_Conditional_0_Template, 2, 1);
36
56
  } if (rf & 2) {
37
57
  let tmp_0_0;
38
58
  i0.ɵɵconditional((tmp_0_0 = ctx.activeComponent()) ? 0 : -1, tmp_0_0);
39
- } }, dependencies: [PrismOverviewCellComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.prism-overview[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: var(--%NS%sp-4);\n align-content: start;\n padding: var(--%NS%sp-6);\n}"] });
59
+ } }, dependencies: [PrismOverviewCellComponent, PrismOverviewMatrixComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.prism-overview[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: var(--%NS%sp-4);\n align-content: start;\n padding: var(--%NS%sp-6);\n}\n\n\n\n\n[data-matrix][_nghost-%COMP%] {\n display: flex;\n flex: 1 1 0;\n flex-direction: column;\n min-height: 0;\n}"] });
40
60
  }
41
61
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismOverviewComponent, [{
42
62
  type: Component,
43
- args: [{ selector: 'prism-overview', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [PrismOverviewCellComponent], template: "@if (activeComponent(); as component) {\n <div\n class=\"prism-overview\"\n role=\"list\">\n @for (_ of variants(); track $index) {\n <prism-overview-cell\n [component]=\"component\"\n [index]=\"$index\" />\n }\n </div>\n}\n", styles: [":host {\n display: block;\n}\n\n.prism-overview {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: var(--sp-4);\n align-content: start;\n padding: var(--sp-6);\n}\n"] }]
63
+ args: [{ selector: 'prism-overview', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [PrismOverviewCellComponent, PrismOverviewMatrixComponent], host: {
64
+ // Hands the panel's height down to the matrix, which scrolls on its own.
65
+ '[attr.data-matrix]': "hasStates() ? '' : null"
66
+ }, template: "@if (activeComponent(); as component) {\n @if (hasStates()) {\n <prism-overview-matrix [component]=\"component\" />\n } @else {\n <div\n class=\"prism-overview\"\n role=\"list\">\n @for (_ of variants(); track $index) {\n <prism-overview-cell\n [component]=\"component\"\n [index]=\"$index\" />\n }\n </div>\n }\n}\n", styles: [":host {\n display: block;\n}\n\n.prism-overview {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: var(--sp-4);\n align-content: start;\n padding: var(--sp-6);\n}\n\n/* The panel host is a column flex box that scrolls. The matrix scrolls inside\n itself instead, so both its scrollbars sit at the edge of the panel and its\n header row and variant column stay in view. */\n:host([data-matrix]) {\n display: flex;\n flex: 1 1 0;\n flex-direction: column;\n min-height: 0;\n}\n"] }]
44
67
  }], null, { activeComponent: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeComponent", required: false }] }] }); })();
45
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismOverviewComponent, { className: "PrismOverviewComponent", filePath: "app/overview/prism-overview.component.ts", lineNumber: 20 }); })();
68
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismOverviewComponent, { className: "PrismOverviewComponent", filePath: "app/overview/prism-overview.component.ts", lineNumber: 28 }); })();