@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
@@ -10,14 +10,35 @@ function PrismHeadInfoComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
10
10
  i0.ɵɵadvance();
11
11
  i0.ɵɵtextInterpolate(ctx_r0.description());
12
12
  } }
13
+ function PrismHeadInfoComponent_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
14
+ i0.ɵɵtext(0);
15
+ } if (rf & 2) {
16
+ const ctx_r0 = i0.ɵɵnextContext(2);
17
+ i0.ɵɵtextInterpolate2(" ", ctx_r0.variantCount(), " ", ctx_r0.variantCount() === 1 ? "variant" : "variants", " ");
18
+ } }
19
+ function PrismHeadInfoComponent_Conditional_6_Conditional_2_Template(rf, ctx) { if (rf & 1) {
20
+ i0.ɵɵtext(0, " \u00B7 ");
21
+ } }
22
+ function PrismHeadInfoComponent_Conditional_6_Conditional_3_Template(rf, ctx) { if (rf & 1) {
23
+ i0.ɵɵtext(0);
24
+ } if (rf & 2) {
25
+ const ctx_r0 = i0.ɵɵnextContext(2);
26
+ i0.ɵɵtextInterpolate2(" ", ctx_r0.stateCount(), " ", ctx_r0.stateCount() === 1 ? "state" : "states", " ");
27
+ } }
13
28
  function PrismHeadInfoComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
14
29
  i0.ɵɵelementStart(0, "p", 5);
15
- i0.ɵɵtext(1);
30
+ i0.ɵɵconditionalCreate(1, PrismHeadInfoComponent_Conditional_6_Conditional_1_Template, 1, 2);
31
+ i0.ɵɵconditionalCreate(2, PrismHeadInfoComponent_Conditional_6_Conditional_2_Template, 1, 0);
32
+ i0.ɵɵconditionalCreate(3, PrismHeadInfoComponent_Conditional_6_Conditional_3_Template, 1, 2);
16
33
  i0.ɵɵelementEnd();
17
34
  } if (rf & 2) {
18
35
  const ctx_r0 = i0.ɵɵnextContext();
19
36
  i0.ɵɵadvance();
20
- i0.ɵɵtextInterpolate2(" ", ctx_r0.variantCount(), " ", ctx_r0.variantCount() === 1 ? "variant" : "variants", " ");
37
+ i0.ɵɵconditional(ctx_r0.variantCount() > 0 ? 1 : -1);
38
+ i0.ɵɵadvance();
39
+ i0.ɵɵconditional(ctx_r0.variantCount() > 0 && ctx_r0.stateCount() > 0 ? 2 : -1);
40
+ i0.ɵɵadvance();
41
+ i0.ɵɵconditional(ctx_r0.stateCount() > 0 ? 3 : -1);
21
42
  } }
22
43
  function PrismHeadInfoComponent_Conditional_7_For_2_Template(rf, ctx) { if (rf & 1) {
23
44
  i0.ɵɵelementStart(0, "span", 7);
@@ -59,8 +80,10 @@ export class PrismHeadInfoComponent {
59
80
  ...(ngDevMode ? [{ debugName: "tags" }] : /* istanbul ignore next */ []));
60
81
  variantCount = input(0, /* @ts-ignore */
61
82
  ...(ngDevMode ? [{ debugName: "variantCount" }] : /* istanbul ignore next */ []));
83
+ stateCount = input(0, /* @ts-ignore */
84
+ ...(ngDevMode ? [{ debugName: "stateCount" }] : /* istanbul ignore next */ []));
62
85
  static ɵfac = function PrismHeadInfoComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PrismHeadInfoComponent)(); };
63
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismHeadInfoComponent, selectors: [["prism-head-info"]], inputs: { selector: [1, "selector"], description: [1, "description"], tags: [1, "tags"], variantCount: [1, "variantCount"] }, decls: 8, vars: 5, consts: [["type", "button", "popovertarget", "prism-head-info", "title", "Component details", "aria-label", "Component details", 1, "info-btn"], ["name", "info", 3, "size"], ["popover", "", "id", "prism-head-info", "role", "dialog", "aria-label", "Component details", 1, "info-card"], [1, "info-card__selector"], [1, "info-card__desc"], [1, "info-card__meta"], [1, "info-card__tags"], [1, "info-card__tag"]], template: function PrismHeadInfoComponent_Template(rf, ctx) { if (rf & 1) {
86
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PrismHeadInfoComponent, selectors: [["prism-head-info"]], inputs: { selector: [1, "selector"], description: [1, "description"], tags: [1, "tags"], variantCount: [1, "variantCount"], stateCount: [1, "stateCount"] }, decls: 8, vars: 5, consts: [["type", "button", "popovertarget", "prism-head-info", "title", "Component details", "aria-label", "Component details", 1, "info-btn"], ["name", "info", 3, "size"], ["popover", "", "id", "prism-head-info", "role", "dialog", "aria-label", "Component details", 1, "info-card"], [1, "info-card__selector"], [1, "info-card__desc"], [1, "info-card__meta"], [1, "info-card__tags"], [1, "info-card__tag"]], template: function PrismHeadInfoComponent_Template(rf, ctx) { if (rf & 1) {
64
87
  i0.ɵɵelementStart(0, "button", 0);
65
88
  i0.ɵɵelement(1, "prism-icon", 1);
66
89
  i0.ɵɵelementEnd();
@@ -68,7 +91,7 @@ export class PrismHeadInfoComponent {
68
91
  i0.ɵɵtext(4);
69
92
  i0.ɵɵelementEnd();
70
93
  i0.ɵɵconditionalCreate(5, PrismHeadInfoComponent_Conditional_5_Template, 2, 1, "p", 4);
71
- i0.ɵɵconditionalCreate(6, PrismHeadInfoComponent_Conditional_6_Template, 2, 2, "p", 5);
94
+ i0.ɵɵconditionalCreate(6, PrismHeadInfoComponent_Conditional_6_Template, 4, 3, "p", 5);
72
95
  i0.ɵɵconditionalCreate(7, PrismHeadInfoComponent_Conditional_7_Template, 3, 0, "div", 6);
73
96
  i0.ɵɵelementEnd();
74
97
  } if (rf & 2) {
@@ -79,13 +102,13 @@ export class PrismHeadInfoComponent {
79
102
  i0.ɵɵadvance();
80
103
  i0.ɵɵconditional(ctx.description() ? 5 : -1);
81
104
  i0.ɵɵadvance();
82
- i0.ɵɵconditional(ctx.variantCount() > 0 ? 6 : -1);
105
+ i0.ɵɵconditional(ctx.variantCount() > 0 || ctx.stateCount() > 0 ? 6 : -1);
83
106
  i0.ɵɵadvance();
84
107
  i0.ɵɵconditional(ctx.tags().length ? 7 : -1);
85
108
  } }, dependencies: [PrismIconComponent], styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n}\n\n.info-btn[_ngcontent-%COMP%] {\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n padding: 0;\n anchor-name: --prism-head-info;\n color: var(--%NS%prism-text-ghost);\n cursor: pointer;\n background: transparent;\n border: 0;\n border-radius: var(--%NS%radius-xs);\n}\n\n.info-btn[_ngcontent-%COMP%]:hover {\n color: var(--%NS%prism-text-2);\n}\n\n.info-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--%NS%prism-primary);\n outline-offset: 1px;\n}\n\n.info-card[_ngcontent-%COMP%] {\n inset: auto;\n width: 320px;\n max-width: calc(100vw - var(--%NS%sp-6));\n padding: var(--%NS%sp-4);\n margin: 0;\n position-area: block-end span-inline-end;\n position-anchor: --prism-head-info;\n position-try-fallbacks: flip-block, flip-inline;\n color: var(--%NS%prism-text-2);\n background: var(--%NS%prism-bg-elevated);\n border: 1px solid var(--%NS%prism-border-strong);\n border-radius: var(--%NS%radius-md);\n box-shadow: 0 8px 28px -10px rgb(0 0 0 / 45%);\n}\n\n.info-card__selector[_ngcontent-%COMP%] {\n display: block;\n font-family: var(--%NS%font-mono);\n font-size: var(--%NS%fs-md);\n color: var(--%NS%prism-primary);\n user-select: all;\n}\n\n.info-card__desc[_ngcontent-%COMP%] {\n margin: var(--%NS%sp-3) 0 0;\n font-size: var(--%NS%fs-lg);\n line-height: 1.55;\n}\n\n\n\n\n.info-card__meta[_ngcontent-%COMP%] {\n margin: var(--%NS%sp-3) 0 0;\n font-size: var(--%NS%fs-md);\n color: var(--%NS%prism-text-muted);\n}\n\n.info-card__tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: var(--%NS%sp-2);\n margin-top: var(--%NS%sp-4);\n}\n\n.info-card__tag[_ngcontent-%COMP%] {\n padding: 1px var(--%NS%sp-3);\n font-size: var(--%NS%fs-xs);\n color: var(--%NS%prism-text-muted);\n border: 1px solid var(--%NS%prism-border);\n border-radius: var(--%NS%radius-xs);\n}"] });
86
109
  }
87
110
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PrismHeadInfoComponent, [{
88
111
  type: Component,
89
- args: [{ selector: 'prism-head-info', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [PrismIconComponent], template: "<button\n class=\"info-btn\"\n type=\"button\"\n popovertarget=\"prism-head-info\"\n title=\"Component details\"\n aria-label=\"Component details\">\n <prism-icon\n name=\"info\"\n [size]=\"13\" />\n</button>\n\n<div\n popover\n id=\"prism-head-info\"\n class=\"info-card\"\n role=\"dialog\"\n aria-label=\"Component details\">\n <code class=\"info-card__selector\">&lt;{{ selector() }}&gt;</code>\n @if (description()) {\n <p class=\"info-card__desc\">{{ description() }}</p>\n }\n @if (variantCount() > 0) {\n <p class=\"info-card__meta\"> {{ variantCount() }} {{ variantCount() === 1 ? 'variant' : 'variants' }} </p>\n }\n @if (tags().length) {\n <div class=\"info-card__tags\">\n @for (tag of tags(); track tag) {\n <span class=\"info-card__tag\">{{ tag }}</span>\n }\n </div>\n }\n</div>\n", styles: [":host {\n display: inline-flex;\n}\n\n.info-btn {\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n padding: 0;\n anchor-name: --prism-head-info;\n color: var(--prism-text-ghost);\n cursor: pointer;\n background: transparent;\n border: 0;\n border-radius: var(--radius-xs);\n}\n\n.info-btn:hover {\n color: var(--prism-text-2);\n}\n\n.info-btn:focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 1px;\n}\n\n.info-card {\n inset: auto;\n width: 320px;\n max-width: calc(100vw - var(--sp-6));\n padding: var(--sp-4);\n margin: 0;\n position-area: block-end span-inline-end;\n position-anchor: --prism-head-info;\n position-try-fallbacks: flip-block, flip-inline;\n color: var(--prism-text-2);\n background: var(--prism-bg-elevated);\n border: 1px solid var(--prism-border-strong);\n border-radius: var(--radius-md);\n box-shadow: 0 8px 28px -10px rgb(0 0 0 / 45%);\n}\n\n.info-card__selector {\n display: block;\n font-family: var(--font-mono);\n font-size: var(--fs-md);\n color: var(--prism-primary);\n user-select: all;\n}\n\n.info-card__desc {\n margin: var(--sp-3) 0 0;\n font-size: var(--fs-lg);\n line-height: 1.55;\n}\n\n/* A plain fact about the component, not a measurement. It sits here with\n the selector and the tags rather than in the gauge, whose numbers all\n answer \"did this pass its threshold\". A count cannot. */\n.info-card__meta {\n margin: var(--sp-3) 0 0;\n font-size: var(--fs-md);\n color: var(--prism-text-muted);\n}\n\n.info-card__tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--sp-2);\n margin-top: var(--sp-4);\n}\n\n.info-card__tag {\n padding: 1px var(--sp-3);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n border: 1px solid var(--prism-border);\n border-radius: var(--radius-xs);\n}\n"] }]
90
- }], null, { selector: [{ type: i0.Input, args: [{ isSignal: true, alias: "selector", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], tags: [{ type: i0.Input, args: [{ isSignal: true, alias: "tags", required: false }] }], variantCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "variantCount", required: false }] }] }); })();
112
+ args: [{ selector: 'prism-head-info', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [PrismIconComponent], template: "<button\n class=\"info-btn\"\n type=\"button\"\n popovertarget=\"prism-head-info\"\n title=\"Component details\"\n aria-label=\"Component details\">\n <prism-icon\n name=\"info\"\n [size]=\"13\" />\n</button>\n\n<div\n popover\n id=\"prism-head-info\"\n class=\"info-card\"\n role=\"dialog\"\n aria-label=\"Component details\">\n <code class=\"info-card__selector\">&lt;{{ selector() }}&gt;</code>\n @if (description()) {\n <p class=\"info-card__desc\">{{ description() }}</p>\n }\n @if (variantCount() > 0 || stateCount() > 0) {\n <p class=\"info-card__meta\">\n @if (variantCount() > 0) {\n {{ variantCount() }} {{ variantCount() === 1 ? 'variant' : 'variants' }}\n }\n @if (variantCount() > 0 && stateCount() > 0) {\n &middot;\n }\n @if (stateCount() > 0) {\n {{ stateCount() }} {{ stateCount() === 1 ? 'state' : 'states' }}\n }\n </p>\n }\n @if (tags().length) {\n <div class=\"info-card__tags\">\n @for (tag of tags(); track tag) {\n <span class=\"info-card__tag\">{{ tag }}</span>\n }\n </div>\n }\n</div>\n", styles: [":host {\n display: inline-flex;\n}\n\n.info-btn {\n display: grid;\n place-items: center;\n width: 20px;\n height: 20px;\n padding: 0;\n anchor-name: --prism-head-info;\n color: var(--prism-text-ghost);\n cursor: pointer;\n background: transparent;\n border: 0;\n border-radius: var(--radius-xs);\n}\n\n.info-btn:hover {\n color: var(--prism-text-2);\n}\n\n.info-btn:focus-visible {\n outline: 2px solid var(--prism-primary);\n outline-offset: 1px;\n}\n\n.info-card {\n inset: auto;\n width: 320px;\n max-width: calc(100vw - var(--sp-6));\n padding: var(--sp-4);\n margin: 0;\n position-area: block-end span-inline-end;\n position-anchor: --prism-head-info;\n position-try-fallbacks: flip-block, flip-inline;\n color: var(--prism-text-2);\n background: var(--prism-bg-elevated);\n border: 1px solid var(--prism-border-strong);\n border-radius: var(--radius-md);\n box-shadow: 0 8px 28px -10px rgb(0 0 0 / 45%);\n}\n\n.info-card__selector {\n display: block;\n font-family: var(--font-mono);\n font-size: var(--fs-md);\n color: var(--prism-primary);\n user-select: all;\n}\n\n.info-card__desc {\n margin: var(--sp-3) 0 0;\n font-size: var(--fs-lg);\n line-height: 1.55;\n}\n\n/* A plain fact about the component, not a measurement. It sits here with\n the selector and the tags rather than in the gauge, whose numbers all\n answer \"did this pass its threshold\". A count cannot. */\n.info-card__meta {\n margin: var(--sp-3) 0 0;\n font-size: var(--fs-md);\n color: var(--prism-text-muted);\n}\n\n.info-card__tags {\n display: flex;\n flex-wrap: wrap;\n gap: var(--sp-2);\n margin-top: var(--sp-4);\n}\n\n.info-card__tag {\n padding: 1px var(--sp-3);\n font-size: var(--fs-xs);\n color: var(--prism-text-muted);\n border: 1px solid var(--prism-border);\n border-radius: var(--radius-xs);\n}\n"] }]
113
+ }], null, { selector: [{ type: i0.Input, args: [{ isSignal: true, alias: "selector", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], tags: [{ type: i0.Input, args: [{ isSignal: true, alias: "tags", required: false }] }], variantCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "variantCount", required: false }] }], stateCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "stateCount", required: false }] }] }); })();
91
114
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PrismHeadInfoComponent, { className: "PrismHeadInfoComponent", filePath: "app/component-head/prism-head-info.component.ts", lineNumber: 25 }); })();
@@ -5,7 +5,7 @@
5
5
  * rendered inside a host component to be exercised, and this package's specs
6
6
  * run under jsdom against SWC-compiled sources, where JIT cannot instantiate
7
7
  * one. Extracted, the maths is ordinary and testable. It is the same reason
8
- * `known-inputs.ts` and `overlay-resolver.ts` sit beside their components.
8
+ * `input-bindings.ts` and `overlay-resolver.ts` sit beside their components.
9
9
  */
10
10
  /**
11
11
  * Where a drag lands.
@@ -5,7 +5,7 @@
5
5
  * rendered inside a host component to be exercised, and this package's specs
6
6
  * run under jsdom against SWC-compiled sources, where JIT cannot instantiate
7
7
  * one. Extracted, the maths is ordinary and testable. It is the same reason
8
- * `known-inputs.ts` and `overlay-resolver.ts` sit beside their components.
8
+ * `input-bindings.ts` and `overlay-resolver.ts` sit beside their components.
9
9
  */
10
10
  /**
11
11
  * Where a drag lands.
@@ -6,8 +6,8 @@ export declare function serializableMeta(meta: Record<string, unknown> | undefin
6
6
  *
7
7
  * It is not the runtime manifest: no Angular class references, no
8
8
  * providers, no scanned input/output metadata. It carries what an external tool
9
- * needs to enumerate and address variants, plus the `@Showcase` metadata that
10
- * lets a tool decide how to treat one.
9
+ * needs to enumerate and address variants and component-level states, plus the
10
+ * `@Showcase` metadata that lets a tool decide how to treat one.
11
11
  */
12
12
  export declare function buildDiscoveryManifest(manifest: RuntimeManifest): DiscoveryManifest;
13
13
  //# sourceMappingURL=discovery-manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-manifest.d.ts","sourceRoot":"","sources":["../../src/app/discovery-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,iBAAiB,EAAoB,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAuD1H,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAM/G;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,CAsCnF"}
1
+ {"version":3,"file":"discovery-manifest.d.ts","sourceRoot":"","sources":["../../src/app/discovery-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,iBAAiB,EAAoC,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAyD1I,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAM/G;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,iBAAiB,CAoDnF"}
@@ -1,4 +1,5 @@
1
1
  import { resolveVariantBg } from '../shared/variant-bg.js';
2
+ import { forcesAnyState } from './pseudo/pseudo-targets.js';
2
3
  /**
3
4
  * External tooling reads `__PRISM_MANIFEST__` through a structured-clone bridge
4
5
  * (Playwright's `page.evaluate()`, `postMessage`, devtools). `ShowcaseConfig.meta`
@@ -59,8 +60,8 @@ export function serializableMeta(meta) {
59
60
  *
60
61
  * It is not the runtime manifest: no Angular class references, no
61
62
  * providers, no scanned input/output metadata. It carries what an external tool
62
- * needs to enumerate and address variants, plus the `@Showcase` metadata that
63
- * lets a tool decide how to treat one.
63
+ * needs to enumerate and address variants and component-level states, plus the
64
+ * `@Showcase` metadata that lets a tool decide how to treat one.
64
65
  */
65
66
  export function buildDiscoveryManifest(manifest) {
66
67
  return {
@@ -75,8 +76,15 @@ export function buildDiscoveryManifest(manifest) {
75
76
  const variants = declared.length
76
77
  ? declared.map((variant, index) => {
77
78
  const meta = serializableMeta(variant.meta);
78
- const bg = resolveVariantBg(showcaseConfig, index);
79
- return meta ? { name: variant.name, index, bg, meta } : { name: variant.name, index, bg };
79
+ const pseudo = forcesAnyState(variant.pseudo) ? serializableMeta(variant.pseudo) : undefined;
80
+ const discovered = { name: variant.name, index, bg: resolveVariantBg(showcaseConfig, index) };
81
+ if (meta)
82
+ discovered.meta = meta;
83
+ if (pseudo)
84
+ discovered.pseudo = pseudo;
85
+ if (variant.states === false)
86
+ discovered.states = false;
87
+ return discovered;
80
88
  })
81
89
  : [
82
90
  {
@@ -85,12 +93,22 @@ export function buildDiscoveryManifest(manifest) {
85
93
  bg: resolveVariantBg(showcaseConfig, 0)
86
94
  }
87
95
  ];
96
+ // Every slot is listed, the empty ones too: the scanner keeps a state it
97
+ // cannot use as `{ name, pseudo: {} }` so the position in the array stays
98
+ // the `?state=` value of the states behind it.
99
+ const states = (showcaseConfig.states ?? []).map((state, index) => ({
100
+ name: state.name,
101
+ index,
102
+ pseudo: (serializableMeta(state.pseudo) ?? {})
103
+ }));
88
104
  const meta = serializableMeta(showcaseConfig.meta);
89
105
  const discovered = {
90
106
  className,
91
107
  title: showcaseConfig.title,
92
108
  variants
93
109
  };
110
+ if (states.length)
111
+ discovered.states = states;
94
112
  if (meta)
95
113
  discovered.meta = meta;
96
114
  return discovered;
@@ -0,0 +1,11 @@
1
+ import type { PrismPanelService } from '../services/prism-panel.service.js';
2
+ import type { PrismRendererService } from '../services/prism-renderer.service.js';
3
+ /**
4
+ * Shows one Overview cell's exact combination in the Playground: the variant,
5
+ * the component state (`null` for none), and the Playground view itself.
6
+ *
7
+ * The view switches last, so the Playground never paints the variant it showed
8
+ * before for a frame.
9
+ */
10
+ export declare function openInPlayground(renderer: Pick<PrismRendererService, 'selectVariant' | 'selectState'>, panels: Pick<PrismPanelService, 'activeViewId'>, variantIndex: number, stateIndex: number | null): void;
11
+ //# sourceMappingURL=open-in-playground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-in-playground.d.ts","sourceRoot":"","sources":["../../../src/app/overview/open-in-playground.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC5B,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,GAAG,aAAa,CAAC,EACrE,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,EAC/C,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GAAG,IAAI,GAC1B,IAAI,CAIN"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shows one Overview cell's exact combination in the Playground: the variant,
3
+ * the component state (`null` for none), and the Playground view itself.
4
+ *
5
+ * The view switches last, so the Playground never paints the variant it showed
6
+ * before for a frame.
7
+ */
8
+ export function openInPlayground(renderer, panels, variantIndex, stateIndex) {
9
+ renderer.selectVariant(variantIndex);
10
+ renderer.selectState(stateIndex);
11
+ panels.activeViewId.set('renderer');
12
+ }
@@ -0,0 +1,79 @@
1
+ import type { ShowcaseConfig } from '../../decorator/showcase.types.js';
2
+ import { type ForcedPseudoStates } from '../../shared/pseudo-state.type.js';
3
+ import { type StateFit } from '../pseudo/state-fit.js';
4
+ /** `state` is the position in `ShowcaseConfig.states`, `null` for the Default column. */
5
+ export interface MatrixColumn {
6
+ state: number | null;
7
+ title: string;
8
+ signature: string;
9
+ /** Whether the column's state forces anything. `false` for Default and for a slot the scanner could not use. */
10
+ forcesState: boolean;
11
+ }
12
+ /** `variant` is the position in `ShowcaseConfig.variants`; the implicit Default row of a variant-less component is 0. */
13
+ export interface MatrixRow {
14
+ variant: number;
15
+ title: string;
16
+ note: string | null;
17
+ optedOut: boolean;
18
+ }
19
+ export interface OverviewMatrix {
20
+ columns: MatrixColumn[];
21
+ rows: MatrixRow[];
22
+ }
23
+ /**
24
+ * The Overview as a matrix: a row per variant, a column for Default and one
25
+ * per component state.
26
+ *
27
+ * A component without variants still renders, as a variant of its own, so it
28
+ * gets one implicit `Default` row, like the canvas. A variant that opts out
29
+ * with `states: false` keeps its row but takes part in no state column.
30
+ */
31
+ export declare function buildOverviewMatrix(config: ShowcaseConfig): OverviewMatrix;
32
+ /**
33
+ * What a state forces, in a line: `hover + active → .btn`.
34
+ *
35
+ * The pseudo-classes come in {@link PSEUDO_STATES} order, grouped by the target
36
+ * they share. Classes with different targets make one group each, joined with
37
+ * `; ` (`hover → .pill; focus-visible → .pill__close`). A slot that names no
38
+ * target forces nothing, as the marker sees it.
39
+ */
40
+ export declare function pseudoSignature(pseudo: ForcedPseudoStates): string;
41
+ /** `fits 2 of 5`: the variants a state fits, of those it is combined with. */
42
+ export declare function fitLabel(fits: number, eligible: number): string;
43
+ /** Key of one cell's result in the map the matrix collects from the cells. */
44
+ export declare function fitKey(variant: number, state: number): string;
45
+ export interface ColumnFit {
46
+ /** Cells of the column whose state fits. */
47
+ fits: number;
48
+ /** Cells the column has: the rows that did not opt out. */
49
+ eligible: number;
50
+ /** Whether every one of those cells has answered. */
51
+ complete: boolean;
52
+ }
53
+ /** The fits of one state column, as far as the cells have answered. */
54
+ export declare function columnFit(results: ReadonlyMap<string, StateFit>, matrix: OverviewMatrix, state: number): ColumnFit;
55
+ /**
56
+ * The states whose column is complete and fits nowhere, by index: almost
57
+ * certainly a selector with a typo.
58
+ *
59
+ * A column that is still waiting for a cell, or whose cell failed to render and
60
+ * so never answers, is not complete: a state is only called misplaced once every
61
+ * cell has had its say. A state no variant is combined with has no cell to
62
+ * judge it, so it is not reported either. Nor is a state that forces nothing (a
63
+ * slot the scanner could not use): it fits nowhere by construction, has no
64
+ * selector to check, and the scanner has reported it already.
65
+ *
66
+ * Stateless: the caller keeps track of what it already reported.
67
+ */
68
+ export declare function statesFittingNowhere(results: ReadonlyMap<string, StateFit>, matrix: OverviewMatrix): number[];
69
+ /** One column header of the matrix. */
70
+ export interface ColumnHeader {
71
+ column: MatrixColumn;
72
+ /** `fits x of y`, `null` for the Default column. */
73
+ fit: string | null;
74
+ /** The state is one of {@link statesFittingNowhere}. */
75
+ fitsNowhere: boolean;
76
+ }
77
+ /** The column headers with their fit counts, and whether a state fits no variant, as far as the cells have answered. */
78
+ export declare function columnHeaders(results: ReadonlyMap<string, StateFit>, matrix: OverviewMatrix): ColumnHeader[];
79
+ //# sourceMappingURL=overview-matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview-matrix.d.ts","sourceRoot":"","sources":["../../../src/app/overview/overview-matrix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,KAAK,kBAAkB,EAAmC,MAAM,mCAAmC,CAAC;AAE7G,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvE,yFAAyF;AACzF,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gHAAgH;IAChH,WAAW,EAAE,OAAO,CAAC;CACxB;AAED,yHAAyH;AACzH,MAAM,WAAW,SAAS;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,IAAI,EAAE,SAAS,EAAE,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAsB1E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAelE;AAED,8EAA8E;AAC9E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,8EAA8E;AAC9E,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,MAAM,WAAW,SAAS;IACtB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAKlH;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,EAAE,CAQ7G;AAED,uCAAuC;AACvC,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,oDAAoD;IACpD,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,wDAAwD;IACxD,WAAW,EAAE,OAAO,CAAC;CACxB;AAED,wHAAwH;AACxH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,GAAG,YAAY,EAAE,CAU5G"}
@@ -0,0 +1,98 @@
1
+ import { PSEUDO_STATES } from '../../shared/pseudo-state.type.js';
2
+ import { forcesAnyState, hasTarget } from '../pseudo/pseudo-targets.js';
3
+ import { describeTarget } from '../pseudo/state-fit.js';
4
+ /**
5
+ * The Overview as a matrix: a row per variant, a column for Default and one
6
+ * per component state.
7
+ *
8
+ * A component without variants still renders, as a variant of its own, so it
9
+ * gets one implicit `Default` row, like the canvas. A variant that opts out
10
+ * with `states: false` keeps its row but takes part in no state column.
11
+ */
12
+ export function buildOverviewMatrix(config) {
13
+ const columns = [
14
+ { state: null, title: 'Default', signature: 'no state', forcesState: false },
15
+ ...(config.states ?? []).map((state, index) => ({
16
+ state: index,
17
+ title: state.name,
18
+ signature: pseudoSignature(state.pseudo),
19
+ forcesState: forcesAnyState(state.pseudo)
20
+ }))
21
+ ];
22
+ const variants = config.variants ?? [];
23
+ const rows = variants.length === 0
24
+ ? [{ variant: 0, title: 'Default', note: null, optedOut: false }]
25
+ : variants.map((variant, index) => ({
26
+ variant: index,
27
+ title: variant.name,
28
+ note: variant.states === false ? 'states: false' : variant.bg ? `bg: ${variant.bg}` : null,
29
+ optedOut: variant.states === false
30
+ }));
31
+ return { columns, rows };
32
+ }
33
+ /**
34
+ * What a state forces, in a line: `hover + active → .btn`.
35
+ *
36
+ * The pseudo-classes come in {@link PSEUDO_STATES} order, grouped by the target
37
+ * they share. Classes with different targets make one group each, joined with
38
+ * `; ` (`hover → .pill; focus-visible → .pill__close`). A slot that names no
39
+ * target forces nothing, as the marker sees it.
40
+ */
41
+ export function pseudoSignature(pseudo) {
42
+ const groups = new Map();
43
+ for (const state of PSEUDO_STATES) {
44
+ const target = pseudo[state];
45
+ if (target === undefined || !hasTarget(target))
46
+ continue;
47
+ const label = describeTarget(target);
48
+ groups.set(label, [...(groups.get(label) ?? []), state]);
49
+ }
50
+ if (groups.size === 0)
51
+ return 'forces no state';
52
+ return Array.from(groups, ([label, states]) => `${states.join(' + ')} → ${label}`).join('; ');
53
+ }
54
+ /** `fits 2 of 5`: the variants a state fits, of those it is combined with. */
55
+ export function fitLabel(fits, eligible) {
56
+ return `fits ${fits} of ${eligible}`;
57
+ }
58
+ /** Key of one cell's result in the map the matrix collects from the cells. */
59
+ export function fitKey(variant, state) {
60
+ return `${variant}:${state}`;
61
+ }
62
+ /** The fits of one state column, as far as the cells have answered. */
63
+ export function columnFit(results, matrix, state) {
64
+ const rows = matrix.rows.filter((row) => !row.optedOut);
65
+ const answers = rows.map((row) => results.get(fitKey(row.variant, state))).filter((answer) => answer !== undefined);
66
+ return { fits: answers.filter((answer) => answer.fits).length, eligible: rows.length, complete: answers.length === rows.length };
67
+ }
68
+ /**
69
+ * The states whose column is complete and fits nowhere, by index: almost
70
+ * certainly a selector with a typo.
71
+ *
72
+ * A column that is still waiting for a cell, or whose cell failed to render and
73
+ * so never answers, is not complete: a state is only called misplaced once every
74
+ * cell has had its say. A state no variant is combined with has no cell to
75
+ * judge it, so it is not reported either. Nor is a state that forces nothing (a
76
+ * slot the scanner could not use): it fits nowhere by construction, has no
77
+ * selector to check, and the scanner has reported it already.
78
+ *
79
+ * Stateless: the caller keeps track of what it already reported.
80
+ */
81
+ export function statesFittingNowhere(results, matrix) {
82
+ return matrix.columns.flatMap((column) => {
83
+ if (column.state === null || !column.forcesState)
84
+ return [];
85
+ const { fits, eligible, complete } = columnFit(results, matrix, column.state);
86
+ return eligible > 0 && complete && fits === 0 ? [column.state] : [];
87
+ });
88
+ }
89
+ /** The column headers with their fit counts, and whether a state fits no variant, as far as the cells have answered. */
90
+ export function columnHeaders(results, matrix) {
91
+ const nowhere = new Set(statesFittingNowhere(results, matrix));
92
+ return matrix.columns.map((column) => {
93
+ if (column.state === null)
94
+ return { column, fit: null, fitsNowhere: false };
95
+ const { fits, eligible } = columnFit(results, matrix, column.state);
96
+ return { column, fit: fitLabel(fits, eligible), fitsNowhere: nowhere.has(column.state) };
97
+ });
98
+ }
@@ -1,4 +1,11 @@
1
+ import type { ShowcaseConfig } from '../../decorator/showcase.types.js';
1
2
  import type { RuntimeComponent } from '../../plugin/plugin.types.js';
3
+ /**
4
+ * How many cells the Overview would hold for this config: the matrix's rows
5
+ * times its columns, where a variant that opted out with `states: false` has
6
+ * one cell instead of a row of them.
7
+ */
8
+ export declare function overviewCellCount(config: ShowcaseConfig): number;
2
9
  /**
3
10
  * Whether the Overview tab is offered for this component.
4
11
  *
@@ -8,8 +15,9 @@ import type { RuntimeComponent } from '../../plugin/plugin.types.js';
8
15
  * `PrismRendererService`. n cells side by side would all show the same state,
9
16
  * so an Overview there would be demonstrably wrong, not merely unhelpful.
10
17
  *
11
- * A single variant needs no contact sheet: the grid would be one cell, and the
12
- * Playground says the same thing better.
18
+ * A single cell needs no contact sheet: the Playground says the same thing
19
+ * better. A state counts as a cell, so one variant with one state already
20
+ * earns the Overview.
13
21
  */
14
22
  export declare function showsOverview(component: RuntimeComponent): boolean;
15
23
  //# sourceMappingURL=overview-visibility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overview-visibility.d.ts","sourceRoot":"","sources":["../../../src/app/overview/overview-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAKlE"}
1
+ {"version":3,"file":"overview-visibility.d.ts","sourceRoot":"","sources":["../../../src/app/overview/overview-visibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGrE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAIhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAKlE"}
@@ -1,3 +1,13 @@
1
+ import { buildOverviewMatrix } from './overview-matrix.js';
2
+ /**
3
+ * How many cells the Overview would hold for this config: the matrix's rows
4
+ * times its columns, where a variant that opted out with `states: false` has
5
+ * one cell instead of a row of them.
6
+ */
7
+ export function overviewCellCount(config) {
8
+ const { columns, rows } = buildOverviewMatrix(config);
9
+ return rows.reduce((cells, row) => cells + (row.optedOut ? 1 : columns.length), 0);
10
+ }
1
11
  /**
2
12
  * Whether the Overview tab is offered for this component.
3
13
  *
@@ -7,12 +17,13 @@
7
17
  * `PrismRendererService`. n cells side by side would all show the same state,
8
18
  * so an Overview there would be demonstrably wrong, not merely unhelpful.
9
19
  *
10
- * A single variant needs no contact sheet: the grid would be one cell, and the
11
- * Playground says the same thing better.
20
+ * A single cell needs no contact sheet: the Playground says the same thing
21
+ * better. A state counts as a cell, so one variant with one state already
22
+ * earns the Overview.
12
23
  */
13
24
  export function showsOverview(component) {
14
25
  const config = component.meta.showcaseConfig;
15
26
  if (config.renderPage)
16
27
  return false;
17
- return (config.variants?.length ?? 0) >= 2;
28
+ return overviewCellCount(config) >= 2;
18
29
  }
@@ -1,4 +1,5 @@
1
1
  import type { RuntimeComponent } from '../../plugin/plugin.types.js';
2
+ import type { StateFit } from '../pseudo/state-fit.js';
2
3
  import * as i0 from "@angular/core";
3
4
  /**
4
5
  * One frame of the contact sheet: a stage painting the variant's declared
@@ -10,20 +11,46 @@ import * as i0 from "@angular/core";
10
11
  * writing to any of them would corrupt what they mean. `data-prism-rendered`
11
12
  * matters most: it is the selector external screenshot runners key on (see
12
13
  * `docs/guide/external-tooling.md`), and this component never emits it.
14
+ *
15
+ * Forced pseudo states are the variant's own, applied by a marker of the
16
+ * cell's own, so a hovered cell never hovers its neighbour. The tools menu's
17
+ * state toggle does not reach here: like every other control, it belongs to
18
+ * the Playground.
19
+ *
20
+ * A cell can combine its variant with one of the component's `states` (the
21
+ * matrix does). When the marker finds that the state does not fit the rendered
22
+ * component, or the variant opted out with `states: false`, the cell shows the
23
+ * reason in place of the component. Every cell, with or without a state, opens
24
+ * its exact combination in the Playground on click, Enter or Space.
13
25
  */
14
26
  export declare class PrismOverviewCellComponent {
15
27
  readonly component: import("@angular/core").InputSignal<RuntimeComponent>;
16
28
  readonly index: import("@angular/core").InputSignal<number>;
29
+ /** Position of the component state in `ShowcaseConfig.states`, `null` for the variant alone. */
30
+ readonly state: import("@angular/core").InputSignal<number | null>;
31
+ /** `matrix` leaves the caption and the grid span to the matrix around the cell. */
32
+ readonly mode: import("@angular/core").InputSignal<"sheet" | "matrix">;
33
+ /** Whether the state fits the rendered variant. Only emitted while `state` is not `null`. */
34
+ readonly fitChange: import("@angular/core").OutputEmitterRef<StateFit>;
17
35
  private readonly injector;
18
36
  private readonly destroyRef;
37
+ private readonly renderer;
38
+ private readonly panels;
39
+ private readonly pseudoMarker;
19
40
  private readonly outlet;
20
41
  /** Never null: `resolveVariantBg` falls back to `DEFAULT_VARIANT_BG`. */
21
42
  protected readonly bg: import("@angular/core").Signal<import("../services/prism-canvas.service.js").CanvasBg>;
22
43
  protected readonly caption: import("@angular/core").Signal<string>;
23
- protected readonly isWide: import("@angular/core").Signal<boolean>;
44
+ /** Why the state is not shown on this cell, `null` while the component is. */
45
+ protected readonly unfitReason: import("@angular/core").WritableSignal<string | null>;
46
+ protected readonly label: import("@angular/core").Signal<string>;
47
+ protected readonly stretches: import("@angular/core").Signal<boolean>;
24
48
  constructor();
49
+ protected open(): void;
50
+ protected onKeydown(event: KeyboardEvent): void;
25
51
  private mount;
52
+ private unfit;
26
53
  static ɵfac: i0.ɵɵFactoryDeclaration<PrismOverviewCellComponent, never>;
27
- static ɵcmp: i0.ɵɵComponentDeclaration<PrismOverviewCellComponent, "prism-overview-cell", never, { "component": { "alias": "component"; "required": true; "isSignal": true; }; "index": { "alias": "index"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
54
+ static ɵcmp: i0.ɵɵComponentDeclaration<PrismOverviewCellComponent, "prism-overview-cell", never, { "component": { "alias": "component"; "required": true; "isSignal": true; }; "index": { "alias": "index"; "required": true; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, { "fitChange": "fitChange"; }, never, never, true, never>;
28
55
  }
29
56
  //# sourceMappingURL=prism-overview-cell.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prism-overview-cell.component.d.ts","sourceRoot":"","sources":["../../../src/app/overview/prism-overview-cell.component.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;;AAOrE;;;;;;;;;;GAUG;AACH,qBAYa,0BAA0B;IACnC,QAAQ,CAAC,SAAS,wDAAsC;IACxD,QAAQ,CAAC,KAAK,8CAA4B;IAE1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;IAEH,yEAAyE;IACzE,SAAS,CAAC,QAAQ,CAAC,EAAE,yFAAwF;IAE7G,SAAS,CAAC,QAAQ,CAAC,OAAO,yCAUvB;IAEH,SAAS,CAAC,QAAQ,CAAC,MAAM,0CAKtB;;IAmBH,OAAO,CAAC,KAAK;yCAjDJ,0BAA0B;2CAA1B,0BAA0B;CAyFtC"}
1
+ {"version":3,"file":"prism-overview-cell.component.d.ts","sourceRoot":"","sources":["../../../src/app/overview/prism-overview-cell.component.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;;AAQvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAmBa,0BAA0B;IACnC,QAAQ,CAAC,SAAS,wDAAsC;IACxD,QAAQ,CAAC,KAAK,8CAA4B;IAC1C,gGAAgG;IAChG,QAAQ,CAAC,KAAK,qDAA8B;IAC5C,mFAAmF;IACnF,QAAQ,CAAC,IAAI,0DAAsC;IACnD,6FAA6F;IAC7F,QAAQ,CAAC,SAAS,qDAAsB;IAExC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6B;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkD;IAC/E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;IAEH,yEAAyE;IACzE,SAAS,CAAC,QAAQ,CAAC,EAAE,yFAAwF;IAE7G,SAAS,CAAC,QAAQ,CAAC,OAAO,yCAUvB;IAEH,8EAA8E;IAC9E,SAAS,CAAC,QAAQ,CAAC,WAAW,wDAA+B;IAE7D,SAAS,CAAC,QAAQ,CAAC,KAAK,yCAOrB;IAEH,SAAS,CAAC,QAAQ,CAAC,SAAS,0CAKzB;;IAuBH,SAAS,CAAC,IAAI,IAAI,IAAI;IAItB,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAkB/C,OAAO,CAAC,KAAK;IAsEb,OAAO,CAAC,KAAK;yCAtKJ,0BAA0B;2CAA1B,0BAA0B;CA0KtC"}