@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
@@ -0,0 +1,122 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_StateAxis = require("../types/StateAxis.cjs");
3
+ const require_canonicalizeStateKey = require("./canonicalizeStateKey.cjs");
4
+ //#region ../tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind Internal v0.0.0-development */
6
+ /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
7
+ const LEGACY_STATE_ATOMS = new Set([
8
+ "disabled",
9
+ "focused",
10
+ "focused-keyboard"
11
+ ]);
12
+ function isKnownStateAtom(atom) {
13
+ return require_StateAxis.isAtomicState(atom) || LEGACY_STATE_ATOMS.has(atom);
14
+ }
15
+ /**
16
+ * Each atom selector contributes exactly (0,1,0) to specificity. The base
17
+ * component class adds another (0,1,0), so a full rule's specificity is
18
+ * `(0, 1 + atom-count, 0)`:
19
+ *
20
+ * rest → (0,1,0) e.g. `.uds-input-...root`
21
+ * 1-atom → (0,2,0) e.g. `.uds-input-...root:hover...`
22
+ * 2-atom → (0,3,0) e.g. `.uds-input-...root:has(...):hover...`
23
+ * 3-atom → (0,4,0)
24
+ * 4-atom → (0,5,0)
25
+ *
26
+ * Cross-rank cascade (compound beats atom beats rest) is therefore encoded
27
+ * in CSS class-count specificity, not source order — making the cascade-
28
+ * cancellation feature robust to any tool that reorders rules within a
29
+ * stylesheet. Within a rank (e.g. `:hover` vs `:focus-visible`, both
30
+ * (0,2,0)) source order still arbitrates; the resolver computes intra-rank
31
+ * order inline from `STATE_PRIORITY`. See {@link resolvePropertyStates}.
32
+ *
33
+ * Why each entry is (0,1,0):
34
+ *
35
+ * - `:hover` / `:active` / `:focus*` / `:visited` are single pseudo-classes,
36
+ * each (0,1,0).
37
+ * - `:hover` and `:active` carry a `:where(:not(...))` blocker so the rule
38
+ * doesn't match when the element is also active/disabled. The outer
39
+ * `:where()` zeros the `:not(...)` contribution, leaving the bare pseudo-
40
+ * class's (0,1,0) as the only contributor.
41
+ * - `:is(:disabled, :has(:disabled))` takes the max specificity of its
42
+ * args; both are (0,1,0), so the whole is (0,1,0).
43
+ * - `:has(...)` selectors take the specificity of their arg's most specific
44
+ * complex selector. Arguments are pseudo-classes or attribute selectors at
45
+ * (0,1,0); where a form-control scope is also needed (e.g. `readonly` —
46
+ * non-form-control elements default to `:read-only` per spec, so a bare
47
+ * `:has(:read-only)` matches any container with DIV/SPAN children), the
48
+ * scope goes inside `:where(...)` so its (0,0,1) type-selector contribution
49
+ * is zeroed.
50
+ *
51
+ * **Consumer override ergonomics:** a plain `.my-input:hover` is (0,2,0),
52
+ * which ties library 1-atom rules at (0,2,0); source order decides. To
53
+ * unconditionally beat the library, consumers need (0,3,0) (e.g.
54
+ * `.scope .my-input:hover` or `.my-input.my-input:hover`).
55
+ */
56
+ const ATOMIC_SELECTORS = {
57
+ hover: ":hover:where(:not(:active, :disabled, :has(:disabled)))",
58
+ pressed: ":active:where(:not(:disabled, :has(:disabled)))",
59
+ disabled: ":is(:disabled, :has(:disabled))",
60
+ visited: ":visited",
61
+ focused: ":focus",
62
+ "focus-within": ":focus-within",
63
+ "focus-visible": ":focus-visible",
64
+ "focused-keyboard": ":focus-visible",
65
+ readonly: ":has(:read-only:where(input, textarea))",
66
+ invalid: ":has([aria-invalid=\"true\"])",
67
+ "placeholder-shown": ":has(:placeholder-shown)",
68
+ autofill: ":has(:autofill, :-webkit-autofill)"
69
+ };
70
+ const ATOMIC_DOCS_CLASSES = {
71
+ hover: "hover",
72
+ pressed: "active",
73
+ disabled: "has-disabled",
74
+ visited: "visited",
75
+ focused: "focus",
76
+ "focus-within": "focus-within",
77
+ "focus-visible": "focus-visible",
78
+ "focused-keyboard": "focus-visible",
79
+ readonly: "input-readonly",
80
+ invalid: "has-input-invalid",
81
+ "placeholder-shown": "has-input-placeholder-shown",
82
+ autofill: "has-input-autofill"
83
+ };
84
+ /**
85
+ * Returns the CSS pseudo-selector string for a state key.
86
+ *
87
+ * - `'rest'`, `''`, and fully-unknown keys return `''`. An unknown atom inside
88
+ * an otherwise-known compound is skipped (the known atoms still contribute) —
89
+ * but callers only pass canonical validated keys, so that case doesn't arise
90
+ * in practice.
91
+ * - Atomic keys return their entry from {@link ATOMIC_SELECTORS}.
92
+ * - Compound keys (`'a&b'`) return the concatenation of each atomic selector
93
+ * in the order they appear in the key.
94
+ */
95
+ function getStateSelector(stateKey) {
96
+ const atoms = require_canonicalizeStateKey.splitStateKey(stateKey);
97
+ if (atoms.length === 0) return "";
98
+ let selector = "";
99
+ for (const atom of atoms) if (isKnownStateAtom(atom)) selector += ATOMIC_SELECTORS[atom];
100
+ return selector;
101
+ }
102
+ /**
103
+ * Returns the docs-mode class name for a state key, used to force-trigger
104
+ * pseudo-states in docs/Storybook previews.
105
+ *
106
+ * - `'rest'`, `''`, and fully-unknown keys return `''`. An unknown atom inside
107
+ * an otherwise-known compound is skipped (the known atoms still contribute) —
108
+ * but callers only pass canonical validated keys, so that case doesn't arise
109
+ * in practice.
110
+ * - Atomic keys return their entry from {@link ATOMIC_DOCS_CLASSES}.
111
+ * - Compound keys join atomic docs classes with `'-and-'`.
112
+ */
113
+ function getStateDocsClass(stateKey) {
114
+ const atoms = require_canonicalizeStateKey.splitStateKey(stateKey);
115
+ if (atoms.length === 0) return "";
116
+ const parts = [];
117
+ for (const atom of atoms) if (isKnownStateAtom(atom)) parts.push(ATOMIC_DOCS_CLASSES[atom]);
118
+ return parts.join("-and-");
119
+ }
120
+ //#endregion
121
+ exports.getStateDocsClass = getStateDocsClass;
122
+ exports.getStateSelector = getStateSelector;
@@ -0,0 +1,121 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { isAtomicState } from "../types/StateAxis.js";
3
+ import { splitStateKey } from "./canonicalizeStateKey.js";
4
+ //#region ../tailwind-internal/dist/packages/automated-config/dist/utils/pseudoStateSelectors.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind Internal v0.0.0-development */
6
+ /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
7
+ const LEGACY_STATE_ATOMS = new Set([
8
+ "disabled",
9
+ "focused",
10
+ "focused-keyboard"
11
+ ]);
12
+ function isKnownStateAtom(atom) {
13
+ return isAtomicState(atom) || LEGACY_STATE_ATOMS.has(atom);
14
+ }
15
+ /**
16
+ * Each atom selector contributes exactly (0,1,0) to specificity. The base
17
+ * component class adds another (0,1,0), so a full rule's specificity is
18
+ * `(0, 1 + atom-count, 0)`:
19
+ *
20
+ * rest → (0,1,0) e.g. `.uds-input-...root`
21
+ * 1-atom → (0,2,0) e.g. `.uds-input-...root:hover...`
22
+ * 2-atom → (0,3,0) e.g. `.uds-input-...root:has(...):hover...`
23
+ * 3-atom → (0,4,0)
24
+ * 4-atom → (0,5,0)
25
+ *
26
+ * Cross-rank cascade (compound beats atom beats rest) is therefore encoded
27
+ * in CSS class-count specificity, not source order — making the cascade-
28
+ * cancellation feature robust to any tool that reorders rules within a
29
+ * stylesheet. Within a rank (e.g. `:hover` vs `:focus-visible`, both
30
+ * (0,2,0)) source order still arbitrates; the resolver computes intra-rank
31
+ * order inline from `STATE_PRIORITY`. See {@link resolvePropertyStates}.
32
+ *
33
+ * Why each entry is (0,1,0):
34
+ *
35
+ * - `:hover` / `:active` / `:focus*` / `:visited` are single pseudo-classes,
36
+ * each (0,1,0).
37
+ * - `:hover` and `:active` carry a `:where(:not(...))` blocker so the rule
38
+ * doesn't match when the element is also active/disabled. The outer
39
+ * `:where()` zeros the `:not(...)` contribution, leaving the bare pseudo-
40
+ * class's (0,1,0) as the only contributor.
41
+ * - `:is(:disabled, :has(:disabled))` takes the max specificity of its
42
+ * args; both are (0,1,0), so the whole is (0,1,0).
43
+ * - `:has(...)` selectors take the specificity of their arg's most specific
44
+ * complex selector. Arguments are pseudo-classes or attribute selectors at
45
+ * (0,1,0); where a form-control scope is also needed (e.g. `readonly` —
46
+ * non-form-control elements default to `:read-only` per spec, so a bare
47
+ * `:has(:read-only)` matches any container with DIV/SPAN children), the
48
+ * scope goes inside `:where(...)` so its (0,0,1) type-selector contribution
49
+ * is zeroed.
50
+ *
51
+ * **Consumer override ergonomics:** a plain `.my-input:hover` is (0,2,0),
52
+ * which ties library 1-atom rules at (0,2,0); source order decides. To
53
+ * unconditionally beat the library, consumers need (0,3,0) (e.g.
54
+ * `.scope .my-input:hover` or `.my-input.my-input:hover`).
55
+ */
56
+ const ATOMIC_SELECTORS = {
57
+ hover: ":hover:where(:not(:active, :disabled, :has(:disabled)))",
58
+ pressed: ":active:where(:not(:disabled, :has(:disabled)))",
59
+ disabled: ":is(:disabled, :has(:disabled))",
60
+ visited: ":visited",
61
+ focused: ":focus",
62
+ "focus-within": ":focus-within",
63
+ "focus-visible": ":focus-visible",
64
+ "focused-keyboard": ":focus-visible",
65
+ readonly: ":has(:read-only:where(input, textarea))",
66
+ invalid: ":has([aria-invalid=\"true\"])",
67
+ "placeholder-shown": ":has(:placeholder-shown)",
68
+ autofill: ":has(:autofill, :-webkit-autofill)"
69
+ };
70
+ const ATOMIC_DOCS_CLASSES = {
71
+ hover: "hover",
72
+ pressed: "active",
73
+ disabled: "has-disabled",
74
+ visited: "visited",
75
+ focused: "focus",
76
+ "focus-within": "focus-within",
77
+ "focus-visible": "focus-visible",
78
+ "focused-keyboard": "focus-visible",
79
+ readonly: "input-readonly",
80
+ invalid: "has-input-invalid",
81
+ "placeholder-shown": "has-input-placeholder-shown",
82
+ autofill: "has-input-autofill"
83
+ };
84
+ /**
85
+ * Returns the CSS pseudo-selector string for a state key.
86
+ *
87
+ * - `'rest'`, `''`, and fully-unknown keys return `''`. An unknown atom inside
88
+ * an otherwise-known compound is skipped (the known atoms still contribute) —
89
+ * but callers only pass canonical validated keys, so that case doesn't arise
90
+ * in practice.
91
+ * - Atomic keys return their entry from {@link ATOMIC_SELECTORS}.
92
+ * - Compound keys (`'a&b'`) return the concatenation of each atomic selector
93
+ * in the order they appear in the key.
94
+ */
95
+ function getStateSelector(stateKey) {
96
+ const atoms = splitStateKey(stateKey);
97
+ if (atoms.length === 0) return "";
98
+ let selector = "";
99
+ for (const atom of atoms) if (isKnownStateAtom(atom)) selector += ATOMIC_SELECTORS[atom];
100
+ return selector;
101
+ }
102
+ /**
103
+ * Returns the docs-mode class name for a state key, used to force-trigger
104
+ * pseudo-states in docs/Storybook previews.
105
+ *
106
+ * - `'rest'`, `''`, and fully-unknown keys return `''`. An unknown atom inside
107
+ * an otherwise-known compound is skipped (the known atoms still contribute) —
108
+ * but callers only pass canonical validated keys, so that case doesn't arise
109
+ * in practice.
110
+ * - Atomic keys return their entry from {@link ATOMIC_DOCS_CLASSES}.
111
+ * - Compound keys join atomic docs classes with `'-and-'`.
112
+ */
113
+ function getStateDocsClass(stateKey) {
114
+ const atoms = splitStateKey(stateKey);
115
+ if (atoms.length === 0) return "";
116
+ const parts = [];
117
+ for (const atom of atoms) if (isKnownStateAtom(atom)) parts.push(ATOMIC_DOCS_CLASSES[atom]);
118
+ return parts.join("-and-");
119
+ }
120
+ //#endregion
121
+ export { getStateDocsClass, getStateSelector };
@@ -0,0 +1,132 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_StateAxis = require("../types/StateAxis.cjs");
3
+ const require_canonicalizeStateKey = require("./canonicalizeStateKey.cjs");
4
+ //#region ../tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind Internal v0.0.0-development */
6
+ /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
7
+ /**
8
+ * Yields every modifier subset of size 1..maxSize, preserving input order
9
+ * within each subset. Used by both the resolver and the docs-class
10
+ * enumeration so the depth they support stays in lock-step.
11
+ *
12
+ * Generic over the element type so callers passing `ModifierAtomic[]` get
13
+ * `Generator<readonly ModifierAtomic[]>` back — keeps the inferred type chain
14
+ * tight enough for downstream consumers to avoid widening to `string`.
15
+ */
16
+ function* modifierSubsets(modifiers, maxSize) {
17
+ const indices = [];
18
+ function* recurse(start) {
19
+ if (indices.length > 0) yield indices.map((i) => modifiers[i]);
20
+ if (indices.length === maxSize) return;
21
+ for (let i = start; i < modifiers.length; i++) {
22
+ indices.push(i);
23
+ yield* recurse(i + 1);
24
+ indices.pop();
25
+ }
26
+ }
27
+ yield* recurse(0);
28
+ }
29
+ /**
30
+ * Yields the interactive subsets that can be simultaneously active on one
31
+ * element, in `modifierSubsets` order. `hover` and `pressed` are mutually
32
+ * exclusive — the `hover` selector carries `:where(:not(:active …))`, so a
33
+ * `hover&pressed` rule could never match — so any subset containing BOTH is
34
+ * dropped. Every other subset is kept (notably `focus-within`/`focus-visible`
35
+ * CAN coexist with a pointer state: you can hover or press a focused element).
36
+ *
37
+ * `interactives` MUST already be sorted by `comparePriority`.
38
+ */
39
+ function* coOccurringInteractiveSubsets(interactives) {
40
+ for (const subset of modifierSubsets(interactives, interactives.length)) {
41
+ if (subset.includes("hover") && subset.includes("pressed")) continue;
42
+ yield subset;
43
+ }
44
+ }
45
+ /**
46
+ * Yields a property's atomic + compound state keys in cascade order from a
47
+ * priority-sorted atomic set:
48
+ *
49
+ * atoms (in the given order)
50
+ * → for each modifier subset: the pure-modifier compound (size ≥ 2) then each
51
+ * modifier-subset × SINGLE-interactive compound
52
+ * → each pure interactive-pair compound (size ≥ 2, co-occurring)
53
+ * → each modifier-subset × interactive-PAIR compound
54
+ *
55
+ * The interactive-pair compounds are APPENDED after the original keys so every
56
+ * pre-existing key keeps its rank — `resolveSlotByCascade`'s tie-break and
57
+ * Figma's published values for already-declared states are therefore unchanged;
58
+ * only genuinely new co-occurring combinations (e.g. `focus-within&hover`) gain
59
+ * a key. Each is a real declared state with its own rule, so a property whose
60
+ * `focus-within` and `hover` resolve to different values renders the
61
+ * per-property-correct blend at `(0, 1+atomCount, 0)` specificity in BOTH emit
62
+ * modes — closing the only exhaustive/selective divergence (two interactives
63
+ * co-occurring with no compound to arbitrate them). `hover&pressed` pairs are
64
+ * never generated (they can't co-occur; see `coOccurringInteractiveSubsets`).
65
+ *
66
+ * `'rest'` is NOT included — callers prepend it (and decide whether to, e.g.
67
+ * `skipRestState`). `atomics` MUST already be sorted by `comparePriority`
68
+ * (weakest first) so the strongest atom emits last and wins on intra-rank
69
+ * source-order ties.
70
+ *
71
+ * Shared by `resolvePropertyStates` (the CSS-emission source of truth) and
72
+ * `resolveSlotByCascade`'s cascade-rank computation, so the emission order —
73
+ * and therefore the cascade tie-break it implies — stays identical across both.
74
+ * Change emission order here, not in either caller.
75
+ */
76
+ function* atomicAndCompoundStateKeys(atomics) {
77
+ for (const atom of atomics) yield atom;
78
+ const modifiers = atomics.filter(require_StateAxis.isModifierAtomic);
79
+ const interactives = atomics.filter(require_StateAxis.isInteractiveAtomic);
80
+ for (const subset of modifierSubsets(modifiers, 3)) {
81
+ if (subset.length >= 2) yield require_canonicalizeStateKey.canonicalizeStateKey(subset);
82
+ for (const interactive of interactives) yield require_canonicalizeStateKey.canonicalizeStateKey([...subset, interactive]);
83
+ }
84
+ const interactivePairs = [...coOccurringInteractiveSubsets(interactives)].filter((subset) => subset.length >= 2);
85
+ for (const interactiveSubset of interactivePairs) yield require_canonicalizeStateKey.canonicalizeStateKey(interactiveSubset);
86
+ for (const subset of modifierSubsets(modifiers, 3)) for (const interactiveSubset of interactivePairs) yield require_canonicalizeStateKey.canonicalizeStateKey([...subset, ...interactiveSubset]);
87
+ }
88
+ /**
89
+ * Returns all canonical state keys a property reacts to, in cascade order:
90
+ *
91
+ * rest → atomics (sorted by global `STATE_PRIORITY`, weakest first)
92
+ * → 2-atom compounds → 3-atom compounds → ...
93
+ *
94
+ * Cross-rank ordering (atom < 2-atom compound < 3-atom compound < ...) is
95
+ * enforced by CSS class-count specificity. Each atom selector contributes
96
+ * (0,1,0), so a 2-atom compound at (0,3,0) strictly beats a 1-atom rule at
97
+ * (0,2,0) — the cascade-cancellation feature is encoded in the selector
98
+ * itself rather than rule source order.
99
+ *
100
+ * Intra-rank ties (which atom wins among the priority-sorted set, or which
101
+ * 2-atom compound wins among siblings of the same size) fall through to
102
+ * source order at the same specificity. Emission order follows the global
103
+ * `STATE_PRIORITY` array — to change which atom wins between any two
104
+ * simultaneously-matching atoms, reorder that array.
105
+ *
106
+ * Resolution sources, in order of precedence:
107
+ *
108
+ * 1. The new system: `layer.atomicStates` declares the atoms this layer can
109
+ * compose; `property.excludeAtomics` opts the property out of selected
110
+ * atoms. Compounds are auto-generated from the resulting set via
111
+ * modifier × interactive expansion.
112
+ * 2. The legacy system: `property.pseudoStates` (no compound generation; the
113
+ * array is used verbatim). Used when `layer.atomicStates` is absent so
114
+ * unmigrated component configs continue to behave exactly as before.
115
+ *
116
+ * `'rest'` is always included unless the property has `skipRestState: true`.
117
+ */
118
+ function resolvePropertyStates(layer, property) {
119
+ const states = [];
120
+ if (!(property.skipRestState === true)) states.push("rest");
121
+ if (layer.atomicStates && layer.atomicStates.length > 0) {
122
+ const exclude = new Set(property.excludeAtomics ?? []);
123
+ const atomics = [...layer.atomicStates].filter((atom) => !exclude.has(atom)).sort(require_StateAxis.comparePriority);
124
+ for (const stateKey of atomicAndCompoundStateKeys(atomics)) states.push(stateKey);
125
+ return states;
126
+ }
127
+ if (property.pseudoStates) for (const s of property.pseudoStates) states.push(s);
128
+ return states;
129
+ }
130
+ //#endregion
131
+ exports.atomicAndCompoundStateKeys = atomicAndCompoundStateKeys;
132
+ exports.resolvePropertyStates = resolvePropertyStates;
@@ -0,0 +1,131 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { comparePriority, isInteractiveAtomic, isModifierAtomic } from "../types/StateAxis.js";
3
+ import { canonicalizeStateKey } from "./canonicalizeStateKey.js";
4
+ //#region ../tailwind-internal/dist/packages/automated-config/dist/utils/resolvePropertyStates.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind Internal v0.0.0-development */
6
+ /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
7
+ /**
8
+ * Yields every modifier subset of size 1..maxSize, preserving input order
9
+ * within each subset. Used by both the resolver and the docs-class
10
+ * enumeration so the depth they support stays in lock-step.
11
+ *
12
+ * Generic over the element type so callers passing `ModifierAtomic[]` get
13
+ * `Generator<readonly ModifierAtomic[]>` back — keeps the inferred type chain
14
+ * tight enough for downstream consumers to avoid widening to `string`.
15
+ */
16
+ function* modifierSubsets(modifiers, maxSize) {
17
+ const indices = [];
18
+ function* recurse(start) {
19
+ if (indices.length > 0) yield indices.map((i) => modifiers[i]);
20
+ if (indices.length === maxSize) return;
21
+ for (let i = start; i < modifiers.length; i++) {
22
+ indices.push(i);
23
+ yield* recurse(i + 1);
24
+ indices.pop();
25
+ }
26
+ }
27
+ yield* recurse(0);
28
+ }
29
+ /**
30
+ * Yields the interactive subsets that can be simultaneously active on one
31
+ * element, in `modifierSubsets` order. `hover` and `pressed` are mutually
32
+ * exclusive — the `hover` selector carries `:where(:not(:active …))`, so a
33
+ * `hover&pressed` rule could never match — so any subset containing BOTH is
34
+ * dropped. Every other subset is kept (notably `focus-within`/`focus-visible`
35
+ * CAN coexist with a pointer state: you can hover or press a focused element).
36
+ *
37
+ * `interactives` MUST already be sorted by `comparePriority`.
38
+ */
39
+ function* coOccurringInteractiveSubsets(interactives) {
40
+ for (const subset of modifierSubsets(interactives, interactives.length)) {
41
+ if (subset.includes("hover") && subset.includes("pressed")) continue;
42
+ yield subset;
43
+ }
44
+ }
45
+ /**
46
+ * Yields a property's atomic + compound state keys in cascade order from a
47
+ * priority-sorted atomic set:
48
+ *
49
+ * atoms (in the given order)
50
+ * → for each modifier subset: the pure-modifier compound (size ≥ 2) then each
51
+ * modifier-subset × SINGLE-interactive compound
52
+ * → each pure interactive-pair compound (size ≥ 2, co-occurring)
53
+ * → each modifier-subset × interactive-PAIR compound
54
+ *
55
+ * The interactive-pair compounds are APPENDED after the original keys so every
56
+ * pre-existing key keeps its rank — `resolveSlotByCascade`'s tie-break and
57
+ * Figma's published values for already-declared states are therefore unchanged;
58
+ * only genuinely new co-occurring combinations (e.g. `focus-within&hover`) gain
59
+ * a key. Each is a real declared state with its own rule, so a property whose
60
+ * `focus-within` and `hover` resolve to different values renders the
61
+ * per-property-correct blend at `(0, 1+atomCount, 0)` specificity in BOTH emit
62
+ * modes — closing the only exhaustive/selective divergence (two interactives
63
+ * co-occurring with no compound to arbitrate them). `hover&pressed` pairs are
64
+ * never generated (they can't co-occur; see `coOccurringInteractiveSubsets`).
65
+ *
66
+ * `'rest'` is NOT included — callers prepend it (and decide whether to, e.g.
67
+ * `skipRestState`). `atomics` MUST already be sorted by `comparePriority`
68
+ * (weakest first) so the strongest atom emits last and wins on intra-rank
69
+ * source-order ties.
70
+ *
71
+ * Shared by `resolvePropertyStates` (the CSS-emission source of truth) and
72
+ * `resolveSlotByCascade`'s cascade-rank computation, so the emission order —
73
+ * and therefore the cascade tie-break it implies — stays identical across both.
74
+ * Change emission order here, not in either caller.
75
+ */
76
+ function* atomicAndCompoundStateKeys(atomics) {
77
+ for (const atom of atomics) yield atom;
78
+ const modifiers = atomics.filter(isModifierAtomic);
79
+ const interactives = atomics.filter(isInteractiveAtomic);
80
+ for (const subset of modifierSubsets(modifiers, 3)) {
81
+ if (subset.length >= 2) yield canonicalizeStateKey(subset);
82
+ for (const interactive of interactives) yield canonicalizeStateKey([...subset, interactive]);
83
+ }
84
+ const interactivePairs = [...coOccurringInteractiveSubsets(interactives)].filter((subset) => subset.length >= 2);
85
+ for (const interactiveSubset of interactivePairs) yield canonicalizeStateKey(interactiveSubset);
86
+ for (const subset of modifierSubsets(modifiers, 3)) for (const interactiveSubset of interactivePairs) yield canonicalizeStateKey([...subset, ...interactiveSubset]);
87
+ }
88
+ /**
89
+ * Returns all canonical state keys a property reacts to, in cascade order:
90
+ *
91
+ * rest → atomics (sorted by global `STATE_PRIORITY`, weakest first)
92
+ * → 2-atom compounds → 3-atom compounds → ...
93
+ *
94
+ * Cross-rank ordering (atom < 2-atom compound < 3-atom compound < ...) is
95
+ * enforced by CSS class-count specificity. Each atom selector contributes
96
+ * (0,1,0), so a 2-atom compound at (0,3,0) strictly beats a 1-atom rule at
97
+ * (0,2,0) — the cascade-cancellation feature is encoded in the selector
98
+ * itself rather than rule source order.
99
+ *
100
+ * Intra-rank ties (which atom wins among the priority-sorted set, or which
101
+ * 2-atom compound wins among siblings of the same size) fall through to
102
+ * source order at the same specificity. Emission order follows the global
103
+ * `STATE_PRIORITY` array — to change which atom wins between any two
104
+ * simultaneously-matching atoms, reorder that array.
105
+ *
106
+ * Resolution sources, in order of precedence:
107
+ *
108
+ * 1. The new system: `layer.atomicStates` declares the atoms this layer can
109
+ * compose; `property.excludeAtomics` opts the property out of selected
110
+ * atoms. Compounds are auto-generated from the resulting set via
111
+ * modifier × interactive expansion.
112
+ * 2. The legacy system: `property.pseudoStates` (no compound generation; the
113
+ * array is used verbatim). Used when `layer.atomicStates` is absent so
114
+ * unmigrated component configs continue to behave exactly as before.
115
+ *
116
+ * `'rest'` is always included unless the property has `skipRestState: true`.
117
+ */
118
+ function resolvePropertyStates(layer, property) {
119
+ const states = [];
120
+ if (!(property.skipRestState === true)) states.push("rest");
121
+ if (layer.atomicStates && layer.atomicStates.length > 0) {
122
+ const exclude = new Set(property.excludeAtomics ?? []);
123
+ const atomics = [...layer.atomicStates].filter((atom) => !exclude.has(atom)).sort(comparePriority);
124
+ for (const stateKey of atomicAndCompoundStateKeys(atomics)) states.push(stateKey);
125
+ return states;
126
+ }
127
+ if (property.pseudoStates) for (const s of property.pseudoStates) states.push(s);
128
+ return states;
129
+ }
130
+ //#endregion
131
+ export { atomicAndCompoundStateKeys, resolvePropertyStates };
@@ -0,0 +1,95 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_StateAxis = require("../types/StateAxis.cjs");
3
+ const require_resolvePropertyStates = require("./resolvePropertyStates.cjs");
4
+ //#region ../tailwind-internal/dist/packages/automated-config/dist/utils/resolveSlotByCascade.js
5
+ /*! © 2026 Yahoo, Inc. UDS Tailwind Internal v0.0.0-development */
6
+ /*! © 2026 Yahoo, Inc. UDS Default Config v0.0.0-development */
7
+ /**
8
+ * Mirrors `resolvePropertyStates`'s emission order using only the atoms that
9
+ * appear in the property's actual state map, so consumers that need a cascade
10
+ * tie-break can compare these indices (later = stronger). The atom + compound
11
+ * ordering comes from the shared `atomicAndCompoundStateKeys` generator, which
12
+ * keeps this rank identical to the CSS the generator emits.
13
+ */
14
+ function computeCascadeOrder(propertyStates) {
15
+ const presentAtoms = /* @__PURE__ */ new Set();
16
+ for (const stateName of Object.keys(propertyStates)) {
17
+ if (stateName === "rest" || propertyStates[stateName] == null) continue;
18
+ for (const atom of stateName.split("&")) presentAtoms.add(atom);
19
+ }
20
+ const atomics = [...presentAtoms].filter(require_StateAxis.isAtomicState).sort(require_StateAxis.comparePriority);
21
+ const order = ["rest"];
22
+ for (const stateKey of require_resolvePropertyStates.atomicAndCompoundStateKeys(atomics)) order.push(stateKey);
23
+ return order;
24
+ }
25
+ /**
26
+ * Resolves a state slot following CSS-cascade semantics: a `rest` slot or a
27
+ * non-rest slot with `isEnabled === true` resolves to itself; an unflagged
28
+ * non-rest slot resolves to the most-specific enabled state whose atoms are a
29
+ * subset of the requested state's atoms. A present-but-disabled single MODIFIER
30
+ * atom is the exception: it participates at the `rest` value (never its own
31
+ * stored value), so a dropped higher-priority modifier (e.g. `invalid`, left
32
+ * flag-less because it equals `rest`) suppresses a lower-priority enabled atom
33
+ * inside a compound rather than letting it brighten through — an invalid field
34
+ * shouldn't get the hover color when `invalid` resets to `rest`. A disabled
35
+ * INTERACTIVE atom does NOT participate: it contributes no rule of its own, so
36
+ * an enabled lower-priority interactive survives (e.g. `focus-within` styling
37
+ * persists while `hover`/`pressed`, left at `rest`, is active). Disabled
38
+ * COMPOUNDS and absent atoms do not participate either.
39
+ *
40
+ * Same-size candidates are tie-broken by the cascade emission order from
41
+ * `resolvePropertyStates` — i.e. the rule that the browser would have applied
42
+ * last under equal specificity. The single rule is: later in emission order =
43
+ * stronger. At the 1-atom level that makes the higher-`STATE_PRIORITY` atom
44
+ * win, so modifiers (`invalid`, `readonly`) beat interactives (`hover`,
45
+ * `pressed`) because they sit later in `STATE_PRIORITY`. At the 2-atom level a
46
+ * pure-modifier compound from subset `[m1, m2]` beats any modifier+interactive
47
+ * compound built from an *earlier* single-modifier subset (e.g.
48
+ * `invalid&readonly` beats `invalid&hover`), since `modifierSubsets` emits the
49
+ * size-2 subset after the size-1 subsets that precede it; compounds from a
50
+ * *later* single-modifier subset (e.g. `readonly&hover`) still emit afterward
51
+ * and win. Falls back to `rest` when no enabled subset exists.
52
+ *
53
+ * Two consumers rely on this:
54
+ * - `generateDeclaration` (exhaustive emission for `atomicStates` layers) resolves
55
+ * the value for every declared state — including the many compounds the
56
+ * sparse stored config never persists — so each emitted rule carries the
57
+ * value the cascade would have produced, with no gap a nested foreign theme
58
+ * could fill.
59
+ * - The Figma plugin emits a single library variable value per (component,
60
+ * layer, property, state) matching that same CSS, so disabled slots don't
61
+ * show up as orphaned customizations in the Figma library.
62
+ */
63
+ function resolveSlotByCascade(stateName, propertyStates) {
64
+ const direct = propertyStates[stateName];
65
+ if (stateName === "rest") return direct;
66
+ if (direct?.isEnabled === true) return direct;
67
+ const cascadeOrder = computeCascadeOrder(propertyStates);
68
+ const rankOf = /* @__PURE__ */ new Map();
69
+ cascadeOrder.forEach((s, i) => rankOf.set(s, i));
70
+ const targetAtoms = new Set(stateName.split("&"));
71
+ let best = null;
72
+ const restSlot = propertyStates.rest;
73
+ for (const [candidateKey, slot] of Object.entries(propertyStates)) {
74
+ if (!slot) continue;
75
+ if (candidateKey === stateName) continue;
76
+ const atoms = candidateKey === "rest" ? [] : candidateKey.split("&");
77
+ if (!atoms.every((a) => targetAtoms.has(a))) continue;
78
+ const enabled = candidateKey === "rest" || slot.isEnabled === true;
79
+ let effectiveSlot;
80
+ if (enabled) effectiveSlot = slot;
81
+ else if (atoms.length === 1 && require_StateAxis.isModifierAtomic(atoms[0])) effectiveSlot = restSlot;
82
+ else continue;
83
+ if (!effectiveSlot) continue;
84
+ const rank = rankOf.get(candidateKey) ?? -1;
85
+ const size = atoms.length;
86
+ if (!best || size > best.size || size === best.size && rank > best.rank) best = {
87
+ rank,
88
+ size,
89
+ slot: effectiveSlot
90
+ };
91
+ }
92
+ return best?.slot ?? propertyStates.rest;
93
+ }
94
+ //#endregion
95
+ exports.resolveSlotByCascade = resolveSlotByCascade;