Files
oak-gpui/styles/src/themes/base16.ts
T
2022-05-11 12:35:00 -04:00

243 lines
6.1 KiB
TypeScript

import { ColorToken, fontWeights, NumberToken } from "../tokens";
import { withOpacity } from "../utils/color";
import Theme, { buildPlayer, Syntax } from "./theme";
export interface Accents {
"red": ColorToken,
"orange": ColorToken,
"yellow": ColorToken,
"green": ColorToken,
"cyan": ColorToken,
"blue": ColorToken,
"violet": ColorToken,
"magenta": ColorToken,
}
export function createTheme(name: string, isLight: boolean, neutral: ColorToken[], accent: Accents): Theme {
if (isLight) {
neutral = [...neutral].reverse();
}
let blend = isLight ? 0.12 : 0.24;
const backgroundColor = {
100: {
base: neutral[1],
hovered: withOpacity(neutral[2], blend),
active: withOpacity(neutral[2], blend * 1.5),
focused: withOpacity(neutral[2], blend),
},
300: {
base: neutral[1],
hovered: withOpacity(neutral[2], blend),
active: withOpacity(neutral[2], blend * 1.5),
focused: withOpacity(neutral[2], blend),
},
500: {
base: neutral[0],
hovered: withOpacity(neutral[1], blend),
active: withOpacity(neutral[1], blend * 1.5),
focused: withOpacity(neutral[1], blend),
},
on300: {
base: neutral[0],
hovered: withOpacity(neutral[1], blend),
active: withOpacity(neutral[1], blend * 2),
focused: withOpacity(neutral[1], blend),
},
on500: {
base: neutral[1],
hovered: withOpacity(neutral[2], blend),
active: withOpacity(neutral[2], blend * 2),
focused: withOpacity(neutral[2], blend),
},
ok: {
base: withOpacity(accent.green, 0.15),
hovered: withOpacity(accent.green, 0.20),
active: withOpacity(accent.green, 0.25),
focused: withOpacity(accent.green, 0.20),
},
error: {
base: withOpacity(accent.red, 0.15),
hovered: withOpacity(accent.red, 0.20),
active: withOpacity(accent.red, 0.25),
focused: withOpacity(accent.red, 0.20),
},
warning: {
base: withOpacity(accent.yellow, 0.15),
hovered: withOpacity(accent.yellow, 0.20),
active: withOpacity(accent.yellow, 0.25),
focused: withOpacity(accent.yellow, 0.20),
},
info: {
base: withOpacity(accent.blue, 0.15),
hovered: withOpacity(accent.blue, 0.20),
active: withOpacity(accent.blue, 0.25),
focused: withOpacity(accent.blue, 0.20),
},
};
const borderColor = {
primary: neutral[0],
secondary: neutral[1],
muted: neutral[3],
focused: neutral[3],
active: neutral[3],
onMedia: withOpacity(neutral[0], 0.1),
ok: withOpacity(accent.green, 0.15),
error: withOpacity(accent.red, 0.15),
warning: withOpacity(accent.yellow, 0.15),
info: withOpacity(accent.blue, 0.15),
};
const textColor = {
primary: neutral[6],
secondary: neutral[5],
muted: neutral[5],
placeholder: neutral[4],
active: neutral[7],
feature: accent.blue,
ok: accent.green,
error: accent.red,
warning: accent.yellow,
info: accent.blue,
};
const player = {
1: buildPlayer(accent.blue),
2: buildPlayer(accent.green),
3: buildPlayer(accent.magenta),
4: buildPlayer(accent.orange),
5: buildPlayer(accent.violet),
6: buildPlayer(accent.cyan),
7: buildPlayer(accent.red),
8: buildPlayer(accent.yellow),
};
const editor = {
background: backgroundColor[500].base,
indent_guide: borderColor.muted,
indent_guide_active: borderColor.secondary,
line: {
active: withOpacity(neutral[7], 0.07),
highlighted: withOpacity(neutral[7], 0.12),
inserted: backgroundColor.ok.active,
deleted: backgroundColor.error.active,
modified: backgroundColor.info.active,
},
highlight: {
selection: player[1].selectionColor,
occurrence: withOpacity(neutral[7], blend / 2),
activeOccurrence: withOpacity(neutral[7], blend),
matchingBracket: backgroundColor[500].active,
match: withOpacity(accent.violet, blend * 2),
activeMatch: withOpacity(accent.violet, blend * 3),
related: backgroundColor[500].focused,
},
gutter: {
primary: textColor.placeholder,
active: textColor.active,
},
};
const syntax: Syntax = {
primary: {
color: neutral[7],
weight: fontWeights.normal,
},
comment: {
color: neutral[5],
weight: fontWeights.normal,
},
punctuation: {
color: neutral[5],
weight: fontWeights.normal,
},
constant: {
color: neutral[4],
weight: fontWeights.normal,
},
keyword: {
color: accent.blue,
weight: fontWeights.normal,
},
function: {
color: accent.yellow,
weight: fontWeights.normal,
},
type: {
color: accent.cyan,
weight: fontWeights.normal,
},
variant: {
color: accent.blue,
weight: fontWeights.normal,
},
property: {
color: accent.blue,
weight: fontWeights.normal,
},
enum: {
color: accent.orange,
weight: fontWeights.normal,
},
operator: {
color: accent.orange,
weight: fontWeights.normal,
},
string: {
color: accent.orange,
weight: fontWeights.normal,
},
number: {
color: accent.green,
weight: fontWeights.normal,
},
boolean: {
color: accent.green,
weight: fontWeights.normal,
},
predictive: {
color: textColor.muted,
weight: fontWeights.normal,
},
title: {
color: accent.yellow,
weight: fontWeights.bold,
},
emphasis: {
color: textColor.feature,
weight: fontWeights.normal,
},
"emphasis.strong": {
color: textColor.feature,
weight: fontWeights.bold,
},
linkUri: {
color: accent.green,
weight: fontWeights.normal,
underline: true,
},
linkText: {
color: accent.orange,
weight: fontWeights.normal,
italic: true,
},
};
const shadowAlpha: NumberToken = {
value: blend,
type: "number",
};
return {
name,
backgroundColor,
borderColor,
textColor,
iconColor: textColor,
editor,
syntax,
player,
shadowAlpha,
};
}