@@ -35,6 +35,7 @@ type WithOptionalLayer<T extends Theme> = T & {
3535
3636interface ThemeSubFunctions {
3737 fallbackVar : typeof fallbackVar ;
38+ raw ( varReference : unknown ) : string ;
3839}
3940
4041type ResolveThemeOutput < T extends Theme > = Resolve < ResolveTheme < T > > ;
@@ -132,6 +133,14 @@ function assignTokensWithPrefix<ThemeTokens extends Theme>(
132133 writable : false
133134 } ) ;
134135
136+ // Add raw utility to extract actual values instead of var() references
137+ Object . defineProperty ( resolvedTokens , "raw" , {
138+ value : createRawExtractor ( vars ) ,
139+ enumerable : false ,
140+ configurable : false ,
141+ writable : false
142+ } ) ;
143+
135144 // Execute two-pass token resolution:
136145 // 1. Assign CSS variables to all tokens
137146 // 2. Resolve semantic token references
@@ -475,6 +484,25 @@ function setByPath(
475484 }
476485}
477486
487+ /**
488+ * Creates a function that extracts raw CSS values from var() references.
489+ * Used to "hardcode" values instead of using CSS variable references.
490+ */
491+ function createRawExtractor ( vars : AssignedVars ) {
492+ return function raw ( varReference : unknown ) {
493+ if ( typeof varReference === "string" ) {
494+ // Use getVarName utility to extract the CSS variable name
495+ const varName = getVarName ( varReference ) ;
496+ // If it was a var() reference and we have the value, return it
497+ if ( varName !== varReference && varName in vars ) {
498+ return vars [ varName ] ;
499+ }
500+ }
501+ // If not a var reference or lookup failed, return as-is
502+ return varReference ;
503+ } ;
504+ }
505+
478506// == Token Value Extractors ==================================================
479507function extractFontFamilyValue ( value : TokenFontFamilyValue ) : CSSVarValue {
480508 if ( Array . isArray ( value ) ) {
@@ -579,7 +607,7 @@ function extractTokenDefinitionValue(definition: TokenDefinition): CSSVarValue {
579607
580608function extractCSSValue ( value : TokenValue ) : CSSVarValue {
581609 if ( isPrimitive ( value ) ) {
582- return String ( value ) as CSSVarValue ;
610+ return value as CSSVarValue ;
583611 }
584612
585613 if ( isTokenUnitValue ( value ) ) {
@@ -687,9 +715,9 @@ if (import.meta.vitest) {
687715 // Compare normalized values (without hashes)
688716 expect ( normalizeVars ( result . vars ) ) . toEqual ( {
689717 "--color" : "red" ,
690- "--size" : "16" ,
691- "--enabled" : " true" ,
692- "--nothing" : " undefined"
718+ "--size" : 16 ,
719+ "--enabled" : true ,
720+ "--nothing" : undefined
693721 } ) ;
694722
695723 expect ( normalizeResolvedTokens ( result . resolvedTokens ) ) . toEqual ( {
@@ -712,7 +740,7 @@ if (import.meta.vitest) {
712740 expect ( normalizeVars ( result . vars ) ) . toEqual ( {
713741 "--background-color" : "white" ,
714742 "--font-size" : "16px" ,
715- "--line-height" : " 1.5"
743+ "--line-height" : 1.5
716744 } ) ;
717745
718746 expect ( normalizeResolvedTokens ( result . resolvedTokens ) ) . toEqual ( {
@@ -730,11 +758,11 @@ if (import.meta.vitest) {
730758 validateHashFormat ( result . vars ) ;
731759
732760 expect ( normalizeVars ( result . vars ) ) . toEqual ( {
733- "--space-0" : "2" ,
734- "--space-1" : "4" ,
735- "--space-2" : "8" ,
736- "--space-3" : "16" ,
737- "--space-4" : "32"
761+ "--space-0" : 2 ,
762+ "--space-1" : 4 ,
763+ "--space-2" : 8 ,
764+ "--space-3" : 16 ,
765+ "--space-4" : 32
738766 } ) ;
739767
740768 expect ( normalizeResolvedTokens ( result . resolvedTokens ) ) . toEqual ( {
@@ -866,6 +894,58 @@ if (import.meta.vitest) {
866894 ) ;
867895 } ) ;
868896
897+ it ( "handles raw value extraction in semantic tokens" , ( ) => {
898+ const result = assignTokens (
899+ composedValue ( {
900+ color : {
901+ base : {
902+ blue : "#0000ff" ,
903+ red : "#ff0000"
904+ } ,
905+ semantic : {
906+ get primary ( ) : string {
907+ // Use raw to get the actual value instead of var() reference
908+ return this . raw ( this . color . base . blue ) ;
909+ } ,
910+ get danger ( ) : string {
911+ // Test raw with another token
912+ return this . raw ( this . color . base . red ) ;
913+ } ,
914+ get custom ( ) : string {
915+ // Test raw with a non-var value
916+ return this . raw ( "#00ff00" ) ;
917+ }
918+ }
919+ } ,
920+ space : {
921+ base : [ 2 , 4 , 8 , 16 , 32 , 64 ] ,
922+ semantic : {
923+ get small ( ) : string {
924+ return this . raw ( this . space . base [ 1 ] ) ;
925+ } ,
926+ get medium ( ) : string {
927+ return this . raw ( this . space . base [ 3 ] ) ;
928+ } ,
929+ get large ( ) : string {
930+ return this . raw ( this . space . base [ 5 ] ) ;
931+ }
932+ }
933+ }
934+ } )
935+ ) ;
936+
937+ validateHashFormat ( result . vars ) ;
938+
939+ const normalizedVars = normalizeVars ( result . vars ) ;
940+ // The semantic tokens should contain the raw values, not var() references
941+ expect ( normalizedVars [ "--color-semantic-primary" ] ) . toBe ( "#0000ff" ) ;
942+ expect ( normalizedVars [ "--color-semantic-danger" ] ) . toBe ( "#ff0000" ) ;
943+ expect ( normalizedVars [ "--color-semantic-custom" ] ) . toBe ( "#00ff00" ) ;
944+ expect ( normalizedVars [ "--space-semantic-small" ] ) . toBe ( 4 ) ;
945+ expect ( normalizedVars [ "--space-semantic-medium" ] ) . toBe ( 16 ) ;
946+ expect ( normalizedVars [ "--space-semantic-large" ] ) . toBe ( 64 ) ;
947+ } ) ;
948+
869949 it ( "handles TokenUnitValue" , ( ) => {
870950 const result = assignTokens ( {
871951 spacing : { value : 1.5 , unit : "rem" } ,
@@ -1170,14 +1250,14 @@ if (import.meta.vitest) {
11701250 validateHashFormat ( result . vars ) ;
11711251 const normalized = normalizeVars ( result . vars ) ;
11721252
1173- expect ( normalized [ "--typography-heading-sizes-0" ] ) . toBe ( "48" ) ;
1174- expect ( normalized [ "--typography-heading-sizes-4" ] ) . toBe ( "16" ) ;
1253+ expect ( normalized [ "--typography-heading-sizes-0" ] ) . toBe ( 48 ) ;
1254+ expect ( normalized [ "--typography-heading-sizes-4" ] ) . toBe ( 16 ) ;
11751255 expect ( normalized [ "--typography-heading-weight" ] ) . toBe ( "700" ) ;
11761256 expect ( normalized [ "--typography-heading-family" ] ) . toBe (
11771257 "Helvetica, sans-serif"
11781258 ) ;
11791259 expect ( normalized [ "--typography-body-size" ] ) . toBe ( "14px" ) ;
1180- expect ( normalized [ "--typography-body-line-height" ] ) . toBe ( " 1.5" ) ;
1260+ expect ( normalized [ "--typography-body-line-height" ] ) . toBe ( 1.5 ) ;
11811261 expect ( normalized [ "--colors-primary" ] ) . toBe ( "#007bff" ) ;
11821262 expect ( normalized [ "--colors-secondary" ] ) . toBe ( "#6c757d" ) ;
11831263 } ) ;
0 commit comments