Merge branch 'main' into update-assistant-styles
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
} from "./theme_config"
|
||||
import { get_ramps } from "./ramps"
|
||||
|
||||
export interface ColorScheme {
|
||||
export interface Theme {
|
||||
name: string
|
||||
is_light: boolean
|
||||
|
||||
@@ -114,7 +114,7 @@ export interface Style {
|
||||
foreground: string
|
||||
}
|
||||
|
||||
export function create_color_scheme(theme: ThemeConfig): ColorScheme {
|
||||
export function create_theme(theme: ThemeConfig): Theme {
|
||||
const {
|
||||
name,
|
||||
appearance,
|
||||
@@ -1,4 +1,25 @@
|
||||
export * from "./color_scheme"
|
||||
import { create } from "zustand"
|
||||
import { Theme } from "./create_theme"
|
||||
|
||||
type ThemeState = {
|
||||
theme: Theme | undefined
|
||||
setTheme: (theme: Theme) => void
|
||||
}
|
||||
|
||||
export const useThemeStore = create<ThemeState>((set) => ({
|
||||
theme: undefined,
|
||||
setTheme: (theme) => set(() => ({ theme })),
|
||||
}))
|
||||
|
||||
export const useTheme = (): Theme => {
|
||||
const { theme } = useThemeStore.getState()
|
||||
|
||||
if (!theme) throw new Error("Tried to use theme before it was loaded")
|
||||
|
||||
return theme
|
||||
}
|
||||
|
||||
export * from "./create_theme"
|
||||
export * from "./ramps"
|
||||
export * from "./syntax"
|
||||
export * from "./theme_config"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import chroma, { Color, Scale } from "chroma-js"
|
||||
import { RampSet } from "./color_scheme"
|
||||
import { RampSet } from "./create_theme"
|
||||
import {
|
||||
ThemeConfigInputColors,
|
||||
ThemeConfigInputColorsKeys,
|
||||
|
||||
+41
-45
@@ -1,6 +1,5 @@
|
||||
import deepmerge from "deepmerge"
|
||||
import { FontWeight, font_weights } from "../common"
|
||||
import { ColorScheme } from "./color_scheme"
|
||||
import { FontWeight, font_weights, useTheme } from "../common"
|
||||
import chroma from "chroma-js"
|
||||
|
||||
export interface SyntaxHighlightStyle {
|
||||
@@ -123,7 +122,9 @@ const default_syntax_highlight_style: Omit<SyntaxHighlightStyle, "color"> = {
|
||||
italic: false,
|
||||
}
|
||||
|
||||
function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
function build_default_syntax(): Syntax {
|
||||
const theme = useTheme()
|
||||
|
||||
// Make a temporary object that is allowed to be missing
|
||||
// the "color" property for each style
|
||||
const syntax: {
|
||||
@@ -141,8 +142,8 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
// predictive color distinct from any other color in the theme
|
||||
const predictive = chroma
|
||||
.mix(
|
||||
color_scheme.ramps.neutral(0.4).hex(),
|
||||
color_scheme.ramps.blue(0.4).hex(),
|
||||
theme.ramps.neutral(0.4).hex(),
|
||||
theme.ramps.blue(0.4).hex(),
|
||||
0.45,
|
||||
"lch"
|
||||
)
|
||||
@@ -151,32 +152,32 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
// hint color distinct from any other color in the theme
|
||||
const hint = chroma
|
||||
.mix(
|
||||
color_scheme.ramps.neutral(0.6).hex(),
|
||||
color_scheme.ramps.blue(0.4).hex(),
|
||||
theme.ramps.neutral(0.6).hex(),
|
||||
theme.ramps.blue(0.4).hex(),
|
||||
0.45,
|
||||
"lch"
|
||||
)
|
||||
.hex()
|
||||
|
||||
const color = {
|
||||
primary: color_scheme.ramps.neutral(1).hex(),
|
||||
comment: color_scheme.ramps.neutral(0.71).hex(),
|
||||
punctuation: color_scheme.ramps.neutral(0.86).hex(),
|
||||
primary: theme.ramps.neutral(1).hex(),
|
||||
comment: theme.ramps.neutral(0.71).hex(),
|
||||
punctuation: theme.ramps.neutral(0.86).hex(),
|
||||
predictive: predictive,
|
||||
hint: hint,
|
||||
emphasis: color_scheme.ramps.blue(0.5).hex(),
|
||||
string: color_scheme.ramps.orange(0.5).hex(),
|
||||
function: color_scheme.ramps.yellow(0.5).hex(),
|
||||
type: color_scheme.ramps.cyan(0.5).hex(),
|
||||
constructor: color_scheme.ramps.blue(0.5).hex(),
|
||||
variant: color_scheme.ramps.blue(0.5).hex(),
|
||||
property: color_scheme.ramps.blue(0.5).hex(),
|
||||
enum: color_scheme.ramps.orange(0.5).hex(),
|
||||
operator: color_scheme.ramps.orange(0.5).hex(),
|
||||
number: color_scheme.ramps.green(0.5).hex(),
|
||||
boolean: color_scheme.ramps.green(0.5).hex(),
|
||||
constant: color_scheme.ramps.green(0.5).hex(),
|
||||
keyword: color_scheme.ramps.blue(0.5).hex(),
|
||||
emphasis: theme.ramps.blue(0.5).hex(),
|
||||
string: theme.ramps.orange(0.5).hex(),
|
||||
function: theme.ramps.yellow(0.5).hex(),
|
||||
type: theme.ramps.cyan(0.5).hex(),
|
||||
constructor: theme.ramps.blue(0.5).hex(),
|
||||
variant: theme.ramps.blue(0.5).hex(),
|
||||
property: theme.ramps.blue(0.5).hex(),
|
||||
enum: theme.ramps.orange(0.5).hex(),
|
||||
operator: theme.ramps.orange(0.5).hex(),
|
||||
number: theme.ramps.green(0.5).hex(),
|
||||
boolean: theme.ramps.green(0.5).hex(),
|
||||
constant: theme.ramps.green(0.5).hex(),
|
||||
keyword: theme.ramps.blue(0.5).hex(),
|
||||
}
|
||||
|
||||
// Then assign colors and use Syntax to enforce each style getting it's own color
|
||||
@@ -211,11 +212,11 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
weight: font_weights.bold,
|
||||
},
|
||||
link_uri: {
|
||||
color: color_scheme.ramps.green(0.5).hex(),
|
||||
color: theme.ramps.green(0.5).hex(),
|
||||
underline: true,
|
||||
},
|
||||
link_text: {
|
||||
color: color_scheme.ramps.orange(0.5).hex(),
|
||||
color: theme.ramps.orange(0.5).hex(),
|
||||
italic: true,
|
||||
},
|
||||
"text.literal": {
|
||||
@@ -231,7 +232,7 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
color: color.punctuation,
|
||||
},
|
||||
"punctuation.special": {
|
||||
color: color_scheme.ramps.neutral(0.86).hex(),
|
||||
color: theme.ramps.neutral(0.86).hex(),
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
color: color.punctuation,
|
||||
@@ -252,10 +253,10 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
color: color.string,
|
||||
},
|
||||
constructor: {
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
color: theme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
variant: {
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
color: theme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
type: {
|
||||
color: color.type,
|
||||
@@ -264,16 +265,16 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
color: color.primary,
|
||||
},
|
||||
label: {
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
color: theme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
tag: {
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
color: theme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
attribute: {
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
color: theme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
property: {
|
||||
color: color_scheme.ramps.blue(0.5).hex(),
|
||||
color: theme.ramps.blue(0.5).hex(),
|
||||
},
|
||||
constant: {
|
||||
color: color.constant,
|
||||
@@ -307,17 +308,18 @@ function build_default_syntax(color_scheme: ColorScheme): Syntax {
|
||||
return default_syntax
|
||||
}
|
||||
|
||||
function merge_syntax(
|
||||
default_syntax: Syntax,
|
||||
color_scheme: ColorScheme
|
||||
): Syntax {
|
||||
if (!color_scheme.syntax) {
|
||||
export function build_syntax(): Syntax {
|
||||
const theme = useTheme()
|
||||
|
||||
const default_syntax: Syntax = build_default_syntax()
|
||||
|
||||
if (!theme.syntax) {
|
||||
return default_syntax
|
||||
}
|
||||
|
||||
return deepmerge<Syntax, Partial<ThemeSyntax>>(
|
||||
const syntax = deepmerge<Syntax, Partial<ThemeSyntax>>(
|
||||
default_syntax,
|
||||
color_scheme.syntax,
|
||||
theme.syntax,
|
||||
{
|
||||
arrayMerge: (destinationArray, sourceArray) => [
|
||||
...destinationArray,
|
||||
@@ -325,12 +327,6 @@ function merge_syntax(
|
||||
],
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export function build_syntax(color_scheme: ColorScheme): Syntax {
|
||||
const default_syntax: Syntax = build_default_syntax(color_scheme)
|
||||
|
||||
const syntax = merge_syntax(default_syntax, color_scheme)
|
||||
|
||||
return syntax
|
||||
}
|
||||
|
||||
@@ -66,35 +66,10 @@ type ThemeConfigProperties = ThemeMeta & {
|
||||
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<Syntax>
|
||||
|
||||
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",
|
||||
@@ -104,45 +79,3 @@ export enum ThemeLicenseType {
|
||||
MIT = "MIT",
|
||||
Apache2 = "Apache License 2.0",
|
||||
}
|
||||
|
||||
export type ThemeFamilyItem =
|
||||
| ThemeConfig
|
||||
| { light: ThemeConfig; dark: ThemeConfig }
|
||||
|
||||
type ThemeFamilyProperties = Partial<Omit<ThemeMeta, "name" | "appearance">> & {
|
||||
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<string, ThemeFamily | ThemeConfig>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SingleColorToken } from "@tokens-studio/types"
|
||||
import { Layer, Style, StyleSet } from "../color_scheme"
|
||||
import { Layer, Style, StyleSet } from "../create_theme"
|
||||
import { color_token } from "./token"
|
||||
|
||||
interface StyleToken {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { SingleColorToken } from "@tokens-studio/types"
|
||||
import { color_token } from "./token"
|
||||
import { ColorScheme, Players } from "../color_scheme"
|
||||
import { Players } from "../create_theme"
|
||||
import { useTheme } from "../../../src/common"
|
||||
|
||||
export type PlayerToken = Record<"selection" | "cursor", SingleColorToken>
|
||||
|
||||
export type PlayersToken = Record<keyof Players, PlayerToken>
|
||||
|
||||
function build_player_token(theme: ColorScheme, index: number): PlayerToken {
|
||||
function build_player_token(index: number): PlayerToken {
|
||||
const theme = useTheme()
|
||||
const player_number = index.toString() as keyof Players
|
||||
|
||||
return {
|
||||
@@ -21,13 +23,15 @@ function build_player_token(theme: ColorScheme, index: number): PlayerToken {
|
||||
}
|
||||
}
|
||||
|
||||
export const players_token = (theme: ColorScheme): PlayersToken => ({
|
||||
"0": build_player_token(theme, 0),
|
||||
"1": build_player_token(theme, 1),
|
||||
"2": build_player_token(theme, 2),
|
||||
"3": build_player_token(theme, 3),
|
||||
"4": build_player_token(theme, 4),
|
||||
"5": build_player_token(theme, 5),
|
||||
"6": build_player_token(theme, 6),
|
||||
"7": build_player_token(theme, 7),
|
||||
})
|
||||
export const players_token = (): PlayersToken => {
|
||||
return {
|
||||
"0": build_player_token(0),
|
||||
"1": build_player_token(1),
|
||||
"2": build_player_token(2),
|
||||
"3": build_player_token(3),
|
||||
"4": build_player_token(4),
|
||||
"5": build_player_token(5),
|
||||
"6": build_player_token(6),
|
||||
"7": build_player_token(7),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,18 @@ import {
|
||||
TokenTypes,
|
||||
} from "@tokens-studio/types"
|
||||
import {
|
||||
ColorScheme,
|
||||
Shadow,
|
||||
SyntaxHighlightStyle,
|
||||
ThemeSyntax,
|
||||
} from "../color_scheme"
|
||||
} 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 ColorSchemeTokens {
|
||||
interface ThemeTokens {
|
||||
name: SingleOtherToken
|
||||
appearance: SingleOtherToken
|
||||
lowest: LayerToken
|
||||
@@ -39,12 +39,14 @@ const create_shadow_token = (
|
||||
}
|
||||
}
|
||||
|
||||
const popover_shadow_token = (theme: ColorScheme): SingleBoxShadowToken => {
|
||||
const popover_shadow_token = (): SingleBoxShadowToken => {
|
||||
const theme = useTheme()
|
||||
const shadow = theme.popover_shadow
|
||||
return create_shadow_token(shadow, "popover_shadow")
|
||||
}
|
||||
|
||||
const modal_shadow_token = (theme: ColorScheme): SingleBoxShadowToken => {
|
||||
const modal_shadow_token = (): SingleBoxShadowToken => {
|
||||
const theme = useTheme()
|
||||
const shadow = theme.modal_shadow
|
||||
return create_shadow_token(shadow, "modal_shadow")
|
||||
}
|
||||
@@ -68,13 +70,15 @@ function syntax_highlight_style_color_tokens(
|
||||
}, {} as ThemeSyntaxColorTokens)
|
||||
}
|
||||
|
||||
const syntax_tokens = (theme: ColorScheme): ColorSchemeTokens["syntax"] => {
|
||||
const syntax = editor(theme).syntax
|
||||
const syntax_tokens = (): ThemeTokens["syntax"] => {
|
||||
const syntax = editor().syntax
|
||||
|
||||
return syntax_highlight_style_color_tokens(syntax)
|
||||
}
|
||||
|
||||
export function theme_tokens(theme: ColorScheme): ColorSchemeTokens {
|
||||
export function theme_tokens(): ThemeTokens {
|
||||
const theme = useTheme()
|
||||
|
||||
return {
|
||||
name: {
|
||||
name: "themeName",
|
||||
@@ -89,9 +93,9 @@ export function theme_tokens(theme: ColorScheme): ColorSchemeTokens {
|
||||
lowest: layer_token(theme.lowest, "lowest"),
|
||||
middle: layer_token(theme.middle, "middle"),
|
||||
highest: layer_token(theme.highest, "highest"),
|
||||
popover_shadow: popover_shadow_token(theme),
|
||||
modal_shadow: modal_shadow_token(theme),
|
||||
players: players_token(theme),
|
||||
syntax: syntax_tokens(theme),
|
||||
popover_shadow: popover_shadow_token(),
|
||||
modal_shadow: modal_shadow_token(),
|
||||
players: players_token(),
|
||||
syntax: syntax_tokens(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user