@yahoo/uds 3.156.2 → 3.157.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 (144) hide show
  1. package/dist/automated-config/dist/generated/autoVariants.cjs +9 -4
  2. package/dist/automated-config/dist/generated/autoVariants.d.cts +2 -1
  3. package/dist/automated-config/dist/generated/autoVariants.d.ts +2 -1
  4. package/dist/automated-config/dist/generated/autoVariants.js +9 -4
  5. package/dist/automated-config/dist/generated/generatedConfigs.cjs +3011 -3038
  6. package/dist/automated-config/dist/generated/generatedConfigs.d.cts +143 -140
  7. package/dist/automated-config/dist/generated/generatedConfigs.d.ts +143 -140
  8. package/dist/automated-config/dist/generated/generatedConfigs.js +3011 -3038
  9. package/dist/automated-config/dist/generated/universalTokensConfigAuto.cjs +1227 -501
  10. package/dist/automated-config/dist/generated/universalTokensConfigAuto.js +1227 -501
  11. package/dist/automated-config/dist/properties.cjs +1 -1
  12. package/dist/automated-config/dist/properties.d.cts +15 -0
  13. package/dist/automated-config/dist/properties.d.ts +15 -0
  14. package/dist/automated-config/dist/properties.js +1 -1
  15. package/dist/automated-config/dist/types/ComponentConfig.d.cts +77 -4
  16. package/dist/automated-config/dist/types/ComponentConfig.d.ts +77 -4
  17. package/dist/automated-config/dist/types/ConfigSchema.d.cts +14 -2
  18. package/dist/automated-config/dist/types/ConfigSchema.d.ts +14 -2
  19. package/dist/automated-config/dist/types/StateAxis.cjs +90 -0
  20. package/dist/automated-config/dist/types/StateAxis.d.cts +70 -0
  21. package/dist/automated-config/dist/types/StateAxis.d.ts +70 -0
  22. package/dist/automated-config/dist/types/StateAxis.js +84 -0
  23. package/dist/automated-config/dist/utils/buildConfigSchema.cjs +98 -82
  24. package/dist/automated-config/dist/utils/buildConfigSchema.d.cts +32 -10
  25. package/dist/automated-config/dist/utils/buildConfigSchema.d.ts +32 -10
  26. package/dist/automated-config/dist/utils/buildConfigSchema.js +99 -83
  27. package/dist/automated-config/dist/utils/canonicalizeStateKey.cjs +32 -0
  28. package/dist/automated-config/dist/utils/canonicalizeStateKey.d.cts +48 -0
  29. package/dist/automated-config/dist/utils/canonicalizeStateKey.d.ts +48 -0
  30. package/dist/automated-config/dist/utils/canonicalizeStateKey.js +31 -0
  31. package/dist/automated-config/dist/utils/getConfigComponentVariant.d.cts +8 -0
  32. package/dist/automated-config/dist/utils/getConfigComponentVariant.d.ts +8 -0
  33. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.cts +3 -3
  34. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +3 -3
  35. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.cjs +12 -5
  36. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.d.cts +8 -1
  37. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.d.ts +8 -1
  38. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.js +12 -5
  39. package/dist/automated-config/dist/utils/index.cjs +407 -97
  40. package/dist/automated-config/dist/utils/index.d.cts +66 -16
  41. package/dist/automated-config/dist/utils/index.d.ts +66 -16
  42. package/dist/automated-config/dist/utils/index.js +408 -99
  43. package/dist/automated-config/dist/utils/pseudoStateSelectors.cjs +122 -0
  44. package/dist/automated-config/dist/utils/pseudoStateSelectors.d.cts +80 -0
  45. package/dist/automated-config/dist/utils/pseudoStateSelectors.d.ts +80 -0
  46. package/dist/automated-config/dist/utils/pseudoStateSelectors.js +120 -0
  47. package/dist/automated-config/dist/utils/resolvePropertyStates.cjs +131 -0
  48. package/dist/automated-config/dist/utils/resolvePropertyStates.d.cts +49 -0
  49. package/dist/automated-config/dist/utils/resolvePropertyStates.d.ts +49 -0
  50. package/dist/automated-config/dist/utils/resolvePropertyStates.js +130 -0
  51. package/dist/automated-config/dist/utils/resolveSlotByCascade.cjs +118 -0
  52. package/dist/automated-config/dist/utils/resolveSlotByCascade.d.cts +68 -0
  53. package/dist/automated-config/dist/utils/resolveSlotByCascade.d.ts +68 -0
  54. package/dist/automated-config/dist/utils/resolveSlotByCascade.js +117 -0
  55. package/dist/automated-config/dist/utils/variantConfigGuards.d.cts +13 -0
  56. package/dist/automated-config/dist/utils/variantConfigGuards.d.ts +13 -0
  57. package/dist/components/client/Input/Input.cjs +42 -6
  58. package/dist/components/client/Input/Input.d.cts +13 -0
  59. package/dist/components/client/Input/Input.d.ts +13 -0
  60. package/dist/components/client/Input/Input.js +42 -6
  61. package/dist/config/dist/index.cjs +221 -550
  62. package/dist/config/dist/index.js +221 -550
  63. package/dist/css/dist/commands/css.cjs +1 -0
  64. package/dist/css/dist/commands/css.helpers.cjs +6 -0
  65. package/dist/css/dist/commands/css.helpers.js +6 -0
  66. package/dist/css/dist/commands/css.js +1 -0
  67. package/dist/css/dist/css/generate.cjs +4 -2
  68. package/dist/css/dist/css/generate.d.cts +28 -0
  69. package/dist/css/dist/css/generate.d.ts +28 -0
  70. package/dist/css/dist/css/generate.helpers.cjs +5 -1
  71. package/dist/css/dist/css/generate.helpers.js +6 -2
  72. package/dist/css/dist/css/generate.js +4 -2
  73. package/dist/css/dist/css/postcss.cjs +81 -0
  74. package/dist/css/dist/css/postcss.helpers.cjs +60 -0
  75. package/dist/css/dist/css/postcss.helpers.js +59 -1
  76. package/dist/css/dist/css/postcss.js +82 -2
  77. package/dist/css/dist/css/runner.cjs +12 -2
  78. package/dist/css/dist/css/runner.js +12 -2
  79. package/dist/css/dist/css/theme.d.cts +6 -0
  80. package/dist/css/dist/css/theme.d.ts +6 -0
  81. package/dist/css/dist/packages/automated-config/dist/properties.cjs +1 -1
  82. package/dist/css/dist/packages/automated-config/dist/properties.js +1 -1
  83. package/dist/css/dist/packages/automated-config/dist/utils/index.d.cts +6 -0
  84. package/dist/css/dist/packages/automated-config/dist/utils/index.d.ts +6 -0
  85. package/dist/css/dist/packages/config/dist/index.cjs +221 -550
  86. package/dist/css/dist/packages/config/dist/index.js +221 -550
  87. package/dist/css/dist/utils/optimizeCSS.cjs +59 -0
  88. package/dist/css/dist/utils/optimizeCSS.js +59 -0
  89. package/dist/index.cjs +25 -0
  90. package/dist/index.d.cts +10 -3
  91. package/dist/index.d.ts +10 -3
  92. package/dist/index.js +9 -2
  93. package/dist/styles/styler.d.cts +12 -11
  94. package/dist/styles/styler.d.ts +12 -11
  95. package/dist/styles/variants.d.cts +9 -4
  96. package/dist/styles/variants.d.ts +9 -4
  97. package/dist/tailwind-internal/dist/packages/automated-config/dist/generated/generatedConfigs.cjs +3011 -3038
  98. package/dist/tailwind-internal/dist/packages/automated-config/dist/generated/generatedConfigs.js +3011 -3038
  99. package/dist/tailwind-internal/dist/packages/automated-config/dist/properties.cjs +1 -1
  100. package/dist/tailwind-internal/dist/packages/automated-config/dist/properties.js +1 -1
  101. package/dist/tailwind-internal/dist/packages/automated-config/dist/types/StateAxis.cjs +81 -0
  102. package/dist/tailwind-internal/dist/packages/automated-config/dist/types/StateAxis.js +76 -0
  103. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/canonicalizeStateKey.cjs +33 -0
  104. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/canonicalizeStateKey.js +32 -0
  105. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/componentStatePseudoStates.cjs +0 -7
  106. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/componentStatePseudoStates.js +1 -7
  107. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.cjs +354 -97
  108. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.d.cts +6 -0
  109. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.d.ts +6 -0
  110. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.js +355 -98
  111. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.cjs +122 -0
  112. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.js +121 -0
  113. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.cjs +132 -0
  114. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.js +131 -0
  115. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.cjs +95 -0
  116. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.js +95 -0
  117. package/dist/tailwind-internal/dist/packages/config/dist/index.cjs +221 -550
  118. package/dist/tailwind-internal/dist/packages/config/dist/index.js +221 -550
  119. package/dist/tailwind-internal/dist/plugins/components.cjs +28 -24
  120. package/dist/tailwind-internal/dist/plugins/components.js +28 -24
  121. package/dist/tailwind-internal/dist/utils/composeTailwindPlugins.d.cts +3 -0
  122. package/dist/tailwind-internal/dist/utils/composeTailwindPlugins.d.ts +3 -0
  123. package/dist/tailwind-internal/dist/utils/getShadowStyles.d.cts +2 -2
  124. package/dist/tailwind-internal/dist/utils/getShadowStyles.d.ts +2 -2
  125. package/dist/tokens/automation/index.cjs +25 -0
  126. package/dist/tokens/automation/index.d.cts +9 -2
  127. package/dist/tokens/automation/index.d.ts +9 -2
  128. package/dist/tokens/automation/index.js +9 -2
  129. package/dist/tokens/index.cjs +25 -0
  130. package/dist/tokens/index.d.cts +10 -3
  131. package/dist/tokens/index.d.ts +10 -3
  132. package/dist/tokens/index.js +9 -2
  133. package/dist/tokens/types.d.cts +1 -1
  134. package/dist/tokens/types.d.ts +1 -1
  135. package/dist/uds/generated/componentData.cjs +2202 -2200
  136. package/dist/uds/generated/componentData.js +2202 -2200
  137. package/dist/uds/generated/migrationSchemaVersion.cjs +1 -1
  138. package/dist/uds/generated/migrationSchemaVersion.js +1 -1
  139. package/dist/uds/generated/tailwindPurge.cjs +79 -78
  140. package/dist/uds/generated/tailwindPurge.js +79 -78
  141. package/generated/componentData.json +2720 -2718
  142. package/generated/migrationSchemaVersion.ts +1 -1
  143. package/generated/tailwindPurge.ts +2 -2
  144. package/package.json +1 -1
@@ -7,7 +7,7 @@ const require_index$1 = require("../../motion-tokens/dist/index.cjs");
7
7
  //#region ../automated-config/dist/properties.js
8
8
  /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
9
9
  const isInputWrapperCtx = (context) => {
10
- return context.componentName === "input" && context.layer === "inputWrapper";
10
+ return context.componentName === "input" && (context.layer === "inputWrapper" || context.layer === "inputWrapperDynamic");
11
11
  };
12
12
  const hexToRgb = (hex) => {
13
13
  hex = hex.replace("#", "");
@@ -1,4 +1,5 @@
1
1
 
2
+ import { AtomicState } from "./types/StateAxis.cjs";
2
3
  import { ShadowPreset } from "../../types/dist/index.cjs";
3
4
  import { ArbitraryFixtures, InferArbitraryType } from "../../fixtures/dist/index.cjs";
4
5
  import { AllPossibleProperties, PossibleStates } from "./types/ComponentConfig.cjs";
@@ -130,7 +131,21 @@ interface SelectedConfigurableProperty<C extends ConfigurablePropertiesName, O e
130
131
  typeOfFixture: T;
131
132
  values: V;
132
133
  skipRestState?: boolean;
134
+ /**
135
+ * Per-property pseudo state list (legacy). New components should declare
136
+ * atomic states at the layer level via `atomicStates` and use
137
+ * `excludeAtomics` here to opt out. Both paths are supported by the
138
+ * resolver — `resolvePropertyStates` falls back to this list when the
139
+ * parent layer has no `atomicStates`.
140
+ */
133
141
  pseudoStates?: PossibleStates[];
142
+ /**
143
+ * Atomic states the property should NOT react to, even when the parent
144
+ * layer's `atomicStates` includes them. Use sparingly — for properties whose
145
+ * visual change for a given state is meaningless (e.g., a font weight that
146
+ * shouldn't shift on `:placeholder-shown`).
147
+ */
148
+ excludeAtomics?: AtomicState[];
134
149
  supportsCustom?: boolean;
135
150
  layerReference?: {
136
151
  variablePath: string;
@@ -1,4 +1,5 @@
1
1
 
2
+ import { AtomicState } from "./types/StateAxis.js";
2
3
  import { ShadowPreset } from "../../types/dist/index.js";
3
4
  import { ArbitraryFixtures, InferArbitraryType } from "../../fixtures/dist/index.js";
4
5
  import { AllPossibleProperties, PossibleStates } from "./types/ComponentConfig.js";
@@ -130,7 +131,21 @@ interface SelectedConfigurableProperty<C extends ConfigurablePropertiesName, O e
130
131
  typeOfFixture: T;
131
132
  values: V;
132
133
  skipRestState?: boolean;
134
+ /**
135
+ * Per-property pseudo state list (legacy). New components should declare
136
+ * atomic states at the layer level via `atomicStates` and use
137
+ * `excludeAtomics` here to opt out. Both paths are supported by the
138
+ * resolver — `resolvePropertyStates` falls back to this list when the
139
+ * parent layer has no `atomicStates`.
140
+ */
133
141
  pseudoStates?: PossibleStates[];
142
+ /**
143
+ * Atomic states the property should NOT react to, even when the parent
144
+ * layer's `atomicStates` includes them. Use sparingly — for properties whose
145
+ * visual change for a given state is meaningless (e.g., a font weight that
146
+ * shouldn't shift on `:placeholder-shown`).
147
+ */
148
+ excludeAtomics?: AtomicState[];
134
149
  supportsCustom?: boolean;
135
150
  layerReference?: {
136
151
  variablePath: string;
@@ -7,7 +7,7 @@ import { SCALE_EFFECTS } from "../../motion-tokens/dist/index.js";
7
7
  //#region ../automated-config/dist/properties.js
8
8
  /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
9
9
  const isInputWrapperCtx = (context) => {
10
- return context.componentName === "input" && context.layer === "inputWrapper";
10
+ return context.componentName === "input" && (context.layer === "inputWrapper" || context.layer === "inputWrapperDynamic");
11
11
  };
12
12
  const hexToRgb = (hex) => {
13
13
  hex = hex.replace("#", "");
@@ -1,4 +1,5 @@
1
1
 
2
+ import { AtomicState, InteractiveAtomic, ModifierAtomic } from "./StateAxis.cjs";
2
3
  import { index_d_exports } from "../../../fixtures/dist/index.cjs";
3
4
  import { ConfigurablePropertiesName, SelectedConfigurableProperty } from "../properties.cjs";
4
5
 
@@ -6,8 +7,35 @@ import { ConfigurablePropertiesName, SelectedConfigurableProperty } from "../pro
6
7
  //#region src/types/ComponentConfig.d.ts
7
8
  /** All configurable property names, excluding button-specific and elevation properties */
8
9
  type AllPossibleProperties = Exclude<keyof typeof index_d_exports, 'iconButtonSize' | 'buttonIconSvgSize' | 'buttonPalettes' | 'buttonStates'> | 'shadowVariantConfig';
9
- /** All possible interactive states a component can have. Compound states use & (e.g., invalid&hover) */
10
- type PossibleStates = 'hover' | 'pressed' | 'focused' | 'invalid' | 'focus-within' | 'focused-keyboard' | 'visited' | 'readonly' | 'disabled' | 'invalid&hover' | 'invalid&pressed';
10
+ /**
11
+ * Legacy atomic state literals still in use by unmigrated configs via the
12
+ * per-property `pseudoStates` array. These aren't part of the new `StateAxis`
13
+ * taxonomy (so the resolver and StateBuilder don't auto-compose them) but
14
+ * configs that still ship them must continue to typecheck and the CSS
15
+ * generator must still resolve their selectors. Drop entries as components
16
+ * migrate to layer-level `atomicStates`.
17
+ */
18
+ type LegacyStateLiteral = 'disabled' | 'focused' | 'focused-keyboard';
19
+ /**
20
+ * All possible state keys a property can be styled for. Encoded structure
21
+ * matches the resolver's enumeration and the StateBuilder's depth cap: 0..3
22
+ * modifiers followed optionally by 1 interactive (canonical form is
23
+ * `'modifier1&modifier2&...&interactive'` — see `canonicalizeStateKey`).
24
+ *
25
+ * The structure-aware form catches malformed compounds at compile time —
26
+ * `'hover&pressed'` (two interactives) and `'foo&hover'` (unknown atom)
27
+ * both fail to typecheck.
28
+ *
29
+ * What the type does NOT catch:
30
+ * - Unsorted modifiers (`'readonly&invalid'` typechecks; canonical form is
31
+ * `'invalid&readonly'`, produced by `canonicalizeStateKey`).
32
+ * - Duplicate atoms (`'invalid&invalid'` typechecks; `canonicalizeStateKey`
33
+ * dedupes within a key).
34
+ *
35
+ * Legacy atoms (`disabled`, `focused`, `focused-keyboard`) are accepted as
36
+ * standalone keys for unmigrated configs only — they aren't composable.
37
+ */
38
+ type PossibleStates = AtomicState | LegacyStateLiteral | `${ModifierAtomic}&${InteractiveAtomic}` | `${ModifierAtomic}&${ModifierAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${InteractiveAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${ModifierAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${ModifierAtomic}&${InteractiveAtomic}`;
11
39
  /** PossibleStates plus 'rest' for the default/inactive state */
12
40
  type PossibleStatesWithRest = 'rest' | PossibleStates;
13
41
  /** Configuration for a single visual layer with its properties and optional pseudo-selector */
@@ -15,6 +43,20 @@ interface LayerConfig {
15
43
  label: string;
16
44
  properties: Readonly<Record<string, SelectedConfigurableProperty<ConfigurablePropertiesName, string>>>;
17
45
  pseudoSelector?: string;
46
+ /**
47
+ * Atomic states this layer can style. Properties on the layer auto-react to
48
+ * each declared atom plus every auto-generated compound up to
49
+ * `MAX_MODIFIERS_PER_COMPOUND` modifiers (currently 3) optionally combined
50
+ * with one interactive — i.e. M, M&M, M&M&M, M&I, M&M&I, and M&M&M&I forms,
51
+ * minus pairs the browser suppresses (e.g. `disabled&hover`). Properties
52
+ * opt out of specific atoms via `excludeAtomics` on
53
+ * `createConfigurableProperty`.
54
+ *
55
+ * Layers without `atomicStates` fall back to the legacy per-property
56
+ * `pseudoStates` array — this lets unmigrated configs keep their behavior
57
+ * while components are migrated incrementally.
58
+ */
59
+ atomicStates?: AtomicState[];
18
60
  }
19
61
  /** Configuration for a specific component state with its options and layer properties */
20
62
  interface ComponentStateConfig {
@@ -22,7 +64,14 @@ interface ComponentStateConfig {
22
64
  options: readonly string[];
23
65
  /** Pseudo-states to omit for specific component state options (e.g. active/on). */
24
66
  excludePseudoStatesForOptions?: Partial<Record<string, readonly PossibleStates[]>>;
25
- layers: {
67
+ /**
68
+ * @deprecated Per-state property overrides are now authored at the schema
69
+ * level (Configurator UI, migrations), not in source configs. Each
70
+ * componentState only declares its options here; CSS emission picks up
71
+ * per-state schema entries automatically. Retained as optional so
72
+ * pre-existing configs still typecheck during migration to the new shape.
73
+ */
74
+ layers?: {
26
75
  root: LayerConfig;
27
76
  } & Record<string, LayerConfig>;
28
77
  }
@@ -47,9 +96,33 @@ interface VariantConfigWithProperties<O extends string = string> extends Variant
47
96
  /** Properties scoped to the variant option (e.g. size/sm/width without a layer). */
48
97
  variantProperties?: Readonly<Record<string, SelectedConfigurableProperty<ConfigurablePropertiesName, string>>>;
49
98
  }
50
- /** Variant with component state definitions (hover, focus, etc.) for each option */
99
+ /**
100
+ * Variant with component state definitions (hover, focus, etc.) for each option.
101
+ *
102
+ * **KNOWN GAP — multi-axis componentStates aren't fully supported end-to-end.**
103
+ * The type permits `componentStates: Record<string, ComponentStateConfig>` with
104
+ * more than one key, and the configurator's StateBuilder renders one picker
105
+ * row per axis, but the pipeline below the picker (schema-key generator,
106
+ * `buildConfigSchema`, the CSS-selector composition in `generateDeclaration`,
107
+ * and the configurator's write path) all assume a single axis. Adding a
108
+ * second axis today lets the user choose a value on it visually, but only
109
+ * one axis's selection survives the round-trip into the stored schema —
110
+ * compound combinations like `value=filled & disabled=true` can't be
111
+ * addressed as their own override slot. Stick to a single componentState
112
+ * axis per variant until this is generalized end-to-end.
113
+ */
51
114
  interface VariantConfigWithComponentStates<O extends string = string> extends VariantConfig<O> {
52
115
  componentStates: Readonly<Record<string, ComponentStateConfig>>;
116
+ /**
117
+ * Optional layers that apply to the variant universally, regardless of any
118
+ * component state. Properties declared here emit CSS at single-class
119
+ * specificity (0,1,0); per-state schema overrides (added at runtime by the
120
+ * Configurator or by data migrations) emit at compound-class specificity
121
+ * (0,2,0)+ and win via the cascade.
122
+ */
123
+ layers?: {
124
+ root: LayerConfig;
125
+ } & Record<string, LayerConfig>;
53
126
  }
54
127
  /** Top-level component configuration with variants and optional sub-components */
55
128
  interface ComponentConfig {
@@ -1,4 +1,5 @@
1
1
 
2
+ import { AtomicState, InteractiveAtomic, ModifierAtomic } from "./StateAxis.js";
2
3
  import { index_d_exports } from "../../../fixtures/dist/index.js";
3
4
  import { ConfigurablePropertiesName, SelectedConfigurableProperty } from "../properties.js";
4
5
 
@@ -6,8 +7,35 @@ import { ConfigurablePropertiesName, SelectedConfigurableProperty } from "../pro
6
7
  //#region src/types/ComponentConfig.d.ts
7
8
  /** All configurable property names, excluding button-specific and elevation properties */
8
9
  type AllPossibleProperties = Exclude<keyof typeof index_d_exports, 'iconButtonSize' | 'buttonIconSvgSize' | 'buttonPalettes' | 'buttonStates'> | 'shadowVariantConfig';
9
- /** All possible interactive states a component can have. Compound states use & (e.g., invalid&hover) */
10
- type PossibleStates = 'hover' | 'pressed' | 'focused' | 'invalid' | 'focus-within' | 'focused-keyboard' | 'visited' | 'readonly' | 'disabled' | 'invalid&hover' | 'invalid&pressed';
10
+ /**
11
+ * Legacy atomic state literals still in use by unmigrated configs via the
12
+ * per-property `pseudoStates` array. These aren't part of the new `StateAxis`
13
+ * taxonomy (so the resolver and StateBuilder don't auto-compose them) but
14
+ * configs that still ship them must continue to typecheck and the CSS
15
+ * generator must still resolve their selectors. Drop entries as components
16
+ * migrate to layer-level `atomicStates`.
17
+ */
18
+ type LegacyStateLiteral = 'disabled' | 'focused' | 'focused-keyboard';
19
+ /**
20
+ * All possible state keys a property can be styled for. Encoded structure
21
+ * matches the resolver's enumeration and the StateBuilder's depth cap: 0..3
22
+ * modifiers followed optionally by 1 interactive (canonical form is
23
+ * `'modifier1&modifier2&...&interactive'` — see `canonicalizeStateKey`).
24
+ *
25
+ * The structure-aware form catches malformed compounds at compile time —
26
+ * `'hover&pressed'` (two interactives) and `'foo&hover'` (unknown atom)
27
+ * both fail to typecheck.
28
+ *
29
+ * What the type does NOT catch:
30
+ * - Unsorted modifiers (`'readonly&invalid'` typechecks; canonical form is
31
+ * `'invalid&readonly'`, produced by `canonicalizeStateKey`).
32
+ * - Duplicate atoms (`'invalid&invalid'` typechecks; `canonicalizeStateKey`
33
+ * dedupes within a key).
34
+ *
35
+ * Legacy atoms (`disabled`, `focused`, `focused-keyboard`) are accepted as
36
+ * standalone keys for unmigrated configs only — they aren't composable.
37
+ */
38
+ type PossibleStates = AtomicState | LegacyStateLiteral | `${ModifierAtomic}&${InteractiveAtomic}` | `${ModifierAtomic}&${ModifierAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${InteractiveAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${ModifierAtomic}` | `${ModifierAtomic}&${ModifierAtomic}&${ModifierAtomic}&${InteractiveAtomic}`;
11
39
  /** PossibleStates plus 'rest' for the default/inactive state */
12
40
  type PossibleStatesWithRest = 'rest' | PossibleStates;
13
41
  /** Configuration for a single visual layer with its properties and optional pseudo-selector */
@@ -15,6 +43,20 @@ interface LayerConfig {
15
43
  label: string;
16
44
  properties: Readonly<Record<string, SelectedConfigurableProperty<ConfigurablePropertiesName, string>>>;
17
45
  pseudoSelector?: string;
46
+ /**
47
+ * Atomic states this layer can style. Properties on the layer auto-react to
48
+ * each declared atom plus every auto-generated compound up to
49
+ * `MAX_MODIFIERS_PER_COMPOUND` modifiers (currently 3) optionally combined
50
+ * with one interactive — i.e. M, M&M, M&M&M, M&I, M&M&I, and M&M&M&I forms,
51
+ * minus pairs the browser suppresses (e.g. `disabled&hover`). Properties
52
+ * opt out of specific atoms via `excludeAtomics` on
53
+ * `createConfigurableProperty`.
54
+ *
55
+ * Layers without `atomicStates` fall back to the legacy per-property
56
+ * `pseudoStates` array — this lets unmigrated configs keep their behavior
57
+ * while components are migrated incrementally.
58
+ */
59
+ atomicStates?: AtomicState[];
18
60
  }
19
61
  /** Configuration for a specific component state with its options and layer properties */
20
62
  interface ComponentStateConfig {
@@ -22,7 +64,14 @@ interface ComponentStateConfig {
22
64
  options: readonly string[];
23
65
  /** Pseudo-states to omit for specific component state options (e.g. active/on). */
24
66
  excludePseudoStatesForOptions?: Partial<Record<string, readonly PossibleStates[]>>;
25
- layers: {
67
+ /**
68
+ * @deprecated Per-state property overrides are now authored at the schema
69
+ * level (Configurator UI, migrations), not in source configs. Each
70
+ * componentState only declares its options here; CSS emission picks up
71
+ * per-state schema entries automatically. Retained as optional so
72
+ * pre-existing configs still typecheck during migration to the new shape.
73
+ */
74
+ layers?: {
26
75
  root: LayerConfig;
27
76
  } & Record<string, LayerConfig>;
28
77
  }
@@ -47,9 +96,33 @@ interface VariantConfigWithProperties<O extends string = string> extends Variant
47
96
  /** Properties scoped to the variant option (e.g. size/sm/width without a layer). */
48
97
  variantProperties?: Readonly<Record<string, SelectedConfigurableProperty<ConfigurablePropertiesName, string>>>;
49
98
  }
50
- /** Variant with component state definitions (hover, focus, etc.) for each option */
99
+ /**
100
+ * Variant with component state definitions (hover, focus, etc.) for each option.
101
+ *
102
+ * **KNOWN GAP — multi-axis componentStates aren't fully supported end-to-end.**
103
+ * The type permits `componentStates: Record<string, ComponentStateConfig>` with
104
+ * more than one key, and the configurator's StateBuilder renders one picker
105
+ * row per axis, but the pipeline below the picker (schema-key generator,
106
+ * `buildConfigSchema`, the CSS-selector composition in `generateDeclaration`,
107
+ * and the configurator's write path) all assume a single axis. Adding a
108
+ * second axis today lets the user choose a value on it visually, but only
109
+ * one axis's selection survives the round-trip into the stored schema —
110
+ * compound combinations like `value=filled & disabled=true` can't be
111
+ * addressed as their own override slot. Stick to a single componentState
112
+ * axis per variant until this is generalized end-to-end.
113
+ */
51
114
  interface VariantConfigWithComponentStates<O extends string = string> extends VariantConfig<O> {
52
115
  componentStates: Readonly<Record<string, ComponentStateConfig>>;
116
+ /**
117
+ * Optional layers that apply to the variant universally, regardless of any
118
+ * component state. Properties declared here emit CSS at single-class
119
+ * specificity (0,1,0); per-state schema overrides (added at runtime by the
120
+ * Configurator or by data migrations) emit at compound-class specificity
121
+ * (0,2,0)+ and win via the cascade.
122
+ */
123
+ layers?: {
124
+ root: LayerConfig;
125
+ } & Record<string, LayerConfig>;
53
126
  }
54
127
  /** Top-level component configuration with variants and optional sub-components */
55
128
  interface ComponentConfig {
@@ -1,5 +1,5 @@
1
1
 
2
- import { AllPossibleProperties } from "./ComponentConfig.cjs";
2
+ import { AllPossibleProperties, PossibleStates } from "./ComponentConfig.cjs";
3
3
 
4
4
  //#region ../automated-config/dist/types/ConfigSchema.d.ts
5
5
  //#region src/types/ConfigSchema.d.ts
@@ -8,7 +8,19 @@ type SchemaStateValue<T = unknown> = {
8
8
  type: AllPossibleProperties;
9
9
  valueType: 'alias' | 'custom';
10
10
  value: T;
11
+ /**
12
+ * Per-state opt-in flag. The CSS generator emits a rule for `rest` always
13
+ * and for any non-rest slot only when this is `true`. Toggling it lets a
14
+ * designer turn off a state's CSS without losing the value they configured
15
+ * — re-enabling restores the previous value. The configurator's setter
16
+ * manages this flag in response to the property's enable checkbox.
17
+ */
18
+ isEnabled?: boolean;
11
19
  };
12
20
  /** Map of component states to schema values. Requires 'rest', optional interactive states */
21
+ type VariableState = {
22
+ rest: SchemaStateValue;
23
+ } & { [K in PossibleStates]?: SchemaStateValue };
24
+ /** Configuration object mapping property keys to their state-based values */
13
25
  //#endregion
14
- export { type SchemaStateValue };
26
+ export { type SchemaStateValue, type VariableState };
@@ -1,5 +1,5 @@
1
1
 
2
- import { AllPossibleProperties } from "./ComponentConfig.js";
2
+ import { AllPossibleProperties, PossibleStates } from "./ComponentConfig.js";
3
3
 
4
4
  //#region ../automated-config/dist/types/ConfigSchema.d.ts
5
5
  //#region src/types/ConfigSchema.d.ts
@@ -8,7 +8,19 @@ type SchemaStateValue<T = unknown> = {
8
8
  type: AllPossibleProperties;
9
9
  valueType: 'alias' | 'custom';
10
10
  value: T;
11
+ /**
12
+ * Per-state opt-in flag. The CSS generator emits a rule for `rest` always
13
+ * and for any non-rest slot only when this is `true`. Toggling it lets a
14
+ * designer turn off a state's CSS without losing the value they configured
15
+ * — re-enabling restores the previous value. The configurator's setter
16
+ * manages this flag in response to the property's enable checkbox.
17
+ */
18
+ isEnabled?: boolean;
11
19
  };
12
20
  /** Map of component states to schema values. Requires 'rest', optional interactive states */
21
+ type VariableState = {
22
+ rest: SchemaStateValue;
23
+ } & { [K in PossibleStates]?: SchemaStateValue };
24
+ /** Configuration object mapping property keys to their state-based values */
13
25
  //#endregion
14
- export { type SchemaStateValue };
26
+ export { type SchemaStateValue, type VariableState };
@@ -0,0 +1,90 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ //#region ../automated-config/dist/types/StateAxis.js
3
+ /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
4
+ /**
5
+ * Atomic-state taxonomy.
6
+ *
7
+ * Every interactive component reacts to a fixed set of "atomic" states, each
8
+ * belonging to one axis:
9
+ *
10
+ * - `interactive` — pointer/keyboard focus signals. At runtime at most one of
11
+ * these is meaningfully "active" at a time on a given element (you can't
12
+ * simultaneously hover and press distinctly enough to style separately, etc.).
13
+ *
14
+ * - `modifier` — semantic flags that can stack independently of each other and
15
+ * of the interactive state. An input can be `invalid` AND `readonly` at the
16
+ * same time, optionally also `hover`ed.
17
+ *
18
+ * Compound states (`'invalid&hover'`, `'invalid&readonly&hover'`, etc.) are
19
+ * built by listing 0..N modifiers followed by 0..1 interactive. The
20
+ * `canonicalizeStateKey` helper enforces this ordering so that, e.g.,
21
+ * `['hover', 'invalid']` and `['invalid', 'hover']` resolve to the same key.
22
+ */
23
+ /**
24
+ * Interactive atomics:
25
+ *
26
+ * - `hover`/`pressed` for pointer interaction.
27
+ * - `focus-within` for containers that wrap a focusable child (e.g. an input
28
+ * wrapper).
29
+ * - `focus-visible` for keyboard-only focus rings on focusable elements.
30
+ */
31
+ const INTERACTIVE_ATOMICS = [
32
+ "hover",
33
+ "pressed",
34
+ "focus-within",
35
+ "focus-visible"
36
+ ];
37
+ const MODIFIER_ATOMICS = [
38
+ "invalid",
39
+ "readonly",
40
+ "placeholder-shown",
41
+ "autofill",
42
+ "visited"
43
+ ];
44
+ const INTERACTIVE_ATOMIC_SET = new Set(INTERACTIVE_ATOMICS);
45
+ const MODIFIER_ATOMIC_SET = new Set(MODIFIER_ATOMICS);
46
+ function isInteractiveAtomic(state) {
47
+ return INTERACTIVE_ATOMIC_SET.has(state);
48
+ }
49
+ function isModifierAtomic(state) {
50
+ return MODIFIER_ATOMIC_SET.has(state);
51
+ }
52
+ function isAtomicState(state) {
53
+ return isInteractiveAtomic(state) || isModifierAtomic(state);
54
+ }
55
+ /**
56
+ * Maximum number of modifiers that may appear in a single compound state.
57
+ * The resolver enumerates compounds up to `M^MAX_MODIFIERS_PER_COMPOUND × I`
58
+ * (with the interactive slot optional), the docs-class enumeration matches,
59
+ * and the StateBuilder picker prevents users from selecting more than this
60
+ * many modifier checkboxes. Keeping all three in lock-step means there's
61
+ * exactly one compound depth supported end-to-end.
62
+ */
63
+ const MAX_MODIFIERS_PER_COMPOUND = 3;
64
+ const STATE_PRIORITY_INDEX = new Map([
65
+ "visited",
66
+ "placeholder-shown",
67
+ "autofill",
68
+ "focus-within",
69
+ "focus-visible",
70
+ "hover",
71
+ "pressed",
72
+ "invalid",
73
+ "readonly"
74
+ ].map((atom, i) => [atom, i]));
75
+ /**
76
+ * Comparator usable with `Array.prototype.sort`. Atoms not in `STATE_PRIORITY`
77
+ * sort to the front (weakest) — this only triggers for unknown strings; every
78
+ * known `AtomicState` is in the priority array.
79
+ */
80
+ function comparePriority(a, b) {
81
+ return (STATE_PRIORITY_INDEX.get(a) ?? -1) - (STATE_PRIORITY_INDEX.get(b) ?? -1);
82
+ }
83
+ //#endregion
84
+ exports.INTERACTIVE_ATOMICS = INTERACTIVE_ATOMICS;
85
+ exports.MAX_MODIFIERS_PER_COMPOUND = MAX_MODIFIERS_PER_COMPOUND;
86
+ exports.MODIFIER_ATOMICS = MODIFIER_ATOMICS;
87
+ exports.comparePriority = comparePriority;
88
+ exports.isAtomicState = isAtomicState;
89
+ exports.isInteractiveAtomic = isInteractiveAtomic;
90
+ exports.isModifierAtomic = isModifierAtomic;
@@ -0,0 +1,70 @@
1
+
2
+ //#region ../automated-config/dist/types/StateAxis.d.ts
3
+ //#region src/types/StateAxis.d.ts
4
+ /**
5
+ * Atomic-state taxonomy.
6
+ *
7
+ * Every interactive component reacts to a fixed set of "atomic" states, each
8
+ * belonging to one axis:
9
+ *
10
+ * - `interactive` — pointer/keyboard focus signals. At runtime at most one of
11
+ * these is meaningfully "active" at a time on a given element (you can't
12
+ * simultaneously hover and press distinctly enough to style separately, etc.).
13
+ *
14
+ * - `modifier` — semantic flags that can stack independently of each other and
15
+ * of the interactive state. An input can be `invalid` AND `readonly` at the
16
+ * same time, optionally also `hover`ed.
17
+ *
18
+ * Compound states (`'invalid&hover'`, `'invalid&readonly&hover'`, etc.) are
19
+ * built by listing 0..N modifiers followed by 0..1 interactive. The
20
+ * `canonicalizeStateKey` helper enforces this ordering so that, e.g.,
21
+ * `['hover', 'invalid']` and `['invalid', 'hover']` resolve to the same key.
22
+ */
23
+ /**
24
+ * Interactive atomics:
25
+ *
26
+ * - `hover`/`pressed` for pointer interaction.
27
+ * - `focus-within` for containers that wrap a focusable child (e.g. an input
28
+ * wrapper).
29
+ * - `focus-visible` for keyboard-only focus rings on focusable elements.
30
+ */
31
+ declare const INTERACTIVE_ATOMICS: readonly ["hover", "pressed", "focus-within", "focus-visible"];
32
+ declare const MODIFIER_ATOMICS: readonly ["invalid", "readonly", "placeholder-shown", "autofill", "visited"];
33
+ type InteractiveAtomic = (typeof INTERACTIVE_ATOMICS)[number];
34
+ type ModifierAtomic = (typeof MODIFIER_ATOMICS)[number];
35
+ type AtomicState = InteractiveAtomic | ModifierAtomic;
36
+ declare function isInteractiveAtomic(state: string): state is InteractiveAtomic;
37
+ declare function isModifierAtomic(state: string): state is ModifierAtomic;
38
+ declare function isAtomicState(state: string): state is AtomicState;
39
+ /**
40
+ * Maximum number of modifiers that may appear in a single compound state.
41
+ * The resolver enumerates compounds up to `M^MAX_MODIFIERS_PER_COMPOUND × I`
42
+ * (with the interactive slot optional), the docs-class enumeration matches,
43
+ * and the StateBuilder picker prevents users from selecting more than this
44
+ * many modifier checkboxes. Keeping all three in lock-step means there's
45
+ * exactly one compound depth supported end-to-end.
46
+ */
47
+ declare const MAX_MODIFIERS_PER_COMPOUND = 3;
48
+ /**
49
+ * Global emission priority for the atomic taxonomy.
50
+ *
51
+ * Every atom selector contributes a uniform (0,1,0) of specificity (see
52
+ * `pseudoStateSelectors`), so a 2-atom compound at (0,3,0) strictly beats a
53
+ * 1-atom rule at (0,2,0) — cross-rank cascade is encoded in class-count
54
+ * specificity. Within a rank (e.g. two atoms simultaneously matching the
55
+ * same element) source order arbitrates: the resolver sorts a layer's
56
+ * `atomicStates` by index in this array, then emits in that order — meaning
57
+ * **later in the array = emits later = wins when multiple atoms match the
58
+ * same element**.
59
+ *
60
+ * The ordering is weakest → strongest. To bump an atom's priority, move it
61
+ * later in this array. Compound-state emission order is derived from this
62
+ * priority too (subset enumeration follows the modifier ordering here), so
63
+ * compound winners follow the same intuition.
64
+ *
65
+ * Legacy atoms (`focused`, `focused-keyboard`, `disabled`) are not in this
66
+ * list because they aren't part of `AtomicState`; their emission order is
67
+ * whatever a config's per-property `pseudoStates` array specifies.
68
+ */
69
+ //#endregion
70
+ export { type AtomicState, INTERACTIVE_ATOMICS, type InteractiveAtomic, MAX_MODIFIERS_PER_COMPOUND, MODIFIER_ATOMICS, type ModifierAtomic, isAtomicState, isInteractiveAtomic, isModifierAtomic };
@@ -0,0 +1,70 @@
1
+
2
+ //#region ../automated-config/dist/types/StateAxis.d.ts
3
+ //#region src/types/StateAxis.d.ts
4
+ /**
5
+ * Atomic-state taxonomy.
6
+ *
7
+ * Every interactive component reacts to a fixed set of "atomic" states, each
8
+ * belonging to one axis:
9
+ *
10
+ * - `interactive` — pointer/keyboard focus signals. At runtime at most one of
11
+ * these is meaningfully "active" at a time on a given element (you can't
12
+ * simultaneously hover and press distinctly enough to style separately, etc.).
13
+ *
14
+ * - `modifier` — semantic flags that can stack independently of each other and
15
+ * of the interactive state. An input can be `invalid` AND `readonly` at the
16
+ * same time, optionally also `hover`ed.
17
+ *
18
+ * Compound states (`'invalid&hover'`, `'invalid&readonly&hover'`, etc.) are
19
+ * built by listing 0..N modifiers followed by 0..1 interactive. The
20
+ * `canonicalizeStateKey` helper enforces this ordering so that, e.g.,
21
+ * `['hover', 'invalid']` and `['invalid', 'hover']` resolve to the same key.
22
+ */
23
+ /**
24
+ * Interactive atomics:
25
+ *
26
+ * - `hover`/`pressed` for pointer interaction.
27
+ * - `focus-within` for containers that wrap a focusable child (e.g. an input
28
+ * wrapper).
29
+ * - `focus-visible` for keyboard-only focus rings on focusable elements.
30
+ */
31
+ declare const INTERACTIVE_ATOMICS: readonly ["hover", "pressed", "focus-within", "focus-visible"];
32
+ declare const MODIFIER_ATOMICS: readonly ["invalid", "readonly", "placeholder-shown", "autofill", "visited"];
33
+ type InteractiveAtomic = (typeof INTERACTIVE_ATOMICS)[number];
34
+ type ModifierAtomic = (typeof MODIFIER_ATOMICS)[number];
35
+ type AtomicState = InteractiveAtomic | ModifierAtomic;
36
+ declare function isInteractiveAtomic(state: string): state is InteractiveAtomic;
37
+ declare function isModifierAtomic(state: string): state is ModifierAtomic;
38
+ declare function isAtomicState(state: string): state is AtomicState;
39
+ /**
40
+ * Maximum number of modifiers that may appear in a single compound state.
41
+ * The resolver enumerates compounds up to `M^MAX_MODIFIERS_PER_COMPOUND × I`
42
+ * (with the interactive slot optional), the docs-class enumeration matches,
43
+ * and the StateBuilder picker prevents users from selecting more than this
44
+ * many modifier checkboxes. Keeping all three in lock-step means there's
45
+ * exactly one compound depth supported end-to-end.
46
+ */
47
+ declare const MAX_MODIFIERS_PER_COMPOUND = 3;
48
+ /**
49
+ * Global emission priority for the atomic taxonomy.
50
+ *
51
+ * Every atom selector contributes a uniform (0,1,0) of specificity (see
52
+ * `pseudoStateSelectors`), so a 2-atom compound at (0,3,0) strictly beats a
53
+ * 1-atom rule at (0,2,0) — cross-rank cascade is encoded in class-count
54
+ * specificity. Within a rank (e.g. two atoms simultaneously matching the
55
+ * same element) source order arbitrates: the resolver sorts a layer's
56
+ * `atomicStates` by index in this array, then emits in that order — meaning
57
+ * **later in the array = emits later = wins when multiple atoms match the
58
+ * same element**.
59
+ *
60
+ * The ordering is weakest → strongest. To bump an atom's priority, move it
61
+ * later in this array. Compound-state emission order is derived from this
62
+ * priority too (subset enumeration follows the modifier ordering here), so
63
+ * compound winners follow the same intuition.
64
+ *
65
+ * Legacy atoms (`focused`, `focused-keyboard`, `disabled`) are not in this
66
+ * list because they aren't part of `AtomicState`; their emission order is
67
+ * whatever a config's per-property `pseudoStates` array specifies.
68
+ */
69
+ //#endregion
70
+ export { type AtomicState, INTERACTIVE_ATOMICS, type InteractiveAtomic, MAX_MODIFIERS_PER_COMPOUND, MODIFIER_ATOMICS, type ModifierAtomic, isAtomicState, isInteractiveAtomic, isModifierAtomic };