WIP syntax tokens

Nate Butler created

Change summary

styles/src/theme/tokens/colorScheme.ts | 70 ++++++++++++++++++++++++---
1 file changed, 61 insertions(+), 9 deletions(-)

Detailed changes

styles/src/theme/tokens/colorScheme.ts 🔗

@@ -1,7 +1,10 @@
 import { SingleBoxShadowToken, SingleColorToken, SingleOtherToken, TokenTypes, TokenTypographyValue } from "@tokens-studio/types"
-import { ColorScheme, Shadow, ThemeSyntax } from "../colorScheme"
+import { ColorScheme, Shadow, SyntaxHighlightStyle, ThemeSyntax } from "../colorScheme"
 import { LayerToken, layerToken } from "./layer"
 import { PlayersToken, playersToken } from "./players"
+import { colorToken } from "./token"
+import { Syntax } from "../syntax";
+import editor from "../../styleTree/editor"
 
 interface ColorSchemeTokens {
     name: SingleOtherToken
@@ -12,7 +15,7 @@ interface ColorSchemeTokens {
     players: PlayersToken
     popoverShadow: SingleBoxShadowToken
     modalShadow: SingleBoxShadowToken
-    syntax?: ThemeSyntaxToken
+    syntax?: Partial<ThemeSyntaxColorTokens> & Partial<ThemeSyntaxTypographyTokens>
 }
 
 const createShadowToken = (shadow: Shadow, tokenName: string): SingleBoxShadowToken => {
@@ -33,15 +36,63 @@ const modalShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
     return createShadowToken(shadow, "modalShadow");
 };
 
-interface SyntaxHighlightStyleToken {
-    color: SingleColorToken
-    weight: TokenTypographyValue['fontWeight']
-    underline: TokenTypographyValue['textDecoration']
-    italic: SingleOtherToken
+type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
+
+function syntaxHighlightStyleColorTokens(syntax: Syntax): ThemeSyntaxColorTokens | null {
+    const styleKeys = Object.keys(syntax) as (keyof Syntax)[]
+
+    return styleKeys.reduce((acc, styleKey) => {
+        // Hack: The type of a style could be "Function"
+        // This can happen because we have a "constructor" property on the syntax object
+        // and a "constructor" property on the prototype of the syntax object
+        // To work around this just assert that the type of the style is not a function
+        if (!syntax[styleKey] || typeof syntax[styleKey] === 'function') return acc;
+        const { color } = syntax[styleKey] as Required<SyntaxHighlightStyle>;
+        return { ...acc, [styleKey]: colorToken(styleKey, color) };
+    }, {} as ThemeSyntaxColorTokens);
 }
 
-// TODO: Implement exporting syntax tokens
-type ThemeSyntaxToken = Record<keyof ThemeSyntax, SyntaxHighlightStyleToken>
+function syntaxHighlightStyleTypographyToken(highlightStyle: SyntaxHighlightStyle): TokenTypographyValue | null {
+    const { weight, underline, italic } = highlightStyle
+
+    let w = weight ? weight : "extended"
+
+    if (italic) {
+        w = `${w} Italic`
+    }
+
+    const fontWeight = w as TokenTypographyValue['fontWeight']
+
+    return {
+        fontWeight,
+        textDecoration: underline ? "underline" : "none",
+    }
+}
+
+type ThemeSyntaxTypographyTokens = Record<keyof ThemeSyntax, TokenTypographyValue>
+
+function syntaxHighlightStyleTypographyTokens(syntax: Syntax): ThemeSyntaxTypographyTokens | null {
+    const styleKeys = Object.keys(syntax) as (keyof Syntax)[]
+
+    return styleKeys.reduce((acc, styleKey) => {
+        // Hack: The type of a style could be "Function"
+        // This can happen because we have a "constructor" property on the syntax object
+        // and a "constructor" property on the prototype of the syntax object
+        // To work around this just assert that the type of the style is not a function
+        if (!syntax[styleKey] || typeof syntax[styleKey] === 'function') return acc;
+        const syntaxHighlightStyle = syntax[styleKey] as Required<SyntaxHighlightStyle>;
+        return { ...acc, [styleKey]: syntaxHighlightStyleTypographyToken(syntaxHighlightStyle) };
+    }, {} as ThemeSyntaxTypographyTokens);
+}
+
+const syntaxTokens = (colorScheme: ColorScheme): ColorSchemeTokens['syntax'] => {
+    const syntax = editor(colorScheme).syntax
+
+    return {
+        ...syntaxHighlightStyleColorTokens(syntax),
+        // ...syntaxHighlightStyleTypographyTokens(syntax),
+    }
+}
 
 export function colorSchemeTokens(colorScheme: ColorScheme): ColorSchemeTokens {
     return {
@@ -61,5 +112,6 @@ export function colorSchemeTokens(colorScheme: ColorScheme): ColorSchemeTokens {
         popoverShadow: popoverShadowToken(colorScheme),
         modalShadow: modalShadowToken(colorScheme),
         players: playersToken(colorScheme),
+        syntax: syntaxTokens(colorScheme),
     }
 }