@styleframe/core 3.0.0 → 3.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @styleframe/core
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#129](https://github.com/styleframe-dev/styleframe/pull/129) [`2610041`](https://github.com/styleframe-dev/styleframe/commit/2610041beb03a8afc8de17af8857b9931f3359b0) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add custom utility syntax support and separate class name generation from CSS escaping
8
+ - Extract `defaultUtilitySelectorFn` to `@styleframe/core` returning raw class names; add `classNameToCssSelector` for consistent CSS escaping
9
+ - Add `ScannerUtilitiesConfig` with pluggable `pattern`, `parse`, and `selector` functions for custom utility naming conventions
10
+ - Thread custom utilities config through extractor, matcher, scanner, and plugin layers
11
+
12
+ - [#133](https://github.com/styleframe-dev/styleframe/pull/133) [`ce62d31`](https://github.com/styleframe-dev/styleframe/commit/ce62d318275deed277d828fdd8d2500c1a9d767f) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add unique id and parent-child traversal to token types, validate @ references, and resolve utility sibling keys
13
+ - Add unique `id` field to Root, Selector, AtRule, Theme, Utility, Modifier, and Variable token types for stable identity tracking
14
+ - Add `parentId` to track parent-child relationships across the token tree
15
+ - Add `root._registry` for efficient id-based lookups and tree traversal
16
+ - Validate `@`-prefixed string references against root-level variables in `parseDeclarationsBlock`, throwing descriptive errors for undefined variables
17
+ - Add null/undefined guard to `ref()` with clear error messages
18
+ - Support `@`-prefixed values in utility entries that resolve to sibling keys (e.g., `{ default: "@solid", solid: "solid" }`)
19
+
20
+ ### Patch Changes
21
+
22
+ - [#141](https://github.com/styleframe-dev/styleframe/pull/141) [`295f04e`](https://github.com/styleframe-dev/styleframe/commit/295f04e6fdd011df6437986cc179e17efd8cd1be) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add `@variablename` notation support in `css` template literals
23
+ - `@variablename` strings in static parts of `css` template literals are automatically converted to variable references: `` css`1px solid @color.primary` `` resolves `@color.primary` to `ref("color.primary")`
24
+ - Supports dotted names (e.g., `@color.primary.500`) and multiple references per segment (e.g., `` css`@spacing.x @spacing.y` ``)
25
+
26
+ - [#128](https://github.com/styleframe-dev/styleframe/pull/128) [`71009c2`](https://github.com/styleframe-dev/styleframe/commit/71009c2c0a07a0bfd240e70e61020c8b7e923edb) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add auto-resolve for variables and at-rules in `css` template literal interpolations
27
+ - Variables interpolated directly in `css` are automatically converted to references: `` css`${variable}` `` is equivalent to `` css`${ref(variable)}` ``
28
+ - AtRule and keyframes instances interpolated in `css` resolve to their rule name: `` css`${keyframeInstance}` `` is equivalent to `` css`${keyframeInstance.rule}` ``
29
+
30
+ - [#140](https://github.com/styleframe-dev/styleframe/pull/140) [`7a61df0`](https://github.com/styleframe-dev/styleframe/commit/7a61df083bc534caa9271a1ef4535f7be979d7c2) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add `@variablename` reference support in `variable()` values, `ref()` fallbacks, and `selector()` declaration values
31
+ - `variable('name', '1px solid @color.primary')` resolves embedded `@` references to a CSS object with mixed text and reference parts
32
+ - `ref('name', '@fallbackvar')` resolves `@`-prefixed fallback values to nested references
33
+ - `selector({ border: "1px solid @color.primary" })` resolves embedded `@` references in declaration values
34
+ - Extract shared `resolvePropertyValue()` utility for consistent `@` reference resolution across all contexts
35
+
36
+ ## 3.0.1
37
+
38
+ ### Patch Changes
39
+
40
+ - [#120](https://github.com/styleframe-dev/styleframe/pull/120) [`fa48802`](https://github.com/styleframe-dev/styleframe/commit/fa488027d32956e20fa26dc92ee1a3b3583671ad) Thanks [@alexgrozav](https://github.com/alexgrozav)! - Add hash-based utility class names for arbitrary CSS values containing whitespace. Values like `transition: 'all 0.3s ease'` now produce valid CSS class names using a deterministic hash (e.g., `_transition:2f7a3b1`) instead of invalid bracket notation with spaces.
41
+
3
42
  ## 3.0.0
4
43
 
5
44
  ### Major Changes
@@ -4,6 +4,8 @@ export declare function applyModifiers<InstanceType extends Container>(baseInsta
4
4
 
5
5
  export declare type AtRule = {
6
6
  type: "at-rule";
7
+ id: string;
8
+ parentId?: string;
7
9
  identifier: string;
8
10
  rule: string;
9
11
  declarations: DeclarationsBlock;
@@ -18,6 +20,12 @@ export declare type CapitalizeFirst<T extends string> = T extends `${infer First
18
20
  */
19
21
  export declare function capitalizeFirst(str: string): string;
20
22
 
23
+ /**
24
+ * Convert a raw class name to a CSS selector by adding a `.` prefix
25
+ * and escaping special characters.
26
+ */
27
+ export declare function classNameToCssSelector(className: string): string;
28
+
21
29
  /**
22
30
  * Deep clone a value.
23
31
  *
@@ -38,6 +46,8 @@ ConstructorHandler<T>
38
46
  ];
39
47
 
40
48
  export declare type Container = {
49
+ id: string;
50
+ parentId?: string;
41
51
  children: ContainerChild[];
42
52
  variables: Variable[];
43
53
  declarations: DeclarationsBlock;
@@ -45,9 +55,11 @@ export declare type Container = {
45
55
 
46
56
  export declare type ContainerChild = Variable | Selector | AtRule | Utility;
47
57
 
58
+ export declare type ContainerInput = Pick<Container, "declarations" | "variables" | "children">;
59
+
48
60
  export declare function createAtRuleFunction(parent: Container, root: Root): (identifier: string, rule: string, declarationsOrCallback?: DeclarationsBlock | DeclarationsCallback) => AtRule;
49
61
 
50
- export declare function createCssFunction(_parent: Container, _root: Root): (strings: TemplateStringsArray, ...interpolations: TokenValue[]) => CSS_2;
62
+ export declare function createCssFunction(_parent: Container, _root: Root): (strings: TemplateStringsArray, ...interpolations: (TokenValue | Variable | AtRule)[]) => CSS_2;
51
63
 
52
64
  export declare function createDeclarationsCallbackContext(parent: Container, root: Root): DeclarationsCallbackContext;
53
65
 
@@ -57,6 +69,14 @@ export declare function createMediaFunction(parent: Container, root: Root): (que
57
69
 
58
70
  export declare function createModifierFunction(_parent: Container, root: Root): <Key extends string>(key: Key | Key[], factory: ModifierFactory["factory"]) => ModifierFactory;
59
71
 
72
+ /**
73
+ * Creates a resolver that converts @-prefixed variable references in string values.
74
+ * - Exact match "@name" → Reference object
75
+ * - Embedded "1px solid @name" → CSS object with mixed parts
76
+ * - Non-string or no @ → returns value unchanged
77
+ */
78
+ export declare function createPropertyValueResolver(parent: Container, root: Root): (value: TokenValue) => TokenValue;
79
+
60
80
  /**
61
81
  * Creates a recipe function to define design system recipes with variants.
62
82
  *
@@ -212,20 +232,20 @@ export declare function createModifierFunction(_parent: Container, root: Root):
212
232
  */
213
233
  export declare function createRecipeFunction(_parent: Container, root: Root): <Name extends string, Variants extends VariantsBase>(options: Omit<Recipe<Name, Variants>, "type">) => Recipe<Name, Variants>;
214
234
 
215
- export declare function createRefFunction(_parent: Container, _root: Root): <Name extends string>(variable: Variable<Name> | Name, fallback?: string) => Reference<Name>;
235
+ export declare function createRefFunction(parent: Container, root: Root): <Name extends string>(variable: Variable<Name> | Name, fallback?: string) => Reference<Name>;
216
236
 
217
237
  export declare function createRoot(): Root;
218
238
 
219
- export declare function createSelectorFunction(parent: Container, root: Root): (query: string, declarationsOrCallback: DeclarationsBlock | Container | DeclarationsCallback) => Selector;
239
+ export declare function createSelectorFunction(parent: Container, root: Root): (query: string, declarationsOrCallback: DeclarationsBlock | ContainerInput | DeclarationsCallback) => Selector;
220
240
 
221
- export declare function createThemeFunction(_parent: Container, root: Root): (name: string, callback: DeclarationsCallback) => Theme;
241
+ export declare function createThemeFunction(parent: Container, root: Root): (name: string, callback: DeclarationsCallback) => Theme;
222
242
 
223
243
  export declare function createUtilityFunction(parent: Container, root: Root): <Name extends string>(name: Name, factory: UtilityCallbackFn, options?: {
224
244
  autogenerate?: UtilityAutogenerateFn;
225
245
  namespace?: string | string[];
226
246
  }) => UtilityCreatorFn;
227
247
 
228
- export declare function createVariableFunction(parent: Container, _root: Root): <Name extends string>(nameOrInstance: Name | Variable<Name>, value: TokenValue, options?: {
248
+ export declare function createVariableFunction(parent: Container, root: Root): <Name extends string>(nameOrInstance: Name | Variable<Name>, value: TokenValue, options?: {
229
249
  default: boolean;
230
250
  }) => Variable<Name>;
231
251
 
@@ -257,6 +277,14 @@ export declare type DeclarationsCallbackContext = {
257
277
 
258
278
  export declare const deepClone: CloneFunction<any>;
259
279
 
280
+ export declare const defaultUtilitySelectorFn: UtilitySelectorFn;
281
+
282
+ /**
283
+ * Checks whether a variable with the given name exists in the scope chain,
284
+ * walking from the given scope up through ancestors via parentId.
285
+ */
286
+ export declare function findVariableInScope(name: string, scope: Container, root: Root): boolean;
287
+
260
288
  /**
261
289
  * Generates a random ID string
262
290
  *
@@ -282,12 +310,25 @@ export declare function getUtility(root: Root, name: string): UtilityFactory;
282
310
 
283
311
  export declare function getVariable(root: Container, name: string): Variable;
284
312
 
313
+ /**
314
+ * Generates a deterministic, CSS-safe hash string from an arbitrary value.
315
+ * Uses DJB2 algorithm for fast, low-collision hashing.
316
+ *
317
+ * @param value - The string value to hash
318
+ * @returns A lowercase hex string of 7 characters (e.g., "a1b2c3d")
319
+ */
320
+ export declare function hashValue(value: string): string;
321
+
285
322
  export declare function isAtRule(value: unknown): value is AtRule;
286
323
 
287
324
  export declare function isContainer(value: unknown): value is Container;
288
325
 
326
+ export declare function isContainerInput(value: unknown): value is ContainerInput;
327
+
289
328
  export declare function isCSS(value: unknown): value is CSS_2;
290
329
 
330
+ export declare function isKeyReferenceValue(value: unknown): value is `@${string}`;
331
+
291
332
  export declare function isModifier(value: unknown): value is ModifierFactory;
292
333
 
293
334
  export declare function isObject(value: unknown): value is object;
@@ -337,7 +378,9 @@ export declare type ModifierFactory = {
337
378
  factory: ModifierCallbackFn;
338
379
  };
339
380
 
340
- export declare function parseDeclarationsBlock(declarations: DeclarationsBlock, context: DeclarationsCallbackContext): DeclarationsBlock;
381
+ export declare function parseAtReferences(str: string): TokenValue[];
382
+
383
+ export declare function parseDeclarationsBlock(declarations: DeclarationsBlock, context: DeclarationsCallbackContext, parent: Container, root: Root): DeclarationsBlock;
341
384
 
342
385
  export declare type PrimitiveTokenValue = number | string | boolean | null | undefined;
343
386
 
@@ -378,6 +421,8 @@ export declare type PrimitiveTokenValue = number | string | boolean | null | und
378
421
  */
379
422
  export declare function processRecipeUtilities(recipe: Recipe, root: Root): void;
380
423
 
424
+ export declare function rebuildRegistry(root: Root): void;
425
+
381
426
  export declare type Recipe<Name extends string = string, Variants extends VariantsBase = VariantsBase> = {
382
427
  type: "recipe";
383
428
  name: Name;
@@ -420,6 +465,8 @@ export declare type Reference<Name extends string = string> = {
420
465
  fallback?: TokenValue;
421
466
  };
422
467
 
468
+ export declare type RefFunction = (variable: string, fallback?: string) => Reference;
469
+
423
470
  export declare function rfdc<T = any>(opts?: RfdcOptions): CloneFunction<T>;
424
471
 
425
472
  declare interface RfdcOptions {
@@ -430,6 +477,8 @@ declare interface RfdcOptions {
430
477
 
431
478
  export declare type Root = {
432
479
  type: "root";
480
+ id: string;
481
+ parentId?: string;
433
482
  declarations: DeclarationsBlock;
434
483
  utilities: UtilityFactory[];
435
484
  modifiers: ModifierFactory[];
@@ -437,6 +486,7 @@ export declare type Root = {
437
486
  variables: Variable[];
438
487
  children: ContainerChild[];
439
488
  themes: Theme[];
489
+ _registry: Map<string, Container | Root | Theme>;
440
490
  };
441
491
 
442
492
  export declare type RuntimeModifierDeclarationsBlock = Record<string, PrimitiveTokenValue>;
@@ -447,6 +497,8 @@ export declare type RuntimeVariantDeclarationsValue = PrimitiveTokenValue | Runt
447
497
 
448
498
  export declare type Selector = {
449
499
  type: "selector";
500
+ id: string;
501
+ parentId?: string;
450
502
  query: string;
451
503
  declarations: DeclarationsBlock;
452
504
  variables: Variable[];
@@ -488,6 +540,8 @@ export declare type StyleframeOptions = {
488
540
 
489
541
  export declare type Theme = {
490
542
  type: "theme";
543
+ id: string;
544
+ parentId?: string;
491
545
  name: string;
492
546
  declarations: DeclarationsBlock;
493
547
  variables: Variable[];
@@ -513,6 +567,8 @@ export declare interface TransformUtilityKeyOptions {
513
567
 
514
568
  export declare type Utility<Name extends string = string> = {
515
569
  type: "utility";
570
+ id: string;
571
+ parentId?: string;
516
572
  name: Name;
517
573
  value: string;
518
574
  declarations: DeclarationsBlock;
@@ -543,14 +599,25 @@ export declare type UtilityFactory<Name extends string = string> = {
543
599
  create: UtilityCreatorFn;
544
600
  };
545
601
 
546
- export declare type UtilitySelectorFn = (options: {
602
+ export declare type UtilitySelectorFn = (options: UtilitySelectorOptions) => string;
603
+
604
+ export declare interface UtilitySelectorOptions {
547
605
  name: string;
548
606
  value: string;
549
607
  modifiers: string[];
550
- }) => string;
608
+ }
609
+
610
+ /**
611
+ * Validates that a variable name exists in the scope chain.
612
+ * Walks from the given scope up through ancestors to root.
613
+ * Throws if the variable is not defined.
614
+ */
615
+ export declare function validateReference(name: string, scope: Container, root: Root): void;
551
616
 
552
617
  export declare type Variable<Name extends string = string> = {
553
618
  type: "variable";
619
+ id: string;
620
+ parentId?: string;
554
621
  name: Name;
555
622
  value: TokenValue;
556
623
  };