@@ -104,7 +104,7 @@ interface CSSVarMap {
104104}
105105
106106function assignTokens < ThemeTokens extends Theme > (
107- tokens : ThemeTokens
107+ tokens : ThemeTokensInput < ThemeTokens >
108108) : {
109109 vars : AssignedVars ;
110110 resolvedTokens : ResolveTheme < ThemeTokens > ;
@@ -259,9 +259,7 @@ function assignTokenVariables(
259259 // Handle TokenCompositeValue
260260 if ( isTokenCompositeValue ( value ) ) {
261261 const resolvedComposite : Record < string , PureCSSVarFunction > = { } ;
262-
263- // Process resolved property
264- vars [ cssVar ] = extractCSSValue ( value . resolved ) ;
262+ const compositeDescriptors = Object . getOwnPropertyDescriptors ( value ) ;
265263
266264 // Create getter for resolved property
267265 Object . defineProperty ( resolvedComposite , "resolved" , {
@@ -273,12 +271,20 @@ function assignTokenVariables(
273271 } ) ;
274272
275273 // Process other properties
276- for ( const [ propKey , propValue ] of Object . entries ( value ) ) {
274+ for ( const [ propKey , propDescriptor ] of Object . entries (
275+ compositeDescriptors
276+ ) ) {
277277 if ( propKey === "resolved" ) continue ;
278278
279279 const propPath = `${ varPath } -${ camelToKebab ( propKey ) } ` ;
280280 const propCssVar = getCSSVarByPath ( propPath , context ) ;
281- vars [ propCssVar ] = extractCSSValue ( propValue as TokenValue ) ;
281+ if ( typeof propDescriptor . get === "function" ) {
282+ // Store placeholder reference; value will be resolved in pass 2
283+ resolvedComposite [ propKey ] = getVarReference ( propPath , context ) ;
284+ continue ;
285+ }
286+
287+ vars [ propCssVar ] = extractCSSValue ( propDescriptor . value as TokenValue ) ;
282288 resolvedComposite [ propKey ] = getVarReference ( propPath , context ) ;
283289 }
284290
@@ -353,6 +359,39 @@ function resolveSemanticTokens(
353359
354360 const value = descriptor . value ;
355361
362+ // Handle TokenCompositeValue resolved property computation
363+ if ( isTokenCompositeValue ( value ) ) {
364+ const compositeDescriptors = Object . getOwnPropertyDescriptors ( value ) ;
365+ const resolvedDescriptor = compositeDescriptors . resolved ;
366+
367+ if ( resolvedDescriptor ?. get ) {
368+ const resolvedPath = [ ...currentPath , "resolved" ] ;
369+ const evaluationContext = Object . create ( resolvedTokens ) ;
370+
371+ for ( const [ propKey , propDescriptor ] of Object . entries (
372+ compositeDescriptors
373+ ) ) {
374+ if ( propKey === "resolved" ) continue ;
375+ Object . defineProperty ( evaluationContext , propKey , propDescriptor ) ;
376+ }
377+
378+ currentProcessingPath = resolvedPath ;
379+ const computedValue = resolvedDescriptor . get . call ( evaluationContext ) ;
380+ currentProcessingPath = [ ] ;
381+
382+ const resolvedPathKey = resolvedPath . join ( "." ) ;
383+
384+ if ( context . aliasMap . has ( resolvedPathKey ) ) {
385+ setByPath ( resolvedTokens , resolvedPath , computedValue ) ;
386+ } else {
387+ const cssVar = getCSSVarByPath ( varPath , context ) ;
388+ vars [ cssVar ] = extractCSSValue ( computedValue as TokenValue ) ;
389+ }
390+ }
391+
392+ continue ;
393+ }
394+
356395 // Handle nested TokenDefinition with object $value
357396 if (
358397 isTokenDefinition ( value ) &&
@@ -689,9 +728,9 @@ if (import.meta.vitest) {
689728 const debugId = "myCSS" ;
690729 setFileScope ( "test" ) ;
691730
692- function composedValue < ComposedValue > (
693- value : ComposedValue & ThisType < ComposedValue & ThemeSubFunctions >
694- ) : ComposedValue {
731+ function compositeValue < CompositeValue > (
732+ value : CompositeValue & ThisType < CompositeValue & ThemeSubFunctions >
733+ ) : CompositeValue {
695734 return value ;
696735 }
697736
@@ -893,7 +932,7 @@ if (import.meta.vitest) {
893932
894933 it ( "handles semantic token references with getters" , ( ) => {
895934 const result = assignTokens (
896- composedValue ( {
935+ compositeValue ( {
897936 color : {
898937 base : {
899938 red : "#ff0000" ,
@@ -941,7 +980,7 @@ if (import.meta.vitest) {
941980
942981 it ( "handles fallbackVar in semantic tokens" , ( ) => {
943982 const result = assignTokens (
944- composedValue ( {
983+ compositeValue ( {
945984 color : {
946985 base : {
947986 blue : "#0000ff" ,
@@ -975,7 +1014,7 @@ if (import.meta.vitest) {
9751014
9761015 it ( "handles alias references in semantic tokens" , ( ) => {
9771016 const result = assignTokens (
978- composedValue ( {
1017+ compositeValue ( {
9791018 color : {
9801019 base : {
9811020 blue : "#0000ff" ,
@@ -1032,7 +1071,7 @@ if (import.meta.vitest) {
10321071
10331072 it ( "handles raw value extraction in semantic tokens" , ( ) => {
10341073 const result = assignTokens (
1035- composedValue ( {
1074+ compositeValue ( {
10361075 color : {
10371076 base : {
10381077 blue : "#0000ff" ,
@@ -1346,27 +1385,27 @@ if (import.meta.vitest) {
13461385 } ) ;
13471386
13481387 it ( "handles TokenComposedValue with resolved getter" , ( ) => {
1349- const shadowValue = composedValue ( {
1350- get resolved ( ) {
1351- return `${ this . color } ${ this . offsetX . value } ${ this . offsetX . unit } ${ this . offsetY . value } ${ this . offsetY . unit } ${ this . blur . value } ${ this . blur . unit } ` ;
1352- } ,
1353- color : "#00000080" ,
1354- offsetX : { value : 0.5 , unit : "rem" } ,
1355- offsetY : { value : 0.5 , unit : "rem" } ,
1356- blur : { value : 1.5 , unit : "rem" }
1357- } ) ;
1358-
13591388 const result = assignTokens ( {
13601389 shadow : {
1361- light : shadowValue
1390+ light : {
1391+ get resolved ( ) : string {
1392+ return `${ this . shadow . light . color } ${ this . shadow . light . offsetX } ${ this . shadow . light . offsetY } ${ this . shadow . light . blur } ` ;
1393+ } ,
1394+ color : "#00000080" ,
1395+ offsetX : { value : 0.5 , unit : "rem" } ,
1396+ offsetY : { value : 0.5 , unit : "rem" } ,
1397+ blur : { value : 1.5 , unit : "rem" }
1398+ }
13621399 }
13631400 } ) ;
13641401
13651402 validateHashFormatForVar ( result . vars ) ;
13661403 validateHashFormatForResolved ( result . resolvedTokens ) ;
13671404
13681405 const normalized = normalizeVars ( result . vars ) ;
1369- expect ( normalized [ "--shadow-light" ] ) . toMatch ( / ^ # 0 0 0 0 0 0 8 0 / ) ;
1406+ expect ( stripHash ( normalized [ "--shadow-light" ] ) ) . toBe (
1407+ "var(--shadow-light-color) var(--shadow-light-offset-x) var(--shadow-light-offset-y) var(--shadow-light-blur)"
1408+ ) ;
13701409 expect ( normalized [ "--shadow-light-color" ] ) . toBe ( "#00000080" ) ;
13711410 expect ( normalized [ "--shadow-light-offset-x" ] ) . toBe ( "0.5rem" ) ;
13721411 expect ( normalized [ "--shadow-light-offset-y" ] ) . toBe ( "0.5rem" ) ;
@@ -1565,7 +1604,7 @@ if (import.meta.vitest) {
15651604
15661605 it ( "handles semantic tokens with fallbackVar" , ( ) => {
15671606 const [ className , themeVars ] = theme (
1568- composedValue ( {
1607+ compositeValue ( {
15691608 color : {
15701609 base : {
15711610 blue : "#0000ff"
@@ -1597,7 +1636,7 @@ if (import.meta.vitest) {
15971636
15981637 it ( "handles semantic tokens with alias" , ( ) => {
15991638 const [ className , themeVars ] = theme (
1600- composedValue ( {
1639+ compositeValue ( {
16011640 color : {
16021641 base : {
16031642 blue : "#0000ff" ,
@@ -1626,7 +1665,7 @@ if (import.meta.vitest) {
16261665
16271666 it ( "handles semantic tokens with raw" , ( ) => {
16281667 const [ className , themeVars ] = theme (
1629- composedValue ( {
1668+ compositeValue ( {
16301669 color : {
16311670 base : {
16321671 blue : "#0000ff" ,
@@ -1663,7 +1702,7 @@ if (import.meta.vitest) {
16631702 } ) ;
16641703
16651704 it ( "handles TokenCompositeValue" , ( ) => {
1666- const shadowValue = composedValue ( {
1705+ const shadowValue = compositeValue ( {
16671706 get resolved ( ) {
16681707 return `${ this . color } ${ this . offsetX . value } ${ this . offsetX . unit } ${ this . offsetY . value } ${ this . offsetY . unit } ` ;
16691708 } ,
@@ -1781,7 +1820,7 @@ if (import.meta.vitest) {
17811820
17821821 it ( "handles complex semantic token references" , ( ) => {
17831822 const [ className , themeVars ] = theme (
1784- composedValue ( {
1823+ compositeValue ( {
17851824 color : {
17861825 base : {
17871826 red : "#ff0000" ,
@@ -1935,6 +1974,17 @@ if (import.meta.vitest) {
19351974 return this . space . base [ 5 ] ;
19361975 }
19371976 }
1977+ } ,
1978+ shadow : {
1979+ light : {
1980+ get resolved ( ) : string {
1981+ return `${ this . shadow . light . color } ${ this . shadow . light . offsetX } ${ this . shadow . light . offsetY } ${ this . shadow . light . blur } ` ;
1982+ } ,
1983+ color : "#00000080" ,
1984+ offsetX : { value : 0.5 , unit : "rem" } ,
1985+ offsetY : { value : 0.5 , unit : "rem" } ,
1986+ blur : { value : 1.5 , unit : "rem" }
1987+ }
19381988 }
19391989 } ,
19401990 debugId
@@ -1969,6 +2019,15 @@ if (import.meta.vitest) {
19692019 medium : "var(--space-base-3)" ,
19702020 large : "var(--space-base-5)"
19712021 }
2022+ } ,
2023+ shadow : {
2024+ light : {
2025+ resolved : "var(--shadow-light)" ,
2026+ color : "var(--shadow-light-color)" ,
2027+ offsetX : "var(--shadow-light-offset-x)" ,
2028+ offsetY : "var(--shadow-light-offset-y)" ,
2029+ blur : "var(--shadow-light-blur)"
2030+ }
19722031 }
19732032 } ) ;
19742033 } ) ;
0 commit comments