@astryxdesign/cli 0.5.2-canary.e4f7677 → 0.5.2-canary.e4f8e4e

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.
@@ -64,8 +64,96 @@ export interface ComponentBestPractice {
64
64
  export interface ComponentAccessibilityRequirement {
65
65
  /** Short scannable label, e.g. `"Accessible name"` or `"Loading"`. */
66
66
  name: string;
67
- /** The accessibility contract consumers must preserve. */
67
+ /**
68
+ * The accessibility contract consumers must preserve. Write at about a
69
+ * grade-7 reading level with short sentences, common words, and active
70
+ * voice. For color contrast, put the ratio in `requirement`; name the exact
71
+ * foreground, background, state, and any overlay in `description`; explain
72
+ * exceptions in plain language; and include enough detail for a human or
73
+ * agent to reproduce the check.
74
+ */
68
75
  description: string;
76
+ /** Groups related requirements in the docsite Accessibility tab. */
77
+ category?: 'Color contrast' | 'Keyboard' | 'Semantics' | 'Content';
78
+ /** Relevant WCAG success criterion, e.g. `"1.4.3 Contrast (Minimum)"`. */
79
+ criterion?: string;
80
+ /** Short threshold or rule, e.g. `"4.5:1"`, `"3:1"`, or `"Exempt"`. */
81
+ requirement?: string;
82
+ /** Component states covered by this requirement. */
83
+ states?: string[];
84
+ }
85
+
86
+ export type ComponentAccessibilityThemeStatus = 'Pass' | 'Fail' | 'Not tested';
87
+
88
+ export type ComponentAccessibilityThemeApplicability =
89
+ 'Required' | 'Conditional' | 'Supplemental' | 'Decorative';
90
+
91
+ export interface ComponentAccessibilityThemeMeasurement {
92
+ /** Column heading, e.g. `"Rest"` or `"Spinner"`. */
93
+ label: string;
94
+ /** Display value, e.g. `"15.13:1"`. */
95
+ value: string;
96
+ /** Optional supporting detail shown below the value, such as a worst case. */
97
+ detail?: string;
98
+ /**
99
+ * Whether this measurement is required for every use, required only in some
100
+ * contexts, shown as a supplemental cue, or decorative. Each theme declares
101
+ * this intent, informed by the component contract. Never infer it from the
102
+ * measured ratio. Non-required measurements do not determine row status.
103
+ */
104
+ applicability?: ComponentAccessibilityThemeApplicability;
105
+ /** Rendered foreground and background colors used for this measurement. */
106
+ colorPair?: {
107
+ foreground: string;
108
+ background: string;
109
+ };
110
+ /** Optional per-variant results shown from a compact details trigger. */
111
+ breakdown?: Array<{
112
+ label: string;
113
+ value: string;
114
+ detail?: string;
115
+ colorPair: {
116
+ foreground: string;
117
+ background: string;
118
+ };
119
+ status?: 'Pass' | 'Fail';
120
+ }>;
121
+ /** Mark a failed measurement so the docsite can emphasize it. */
122
+ status?: 'Pass' | 'Fail';
123
+ }
124
+
125
+ export interface ComponentAccessibilityThemeResult {
126
+ /** Row heading, usually a component variant. */
127
+ name: string;
128
+ /** Measurements shown between the row heading and status. */
129
+ measurements: ComponentAccessibilityThemeMeasurement[];
130
+ /** Overall result for the row. */
131
+ status: ComponentAccessibilityThemeStatus;
132
+ }
133
+
134
+ export interface ComponentAccessibilityThemeMode {
135
+ /** Theme mode covered by these results. */
136
+ mode: 'Light' | 'Dark';
137
+ /** Detailed results for the component in this mode. */
138
+ results: ComponentAccessibilityThemeResult[];
139
+ }
140
+
141
+ export interface ComponentAccessibilityThemeTable {
142
+ /** Optional heading for one complete group of measurements. */
143
+ title?: string;
144
+ /** Explains the scope of this measurement group. */
145
+ description?: string;
146
+ /** Detailed results separated by theme mode. */
147
+ modes: ComponentAccessibilityThemeMode[];
148
+ }
149
+
150
+ export interface ComponentAccessibilityThemeCoverage {
151
+ /** Display name of the audited theme. */
152
+ theme: string;
153
+ /** Complete groups of measurements for this theme and component. */
154
+ tables: ComponentAccessibilityThemeTable[];
155
+ /** Theme visuals intentionally excluded from measurement, with a reason. */
156
+ notMeasured?: string[];
69
157
  }
70
158
 
71
159
  /**
@@ -462,6 +550,8 @@ export interface UsageDoc {
462
550
  /** Accessibility requirements specific to this component and its supported
463
551
  * content combinations. Generic audit procedure stays in the wiki rubric. */
464
552
  accessibility?: ComponentAccessibilityRequirement[];
553
+ /** Verified color-accessibility coverage for bundled themes. */
554
+ accessibilityThemeCoverage?: ComponentAccessibilityThemeCoverage[];
465
555
  /** Structural/visual anatomy of the component. Each entry describes one
466
556
  * element that makes up the component (icon slot, label, container, etc.).
467
557
  * Order entries in the visual reading order (leading → trailing, top → bottom). */
@@ -132,7 +132,13 @@ export const doc = {
132
132
  name: 'usage.accessibility',
133
133
  type: 'ComponentAccessibilityRequirement[]',
134
134
  description:
135
- 'Component-specific accessibility requirements ({name, description}) rendered as a dedicated Accessibility section. Keep audit procedures in the wiki rubric.',
135
+ 'Component-specific requirements rendered in the shared Accessibility tab. Write at about a grade-7 reading level with short sentences, common words, and active voice. For color contrast, put the ratio in `requirement`; name the exact foreground, background, state, and any overlay in `description`; explain exceptions in plain language; and give a human or agent enough detail to reproduce the check. Keep repository audit procedures in the wiki rubric.',
136
+ },
137
+ {
138
+ name: 'usage.accessibilityThemeCoverage',
139
+ type: 'ComponentAccessibilityThemeCoverage[]',
140
+ description:
141
+ 'Verified per-theme accessibility measurements rendered in the shared Accessibility tab. Record light and dark mode separately, include rendered color pairs, and mark failed measurements. Put visuals excluded from the audit in `notMeasured` with a short reason; do not add them as table measurements. Each theme declares `applicability` for measured values, informed by the component contract and never inferred from the ratio: `Conditional` is required only in some contexts, `Supplemental` adds another meaningful cue, and `Decorative` has no required meaning. These values do not change row status. Provide a complete breakdown when one cell summarizes multiple combinations, and protect derived values with an automated audit.',
136
142
  },
137
143
  {
138
144
  name: 'usage.anatomy',
@@ -68,6 +68,13 @@ export type {
68
68
  ComponentExampleDoc,
69
69
  ComponentAnatomyElement,
70
70
  ComponentAccessibilityRequirement,
71
+ ComponentAccessibilityThemeStatus,
72
+ ComponentAccessibilityThemeApplicability,
73
+ ComponentAccessibilityThemeMeasurement,
74
+ ComponentAccessibilityThemeResult,
75
+ ComponentAccessibilityThemeMode,
76
+ ComponentAccessibilityThemeTable,
77
+ ComponentAccessibilityThemeCoverage,
71
78
  ComponentBestPractice,
72
79
  ComponentSlotElement,
73
80
  ComponentPlaygroundConfig,
@@ -15,6 +15,16 @@ export namespace docs {
15
15
  name: string;
16
16
  description: string;
17
17
  }[];
18
+ let accessibilityThemeCoverage: {
19
+ theme: string;
20
+ tables: {
21
+ modes: {
22
+ mode: string;
23
+ results: never[];
24
+ }[];
25
+ }[];
26
+ notMeasured: string[];
27
+ }[];
18
28
  let anatomy: {
19
29
  name: string;
20
30
  required: boolean;
@@ -18,6 +18,20 @@ export const docs = {
18
18
  description: 'Provide an accessible name.',
19
19
  },
20
20
  ],
21
+ accessibilityThemeCoverage: [
22
+ {
23
+ theme: 'Fixture',
24
+ tables: [
25
+ {
26
+ modes: [
27
+ {mode: 'Light', results: []},
28
+ {mode: 'Dark', results: []},
29
+ ],
30
+ },
31
+ ],
32
+ notMeasured: ['Decorative track — Not part of the contrast audit.'],
33
+ },
34
+ ],
21
35
  anatomy: [
22
36
  {
23
37
  name: 'Base-only anatomy',
@@ -194,16 +194,23 @@ function overlayComponentDoc(docs, translation) {
194
194
  });
195
195
  };
196
196
 
197
- /** Preserve the new accessibility field without changing established translated output.
197
+ /** Preserve structured accessibility data without changing established translated output.
198
198
  * @param {any} baseUsage
199
199
  * @param {any} translatedUsage
200
200
  */
201
201
  const mergeUsage = (baseUsage, translatedUsage) => {
202
202
  if (!translatedUsage) return baseUsage;
203
- if (!baseUsage?.accessibility || translatedUsage.accessibility !== undefined) {
204
- return translatedUsage;
205
- }
206
- return {...translatedUsage, accessibility: baseUsage.accessibility};
203
+ return {
204
+ ...translatedUsage,
205
+ ...(translatedUsage.accessibility === undefined &&
206
+ baseUsage?.accessibility !== undefined
207
+ ? {accessibility: baseUsage.accessibility}
208
+ : null),
209
+ ...(translatedUsage.accessibilityThemeCoverage === undefined &&
210
+ baseUsage?.accessibilityThemeCoverage !== undefined
211
+ ? {accessibilityThemeCoverage: baseUsage.accessibilityThemeCoverage}
212
+ : null),
213
+ };
207
214
  };
208
215
 
209
216
  const merged = {...docs, ...translation, usage: mergeUsage(docs.usage, translation.usage)};
@@ -120,6 +120,12 @@ describe('the reported symptom', () => {
120
120
 
121
121
  expect(english.usage.accessibility.length).toBeGreaterThan(0);
122
122
  expect(dense.usage.accessibility).toEqual(english.usage.accessibility);
123
+ expect(dense.usage.accessibilityThemeCoverage).toEqual(
124
+ english.usage.accessibilityThemeCoverage,
125
+ );
126
+ expect(dense.usage.accessibilityThemeCoverage[0].notMeasured).toContain(
127
+ 'Decorative track — Not part of the contrast audit.',
128
+ );
123
129
  expect(dense.usage.bestPractices).toBeUndefined();
124
130
  expect(dense.usage.anatomy).toBeUndefined();
125
131
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/cli",
3
- "version": "0.5.2-canary.e4f7677",
3
+ "version": "0.5.2-canary.e4f8e4e",
4
4
  "displayName": "CLI",
5
5
  "description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
6
6
  "author": "Meta Open Source",
@@ -87,10 +87,10 @@
87
87
  "zod": "^4.4.3"
88
88
  },
89
89
  "peerDependencies": {
90
- "@astryxdesign/charts": "0.5.2-canary.e4f7677",
91
- "@astryxdesign/core": "0.5.2-canary.e4f7677",
92
- "@astryxdesign/lab": "0.5.2-canary.e4f7677",
93
- "@astryxdesign/theme-neutral": "0.5.2-canary.e4f7677",
90
+ "@astryxdesign/charts": "0.5.2-canary.e4f8e4e",
91
+ "@astryxdesign/core": "0.5.2-canary.e4f8e4e",
92
+ "@astryxdesign/lab": "0.5.2-canary.e4f8e4e",
93
+ "@astryxdesign/theme-neutral": "0.5.2-canary.e4f8e4e",
94
94
  "gpt-tokenizer": "^3.4.0"
95
95
  },
96
96
  "peerDependenciesMeta": {
@@ -108,10 +108,10 @@
108
108
  }
109
109
  },
110
110
  "devDependencies": {
111
- "@astryxdesign/charts": "0.5.2-canary.e4f7677",
112
- "@astryxdesign/core": "0.5.2-canary.e4f7677",
113
- "@astryxdesign/lab": "0.5.2-canary.e4f7677",
114
- "@astryxdesign/theme-neutral": "0.5.2-canary.e4f7677",
111
+ "@astryxdesign/charts": "0.5.2-canary.e4f8e4e",
112
+ "@astryxdesign/core": "0.5.2-canary.e4f8e4e",
113
+ "@astryxdesign/lab": "0.5.2-canary.e4f8e4e",
114
+ "@astryxdesign/theme-neutral": "0.5.2-canary.e4f8e4e",
115
115
  "gpt-tokenizer": "^3.4.0"
116
116
  },
117
117
  "scripts": {