@yahoo/uds 3.156.2 → 3.157.1

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 (180) 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 +3078 -3089
  6. package/dist/automated-config/dist/generated/generatedConfigs.d.cts +158 -141
  7. package/dist/automated-config/dist/generated/generatedConfigs.d.ts +158 -141
  8. package/dist/automated-config/dist/generated/generatedConfigs.js +3078 -3089
  9. package/dist/automated-config/dist/generated/universalTokensConfigAuto.cjs +1217 -491
  10. package/dist/automated-config/dist/generated/universalTokensConfigAuto.d.cts +4 -1
  11. package/dist/automated-config/dist/generated/universalTokensConfigAuto.d.ts +4 -1
  12. package/dist/automated-config/dist/generated/universalTokensConfigAuto.js +1217 -491
  13. package/dist/automated-config/dist/properties.cjs +9 -2
  14. package/dist/automated-config/dist/properties.d.cts +23 -0
  15. package/dist/automated-config/dist/properties.d.ts +23 -0
  16. package/dist/automated-config/dist/properties.js +9 -2
  17. package/dist/automated-config/dist/types/ComponentConfig.d.cts +77 -4
  18. package/dist/automated-config/dist/types/ComponentConfig.d.ts +77 -4
  19. package/dist/automated-config/dist/types/ConfigSchema.d.cts +14 -2
  20. package/dist/automated-config/dist/types/ConfigSchema.d.ts +14 -2
  21. package/dist/automated-config/dist/types/StateAxis.cjs +90 -0
  22. package/dist/automated-config/dist/types/StateAxis.d.cts +70 -0
  23. package/dist/automated-config/dist/types/StateAxis.d.ts +70 -0
  24. package/dist/automated-config/dist/types/StateAxis.js +84 -0
  25. package/dist/automated-config/dist/utils/buildConfigSchema.cjs +105 -82
  26. package/dist/automated-config/dist/utils/buildConfigSchema.d.cts +41 -12
  27. package/dist/automated-config/dist/utils/buildConfigSchema.d.ts +41 -12
  28. package/dist/automated-config/dist/utils/buildConfigSchema.js +106 -83
  29. package/dist/automated-config/dist/utils/canonicalizeStateKey.cjs +32 -0
  30. package/dist/automated-config/dist/utils/canonicalizeStateKey.d.cts +48 -0
  31. package/dist/automated-config/dist/utils/canonicalizeStateKey.d.ts +48 -0
  32. package/dist/automated-config/dist/utils/canonicalizeStateKey.js +31 -0
  33. package/dist/automated-config/dist/utils/getButtonControlHeight.cjs +129 -0
  34. package/dist/automated-config/dist/utils/getButtonControlHeight.d.cts +133 -0
  35. package/dist/automated-config/dist/utils/getButtonControlHeight.d.ts +133 -0
  36. package/dist/automated-config/dist/utils/getButtonControlHeight.js +122 -0
  37. package/dist/automated-config/dist/utils/getButtonControlHeightPx.cjs +114 -0
  38. package/dist/automated-config/dist/utils/getButtonControlHeightPx.d.cts +78 -0
  39. package/dist/automated-config/dist/utils/getButtonControlHeightPx.d.ts +78 -0
  40. package/dist/automated-config/dist/utils/getButtonControlHeightPx.js +108 -0
  41. package/dist/automated-config/dist/utils/getConfigComponentVariant.d.cts +8 -0
  42. package/dist/automated-config/dist/utils/getConfigComponentVariant.d.ts +8 -0
  43. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.cts +3 -3
  44. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +3 -3
  45. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.cjs +12 -5
  46. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.d.cts +8 -1
  47. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.d.ts +8 -1
  48. package/dist/automated-config/dist/utils/getConfigVariantPseudoStates.js +12 -5
  49. package/dist/automated-config/dist/utils/iconButtonMatchButtonHeight.cjs +110 -0
  50. package/dist/automated-config/dist/utils/iconButtonMatchButtonHeight.d.cts +19 -0
  51. package/dist/automated-config/dist/utils/iconButtonMatchButtonHeight.d.ts +19 -0
  52. package/dist/automated-config/dist/utils/iconButtonMatchButtonHeight.js +108 -0
  53. package/dist/automated-config/dist/utils/index.cjs +478 -111
  54. package/dist/automated-config/dist/utils/index.d.cts +76 -15
  55. package/dist/automated-config/dist/utils/index.d.ts +76 -15
  56. package/dist/automated-config/dist/utils/index.js +479 -113
  57. package/dist/automated-config/dist/utils/isConfiguratorPropertyVisible.cjs +15 -0
  58. package/dist/automated-config/dist/utils/isConfiguratorPropertyVisible.d.cts +20 -0
  59. package/dist/automated-config/dist/utils/isConfiguratorPropertyVisible.d.ts +20 -0
  60. package/dist/automated-config/dist/utils/isConfiguratorPropertyVisible.js +15 -0
  61. package/dist/automated-config/dist/utils/pseudoStateSelectors.cjs +122 -0
  62. package/dist/automated-config/dist/utils/pseudoStateSelectors.d.cts +80 -0
  63. package/dist/automated-config/dist/utils/pseudoStateSelectors.d.ts +80 -0
  64. package/dist/automated-config/dist/utils/pseudoStateSelectors.js +120 -0
  65. package/dist/automated-config/dist/utils/resolvePropertyStates.cjs +131 -0
  66. package/dist/automated-config/dist/utils/resolvePropertyStates.d.cts +49 -0
  67. package/dist/automated-config/dist/utils/resolvePropertyStates.d.ts +49 -0
  68. package/dist/automated-config/dist/utils/resolvePropertyStates.js +130 -0
  69. package/dist/automated-config/dist/utils/resolveSlotByCascade.cjs +118 -0
  70. package/dist/automated-config/dist/utils/resolveSlotByCascade.d.cts +68 -0
  71. package/dist/automated-config/dist/utils/resolveSlotByCascade.d.ts +68 -0
  72. package/dist/automated-config/dist/utils/resolveSlotByCascade.js +117 -0
  73. package/dist/automated-config/dist/utils/variantConfigGuards.d.cts +13 -0
  74. package/dist/automated-config/dist/utils/variantConfigGuards.d.ts +13 -0
  75. package/dist/components/client/Button.cjs +3 -3
  76. package/dist/components/client/Button.js +3 -3
  77. package/dist/components/client/Input/Input.cjs +42 -6
  78. package/dist/components/client/Input/Input.d.cts +13 -0
  79. package/dist/components/client/Input/Input.d.ts +13 -0
  80. package/dist/components/client/Input/Input.js +42 -6
  81. package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
  82. package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
  83. package/dist/config/dist/index.cjs +224 -553
  84. package/dist/config/dist/index.js +224 -553
  85. package/dist/css/dist/commands/css.cjs +1 -0
  86. package/dist/css/dist/commands/css.helpers.cjs +6 -0
  87. package/dist/css/dist/commands/css.helpers.js +6 -0
  88. package/dist/css/dist/commands/css.js +1 -0
  89. package/dist/css/dist/css/generate.cjs +4 -2
  90. package/dist/css/dist/css/generate.d.cts +28 -0
  91. package/dist/css/dist/css/generate.d.ts +28 -0
  92. package/dist/css/dist/css/generate.helpers.cjs +5 -1
  93. package/dist/css/dist/css/generate.helpers.js +6 -2
  94. package/dist/css/dist/css/generate.js +4 -2
  95. package/dist/css/dist/css/postcss.cjs +81 -0
  96. package/dist/css/dist/css/postcss.helpers.cjs +60 -0
  97. package/dist/css/dist/css/postcss.helpers.js +59 -1
  98. package/dist/css/dist/css/postcss.js +82 -2
  99. package/dist/css/dist/css/runner.cjs +12 -2
  100. package/dist/css/dist/css/runner.js +12 -2
  101. package/dist/css/dist/css/theme.d.cts +6 -0
  102. package/dist/css/dist/css/theme.d.ts +6 -0
  103. package/dist/css/dist/packages/automated-config/dist/properties.cjs +9 -2
  104. package/dist/css/dist/packages/automated-config/dist/properties.js +9 -2
  105. package/dist/css/dist/packages/automated-config/dist/utils/index.d.cts +6 -0
  106. package/dist/css/dist/packages/automated-config/dist/utils/index.d.ts +6 -0
  107. package/dist/css/dist/packages/config/dist/index.cjs +224 -553
  108. package/dist/css/dist/packages/config/dist/index.js +224 -553
  109. package/dist/css/dist/utils/optimizeCSS.cjs +59 -0
  110. package/dist/css/dist/utils/optimizeCSS.js +59 -0
  111. package/dist/css-tokens/dist/index.cjs +2 -0
  112. package/dist/css-tokens/dist/index.d.cts +2 -1
  113. package/dist/css-tokens/dist/index.d.ts +2 -1
  114. package/dist/css-tokens/dist/index.js +2 -1
  115. package/dist/index.cjs +48 -0
  116. package/dist/index.d.cts +15 -4
  117. package/dist/index.d.ts +15 -4
  118. package/dist/index.js +14 -3
  119. package/dist/styles/styler.d.cts +8 -7
  120. package/dist/styles/styler.d.ts +8 -7
  121. package/dist/styles/variants.d.cts +9 -4
  122. package/dist/styles/variants.d.ts +9 -4
  123. package/dist/tailwind-internal/dist/packages/automated-config/dist/generated/generatedConfigs.cjs +3078 -3089
  124. package/dist/tailwind-internal/dist/packages/automated-config/dist/generated/generatedConfigs.js +3078 -3089
  125. package/dist/tailwind-internal/dist/packages/automated-config/dist/properties.cjs +9 -2
  126. package/dist/tailwind-internal/dist/packages/automated-config/dist/properties.js +9 -2
  127. package/dist/tailwind-internal/dist/packages/automated-config/dist/types/StateAxis.cjs +81 -0
  128. package/dist/tailwind-internal/dist/packages/automated-config/dist/types/StateAxis.js +76 -0
  129. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/canonicalizeStateKey.cjs +33 -0
  130. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/canonicalizeStateKey.js +32 -0
  131. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/componentStatePseudoStates.cjs +0 -7
  132. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/componentStatePseudoStates.js +1 -7
  133. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/getButtonControlHeight.cjs +126 -0
  134. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/getButtonControlHeight.js +123 -0
  135. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/iconButtonMatchButtonHeight.cjs +20 -0
  136. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/iconButtonMatchButtonHeight.js +20 -0
  137. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.cjs +422 -111
  138. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.d.cts +6 -0
  139. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.d.ts +6 -0
  140. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.js +423 -112
  141. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.cjs +122 -0
  142. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.js +121 -0
  143. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.cjs +132 -0
  144. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.js +131 -0
  145. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.cjs +95 -0
  146. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.js +95 -0
  147. package/dist/tailwind-internal/dist/packages/config/dist/index.cjs +224 -553
  148. package/dist/tailwind-internal/dist/packages/config/dist/index.js +224 -553
  149. package/dist/tailwind-internal/dist/packages/css-tokens/dist/index.cjs +2 -0
  150. package/dist/tailwind-internal/dist/packages/css-tokens/dist/index.js +2 -1
  151. package/dist/tailwind-internal/dist/plugins/components.cjs +28 -24
  152. package/dist/tailwind-internal/dist/plugins/components.js +28 -24
  153. package/dist/tailwind-internal/dist/utils/composeTailwindPlugins.d.cts +3 -0
  154. package/dist/tailwind-internal/dist/utils/composeTailwindPlugins.d.ts +3 -0
  155. package/dist/tailwind-internal/dist/utils/getShadowStyles.d.cts +2 -2
  156. package/dist/tailwind-internal/dist/utils/getShadowStyles.d.ts +2 -2
  157. package/dist/tokens/automation/index.cjs +47 -0
  158. package/dist/tokens/automation/index.d.cts +13 -2
  159. package/dist/tokens/automation/index.d.ts +13 -2
  160. package/dist/tokens/automation/index.js +13 -2
  161. package/dist/tokens/consts/cssTokens.cjs +1 -0
  162. package/dist/tokens/consts/cssTokens.d.cts +2 -2
  163. package/dist/tokens/consts/cssTokens.d.ts +2 -2
  164. package/dist/tokens/consts/cssTokens.js +2 -2
  165. package/dist/tokens/index.cjs +48 -0
  166. package/dist/tokens/index.d.cts +15 -4
  167. package/dist/tokens/index.d.ts +15 -4
  168. package/dist/tokens/index.js +14 -3
  169. package/dist/tokens/types.d.cts +1 -1
  170. package/dist/tokens/types.d.ts +1 -1
  171. package/dist/uds/generated/componentData.cjs +2177 -2172
  172. package/dist/uds/generated/componentData.js +2177 -2172
  173. package/dist/uds/generated/migrationSchemaVersion.cjs +1 -1
  174. package/dist/uds/generated/migrationSchemaVersion.js +1 -1
  175. package/dist/uds/generated/tailwindPurge.cjs +79 -78
  176. package/dist/uds/generated/tailwindPurge.js +79 -78
  177. package/generated/componentData.json +2718 -2713
  178. package/generated/migrationSchemaVersion.ts +1 -1
  179. package/generated/tailwindPurge.ts +2 -2
  180. package/package.json +1 -1
@@ -3,21 +3,31 @@ require("../../../_virtual/_rolldown/runtime.cjs");
3
3
  const require_index = require("../../../css-tokens/dist/index.cjs");
4
4
  const require_mapTextVariantFixtureToValue = require("../mapTextVariantFixtureToValue.cjs");
5
5
  const require_properties = require("../properties.cjs");
6
+ const require_StateAxis = require("../types/StateAxis.cjs");
6
7
  const require_componentStatePseudoStates = require("./componentStatePseudoStates.cjs");
7
8
  const require_generateSchemaKey = require("./generateSchemaKey.cjs");
9
+ require("./canonicalizeStateKey.cjs");
10
+ const require_resolvePropertyStates = require("./resolvePropertyStates.cjs");
8
11
  const require_variantConfigGuards = require("./variantConfigGuards.cjs");
9
12
  const require_buildConfigSchema = require("./buildConfigSchema.cjs");
10
13
  const require_generateDefaultClassName = require("./generateDefaultClassName.cjs");
14
+ const require_getButtonControlHeight = require("./getButtonControlHeight.cjs");
15
+ require("./iconButtonMatchButtonHeight.cjs");
16
+ require("./getButtonControlHeightPx.cjs");
17
+ const require_pseudoStateSelectors = require("./pseudoStateSelectors.cjs");
18
+ const require_resolveSlotByCascade = require("./resolveSlotByCascade.cjs");
11
19
  require("./cartesianProduct.cjs");
12
20
  require("./subcomponents.cjs");
13
21
  require("./coalesceConfigVariant.cjs");
14
22
  require("./defaults.cjs");
15
23
  require("./generateKeyFromFlatConfigPath.cjs");
24
+ require("./getConfigComponentVariant.cjs");
16
25
  require("./getConfigVariantComponentStatesMatrix.cjs");
17
26
  require("./getConfigVariantProperties.cjs");
18
27
  require("./getConfigVariantPseudoStates.cjs");
19
28
  require("./getConfigVariants.cjs");
20
29
  require("./getPaginationControlWidthPx.cjs");
30
+ require("./isConfiguratorPropertyVisible.cjs");
21
31
  let lodash_es = require("lodash-es");
22
32
  //#region ../automated-config/dist/utils/index.js
23
33
  /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
@@ -71,47 +81,59 @@ const COMPONENTS_WITH_SHADOW_BORDERS = [
71
81
  }
72
82
  ];
73
83
  /**
74
- * Map our "states" to pseudo-classes (hover => :hover, pressed => :active, etc.).
75
- * Adjust or extend as needed.
84
+ * Legacy state keys still used by unmigrated component configs via per-property
85
+ * `pseudoStates` arrays. They aren't in the new `StateAxis` taxonomy (so the
86
+ * resolver/StateBuilder don't auto-compose them) but they must remain in
87
+ * `KNOWN_STATE_KEYS` so the docs-mode map / configurator safelist still cover
88
+ * configs that emit them. Drop entries from this list as components migrate.
76
89
  */
77
- const statePseudoMap = {
78
- rest: "",
79
- hover: ":hover:not(:active, :disabled, :has(:disabled))",
80
- pressed: ":active:not(:disabled, :has(:disabled))",
81
- disabled: ":is(:disabled, :has(:disabled))",
82
- visited: ":visited",
83
- focused: ":focus",
84
- "focus-within": ":focus-within",
85
- "focused-keyboard": ":focus-visible",
86
- readonly: ":has(input:read-only)",
87
- invalid: ":has(input[aria-invalid=\"true\"])",
88
- "invalid&hover": ":has(input[aria-invalid=\"true\"]):hover:not(:active, :disabled, :has(:disabled))",
89
- "invalid&pressed": ":has(input[aria-invalid=\"true\"]):active:not(:disabled, :has(:disabled))"
90
- };
91
- const statePseudoMapDocsMode = {
92
- rest: "",
93
- hover: "hover",
94
- pressed: "active",
95
- disabled: "has-disabled",
96
- visited: "visited",
97
- focused: "focus",
98
- "focus-within": "focus-within",
99
- "focused-keyboard": "focus-visible",
100
- readonly: "input-readonly",
101
- invalid: "has-input-invalid",
102
- "invalid&hover": "has-input-invalid-and-hover",
103
- "invalid&pressed": "has-input-invalid-and-active"
104
- };
90
+ const LEGACY_STATE_KEYS = [
91
+ "disabled",
92
+ "focused",
93
+ "focused-keyboard"
94
+ ];
105
95
  /**
106
- * Generates button line-height with icon size minimum.
107
- * Ensures button line-height is at least as tall as the icon to prevent clipping.
108
- * @returns Enhanced line-height CSS value with max(), or original value if icon size unavailable
96
+ * Enumerates every canonical state key the system supports: rest, every atom,
97
+ * every modifier-subset (up to {@link MAX_MODIFIERS_PER_COMPOUND}) on its own
98
+ * and combined with each interactive, plus any legacy keys still in use.
99
+ *
100
+ * Mirrors `resolvePropertyStates` exactly so what the resolver pre-emits in
101
+ * the schema, what the StateBuilder lets users compose, and what the docs
102
+ * map / configurator safelist preserve are all the same set.
109
103
  */
110
- function getButtonLineHeightWithIconMinimum({ lineHeight, schema, iconLayerKey, state, theme }) {
111
- const iconSizeValue = schema.variables?.[iconLayerKey]?.size?.[state]?.value;
112
- if (iconSizeValue) return `max(${lineHeight}, ${theme(require_properties.configurableProperties.iconSize.twThemePath("iconSizes", iconSizeValue))})`;
113
- return lineHeight;
104
+ function enumerateAllStateKeys() {
105
+ const states = ["rest"];
106
+ const atoms = [...require_StateAxis.INTERACTIVE_ATOMICS, ...require_StateAxis.MODIFIER_ATOMICS].sort(require_StateAxis.comparePriority);
107
+ for (const stateKey of require_resolvePropertyStates.atomicAndCompoundStateKeys(atoms)) states.push(stateKey);
108
+ for (const legacy of LEGACY_STATE_KEYS) states.push(legacy);
109
+ return states;
110
+ }
111
+ const KNOWN_STATE_KEYS = enumerateAllStateKeys();
112
+ /**
113
+ * Lookup of every known state key to its index in `KNOWN_STATE_KEYS` — i.e. the
114
+ * resolver's emission order. The CSS generator iterates property-state maps
115
+ * in this order (instead of the alphabetical insertion order produced by
116
+ * `syncYosConfig`'s `normalizeConfig`), so cascade tie-breaking under the
117
+ * uniform per-atom specificity actually follows the priority chain. Unknown
118
+ * keys sort to the end.
119
+ */
120
+ const KNOWN_STATE_RANK = new Map(KNOWN_STATE_KEYS.map((key, index) => [key, index]));
121
+ function compareStateKeys(a, b) {
122
+ const ra = KNOWN_STATE_RANK.get(a) ?? Number.POSITIVE_INFINITY;
123
+ const rb = KNOWN_STATE_RANK.get(b) ?? Number.POSITIVE_INFINITY;
124
+ if (ra === rb) return a < b ? -1 : a > b ? 1 : 0;
125
+ return ra - rb;
126
+ }
127
+ function buildStateRecord(transform) {
128
+ const record = {};
129
+ for (const key of KNOWN_STATE_KEYS) record[key] = transform(key);
130
+ return record;
114
131
  }
132
+ const statePseudoMapDocsMode = buildStateRecord(require_pseudoStateSelectors.getStateDocsClass);
133
+ /**
134
+ * Layout line-height for button root: icon size only (not textVariant line-height).
135
+ * @see getButtonContentLineHeight
136
+ */
115
137
  /**
116
138
  * Shared pagination control content size: max(icon size, text line-height).
117
139
  * Keeps page numbers and prev/next icons vertically centered when typography exceeds icon height.
@@ -244,7 +266,65 @@ const getTheCssPropertyValue = (schema, theme, propertyName, schemaStateValue, e
244
266
  if (propertyConfig.concatenate && existingValue) return `${existingValue}${propertyConfig.concatenationDelimiter || ", "}${newValue}`;
245
267
  return newValue;
246
268
  };
247
- function generateDeclaration({ componentName, subComponentName, variantKey, variantValue, layer, layerOptionalPseudoSelector, componentStateKey, componentStateValue, schema, propertyKey, originalPropertyDefinition, theme, currentStyles, previewOptions, excludedPseudoStates = [] }) {
269
+ /**
270
+ * Builds the per-state resolution map for a per-componentState OVERRIDE in
271
+ * exhaustive mode: the universal layer's state map with the override's ENABLED
272
+ * (and `rest`) slots layered on top. An unset or disabled override slot defers
273
+ * to the universal layer's value, so `resolveSlotByCascade` picks the
274
+ * most-specific *enabled* slot across both layers (override winning ties) rather
275
+ * than collapsing every unset state to the override's own `rest`.
276
+ */
277
+ function mergeUniversalUnderOverride(universal, override) {
278
+ const merged = { ...universal };
279
+ const overrideRecord = override;
280
+ for (const state of Object.keys(overrideRecord)) {
281
+ const slot = overrideRecord[state];
282
+ if (state === "rest" && slot?.isEnabled !== false || slot?.isEnabled === true) merged[state] = slot;
283
+ }
284
+ return merged;
285
+ }
286
+ /**
287
+ * Replays SELECTIVE emission for a STANDALONE atomicStates layer (no universal
288
+ * fallback) and returns the sparse set of slots it would emit: `rest`, every
289
+ * explicitly-enabled state, and every cascade-correction. Mirrors the inline
290
+ * selective decision in `generateDeclaration` — keep the two in lock-step.
291
+ *
292
+ * The override path seeds its own correction accumulator with this for the
293
+ * UNIVERSAL layer. Universal layers are emitted in a separate pass at the SAME
294
+ * specificity tier as their per-option overrides (see `bumpRootSpecificity`), so
295
+ * at runtime a universal rule wins wherever the override emits nothing. Without
296
+ * this seed, an override that flattens a state to `rest` (e.g. a `filled` help
297
+ * text that's `muted` everywhere) silently inherits the universal's brighter
298
+ * rule for that state in selective mode — a divergence from exhaustive, where
299
+ * the override emits every state explicitly. Seeding makes the override emit a
300
+ * correction whenever the universal would otherwise render a different value.
301
+ */
302
+ function selectiveEmittedStates(stateMap, orderedStateKeys, emittableStates) {
303
+ const emitted = { rest: stateMap.rest };
304
+ for (const stateKey of orderedStateKeys) {
305
+ if (stateKey === "rest" || !emittableStates.has(stateKey)) continue;
306
+ const value = require_resolveSlotByCascade.resolveSlotByCascade(stateKey, stateMap);
307
+ if (!value) continue;
308
+ if (!(stateMap[stateKey]?.isEnabled === true)) {
309
+ if (require_resolveSlotByCascade.resolveSlotByCascade(stateKey, emitted)?.value === value.value) continue;
310
+ }
311
+ emitted[stateKey] = {
312
+ ...value,
313
+ isEnabled: true
314
+ };
315
+ }
316
+ return emitted;
317
+ }
318
+ function generateDeclaration({ componentName, subComponentName, variantKey, variantValue, layer, layerOptionalPseudoSelector, componentStateKey, componentStateValue, schema, propertyKey, originalPropertyDefinition, declaredStates, layerUsesAtomicStates, theme, currentStyles, previewOptions, excludedPseudoStates = [], emit, fallbackStateMap, bumpRootSpecificity, buttonHeightReferenceSchema }) {
319
+ const shouldUseExhaustive = (emit ?? "exhaustive") === "exhaustive" && layerUsesAtomicStates;
320
+ const { cssProperties: configuredCssProperties, extendedProperties: configuredExtendedGetter } = require_properties.configurableProperties[originalPropertyDefinition.name];
321
+ const configuredExtendedProperties = (0, lodash_es.isFunction)(configuredExtendedGetter) ? configuredExtendedGetter({
322
+ componentName,
323
+ subComponentName,
324
+ layer,
325
+ propertyKey
326
+ }) : configuredExtendedGetter;
327
+ if (!(typeof configuredCssProperties === "string" && configuredCssProperties.length > 0 || Array.isArray(configuredCssProperties) && configuredCssProperties.length > 0 || Array.isArray(configuredExtendedProperties) && configuredExtendedProperties.length > 0)) return {};
248
328
  const schemaKey = require_generateSchemaKey.generateSchemaKey({
249
329
  variantKey,
250
330
  variantValue,
@@ -265,14 +345,29 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
265
345
  const propertyStateMap = schema.variables?.[schemaKey]?.[propertyKey];
266
346
  if (!propertyStateMap) throw new Error(`Prop definition (${componentName} - ${schemaKey} - ${propertyKey}) not found, this is not expected, please report the bug to the UDS team`);
267
347
  const styles = {};
268
- const skipRestForProperty = originalPropertyDefinition.skipRestState === true;
269
- const declaredPseudoStates = require_componentStatePseudoStates.filterPseudoStatesByExclusion(originalPropertyDefinition.pseudoStates, excludedPseudoStates);
270
- const declaredPropertyStates = new Set([...skipRestForProperty ? [] : ["rest"], ...declaredPseudoStates]);
271
- for (const propStateStr in propertyStateMap) {
272
- if (!declaredPropertyStates.has(propStateStr)) continue;
348
+ const excludedStateSet = new Set(excludedPseudoStates);
349
+ const emittableStates = new Set([...declaredStates].filter((state) => !excludedStateSet.has(state)));
350
+ const orderedStateKeys = (shouldUseExhaustive || layerUsesAtomicStates ? [...emittableStates] : Object.keys(propertyStateMap)).sort(compareStateKeys);
351
+ const resolutionStates = fallbackStateMap ? mergeUniversalUnderOverride(fallbackStateMap, propertyStateMap) : propertyStateMap;
352
+ const emittedForSelective = layerUsesAtomicStates && !shouldUseExhaustive ? fallbackStateMap ? selectiveEmittedStates(fallbackStateMap, orderedStateKeys, emittableStates) : { rest: resolutionStates.rest } : {};
353
+ for (const propStateStr of orderedStateKeys) {
354
+ if (!emittableStates.has(propStateStr)) continue;
273
355
  const propertyState = propStateStr;
274
- const propertyStateSelector = statePseudoMap[propertyState] ?? "";
275
- const schemaValueForState = propertyStateMap[propertyState];
356
+ const propertyStateSelector = require_pseudoStateSelectors.getStateSelector(propertyState);
357
+ const schemaValueForState = shouldUseExhaustive || layerUsesAtomicStates ? require_resolveSlotByCascade.resolveSlotByCascade(propStateStr, resolutionStates) : propertyStateMap[propertyState];
358
+ if (!schemaValueForState) continue;
359
+ if (!shouldUseExhaustive) {
360
+ if (layerUsesAtomicStates) {
361
+ const isExplicitlyEnabled = propertyStateMap[propertyState]?.isEnabled === true;
362
+ if (propStateStr !== "rest" && !isExplicitlyEnabled) {
363
+ if (require_resolveSlotByCascade.resolveSlotByCascade(propStateStr, emittedForSelective)?.value === schemaValueForState.value) continue;
364
+ }
365
+ emittedForSelective[propStateStr] = {
366
+ ...schemaValueForState,
367
+ isEnabled: true
368
+ };
369
+ } else if (schemaValueForState.isEnabled === false) continue;
370
+ }
276
371
  let fullClassName = ``;
277
372
  if (layer === "root") if (componentStateKey && componentStateValue) {
278
373
  const rootVariantClass = generateClassName({
@@ -291,7 +386,7 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
291
386
  componentStateValue
292
387
  });
293
388
  fullClassName = `.${rootVariantClass}${propertyStateSelector}.${className}`;
294
- } else fullClassName = `.${className}${propertyStateSelector}`;
389
+ } else fullClassName = bumpRootSpecificity ? `.${className}.${className}${propertyStateSelector}` : `.${className}${propertyStateSelector}`;
295
390
  else {
296
391
  const rootVariantClassName = generateClassName({
297
392
  componentName,
@@ -318,7 +413,17 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
318
413
  subComponentName
319
414
  });
320
415
  fullClassName = `.${rootVariantClassName}${propertyStateSelector}.${rootVariantClassNameWithComponentState} .${className}`;
321
- } else fullClassName = `.${rootVariantClassName}${propertyStateSelector} .${className}`;
416
+ } else {
417
+ className = generateClassName({
418
+ componentName,
419
+ variantKey,
420
+ variantValue,
421
+ layer,
422
+ layerOptionalPseudoSelector,
423
+ subComponentName
424
+ });
425
+ fullClassName = bumpRootSpecificity ? `.${rootVariantClassName}.${rootVariantClassName}${propertyStateSelector} .${className}` : `.${rootVariantClassName}${propertyStateSelector} .${className}`;
426
+ }
322
427
  }
323
428
  const { cssProperties, extendedProperties: extendedPropertiesGetter } = require_properties.configurableProperties[originalPropertyDefinition.name];
324
429
  const cssDeclarations = {};
@@ -354,6 +459,28 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
354
459
  */
355
460
  if (componentName === "button" && layer === "root") {
356
461
  if (propertyKey === CSS_GAP) cssDeclarations[require_index.BUTTON_GAP_VAR] = cssDeclarations[CSS_GAP];
462
+ if (propertyKey === "spacingVertical") {
463
+ const paddingVertical = cssDeclarations["padding-top"];
464
+ if (paddingVertical) require_getButtonControlHeight.applyButtonControlHeightDeclarations({
465
+ cssDeclarations,
466
+ paddingVertical,
467
+ schema,
468
+ rootLayerKey: require_generateSchemaKey.generateSchemaKey({
469
+ variantKey,
470
+ variantValue,
471
+ layer: "root",
472
+ subComponentName
473
+ }),
474
+ iconLayerKey: require_generateSchemaKey.generateSchemaKey({
475
+ variantKey,
476
+ variantValue,
477
+ layer: "icon",
478
+ subComponentName
479
+ }),
480
+ state: propertyState,
481
+ theme
482
+ });
483
+ }
357
484
  if (propertyKey === "scaleEffect" && propertyState === "hover") {
358
485
  const rootClassName = `.${className}`;
359
486
  const renderValue = (schemaValue) => require_properties.configurableProperties.scaleEffect.customValueRenderer?.(schemaValue, schema, () => "") ?? "1";
@@ -362,17 +489,39 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
362
489
  if (propertyStateMap.hover) styles[rootClassName][require_index.BUTTON_SCALE_EFFECT_HOVER] = renderValue(propertyStateMap.hover);
363
490
  if (propertyStateMap.pressed) styles[rootClassName][require_index.BUTTON_SCALE_EFFECT_PRESSED] = renderValue(propertyStateMap.pressed);
364
491
  }
365
- if (cssDeclarations[CSS_LINE_HEIGHT]) {
366
- const iconLayerKey = require_generateSchemaKey.generateSchemaKey({
492
+ if (cssDeclarations[CSS_LINE_HEIGHT]) cssDeclarations[CSS_LINE_HEIGHT] = require_getButtonControlHeight.getButtonContentLineHeight({
493
+ schema,
494
+ rootLayerKey: require_generateSchemaKey.generateSchemaKey({
495
+ variantKey,
496
+ variantValue,
497
+ layer: "root",
498
+ subComponentName
499
+ }),
500
+ iconLayerKey: require_generateSchemaKey.generateSchemaKey({
367
501
  variantKey,
368
502
  variantValue,
369
503
  layer: "icon",
370
504
  subComponentName
371
- });
372
- cssDeclarations[CSS_LINE_HEIGHT] = getButtonLineHeightWithIconMinimum({
373
- lineHeight: cssDeclarations[CSS_LINE_HEIGHT],
374
- schema,
375
- iconLayerKey,
505
+ }),
506
+ state: propertyState,
507
+ theme
508
+ });
509
+ }
510
+ if (componentName === "iconbutton" && layer === "root") {
511
+ if (propertyKey === "spacing") {
512
+ const paddingVertical = cssDeclarations[CSS_PADDING];
513
+ if (paddingVertical) require_getButtonControlHeight.applyIconButtonControlHeightDeclarations({
514
+ cssDeclarations,
515
+ paddingVertical,
516
+ iconButtonSchema: schema,
517
+ buttonHeightReferenceSchema,
518
+ variantValue,
519
+ iconLayerKey: require_generateSchemaKey.generateSchemaKey({
520
+ variantKey,
521
+ variantValue,
522
+ layer: "icon",
523
+ subComponentName
524
+ }),
376
525
  state: propertyState,
377
526
  theme
378
527
  });
@@ -460,7 +609,7 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
460
609
  ...styles[fullClassName]
461
610
  };
462
611
  if (previewOptions?.generatePseudoStateClassModifier) {
463
- const pseudoPrefixClass = statePseudoMapDocsMode[propertyState] ?? "";
612
+ const pseudoPrefixClass = require_pseudoStateSelectors.getStateDocsClass(propertyState);
464
613
  if (pseudoPrefixClass.length) {
465
614
  const importantCssDeclarations = Object.fromEntries(Object.entries(cssDeclarations).map(([prop, value]) => {
466
615
  const strValue = String(value).trimEnd().replace(/;$/, "");
@@ -476,12 +625,139 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
476
625
  }
477
626
  return styles;
478
627
  }
479
- function generateConfigStyles(config, schema, theme, previewOptions) {
628
+ /**
629
+ * Emit CSS for per-state schema entries that target a variant's universal
630
+ * layers — the "override" path. Per-state schema entries can be authored by
631
+ * the Configurator (via `setConfigPseudoStateVariable`) or written by data
632
+ * migrations; they aren't declared in source configs.
633
+ *
634
+ * Iterates the cartesian product of `componentStates.X.options × universal
635
+ * layers × universal properties`. For each combination, calls
636
+ * `generateDeclaration` with the universal property's metadata plus the
637
+ * componentState key/value — the existing schema lookup inside
638
+ * `generateDeclaration` picks up the override slot if one exists and skips
639
+ * the property otherwise.
640
+ */
641
+ function emitSchemaOverrideStyles({ componentName, subComponentName, variantKey, variantOption, variantConfig, schema, theme, previewOptions, emit, currentStyles }) {
642
+ let styles = currentStyles;
643
+ const universalLayers = variantConfig.layers;
644
+ const componentStates = variantConfig.componentStates;
645
+ if (!universalLayers || !componentStates) return styles;
646
+ const variables = schema.variables;
647
+ if (!variables) return styles;
648
+ for (const componentStateKey in componentStates) {
649
+ const componentState = componentStates[componentStateKey];
650
+ for (const componentStateOption of componentState.options) for (const layerKey in universalLayers) {
651
+ const universalLayer = universalLayers[layerKey];
652
+ const schemaEntry = variables[require_generateSchemaKey.generateSchemaKey({
653
+ variantKey,
654
+ variantValue: variantOption,
655
+ componentStateKey,
656
+ componentStateValue: componentStateOption,
657
+ layer: layerKey,
658
+ subComponentName
659
+ })];
660
+ if (!schemaEntry) continue;
661
+ for (const propertyKey in universalLayer.properties) {
662
+ if (!schemaEntry[propertyKey]) continue;
663
+ const originalPropertyDefinition = universalLayer.properties[propertyKey];
664
+ const fallbackStateMap = variables[require_generateSchemaKey.generateSchemaKey({
665
+ variantKey,
666
+ variantValue: variantOption,
667
+ layer: layerKey,
668
+ subComponentName
669
+ })]?.[propertyKey];
670
+ const declarations = generateDeclaration({
671
+ componentName,
672
+ subComponentName,
673
+ variantKey,
674
+ variantValue: variantOption,
675
+ componentStateKey,
676
+ componentStateValue: componentStateOption,
677
+ layer: layerKey,
678
+ layerOptionalPseudoSelector: universalLayer.pseudoSelector,
679
+ propertyKey,
680
+ originalPropertyDefinition,
681
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(universalLayer, originalPropertyDefinition)),
682
+ layerUsesAtomicStates: (universalLayer.atomicStates?.length ?? 0) > 0,
683
+ theme,
684
+ schema,
685
+ currentStyles: styles,
686
+ previewOptions,
687
+ emit,
688
+ fallbackStateMap
689
+ });
690
+ styles = deepMerge(styles, declarations);
691
+ }
692
+ }
693
+ }
694
+ return styles;
695
+ }
696
+ /**
697
+ * Emit CSS for a set of layers without a component-state segment in the
698
+ * selector. Used by both `VariantConfigWithProperties` (where layers are the
699
+ * only source of styles) and `VariantConfigWithComponentStates` (where these
700
+ * layers express the variant's universal baseline, with per-state overrides
701
+ * winning via class-compound specificity).
702
+ */
703
+ function emitUniversalLayers({ componentName, subComponentName, variantKey, variantOption, layers, schema, theme, previewOptions, emit, currentStyles, bumpRootSpecificity, buttonHeightReferenceSchema }) {
704
+ let styles = currentStyles;
705
+ const variables = schema.variables;
706
+ for (const layerKey in layers) {
707
+ const layer = layers[layerKey];
708
+ const schemaKey = require_generateSchemaKey.generateSchemaKey({
709
+ variantKey,
710
+ variantValue: variantOption,
711
+ layer: layerKey,
712
+ subComponentName
713
+ });
714
+ const schemaEntry = variables?.[schemaKey];
715
+ for (const propertyKey in layer.properties) {
716
+ if (!schemaEntry || !schemaEntry[propertyKey]) continue;
717
+ const originalPropertyDefinition = layer.properties[propertyKey];
718
+ const declarations = generateDeclaration({
719
+ componentName,
720
+ subComponentName,
721
+ variantKey,
722
+ variantValue: variantOption,
723
+ layer: layerKey,
724
+ layerOptionalPseudoSelector: layer.pseudoSelector,
725
+ propertyKey,
726
+ originalPropertyDefinition,
727
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(layer, originalPropertyDefinition)),
728
+ layerUsesAtomicStates: (layer.atomicStates?.length ?? 0) > 0,
729
+ theme,
730
+ schema,
731
+ currentStyles: styles,
732
+ previewOptions,
733
+ emit,
734
+ bumpRootSpecificity,
735
+ buttonHeightReferenceSchema
736
+ });
737
+ styles = deepMerge(styles, declarations);
738
+ }
739
+ }
740
+ return styles;
741
+ }
742
+ function generateConfigStyles(config, schema, theme, previewOptions, emit, generateStylesContext) {
480
743
  const componentName = config.label.toLowerCase();
481
744
  let styles = {};
482
745
  for (const variantKey in config.variants) {
483
746
  const variantConfig = config.variants[variantKey];
484
747
  for (const variantOption of variantConfig.options) if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
748
+ if (variantConfig.layers) styles = emitUniversalLayers({
749
+ componentName,
750
+ variantKey,
751
+ variantOption,
752
+ layers: variantConfig.layers,
753
+ schema,
754
+ theme,
755
+ previewOptions,
756
+ emit,
757
+ currentStyles: styles,
758
+ bumpRootSpecificity: true,
759
+ buttonHeightReferenceSchema: generateStylesContext?.buttonHeightReferenceSchema
760
+ });
485
761
  const componentStates = variantConfig.componentStates;
486
762
  for (const componentStateKey in componentStates) {
487
763
  const componentState = componentStates[componentStateKey];
@@ -501,46 +777,64 @@ function generateConfigStyles(config, schema, theme, previewOptions) {
501
777
  layerOptionalPseudoSelector: layer.pseudoSelector,
502
778
  propertyKey,
503
779
  originalPropertyDefinition,
780
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(layer, originalPropertyDefinition)),
781
+ layerUsesAtomicStates: (layer.atomicStates?.length ?? 0) > 0,
504
782
  theme,
505
783
  schema,
506
784
  currentStyles: styles,
507
785
  previewOptions,
508
- excludedPseudoStates
786
+ excludedPseudoStates,
787
+ emit,
788
+ buttonHeightReferenceSchema: generateStylesContext?.buttonHeightReferenceSchema
509
789
  });
510
790
  styles = deepMerge(styles, declarations);
511
791
  }
512
792
  }
513
793
  }
514
794
  }
515
- } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) {
516
- const layers = variantConfig.layers;
517
- for (const layerKey in layers) {
518
- const layer = layers[layerKey];
519
- for (const propertyKey in layer.properties) {
520
- const originalPropertyDefinition = layer.properties[propertyKey];
521
- const declarations = generateDeclaration({
522
- componentName,
523
- variantKey,
524
- variantValue: variantOption,
525
- layer: layerKey,
526
- layerOptionalPseudoSelector: layer.pseudoSelector,
527
- propertyKey,
528
- originalPropertyDefinition,
529
- theme,
530
- schema,
531
- currentStyles: styles,
532
- previewOptions
533
- });
534
- styles = deepMerge(styles, declarations);
535
- }
536
- }
537
- }
795
+ styles = emitSchemaOverrideStyles({
796
+ componentName,
797
+ variantKey,
798
+ variantOption,
799
+ variantConfig,
800
+ schema,
801
+ theme,
802
+ previewOptions,
803
+ emit,
804
+ currentStyles: styles
805
+ });
806
+ } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) styles = emitUniversalLayers({
807
+ componentName,
808
+ variantKey,
809
+ variantOption,
810
+ layers: variantConfig.layers,
811
+ schema,
812
+ theme,
813
+ previewOptions,
814
+ emit,
815
+ currentStyles: styles,
816
+ buttonHeightReferenceSchema: generateStylesContext?.buttonHeightReferenceSchema
817
+ });
538
818
  }
539
819
  if (config.subComponents) {
540
820
  const { subComponents } = config;
541
821
  for (const subComponentKey in subComponents) for (const variantKey in subComponents[subComponentKey].variants) {
542
822
  const variantConfig = subComponents[subComponentKey].variants[variantKey];
543
823
  for (const variantOption of variantConfig.options) if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
824
+ if (variantConfig.layers) styles = emitUniversalLayers({
825
+ componentName,
826
+ subComponentName: subComponentKey,
827
+ variantKey,
828
+ variantOption,
829
+ layers: variantConfig.layers,
830
+ schema,
831
+ theme,
832
+ previewOptions,
833
+ emit,
834
+ currentStyles: styles,
835
+ bumpRootSpecificity: true,
836
+ buttonHeightReferenceSchema: generateStylesContext?.buttonHeightReferenceSchema
837
+ });
544
838
  const componentStates = variantConfig.componentStates;
545
839
  for (const componentStateKey in componentStates) {
546
840
  const componentState = componentStates[componentStateKey];
@@ -561,41 +855,46 @@ function generateConfigStyles(config, schema, theme, previewOptions) {
561
855
  layerOptionalPseudoSelector: layer.pseudoSelector,
562
856
  propertyKey,
563
857
  originalPropertyDefinition,
858
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(layer, originalPropertyDefinition)),
859
+ layerUsesAtomicStates: (layer.atomicStates?.length ?? 0) > 0,
564
860
  theme,
565
861
  schema,
566
862
  currentStyles: styles,
567
863
  previewOptions,
568
- excludedPseudoStates
864
+ excludedPseudoStates,
865
+ emit,
866
+ buttonHeightReferenceSchema: generateStylesContext?.buttonHeightReferenceSchema
569
867
  });
570
868
  styles = deepMerge(styles, declarations);
571
869
  }
572
870
  }
573
871
  }
574
872
  }
575
- } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) {
576
- const layers = variantConfig.layers;
577
- for (const layerKey in layers) {
578
- const layer = layers[layerKey];
579
- for (const propertyKey in layer.properties) {
580
- const originalPropertyDefinition = layer.properties[propertyKey];
581
- const declarations = generateDeclaration({
582
- componentName,
583
- subComponentName: subComponentKey,
584
- variantKey,
585
- variantValue: variantOption,
586
- layer: layerKey,
587
- layerOptionalPseudoSelector: layer.pseudoSelector,
588
- propertyKey,
589
- originalPropertyDefinition,
590
- theme,
591
- schema,
592
- currentStyles: styles,
593
- previewOptions
594
- });
595
- styles = deepMerge(styles, declarations);
596
- }
597
- }
598
- }
873
+ styles = emitSchemaOverrideStyles({
874
+ componentName,
875
+ subComponentName: subComponentKey,
876
+ variantKey,
877
+ variantOption,
878
+ variantConfig,
879
+ schema,
880
+ theme,
881
+ previewOptions,
882
+ emit,
883
+ currentStyles: styles
884
+ });
885
+ } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) styles = emitUniversalLayers({
886
+ componentName,
887
+ subComponentName: subComponentKey,
888
+ variantKey,
889
+ variantOption,
890
+ layers: variantConfig.layers,
891
+ schema,
892
+ theme,
893
+ previewOptions,
894
+ emit,
895
+ currentStyles: styles,
896
+ buttonHeightReferenceSchema: generateStylesContext?.buttonHeightReferenceSchema
897
+ });
599
898
  }
600
899
  }
601
900
  /**
@@ -628,8 +927,8 @@ function generateConfigStyles(config, schema, theme, previewOptions) {
628
927
  * @param previewOptions - Options for generating preview mode class modifiers
629
928
  * @returns CSS styles object with grouped selectors for default aliases
630
929
  */
631
- const generateStyles = (config, schema, theme, previewOptions) => {
632
- const styles = generateConfigStyles(config, schema, theme, previewOptions);
930
+ const generateStylesInner = (config, schema, theme, previewOptions, generateStylesContext) => {
931
+ const styles = generateConfigStyles(config, schema, theme, previewOptions, previewOptions.emit ?? "exhaustive", generateStylesContext);
633
932
  if (!config.variants && !config.subComponents) return styles;
634
933
  const componentName = config.label.toLowerCase();
635
934
  if (componentName !== "button" && componentName !== "iconbutton") return styles;
@@ -637,14 +936,15 @@ const generateStyles = (config, schema, theme, previewOptions) => {
637
936
  /**
638
937
  * Helper: Extract all layer keys from a variant configuration
639
938
  * Handles both simple variants (with direct layers) and variants with component states
939
+ * (which may additionally declare top-level universal layers).
640
940
  */
641
941
  const getLayerKeys = (variantConfig) => {
642
- if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) return Object.keys(variantConfig.layers);
643
- else if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
942
+ if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
644
943
  const layerKeysSet = /* @__PURE__ */ new Set();
645
- for (const componentStateConfig of Object.values(variantConfig.componentStates)) Object.keys(componentStateConfig.layers).forEach((key) => layerKeysSet.add(key));
944
+ for (const componentStateConfig of Object.values(variantConfig.componentStates)) Object.keys(componentStateConfig.layers ?? {}).forEach((key) => layerKeysSet.add(key));
945
+ if (variantConfig.layers) Object.keys(variantConfig.layers).forEach((key) => layerKeysSet.add(key));
646
946
  return Array.from(layerKeysSet);
647
- }
947
+ } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) return Object.keys(variantConfig.layers);
648
948
  return [];
649
949
  };
650
950
  /**
@@ -694,7 +994,39 @@ const generateStyles = (config, schema, theme, previewOptions) => {
694
994
  }
695
995
  return finalStyles;
696
996
  };
997
+ /**
998
+ * Public entry point. Generates a component's CSS, emitting each declared state
999
+ * as its own rule (one selector per rule) so the cascade is carried entirely by
1000
+ * per-rule specificity — which CSS minifiers preserve.
1001
+ *
1002
+ * An earlier optimization merged rules sharing a declaration block into a single
1003
+ * comma-separated selector list (to avoid repeating invariant declarations per
1004
+ * state). It was removed: a minifier's forgiving-`:is()` rewrite — applied to a
1005
+ * comma-separated list that contains `:has()` when targeting browsers without
1006
+ * native `:has()` support — collapses the list to its single highest
1007
+ * specificity, inflating the weakest selector (`rest`) above genuinely
1008
+ * customized states and corrupting the cascade. Separate rules never form such a
1009
+ * list, so minifiers leave their specificity intact. (gzip already collapses the
1010
+ * repeated declaration blocks, so the shipped-size cost is minimal.)
1011
+ */
1012
+ const generateStyles = (config, schema, theme, previewOptions, generateStylesContext) => generateStylesInner(config, schema, theme, previewOptions, generateStylesContext);
1013
+ /**
1014
+ * Throws if `values` contains a duplicate entry. Runs at config-import time so
1015
+ * a typo like `atomicStates: ['hover', 'hover']` fails the UDS build instead
1016
+ * of silently degrading the configurator's sidebar (where the resolver would
1017
+ * emit two entries for the same state).
1018
+ */
1019
+ function assertNoDuplicates(values, field, ownerLabel) {
1020
+ if (!values) return;
1021
+ const seen = /* @__PURE__ */ new Set();
1022
+ for (const v of values) {
1023
+ if (seen.has(v)) throw new Error(`Duplicate "${v}" in ${field} on ${ownerLabel}. Each entry must appear at most once.`);
1024
+ seen.add(v);
1025
+ }
1026
+ }
697
1027
  function createConfigurableProperty(prop) {
1028
+ assertNoDuplicates(prop.pseudoStates, "pseudoStates", `property "${prop.label}"`);
1029
+ assertNoDuplicates(prop.excludeAtomics, "excludeAtomics", `property "${prop.label}"`);
698
1030
  return prop;
699
1031
  }
700
1032
  function createVariantConfig(config) {
@@ -710,8 +1042,42 @@ function createComponentStates(config) {
710
1042
  return config;
711
1043
  }
712
1044
  function createLayerConfig(config) {
1045
+ assertNoDuplicates(config.atomicStates, "atomicStates", `layer "${config.label}"`);
1046
+ assertNoSkipRestStateOnAtomicLayer(config);
713
1047
  return config;
714
1048
  }
1049
+ /**
1050
+ * Disallows pairing `skipRestState: true` properties with a layer that uses
1051
+ * `atomicStates`. The combination breaks exhaustive emission's cascade
1052
+ * resolution:
1053
+ *
1054
+ * Under `atomicStates`, `generateDeclaration` emits every declared state and
1055
+ * resolves each non-customized compound through `resolveSlotByCascade`, so a
1056
+ * deliberate atom customization (e.g. `hover`) flows into every compound that
1057
+ * inherits from it (`invalid&hover`, …). That inheritance is what keeps the
1058
+ * higher-specificity compound rules from cancelling a lower-specificity atom
1059
+ * customization.
1060
+ *
1061
+ * But `buildPropertyStateMap` force-marks EVERY slot of a `skipRestState`
1062
+ * property `isEnabled: true` (there's no `rest` fall-through, so each state must
1063
+ * carry its own value). `resolveSlotByCascade` returns an enabled slot as-is,
1064
+ * so each force-enabled compound emits the property's *default* value instead of
1065
+ * inheriting a sibling atom's customization — and the compound's higher
1066
+ * specificity then silently overrides that customization (e.g. a customized
1067
+ * `hover` is cancelled by an unmodified `invalid&hover` carrying the default).
1068
+ *
1069
+ * Resolution path when this becomes a real need (currently the only
1070
+ * `skipRestState` properties are Button's `opacity` and `scaleEffect`, and
1071
+ * Button is on legacy `pseudoStates`):
1072
+ * teach `generateDeclaration` to skip compound state emission entirely for
1073
+ * `skipRestState` properties — atom rules cascade naturally, and designers
1074
+ * who want fine compound control simply drop `skipRestState` for that
1075
+ * property.
1076
+ */
1077
+ function assertNoSkipRestStateOnAtomicLayer(config) {
1078
+ if (!config.atomicStates || config.atomicStates.length === 0) return;
1079
+ for (const [propertyKey, property] of Object.entries(config.properties)) if (property.skipRestState) throw new Error(`Property "${propertyKey}" on layer "${config.label}" uses skipRestState: true, but the layer declares atomicStates. This combination isn't currently supported — see the comment on assertNoSkipRestStateOnAtomicLayer for the trade-offs and resolution path. For now, either drop skipRestState on this property or keep the layer on legacy per-property pseudoStates.`);
1080
+ }
715
1081
  function createSubComponentConfig(config) {
716
1082
  return config;
717
1083
  }
@@ -728,4 +1094,5 @@ exports.generateClassName = generateClassName;
728
1094
  exports.generateConfigStyles = generateConfigStyles;
729
1095
  exports.generateDeclaration = generateDeclaration;
730
1096
  exports.generateStyles = generateStyles;
1097
+ exports.mergeUniversalUnderOverride = mergeUniversalUnderOverride;
731
1098
  exports.statePseudoMapDocsMode = statePseudoMapDocsMode;