Files
oak-gpui/styles/src/theme/tokens/theme.ts
T
2023-08-29 16:02:04 -04:00

98 lines
3.1 KiB
TypeScript

import {
SingleBoxShadowToken,
SingleColorToken,
SingleOtherToken,
TokenTypes,
} from "@tokens-studio/types"
import { Shadow, SyntaxHighlightStyle, ThemeSyntax } from "../create_theme"
import { LayerToken, layer_token } from "./layer"
import { PlayersToken, players_token } from "./players"
import { color_token } from "./token"
import { Syntax } from "../syntax"
import editor from "../../style_tree/editor"
import { useTheme } from "../../../src/common"
interface ThemeTokens {
name: SingleOtherToken
appearance: SingleOtherToken
lowest: LayerToken
middle: LayerToken
highest: LayerToken
players: PlayersToken
popover_shadow: SingleBoxShadowToken
modal_shadow: SingleBoxShadowToken
syntax?: Partial<ThemeSyntaxColorTokens>
}
const create_shadow_token = (
shadow: Shadow,
token_name: string
): SingleBoxShadowToken => {
return {
name: token_name,
type: TokenTypes.BOX_SHADOW,
value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}`,
}
}
const popover_shadow_token = (): SingleBoxShadowToken => {
const theme = useTheme()
const shadow = theme.popover_shadow
return create_shadow_token(shadow, "popover_shadow")
}
const modal_shadow_token = (): SingleBoxShadowToken => {
const theme = useTheme()
const shadow = theme.modal_shadow
return create_shadow_token(shadow, "modal_shadow")
}
type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
function syntax_highlight_style_color_tokens(
syntax: Syntax
): ThemeSyntaxColorTokens {
const style_keys = Object.keys(syntax) as (keyof Syntax)[]
return style_keys.reduce((acc, style_key) => {
// 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[style_key] || typeof syntax[style_key] === "function")
return acc
const { color } = syntax[style_key] as Required<SyntaxHighlightStyle>
return { ...acc, [style_key]: color_token(style_key, color) }
}, {} as ThemeSyntaxColorTokens)
}
const syntax_tokens = (): ThemeTokens["syntax"] => {
const syntax = editor().syntax
return syntax_highlight_style_color_tokens(syntax)
}
export function theme_tokens(): ThemeTokens {
const theme = useTheme()
return {
name: {
name: "themeName",
value: theme.name,
type: TokenTypes.OTHER,
},
appearance: {
name: "themeAppearance",
value: theme.is_light ? "light" : "dark",
type: TokenTypes.OTHER,
},
lowest: layer_token(theme.lowest, "lowest"),
middle: layer_token(theme.middle, "middle"),
highest: layer_token(theme.highest, "highest"),
popover_shadow: popover_shadow_token(),
modal_shadow: modal_shadow_token(),
players: players_token(),
syntax: syntax_tokens(),
}
}