@vellira-ui/tokens 2.104.14 → 2.104.16
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.
- package/dist/component-token-dependencies.d.ts +8 -0
- package/dist/component-token-dependencies.d.ts.map +1 -1
- package/dist/component-token-dependencies.js +8 -0
- package/dist/component-token-dependency-audit.d.ts +15 -0
- package/dist/component-token-dependency-audit.d.ts.map +1 -0
- package/dist/component-token-dependency-audit.js +60 -0
- package/dist/component-token-factory-conventions.d.ts +55 -0
- package/dist/component-token-factory-conventions.d.ts.map +1 -0
- package/dist/component-token-factory-conventions.js +53 -0
- package/dist/interaction-state-contract.d.ts +138 -0
- package/dist/interaction-state-contract.d.ts.map +1 -0
- package/dist/interaction-state-contract.js +127 -0
- package/dist/platform-output/component-token-boundary.d.ts +7 -0
- package/dist/platform-output/component-token-boundary.d.ts.map +1 -0
- package/dist/platform-output/component-token-boundary.js +37 -0
- package/dist/public-api-policy.d.ts +19 -0
- package/dist/public-api-policy.d.ts.map +1 -1
- package/dist/public-api-policy.js +19 -0
- package/dist/token-architecture.d.ts +2 -2
- package/dist/token-architecture.js +2 -2
- package/package.json +1 -1
|
@@ -123,18 +123,26 @@ export declare const componentTokenDependencyAuditV1: readonly [{
|
|
|
123
123
|
export declare const semanticDependencyRepairsV1: readonly [{
|
|
124
124
|
readonly component: "formField";
|
|
125
125
|
readonly paths: readonly ["requiredMark.fg", "labelInfo.border"];
|
|
126
|
+
readonly target: "factory";
|
|
127
|
+
readonly assertion: "form-field-presentation";
|
|
126
128
|
readonly repair: "Move component-specific presentation paint out of unrelated status/text semantic roles while preserving the resolved theme values.";
|
|
127
129
|
}, {
|
|
128
130
|
readonly component: "input";
|
|
129
131
|
readonly paths: readonly ["clearButton.hoverFg", "clearButton.hoverBg"];
|
|
132
|
+
readonly target: "theme";
|
|
133
|
+
readonly assertion: "clear-button-danger";
|
|
130
134
|
readonly repair: "Use canonical danger icon semantics when value-equivalent; otherwise use explicit component-owned presentation paint to preserve the existing resolved value without depending on validation status.";
|
|
131
135
|
}, {
|
|
132
136
|
readonly component: "input";
|
|
133
137
|
readonly paths: readonly ["error.ring"];
|
|
138
|
+
readonly target: "theme";
|
|
139
|
+
readonly assertion: "input-error-ring";
|
|
134
140
|
readonly repair: "Use status.error.ring rather than a coincidentally equal status.error.fg value.";
|
|
135
141
|
}, {
|
|
136
142
|
readonly component: "select";
|
|
137
143
|
readonly paths: readonly ["clearButton.hoverFg", "clearButton.hoverBg"];
|
|
144
|
+
readonly target: "theme";
|
|
145
|
+
readonly assertion: "clear-button-danger";
|
|
138
146
|
readonly repair: "Use canonical danger icon semantics when value-equivalent; otherwise use explicit component-owned presentation paint to preserve the existing resolved value without depending on validation status.";
|
|
139
147
|
}];
|
|
140
148
|
//# sourceMappingURL=component-token-dependencies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-token-dependencies.d.ts","sourceRoot":"","sources":["../src/component-token-dependencies.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;CA8BnC,CAAC;AAEX,MAAM,MAAM,4BAA4B,GACtC,MAAM,GAAG,6BAA6B,GAAG,8BAA8B,CAAC;AAE1E,eAAO,MAAM,wCAAwC;;;;;;;;;;EAe3C,CAAC;AAEX,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmHlC,CAAC;AAEX,eAAO,MAAM,2BAA2B
|
|
1
|
+
{"version":3,"file":"component-token-dependencies.d.ts","sourceRoot":"","sources":["../src/component-token-dependencies.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;CA8BnC,CAAC;AAEX,MAAM,MAAM,4BAA4B,GACtC,MAAM,GAAG,6BAA6B,GAAG,8BAA8B,CAAC;AAE1E,eAAO,MAAM,wCAAwC;;;;;;;;;;EAe3C,CAAC;AAEX,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmHlC,CAAC;AAEX,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;EAiC9B,CAAC"}
|
|
@@ -161,21 +161,29 @@ export const semanticDependencyRepairsV1 = [
|
|
|
161
161
|
{
|
|
162
162
|
component: 'formField',
|
|
163
163
|
paths: ['requiredMark.fg', 'labelInfo.border'],
|
|
164
|
+
target: 'factory',
|
|
165
|
+
assertion: 'form-field-presentation',
|
|
164
166
|
repair: 'Move component-specific presentation paint out of unrelated status/text semantic roles while preserving the resolved theme values.',
|
|
165
167
|
},
|
|
166
168
|
{
|
|
167
169
|
component: 'input',
|
|
168
170
|
paths: ['clearButton.hoverFg', 'clearButton.hoverBg'],
|
|
171
|
+
target: 'theme',
|
|
172
|
+
assertion: 'clear-button-danger',
|
|
169
173
|
repair: 'Use canonical danger icon semantics when value-equivalent; otherwise use explicit component-owned presentation paint to preserve the existing resolved value without depending on validation status.',
|
|
170
174
|
},
|
|
171
175
|
{
|
|
172
176
|
component: 'input',
|
|
173
177
|
paths: ['error.ring'],
|
|
178
|
+
target: 'theme',
|
|
179
|
+
assertion: 'input-error-ring',
|
|
174
180
|
repair: 'Use status.error.ring rather than a coincidentally equal status.error.fg value.',
|
|
175
181
|
},
|
|
176
182
|
{
|
|
177
183
|
component: 'select',
|
|
178
184
|
paths: ['clearButton.hoverFg', 'clearButton.hoverBg'],
|
|
185
|
+
target: 'theme',
|
|
186
|
+
assertion: 'clear-button-danger',
|
|
179
187
|
repair: 'Use canonical danger icon semantics when value-equivalent; otherwise use explicit component-owned presentation paint to preserve the existing resolved value without depending on validation status.',
|
|
180
188
|
},
|
|
181
189
|
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type semanticDependencyRepairsV1 } from './component-token-dependencies.js';
|
|
2
|
+
export type ComponentDependencyTheme = 'light' | 'dark' | 'highContrast';
|
|
3
|
+
export type SemanticDependencyRepair = (typeof semanticDependencyRepairsV1)[number];
|
|
4
|
+
export type SemanticDependencySourceIssue = {
|
|
5
|
+
code: string;
|
|
6
|
+
evidence: string;
|
|
7
|
+
expected: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function auditSemanticDependencyRepairSource(input: {
|
|
10
|
+
repair: SemanticDependencyRepair;
|
|
11
|
+
source: string;
|
|
12
|
+
theme?: ComponentDependencyTheme | null;
|
|
13
|
+
}): SemanticDependencySourceIssue[];
|
|
14
|
+
export declare function auditGeneratedThemeTokenDependencySource(content: string): SemanticDependencySourceIssue[];
|
|
15
|
+
//# sourceMappingURL=component-token-dependency-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-token-dependency-audit.d.ts","sourceRoot":"","sources":["../src/component-token-dependency-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,2BAA2B,EACjC,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC;AACzE,MAAM,MAAM,wBAAwB,GAClC,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/C,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAUF,wBAAgB,mCAAmC,CAAC,KAAK,EAAE;IACzD,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACzC,GAAG,6BAA6B,EAAE,CA0GlC;AAED,wBAAgB,wCAAwC,CACtD,OAAO,EAAE,MAAM,GACd,6BAA6B,EAAE,CAwBjC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { componentTokenDependencyPolicyV1, } from './component-token-dependencies.js';
|
|
2
|
+
function issue(code, evidence, expected) {
|
|
3
|
+
return { code, evidence, expected };
|
|
4
|
+
}
|
|
5
|
+
export function auditSemanticDependencyRepairSource(input) {
|
|
6
|
+
const findings = [];
|
|
7
|
+
switch (input.repair.assertion) {
|
|
8
|
+
case 'form-field-presentation': {
|
|
9
|
+
if (!input.source.includes('border: presentation.labelInfoBorder')) {
|
|
10
|
+
findings.push(issue('missing-form-field-label-info-presentation', 'FormField no longer maps labelInfo.border through component-owned presentation paint.', 'Keep labelInfo.border on presentation.labelInfoBorder.'));
|
|
11
|
+
}
|
|
12
|
+
if (!input.source.includes('fg: presentation.requiredMarkFg')) {
|
|
13
|
+
findings.push(issue('missing-form-field-required-mark-presentation', 'FormField no longer maps requiredMark.fg through component-owned presentation paint.', 'Keep requiredMark.fg on presentation.requiredMarkFg.'));
|
|
14
|
+
}
|
|
15
|
+
if (input.source.includes('border: text.secondary')) {
|
|
16
|
+
findings.push(issue('form-field-unrelated-text-semantic', 'FormField labelInfo.border depends on text.secondary.', 'Component presentation paint must not borrow an unrelated text semantic role.'));
|
|
17
|
+
}
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
case 'clear-button-danger': {
|
|
21
|
+
if (!input.theme) {
|
|
22
|
+
findings.push(issue('missing-clear-button-theme-context', 'Clear-button repair validation was invoked without a theme.', 'Validate clear-button semantic repair for every maintained theme.'));
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
if (input.source.includes('hoverFg: status.error.fg')) {
|
|
26
|
+
findings.push(issue('clear-button-validation-fg-dependency', 'Destructive clear-button hover foreground depends on validation status.error.fg.', 'Use danger icon semantics or explicit component-owned presentation paint.'));
|
|
27
|
+
}
|
|
28
|
+
if (input.source.includes('hoverBg: status.error.bg')) {
|
|
29
|
+
findings.push(issue('clear-button-validation-bg-dependency', 'Destructive clear-button hover background depends on validation status.error.bg.', 'Use explicit danger presentation paint rather than validation status paint.'));
|
|
30
|
+
}
|
|
31
|
+
const expectedHoverFg = input.theme === 'highContrast'
|
|
32
|
+
? 'hoverFg: colors.error[400]'
|
|
33
|
+
: 'hoverFg: icons.danger';
|
|
34
|
+
if (!input.source.includes(expectedHoverFg)) {
|
|
35
|
+
findings.push(issue('clear-button-danger-foreground-drift', `Expected ${expectedHoverFg} for the ${input.theme} clear-button repair.`, 'Preserve the accepted #888 danger foreground repair for this theme.'));
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case 'input-error-ring': {
|
|
40
|
+
if (!input.source.includes('ring: status.error.ring')) {
|
|
41
|
+
findings.push(issue('input-error-ring-role-drift', 'Input validation ring no longer consumes status.error.ring.', 'Use the dedicated status.error.ring semantic role.'));
|
|
42
|
+
}
|
|
43
|
+
if (input.source.includes('ring: status.error.fg')) {
|
|
44
|
+
findings.push(issue('input-error-ring-foreground-bypass', 'Input validation ring consumes status.error.fg.', 'Do not substitute a value-equal foreground role for the dedicated ring role.'));
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return findings;
|
|
50
|
+
}
|
|
51
|
+
export function auditGeneratedThemeTokenDependencySource(content) {
|
|
52
|
+
const findings = [];
|
|
53
|
+
if (content.includes('../../primitives/colors.js')) {
|
|
54
|
+
findings.push(issue('generated-token-primitive-bypass', 'Generated theme token construction imports primitive colors directly.', componentTokenDependencyPolicyV1.generatorRule));
|
|
55
|
+
}
|
|
56
|
+
if (content.includes('../semantic/action.js')) {
|
|
57
|
+
findings.push(issue('generated-token-deprecated-action-dependency', 'Generated theme token construction imports deprecated semantic/action.', componentTokenDependencyPolicyV1.generatorRule));
|
|
58
|
+
}
|
|
59
|
+
return findings;
|
|
60
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export declare const componentTokenFactoryConventionV1: {
|
|
2
|
+
readonly rootEntries: readonly [{
|
|
3
|
+
readonly name: "components";
|
|
4
|
+
readonly kind: "directory";
|
|
5
|
+
}, {
|
|
6
|
+
readonly name: "index.ts";
|
|
7
|
+
readonly kind: "file";
|
|
8
|
+
}, {
|
|
9
|
+
readonly name: "palettes";
|
|
10
|
+
readonly kind: "directory";
|
|
11
|
+
}, {
|
|
12
|
+
readonly name: "shared";
|
|
13
|
+
readonly kind: "directory";
|
|
14
|
+
}];
|
|
15
|
+
readonly paletteFamilies: readonly [{
|
|
16
|
+
readonly component: "button";
|
|
17
|
+
readonly componentName: "Button";
|
|
18
|
+
readonly factory: "createButtonTokens";
|
|
19
|
+
readonly helper: "createButtonIntentPalette.ts";
|
|
20
|
+
readonly themeFile: "button.ts";
|
|
21
|
+
}, {
|
|
22
|
+
readonly component: "checkbox";
|
|
23
|
+
readonly componentName: "Checkbox";
|
|
24
|
+
readonly factory: "createCheckboxTokens";
|
|
25
|
+
readonly helper: "createCheckboxIntentPalette.ts";
|
|
26
|
+
readonly themeFile: "checkbox.ts";
|
|
27
|
+
}, {
|
|
28
|
+
readonly component: "dropdown";
|
|
29
|
+
readonly componentName: "Dropdown";
|
|
30
|
+
readonly factory: "createDropdownTokens";
|
|
31
|
+
readonly helper: "createDropdownIntentPalette.ts";
|
|
32
|
+
readonly themeFile: "dropdown.ts";
|
|
33
|
+
}, {
|
|
34
|
+
readonly component: "input";
|
|
35
|
+
readonly componentName: "Input";
|
|
36
|
+
readonly factory: "createInputTokens";
|
|
37
|
+
readonly helper: "createInputIntentPalette.ts";
|
|
38
|
+
readonly themeFile: "input.ts";
|
|
39
|
+
}, {
|
|
40
|
+
readonly component: "radio";
|
|
41
|
+
readonly componentName: "Radio";
|
|
42
|
+
readonly factory: "createRadioTokens";
|
|
43
|
+
readonly helper: "createRadioIntentPalette.ts";
|
|
44
|
+
readonly themeFile: "radio.ts";
|
|
45
|
+
}, {
|
|
46
|
+
readonly component: "select";
|
|
47
|
+
readonly componentName: "Select";
|
|
48
|
+
readonly factory: "createSelectTokens";
|
|
49
|
+
readonly helper: "createSelectIntentPalette.ts";
|
|
50
|
+
readonly themeFile: "select.ts";
|
|
51
|
+
}];
|
|
52
|
+
readonly sharedHelpers: readonly ["componentFocusRing.ts"];
|
|
53
|
+
};
|
|
54
|
+
export type ComponentTokenFactoryConvention = typeof componentTokenFactoryConventionV1;
|
|
55
|
+
//# sourceMappingURL=component-token-factory-conventions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-token-factory-conventions.d.ts","sourceRoot":"","sources":["../src/component-token-factory-conventions.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDpC,CAAC;AAEX,MAAM,MAAM,+BAA+B,GACzC,OAAO,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export const componentTokenFactoryConventionV1 = {
|
|
2
|
+
rootEntries: [
|
|
3
|
+
{ name: 'components', kind: 'directory' },
|
|
4
|
+
{ name: 'index.ts', kind: 'file' },
|
|
5
|
+
{ name: 'palettes', kind: 'directory' },
|
|
6
|
+
{ name: 'shared', kind: 'directory' },
|
|
7
|
+
],
|
|
8
|
+
paletteFamilies: [
|
|
9
|
+
{
|
|
10
|
+
component: 'button',
|
|
11
|
+
componentName: 'Button',
|
|
12
|
+
factory: 'createButtonTokens',
|
|
13
|
+
helper: 'createButtonIntentPalette.ts',
|
|
14
|
+
themeFile: 'button.ts',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
component: 'checkbox',
|
|
18
|
+
componentName: 'Checkbox',
|
|
19
|
+
factory: 'createCheckboxTokens',
|
|
20
|
+
helper: 'createCheckboxIntentPalette.ts',
|
|
21
|
+
themeFile: 'checkbox.ts',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
component: 'dropdown',
|
|
25
|
+
componentName: 'Dropdown',
|
|
26
|
+
factory: 'createDropdownTokens',
|
|
27
|
+
helper: 'createDropdownIntentPalette.ts',
|
|
28
|
+
themeFile: 'dropdown.ts',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
component: 'input',
|
|
32
|
+
componentName: 'Input',
|
|
33
|
+
factory: 'createInputTokens',
|
|
34
|
+
helper: 'createInputIntentPalette.ts',
|
|
35
|
+
themeFile: 'input.ts',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
component: 'radio',
|
|
39
|
+
componentName: 'Radio',
|
|
40
|
+
factory: 'createRadioTokens',
|
|
41
|
+
helper: 'createRadioIntentPalette.ts',
|
|
42
|
+
themeFile: 'radio.ts',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
component: 'select',
|
|
46
|
+
componentName: 'Select',
|
|
47
|
+
factory: 'createSelectTokens',
|
|
48
|
+
helper: 'createSelectIntentPalette.ts',
|
|
49
|
+
themeFile: 'select.ts',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
sharedHelpers: ['componentFocusRing.ts'],
|
|
53
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
export type CompoundInteractionResolution = {
|
|
2
|
+
readonly strategy: 'selected-variant' | 'disabled-wins' | 'orthogonal-focus' | 'domain-specific-active';
|
|
3
|
+
readonly semanticPath: string | null;
|
|
4
|
+
readonly meaning: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Companion contract for Interaction State Vocabulary V1 (#882).
|
|
8
|
+
*
|
|
9
|
+
* State names and their meanings remain owned by token-architecture.ts. This
|
|
10
|
+
* contract only defines how selected composes with every other canonical state
|
|
11
|
+
* so renderers and generators cannot invent precedence rules independently.
|
|
12
|
+
*/
|
|
13
|
+
export declare const selectedCompoundStateGrammarV1: {
|
|
14
|
+
readonly default: {
|
|
15
|
+
readonly strategy: "selected-variant";
|
|
16
|
+
readonly semanticPath: "semantic.control.selected.default";
|
|
17
|
+
readonly meaning: "Selected resting presentation.";
|
|
18
|
+
};
|
|
19
|
+
readonly hover: {
|
|
20
|
+
readonly strategy: "selected-variant";
|
|
21
|
+
readonly semanticPath: "semantic.control.selected.hover";
|
|
22
|
+
readonly meaning: "Selected plus pointer hover when the platform supports hover.";
|
|
23
|
+
};
|
|
24
|
+
readonly pressed: {
|
|
25
|
+
readonly strategy: "selected-variant";
|
|
26
|
+
readonly semanticPath: "semantic.control.selected.pressed";
|
|
27
|
+
readonly meaning: "Selected plus transient physical pointer/key press.";
|
|
28
|
+
};
|
|
29
|
+
readonly active: {
|
|
30
|
+
readonly strategy: "domain-specific-active";
|
|
31
|
+
readonly semanticPath: null;
|
|
32
|
+
readonly meaning: "Selected may combine with active only in a registered persistent/current active domain; active is never physical press.";
|
|
33
|
+
};
|
|
34
|
+
readonly selected: {
|
|
35
|
+
readonly strategy: "selected-variant";
|
|
36
|
+
readonly semanticPath: "semantic.control.selected.default";
|
|
37
|
+
readonly meaning: "Idempotent selected state resolves to the selected baseline.";
|
|
38
|
+
};
|
|
39
|
+
readonly disabled: {
|
|
40
|
+
readonly strategy: "disabled-wins";
|
|
41
|
+
readonly semanticPath: "semantic.control.disabled";
|
|
42
|
+
readonly meaning: "Disabled suppresses transient hover/press interaction. Components may preserve selected identity with component-level selected+disabled paint.";
|
|
43
|
+
};
|
|
44
|
+
readonly focus: {
|
|
45
|
+
readonly strategy: "orthogonal-focus";
|
|
46
|
+
readonly semanticPath: "semantic.focus.ring";
|
|
47
|
+
readonly meaning: "Focus indication composes orthogonally with selection and does not replace the selected paint state.";
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export type PlatformInteractionStateMapping = {
|
|
51
|
+
readonly support: 'required' | 'optional';
|
|
52
|
+
readonly signal: string;
|
|
53
|
+
readonly meaning: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Platform event/state mapping for the canonical vocabulary.
|
|
57
|
+
*
|
|
58
|
+
* React Native hover is deliberately optional: pointer-capable RN targets may
|
|
59
|
+
* expose it, but native parity never requires hover where the platform has no
|
|
60
|
+
* hover capability.
|
|
61
|
+
*/
|
|
62
|
+
export declare const interactionStatePlatformContractV1: {
|
|
63
|
+
readonly web: {
|
|
64
|
+
readonly default: {
|
|
65
|
+
readonly support: "required";
|
|
66
|
+
readonly signal: "rest";
|
|
67
|
+
readonly meaning: "Resting enabled presentation.";
|
|
68
|
+
};
|
|
69
|
+
readonly hover: {
|
|
70
|
+
readonly support: "required";
|
|
71
|
+
readonly signal: ":hover";
|
|
72
|
+
readonly meaning: "Pointer hover only.";
|
|
73
|
+
};
|
|
74
|
+
readonly pressed: {
|
|
75
|
+
readonly support: "required";
|
|
76
|
+
readonly signal: ":active";
|
|
77
|
+
readonly meaning: "Transient pointer/key activation while held.";
|
|
78
|
+
};
|
|
79
|
+
readonly active: {
|
|
80
|
+
readonly support: "required";
|
|
81
|
+
readonly signal: "domain-current";
|
|
82
|
+
readonly meaning: "Persistent/current domain state, never the CSS :active press.";
|
|
83
|
+
};
|
|
84
|
+
readonly selected: {
|
|
85
|
+
readonly support: "required";
|
|
86
|
+
readonly signal: ":checked-or-aria-selected";
|
|
87
|
+
readonly meaning: "Persistent chosen/checked/selected state.";
|
|
88
|
+
};
|
|
89
|
+
readonly disabled: {
|
|
90
|
+
readonly support: "required";
|
|
91
|
+
readonly signal: ":disabled-or-aria-disabled";
|
|
92
|
+
readonly meaning: "Unavailable interaction state.";
|
|
93
|
+
};
|
|
94
|
+
readonly focus: {
|
|
95
|
+
readonly support: "required";
|
|
96
|
+
readonly signal: ":focus-visible-or-focus";
|
|
97
|
+
readonly meaning: "Current input focus indication.";
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
readonly 'react-native': {
|
|
101
|
+
readonly default: {
|
|
102
|
+
readonly support: "required";
|
|
103
|
+
readonly signal: "rest";
|
|
104
|
+
readonly meaning: "Resting enabled presentation.";
|
|
105
|
+
};
|
|
106
|
+
readonly hover: {
|
|
107
|
+
readonly support: "optional";
|
|
108
|
+
readonly signal: "pointer-hover-when-capable";
|
|
109
|
+
readonly meaning: "Optional pointer hover on targets that expose hover capability.";
|
|
110
|
+
};
|
|
111
|
+
readonly pressed: {
|
|
112
|
+
readonly support: "required";
|
|
113
|
+
readonly signal: "PressableStateCallbackType.pressed";
|
|
114
|
+
readonly meaning: "Transient physical press reported by Pressable state.";
|
|
115
|
+
};
|
|
116
|
+
readonly active: {
|
|
117
|
+
readonly support: "required";
|
|
118
|
+
readonly signal: "domain-current";
|
|
119
|
+
readonly meaning: "Persistent/current domain state, never Pressable.pressed.";
|
|
120
|
+
};
|
|
121
|
+
readonly selected: {
|
|
122
|
+
readonly support: "required";
|
|
123
|
+
readonly signal: "accessibilityState.checked-or-selected";
|
|
124
|
+
readonly meaning: "Persistent chosen/checked/selected state.";
|
|
125
|
+
};
|
|
126
|
+
readonly disabled: {
|
|
127
|
+
readonly support: "required";
|
|
128
|
+
readonly signal: "disabled-and-accessibilityState.disabled";
|
|
129
|
+
readonly meaning: "Unavailable interaction state.";
|
|
130
|
+
};
|
|
131
|
+
readonly focus: {
|
|
132
|
+
readonly support: "optional";
|
|
133
|
+
readonly signal: "focus-when-capable";
|
|
134
|
+
readonly meaning: "Focus indication on keyboard/TV/pointer-capable targets; not fabricated on targets without focus presentation.";
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=interaction-state-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-state-contract.d.ts","sourceRoot":"","sources":["../src/interaction-state-contract.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,CAAC,QAAQ,EACb,kBAAkB,GAClB,eAAe,GACf,kBAAkB,GAClB,wBAAwB,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C1C,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgF9C,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Companion contract for Interaction State Vocabulary V1 (#882).
|
|
3
|
+
*
|
|
4
|
+
* State names and their meanings remain owned by token-architecture.ts. This
|
|
5
|
+
* contract only defines how selected composes with every other canonical state
|
|
6
|
+
* so renderers and generators cannot invent precedence rules independently.
|
|
7
|
+
*/
|
|
8
|
+
export const selectedCompoundStateGrammarV1 = {
|
|
9
|
+
default: {
|
|
10
|
+
strategy: 'selected-variant',
|
|
11
|
+
semanticPath: 'semantic.control.selected.default',
|
|
12
|
+
meaning: 'Selected resting presentation.',
|
|
13
|
+
},
|
|
14
|
+
hover: {
|
|
15
|
+
strategy: 'selected-variant',
|
|
16
|
+
semanticPath: 'semantic.control.selected.hover',
|
|
17
|
+
meaning: 'Selected plus pointer hover when the platform supports hover.',
|
|
18
|
+
},
|
|
19
|
+
pressed: {
|
|
20
|
+
strategy: 'selected-variant',
|
|
21
|
+
semanticPath: 'semantic.control.selected.pressed',
|
|
22
|
+
meaning: 'Selected plus transient physical pointer/key press.',
|
|
23
|
+
},
|
|
24
|
+
active: {
|
|
25
|
+
strategy: 'domain-specific-active',
|
|
26
|
+
semanticPath: null,
|
|
27
|
+
meaning: 'Selected may combine with active only in a registered persistent/current active domain; active is never physical press.',
|
|
28
|
+
},
|
|
29
|
+
selected: {
|
|
30
|
+
strategy: 'selected-variant',
|
|
31
|
+
semanticPath: 'semantic.control.selected.default',
|
|
32
|
+
meaning: 'Idempotent selected state resolves to the selected baseline.',
|
|
33
|
+
},
|
|
34
|
+
disabled: {
|
|
35
|
+
strategy: 'disabled-wins',
|
|
36
|
+
semanticPath: 'semantic.control.disabled',
|
|
37
|
+
meaning: 'Disabled suppresses transient hover/press interaction. Components may preserve selected identity with component-level selected+disabled paint.',
|
|
38
|
+
},
|
|
39
|
+
focus: {
|
|
40
|
+
strategy: 'orthogonal-focus',
|
|
41
|
+
semanticPath: 'semantic.focus.ring',
|
|
42
|
+
meaning: 'Focus indication composes orthogonally with selection and does not replace the selected paint state.',
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Platform event/state mapping for the canonical vocabulary.
|
|
47
|
+
*
|
|
48
|
+
* React Native hover is deliberately optional: pointer-capable RN targets may
|
|
49
|
+
* expose it, but native parity never requires hover where the platform has no
|
|
50
|
+
* hover capability.
|
|
51
|
+
*/
|
|
52
|
+
export const interactionStatePlatformContractV1 = {
|
|
53
|
+
web: {
|
|
54
|
+
default: {
|
|
55
|
+
support: 'required',
|
|
56
|
+
signal: 'rest',
|
|
57
|
+
meaning: 'Resting enabled presentation.',
|
|
58
|
+
},
|
|
59
|
+
hover: {
|
|
60
|
+
support: 'required',
|
|
61
|
+
signal: ':hover',
|
|
62
|
+
meaning: 'Pointer hover only.',
|
|
63
|
+
},
|
|
64
|
+
pressed: {
|
|
65
|
+
support: 'required',
|
|
66
|
+
signal: ':active',
|
|
67
|
+
meaning: 'Transient pointer/key activation while held.',
|
|
68
|
+
},
|
|
69
|
+
active: {
|
|
70
|
+
support: 'required',
|
|
71
|
+
signal: 'domain-current',
|
|
72
|
+
meaning: 'Persistent/current domain state, never the CSS :active press.',
|
|
73
|
+
},
|
|
74
|
+
selected: {
|
|
75
|
+
support: 'required',
|
|
76
|
+
signal: ':checked-or-aria-selected',
|
|
77
|
+
meaning: 'Persistent chosen/checked/selected state.',
|
|
78
|
+
},
|
|
79
|
+
disabled: {
|
|
80
|
+
support: 'required',
|
|
81
|
+
signal: ':disabled-or-aria-disabled',
|
|
82
|
+
meaning: 'Unavailable interaction state.',
|
|
83
|
+
},
|
|
84
|
+
focus: {
|
|
85
|
+
support: 'required',
|
|
86
|
+
signal: ':focus-visible-or-focus',
|
|
87
|
+
meaning: 'Current input focus indication.',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
'react-native': {
|
|
91
|
+
default: {
|
|
92
|
+
support: 'required',
|
|
93
|
+
signal: 'rest',
|
|
94
|
+
meaning: 'Resting enabled presentation.',
|
|
95
|
+
},
|
|
96
|
+
hover: {
|
|
97
|
+
support: 'optional',
|
|
98
|
+
signal: 'pointer-hover-when-capable',
|
|
99
|
+
meaning: 'Optional pointer hover on targets that expose hover capability.',
|
|
100
|
+
},
|
|
101
|
+
pressed: {
|
|
102
|
+
support: 'required',
|
|
103
|
+
signal: 'PressableStateCallbackType.pressed',
|
|
104
|
+
meaning: 'Transient physical press reported by Pressable state.',
|
|
105
|
+
},
|
|
106
|
+
active: {
|
|
107
|
+
support: 'required',
|
|
108
|
+
signal: 'domain-current',
|
|
109
|
+
meaning: 'Persistent/current domain state, never Pressable.pressed.',
|
|
110
|
+
},
|
|
111
|
+
selected: {
|
|
112
|
+
support: 'required',
|
|
113
|
+
signal: 'accessibilityState.checked-or-selected',
|
|
114
|
+
meaning: 'Persistent chosen/checked/selected state.',
|
|
115
|
+
},
|
|
116
|
+
disabled: {
|
|
117
|
+
support: 'required',
|
|
118
|
+
signal: 'disabled-and-accessibilityState.disabled',
|
|
119
|
+
meaning: 'Unavailable interaction state.',
|
|
120
|
+
},
|
|
121
|
+
focus: {
|
|
122
|
+
support: 'optional',
|
|
123
|
+
signal: 'focus-when-capable',
|
|
124
|
+
meaning: 'Focus indication on keyboard/TV/pointer-capable targets; not fabricated on targets without focus presentation.',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type ComponentTokenBoundaryFinding = {
|
|
2
|
+
path: string;
|
|
3
|
+
reason: string;
|
|
4
|
+
};
|
|
5
|
+
/** Shared #884 boundary check; platform intents remain atomic contracts. */
|
|
6
|
+
export declare function scanCanonicalComponentTokens(value: unknown, path: string, findings: ComponentTokenBoundaryFinding[]): void;
|
|
7
|
+
//# sourceMappingURL=component-token-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-token-boundary.d.ts","sourceRoot":"","sources":["../../src/platform-output/component-token-boundary.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AASF,4EAA4E;AAC5E,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,6BAA6B,EAAE,GACxC,IAAI,CAoCN"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { isComponentPlatformIntent } from './component-token-intents.js';
|
|
2
|
+
const rendererKeys = new Set([
|
|
3
|
+
'web',
|
|
4
|
+
'native',
|
|
5
|
+
'reactNative',
|
|
6
|
+
'nativeMaxHeight',
|
|
7
|
+
]);
|
|
8
|
+
/** Shared #884 boundary check; platform intents remain atomic contracts. */
|
|
9
|
+
export function scanCanonicalComponentTokens(value, path, findings) {
|
|
10
|
+
if (isComponentPlatformIntent(value))
|
|
11
|
+
return;
|
|
12
|
+
if (Array.isArray(value)) {
|
|
13
|
+
value.forEach((entry, index) => scanCanonicalComponentTokens(entry, `${path}.${index}`, findings));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (typeof value !== 'object' || value === null) {
|
|
17
|
+
if (path.endsWith('.shadow') && typeof value === 'string') {
|
|
18
|
+
findings.push({
|
|
19
|
+
path,
|
|
20
|
+
reason: 'canonical shadow contains renderer-specific CSS syntax',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const [key, child] of Object.entries(value)) {
|
|
26
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
27
|
+
if (rendererKeys.has(key) ||
|
|
28
|
+
key.startsWith('native') ||
|
|
29
|
+
key.startsWith('reactNative')) {
|
|
30
|
+
findings.push({
|
|
31
|
+
path: childPath,
|
|
32
|
+
reason: `renderer-specific canonical key "${key}"`,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
scanCanonicalComponentTokens(child, childPath, findings);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -10,6 +10,25 @@ export declare const tokenPublicApiDeprecationPolicyV1: {
|
|
|
10
10
|
readonly removal: "Compatibility aliases introduced or retained during Token Architecture Normalization V1 are removed at the next major boundary, Vellira 3.0.0, unless a separately reviewed policy revision supersedes this contract.";
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
|
+
export declare const tokenPackagePublicSurfaceV1: {
|
|
14
|
+
readonly main: "./dist/index.js";
|
|
15
|
+
readonly types: "./dist/index.d.ts";
|
|
16
|
+
readonly exports: {
|
|
17
|
+
readonly '.': {
|
|
18
|
+
readonly 'react-native': {
|
|
19
|
+
readonly types: "./dist/index.d.ts";
|
|
20
|
+
readonly default: "./dist/index.js";
|
|
21
|
+
};
|
|
22
|
+
readonly 'vellira-source': "./src/index.ts";
|
|
23
|
+
readonly types: "./dist/index.d.ts";
|
|
24
|
+
readonly import: "./dist/index.js";
|
|
25
|
+
};
|
|
26
|
+
readonly './css': {
|
|
27
|
+
readonly types: "./css.d.ts";
|
|
28
|
+
readonly default: "./dist/css/tokens.css";
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
13
32
|
export declare const publicThemeContractsV1: readonly [{
|
|
14
33
|
readonly exportName: "lightTheme";
|
|
15
34
|
readonly themeName: "light";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api-policy.d.ts","sourceRoot":"","sources":["../src/public-api-policy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC;;;;;;;;;;;CAgBpC,CAAC;AAEX,eAAO,MAAM,sBAAsB;;;;;;;;;EAIzB,CAAC;AAEX,eAAO,MAAM,2BAA2B;;;;;;EAS9B,CAAC"}
|
|
1
|
+
{"version":3,"file":"public-api-policy.d.ts","sourceRoot":"","sources":["../src/public-api-policy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC;;;;;;;;;;;CAgBpC,CAAC;AAEX,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;CAkB9B,CAAC;AAEX,eAAO,MAAM,sBAAsB;;;;;;;;;EAIzB,CAAC;AAEX,eAAO,MAAM,2BAA2B;;;;;;EAS9B,CAAC"}
|
|
@@ -10,6 +10,25 @@ export const tokenPublicApiDeprecationPolicyV1 = {
|
|
|
10
10
|
removal: 'Compatibility aliases introduced or retained during Token Architecture Normalization V1 are removed at the next major boundary, Vellira 3.0.0, unless a separately reviewed policy revision supersedes this contract.',
|
|
11
11
|
},
|
|
12
12
|
};
|
|
13
|
+
export const tokenPackagePublicSurfaceV1 = {
|
|
14
|
+
main: './dist/index.js',
|
|
15
|
+
types: './dist/index.d.ts',
|
|
16
|
+
exports: {
|
|
17
|
+
'.': {
|
|
18
|
+
'react-native': {
|
|
19
|
+
types: './dist/index.d.ts',
|
|
20
|
+
default: './dist/index.js',
|
|
21
|
+
},
|
|
22
|
+
'vellira-source': './src/index.ts',
|
|
23
|
+
types: './dist/index.d.ts',
|
|
24
|
+
import: './dist/index.js',
|
|
25
|
+
},
|
|
26
|
+
'./css': {
|
|
27
|
+
types: './css.d.ts',
|
|
28
|
+
default: './dist/css/tokens.css',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
13
32
|
export const publicThemeContractsV1 = [
|
|
14
33
|
{ exportName: 'lightTheme', themeName: 'light' },
|
|
15
34
|
{ exportName: 'darkTheme', themeName: 'dark' },
|
|
@@ -181,8 +181,8 @@ export declare const semanticVocabularyV1: {
|
|
|
181
181
|
readonly roles: readonly ["default", "hover", "pressed", "selected", "disabled", "focus"];
|
|
182
182
|
};
|
|
183
183
|
readonly menu: {
|
|
184
|
-
readonly purpose: "Menu
|
|
185
|
-
readonly roles: readonly ["item", "item.danger"];
|
|
184
|
+
readonly purpose: "Menu container chrome plus item roles where active/current is a legitimate domain state.";
|
|
185
|
+
readonly roles: readonly ["background", "border", "item", "item.danger"];
|
|
186
186
|
};
|
|
187
187
|
readonly overlay: {
|
|
188
188
|
readonly purpose: "Reusable overlay surfaces named by presentation purpose, not component history.";
|
|
@@ -380,8 +380,8 @@ export const semanticVocabularyV1 = {
|
|
|
380
380
|
roles: ['default', 'hover', 'pressed', 'selected', 'disabled', 'focus'],
|
|
381
381
|
},
|
|
382
382
|
menu: {
|
|
383
|
-
purpose: 'Menu
|
|
384
|
-
roles: ['item', 'item.danger'],
|
|
383
|
+
purpose: 'Menu container chrome plus item roles where active/current is a legitimate domain state.',
|
|
384
|
+
roles: ['background', 'border', 'item', 'item.danger'],
|
|
385
385
|
},
|
|
386
386
|
overlay: {
|
|
387
387
|
purpose: 'Reusable overlay surfaces named by presentation purpose, not component history.',
|