diff --git a/styles/src/themeConfig.ts b/styles/src/themeConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..0b93a678533f7756e2d0d5fc6b105ab38a702003 --- /dev/null +++ b/styles/src/themeConfig.ts @@ -0,0 +1,137 @@ +import { Scale, Color } from "chroma-js" +import { Syntax } from "./themes/common/syntax" + +interface ThemeMeta { + /** The name of the theme */ + name: string + /** The theme's appearance. Either `light` or `dark`. */ + appearance: ThemeAppearance + /** The author of the theme + * + * Ideally formatted as `Full Name ` + * + * Example: `John Doe ` + */ + author: string + /** SPDX License string + * + * Example: `MIT` + */ + licenseType?: string + licenseUrl?: string + themeUrl?: string +} + +export interface ThemeConfigInputColors { + neutral: Scale + red: Scale + orange: Scale + yellow: Scale + green: Scale + cyan: Scale + blue: Scale + violet: Scale + magenta: Scale +} + +export type ThemeConfigInputColorsKeys = keyof ThemeConfigInputColors + +/** Allow any part of a syntax highlight style to be overriden by the theme + * + * Example: + * ```ts + * override: { + * syntax: { + * boolean: { + * underline: true, + * }, + * }, + * } + * ``` + */ +export type ThemeConfigInputSyntax = Partial + +interface ThemeConfigOverrides { + syntax: ThemeConfigInputSyntax +} + +type ThemeConfigProperties = ThemeMeta & { + inputColor: ThemeConfigInputColors + override: ThemeConfigOverrides +} + +// This should be the format a theme is defined as +export type ThemeConfig = { + [K in keyof ThemeConfigProperties]: ThemeConfigProperties[K] +} + +interface ThemeColors { + neutral: string[] + red: string[] + orange: string[] + yellow: string[] + green: string[] + cyan: string[] + blue: string[] + violet: string[] + magenta: string[] +} + +type ThemeSyntax = Required + +export type ThemeProperties = ThemeMeta & { + color: ThemeColors + syntax: ThemeSyntax +} + +// This should be a theme after all its properties have been resolved +export type Theme = { + [K in keyof ThemeProperties]: ThemeProperties[K] +} + +export enum ThemeAppearance { + Light = "light", + Dark = "dark", +} + +export type ThemeFamilyItem = + | ThemeConfig + | { light: ThemeConfig; dark: ThemeConfig } + +type ThemeFamilyProperties = Partial> & { + name: string + default: ThemeFamilyItem + variants: { + [key: string]: ThemeFamilyItem + } +} + +// Idea: A theme family is a collection of themes that share the same name +// For example, a theme family could be `One Dark` and have a `light` and `dark` variant +// The Ayu family could have `light`, `mirage`, and `dark` variants + +type ThemeFamily = { + [K in keyof ThemeFamilyProperties]: ThemeFamilyProperties[K] +} + +/** The collection of all themes + * + * Example: + * ```ts + * { + * one_dark, + * one_light, + * ayu: { + * name: 'Ayu', + * default: 'ayu_mirage', + * variants: { + * light: 'ayu_light', + * mirage: 'ayu_mirage', + * dark: 'ayu_dark', + * }, + * }, + * ... + * } + * ``` + */ +export type ThemeIndex = Record