@@ -675,26 +675,33 @@ impl Theme {
675675 for ty in self . typography . iter ( ) {
676676 for ( idx, t) in ty. 1 . 0 . iter ( ) . enumerate ( ) {
677677 if let Some ( t) = t {
678+ let resolve = |v : & str | -> String {
679+ if let Some ( token) = v. strip_prefix ( '$' ) {
680+ format ! ( "var(--{})" , token)
681+ } else {
682+ optimize_value ( v)
683+ }
684+ } ;
678685 let css_content = [
679686 t. font_family
680687 . as_ref ( )
681- . map ( |v| format ! ( "font-family:{}" , optimize_value ( v) ) )
688+ . map ( |v| format ! ( "font-family:{}" , resolve ( v) ) )
682689 . unwrap_or_default ( ) ,
683690 t. font_size
684691 . as_ref ( )
685- . map ( |v| format ! ( "font-size:{}" , optimize_value ( v) ) )
692+ . map ( |v| format ! ( "font-size:{}" , resolve ( v) ) )
686693 . unwrap_or_default ( ) ,
687694 t. font_weight
688695 . as_ref ( )
689- . map ( |v| format ! ( "font-weight:{}" , optimize_value ( v) ) )
696+ . map ( |v| format ! ( "font-weight:{}" , resolve ( v) ) )
690697 . unwrap_or_default ( ) ,
691698 t. line_height
692699 . as_ref ( )
693- . map ( |v| format ! ( "line-height:{}" , optimize_value ( v) ) )
700+ . map ( |v| format ! ( "line-height:{}" , resolve ( v) ) )
694701 . unwrap_or_default ( ) ,
695702 t. letter_spacing
696703 . as_ref ( )
697- . map ( |v| format ! ( "letter-spacing:{}" , optimize_value ( v) ) )
704+ . map ( |v| format ! ( "letter-spacing:{}" , resolve ( v) ) )
698705 . unwrap_or_default ( ) ,
699706 ]
700707 . iter ( )
@@ -1380,6 +1387,71 @@ mod tests {
13801387 assert ! ( err. contains( "cannot start with an array" ) ) ;
13811388 }
13821389
1390+ #[ test]
1391+ fn test_typography_variable_reference ( ) {
1392+ let theme: Theme = serde_json:: from_str (
1393+ r##"{
1394+ "typography": {
1395+ "body": {
1396+ "fontSize": "$text",
1397+ "lineHeight": "$leading",
1398+ "fontWeight": 400
1399+ }
1400+ }
1401+ }"## ,
1402+ )
1403+ . unwrap ( ) ;
1404+
1405+ let css = theme. to_css ( ) ;
1406+ assert ! (
1407+ css. contains( "font-size:var(--text)" ) ,
1408+ "Expected font-size:var(--text), got: {}" ,
1409+ css
1410+ ) ;
1411+ assert ! (
1412+ css. contains( "line-height:var(--leading)" ) ,
1413+ "Expected line-height:var(--leading), got: {}" ,
1414+ css
1415+ ) ;
1416+ assert ! ( css. contains( "font-weight:400" ) ) ;
1417+ }
1418+
1419+ #[ test]
1420+ fn test_typography_variable_reference_responsive ( ) {
1421+ let theme: Theme = serde_json:: from_str (
1422+ r##"{
1423+ "typography": {
1424+ "heading": [
1425+ {
1426+ "fontSize": "$textSm",
1427+ "fontWeight": 700
1428+ },
1429+ null,
1430+ null,
1431+ null,
1432+ {
1433+ "fontSize": "$textLg",
1434+ "fontWeight": 700
1435+ }
1436+ ]
1437+ }
1438+ }"## ,
1439+ )
1440+ . unwrap ( ) ;
1441+
1442+ let css = theme. to_css ( ) ;
1443+ assert ! (
1444+ css. contains( "font-size:var(--textSm)" ) ,
1445+ "Expected font-size:var(--textSm), got: {}" ,
1446+ css
1447+ ) ;
1448+ assert ! (
1449+ css. contains( "font-size:var(--textLg)" ) ,
1450+ "Expected font-size:var(--textLg), got: {}" ,
1451+ css
1452+ ) ;
1453+ }
1454+
13831455 #[ test]
13841456 fn test_mixed_typography_formats ( ) {
13851457 // Test that both formats can coexist in the same theme
0 commit comments