diff --git a/styles/src/theme/tokens/colorScheme.ts b/styles/src/theme/tokens/colorScheme.ts index 1874fbcd95..dcaab85816 100644 --- a/styles/src/theme/tokens/colorScheme.ts +++ b/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 & Partial } 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 + +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; + return { ...acc, [styleKey]: colorToken(styleKey, color) }; + }, {} as ThemeSyntaxColorTokens); } -// TODO: Implement exporting syntax tokens -type ThemeSyntaxToken = Record +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 + +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; + 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), } }