@yahoo/uds 3.156.1 → 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/getPaginationControlWidthPx.cjs +1 -1
  40. package/dist/automated-config/dist/utils/getPaginationControlWidthPx.js +1 -1
  41. package/dist/automated-config/dist/utils/index.cjs +407 -97
  42. package/dist/automated-config/dist/utils/index.d.cts +66 -16
  43. package/dist/automated-config/dist/utils/index.d.ts +66 -16
  44. package/dist/automated-config/dist/utils/index.js +408 -99
  45. package/dist/automated-config/dist/utils/pseudoStateSelectors.cjs +122 -0
  46. package/dist/automated-config/dist/utils/pseudoStateSelectors.d.cts +80 -0
  47. package/dist/automated-config/dist/utils/pseudoStateSelectors.d.ts +80 -0
  48. package/dist/automated-config/dist/utils/pseudoStateSelectors.js +120 -0
  49. package/dist/automated-config/dist/utils/resolvePropertyStates.cjs +131 -0
  50. package/dist/automated-config/dist/utils/resolvePropertyStates.d.cts +49 -0
  51. package/dist/automated-config/dist/utils/resolvePropertyStates.d.ts +49 -0
  52. package/dist/automated-config/dist/utils/resolvePropertyStates.js +130 -0
  53. package/dist/automated-config/dist/utils/resolveSlotByCascade.cjs +118 -0
  54. package/dist/automated-config/dist/utils/resolveSlotByCascade.d.cts +68 -0
  55. package/dist/automated-config/dist/utils/resolveSlotByCascade.d.ts +68 -0
  56. package/dist/automated-config/dist/utils/resolveSlotByCascade.js +117 -0
  57. package/dist/automated-config/dist/utils/variantConfigGuards.d.cts +13 -0
  58. package/dist/automated-config/dist/utils/variantConfigGuards.d.ts +13 -0
  59. package/dist/components/client/Input/Input.cjs +42 -6
  60. package/dist/components/client/Input/Input.d.cts +13 -0
  61. package/dist/components/client/Input/Input.d.ts +13 -0
  62. package/dist/components/client/Input/Input.js +42 -6
  63. package/dist/config/dist/index.cjs +221 -550
  64. package/dist/config/dist/index.js +221 -550
  65. package/dist/css/dist/commands/css.cjs +1 -0
  66. package/dist/css/dist/commands/css.helpers.cjs +6 -0
  67. package/dist/css/dist/commands/css.helpers.js +6 -0
  68. package/dist/css/dist/commands/css.js +1 -0
  69. package/dist/css/dist/css/generate.cjs +4 -2
  70. package/dist/css/dist/css/generate.d.cts +28 -0
  71. package/dist/css/dist/css/generate.d.ts +28 -0
  72. package/dist/css/dist/css/generate.helpers.cjs +5 -1
  73. package/dist/css/dist/css/generate.helpers.js +6 -2
  74. package/dist/css/dist/css/generate.js +4 -2
  75. package/dist/css/dist/css/postcss.cjs +81 -0
  76. package/dist/css/dist/css/postcss.helpers.cjs +60 -0
  77. package/dist/css/dist/css/postcss.helpers.js +59 -1
  78. package/dist/css/dist/css/postcss.js +82 -2
  79. package/dist/css/dist/css/runner.cjs +12 -2
  80. package/dist/css/dist/css/runner.js +12 -2
  81. package/dist/css/dist/css/theme.d.cts +6 -0
  82. package/dist/css/dist/css/theme.d.ts +6 -0
  83. package/dist/css/dist/packages/automated-config/dist/properties.cjs +1 -1
  84. package/dist/css/dist/packages/automated-config/dist/properties.js +1 -1
  85. package/dist/css/dist/packages/automated-config/dist/utils/index.d.cts +6 -0
  86. package/dist/css/dist/packages/automated-config/dist/utils/index.d.ts +6 -0
  87. package/dist/css/dist/packages/config/dist/index.cjs +221 -550
  88. package/dist/css/dist/packages/config/dist/index.js +221 -550
  89. package/dist/css/dist/utils/optimizeCSS.cjs +59 -0
  90. package/dist/css/dist/utils/optimizeCSS.js +59 -0
  91. package/dist/index.cjs +25 -0
  92. package/dist/index.d.cts +10 -3
  93. package/dist/index.d.ts +10 -3
  94. package/dist/index.js +9 -2
  95. package/dist/styles/styler.d.cts +14 -13
  96. package/dist/styles/styler.d.ts +14 -13
  97. package/dist/styles/variants.d.cts +9 -4
  98. package/dist/styles/variants.d.ts +9 -4
  99. package/dist/tailwind-internal/dist/packages/automated-config/dist/generated/generatedConfigs.cjs +3011 -3038
  100. package/dist/tailwind-internal/dist/packages/automated-config/dist/generated/generatedConfigs.js +3011 -3038
  101. package/dist/tailwind-internal/dist/packages/automated-config/dist/properties.cjs +1 -1
  102. package/dist/tailwind-internal/dist/packages/automated-config/dist/properties.js +1 -1
  103. package/dist/tailwind-internal/dist/packages/automated-config/dist/types/StateAxis.cjs +81 -0
  104. package/dist/tailwind-internal/dist/packages/automated-config/dist/types/StateAxis.js +76 -0
  105. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/canonicalizeStateKey.cjs +33 -0
  106. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/canonicalizeStateKey.js +32 -0
  107. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/componentStatePseudoStates.cjs +0 -7
  108. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/componentStatePseudoStates.js +1 -7
  109. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.cjs +354 -97
  110. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.d.cts +6 -0
  111. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.d.ts +6 -0
  112. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/index.js +355 -98
  113. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.cjs +122 -0
  114. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.js +121 -0
  115. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.cjs +132 -0
  116. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.js +131 -0
  117. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.cjs +95 -0
  118. package/dist/tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.js +95 -0
  119. package/dist/tailwind-internal/dist/packages/config/dist/index.cjs +221 -550
  120. package/dist/tailwind-internal/dist/packages/config/dist/index.js +221 -550
  121. package/dist/tailwind-internal/dist/plugins/components.cjs +28 -24
  122. package/dist/tailwind-internal/dist/plugins/components.js +28 -24
  123. package/dist/tailwind-internal/dist/utils/composeTailwindPlugins.d.cts +3 -0
  124. package/dist/tailwind-internal/dist/utils/composeTailwindPlugins.d.ts +3 -0
  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 +2010 -2008
  136. package/dist/uds/generated/componentData.js +2010 -2008
  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 +2553 -2551
  142. package/generated/migrationSchemaVersion.ts +1 -1
  143. package/generated/tailwindPurge.ts +2 -2
  144. package/package.json +1 -1
@@ -3,16 +3,22 @@ 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_pseudoStateSelectors = require("./pseudoStateSelectors.cjs");
15
+ const require_resolveSlotByCascade = require("./resolveSlotByCascade.cjs");
11
16
  require("./cartesianProduct.cjs");
12
17
  require("./subcomponents.cjs");
13
18
  require("./coalesceConfigVariant.cjs");
14
19
  require("./defaults.cjs");
15
20
  require("./generateKeyFromFlatConfigPath.cjs");
21
+ require("./getConfigComponentVariant.cjs");
16
22
  require("./getConfigVariantComponentStatesMatrix.cjs");
17
23
  require("./getConfigVariantProperties.cjs");
18
24
  require("./getConfigVariantPseudoStates.cjs");
@@ -71,37 +77,55 @@ const COMPONENTS_WITH_SHADOW_BORDERS = [
71
77
  }
72
78
  ];
73
79
  /**
74
- * Map our "states" to pseudo-classes (hover => :hover, pressed => :active, etc.).
75
- * Adjust or extend as needed.
80
+ * Legacy state keys still used by unmigrated component configs via per-property
81
+ * `pseudoStates` arrays. They aren't in the new `StateAxis` taxonomy (so the
82
+ * resolver/StateBuilder don't auto-compose them) but they must remain in
83
+ * `KNOWN_STATE_KEYS` so the docs-mode map / configurator safelist still cover
84
+ * configs that emit them. Drop entries from this list as components migrate.
76
85
  */
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
- };
86
+ const LEGACY_STATE_KEYS = [
87
+ "disabled",
88
+ "focused",
89
+ "focused-keyboard"
90
+ ];
91
+ /**
92
+ * Enumerates every canonical state key the system supports: rest, every atom,
93
+ * every modifier-subset (up to {@link MAX_MODIFIERS_PER_COMPOUND}) on its own
94
+ * and combined with each interactive, plus any legacy keys still in use.
95
+ *
96
+ * Mirrors `resolvePropertyStates` exactly so what the resolver pre-emits in
97
+ * the schema, what the StateBuilder lets users compose, and what the docs
98
+ * map / configurator safelist preserve are all the same set.
99
+ */
100
+ function enumerateAllStateKeys() {
101
+ const states = ["rest"];
102
+ const atoms = [...require_StateAxis.INTERACTIVE_ATOMICS, ...require_StateAxis.MODIFIER_ATOMICS].sort(require_StateAxis.comparePriority);
103
+ for (const stateKey of require_resolvePropertyStates.atomicAndCompoundStateKeys(atoms)) states.push(stateKey);
104
+ for (const legacy of LEGACY_STATE_KEYS) states.push(legacy);
105
+ return states;
106
+ }
107
+ const KNOWN_STATE_KEYS = enumerateAllStateKeys();
108
+ /**
109
+ * Lookup of every known state key to its index in `KNOWN_STATE_KEYS` — i.e. the
110
+ * resolver's emission order. The CSS generator iterates property-state maps
111
+ * in this order (instead of the alphabetical insertion order produced by
112
+ * `syncYosConfig`'s `normalizeConfig`), so cascade tie-breaking under the
113
+ * uniform per-atom specificity actually follows the priority chain. Unknown
114
+ * keys sort to the end.
115
+ */
116
+ const KNOWN_STATE_RANK = new Map(KNOWN_STATE_KEYS.map((key, index) => [key, index]));
117
+ function compareStateKeys(a, b) {
118
+ const ra = KNOWN_STATE_RANK.get(a) ?? Number.POSITIVE_INFINITY;
119
+ const rb = KNOWN_STATE_RANK.get(b) ?? Number.POSITIVE_INFINITY;
120
+ if (ra === rb) return a < b ? -1 : a > b ? 1 : 0;
121
+ return ra - rb;
122
+ }
123
+ function buildStateRecord(transform) {
124
+ const record = {};
125
+ for (const key of KNOWN_STATE_KEYS) record[key] = transform(key);
126
+ return record;
127
+ }
128
+ const statePseudoMapDocsMode = buildStateRecord(require_pseudoStateSelectors.getStateDocsClass);
105
129
  /**
106
130
  * Generates button line-height with icon size minimum.
107
131
  * Ensures button line-height is at least as tall as the icon to prevent clipping.
@@ -244,7 +268,57 @@ const getTheCssPropertyValue = (schema, theme, propertyName, schemaStateValue, e
244
268
  if (propertyConfig.concatenate && existingValue) return `${existingValue}${propertyConfig.concatenationDelimiter || ", "}${newValue}`;
245
269
  return newValue;
246
270
  };
247
- function generateDeclaration({ componentName, subComponentName, variantKey, variantValue, layer, layerOptionalPseudoSelector, componentStateKey, componentStateValue, schema, propertyKey, originalPropertyDefinition, theme, currentStyles, previewOptions, excludedPseudoStates = [] }) {
271
+ /**
272
+ * Builds the per-state resolution map for a per-componentState OVERRIDE in
273
+ * exhaustive mode: the universal layer's state map with the override's ENABLED
274
+ * (and `rest`) slots layered on top. An unset or disabled override slot defers
275
+ * to the universal layer's value, so `resolveSlotByCascade` picks the
276
+ * most-specific *enabled* slot across both layers (override winning ties) rather
277
+ * than collapsing every unset state to the override's own `rest`.
278
+ */
279
+ function mergeUniversalUnderOverride(universal, override) {
280
+ const merged = { ...universal };
281
+ const overrideRecord = override;
282
+ for (const state of Object.keys(overrideRecord)) {
283
+ const slot = overrideRecord[state];
284
+ if (state === "rest" && slot?.isEnabled !== false || slot?.isEnabled === true) merged[state] = slot;
285
+ }
286
+ return merged;
287
+ }
288
+ /**
289
+ * Replays SELECTIVE emission for a STANDALONE atomicStates layer (no universal
290
+ * fallback) and returns the sparse set of slots it would emit: `rest`, every
291
+ * explicitly-enabled state, and every cascade-correction. Mirrors the inline
292
+ * selective decision in `generateDeclaration` — keep the two in lock-step.
293
+ *
294
+ * The override path seeds its own correction accumulator with this for the
295
+ * UNIVERSAL layer. Universal layers are emitted in a separate pass at the SAME
296
+ * specificity tier as their per-option overrides (see `bumpRootSpecificity`), so
297
+ * at runtime a universal rule wins wherever the override emits nothing. Without
298
+ * this seed, an override that flattens a state to `rest` (e.g. a `filled` help
299
+ * text that's `muted` everywhere) silently inherits the universal's brighter
300
+ * rule for that state in selective mode — a divergence from exhaustive, where
301
+ * the override emits every state explicitly. Seeding makes the override emit a
302
+ * correction whenever the universal would otherwise render a different value.
303
+ */
304
+ function selectiveEmittedStates(stateMap, orderedStateKeys, emittableStates) {
305
+ const emitted = { rest: stateMap.rest };
306
+ for (const stateKey of orderedStateKeys) {
307
+ if (stateKey === "rest" || !emittableStates.has(stateKey)) continue;
308
+ const value = require_resolveSlotByCascade.resolveSlotByCascade(stateKey, stateMap);
309
+ if (!value) continue;
310
+ if (!(stateMap[stateKey]?.isEnabled === true)) {
311
+ if (require_resolveSlotByCascade.resolveSlotByCascade(stateKey, emitted)?.value === value.value) continue;
312
+ }
313
+ emitted[stateKey] = {
314
+ ...value,
315
+ isEnabled: true
316
+ };
317
+ }
318
+ return emitted;
319
+ }
320
+ function generateDeclaration({ componentName, subComponentName, variantKey, variantValue, layer, layerOptionalPseudoSelector, componentStateKey, componentStateValue, schema, propertyKey, originalPropertyDefinition, declaredStates, layerUsesAtomicStates, theme, currentStyles, previewOptions, excludedPseudoStates = [], emit, fallbackStateMap, bumpRootSpecificity }) {
321
+ const shouldUseExhaustive = (emit ?? "exhaustive") === "exhaustive" && layerUsesAtomicStates;
248
322
  const schemaKey = require_generateSchemaKey.generateSchemaKey({
249
323
  variantKey,
250
324
  variantValue,
@@ -265,14 +339,29 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
265
339
  const propertyStateMap = schema.variables?.[schemaKey]?.[propertyKey];
266
340
  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
341
  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;
342
+ const excludedStateSet = new Set(excludedPseudoStates);
343
+ const emittableStates = new Set([...declaredStates].filter((state) => !excludedStateSet.has(state)));
344
+ const orderedStateKeys = (shouldUseExhaustive || layerUsesAtomicStates ? [...emittableStates] : Object.keys(propertyStateMap)).sort(compareStateKeys);
345
+ const resolutionStates = fallbackStateMap ? mergeUniversalUnderOverride(fallbackStateMap, propertyStateMap) : propertyStateMap;
346
+ const emittedForSelective = layerUsesAtomicStates && !shouldUseExhaustive ? fallbackStateMap ? selectiveEmittedStates(fallbackStateMap, orderedStateKeys, emittableStates) : { rest: resolutionStates.rest } : {};
347
+ for (const propStateStr of orderedStateKeys) {
348
+ if (!emittableStates.has(propStateStr)) continue;
273
349
  const propertyState = propStateStr;
274
- const propertyStateSelector = statePseudoMap[propertyState] ?? "";
275
- const schemaValueForState = propertyStateMap[propertyState];
350
+ const propertyStateSelector = require_pseudoStateSelectors.getStateSelector(propertyState);
351
+ const schemaValueForState = shouldUseExhaustive || layerUsesAtomicStates ? require_resolveSlotByCascade.resolveSlotByCascade(propStateStr, resolutionStates) : propertyStateMap[propertyState];
352
+ if (!schemaValueForState) continue;
353
+ if (!shouldUseExhaustive) {
354
+ if (layerUsesAtomicStates) {
355
+ const isExplicitlyEnabled = propertyStateMap[propertyState]?.isEnabled === true;
356
+ if (propStateStr !== "rest" && !isExplicitlyEnabled) {
357
+ if (require_resolveSlotByCascade.resolveSlotByCascade(propStateStr, emittedForSelective)?.value === schemaValueForState.value) continue;
358
+ }
359
+ emittedForSelective[propStateStr] = {
360
+ ...schemaValueForState,
361
+ isEnabled: true
362
+ };
363
+ } else if (schemaValueForState.isEnabled === false) continue;
364
+ }
276
365
  let fullClassName = ``;
277
366
  if (layer === "root") if (componentStateKey && componentStateValue) {
278
367
  const rootVariantClass = generateClassName({
@@ -291,7 +380,7 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
291
380
  componentStateValue
292
381
  });
293
382
  fullClassName = `.${rootVariantClass}${propertyStateSelector}.${className}`;
294
- } else fullClassName = `.${className}${propertyStateSelector}`;
383
+ } else fullClassName = bumpRootSpecificity ? `.${className}.${className}${propertyStateSelector}` : `.${className}${propertyStateSelector}`;
295
384
  else {
296
385
  const rootVariantClassName = generateClassName({
297
386
  componentName,
@@ -318,7 +407,17 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
318
407
  subComponentName
319
408
  });
320
409
  fullClassName = `.${rootVariantClassName}${propertyStateSelector}.${rootVariantClassNameWithComponentState} .${className}`;
321
- } else fullClassName = `.${rootVariantClassName}${propertyStateSelector} .${className}`;
410
+ } else {
411
+ className = generateClassName({
412
+ componentName,
413
+ variantKey,
414
+ variantValue,
415
+ layer,
416
+ layerOptionalPseudoSelector,
417
+ subComponentName
418
+ });
419
+ fullClassName = bumpRootSpecificity ? `.${rootVariantClassName}.${rootVariantClassName}${propertyStateSelector} .${className}` : `.${rootVariantClassName}${propertyStateSelector} .${className}`;
420
+ }
322
421
  }
323
422
  const { cssProperties, extendedProperties: extendedPropertiesGetter } = require_properties.configurableProperties[originalPropertyDefinition.name];
324
423
  const cssDeclarations = {};
@@ -460,7 +559,7 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
460
559
  ...styles[fullClassName]
461
560
  };
462
561
  if (previewOptions?.generatePseudoStateClassModifier) {
463
- const pseudoPrefixClass = statePseudoMapDocsMode[propertyState] ?? "";
562
+ const pseudoPrefixClass = require_pseudoStateSelectors.getStateDocsClass(propertyState);
464
563
  if (pseudoPrefixClass.length) {
465
564
  const importantCssDeclarations = Object.fromEntries(Object.entries(cssDeclarations).map(([prop, value]) => {
466
565
  const strValue = String(value).trimEnd().replace(/;$/, "");
@@ -476,12 +575,137 @@ function generateDeclaration({ componentName, subComponentName, variantKey, vari
476
575
  }
477
576
  return styles;
478
577
  }
479
- function generateConfigStyles(config, schema, theme, previewOptions) {
578
+ /**
579
+ * Emit CSS for per-state schema entries that target a variant's universal
580
+ * layers — the "override" path. Per-state schema entries can be authored by
581
+ * the Configurator (via `setConfigPseudoStateVariable`) or written by data
582
+ * migrations; they aren't declared in source configs.
583
+ *
584
+ * Iterates the cartesian product of `componentStates.X.options × universal
585
+ * layers × universal properties`. For each combination, calls
586
+ * `generateDeclaration` with the universal property's metadata plus the
587
+ * componentState key/value — the existing schema lookup inside
588
+ * `generateDeclaration` picks up the override slot if one exists and skips
589
+ * the property otherwise.
590
+ */
591
+ function emitSchemaOverrideStyles({ componentName, subComponentName, variantKey, variantOption, variantConfig, schema, theme, previewOptions, emit, currentStyles }) {
592
+ let styles = currentStyles;
593
+ const universalLayers = variantConfig.layers;
594
+ const componentStates = variantConfig.componentStates;
595
+ if (!universalLayers || !componentStates) return styles;
596
+ const variables = schema.variables;
597
+ if (!variables) return styles;
598
+ for (const componentStateKey in componentStates) {
599
+ const componentState = componentStates[componentStateKey];
600
+ for (const componentStateOption of componentState.options) for (const layerKey in universalLayers) {
601
+ const universalLayer = universalLayers[layerKey];
602
+ const schemaEntry = variables[require_generateSchemaKey.generateSchemaKey({
603
+ variantKey,
604
+ variantValue: variantOption,
605
+ componentStateKey,
606
+ componentStateValue: componentStateOption,
607
+ layer: layerKey,
608
+ subComponentName
609
+ })];
610
+ if (!schemaEntry) continue;
611
+ for (const propertyKey in universalLayer.properties) {
612
+ if (!schemaEntry[propertyKey]) continue;
613
+ const originalPropertyDefinition = universalLayer.properties[propertyKey];
614
+ const fallbackStateMap = variables[require_generateSchemaKey.generateSchemaKey({
615
+ variantKey,
616
+ variantValue: variantOption,
617
+ layer: layerKey,
618
+ subComponentName
619
+ })]?.[propertyKey];
620
+ const declarations = generateDeclaration({
621
+ componentName,
622
+ subComponentName,
623
+ variantKey,
624
+ variantValue: variantOption,
625
+ componentStateKey,
626
+ componentStateValue: componentStateOption,
627
+ layer: layerKey,
628
+ layerOptionalPseudoSelector: universalLayer.pseudoSelector,
629
+ propertyKey,
630
+ originalPropertyDefinition,
631
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(universalLayer, originalPropertyDefinition)),
632
+ layerUsesAtomicStates: (universalLayer.atomicStates?.length ?? 0) > 0,
633
+ theme,
634
+ schema,
635
+ currentStyles: styles,
636
+ previewOptions,
637
+ emit,
638
+ fallbackStateMap
639
+ });
640
+ styles = deepMerge(styles, declarations);
641
+ }
642
+ }
643
+ }
644
+ return styles;
645
+ }
646
+ /**
647
+ * Emit CSS for a set of layers without a component-state segment in the
648
+ * selector. Used by both `VariantConfigWithProperties` (where layers are the
649
+ * only source of styles) and `VariantConfigWithComponentStates` (where these
650
+ * layers express the variant's universal baseline, with per-state overrides
651
+ * winning via class-compound specificity).
652
+ */
653
+ function emitUniversalLayers({ componentName, subComponentName, variantKey, variantOption, layers, schema, theme, previewOptions, emit, currentStyles, bumpRootSpecificity }) {
654
+ let styles = currentStyles;
655
+ const variables = schema.variables;
656
+ for (const layerKey in layers) {
657
+ const layer = layers[layerKey];
658
+ const schemaKey = require_generateSchemaKey.generateSchemaKey({
659
+ variantKey,
660
+ variantValue: variantOption,
661
+ layer: layerKey,
662
+ subComponentName
663
+ });
664
+ const schemaEntry = variables?.[schemaKey];
665
+ for (const propertyKey in layer.properties) {
666
+ if (!schemaEntry || !schemaEntry[propertyKey]) continue;
667
+ const originalPropertyDefinition = layer.properties[propertyKey];
668
+ const declarations = generateDeclaration({
669
+ componentName,
670
+ subComponentName,
671
+ variantKey,
672
+ variantValue: variantOption,
673
+ layer: layerKey,
674
+ layerOptionalPseudoSelector: layer.pseudoSelector,
675
+ propertyKey,
676
+ originalPropertyDefinition,
677
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(layer, originalPropertyDefinition)),
678
+ layerUsesAtomicStates: (layer.atomicStates?.length ?? 0) > 0,
679
+ theme,
680
+ schema,
681
+ currentStyles: styles,
682
+ previewOptions,
683
+ emit,
684
+ bumpRootSpecificity
685
+ });
686
+ styles = deepMerge(styles, declarations);
687
+ }
688
+ }
689
+ return styles;
690
+ }
691
+ function generateConfigStyles(config, schema, theme, previewOptions, emit) {
480
692
  const componentName = config.label.toLowerCase();
481
693
  let styles = {};
482
694
  for (const variantKey in config.variants) {
483
695
  const variantConfig = config.variants[variantKey];
484
696
  for (const variantOption of variantConfig.options) if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
697
+ if (variantConfig.layers) styles = emitUniversalLayers({
698
+ componentName,
699
+ variantKey,
700
+ variantOption,
701
+ layers: variantConfig.layers,
702
+ schema,
703
+ theme,
704
+ previewOptions,
705
+ emit,
706
+ currentStyles: styles,
707
+ bumpRootSpecificity: true
708
+ });
485
709
  const componentStates = variantConfig.componentStates;
486
710
  for (const componentStateKey in componentStates) {
487
711
  const componentState = componentStates[componentStateKey];
@@ -501,46 +725,61 @@ function generateConfigStyles(config, schema, theme, previewOptions) {
501
725
  layerOptionalPseudoSelector: layer.pseudoSelector,
502
726
  propertyKey,
503
727
  originalPropertyDefinition,
728
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(layer, originalPropertyDefinition)),
729
+ layerUsesAtomicStates: (layer.atomicStates?.length ?? 0) > 0,
504
730
  theme,
505
731
  schema,
506
732
  currentStyles: styles,
507
733
  previewOptions,
508
- excludedPseudoStates
734
+ excludedPseudoStates,
735
+ emit
509
736
  });
510
737
  styles = deepMerge(styles, declarations);
511
738
  }
512
739
  }
513
740
  }
514
741
  }
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
- }
742
+ styles = emitSchemaOverrideStyles({
743
+ componentName,
744
+ variantKey,
745
+ variantOption,
746
+ variantConfig,
747
+ schema,
748
+ theme,
749
+ previewOptions,
750
+ emit,
751
+ currentStyles: styles
752
+ });
753
+ } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) styles = emitUniversalLayers({
754
+ componentName,
755
+ variantKey,
756
+ variantOption,
757
+ layers: variantConfig.layers,
758
+ schema,
759
+ theme,
760
+ previewOptions,
761
+ emit,
762
+ currentStyles: styles
763
+ });
538
764
  }
539
765
  if (config.subComponents) {
540
766
  const { subComponents } = config;
541
767
  for (const subComponentKey in subComponents) for (const variantKey in subComponents[subComponentKey].variants) {
542
768
  const variantConfig = subComponents[subComponentKey].variants[variantKey];
543
769
  for (const variantOption of variantConfig.options) if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
770
+ if (variantConfig.layers) styles = emitUniversalLayers({
771
+ componentName,
772
+ subComponentName: subComponentKey,
773
+ variantKey,
774
+ variantOption,
775
+ layers: variantConfig.layers,
776
+ schema,
777
+ theme,
778
+ previewOptions,
779
+ emit,
780
+ currentStyles: styles,
781
+ bumpRootSpecificity: true
782
+ });
544
783
  const componentStates = variantConfig.componentStates;
545
784
  for (const componentStateKey in componentStates) {
546
785
  const componentState = componentStates[componentStateKey];
@@ -561,41 +800,44 @@ function generateConfigStyles(config, schema, theme, previewOptions) {
561
800
  layerOptionalPseudoSelector: layer.pseudoSelector,
562
801
  propertyKey,
563
802
  originalPropertyDefinition,
803
+ declaredStates: new Set(require_resolvePropertyStates.resolvePropertyStates(layer, originalPropertyDefinition)),
804
+ layerUsesAtomicStates: (layer.atomicStates?.length ?? 0) > 0,
564
805
  theme,
565
806
  schema,
566
807
  currentStyles: styles,
567
808
  previewOptions,
568
- excludedPseudoStates
809
+ excludedPseudoStates,
810
+ emit
569
811
  });
570
812
  styles = deepMerge(styles, declarations);
571
813
  }
572
814
  }
573
815
  }
574
816
  }
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
- }
817
+ styles = emitSchemaOverrideStyles({
818
+ componentName,
819
+ subComponentName: subComponentKey,
820
+ variantKey,
821
+ variantOption,
822
+ variantConfig,
823
+ schema,
824
+ theme,
825
+ previewOptions,
826
+ emit,
827
+ currentStyles: styles
828
+ });
829
+ } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) styles = emitUniversalLayers({
830
+ componentName,
831
+ subComponentName: subComponentKey,
832
+ variantKey,
833
+ variantOption,
834
+ layers: variantConfig.layers,
835
+ schema,
836
+ theme,
837
+ previewOptions,
838
+ emit,
839
+ currentStyles: styles
840
+ });
599
841
  }
600
842
  }
601
843
  /**
@@ -628,8 +870,8 @@ function generateConfigStyles(config, schema, theme, previewOptions) {
628
870
  * @param previewOptions - Options for generating preview mode class modifiers
629
871
  * @returns CSS styles object with grouped selectors for default aliases
630
872
  */
631
- const generateStyles = (config, schema, theme, previewOptions) => {
632
- const styles = generateConfigStyles(config, schema, theme, previewOptions);
873
+ const generateStylesInner = (config, schema, theme, previewOptions) => {
874
+ const styles = generateConfigStyles(config, schema, theme, previewOptions, previewOptions.emit ?? "exhaustive");
633
875
  if (!config.variants && !config.subComponents) return styles;
634
876
  const componentName = config.label.toLowerCase();
635
877
  if (componentName !== "button" && componentName !== "iconbutton") return styles;
@@ -637,14 +879,15 @@ const generateStyles = (config, schema, theme, previewOptions) => {
637
879
  /**
638
880
  * Helper: Extract all layer keys from a variant configuration
639
881
  * Handles both simple variants (with direct layers) and variants with component states
882
+ * (which may additionally declare top-level universal layers).
640
883
  */
641
884
  const getLayerKeys = (variantConfig) => {
642
- if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) return Object.keys(variantConfig.layers);
643
- else if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
885
+ if (require_variantConfigGuards.isVariantConfigWithComponentStates(variantConfig)) {
644
886
  const layerKeysSet = /* @__PURE__ */ new Set();
645
- for (const componentStateConfig of Object.values(variantConfig.componentStates)) Object.keys(componentStateConfig.layers).forEach((key) => layerKeysSet.add(key));
887
+ for (const componentStateConfig of Object.values(variantConfig.componentStates)) Object.keys(componentStateConfig.layers ?? {}).forEach((key) => layerKeysSet.add(key));
888
+ if (variantConfig.layers) Object.keys(variantConfig.layers).forEach((key) => layerKeysSet.add(key));
646
889
  return Array.from(layerKeysSet);
647
- }
890
+ } else if (require_variantConfigGuards.isVariantConfigWithProperties(variantConfig)) return Object.keys(variantConfig.layers);
648
891
  return [];
649
892
  };
650
893
  /**
@@ -694,7 +937,39 @@ const generateStyles = (config, schema, theme, previewOptions) => {
694
937
  }
695
938
  return finalStyles;
696
939
  };
940
+ /**
941
+ * Public entry point. Generates a component's CSS, emitting each declared state
942
+ * as its own rule (one selector per rule) so the cascade is carried entirely by
943
+ * per-rule specificity — which CSS minifiers preserve.
944
+ *
945
+ * An earlier optimization merged rules sharing a declaration block into a single
946
+ * comma-separated selector list (to avoid repeating invariant declarations per
947
+ * state). It was removed: a minifier's forgiving-`:is()` rewrite — applied to a
948
+ * comma-separated list that contains `:has()` when targeting browsers without
949
+ * native `:has()` support — collapses the list to its single highest
950
+ * specificity, inflating the weakest selector (`rest`) above genuinely
951
+ * customized states and corrupting the cascade. Separate rules never form such a
952
+ * list, so minifiers leave their specificity intact. (gzip already collapses the
953
+ * repeated declaration blocks, so the shipped-size cost is minimal.)
954
+ */
955
+ const generateStyles = (config, schema, theme, previewOptions) => generateStylesInner(config, schema, theme, previewOptions);
956
+ /**
957
+ * Throws if `values` contains a duplicate entry. Runs at config-import time so
958
+ * a typo like `atomicStates: ['hover', 'hover']` fails the UDS build instead
959
+ * of silently degrading the configurator's sidebar (where the resolver would
960
+ * emit two entries for the same state).
961
+ */
962
+ function assertNoDuplicates(values, field, ownerLabel) {
963
+ if (!values) return;
964
+ const seen = /* @__PURE__ */ new Set();
965
+ for (const v of values) {
966
+ if (seen.has(v)) throw new Error(`Duplicate "${v}" in ${field} on ${ownerLabel}. Each entry must appear at most once.`);
967
+ seen.add(v);
968
+ }
969
+ }
697
970
  function createConfigurableProperty(prop) {
971
+ assertNoDuplicates(prop.pseudoStates, "pseudoStates", `property "${prop.label}"`);
972
+ assertNoDuplicates(prop.excludeAtomics, "excludeAtomics", `property "${prop.label}"`);
698
973
  return prop;
699
974
  }
700
975
  function createVariantConfig(config) {
@@ -710,8 +985,42 @@ function createComponentStates(config) {
710
985
  return config;
711
986
  }
712
987
  function createLayerConfig(config) {
988
+ assertNoDuplicates(config.atomicStates, "atomicStates", `layer "${config.label}"`);
989
+ assertNoSkipRestStateOnAtomicLayer(config);
713
990
  return config;
714
991
  }
992
+ /**
993
+ * Disallows pairing `skipRestState: true` properties with a layer that uses
994
+ * `atomicStates`. The combination breaks exhaustive emission's cascade
995
+ * resolution:
996
+ *
997
+ * Under `atomicStates`, `generateDeclaration` emits every declared state and
998
+ * resolves each non-customized compound through `resolveSlotByCascade`, so a
999
+ * deliberate atom customization (e.g. `hover`) flows into every compound that
1000
+ * inherits from it (`invalid&hover`, …). That inheritance is what keeps the
1001
+ * higher-specificity compound rules from cancelling a lower-specificity atom
1002
+ * customization.
1003
+ *
1004
+ * But `buildPropertyStateMap` force-marks EVERY slot of a `skipRestState`
1005
+ * property `isEnabled: true` (there's no `rest` fall-through, so each state must
1006
+ * carry its own value). `resolveSlotByCascade` returns an enabled slot as-is,
1007
+ * so each force-enabled compound emits the property's *default* value instead of
1008
+ * inheriting a sibling atom's customization — and the compound's higher
1009
+ * specificity then silently overrides that customization (e.g. a customized
1010
+ * `hover` is cancelled by an unmodified `invalid&hover` carrying the default).
1011
+ *
1012
+ * Resolution path when this becomes a real need (currently the only
1013
+ * `skipRestState` properties are Button's `opacity` and `scaleEffect`, and
1014
+ * Button is on legacy `pseudoStates`):
1015
+ * teach `generateDeclaration` to skip compound state emission entirely for
1016
+ * `skipRestState` properties — atom rules cascade naturally, and designers
1017
+ * who want fine compound control simply drop `skipRestState` for that
1018
+ * property.
1019
+ */
1020
+ function assertNoSkipRestStateOnAtomicLayer(config) {
1021
+ if (!config.atomicStates || config.atomicStates.length === 0) return;
1022
+ 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.`);
1023
+ }
715
1024
  function createSubComponentConfig(config) {
716
1025
  return config;
717
1026
  }
@@ -728,4 +1037,5 @@ exports.generateClassName = generateClassName;
728
1037
  exports.generateConfigStyles = generateConfigStyles;
729
1038
  exports.generateDeclaration = generateDeclaration;
730
1039
  exports.generateStyles = generateStyles;
1040
+ exports.mergeUniversalUnderOverride = mergeUniversalUnderOverride;
731
1041
  exports.statePseudoMapDocsMode = statePseudoMapDocsMode;