Use new theme vars (#63)

This PR swaps the theme to use the new stuff from the Theme Studio
This commit is contained in:
Gregory Schier
2024-08-13 07:44:28 -07:00
committed by GitHub
parent a0950ce5b8
commit b5242b9a3f
79 changed files with 1113 additions and 1004 deletions

View File

@@ -1,5 +1,6 @@
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import type { Appearance } from './window';
type Appearance = 'light' | 'dark';
export function getCSSAppearance(): Appearance {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';

View File

@@ -1,94 +0,0 @@
import parseColor from 'parse-color';
export class Color {
private theme: 'dark' | 'light' = 'light';
private hue: number = 0;
private saturation: number = 0;
private lightness: number = 0;
private alpha: number = 1;
constructor(cssColor: string, theme: 'dark' | 'light') {
try {
const { hsla } = parseColor(cssColor || '');
this.hue = hsla[0];
this.saturation = hsla[1];
this.lightness = hsla[2];
this.alpha = hsla[3] ?? 1;
this.theme = theme;
} catch (err) {
console.log('Failed to parse CSS color', cssColor, err);
}
}
static transparent(): Color {
return new Color('rgb(0,0,0)', 'light').translucify(1);
}
static white(): Color {
return new Color('rgb(0,0,0)', 'light').lower(1);
}
static black(): Color {
return new Color('rgb(0,0,0)', 'light').lift(1);
}
private clone(): Color {
return new Color(this.css(), this.theme);
}
lower(mod: number): Color {
return this.theme === 'dark' ? this._darken(mod) : this._lighten(mod);
}
lift(mod: number): Color {
return this.theme === 'dark' ? this._lighten(mod) : this._darken(mod);
}
translucify(mod: number): Color {
const c = this.clone();
c.alpha = c.alpha - c.alpha * mod;
return c;
}
desaturate(mod: number): Color {
const c = this.clone();
c.saturation = c.saturation - c.saturation * mod;
return c;
}
saturate(mod: number): Color {
const c = this.clone();
c.saturation = this.saturation + (100 - this.saturation) * mod;
return c;
}
lighterThan(c: Color): boolean {
return this.lightness > c.lightness;
}
css(): string {
// If opacity is 1, allow for Tailwind modification
const h = Math.round(this.hue);
const s = Math.round(this.saturation);
const l = Math.round(this.lightness);
const a = Math.round(this.alpha * 100) / 100;
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
}
hex(): string {
return parseColor(this.css()).hex;
}
private _lighten(mod: number): Color {
const c = this.clone();
c.lightness = this.lightness + (100 - this.lightness) * mod;
return c;
}
private _darken(mod: number): Color {
const c = this.clone();
c.lightness = this.lightness - this.lightness * mod;
return c;
}
}

View File

@@ -1,9 +1,8 @@
import { catppuccin } from './themes/catppuccin';
import { dracula } from './themes/dracula';
import { github } from './themes/github';
import { hotdogStand } from './themes/hotdog-stand';
import { monokaiPro } from './themes/monokai-pro';
import { moonlight } from './themes/moonlight';
import { relaxing } from './themes/relaxing';
import { rosePine } from './themes/rose-pine';
import { yaak, yaakDark, yaakLight } from './themes/yaak';
@@ -13,10 +12,9 @@ export const defaultLightTheme = yaakLight;
export const yaakThemes = [
...yaak,
...catppuccin,
...relaxing,
...rosePine,
...monokaiPro,
...github,
...moonlight,
...dracula,
...monokaiPro,
...hotdogStand,
];

View File

@@ -1,32 +1,28 @@
import { Color } from '../color';
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
export const catppuccinLatte: YaakTheme = {
name: 'Catppuccin Latte',
id: 'catppuccin-latte',
background: new Color('#eff1f5', 'light'),
foreground: new Color('#4c4f69', 'dark'),
foregroundSubtle: new Color('#6c6f85', 'light'),
foregroundSubtler: new Color('#8c8fa1', 'light'),
colors: {
primary: new Color('#8839ef', 'light'),
secondary: new Color('#6c6f85', 'light'),
info: new Color('#7287fd', 'light'),
success: new Color('#179299', 'light'),
notice: new Color('#df8e1d', 'light'),
warning: new Color('#fe640b', 'light'),
danger: new Color('#e64553', 'light'),
},
surface: new YaakColor('#eff1f5', 'light'),
text: new YaakColor('#4c4f69', 'dark'),
textSubtle: new YaakColor('#6c6f85', 'light'),
textSubtlest: new YaakColor('#8c8fa1', 'light'),
primary: new YaakColor('#8839ef', 'light'),
secondary: new YaakColor('#6c6f85', 'light'),
info: new YaakColor('#7287fd', 'light'),
success: new YaakColor('#179299', 'light'),
notice: new YaakColor('#df8e1d', 'light'),
warning: new YaakColor('#fe640b', 'light'),
danger: new YaakColor('#e64553', 'light'),
components: {
sidebar: {
background: new Color('#e6e9ef', 'light'),
backgroundHighlight: new Color('#e6e9ef', 'light').lift(0.05),
foregroundSubtler: new Color('#7287fd', 'light'),
surface: new YaakColor('#e6e9ef', 'light'),
border: new YaakColor('#e6e9ef', 'light').lift(0.05),
},
appHeader: {
background: new Color('#dce0e8', 'light'),
backgroundHighlight: new Color('#e6e9ef', 'light').lift(0.05),
foregroundSubtler: new Color('#7287fd', 'light'),
surface: new YaakColor('#dce0e8', 'light'),
border: new YaakColor('#e6e9ef', 'light').lift(0.05),
},
},
};
@@ -34,45 +30,41 @@ export const catppuccinLatte: YaakTheme = {
export const catppuccinMacchiato: YaakTheme = {
name: 'Catppuccin Macchiato',
id: 'catppuccin-macchiato',
background: new Color('#1e2030', 'dark'),
foreground: new Color('#cad3f5', 'dark'),
foregroundSubtle: new Color('#a5adcb', 'dark'),
foregroundSubtler: new Color('#8087a2', 'dark'),
colors: {
primary: new Color('#c6a0f6', 'dark'),
secondary: new Color('#b8c0e0', 'dark'),
info: new Color('#8aadf4', 'dark'),
success: new Color('#a6da95', 'dark'),
notice: new Color('#eed49f', 'dark'),
warning: new Color('#f5a97f', 'dark'),
danger: new Color('#ed8796', 'dark'),
},
surface: new YaakColor('#1e2030', 'dark'),
text: new YaakColor('#cad3f5', 'dark'),
textSubtle: new YaakColor('#a5adcb', 'dark'),
textSubtlest: new YaakColor('#8087a2', 'dark'),
primary: new YaakColor('#c6a0f6', 'dark'),
secondary: new YaakColor('#b8c0e0', 'dark'),
info: new YaakColor('#8aadf4', 'dark'),
success: new YaakColor('#a6da95', 'dark'),
notice: new YaakColor('#eed49f', 'dark'),
warning: new YaakColor('#f5a97f', 'dark'),
danger: new YaakColor('#ed8796', 'dark'),
components: {
dialog: {
background: new Color('#181825', 'dark'),
surface: new YaakColor('#181825', 'dark'),
},
sidebar: {
background: new Color('#24273a', 'dark'),
backgroundHighlight: new Color('#24273a', 'dark').lift(0.05),
surface: new YaakColor('#24273a', 'dark'),
border: new YaakColor('#24273a', 'dark').lift(0.05),
},
appHeader: {
background: new Color('#181926', 'dark'),
backgroundHighlight: new Color('#181926', 'dark').lift(0.1),
surface: new YaakColor('#181926', 'dark'),
border: new YaakColor('#181926', 'dark').lift(0.1),
},
responsePane: {
background: new Color('#24273a', 'dark'),
backgroundHighlight: new Color('#24273a', 'dark').lift(0.05),
surface: new YaakColor('#24273a', 'dark'),
border: new YaakColor('#24273a', 'dark').lift(0.05),
},
button: {
colors: {
primary: new Color('#c6a0f6', 'dark').lower(0.1),
secondary: new Color('#b8c0e0', 'dark').lower(0.1),
info: new Color('#8aadf4', 'dark').lower(0.1),
success: new Color('#a6da95', 'dark').lower(0.1),
notice: new Color('#eed49f', 'dark').lower(0.1),
warning: new Color('#f5a97f', 'dark').lower(0.1),
danger: new Color('#ed8796', 'dark').lower(0.1),
},
primary: new YaakColor('#c6a0f6', 'dark').lower(0.1),
secondary: new YaakColor('#b8c0e0', 'dark').lower(0.1),
info: new YaakColor('#8aadf4', 'dark').lower(0.1),
success: new YaakColor('#a6da95', 'dark').lower(0.1),
notice: new YaakColor('#eed49f', 'dark').lower(0.1),
warning: new YaakColor('#f5a97f', 'dark').lower(0.1),
danger: new YaakColor('#ed8796', 'dark').lower(0.1),
},
},
};
@@ -80,45 +72,41 @@ export const catppuccinMacchiato: YaakTheme = {
export const catppuccinFrappe: YaakTheme = {
name: 'Catppuccin Frappé',
id: 'catppuccin-frappe',
background: new Color('#292c3c', 'dark'),
foreground: new Color('#c6d0f5', 'dark'),
foregroundSubtle: new Color('#a5adce', 'dark'),
foregroundSubtler: new Color('#838ba7', 'dark'),
colors: {
primary: new Color('#ca9ee6', 'dark'),
secondary: new Color('#b8c0e0', 'dark'),
info: new Color('#8caaee', 'dark'),
success: new Color('#a6d189', 'dark'),
notice: new Color('#e5c890', 'dark'),
warning: new Color('#ef9f76', 'dark'),
danger: new Color('#e78284', 'dark'),
},
surface: new YaakColor('#292c3c', 'dark'),
text: new YaakColor('#c6d0f5', 'dark'),
textSubtle: new YaakColor('#a5adce', 'dark'),
textSubtlest: new YaakColor('#838ba7', 'dark'),
primary: new YaakColor('#ca9ee6', 'dark'),
secondary: new YaakColor('#b8c0e0', 'dark'),
info: new YaakColor('#8caaee', 'dark'),
success: new YaakColor('#a6d189', 'dark'),
notice: new YaakColor('#e5c890', 'dark'),
warning: new YaakColor('#ef9f76', 'dark'),
danger: new YaakColor('#e78284', 'dark'),
components: {
dialog: {
background: new Color('#181825', 'dark'),
surface: new YaakColor('#181825', 'dark'),
},
sidebar: {
background: new Color('#303446', 'dark'),
backgroundHighlight: new Color('#303446', 'dark').lift(0.05),
surface: new YaakColor('#303446', 'dark'),
border: new YaakColor('#303446', 'dark').lift(0.05),
},
appHeader: {
background: new Color('#232634', 'dark'),
backgroundHighlight: new Color('#232634', 'dark').lift(0.1),
surface: new YaakColor('#232634', 'dark'),
border: new YaakColor('#232634', 'dark').lift(0.1),
},
responsePane: {
background: new Color('#303446', 'dark'),
backgroundHighlight: new Color('#303446', 'dark').lift(0.05),
surface: new YaakColor('#303446', 'dark'),
border: new YaakColor('#303446', 'dark').lift(0.05),
},
button: {
colors: {
primary: new Color('#ca9ee6', 'dark').lower(0.1),
secondary: new Color('#b8c0e0', 'dark').lower(0.1),
info: new Color('#8caaee', 'dark').lower(0.1),
success: new Color('#a6d189', 'dark').lower(0.1),
notice: new Color('#e5c890', 'dark').lower(0.1),
warning: new Color('#ef9f76', 'dark').lower(0.1),
danger: new Color('#e78284', 'dark').lower(0.1),
},
primary: new YaakColor('#ca9ee6', 'dark').lower(0.1),
secondary: new YaakColor('#b8c0e0', 'dark').lower(0.1),
info: new YaakColor('#8caaee', 'dark').lower(0.1),
success: new YaakColor('#a6d189', 'dark').lower(0.1),
notice: new YaakColor('#e5c890', 'dark').lower(0.1),
warning: new YaakColor('#ef9f76', 'dark').lower(0.1),
danger: new YaakColor('#e78284', 'dark').lower(0.1),
},
},
};
@@ -126,45 +114,41 @@ export const catppuccinFrappe: YaakTheme = {
const catppuccinMocha: YaakTheme = {
name: 'Catppuccin Mocha',
id: 'catppuccin-mocha',
background: new Color('#181825', 'dark'),
foreground: new Color('#cdd6f4', 'dark'),
foregroundSubtle: new Color('#a6adc8', 'dark'),
foregroundSubtler: new Color('#7f849c', 'dark'),
colors: {
primary: new Color('#c6a0f6', 'dark'),
secondary: new Color('#bac2de', 'dark'),
info: new Color('#89b4fa', 'dark'),
success: new Color('#a6e3a1', 'dark'),
notice: new Color('#f9e2af', 'dark'),
warning: new Color('#fab387', 'dark'),
danger: new Color('#f38ba8', 'dark'),
},
surface: new YaakColor('#181825', 'dark'),
text: new YaakColor('#cdd6f4', 'dark'),
textSubtle: new YaakColor('#a6adc8', 'dark'),
textSubtlest: new YaakColor('#7f849c', 'dark'),
primary: new YaakColor('#c6a0f6', 'dark'),
secondary: new YaakColor('#bac2de', 'dark'),
info: new YaakColor('#89b4fa', 'dark'),
success: new YaakColor('#a6e3a1', 'dark'),
notice: new YaakColor('#f9e2af', 'dark'),
warning: new YaakColor('#fab387', 'dark'),
danger: new YaakColor('#f38ba8', 'dark'),
components: {
dialog: {
background: new Color('#181825', 'dark'),
surface: new YaakColor('#181825', 'dark'),
},
sidebar: {
background: new Color('#1e1e2e', 'dark'),
backgroundHighlight: new Color('#1e1e2e', 'dark').lift(0.05),
surface: new YaakColor('#1e1e2e', 'dark'),
border: new YaakColor('#1e1e2e', 'dark').lift(0.05),
},
appHeader: {
background: new Color('#11111b', 'dark'),
backgroundHighlight: new Color('#11111b', 'dark').lift(0.1),
surface: new YaakColor('#11111b', 'dark'),
border: new YaakColor('#11111b', 'dark').lift(0.1),
},
responsePane: {
background: new Color('#1e1e2e', 'dark'),
backgroundHighlight: new Color('#1e1e2e', 'dark').lift(0.05),
surface: new YaakColor('#1e1e2e', 'dark'),
border: new YaakColor('#1e1e2e', 'dark').lift(0.05),
},
button: {
colors: {
primary: new Color('#cba6f7', 'dark').lower(0.2).desaturate(0.2),
secondary: new Color('#bac2de', 'dark').lower(0.2).desaturate(0.2),
info: new Color('#89b4fa', 'dark').lower(0.2).desaturate(0.2),
success: new Color('#a6e3a1', 'dark').lower(0.2).desaturate(0.2),
notice: new Color('#f9e2af', 'dark').lower(0.2).desaturate(0.2),
warning: new Color('#fab387', 'dark').lower(0.2).desaturate(0.2),
danger: new Color('#f38ba8', 'dark').lower(0.2).desaturate(0.2),
},
primary: new YaakColor('#cba6f7', 'dark').lower(0.2).desaturate(0.2),
secondary: new YaakColor('#bac2de', 'dark').lower(0.2).desaturate(0.2),
info: new YaakColor('#89b4fa', 'dark').lower(0.2).desaturate(0.2),
success: new YaakColor('#a6e3a1', 'dark').lower(0.2).desaturate(0.2),
notice: new YaakColor('#f9e2af', 'dark').lower(0.2).desaturate(0.2),
warning: new YaakColor('#fab387', 'dark').lower(0.2).desaturate(0.2),
danger: new YaakColor('#f38ba8', 'dark').lower(0.2).desaturate(0.2),
},
},
};

View File

@@ -1,30 +1,27 @@
import { Color } from '../color';
import type { YaakTheme } from '../window';
import { YaakColor } from '../yaakColor';
const draculaDefault: YaakTheme = {
id: 'dracula',
name: 'Dracula',
background: new Color('#282A36', 'dark'),
backgroundHighlight: new Color('#343746', 'dark'),
backgroundHighlightSecondary: new Color('#424450', 'dark'),
foreground: new Color('#F8F8F2', 'dark'),
foregroundSubtle: new Color('hsl(232,14%,65%)', 'dark'),
foregroundSubtler: new Color('hsl(232,14%,50%)', 'dark'),
colors: {
primary: new Color('#BD93F9', 'dark'),
secondary: new Color('#6272A4', 'dark'),
info: new Color('#8BE9FD', 'dark'),
success: new Color('#50FA7B', 'dark'),
notice: new Color('#F1FA8C', 'dark'),
warning: new Color('#FFB86C', 'dark'),
danger: new Color('#FF5555', 'dark'),
},
surface: new YaakColor('#282A36', 'dark'),
surfaceHighlight: new YaakColor('#343746', 'dark'),
text: new YaakColor('#F8F8F2', 'dark'),
textSubtle: new YaakColor('hsl(232,14%,65%)', 'dark'),
textSubtlest: new YaakColor('hsl(232,14%,50%)', 'dark'),
primary: new YaakColor('#BD93F9', 'dark'),
secondary: new YaakColor('#6272A4', 'dark'),
info: new YaakColor('#8BE9FD', 'dark'),
success: new YaakColor('#50FA7B', 'dark'),
notice: new YaakColor('#F1FA8C', 'dark'),
warning: new YaakColor('#FFB86C', 'dark'),
danger: new YaakColor('#FF5555', 'dark'),
components: {
sidebar: {
background: new Color('hsl(230,15%,24%)', 'dark'),
backdrop: new YaakColor('hsl(230,15%,24%)', 'dark'),
},
appHeader: {
background: new Color('#21222C', 'dark'),
backdrop: new YaakColor('#21222C', 'dark'),
},
},
};

View File

@@ -1,57 +1,52 @@
import { Color } from '../color';
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
const githubDark: YaakTheme = {
id: 'github-dark',
name: 'GitHub Dark',
background: new Color('#0d1218', 'dark'),
backgroundHighlight: new Color('#171c23', 'dark'),
backgroundHighlightSecondary: new Color('#1c2127', 'dark'),
foreground: new Color('#dce3eb', 'dark'),
foregroundSubtle: new Color('#88919b', 'dark'),
foregroundSubtler: new Color('#6b727d', 'dark'),
colors: {
primary: new Color('#a579ef', 'dark').lift(0.1),
secondary: new Color('#6b727d', 'dark').lift(0.1),
info: new Color('#458def', 'dark').lift(0.1),
success: new Color('#3eb24f', 'dark').lift(0.1),
notice: new Color('#dca132', 'dark').lift(0.1),
warning: new Color('#ec7934', 'dark').lift(0.1),
danger: new Color('#ee5049', 'dark').lift(0.1),
},
name: 'GitHub',
surface: new YaakColor('#0d1218', 'dark'),
border: new YaakColor('#171c23', 'dark'),
surfaceHighlight: new YaakColor('#1c2127', 'dark'),
text: new YaakColor('#dce3eb', 'dark'),
textSubtle: new YaakColor('#88919b', 'dark'),
textSubtlest: new YaakColor('#6b727d', 'dark'),
primary: new YaakColor('#a579ef', 'dark').lift(0.1),
secondary: new YaakColor('#6b727d', 'dark').lift(0.1),
info: new YaakColor('#458def', 'dark').lift(0.1),
success: new YaakColor('#3eb24f', 'dark').lift(0.1),
notice: new YaakColor('#dca132', 'dark').lift(0.1),
warning: new YaakColor('#ec7934', 'dark').lift(0.1),
danger: new YaakColor('#ee5049', 'dark').lift(0.1),
components: {
button: {
colors: {
primary: new Color('#a579ef', 'dark'),
secondary: new Color('#6b727d', 'dark'),
info: new Color('#458def', 'dark'),
success: new Color('#3eb24f', 'dark'),
notice: new Color('#dca132', 'dark'),
warning: new Color('#ec7934', 'dark'),
danger: new Color('#ee5049', 'dark'),
},
primary: new YaakColor('#a579ef', 'dark'),
secondary: new YaakColor('#6b727d', 'dark'),
info: new YaakColor('#458def', 'dark'),
success: new YaakColor('#3eb24f', 'dark'),
notice: new YaakColor('#dca132', 'dark'),
warning: new YaakColor('#ec7934', 'dark'),
danger: new YaakColor('#ee5049', 'dark'),
},
},
};
export const githubLight: YaakTheme = {
id: 'github-light',
name: 'GitHub Light',
background: new Color('#ffffff', 'light'),
backgroundHighlight: new Color('hsl(210,15%,92%)', 'light'),
backgroundHighlightSecondary: new Color('hsl(210,29%,94%)', 'light'),
foreground: new Color('#1f2328', 'light'),
foregroundSubtle: new Color('#636c76', 'light'),
foregroundSubtler: new Color('#828d94', 'light'),
colors: {
primary: new Color('#8250df', 'light'),
secondary: new Color('#6e7781', 'light'),
info: new Color('hsl(212,92%,48%)', 'light'),
success: new Color('hsl(137,66%,32%)', 'light'),
notice: new Color('hsl(40,100%,40%)', 'light'),
warning: new Color('hsl(24,100%,44%)', 'light'),
danger: new Color('#d1242f', 'light'),
},
name: 'GitHub',
surface: new YaakColor('#ffffff', 'light'),
surfaceHighlight: new YaakColor('hsl(210,29%,94%)', 'light'),
border: new YaakColor('hsl(210,15%,92%)', 'light'),
borderSubtle: new YaakColor('hsl(210,15%,92%)', 'light'),
text: new YaakColor('#1f2328', 'light'),
textSubtle: new YaakColor('#636c76', 'light'),
textSubtlest: new YaakColor('#828d94', 'light'),
primary: new YaakColor('#8250df', 'light'),
secondary: new YaakColor('#6e7781', 'light'),
info: new YaakColor('hsl(212,92%,48%)', 'light'),
success: new YaakColor('hsl(137,66%,32%)', 'light'),
notice: new YaakColor('hsl(40,100%,40%)', 'light'),
warning: new YaakColor('hsl(24,100%,44%)', 'light'),
danger: new YaakColor('#d1242f', 'light'),
};
export const github = [githubDark, githubLight];

View File

@@ -1,59 +1,56 @@
import { Color } from '../color';
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
export const hotdogStandDefault: YaakTheme = {
id: 'hotdog-stand',
name: 'Hotdog Stand',
background: new Color('#ff0000', 'dark'),
backgroundHighlight: new Color('#000000', 'dark'),
backgroundHighlightSecondary: new Color('#000000', 'dark'),
foreground: new Color('#ffffff', 'dark'),
foregroundSubtle: new Color('#ffffff', 'dark'),
foregroundSubtler: new Color('#ffff00', 'dark'),
colors: {
primary: new Color('#ffff00', 'dark'),
secondary: new Color('#ffff00', 'dark'),
info: new Color('#ffff00', 'dark'),
notice: new Color('#ffff00', 'dark'),
warning: new Color('#ffff00', 'dark'),
danger: new Color('#ffff00', 'dark'),
},
surface: new YaakColor('#ff0000', 'dark'),
border: new YaakColor('#000000', 'dark'),
surfaceHighlight: new YaakColor('#000000', 'dark'),
text: new YaakColor('#ffffff', 'dark'),
textSubtle: new YaakColor('#ffffff', 'dark'),
textSubtlest: new YaakColor('#ffff00', 'dark'),
primary: new YaakColor('#ffff00', 'dark'),
secondary: new YaakColor('#ffff00', 'dark'),
info: new YaakColor('#ffff00', 'dark'),
success: new YaakColor('#ffff00', 'dark'),
notice: new YaakColor('#ffff00', 'dark'),
warning: new YaakColor('#ffff00', 'dark'),
danger: new YaakColor('#ffff00', 'dark'),
components: {
appHeader: {
background: new Color('#000000', 'dark'),
foreground: new Color('#ffffff', 'dark'),
foregroundSubtle: new Color('#ffff00', 'dark'),
foregroundSubtler: new Color('#ff0000', 'dark'),
surface: new YaakColor('#000000', 'dark'),
text: new YaakColor('#ffffff', 'dark'),
textSubtle: new YaakColor('#ffff00', 'dark'),
textSubtlest: new YaakColor('#ff0000', 'dark'),
},
menu: {
background: new Color('#000000', 'dark'),
backgroundHighlight: new Color('#ff0000', 'dark'),
backgroundHighlightSecondary: new Color('#ff0000', 'dark'),
foreground: new Color('#ffffff', 'dark'),
foregroundSubtle: new Color('#ffff00', 'dark'),
foregroundSubtler: new Color('#ffff00', 'dark'),
surface: new YaakColor('#000000', 'dark'),
border: new YaakColor('#ff0000', 'dark'),
surfaceHighlight: new YaakColor('#ff0000', 'dark'),
text: new YaakColor('#ffffff', 'dark'),
textSubtle: new YaakColor('#ffff00', 'dark'),
textSubtlest: new YaakColor('#ffff00', 'dark'),
},
button: {
background: new Color('#000000', 'dark'),
foreground: new Color('#ffffff', 'dark'),
colors: {
primary: new Color('#000000', 'dark'),
secondary: new Color('#ffffff', 'dark'),
info: new Color('#000000', 'dark'),
notice: new Color('#ffff00', 'dark'),
warning: new Color('#000000', 'dark'),
danger: new Color('#ff0000', 'dark'),
},
surface: new YaakColor('#000000', 'dark'),
text: new YaakColor('#ffffff', 'dark'),
primary: new YaakColor('#000000', 'dark'),
secondary: new YaakColor('#ffffff', 'dark'),
info: new YaakColor('#000000', 'dark'),
success: new YaakColor('#ffff00', 'dark'),
notice: new YaakColor('#ffff00', 'dark'),
warning: new YaakColor('#000000', 'dark'),
danger: new YaakColor('#ff0000', 'dark'),
},
editor: {
colors: {
primary: new Color('#ffffff', 'dark'),
secondary: new Color('#ffffff', 'dark'),
info: new Color('#ffffff', 'dark'),
notice: new Color('#ffff00', 'dark'),
warning: new Color('#ffffff', 'dark'),
danger: new Color('#ffffff', 'dark'),
},
primary: new YaakColor('#ffffff', 'dark'),
secondary: new YaakColor('#ffffff', 'dark'),
info: new YaakColor('#ffffff', 'dark'),
success: new YaakColor('#ffffff', 'dark'),
notice: new YaakColor('#ffff00', 'dark'),
warning: new YaakColor('#ffffff', 'dark'),
danger: new YaakColor('#ffffff', 'dark'),
},
},
};

View File

@@ -1,41 +1,37 @@
import { Color } from '../color';
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
export const monokaiProDefault: YaakTheme = {
id: 'monokai-pro',
name: 'Monokai Pro',
background: new Color('#2d2a2e', 'dark'),
foreground: new Color('#fcfcfa', 'dark'),
foregroundSubtle: new Color('#c1c0c0', 'dark'),
foregroundSubtler: new Color('#939293', 'dark'),
surface: new YaakColor('#2d2a2e', 'dark'),
text: new YaakColor('#fcfcfa', 'dark'),
textSubtle: new YaakColor('#c1c0c0', 'dark'),
textSubtlest: new YaakColor('#939293', 'dark'),
colors: {
primary: new Color('#ab9df2', 'dark'),
secondary: new Color('#c1c0c0', 'dark'),
info: new Color('#78dce8', 'dark'),
success: new Color('#a9dc76', 'dark'),
notice: new Color('#ffd866', 'dark'),
warning: new Color('#fc9867', 'dark'),
danger: new Color('#ff6188', 'dark'),
},
primary: new YaakColor('#ab9df2', 'dark'),
secondary: new YaakColor('#c1c0c0', 'dark'),
info: new YaakColor('#78dce8', 'dark'),
success: new YaakColor('#a9dc76', 'dark'),
notice: new YaakColor('#ffd866', 'dark'),
warning: new YaakColor('#fc9867', 'dark'),
danger: new YaakColor('#ff6188', 'dark'),
components: {
appHeader: {
background: new Color('#221f22', 'dark'),
foreground: new Color('#c1c0c0', 'dark'),
foregroundSubtle: new Color('#939293', 'dark'),
foregroundSubtler: new Color('#727072', 'dark'),
surface: new YaakColor('#221f22', 'dark'),
text: new YaakColor('#c1c0c0', 'dark'),
textSubtle: new YaakColor('#939293', 'dark'),
textSubtlest: new YaakColor('#727072', 'dark'),
},
button: {
colors: {
primary: new Color('#ab9df2', 'dark').lower(0.1),
secondary: new Color('#c1c0c0', 'dark').lower(0.1),
info: new Color('#78dce8', 'dark').lower(0.1),
success: new Color('#a9dc76', 'dark').lower(0.1),
notice: new Color('#ffd866', 'dark').lower(0.1),
warning: new Color('#fc9867', 'dark').lower(0.1),
danger: new Color('#ff6188', 'dark').lower(0.1),
},
primary: new YaakColor('#ab9df2', 'dark').lower(0.1),
secondary: new YaakColor('#c1c0c0', 'dark').lower(0.1),
info: new YaakColor('#78dce8', 'dark').lower(0.1),
success: new YaakColor('#a9dc76', 'dark').lower(0.1),
notice: new YaakColor('#ffd866', 'dark').lower(0.1),
warning: new YaakColor('#fc9867', 'dark').lower(0.1),
danger: new YaakColor('#ff6188', 'dark').lower(0.1),
},
},
};
@@ -43,38 +39,34 @@ export const monokaiProDefault: YaakTheme = {
const monokaiProClassic: YaakTheme = {
id: 'monokai-pro-classic',
name: 'Monokai Pro Classic',
background: new Color('#272822', 'dark'),
foreground: new Color('#fdfff1', 'dark'),
foregroundSubtle: new Color('#c0c1b5', 'dark'),
foregroundSubtler: new Color('#919288', 'dark'),
surface: new YaakColor('#272822', 'dark'),
text: new YaakColor('#fdfff1', 'dark'),
textSubtle: new YaakColor('#c0c1b5', 'dark'),
textSubtlest: new YaakColor('#919288', 'dark'),
colors: {
primary: new Color('#ae81ff', 'dark'),
secondary: new Color('#b2b9bd', 'dark'),
info: new Color('#66d9ef', 'dark'),
success: new Color('#a6e22e', 'dark'),
notice: new Color('#e6db74', 'dark'),
warning: new Color('#fd971f', 'dark'),
danger: new Color('#f92672', 'dark'),
},
primary: new YaakColor('#ae81ff', 'dark'),
secondary: new YaakColor('#b2b9bd', 'dark'),
info: new YaakColor('#66d9ef', 'dark'),
success: new YaakColor('#a6e22e', 'dark'),
notice: new YaakColor('#e6db74', 'dark'),
warning: new YaakColor('#fd971f', 'dark'),
danger: new YaakColor('#f92672', 'dark'),
components: {
appHeader: {
background: new Color('#1d1e19', 'dark'),
foreground: new Color('#b2b9bd', 'dark'),
foregroundSubtle: new Color('#767b81', 'dark'),
foregroundSubtler: new Color('#696d77', 'dark'),
surface: new YaakColor('#1d1e19', 'dark'),
text: new YaakColor('#b2b9bd', 'dark'),
textSubtle: new YaakColor('#767b81', 'dark'),
textSubtlest: new YaakColor('#696d77', 'dark'),
},
button: {
colors: {
primary: new Color('#ae81ff', 'dark').lower(0.1),
secondary: new Color('#b2b9bd', 'dark').lower(0.1),
info: new Color('#66d9ef', 'dark').lower(0.1),
success: new Color('#a6e22e', 'dark').lower(0.1),
notice: new Color('#e6db74', 'dark').lower(0.1),
warning: new Color('#fd971f', 'dark').lower(0.1),
danger: new Color('#f92672', 'dark').lower(0.1),
},
primary: new YaakColor('#ae81ff', 'dark').lower(0.1),
secondary: new YaakColor('#b2b9bd', 'dark').lower(0.1),
info: new YaakColor('#66d9ef', 'dark').lower(0.1),
success: new YaakColor('#a6e22e', 'dark').lower(0.1),
notice: new YaakColor('#e6db74', 'dark').lower(0.1),
warning: new YaakColor('#fd971f', 'dark').lower(0.1),
danger: new YaakColor('#f92672', 'dark').lower(0.1),
},
},
};
@@ -82,38 +74,34 @@ const monokaiProClassic: YaakTheme = {
const monokaiProMachine: YaakTheme = {
id: 'monokai-pro-machine',
name: 'Monokai Pro Machine',
background: new Color('#273136', 'dark'),
foreground: new Color('#eaf2f1', 'dark'),
foregroundSubtle: new Color('#8b9798', 'dark'),
foregroundSubtler: new Color('#6b7678', 'dark'),
surface: new YaakColor('#273136', 'dark'),
text: new YaakColor('#eaf2f1', 'dark'),
textSubtle: new YaakColor('#8b9798', 'dark'),
textSubtlest: new YaakColor('#6b7678', 'dark'),
colors: {
primary: new Color('#baa0f8', 'dark'),
secondary: new Color('#b8c4c3', 'dark'),
info: new Color('#7cd5f1', 'dark'),
success: new Color('#a2e57b', 'dark'),
notice: new Color('#ffed72', 'dark'),
warning: new Color('#ffb270', 'dark'),
danger: new Color('#ff6d7e', 'dark'),
},
primary: new YaakColor('#baa0f8', 'dark'),
secondary: new YaakColor('#b8c4c3', 'dark'),
info: new YaakColor('#7cd5f1', 'dark'),
success: new YaakColor('#a2e57b', 'dark'),
notice: new YaakColor('#ffed72', 'dark'),
warning: new YaakColor('#ffb270', 'dark'),
danger: new YaakColor('#ff6d7e', 'dark'),
components: {
appHeader: {
background: new Color('#1d2528', 'dark'),
foreground: new Color('#b2b9bd', 'dark'),
foregroundSubtle: new Color('#767b81', 'dark'),
foregroundSubtler: new Color('#696d77', 'dark'),
surface: new YaakColor('#1d2528', 'dark'),
text: new YaakColor('#b2b9bd', 'dark'),
textSubtle: new YaakColor('#767b81', 'dark'),
textSubtlest: new YaakColor('#696d77', 'dark'),
},
button: {
colors: {
primary: new Color('#baa0f8', 'dark').lower(0.1),
secondary: new Color('#b8c4c3', 'dark').lower(0.1),
info: new Color('#7cd5f1', 'dark').lower(0.1),
success: new Color('#a2e57b', 'dark').lower(0.1),
notice: new Color('#ffed72', 'dark').lower(0.1),
warning: new Color('#ffb270', 'dark').lower(0.1),
danger: new Color('#ff6d7e', 'dark').lower(0.1),
},
primary: new YaakColor('#baa0f8', 'dark').lower(0.1),
secondary: new YaakColor('#b8c4c3', 'dark').lower(0.1),
info: new YaakColor('#7cd5f1', 'dark').lower(0.1),
success: new YaakColor('#a2e57b', 'dark').lower(0.1),
notice: new YaakColor('#ffed72', 'dark').lower(0.1),
warning: new YaakColor('#ffb270', 'dark').lower(0.1),
danger: new YaakColor('#ff6d7e', 'dark').lower(0.1),
},
},
};
@@ -121,38 +109,34 @@ const monokaiProMachine: YaakTheme = {
const monokaiProOctagon: YaakTheme = {
id: 'monokai-pro-octagon',
name: 'Monokai Pro Octagon',
background: new Color('#282a3a', 'dark'),
foreground: new Color('#eaf2f1', 'dark'),
foregroundSubtle: new Color('#b2b9bd', 'dark'),
foregroundSubtler: new Color('#767b81', 'dark'),
surface: new YaakColor('#282a3a', 'dark'),
text: new YaakColor('#eaf2f1', 'dark'),
textSubtle: new YaakColor('#b2b9bd', 'dark'),
textSubtlest: new YaakColor('#767b81', 'dark'),
colors: {
primary: new Color('#c39ac9', 'dark'),
secondary: new Color('#b2b9bd', 'dark'),
info: new Color('#9cd1bb', 'dark'),
success: new Color('#bad761', 'dark'),
notice: new Color('#ffd76d', 'dark'),
warning: new Color('#ff9b5e', 'dark'),
danger: new Color('#ff657a', 'dark'),
},
primary: new YaakColor('#c39ac9', 'dark'),
secondary: new YaakColor('#b2b9bd', 'dark'),
info: new YaakColor('#9cd1bb', 'dark'),
success: new YaakColor('#bad761', 'dark'),
notice: new YaakColor('#ffd76d', 'dark'),
warning: new YaakColor('#ff9b5e', 'dark'),
danger: new YaakColor('#ff657a', 'dark'),
components: {
appHeader: {
background: new Color('#1e1f2b', 'dark'),
foreground: new Color('#b2b9bd', 'dark'),
foregroundSubtle: new Color('#767b81', 'dark'),
foregroundSubtler: new Color('#696d77', 'dark'),
surface: new YaakColor('#1e1f2b', 'dark'),
text: new YaakColor('#b2b9bd', 'dark'),
textSubtle: new YaakColor('#767b81', 'dark'),
textSubtlest: new YaakColor('#696d77', 'dark'),
},
button: {
colors: {
primary: new Color('#c39ac9', 'dark').lower(0.1).desaturate(0.1),
secondary: new Color('#b2b9bd', 'dark').lower(0.1).desaturate(0.1),
info: new Color('#9cd1bb', 'dark').lower(0.1).desaturate(0.1),
success: new Color('#bad761', 'dark').lower(0.1).desaturate(0.1),
notice: new Color('#ffd76d', 'dark').lower(0.1).desaturate(0.1),
warning: new Color('#ff9b5e', 'dark').lower(0.1).desaturate(0.1),
danger: new Color('#ff657a', 'dark').lower(0.1).desaturate(0.1),
},
primary: new YaakColor('#c39ac9', 'dark').lower(0.1).desaturate(0.1),
secondary: new YaakColor('#b2b9bd', 'dark').lower(0.1).desaturate(0.1),
info: new YaakColor('#9cd1bb', 'dark').lower(0.1).desaturate(0.1),
success: new YaakColor('#bad761', 'dark').lower(0.1).desaturate(0.1),
notice: new YaakColor('#ffd76d', 'dark').lower(0.1).desaturate(0.1),
warning: new YaakColor('#ff9b5e', 'dark').lower(0.1).desaturate(0.1),
danger: new YaakColor('#ff657a', 'dark').lower(0.1).desaturate(0.1),
},
},
};
@@ -160,38 +144,34 @@ const monokaiProOctagon: YaakTheme = {
const monokaiProRistretto: YaakTheme = {
id: 'monokai-pro-ristretto',
name: 'Monokai Pro Ristretto',
background: new Color('#2c2525', 'dark'),
foreground: new Color('#fff1f3', 'dark'),
foregroundSubtle: new Color('#c3b7b8', 'dark'),
foregroundSubtler: new Color('#948a8b', 'dark'),
surface: new YaakColor('#2c2525', 'dark'),
text: new YaakColor('#fff1f3', 'dark'),
textSubtle: new YaakColor('#c3b7b8', 'dark'),
textSubtlest: new YaakColor('#948a8b', 'dark'),
colors: {
primary: new Color('#a8a9eb', 'dark'),
secondary: new Color('#c3b7b8', 'dark'),
info: new Color('#85dacc', 'dark'),
success: new Color('#adda78', 'dark'),
notice: new Color('#f9cc6c', 'dark'),
warning: new Color('#f38d70', 'dark'),
danger: new Color('#fd6883', 'dark'),
},
primary: new YaakColor('#a8a9eb', 'dark'),
secondary: new YaakColor('#c3b7b8', 'dark'),
info: new YaakColor('#85dacc', 'dark'),
success: new YaakColor('#adda78', 'dark'),
notice: new YaakColor('#f9cc6c', 'dark'),
warning: new YaakColor('#f38d70', 'dark'),
danger: new YaakColor('#fd6883', 'dark'),
components: {
appHeader: {
background: new Color('#211c1c', 'dark'),
foreground: new Color('#c3b7b8', 'dark'),
foregroundSubtle: new Color('#948a8b', 'dark'),
foregroundSubtler: new Color('#72696a', 'dark'),
surface: new YaakColor('#211c1c', 'dark'),
text: new YaakColor('#c3b7b8', 'dark'),
textSubtle: new YaakColor('#948a8b', 'dark'),
textSubtlest: new YaakColor('#72696a', 'dark'),
},
button: {
colors: {
primary: new Color('#a8a9eb', 'dark').lower(0.1),
secondary: new Color('#c3b7b8', 'dark').lower(0.1),
info: new Color('#85dacc', 'dark').lower(0.1),
success: new Color('#adda78', 'dark').lower(0.1),
notice: new Color('#f9cc6c', 'dark').lower(0.1),
warning: new Color('#f38d70', 'dark').lower(0.1),
danger: new Color('#fd6883', 'dark').lower(0.1),
},
primary: new YaakColor('#a8a9eb', 'dark').lower(0.1),
secondary: new YaakColor('#c3b7b8', 'dark').lower(0.1),
info: new YaakColor('#85dacc', 'dark').lower(0.1),
success: new YaakColor('#adda78', 'dark').lower(0.1),
notice: new YaakColor('#f9cc6c', 'dark').lower(0.1),
warning: new YaakColor('#f38d70', 'dark').lower(0.1),
danger: new YaakColor('#fd6883', 'dark').lower(0.1),
},
},
};
@@ -199,38 +179,34 @@ const monokaiProRistretto: YaakTheme = {
const monokaiProSpectrum: YaakTheme = {
id: 'monokai-pro-spectrum',
name: 'Monokai Pro Spectrum',
background: new Color('#222222', 'dark'),
foreground: new Color('#f7f1ff', 'dark'),
foregroundSubtle: new Color('#bab6c0', 'dark'),
foregroundSubtler: new Color('#8b888f', 'dark'),
surface: new YaakColor('#222222', 'dark'),
text: new YaakColor('#f7f1ff', 'dark'),
textSubtle: new YaakColor('#bab6c0', 'dark'),
textSubtlest: new YaakColor('#8b888f', 'dark'),
colors: {
primary: new Color('#948ae3', 'dark'),
secondary: new Color('#bab6c0', 'dark'),
info: new Color('#5ad4e6', 'dark'),
success: new Color('#7bd88f', 'dark'),
notice: new Color('#fce566', 'dark'),
warning: new Color('#fd9353', 'dark'),
danger: new Color('#fc618d', 'dark'),
},
primary: new YaakColor('#948ae3', 'dark'),
secondary: new YaakColor('#bab6c0', 'dark'),
info: new YaakColor('#5ad4e6', 'dark'),
success: new YaakColor('#7bd88f', 'dark'),
notice: new YaakColor('#fce566', 'dark'),
warning: new YaakColor('#fd9353', 'dark'),
danger: new YaakColor('#fc618d', 'dark'),
components: {
appHeader: {
background: new Color('#191919', 'dark'),
foreground: new Color('#bab6c0', 'dark'),
foregroundSubtle: new Color('#8b888f', 'dark'),
foregroundSubtler: new Color('#69676c', 'dark'),
surface: new YaakColor('#191919', 'dark'),
text: new YaakColor('#bab6c0', 'dark'),
textSubtle: new YaakColor('#8b888f', 'dark'),
textSubtlest: new YaakColor('#69676c', 'dark'),
},
button: {
colors: {
primary: new Color('#948ae3', 'dark').lower(0.1),
secondary: new Color('#bab6c0', 'dark').lower(0.1),
info: new Color('#5ad4e6', 'dark').lower(0.1),
success: new Color('#7bd88f', 'dark').lower(0.1),
notice: new Color('#fce566', 'dark').lower(0.1),
warning: new Color('#fd9353', 'dark').lower(0.1),
danger: new Color('#fc618d', 'dark').lower(0.1),
},
primary: new YaakColor('#948ae3', 'dark').lower(0.1),
secondary: new YaakColor('#bab6c0', 'dark').lower(0.1),
info: new YaakColor('#5ad4e6', 'dark').lower(0.1),
success: new YaakColor('#7bd88f', 'dark').lower(0.1),
notice: new YaakColor('#fce566', 'dark').lower(0.1),
warning: new YaakColor('#fd9353', 'dark').lower(0.1),
danger: new YaakColor('#fc618d', 'dark').lower(0.1),
},
},
};

View File

@@ -1,5 +1,5 @@
import { Color } from '../color';
import type { YaakTheme } from '../window';
import { YaakColor } from '../yaakColor';
export const colors = {
lightRed: '#ff98a4',
@@ -40,25 +40,23 @@ export const colors = {
const moonlightDefault: YaakTheme = {
id: 'moonlight',
name: 'Moonlight',
background: new Color('#222436', 'dark'),
foreground: new Color('#d5def8', 'dark'),
foregroundSubtle: new Color('#828bb8', 'dark'),
foregroundSubtler: new Color('hsl(232,26%,43%)', 'dark'),
colors: {
primary: new Color(colors.purple, 'dark'),
secondary: new Color(colors.desaturatedGray, 'dark'),
info: new Color(colors.blue, 'dark'),
success: new Color(colors.teal, 'dark'),
notice: new Color(colors.yellow, 'dark'),
warning: new Color(colors.orange, 'dark'),
danger: new Color(colors.red, 'dark'),
},
surface: new YaakColor('#222436', 'dark'),
text: new YaakColor('#d5def8', 'dark'),
textSubtle: new YaakColor('#828bb8', 'dark'),
textSubtlest: new YaakColor('hsl(232,26%,43%)', 'dark'),
primary: new YaakColor(colors.purple, 'dark'),
secondary: new YaakColor(colors.desaturatedGray, 'dark'),
info: new YaakColor(colors.blue, 'dark'),
success: new YaakColor(colors.teal, 'dark'),
notice: new YaakColor(colors.yellow, 'dark'),
warning: new YaakColor(colors.orange, 'dark'),
danger: new YaakColor(colors.red, 'dark'),
components: {
appHeader: {
background: new Color(colors.gray3, 'dark'),
surface: new YaakColor(colors.gray3, 'dark'),
},
sidebar: {
background: new Color(colors.gray3, 'dark'),
surface: new YaakColor(colors.gray3, 'dark'),
},
},
};

View File

@@ -0,0 +1,18 @@
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
const relaxingDefault: YaakTheme = {
name: 'Relaxing',
id: 'relaxing',
surface: new YaakColor('#2b1e3b', 'dark'),
text: new YaakColor('#ede2f5', 'dark'),
primary: new YaakColor('#cba6f7', 'dark'),
secondary: new YaakColor('#bac2de', 'dark'),
info: new YaakColor('#89b4fa', 'dark'),
success: new YaakColor('#a6e3a1', 'dark'),
notice: new YaakColor('#f9e2af', 'dark'),
warning: new YaakColor('#fab387', 'dark'),
danger: new YaakColor('#f38ba8', 'dark'),
};
export const relaxing = [relaxingDefault];

View File

@@ -1,33 +1,31 @@
import { Color } from '../color';
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
export const rosePineDefault: YaakTheme = {
id: 'rose-pine',
name: 'Rosé Pine',
background: new Color('#191724', 'dark'),
foreground: new Color('#e0def4', 'dark'),
foregroundSubtle: new Color('#908caa', 'dark'),
foregroundSubtler: new Color('#6e6a86', 'dark'),
colors: {
primary: new Color('#c4a7e7', 'dark'),
secondary: new Color('#6e6a86', 'dark'),
info: new Color('#67abcb', 'dark'),
success: new Color('#9cd8d8', 'dark'),
notice: new Color('#f6c177', 'dark'),
warning: new Color('#f1a3a1', 'dark'),
danger: new Color('#eb6f92', 'dark'),
},
surface: new YaakColor('#191724', 'dark'),
text: new YaakColor('#e0def4', 'dark'),
textSubtle: new YaakColor('#908caa', 'dark'),
textSubtlest: new YaakColor('#6e6a86', 'dark'),
primary: new YaakColor('#c4a7e7', 'dark'),
secondary: new YaakColor('#6e6a86', 'dark'),
info: new YaakColor('#67abcb', 'dark'),
success: new YaakColor('#9cd8d8', 'dark'),
notice: new YaakColor('#f6c177', 'dark'),
warning: new YaakColor('#f1a3a1', 'dark'),
danger: new YaakColor('#eb6f92', 'dark'),
components: {
responsePane: {
background: new Color('#1f1d2e', 'dark'),
surface: new YaakColor('#1f1d2e', 'dark'),
},
sidebar: {
background: new Color('#1f1d2e', 'dark'),
surface: new YaakColor('#1f1d2e', 'dark'),
},
menu: {
background: new Color('#393552', 'dark'),
foregroundSubtle: new Color('#908caa', 'dark').lift(0.15),
foregroundSubtler: new Color('#6e6a86', 'dark').lift(0.15),
surface: new YaakColor('#393552', 'dark'),
textSubtle: new YaakColor('#908caa', 'dark').lift(0.15),
textSubtlest: new YaakColor('#6e6a86', 'dark').lift(0.15),
},
},
};
@@ -35,30 +33,28 @@ export const rosePineDefault: YaakTheme = {
const rosePineMoon: YaakTheme = {
id: 'rose-pine-moon',
name: 'Rosé Pine Moon',
background: new Color('#232136', 'dark'),
foreground: new Color('#e0def4', 'dark'),
foregroundSubtle: new Color('#908caa', 'dark'),
foregroundSubtler: new Color('#6e6a86', 'dark'),
colors: {
primary: new Color('#c4a7e7', 'dark'),
secondary: new Color('#908caa', 'dark'),
info: new Color('#68aeca', 'dark'),
success: new Color('#9ccfd8', 'dark'),
notice: new Color('#f6c177', 'dark'),
warning: new Color('#ea9a97', 'dark'),
danger: new Color('#eb6f92', 'dark'),
},
surface: new YaakColor('#232136', 'dark'),
text: new YaakColor('#e0def4', 'dark'),
textSubtle: new YaakColor('#908caa', 'dark'),
textSubtlest: new YaakColor('#6e6a86', 'dark'),
primary: new YaakColor('#c4a7e7', 'dark'),
secondary: new YaakColor('#908caa', 'dark'),
info: new YaakColor('#68aeca', 'dark'),
success: new YaakColor('#9ccfd8', 'dark'),
notice: new YaakColor('#f6c177', 'dark'),
warning: new YaakColor('#ea9a97', 'dark'),
danger: new YaakColor('#eb6f92', 'dark'),
components: {
responsePane: {
background: new Color('#2a273f', 'dark'),
surface: new YaakColor('#2a273f', 'dark'),
},
sidebar: {
background: new Color('#2a273f', 'dark'),
surface: new YaakColor('#2a273f', 'dark'),
},
menu: {
background: new Color('#393552', 'dark'),
foregroundSubtle: new Color('#908caa', 'dark').lift(0.15),
foregroundSubtler: new Color('#6e6a86', 'dark').lift(0.15),
surface: new YaakColor('#393552', 'dark'),
textSubtle: new YaakColor('#908caa', 'dark').lift(0.15),
textSubtlest: new YaakColor('#6e6a86', 'dark').lift(0.15),
},
},
};
@@ -66,39 +62,39 @@ const rosePineMoon: YaakTheme = {
const rosePineDawn: YaakTheme = {
id: 'rose-pine-dawn',
name: 'Rosé Pine Dawn',
background: new Color('#faf4ed', 'light'),
backgroundHighlight: new Color('#dfdad9', 'light'),
backgroundHighlightSecondary: new Color('#f4ede8', 'light'),
foreground: new Color('#575279', 'light'),
foregroundSubtle: new Color('#797593', 'light'),
foregroundSubtler: new Color('#9893a5', 'light'),
colors: {
primary: new Color('#9070ad', 'light'),
secondary: new Color('#6e6a86', 'light'),
info: new Color('#2d728d', 'light'),
success: new Color('#4f8c96', 'light'),
notice: new Color('#cb862d', 'light'),
warning: new Color('#ce7b78', 'light'),
danger: new Color('#b4637a', 'light'),
},
surface: new YaakColor('#faf4ed', 'light'),
border: new YaakColor('#dfdad9', 'light'),
surfaceHighlight: new YaakColor('#f4ede8', 'light'),
text: new YaakColor('#575279', 'light'),
textSubtle: new YaakColor('#797593', 'light'),
textSubtlest: new YaakColor('#9893a5', 'light'),
primary: new YaakColor('#9070ad', 'light'),
secondary: new YaakColor('#6e6a86', 'light'),
info: new YaakColor('#2d728d', 'light'),
success: new YaakColor('#4f8c96', 'light'),
notice: new YaakColor('#cb862d', 'light'),
warning: new YaakColor('#ce7b78', 'light'),
danger: new YaakColor('#b4637a', 'light'),
components: {
responsePane: {
backgroundHighlight: new Color('#e8e4e2', 'light'),
border: new YaakColor('#e8e4e2', 'light'),
},
sidebar: {
backgroundHighlight: new Color('#e8e4e2', 'light'),
border: new YaakColor('#e8e4e2', 'light'),
},
appHeader: {
backgroundHighlight: new Color('#e8e4e2', 'light'),
border: new YaakColor('#e8e4e2', 'light'),
},
input: {
backgroundHighlight: new Color('#dfdad9', 'light'),
border: new YaakColor('#dfdad9', 'light'),
},
dialog: {
backgroundHighlight: new Color('#e8e4e2', 'light'),
border: new YaakColor('#e8e4e2', 'light'),
},
menu: {
background: new Color('#f2e9e1', 'light'),
surface: new YaakColor('#f2e9e1', 'light'),
border: new YaakColor('#dfdad9', 'light'),
surfaceHighlight: new YaakColor('#6e6a86', 'light'),
},
},
};

View File

@@ -1,82 +1,72 @@
import { Color } from '../color';
import { YaakColor } from '../yaakColor';
import type { YaakTheme } from '../window';
export const yaakLight: YaakTheme = {
id: 'yaak-light',
name: 'Yaak Light',
background: new Color('hsl(216,24%,100%)', 'light'),
backgroundHighlight: new Color('hsl(216,24%,93%)', 'light'),
backgroundHighlightSecondary: new Color('hsl(216,24%,87%)', 'light'),
foreground: new Color('hsl(219,23%,15%)', 'light'),
foregroundSubtle: new Color('hsl(219,23%,15%)', 'light').lower(0.3),
foregroundSubtler: new Color('hsl(219,23%,15%)', 'light').lower(0.5),
colors: {
primary: new Color('hsl(266,100%,70%)', 'light'),
secondary: new Color('hsl(220,24%,59%)', 'light'),
info: new Color('hsl(206,100%,48%)', 'light'),
success: new Color('hsl(155,95%,33%)', 'light'),
notice: new Color('hsl(45,100%,41%)', 'light'),
warning: new Color('hsl(30,100%,43%)', 'light'),
danger: new Color('hsl(335,75%,57%)', 'light'),
},
name: 'Yaak',
surface: new YaakColor('hsl(216,24%,100%)', 'light'),
border: new YaakColor('hsl(216,24%,93%)', 'light'),
surfaceHighlight: new YaakColor('hsl(216,24%,87%)', 'light'),
text: new YaakColor('hsl(219,23%,15%)', 'light'),
textSubtle: new YaakColor('hsl(219,23%,15%)', 'light').lower(0.3),
textSubtlest: new YaakColor('hsl(219,23%,15%)', 'light').lower(0.5),
primary: new YaakColor('hsl(266,100%,70%)', 'light'),
secondary: new YaakColor('hsl(220,24%,59%)', 'light'),
info: new YaakColor('hsl(206,100%,48%)', 'light'),
success: new YaakColor('hsl(155,95%,33%)', 'light'),
notice: new YaakColor('hsl(45,100%,41%)', 'light'),
warning: new YaakColor('hsl(30,100%,43%)', 'light'),
danger: new YaakColor('hsl(335,75%,57%)', 'light'),
components: {
sidebar: {
background: new Color('hsl(216,24%,97%)', 'light'),
backgroundHighlight: new Color('hsl(216,24%,93%)', 'light'),
backgroundHighlightSecondary: new Color('hsl(216,24%,90%)', 'light'),
surface: new YaakColor('hsl(216,24%,97%)', 'light'),
border: new YaakColor('hsl(216,24%,93%)', 'light'),
surfaceHighlight: new YaakColor('hsl(216,24%,90%)', 'light'),
},
},
};
export const yaakDark: YaakTheme = {
id: 'yaak-dark',
name: 'Yaak Dark',
background: new Color('hsl(244,23%,14%)', 'dark'),
backgroundHighlight: new Color('hsl(244,23%,23%)', 'dark'),
backgroundHighlightSecondary: new Color('hsl(244,23%,20%)', 'dark'),
foreground: new Color('hsl(245,23%,83%)', 'dark'),
foregroundSubtle: new Color('hsl(245,20%,65%)', 'dark'),
foregroundSubtler: new Color('hsl(245,18%,51%)', 'dark'),
colors: {
primary: new Color('hsl(266,100%,79%)', 'dark'),
secondary: new Color('hsl(245,23%,60%)', 'dark'),
info: new Color('hsl(206,100%,63%)', 'dark'),
success: new Color('hsl(150,99%,44%)', 'dark'),
notice: new Color('hsl(48,80%,63%)', 'dark'),
warning: new Color('hsl(28,100%,61%)', 'dark'),
danger: new Color('hsl(342,90%,68%)', 'dark'),
},
name: 'Yaak',
surface: new YaakColor('hsl(244,23%,14%)', 'dark'),
border: new YaakColor('hsl(244,23%,25%)', 'dark'),
surfaceHighlight: new YaakColor('hsl(244,23%,20%)', 'dark'),
text: new YaakColor('hsl(245,23%,84%)', 'dark'),
textSubtle: new YaakColor('hsl(245,18%,58%)', 'dark'),
textSubtlest: new YaakColor('hsl(245,18%,45%)', 'dark'),
primary: new YaakColor('hsl(266,100%,79%)', 'dark'),
secondary: new YaakColor('hsl(245,23%,60%)', 'dark'),
info: new YaakColor('hsl(206,100%,63%)', 'dark'),
success: new YaakColor('hsl(150,99%,44%)', 'dark'),
notice: new YaakColor('hsl(48,80%,63%)', 'dark'),
warning: new YaakColor('hsl(28,100%,61%)', 'dark'),
danger: new YaakColor('hsl(342,90%,68%)', 'dark'),
components: {
button: {
colors: {
primary: new Color('hsl(266,100%,79%)', 'dark').lower(0.1),
secondary: new Color('hsl(245,23%,60%)', 'dark').lower(0.1),
info: new Color('hsl(206,100%,63%)', 'dark').lower(0.1),
success: new Color('hsl(150,99%,44%)', 'dark').lower(0.15),
notice: new Color('hsl(48,80%,63%)', 'dark').lower(0.2),
warning: new Color('hsl(28,100%,61%)', 'dark').lower(0.1),
danger: new Color('hsl(342,90%,68%)', 'dark').lower(0.1),
},
},
input: {
backgroundHighlight: new Color('hsl(244,23%,24%)', 'dark'),
primary: new YaakColor('hsl(266,100%,79%)', 'dark').lower(0.1),
secondary: new YaakColor('hsl(245,23%,60%)', 'dark').lower(0.1),
info: new YaakColor('hsl(206,100%,63%)', 'dark').lower(0.1),
success: new YaakColor('hsl(150,99%,44%)', 'dark').lower(0.15),
notice: new YaakColor('hsl(48,80%,63%)', 'dark').lower(0.2),
warning: new YaakColor('hsl(28,100%,61%)', 'dark').lower(0.1),
danger: new YaakColor('hsl(342,90%,68%)', 'dark').lower(0.1),
},
dialog: {
backgroundHighlight: new Color('hsl(244,23%,24%)', 'dark'),
border: new YaakColor('hsl(244,23%,24%)', 'dark'),
},
sidebar: {
background: new Color('hsl(243,23%,16%)', 'dark'),
backgroundHighlight: new Color('hsl(244,23%,22%)', 'dark'),
surface: new YaakColor('hsl(243,23%,16%)', 'dark'),
border: new YaakColor('hsl(244,23%,22%)', 'dark'),
},
responsePane: {
background: new Color('hsl(243,23%,16%)', 'dark'),
backgroundHighlight: new Color('hsl(244,23%,16%)', 'dark').lift(0.08),
surface: new YaakColor('hsl(243,23%,16%)', 'dark'),
border: new YaakColor('hsl(244,23%,16%)', 'dark').lift(0.08),
},
appHeader: {
background: new Color('hsl(244,23%,12%)', 'dark'),
backgroundHighlight: new Color('hsl(244,23%,12%)', 'dark').lift(0.1),
surface: new YaakColor('hsl(244,23%,12%)', 'dark'),
border: new YaakColor('hsl(244,23%,12%)', 'dark').lift(0.1),
},
},
};

View File

@@ -1,138 +1,166 @@
import { Color } from './color';
import { defaultDarkTheme, defaultLightTheme } from './themes';
import { YaakColor } from './yaakColor';
export type Appearance = 'dark' | 'light' | 'system';
export type YaakColors = {
surface: YaakColor;
surfaceHighlight?: YaakColor;
surfaceActive?: YaakColor;
interface ThemeComponent {
background?: Color;
backgroundHighlight?: Color;
backgroundHighlightSecondary?: Color;
backgroundActive?: Color;
foreground?: Color;
foregroundSubtle?: Color;
foregroundSubtler?: Color;
shadow?: Color;
colors?: Partial<RootColors>;
}
text: YaakColor;
textSubtle?: YaakColor;
textSubtlest?: YaakColor;
export interface YaakTheme extends ThemeComponent {
border?: YaakColor;
borderSubtle?: YaakColor;
borderFocus?: YaakColor;
shadow?: YaakColor;
backdrop?: YaakColor;
selection?: YaakColor;
primary?: YaakColor;
secondary?: YaakColor;
info?: YaakColor;
success?: YaakColor;
notice?: YaakColor;
warning?: YaakColor;
danger?: YaakColor;
};
export type YaakTheme = YaakColors & {
id: string;
name: string;
components?: {
dialog?: ThemeComponent;
menu?: ThemeComponent;
toast?: ThemeComponent;
sidebar?: ThemeComponent;
responsePane?: ThemeComponent;
appHeader?: ThemeComponent;
button?: ThemeComponent;
banner?: ThemeComponent;
placeholder?: ThemeComponent;
urlBar?: ThemeComponent;
editor?: ThemeComponent;
input?: ThemeComponent;
};
}
components?: Partial<{
dialog: Partial<YaakColors>;
menu: Partial<YaakColors>;
toast: Partial<YaakColors>;
sidebar: Partial<YaakColors>;
responsePane: Partial<YaakColors>;
appHeader: Partial<YaakColors>;
button: Partial<YaakColors>;
banner: Partial<YaakColors>;
placeholder: Partial<YaakColors>;
urlBar: Partial<YaakColors>;
editor: Partial<YaakColors>;
input: Partial<YaakColors>;
}>;
};
interface RootColors {
primary: Color;
secondary: Color;
info: Color;
success: Color;
notice: Color;
warning: Color;
danger: Color;
}
export type YaakColorKey = keyof YaakColors;
type ColorName = keyof RootColors;
type ComponentName = keyof NonNullable<YaakTheme['components']>;
type CSSVariables = Record<string, string | undefined>;
type CSSVariables = Record<YaakColorKey, YaakColor | undefined>;
function themeVariables(theme?: ThemeComponent, base?: CSSVariables): CSSVariables | null {
function themeVariables(theme?: Partial<YaakColors>, base?: CSSVariables): CSSVariables | null {
const vars: CSSVariables = {
'--background': theme?.background?.css(),
'--background-highlight':
theme?.backgroundHighlight?.css() ?? theme?.background?.lift(0.11).css(),
'--background-highlight-secondary':
theme?.backgroundHighlightSecondary?.css() ?? theme?.background?.lift(0.06).css(),
'--background-active':
theme?.backgroundActive?.css() ?? theme?.colors?.primary?.lower(0.2).translucify(0.8).css(),
'--background-backdrop': theme?.background?.lower(0.2).translucify(0.2).css(),
'--background-selection': theme?.colors?.primary?.lower(0.1).translucify(0.7).css(),
'--fg': theme?.foreground?.css(),
'--fg-subtle': theme?.foregroundSubtle?.css() ?? theme?.foreground?.lower(0.2).css(),
'--fg-subtler': theme?.foregroundSubtler?.css() ?? theme?.foreground?.lower(0.3).css(),
'--border-focus': theme?.colors?.info?.css(),
'--shadow':
theme?.shadow?.css() ??
Color.black()
.translucify(isThemeDark(theme ?? {}) ? 0.7 : 0.93)
.css(),
surface: theme?.surface,
surfaceHighlight: theme?.surfaceHighlight ?? theme?.surface?.lift(0.06),
surfaceActive: theme?.surfaceActive ?? theme?.primary?.lower(0.2).translucify(0.8),
backdrop: theme?.surface?.lower(0.2).translucify(0.2),
selection: theme?.primary?.lower(0.1).translucify(0.7),
border: theme?.border ?? theme?.surface?.lift(0.11),
borderSubtle: theme?.borderSubtle ?? theme?.border?.lower(0.06),
borderFocus: theme?.info?.translucify(0.5),
text: theme?.text,
textSubtle: theme?.textSubtle ?? theme?.text?.lower(0.2),
textSubtlest: theme?.textSubtlest ?? theme?.text?.lower(0.3),
shadow:
theme?.shadow ??
YaakColor.black().translucify(isThemeDark(theme ?? ({} as Partial<YaakColors>)) ? 0.7 : 0.93),
primary: theme?.primary,
secondary: theme?.primary,
info: theme?.info,
success: theme?.success,
notice: theme?.notice,
warning: theme?.warning,
danger: theme?.danger,
};
for (const [color, value] of Object.entries(theme?.colors ?? {})) {
vars[`--fg-${color}`] = (value as Color).css();
}
// Extend with base
for (const [k, v] of Object.entries(vars)) {
if (!v && base?.[k]) {
vars[k] = base[k];
if (!v && base?.[k as YaakColorKey]) {
vars[k as YaakColorKey] = base[k as YaakColorKey];
}
}
return vars;
}
function placeholderColorVariables(color: Color): CSSVariables {
function placeholderColorVariables(color: YaakColor): Partial<CSSVariables> {
return {
'--fg': color.lift(0.6).css(),
'--fg-subtle': color.lift(0.4).css(),
'--fg-subtler': color.css(),
'--background': color.lower(0.2).translucify(0.8).css(),
'--background-highlight': color.lower(0.2).translucify(0.2).css(),
'--background-highlight-secondary': color.lower(0.1).translucify(0.7).css(),
text: color.lift(0.6),
textSubtle: color.lift(0.4),
textSubtlest: color,
surface: color.lower(0.2).translucify(0.8),
border: color.lower(0.2).translucify(0.2),
surfaceHighlight: color.lower(0.1).translucify(0.7),
};
}
function bannerColorVariables(color: Color): CSSVariables {
function bannerColorVariables(color: YaakColor): Partial<CSSVariables> {
return {
'--fg': color.lift(0.8).css(),
'--fg-subtle': color.translucify(0.3).css(),
'--fg-subtler': color.css(),
'--background': color.css(),
'--background-highlight': color.lift(0.3).translucify(0.4).css(),
'--background-highlight-secondary': color.translucify(0.9).css(),
text: color.lift(0.8),
textSubtle: color.translucify(0.3),
textSubtlest: color,
surface: color,
border: color.lift(0.3).translucify(0.4),
surfaceHighlight: color.translucify(0.9),
};
}
function buttonSolidColorVariables(color: Color): CSSVariables {
return {
'--fg': new Color('white', 'dark').css(),
'--background': color.lower(0.15).css(),
'--background-highlight': color.css(),
'--background-highlight-secondary': color.lower(0.3).css(),
function buttonSolidColorVariables(
color: YaakColor,
isDefault: boolean = false,
): Partial<CSSVariables> {
const theme: Partial<YaakTheme> = {
text: new YaakColor('white', 'dark'),
surface: color.lower(0.3),
surfaceHighlight: color.lower(0.1),
border: color,
};
if (isDefault) {
theme.text = color.lift(0.8);
theme.surface = undefined; // Inherit from root
theme.surfaceHighlight = color.lift(0.08);
}
return theme;
}
function buttonBorderColorVariables(color: Color): CSSVariables {
return {
'--fg': color.lift(0.6).css(),
'--fg-subtle': color.lift(0.4).css(),
'--fg-subtler': color.lift(0.4).translucify(0.6).css(),
'--background': Color.transparent().css(),
'--background-highlight': color.translucify(0.8).css(),
function buttonBorderColorVariables(
color: YaakColor,
isDefault: boolean = false,
): Partial<CSSVariables> {
const theme = {
text: color.lift(0.8),
textSubtle: color.lift(0.55),
textSubtlest: color.lift(0.4).translucify(0.6),
surfaceHighlight: color.translucify(0.8),
borderSubtle: color.translucify(0.5),
border: color.translucify(0.3),
};
if (isDefault) {
theme.borderSubtle = color.lift(0.28);
theme.border = color.lift(0.5);
}
return theme;
}
function variablesToCSS(selector: string | null, vars: CSSVariables | null): string | null {
function variablesToCSS(
selector: string | null,
vars: Partial<CSSVariables> | null,
): string | null {
if (vars == null) {
return null;
}
const css = Object.entries(vars ?? {})
.filter(([, value]) => value)
.map(([name, value]) => `${name}: ${value};`)
.map(([name, value]) => `--${name}: ${value?.css()};`)
.join('\n');
return selector == null ? css : `${selector} {\n${indent(css)}\n}`;
@@ -150,41 +178,43 @@ function componentCSS(
return variablesToCSS(`.x-theme-${component}`, themeVars);
}
function buttonCSS(color: ColorName, colors?: Partial<RootColors>): string | null {
const cssColor = colors?.[color];
if (cssColor == null) {
function buttonCSS(color: YaakColorKey, colors?: Partial<YaakColors>): string | null {
const yaakColor = colors?.[color];
if (yaakColor == null) {
return null;
}
return [
variablesToCSS(`.x-theme-button--solid--${color}`, buttonSolidColorVariables(cssColor)),
variablesToCSS(`.x-theme-button--border--${color}`, buttonBorderColorVariables(cssColor)),
variablesToCSS(`.x-theme-button--solid--${color}`, buttonSolidColorVariables(yaakColor)),
variablesToCSS(`.x-theme-button--border--${color}`, buttonBorderColorVariables(yaakColor)),
].join('\n\n');
}
function bannerCSS(color: ColorName, colors?: Partial<RootColors>): string | null {
const cssColor = colors?.[color];
if (cssColor == null) {
function bannerCSS(color: YaakColorKey, colors?: Partial<YaakColors>): string | null {
const yaakColor = colors?.[color];
if (yaakColor == null) {
return null;
}
return [variablesToCSS(`.x-theme-banner--${color}`, bannerColorVariables(cssColor))].join('\n\n');
return [variablesToCSS(`.x-theme-banner--${color}`, bannerColorVariables(yaakColor))].join(
'\n\n',
);
}
function placeholderCSS(color: ColorName, colors?: Partial<RootColors>): string | null {
const cssColor = colors?.[color];
if (cssColor == null) {
function placeholderCSS(color: YaakColorKey, colors?: Partial<YaakColors>): string | null {
const yaakColor = colors?.[color];
if (yaakColor == null) {
return null;
}
return [
variablesToCSS(`.x-theme-placeholder--${color}`, placeholderColorVariables(cssColor)),
variablesToCSS(`.x-theme-placeholder--${color}`, placeholderColorVariables(yaakColor)),
].join('\n\n');
}
export function isThemeDark(theme: ThemeComponent): boolean {
if (theme.background && theme.foreground) {
return theme.foreground.lighterThan(theme.background);
export function isThemeDark(theme: Partial<YaakColors>): boolean {
if (theme.surface && theme.text) {
return theme.text.lighterThan(theme.surface);
}
return false;
@@ -193,35 +223,49 @@ export function isThemeDark(theme: ThemeComponent): boolean {
export function getThemeCSS(theme: YaakTheme): string {
theme.components = theme.components ?? {};
// Toast defaults to menu styles
theme.components.toast = theme.components.toast ?? theme.components.menu;
theme.components.toast = theme.components.toast ?? theme.components.menu ?? {};
const { components, id, name } = theme;
const colors = Object.keys(theme)
.filter((key) => theme[key as YaakColorKey] instanceof YaakColor)
.reduce((prev, key) => {
return { ...prev, [key]: theme[key as YaakColorKey] };
}, {});
let themeCSS = '';
try {
const baseCss = variablesToCSS(null, themeVariables(theme));
const { components, colors } = theme;
themeCSS = [
baseCss,
...Object.keys(components ?? {}).map((key) =>
componentCSS(key as ComponentName, theme.components),
),
...Object.keys(colors ?? {}).map((key) =>
buttonCSS(key as ColorName, theme.components?.button?.colors ?? colors),
variablesToCSS(
`.x-theme-button--solid--default`,
buttonSolidColorVariables(theme.surface, true),
),
variablesToCSS(
`.x-theme-button--border--default`,
buttonBorderColorVariables(theme.surface, true),
),
...Object.keys(colors ?? {}).map((key) =>
bannerCSS(key as ColorName, theme.components?.banner?.colors ?? colors),
buttonCSS(key as YaakColorKey, theme.components?.button ?? colors),
),
...Object.keys(colors ?? {}).map((key) =>
placeholderCSS(key as ColorName, theme.components?.placeholder?.colors ?? colors),
bannerCSS(key as YaakColorKey, theme.components?.banner ?? colors),
),
...Object.keys(colors ?? {}).map((key) =>
placeholderCSS(key as YaakColorKey, theme.components?.placeholder ?? colors),
),
].join('\n\n');
} catch (err) {
console.error(err);
console.error('Failed to generate CSS', err);
}
return [`/* ${theme.name} */`, `[data-theme="${theme.id}"] {`, indent(themeCSS), '}'].join('\n');
return [`/* ${name} */`, `[data-theme="${id}"] {`, indent(themeCSS), '}'].join('\n');
}
export function addThemeStylesToDocument(theme: YaakTheme) {
theme = completeTheme(theme);
let styleEl = document.head.querySelector(`style[data-theme]`);
if (!styleEl) {
styleEl = document.createElement('style');
@@ -229,6 +273,7 @@ export function addThemeStylesToDocument(theme: YaakTheme) {
}
styleEl.setAttribute('data-theme', theme.id);
styleEl.setAttribute('data-updated-at', new Date().toISOString());
styleEl.textContent = getThemeCSS(theme);
}
@@ -242,3 +287,74 @@ export function indent(text: string, space = ' '): string {
.map((line) => space + line)
.join('\n');
}
export function completeTheme(theme: YaakTheme): YaakTheme {
const isDark = isThemeDark(theme);
// Clone the theme
theme = deserializeTheme(serializeTheme(theme), isDark ? 'dark' : 'light');
const base = isDark ? defaultDarkTheme : defaultLightTheme;
theme.primary = theme.primary ?? base.primary;
theme.secondary = theme.secondary ?? base.secondary;
theme.info = theme.info ?? base.info;
theme.success = theme.success ?? base.success;
theme.notice = theme.notice ?? base.notice;
theme.warning = theme.warning ?? base.warning;
theme.danger = theme.danger ?? base.danger;
theme.surface = theme.surface ?? base.surface;
theme.surfaceHighlight = theme.surfaceHighlight ?? theme.surface?.lift(0.06);
theme.surfaceActive = theme.surfaceActive ?? theme.primary?.lower(0.2).translucify(0.8);
theme.border = theme.border ?? theme.surface?.lift(0.12);
theme.borderSubtle = theme.borderSubtle ?? theme.border?.lower(0.08);
console.log('HELLO', { theme });
theme.text = theme.text ?? theme.border?.lift(1).lower(0.2);
theme.textSubtle = theme.textSubtle ?? theme.text?.lower(0.3);
theme.textSubtlest = theme.textSubtlest ?? theme.text?.lower(0.5);
return theme;
}
export function serializeTheme(theme: YaakTheme): string {
function next(o: Record<string, unknown>) {
o = { ...o }; // Clone first
for (const k of Object.keys(o)) {
const v = o[k];
if (v instanceof YaakColor) {
o[k] = v.css();
} else if (Object.prototype.toString.call(v) === '[object Object]') {
o[k] = next(v as Record<string, unknown>);
} else {
o[k] = v;
}
}
return o;
}
return JSON.stringify(next(theme));
}
export function deserializeTheme(theme: string, appearance: 'dark' | 'light'): YaakTheme {
function next(o: Record<string, unknown>) {
for (const k of Object.keys(o)) {
const v = o[k];
if (v instanceof YaakColor) {
o[k] = v;
} else if (typeof v === 'string' && v.match(/^(#|hsla\()/)) {
o[k] = new YaakColor(v, appearance);
} else if (Object.prototype.toString.call(v) === '[object Object]') {
o[k] = next(v as Record<string, unknown>);
} else {
o[k] = v;
}
}
return o;
}
return next(JSON.parse(theme)) as YaakTheme;
}

View File

@@ -0,0 +1,140 @@
import parseColor from 'parse-color';
export class YaakColor {
private readonly appearance: 'dark' | 'light' = 'light';
private hue: number = 0;
private saturation: number = 0;
private lightness: number = 0;
private alpha: number = 1;
constructor(cssColor: string, appearance: 'dark' | 'light' = 'light') {
try {
this.set(cssColor);
this.appearance = appearance;
} catch (err) {
console.log('Failed to parse CSS color', cssColor, err);
}
}
static transparent(): YaakColor {
return new YaakColor('rgb(0,0,0)', 'light').translucify(1);
}
static white(): YaakColor {
return new YaakColor('rgb(0,0,0)', 'light').lower(1);
}
static black(): YaakColor {
return new YaakColor('rgb(0,0,0)', 'light').lift(1);
}
set(cssColor: string): YaakColor {
if (cssColor.startsWith('#') && cssColor.length === 9) {
const [r, g, b, a] = hexToRgba(cssColor);
cssColor = `rgba(${r},${g},${b},${a})`;
}
const { hsla } = parseColor(cssColor);
this.hue = hsla[0];
this.saturation = hsla[1];
this.lightness = hsla[2];
this.alpha = hsla[3] ?? 1;
return this;
}
clone(): YaakColor {
return new YaakColor(this.css(), this.appearance);
}
lower(mod: number): YaakColor {
return this.appearance === 'dark' ? this._darken(mod) : this._lighten(mod);
}
lift(mod: number): YaakColor {
return this.appearance === 'dark' ? this._lighten(mod) : this._darken(mod);
}
minLightness(n: number): YaakColor {
const c = this.clone();
if (c.lightness < n) {
c.lightness = n;
}
return c;
}
isDark(): boolean {
return this.lightness < 50;
}
translucify(mod: number): YaakColor {
const c = this.clone();
c.alpha = c.alpha - c.alpha * mod;
return c;
}
opacify(mod: number): YaakColor {
const c = this.clone();
c.alpha = this.alpha + (100 - this.alpha) * mod;
return c;
}
desaturate(mod: number): YaakColor {
const c = this.clone();
c.saturation = c.saturation - c.saturation * mod;
return c;
}
saturate(mod: number): YaakColor {
const c = this.clone();
c.saturation = this.saturation + (100 - this.saturation) * mod;
return c;
}
lighterThan(c: YaakColor): boolean {
return this.lightness > c.lightness;
}
css(): string {
const h = this.hue;
const s = this.saturation;
const l = this.lightness;
const a = this.alpha; // Convert from 0-1 to 0-255
const [r, g, b] = parseColor(`hsl(${h},${s}%,${l}%)`).rgb;
return rgbaToHex(r, g, b, a);
}
private _lighten(mod: number): YaakColor {
const c = this.clone();
c.lightness = this.lightness + (100 - this.lightness) * mod;
return c;
}
private _darken(mod: number): YaakColor {
const c = this.clone();
c.lightness = this.lightness - this.lightness * mod;
return c;
}
}
function rgbaToHex(r: number, g: number, b: number, a: number): string {
const toHex = (n: number): string => {
const hex = Number(Math.round(n)).toString(16);
return hex.length === 1 ? `0${hex}` : hex;
};
return '#' + [toHex(r), toHex(g), toHex(b), toHex(a * 255)].join('').toUpperCase();
}
function hexToRgba(hex: string): [number, number, number, number] {
const fromHex = (h: string): number => {
if (h === '') return 255;
return Number(`0x${h}`);
};
const r = fromHex(hex.slice(1, 3));
const g = fromHex(hex.slice(3, 5));
const b = fromHex(hex.slice(5, 7));
const a = fromHex(hex.slice(7, 9));
return [r, g, b, a / 255];
}