@yahoo/uds-v5-wip 1.13.0 → 1.15.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.
- package/dist/config/dist/createConfig.d.ts +70 -20
- package/dist/config/dist/createConfig.js +152 -73
- package/dist/config/dist/index.d.ts +2 -2
- package/dist/config/dist/index.js +2 -1
- package/dist/config/dist/preset-merge.js +12 -4
- package/dist/config/dist/propertyGroups.d.ts +11 -0
- package/dist/config/dist/propertyGroups.js +432 -0
- package/dist/config/dist/resolveTokenTypes.d.ts +1 -0
- package/dist/config/dist/resolveTokenTypes.js +149 -0
- package/dist/config/dist/types.d.ts +31 -64
- package/dist/config.d.ts +45 -3842
- package/dist/config.js +1 -2
- package/dist/foundational-presets/dist/boldVibrant.d.ts +44 -3839
- package/dist/foundational-presets/dist/brutalist.d.ts +44 -3839
- package/dist/foundational-presets/dist/candy.d.ts +44 -3839
- package/dist/foundational-presets/dist/cleanMinimalist.d.ts +44 -3839
- package/dist/foundational-presets/dist/corporate.d.ts +44 -3839
- package/dist/foundational-presets/dist/darkMoody.d.ts +44 -3839
- package/dist/foundational-presets/dist/defaultPreset.d.ts +44 -3839
- package/dist/foundational-presets/dist/defaultPreset.js +288 -614
- package/dist/foundational-presets/dist/forest.d.ts +44 -3839
- package/dist/foundational-presets/dist/highContrast.d.ts +44 -3839
- package/dist/foundational-presets/dist/lavender.d.ts +44 -3839
- package/dist/foundational-presets/dist/luxury.d.ts +44 -3839
- package/dist/foundational-presets/dist/monochrome.d.ts +44 -3839
- package/dist/foundational-presets/dist/motion.d.ts +2 -1
- package/dist/foundational-presets/dist/neonCyber.d.ts +44 -3839
- package/dist/foundational-presets/dist/newspaper.d.ts +44 -3839
- package/dist/foundational-presets/dist/ocean.d.ts +44 -3839
- package/dist/foundational-presets/dist/slate.d.ts +44 -3839
- package/dist/foundational-presets/dist/sunset.d.ts +44 -3839
- package/dist/foundational-presets/dist/terminal.d.ts +44 -3839
- package/dist/foundational-presets/dist/warmOrganic.d.ts +44 -3839
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/config/dist/resolvedMappings.d.ts +0 -22
- package/dist/config/dist/resolvedMappings.js +0 -43
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PropertyGroupId } from "./propertyGroups.js";
|
|
2
|
+
import { TokenType, VarsConfig } from "./types.js";
|
|
2
3
|
import { BaseModifierProp, ComponentsConfig, ConfigurableProp, MacroConfig, ModifierProp, MotionPreset, RemotionComponentDef, RemotionConfig, RemotionTransitionDef, StyleProp } from "@uds/types";
|
|
3
4
|
|
|
4
5
|
//#region ../config/dist/createConfig.d.ts
|
|
@@ -47,11 +48,23 @@ interface ArbitraryTokenGroup {
|
|
|
47
48
|
type AtomicTokenValue<M extends ModifierNameShape> = {
|
|
48
49
|
name: string;
|
|
49
50
|
value: string;
|
|
51
|
+
/**
|
|
52
|
+
* Resolved DTCG-aligned token type. Populated per-token only when the
|
|
53
|
+
* token overrides the group-level `type` (e.g. a `'string'`-typed
|
|
54
|
+
* `transparent` sitting inside a `'color'` namespace).
|
|
55
|
+
*/
|
|
56
|
+
type?: TokenType;
|
|
50
57
|
modifiers?: Partial<Record<M, string>>;
|
|
51
58
|
};
|
|
52
59
|
interface AtomicToken<M extends ModifierNameShape = ModifierNameShape> {
|
|
53
60
|
properties: ConfigurableProp[];
|
|
54
61
|
tokens: AtomicTokenValue<M>[];
|
|
62
|
+
/**
|
|
63
|
+
* Resolved DTCG-aligned token type for the whole group. Set from
|
|
64
|
+
* `$type` on `defineVars`, or inferred from `defineScopes` / value sniff
|
|
65
|
+
* during config resolution.
|
|
66
|
+
*/
|
|
67
|
+
type?: TokenType;
|
|
55
68
|
/**
|
|
56
69
|
* Optional CSS variable prefix override
|
|
57
70
|
*
|
|
@@ -76,29 +89,19 @@ interface AtomicToken<M extends ModifierNameShape = ModifierNameShape> {
|
|
|
76
89
|
/** Merge two token structures */
|
|
77
90
|
type MergeTokens<A, B> = { [K in keyof A | keyof B]: K extends keyof B ? K extends keyof A ? A[K] & B[K] : B[K] : K extends keyof A ? A[K] : never };
|
|
78
91
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends ((x: infer I) => void) ? I : never;
|
|
85
|
-
/**
|
|
86
|
-
* Derive the token map shape (`{ propName: { tokenName: string } }`) that
|
|
87
|
-
* `defineUtilities` adds to `TTokens`, based on the accumulated `TVars` and the
|
|
88
|
-
* concrete utilities config type.
|
|
89
|
-
*
|
|
90
|
-
* Only `values: '{namespace}'` references produce typed tokens; literal-values
|
|
91
|
-
* and boolean utilities fall through to `Record<string, string>`.
|
|
92
|
+
* Derive token types directly from defineVars namespaces.
|
|
93
|
+
* Each var namespace key becomes a token property with the namespace's token names.
|
|
94
|
+
* An index signature allows property-name access (e.g., `tokens.borderRadius`)
|
|
95
|
+
* in addition to var-namespace access (e.g., `tokens.radius`).
|
|
96
|
+
* Used by `defineScopes` to populate tokens without an explicit utility mapping.
|
|
92
97
|
*/
|
|
93
|
-
type
|
|
94
|
-
values: infer V;
|
|
95
|
-
} ? V extends string ? ExtractNsTokens<TVars, V> : V extends readonly string[] ? UnionToIntersection<ExtractNsTokens<TVars, V[number]>> : Record<string, string> : Record<string, string> };
|
|
98
|
+
type VarsToTokens<TVars extends VarsConfig> = { [K in keyof TVars]: { [T in Exclude<keyof TVars[K], '$type'>]: string } } & Record<string, Record<string, string>>;
|
|
96
99
|
/** Empty tokens type for initial state */
|
|
97
100
|
type EmptyTokens = {};
|
|
98
101
|
/** Empty vars type for initial state */
|
|
99
102
|
type EmptyVars = {};
|
|
100
103
|
/** Build a structured token reference object from atomic tokens */
|
|
101
|
-
declare function buildTokenReference(atomic: AtomicToken<ModifierNameShape>[], configPrefix: string): Record<
|
|
104
|
+
declare function buildTokenReference(atomic: AtomicToken<ModifierNameShape>[], configPrefix: string): Record<string, Record<string, string>>;
|
|
102
105
|
/** Build a structured macro reference object for use in defineModifiers context */
|
|
103
106
|
/** Extract all modifiers from mode groups and check if any are reserved */
|
|
104
107
|
type CheckForReservedModifiers<T extends readonly ModeGroup[]> = true extends HasReservedModifier<GetModifierName<T>> ? 'ERROR: Cannot use reserved modifier names from ModifierProp. Please use a different modifier name.' : T;
|
|
@@ -136,7 +139,18 @@ interface UdsConfigData {
|
|
|
136
139
|
examples?: Record<string, ExampleDef>;
|
|
137
140
|
designPrinciples?: string[];
|
|
138
141
|
vars?: VarsConfig;
|
|
139
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Map each ConfigurableProp to its generated CSS class prefix.
|
|
144
|
+
* Set via `defineClassNames()`. Falls back to kebab-case of the property name.
|
|
145
|
+
*/
|
|
146
|
+
classNames?: Record<string, string>;
|
|
147
|
+
/**
|
|
148
|
+
* Map each var namespace to the property group IDs it feeds.
|
|
149
|
+
* Set via `defineScopes()`. This is the canonical source for
|
|
150
|
+
* "which tokens can this property use" — the Studio UI reads and
|
|
151
|
+
* edits this via draft patches.
|
|
152
|
+
*/
|
|
153
|
+
scopes?: Record<string, string[]>;
|
|
140
154
|
}
|
|
141
155
|
interface ComponentConfig<TComponents extends ComponentsConfig<string> = ComponentsConfig<string>, TMotion extends MotionPresetsDef | undefined = MotionPresetsDef | undefined> {
|
|
142
156
|
name?: string;
|
|
@@ -205,7 +219,43 @@ interface UdsConfig<TModifier extends ModifierNameShape = ModifierProp, TTokens
|
|
|
205
219
|
tokens: TTokens;
|
|
206
220
|
}) => Record<string, RemotionTransitionDef>)): ConfigResult<TModifier, TTokens, TMotion, TExt, TMacros, TModeModifiers, TVars>;
|
|
207
221
|
defineVars<const TVarsNew extends VarsConfig<[TModeModifiers] extends [never] ? `_${string}` : TModeModifiers>>(vars: TVarsNew): ConfigResult<TModifier, TTokens, TMotion, TExt, TMacros, TModeModifiers, TVars & TVarsNew>;
|
|
208
|
-
|
|
222
|
+
/**
|
|
223
|
+
* Map each ConfigurableProp to a CSS class prefix.
|
|
224
|
+
* Falls back to kebab-case of the property name when not specified.
|
|
225
|
+
* Typically called once by the foundational preset — consumers rarely touch this.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```ts
|
|
229
|
+
* uds.defineClassNames({
|
|
230
|
+
* color: 'text',
|
|
231
|
+
* bg: 'bg',
|
|
232
|
+
* borderColor: 'border-color',
|
|
233
|
+
* spacing: 'p',
|
|
234
|
+
* gap: 'gap',
|
|
235
|
+
* borderRadius: 'rounded',
|
|
236
|
+
* })
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
defineClassNames(classNames: { [K in StyleProp]?: string }): ConfigResult<TModifier, TTokens, TMotion, TExt, TMacros, TModeModifiers, TVars>;
|
|
240
|
+
/**
|
|
241
|
+
* Map var namespaces to property groups, defining which tokens each property
|
|
242
|
+
* group can reference. This is the canonical scope definition — the Studio UI
|
|
243
|
+
* renders it as checkboxes per token group.
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```ts
|
|
247
|
+
* uds
|
|
248
|
+
* .defineVars({
|
|
249
|
+
* color: { brand: { value: '#1167f4' } },
|
|
250
|
+
* spacing: { sm: { value: '4px' } },
|
|
251
|
+
* })
|
|
252
|
+
* .defineScopes({
|
|
253
|
+
* color: ['textColor', 'background', 'borderColor', 'ringColor'],
|
|
254
|
+
* spacing: ['padding', 'gap', 'margin'],
|
|
255
|
+
* })
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
defineScopes(scopes: [keyof TVars] extends [never] ? Record<string, PropertyGroupId[]> : { [K in keyof TVars]?: PropertyGroupId[] }): ConfigResult<TModifier, MergeTokens<TTokens, VarsToTokens<TVars>>, TMotion, TExt, TMacros, TModeModifiers, TVars>;
|
|
209
259
|
}
|
|
210
260
|
type AnyUdsConfig = UdsConfig<ModifierNameShape, any, any, any, any, any, any>;
|
|
211
261
|
/** Extract the raw config data from a builder instance */
|
|
@@ -4,19 +4,29 @@ import "../../utils/dist/index.js";
|
|
|
4
4
|
import { getConfigurablePropMapping } from "../../core/dist/propMappings.js";
|
|
5
5
|
import "../../core/dist/index.js";
|
|
6
6
|
import { buildMotionReference, resolveComponentMotionAliases, validateComponentVariants } from "./component-resolution.js";
|
|
7
|
+
import { expandPropertyGroups } from "./propertyGroups.js";
|
|
8
|
+
import { resolveTokenType, sniffTokenTypeFromValue } from "./resolveTokenTypes.js";
|
|
7
9
|
import { applyPresetToData, deepMerge, mergeAtomic } from "./preset-merge.js";
|
|
8
10
|
//#region ../config/dist/createConfig.js
|
|
9
11
|
/** biome-ignore-all lint/suspicious/noExplicitAny: necessary for dynamic builder to work correctly */
|
|
10
12
|
/** Build a structured token reference object from atomic tokens */
|
|
11
13
|
function buildTokenReference(atomic, configPrefix) {
|
|
12
14
|
const result = Object.create(null);
|
|
13
|
-
for (const token of atomic)
|
|
14
|
-
|
|
15
|
+
for (const token of atomic) {
|
|
16
|
+
const varPrefix = token.cssPrefix ?? getConfigurablePropMapping(token.properties[0])?.defaultVarPrefix;
|
|
17
|
+
const tokenEntries = Object.create(null);
|
|
15
18
|
for (const t of token.tokens) {
|
|
16
|
-
const varPrefix = token.cssPrefix ?? getConfigurablePropMapping(prop)?.defaultVarPrefix;
|
|
17
19
|
const safeName = safeTokenName(t.name);
|
|
18
20
|
const cssVarName = configPrefix ? `--${configPrefix}-${varPrefix}-${safeName}` : `--${varPrefix}-${safeName}`;
|
|
19
|
-
|
|
21
|
+
tokenEntries[t.name] = `var(${cssVarName})`;
|
|
22
|
+
}
|
|
23
|
+
for (const prop of token.properties) {
|
|
24
|
+
if (!result[prop]) result[prop] = Object.create(null);
|
|
25
|
+
Object.assign(result[prop], tokenEntries);
|
|
26
|
+
}
|
|
27
|
+
if (varPrefix) {
|
|
28
|
+
if (!result[varPrefix]) result[varPrefix] = Object.create(null);
|
|
29
|
+
Object.assign(result[varPrefix], tokenEntries);
|
|
20
30
|
}
|
|
21
31
|
}
|
|
22
32
|
return result;
|
|
@@ -31,84 +41,142 @@ function buildMacroReference(macros) {
|
|
|
31
41
|
return result;
|
|
32
42
|
}
|
|
33
43
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
44
|
+
* Convert a VarGroupDef into AtomicToken tokens, extracting modifier overrides.
|
|
45
|
+
*
|
|
46
|
+
* Also extracts `$type` metadata:
|
|
47
|
+
* - A top-level `$type` on the group → `groupType`
|
|
48
|
+
* - A `$type` on an individual token → `type` on that token (overrides group)
|
|
49
|
+
*
|
|
50
|
+
* `$type` is filtered out of the emitted tokens; it is metadata only.
|
|
36
51
|
*/
|
|
37
|
-
function parseVarsReference(ref) {
|
|
38
|
-
return ref.match(/^\{(.+)\}$/)?.[1];
|
|
39
|
-
}
|
|
40
|
-
/** Normalize values to an array of string refs, filtering out non-string forms. */
|
|
41
|
-
function normalizeValuesRefs(values) {
|
|
42
|
-
if (!values) return [];
|
|
43
|
-
if (typeof values === "string") return [values];
|
|
44
|
-
if (Array.isArray(values)) return values;
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
/** Convert a VarGroupDef into AtomicToken tokens, extracting modifier overrides. */
|
|
48
52
|
function varGroupToTokens(varGroup, knownModifiers) {
|
|
53
|
+
let groupType;
|
|
49
54
|
const tokens = [];
|
|
50
|
-
for (const [tokenName,
|
|
55
|
+
for (const [tokenName, rawDef] of Object.entries(varGroup)) {
|
|
56
|
+
if (tokenName === "$type") {
|
|
57
|
+
if (typeof rawDef === "string") groupType = rawDef;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (rawDef == null || typeof rawDef !== "object") continue;
|
|
61
|
+
const tokenDef = rawDef;
|
|
51
62
|
const modifiers = {};
|
|
52
63
|
for (const [key, val] of Object.entries(tokenDef)) {
|
|
53
|
-
if (key === "value" || val === void 0) continue;
|
|
64
|
+
if (key === "value" || key === "$type" || val === void 0) continue;
|
|
54
65
|
if (key.startsWith("_") && knownModifiers.has(key)) modifiers[key] = val;
|
|
55
66
|
}
|
|
56
67
|
tokens.push({
|
|
57
68
|
name: tokenName,
|
|
58
69
|
value: tokenDef.value,
|
|
70
|
+
...tokenDef.$type ? { type: tokenDef.$type } : {},
|
|
59
71
|
...Object.keys(modifiers).length > 0 ? { modifiers } : {}
|
|
60
72
|
});
|
|
61
73
|
}
|
|
62
|
-
return
|
|
74
|
+
return {
|
|
75
|
+
tokens,
|
|
76
|
+
groupType
|
|
77
|
+
};
|
|
63
78
|
}
|
|
64
79
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
* Sort properties so the one matching the cssPrefix comes last.
|
|
81
|
+
* `buildVarToTokenMap` uses "last wins", so this ensures e.g. `color.brand`
|
|
82
|
+
* beats `shadowColor.brand` when both reference `var(--uds-color-brand)`.
|
|
83
|
+
*/
|
|
84
|
+
function sortPropertiesByPrefixMatch(properties, namespace, cssPfx) {
|
|
85
|
+
return properties.slice().sort((a, b) => {
|
|
86
|
+
return (a === namespace || kebabCase(a) === cssPfx ? 1 : 0) - (b === namespace || kebabCase(b) === cssPfx ? 1 : 0);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Synthesize AtomicToken[] from defineScopes + defineVars data.
|
|
71
91
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
92
|
+
* For each namespace in `scopes`, expands property group IDs into
|
|
93
|
+
* ConfigurableProps, extracts tokens from the matching var namespace,
|
|
94
|
+
* and produces an AtomicToken group.
|
|
75
95
|
*/
|
|
76
|
-
function
|
|
96
|
+
function synthesizeAtomicFromScopesAndVars(vars, scopes, modes) {
|
|
77
97
|
const knownModifiers = /* @__PURE__ */ new Set();
|
|
78
98
|
for (const mode of modes) for (const option of mode.options) knownModifiers.add(option.modifier);
|
|
79
|
-
const pairs = /* @__PURE__ */ new Map();
|
|
80
|
-
for (const [propName, utilDef] of Object.entries(utilities)) {
|
|
81
|
-
if (!utilDef) continue;
|
|
82
|
-
const refs = normalizeValuesRefs(utilDef.values);
|
|
83
|
-
for (const ref of refs) {
|
|
84
|
-
const namespace = parseVarsReference(ref);
|
|
85
|
-
if (!namespace || !vars[namespace]) continue;
|
|
86
|
-
const key = `${namespace}|${propName}`;
|
|
87
|
-
pairs.set(key, {
|
|
88
|
-
namespace,
|
|
89
|
-
property: propName
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
const namespaceGroups = /* @__PURE__ */ new Map();
|
|
94
|
-
for (const { namespace, property } of pairs.values()) {
|
|
95
|
-
const props = namespaceGroups.get(namespace) ?? /* @__PURE__ */ new Set();
|
|
96
|
-
props.add(property);
|
|
97
|
-
namespaceGroups.set(namespace, props);
|
|
98
|
-
}
|
|
99
99
|
const result = [];
|
|
100
|
-
for (const [namespace,
|
|
100
|
+
for (const [namespace, groupIds] of Object.entries(scopes)) {
|
|
101
101
|
const varGroup = vars[namespace];
|
|
102
102
|
if (!varGroup) continue;
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
103
|
+
const properties = expandPropertyGroups(groupIds);
|
|
104
|
+
if (properties.length === 0) continue;
|
|
105
|
+
const { tokens, groupType } = varGroupToTokens(varGroup, knownModifiers);
|
|
106
|
+
const cssPfx = (properties.includes(namespace) ? getConfigurablePropMapping(namespace) : void 0)?.defaultVarPrefix ?? kebabCase(namespace);
|
|
107
|
+
const sorted = sortPropertiesByPrefixMatch(properties, namespace, cssPfx);
|
|
108
|
+
const resolvedGroupType = resolveTokenType({
|
|
109
|
+
explicit: groupType,
|
|
110
|
+
scopes: groupIds
|
|
107
111
|
});
|
|
112
|
+
if (resolvedGroupType && resolvedGroupType !== "string") for (const token of tokens) {
|
|
113
|
+
if (token.type) continue;
|
|
114
|
+
if (sniffTokenTypeFromValue(token.value) === "string") token.type = "string";
|
|
115
|
+
}
|
|
108
116
|
result.push({
|
|
109
|
-
properties,
|
|
117
|
+
properties: sorted,
|
|
110
118
|
tokens,
|
|
111
|
-
cssPrefix: cssPfx
|
|
119
|
+
cssPrefix: cssPfx,
|
|
120
|
+
...resolvedGroupType ? { type: resolvedGroupType } : {}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return disambiguateOverlappingProperties(result, scopes);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* When multiple scope namespaces reference the **same** property group
|
|
127
|
+
* (e.g. `rotate`, `scale`, `skew`, `translate` all mapping to `['transform']`),
|
|
128
|
+
* each namespace's AtomicToken gets ALL properties from that group, causing
|
|
129
|
+
* last-write-wins collisions in CSS generation.
|
|
130
|
+
*
|
|
131
|
+
* This function partitions those shared-group properties among namespaces
|
|
132
|
+
* using longest camelCase prefix matching. Cross-group overlaps (e.g.
|
|
133
|
+
* `color` and `bg` both including the `bg` property via different groups)
|
|
134
|
+
* are intentional cascading and left untouched.
|
|
135
|
+
*/
|
|
136
|
+
function disambiguateOverlappingProperties(tokens, scopes) {
|
|
137
|
+
const groupToNamespaces = /* @__PURE__ */ new Map();
|
|
138
|
+
for (const [ns, groupIds] of Object.entries(scopes)) for (const gid of groupIds) {
|
|
139
|
+
const list = groupToNamespaces.get(gid) ?? [];
|
|
140
|
+
list.push(ns);
|
|
141
|
+
groupToNamespaces.set(gid, list);
|
|
142
|
+
}
|
|
143
|
+
const contestedGroups = /* @__PURE__ */ new Map();
|
|
144
|
+
for (const [gid, nsList] of groupToNamespaces) if (nsList.length > 1) contestedGroups.set(gid, nsList);
|
|
145
|
+
if (contestedGroups.size === 0) return tokens;
|
|
146
|
+
const propOwner = /* @__PURE__ */ new Map();
|
|
147
|
+
for (const [gid, nsList] of contestedGroups) {
|
|
148
|
+
const groupProps = expandPropertyGroups([gid]);
|
|
149
|
+
const assignments = /* @__PURE__ */ new Map();
|
|
150
|
+
const nsWithMatch = /* @__PURE__ */ new Set();
|
|
151
|
+
for (const prop of groupProps) {
|
|
152
|
+
let bestNs = "";
|
|
153
|
+
let bestLen = 0;
|
|
154
|
+
for (const ns of nsList) if (prop === ns || prop.startsWith(ns) && prop.length > ns.length) {
|
|
155
|
+
if (ns.length > bestLen) {
|
|
156
|
+
bestNs = ns;
|
|
157
|
+
bestLen = ns.length;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (bestNs) {
|
|
161
|
+
assignments.set(prop, bestNs);
|
|
162
|
+
nsWithMatch.add(bestNs);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (nsWithMatch.size < 2) continue;
|
|
166
|
+
for (const [prop, ns] of assignments) propOwner.set(prop, ns);
|
|
167
|
+
}
|
|
168
|
+
if (propOwner.size === 0) return tokens;
|
|
169
|
+
const namespaces = Object.keys(scopes);
|
|
170
|
+
const result = [];
|
|
171
|
+
for (const token of tokens) {
|
|
172
|
+
const ns = namespaces.find((n) => token.cssPrefix === kebabCase(n)) ?? "";
|
|
173
|
+
const filtered = token.properties.filter((prop) => {
|
|
174
|
+
const owner = propOwner.get(prop);
|
|
175
|
+
return !owner || owner === ns;
|
|
176
|
+
});
|
|
177
|
+
if (filtered.length > 0) result.push({
|
|
178
|
+
...token,
|
|
179
|
+
properties: filtered
|
|
112
180
|
});
|
|
113
181
|
}
|
|
114
182
|
return result;
|
|
@@ -133,13 +201,15 @@ function resolveConfig(config) {
|
|
|
133
201
|
examples: config.examples,
|
|
134
202
|
designPrinciples: config.designPrinciples,
|
|
135
203
|
vars: config.vars,
|
|
136
|
-
|
|
204
|
+
classNames: config.classNames,
|
|
205
|
+
scopes: config.scopes
|
|
137
206
|
};
|
|
138
|
-
if (configData.vars && configData.
|
|
139
|
-
const synthesized =
|
|
207
|
+
if (configData.vars && configData.scopes) {
|
|
208
|
+
const synthesized = synthesizeAtomicFromScopesAndVars(configData.vars, configData.scopes, configData.modes);
|
|
209
|
+
const atomic = mergeAtomic(configData.atomic, synthesized, "merge");
|
|
140
210
|
configData = {
|
|
141
211
|
...configData,
|
|
142
|
-
atomic
|
|
212
|
+
atomic
|
|
143
213
|
};
|
|
144
214
|
}
|
|
145
215
|
return configData;
|
|
@@ -192,7 +262,8 @@ function resolvePresetData(input) {
|
|
|
192
262
|
examples: input.examples,
|
|
193
263
|
designPrinciples: input.designPrinciples,
|
|
194
264
|
vars: input.vars,
|
|
195
|
-
|
|
265
|
+
classNames: input.classNames,
|
|
266
|
+
scopes: input.scopes
|
|
196
267
|
};
|
|
197
268
|
}
|
|
198
269
|
function extractVarReferences(value) {
|
|
@@ -230,7 +301,10 @@ function collectRequiredTokens(sourceData, components, motion) {
|
|
|
230
301
|
}
|
|
231
302
|
function availableTokenNames(data) {
|
|
232
303
|
const names = /* @__PURE__ */ new Set();
|
|
233
|
-
for (const group of data.atomic) for (const
|
|
304
|
+
for (const group of data.atomic) for (const token of group.tokens) {
|
|
305
|
+
for (const prop of group.properties) names.add(`${prop}.${token.name}`);
|
|
306
|
+
if (group.cssPrefix) names.add(`${group.cssPrefix}.${token.name}`);
|
|
307
|
+
}
|
|
234
308
|
return names;
|
|
235
309
|
}
|
|
236
310
|
function validatePresetRequiredTokens(base, preset) {
|
|
@@ -434,8 +508,7 @@ function createConfigBuilder(data, extensions) {
|
|
|
434
508
|
arbitraryTokens: input.arbitraryTokens ?? data.arbitraryTokens,
|
|
435
509
|
examples: input.examples ?? data.examples,
|
|
436
510
|
designPrinciples: input.designPrinciples ?? data.designPrinciples,
|
|
437
|
-
vars: input.vars ?? data.vars
|
|
438
|
-
utilities: input.utilities ?? data.utilities
|
|
511
|
+
vars: input.vars ?? data.vars
|
|
439
512
|
}, extensions);
|
|
440
513
|
},
|
|
441
514
|
extend(ext) {
|
|
@@ -515,8 +588,8 @@ function createConfigBuilder(data, extensions) {
|
|
|
515
588
|
...group
|
|
516
589
|
};
|
|
517
590
|
const updates = { vars: merged };
|
|
518
|
-
if (data.
|
|
519
|
-
const synthesized =
|
|
591
|
+
if (data.scopes && Object.keys(data.scopes).length > 0) {
|
|
592
|
+
const synthesized = synthesizeAtomicFromScopesAndVars(merged, data.scopes, data.modes ?? []);
|
|
520
593
|
updates.atomic = mergeAtomic(data.atomic, synthesized, "merge");
|
|
521
594
|
}
|
|
522
595
|
return createConfigBuilder({
|
|
@@ -524,14 +597,20 @@ function createConfigBuilder(data, extensions) {
|
|
|
524
597
|
...updates
|
|
525
598
|
}, extensions);
|
|
526
599
|
},
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
...data.
|
|
530
|
-
...
|
|
600
|
+
defineClassNames(classNames) {
|
|
601
|
+
return next({ classNames: {
|
|
602
|
+
...data.classNames,
|
|
603
|
+
...classNames
|
|
604
|
+
} });
|
|
605
|
+
},
|
|
606
|
+
defineScopes(scopes) {
|
|
607
|
+
const mergedScopes = {
|
|
608
|
+
...data.scopes,
|
|
609
|
+
...scopes
|
|
531
610
|
};
|
|
532
|
-
const updates = {
|
|
611
|
+
const updates = { scopes: mergedScopes };
|
|
533
612
|
if (data.vars && Object.keys(data.vars).length > 0) {
|
|
534
|
-
const synthesized =
|
|
613
|
+
const synthesized = synthesizeAtomicFromScopesAndVars(data.vars, mergedScopes, data.modes ?? []);
|
|
535
614
|
updates.atomic = mergeAtomic(data.atomic ?? [], synthesized, "merge");
|
|
536
615
|
}
|
|
537
616
|
return createConfigBuilder({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defaultColors } from "./consts/defaultColors.js";
|
|
2
|
-
import {
|
|
2
|
+
import { PropertyGroupId } from "./propertyGroups.js";
|
|
3
|
+
import { TokenType, VarGroupDef, VarTokenDef, VarsConfig } from "./types.js";
|
|
3
4
|
import { ArbitraryTokenGroup, AtomicToken, BuildOptions, ComponentConfig, DefineComponentInput, DefineComponentMotionInput, ExampleDef, ExampleEntryDef, ExampleLayoutStyles, GlobalStylesDef, InterpolateMarker, ModeGroup, ModifierDef, MotionPresetsDef, UdsConfig, UdsConfigData, buildTokenReference, createConfigBuilder, darker, lighter, resolveConfig } from "./createConfig.js";
|
|
4
|
-
import { ResolvedUtilityMapping, resolveUtilityMappings } from "./resolvedMappings.js";
|
|
5
5
|
import { SerializedConfig, TokenRef, buildReverseMap, deserializeConfig, serializeConfig } from "./serialize.js";
|
|
6
6
|
import { ComponentsConfig as ComponentsConfig$1 } from "@uds/types";
|
|
7
7
|
export { type ComponentsConfig$1 as ComponentsConfig };
|
|
@@ -14,6 +14,7 @@ function flattenAtomic(atomic) {
|
|
|
14
14
|
for (const group of atomic) for (const property of group.properties) for (const token of group.tokens) entries.push({
|
|
15
15
|
property,
|
|
16
16
|
cssPrefix: group.cssPrefix,
|
|
17
|
+
groupType: group.type,
|
|
17
18
|
token
|
|
18
19
|
});
|
|
19
20
|
return entries;
|
|
@@ -39,11 +40,13 @@ function mergeAtomic(base, incoming, mode) {
|
|
|
39
40
|
const existing = regrouped.get(groupKey);
|
|
40
41
|
if (existing) {
|
|
41
42
|
existing.tokens.push(entry.token);
|
|
43
|
+
if (entry.groupType) existing.type = entry.groupType;
|
|
42
44
|
continue;
|
|
43
45
|
}
|
|
44
46
|
regrouped.set(groupKey, {
|
|
45
47
|
properties: [entry.property],
|
|
46
48
|
...entry.cssPrefix ? { cssPrefix: entry.cssPrefix } : {},
|
|
49
|
+
...entry.groupType ? { type: entry.groupType } : {},
|
|
47
50
|
tokens: [entry.token]
|
|
48
51
|
});
|
|
49
52
|
}
|
|
@@ -142,9 +145,13 @@ function applyPresetToData(base, preset, strategy) {
|
|
|
142
145
|
const mergedPrinciples = base.designPrinciples || preset.designPrinciples ? [...base.designPrinciples ?? [], ...preset.designPrinciples ?? []] : void 0;
|
|
143
146
|
const mergedArbitraryTokens = base.arbitraryTokens || preset.arbitraryTokens ? [...base.arbitraryTokens ?? [], ...preset.arbitraryTokens ?? []] : void 0;
|
|
144
147
|
const mergedVars = base.vars || preset.vars ? mergeRecordByKey(base.vars ?? {}, preset.vars ?? {}, "merge") : void 0;
|
|
145
|
-
const
|
|
146
|
-
...base.
|
|
147
|
-
...preset.
|
|
148
|
+
const mergedClassNames = base.classNames || preset.classNames ? {
|
|
149
|
+
...base.classNames,
|
|
150
|
+
...preset.classNames
|
|
151
|
+
} : void 0;
|
|
152
|
+
const mergedScopes = base.scopes || preset.scopes ? {
|
|
153
|
+
...base.scopes,
|
|
154
|
+
...preset.scopes
|
|
148
155
|
} : void 0;
|
|
149
156
|
const merged = {
|
|
150
157
|
...base,
|
|
@@ -163,7 +170,8 @@ function applyPresetToData(base, preset, strategy) {
|
|
|
163
170
|
examples: mergedExamples,
|
|
164
171
|
designPrinciples: mergedPrinciples,
|
|
165
172
|
vars: mergedVars,
|
|
166
|
-
|
|
173
|
+
classNames: mergedClassNames,
|
|
174
|
+
scopes: mergedScopes
|
|
167
175
|
};
|
|
168
176
|
validateComponentVariants(merged.components);
|
|
169
177
|
return merged;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ConfigurableProp } from "@uds/types";
|
|
2
|
+
|
|
3
|
+
//#region ../config/dist/propertyGroups.d.ts
|
|
4
|
+
//#region src/propertyGroups.d.ts
|
|
5
|
+
type PropertyGroupId = 'textColor' | 'background' | 'borderColor' | 'outlineColor' | 'ringColor' | 'divideColor' | 'shadowColor' | 'svgFill' | 'svgStroke' | 'caretColor' | 'textDecorationColor' | 'opacity' | 'colorOpacity' | 'bgOpacity' | 'borderColorOpacity' | 'divideColorOpacity' | 'outlineColorOpacity' | 'ringColorOpacity' | 'textDecorationColorOpacity' | 'svgFillOpacity' | 'svgStrokeOpacity' | 'shadowColorOpacity' | 'caretColorOpacity' | 'fontFamily' | 'fontSize' | 'fontWeight' | 'lineHeight' | 'letterSpacing' | 'blur' | 'backdropBlur' | 'animation' | 'shadow' | 'textShadow' | 'zIndex' | 'borderWidth' | 'borderRadius' | 'outlineWidth' | 'divideWidth' | 'ringWidth' | 'padding' | 'margin' | 'offset' | 'gap' | 'indent' | 'scrollSnapGap' | 'scrollSnapSpacing' | 'tableBorderSpacing' | 'width' | 'height' | 'aspectRatio' | 'positionPlacement' | 'flex' | 'transform' | 'strokeWidth';
|
|
6
|
+
/**
|
|
7
|
+
* A logical grouping of ConfigurableProps with a human-readable label.
|
|
8
|
+
* Used by the Studio UI to let users scope token groups to specific properties.
|
|
9
|
+
*/
|
|
10
|
+
//#endregion
|
|
11
|
+
export { PropertyGroupId };
|