Rework darkest color in base16, shadows, and add hoverPopover styleTree

This commit is contained in:
Keith Simmons 2022-05-27 11:30:58 -07:00
parent 0c4f798a2d
commit 02249dc2e8
8 changed files with 128 additions and 99 deletions

View file

@ -4,9 +4,10 @@ import {
backgroundColor, backgroundColor,
border, border,
player, player,
shadow, modalShadow,
text, text,
TextColor TextColor,
popoverShadow
} from "./components"; } from "./components";
export default function chatPanel(theme: Theme) { export default function chatPanel(theme: Theme) {
@ -69,7 +70,7 @@ export default function chatPanel(theme: Theme) {
cornerRadius: 6, cornerRadius: 6,
padding: 4, padding: 4,
border: border(theme, "primary"), border: border(theme, "primary"),
shadow: shadow(theme), shadow: popoverShadow(theme),
}, },
}, },
signInPrompt: text(theme, "sans", "secondary", { underline: true }), signInPrompt: text(theme, "sans", "secondary", { underline: true }),

View file

@ -1,4 +1,5 @@
import chroma from "chroma-js"; import chroma from "chroma-js";
import { isIPv4 } from "net";
import Theme, { BackgroundColorSet } from "../themes/common/theme"; import Theme, { BackgroundColorSet } from "../themes/common/theme";
import { fontFamilies, fontSizes, FontWeight } from "../tokens"; import { fontFamilies, fontSizes, FontWeight } from "../tokens";
import { Color } from "../utils/color"; import { Color } from "../utils/color";
@ -84,10 +85,18 @@ export function backgroundColor(
return theme.backgroundColor[name][state || "base"].value; return theme.backgroundColor[name][state || "base"].value;
} }
export function shadow(theme: Theme) { export function modalShadow(theme: Theme) {
return { return {
blur: 16, blur: 16,
color: chroma("black").alpha(theme.shadowAlpha.value).hex(), color: theme.shadow.value,
offset: [0, 2], offset: [0, 2],
}; };
} }
export function popoverShadow(theme: Theme) {
return {
blur: 4,
color: theme.shadow.value,
offset: [1, 2],
};
}

View file

@ -4,6 +4,7 @@ import {
border, border,
iconColor, iconColor,
player, player,
popoverShadow,
text, text,
TextColor TextColor
} from "./components"; } from "./components";
@ -80,6 +81,7 @@ export default function editor(theme: Theme) {
cornerRadius: 8, cornerRadius: 8,
padding: 4, padding: 4,
border: border(theme, "secondary"), border: border(theme, "secondary"),
shadow: popoverShadow(theme),
item: autocompleteItem, item: autocompleteItem,
hoveredItem: { hoveredItem: {
...autocompleteItem, ...autocompleteItem,

View file

@ -0,0 +1,20 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, popoverShadow } from "./components";
export default function HoverPopover(theme: Theme) {
return {
background: backgroundColor(theme, 500),
cornerRadius: 8,
padding: {
left: 8,
right: 8,
top: 4,
bottom: 4
},
shadow: popoverShadow(theme),
border: border(theme, "primary"),
margin: {
left: -14,
},
}
}

View file

@ -1,5 +1,5 @@
import Theme from "../themes/common/theme"; import Theme from "../themes/common/theme";
import { backgroundColor, border, player, shadow, text } from "./components"; import { backgroundColor, border, player, modalShadow, text } from "./components";
export default function picker(theme: Theme) { export default function picker(theme: Theme) {
return { return {
@ -48,6 +48,6 @@ export default function picker(theme: Theme) {
top: 7, top: 7,
}, },
}, },
shadow: shadow(theme), shadow: modalShadow(theme),
}; };
} }

View file

@ -1,6 +1,6 @@
import Theme from "../themes/common/theme"; import Theme from "../themes/common/theme";
import { withOpacity } from "../utils/color"; import { withOpacity } from "../utils/color";
import { backgroundColor, border, iconColor, shadow, text } from "./components"; import { backgroundColor, border, iconColor, modalShadow, text } from "./components";
import statusBar from "./statusBar"; import statusBar from "./statusBar";
export function workspaceBackground(theme: Theme) { export function workspaceBackground(theme: Theme) {
@ -164,7 +164,7 @@ export default function workspace(theme: Theme) {
cornerRadius: 6, cornerRadius: 6,
padding: 12, padding: 12,
border: border(theme, "primary"), border: border(theme, "primary"),
shadow: shadow(theme), shadow: modalShadow(theme),
}, },
notifications: { notifications: {
width: 380, width: 380,

View file

@ -14,7 +14,6 @@ export function createTheme(
name: string, name: string,
isLight: boolean, isLight: boolean,
ramps: { [rampName: string]: Scale }, ramps: { [rampName: string]: Scale },
blend?: number
): Theme { ): Theme {
if (isLight) { if (isLight) {
for (var rampName in ramps) { for (var rampName in ramps) {
@ -25,100 +24,99 @@ export function createTheme(
ramps.neutral = ramps.neutral.domain([0, 7]); ramps.neutral = ramps.neutral.domain([0, 7]);
} }
if (blend === undefined) { let blend = isLight ? 0.12 : 0.24;
blend = isLight ? 0.12 : 0.24;
}
function rampColor(ramp: Scale, index: number): ColorToken { function sample(ramp: Scale, index: number): ColorToken {
return color(ramp(index).hex()); return color(ramp(index).hex());
} }
const darkest = color(ramps.neutral(isLight ? 7 : 0).hex());
const backgroundColor = { const backgroundColor = {
// Title bar // Title bar
100: { 100: {
base: rampColor(ramps.neutral, 1.25), base: sample(ramps.neutral, 1.25),
hovered: rampColor(ramps.neutral, 1.5), hovered: sample(ramps.neutral, 1.5),
active: rampColor(ramps.neutral, 1.75), active: sample(ramps.neutral, 1.75),
}, },
// Midground (panels, etc) // Midground (panels, etc)
300: { 300: {
base: rampColor(ramps.neutral, 1), base: sample(ramps.neutral, 1),
hovered: rampColor(ramps.neutral, 1.25), hovered: sample(ramps.neutral, 1.25),
active: rampColor(ramps.neutral, 1.5), active: sample(ramps.neutral, 1.5),
}, },
// Editor // Editor
500: { 500: {
base: rampColor(ramps.neutral, 0), base: sample(ramps.neutral, 0),
hovered: rampColor(ramps.neutral, 0.25), hovered: sample(ramps.neutral, 0.25),
active: rampColor(ramps.neutral, 0.5), active: sample(ramps.neutral, 0.5),
}, },
on300: { on300: {
base: rampColor(ramps.neutral, 0), base: sample(ramps.neutral, 0),
hovered: rampColor(ramps.neutral, 0.25), hovered: sample(ramps.neutral, 0.25),
active: rampColor(ramps.neutral, 0.5), active: sample(ramps.neutral, 0.5),
}, },
on500: { on500: {
base: rampColor(ramps.neutral, 1.25), base: sample(ramps.neutral, 1.25),
hovered: rampColor(ramps.neutral, 1.5), hovered: sample(ramps.neutral, 1.5),
active: rampColor(ramps.neutral, 1.75), active: sample(ramps.neutral, 1.75),
}, },
ok: { ok: {
base: withOpacity(rampColor(ramps.green, 0.5), 0.15), base: withOpacity(sample(ramps.green, 0.5), 0.15),
hovered: withOpacity(rampColor(ramps.green, 0.5), 0.2), hovered: withOpacity(sample(ramps.green, 0.5), 0.2),
active: withOpacity(rampColor(ramps.green, 0.5), 0.25), active: withOpacity(sample(ramps.green, 0.5), 0.25),
}, },
error: { error: {
base: withOpacity(rampColor(ramps.red, 0.5), 0.15), base: withOpacity(sample(ramps.red, 0.5), 0.15),
hovered: withOpacity(rampColor(ramps.red, 0.5), 0.2), hovered: withOpacity(sample(ramps.red, 0.5), 0.2),
active: withOpacity(rampColor(ramps.red, 0.5), 0.25), active: withOpacity(sample(ramps.red, 0.5), 0.25),
}, },
warning: { warning: {
base: withOpacity(rampColor(ramps.yellow, 0.5), 0.15), base: withOpacity(sample(ramps.yellow, 0.5), 0.15),
hovered: withOpacity(rampColor(ramps.yellow, 0.5), 0.2), hovered: withOpacity(sample(ramps.yellow, 0.5), 0.2),
active: withOpacity(rampColor(ramps.yellow, 0.5), 0.25), active: withOpacity(sample(ramps.yellow, 0.5), 0.25),
}, },
info: { info: {
base: withOpacity(rampColor(ramps.blue, 0.5), 0.15), base: withOpacity(sample(ramps.blue, 0.5), 0.15),
hovered: withOpacity(rampColor(ramps.blue, 0.5), 0.2), hovered: withOpacity(sample(ramps.blue, 0.5), 0.2),
active: withOpacity(rampColor(ramps.blue, 0.5), 0.25), active: withOpacity(sample(ramps.blue, 0.5), 0.25),
}, },
}; };
const borderColor = { const borderColor = {
primary: rampColor(ramps.neutral, isLight ? 1.5 : 0), primary: sample(ramps.neutral, isLight ? 1.5 : 0),
secondary: rampColor(ramps.neutral, isLight ? 1.25 : 1), secondary: sample(ramps.neutral, isLight ? 1.25 : 1),
muted: rampColor(ramps.neutral, isLight ? 1 : 3), muted: sample(ramps.neutral, isLight ? 1 : 3),
active: rampColor(ramps.neutral, isLight ? 4 : 3), active: sample(ramps.neutral, isLight ? 4 : 3),
onMedia: withOpacity(rampColor(ramps.neutral, 0), 0.1), onMedia: withOpacity(darkest, 0.1),
ok: withOpacity(rampColor(ramps.green, 0.5), 0.15), ok: withOpacity(sample(ramps.green, 0.5), 0.15),
error: withOpacity(rampColor(ramps.red, 0.5), 0.15), error: withOpacity(sample(ramps.red, 0.5), 0.15),
warning: withOpacity(rampColor(ramps.yellow, 0.5), 0.15), warning: withOpacity(sample(ramps.yellow, 0.5), 0.15),
info: withOpacity(rampColor(ramps.blue, 0.5), 0.15), info: withOpacity(sample(ramps.blue, 0.5), 0.15),
}; };
const textColor = { const textColor = {
primary: rampColor(ramps.neutral, 6), primary: sample(ramps.neutral, 6),
secondary: rampColor(ramps.neutral, 5), secondary: sample(ramps.neutral, 5),
muted: rampColor(ramps.neutral, 5), muted: sample(ramps.neutral, 5),
placeholder: rampColor(ramps.neutral, 4), placeholder: sample(ramps.neutral, 4),
active: rampColor(ramps.neutral, 7), active: sample(ramps.neutral, 7),
feature: rampColor(ramps.blue, 0.5), feature: sample(ramps.blue, 0.5),
ok: rampColor(ramps.green, 0.5), ok: sample(ramps.green, 0.5),
error: rampColor(ramps.red, 0.5), error: sample(ramps.red, 0.5),
warning: rampColor(ramps.yellow, 0.5), warning: sample(ramps.yellow, 0.5),
info: rampColor(ramps.blue, 0.5), info: sample(ramps.blue, 0.5),
onMedia: rampColor(ramps.neutral, isLight ? 0 : 7), onMedia: darkest,
}; };
const player = { const player = {
1: buildPlayer(rampColor(ramps.blue, 0.5)), 1: buildPlayer(sample(ramps.blue, 0.5)),
2: buildPlayer(rampColor(ramps.green, 0.5)), 2: buildPlayer(sample(ramps.green, 0.5)),
3: buildPlayer(rampColor(ramps.magenta, 0.5)), 3: buildPlayer(sample(ramps.magenta, 0.5)),
4: buildPlayer(rampColor(ramps.orange, 0.5)), 4: buildPlayer(sample(ramps.orange, 0.5)),
5: buildPlayer(rampColor(ramps.violet, 0.5)), 5: buildPlayer(sample(ramps.violet, 0.5)),
6: buildPlayer(rampColor(ramps.cyan, 0.5)), 6: buildPlayer(sample(ramps.cyan, 0.5)),
7: buildPlayer(rampColor(ramps.red, 0.5)), 7: buildPlayer(sample(ramps.red, 0.5)),
8: buildPlayer(rampColor(ramps.yellow, 0.5)), 8: buildPlayer(sample(ramps.yellow, 0.5)),
}; };
const editor = { const editor = {
@ -126,16 +124,16 @@ export function createTheme(
indent_guide: borderColor.muted, indent_guide: borderColor.muted,
indent_guide_active: borderColor.secondary, indent_guide_active: borderColor.secondary,
line: { line: {
active: rampColor(ramps.neutral, 1), active: sample(ramps.neutral, 1),
highlighted: rampColor(ramps.neutral, 1.25), // TODO: Where is this used? highlighted: sample(ramps.neutral, 1.25), // TODO: Where is this used?
}, },
highlight: { highlight: {
selection: player[1].selectionColor, selection: player[1].selectionColor,
occurrence: withOpacity(rampColor(ramps.neutral, 3.5), blend), occurrence: withOpacity(sample(ramps.neutral, 3.5), blend),
activeOccurrence: withOpacity(rampColor(ramps.neutral, 3.5), blend * 2), // TODO: Not hooked up - https://github.com/zed-industries/zed/issues/751 activeOccurrence: withOpacity(sample(ramps.neutral, 3.5), blend * 2), // TODO: Not hooked up - https://github.com/zed-industries/zed/issues/751
matchingBracket: backgroundColor[500].active, // TODO: Not hooked up matchingBracket: backgroundColor[500].active, // TODO: Not hooked up
match: rampColor(ramps.violet, 0.15), match: sample(ramps.violet, 0.15),
activeMatch: withOpacity(rampColor(ramps.violet, 0.4), blend * 2), // TODO: Not hooked up - https://github.com/zed-industries/zed/issues/751 activeMatch: withOpacity(sample(ramps.violet, 0.4), blend * 2), // TODO: Not hooked up - https://github.com/zed-industries/zed/issues/751
related: backgroundColor[500].hovered, related: backgroundColor[500].hovered,
}, },
gutter: { gutter: {
@ -146,59 +144,59 @@ export function createTheme(
const syntax: Syntax = { const syntax: Syntax = {
primary: { primary: {
color: rampColor(ramps.neutral, 7), color: sample(ramps.neutral, 7),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
comment: { comment: {
color: rampColor(ramps.neutral, 5), color: sample(ramps.neutral, 5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
punctuation: { punctuation: {
color: rampColor(ramps.neutral, 6), color: sample(ramps.neutral, 6),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
constant: { constant: {
color: rampColor(ramps.neutral, 4), color: sample(ramps.neutral, 4),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
keyword: { keyword: {
color: rampColor(ramps.blue, 0.5), color: sample(ramps.blue, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
function: { function: {
color: rampColor(ramps.yellow, 0.5), color: sample(ramps.yellow, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
type: { type: {
color: rampColor(ramps.cyan, 0.5), color: sample(ramps.cyan, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
variant: { variant: {
color: rampColor(ramps.blue, 0.5), color: sample(ramps.blue, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
property: { property: {
color: rampColor(ramps.blue, 0.5), color: sample(ramps.blue, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
enum: { enum: {
color: rampColor(ramps.orange, 0.5), color: sample(ramps.orange, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
operator: { operator: {
color: rampColor(ramps.orange, 0.5), color: sample(ramps.orange, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
string: { string: {
color: rampColor(ramps.orange, 0.5), color: sample(ramps.orange, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
number: { number: {
color: rampColor(ramps.green, 0.5), color: sample(ramps.green, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
boolean: { boolean: {
color: rampColor(ramps.green, 0.5), color: sample(ramps.green, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
predictive: { predictive: {
@ -206,7 +204,7 @@ export function createTheme(
weight: fontWeights.normal, weight: fontWeights.normal,
}, },
title: { title: {
color: rampColor(ramps.yellow, 0.5), color: sample(ramps.yellow, 0.5),
weight: fontWeights.bold, weight: fontWeights.bold,
}, },
emphasis: { emphasis: {
@ -218,21 +216,20 @@ export function createTheme(
weight: fontWeights.bold, weight: fontWeights.bold,
}, },
linkUri: { linkUri: {
color: rampColor(ramps.green, 0.5), color: sample(ramps.green, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
underline: true, underline: true,
}, },
linkText: { linkText: {
color: rampColor(ramps.orange, 0.5), color: sample(ramps.orange, 0.5),
weight: fontWeights.normal, weight: fontWeights.normal,
italic: true, italic: true,
}, },
}; };
const shadowAlpha: NumberToken = { const shadow = withOpacity(
value: blend, color(ramps.neutral(isLight ? 7 : 0).darken().hex()),
type: "number", blend);
};
return { return {
name, name,
@ -243,6 +240,6 @@ export function createTheme(
editor, editor,
syntax, syntax,
player, player,
shadowAlpha, shadow,
}; };
} }

View file

@ -153,6 +153,6 @@ export default interface Theme {
6: Player; 6: Player;
7: Player; 7: Player;
8: Player; 8: Player;
}; },
shadowAlpha: NumberToken; shadow: ColorToken;
} }