Start loading new theme JSON format instead of TOML

Replaced remaining extends with javascript object extension.
Moved tokens/core.ts to tokens.ts and massaged the types to make it more
obvious when types don't match up.

Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Nathan Sobo
2022-04-04 12:13:59 -07:00
committed by Keith Simmons
parent 371ea7c552
commit 391aed3d66
23 changed files with 3283 additions and 2008 deletions
+7 -7
View File
@@ -7,11 +7,11 @@ import decamelizeTree from "./utils/decamelizeTree";
const themes = [dark, light];
for (let theme of themes) {
let styleTree = decamelizeTree(app(theme));
let styleTreeJSON = JSON.stringify(styleTree, null, 2);
let outPath = path.resolve(
`${__dirname}/../crates/zed/assets/themes/${theme.name}.json`
);
fs.writeFileSync(outPath, styleTreeJSON);
console.log(`Generated ${outPath}`);
let styleTree = decamelizeTree(app(theme));
let styleTreeJSON = JSON.stringify(styleTree, null, 2);
let outPath = path.resolve(
`${__dirname}/../crates/zed/assets/themes/${theme.name}.json`
);
fs.writeFileSync(outPath, styleTreeJSON);
console.log(`Generated ${outPath}`);
}
+31 -75
View File
@@ -1,6 +1,7 @@
import Theme from "../themes/theme";
import chatPanel from "./chatPanel";
import { backgroundColor, borderColor, text } from "./components";
import contactsPanel from "./contactsPanel";
import editor from "./editor";
import projectPanel from "./projectPanel";
import search from "./search";
@@ -8,83 +9,38 @@ import selectorModal from "./selectorModal";
import workspace from "./workspace";
export const panel = {
padding: { top: 12, left: 12, bottom: 12, right: 12 },
padding: { top: 12, left: 12, bottom: 12, right: 12 },
};
export default function app(theme: Theme): Object {
return {
selector: selectorModal(theme),
workspace: workspace(theme),
editor: editor(theme),
projectDiagnostics: {
background: backgroundColor(theme, 300),
tabIconSpacing: 4,
tabIconWidth: 13,
tabSummarySpacing: 10,
emptyMessage: {
...text(theme, "sans", "primary", { size: "lg" }),
},
statusBarItem: {
...text(theme, "sans", "muted"),
margin: {
right: 10,
return {
selector: selectorModal(theme),
workspace: workspace(theme),
editor: editor(theme),
projectDiagnostics: {
background: backgroundColor(theme, 300),
tabIconSpacing: 4,
tabIconWidth: 13,
tabSummarySpacing: 10,
emptyMessage: {
...text(theme, "sans", "primary", { size: "lg" }),
},
statusBarItem: {
...text(theme, "sans", "muted"),
margin: {
right: 10,
},
},
},
},
},
projectPanel: projectPanel(theme),
chatPanel: chatPanel(theme),
contactsPanel: {
...panel,
hostRowHeight: 28,
treeBranchColor: borderColor(theme, "muted"),
treeBranchWidth: 1,
hostAvatar: {
cornerRadius: 10,
width: 18,
},
hostUsername: {
...text(theme, "mono", "muted"),
padding: {
left: 8,
},
},
hoveredSharedProject: {
extends: "$contacts_panel.sharedProject",
background: theme.editor.line.active.value,
cornerRadius: 6,
},
hoveredUnsharedProject: {
extends: "$contacts_panel.unsharedProject",
background: theme.editor.line.active.value,
cornerRadius: 6,
},
project: {
guestAvatarSpacing: 4,
height: 24,
guestAvatar: {
cornerRadius: 8,
width: 14,
},
name: {
extends: text(theme, "mono", "secondary"),
margin: {
right: 6,
},
},
padding: {
left: 8,
},
},
sharedProject: {
extends: "$contactsPanel.project",
name: {
color: text(theme, "mono", "primary"),
},
},
unsharedProject: {
extends: "$contactsPanel.project",
},
},
search: search(theme),
};
projectPanel: projectPanel(theme),
chatPanel: chatPanel(theme),
contactsPanel: contactsPanel(theme),
search: search(theme),
breadcrumbs: {
...text(theme, "sans", "primary"),
padding: {
left: 6,
},
}
};
}
+7 -7
View File
@@ -1,25 +1,25 @@
import chroma from "chroma-js";
import Theme, { BackgroundColor, Weight } from "../themes/theme";
import core from "../tokens/core";
import Theme, { BackgroundColor } from "../themes/theme";
import { fontFamilies, fontSizes, FontWeight } from "../tokens";
import { Color } from "../utils/color";
export type TextColor = keyof Theme["textColor"];
export function text(
theme: Theme,
fontFamily: keyof typeof core.fontFamily,
fontFamily: keyof typeof fontFamilies,
color: TextColor,
properties?: {
size?: keyof typeof core["fontSize"];
weight?: Weight;
size?: keyof typeof fontSizes;
weight?: FontWeight;
underline?: boolean;
}
) {
const sizeKey = properties?.size || fontFamily === "sans" ? "sm" : "md";
const size = core.fontSize[sizeKey].value;
const size = fontSizes[sizeKey].value;
return {
family: core.fontFamily[fontFamily],
family: fontFamilies[fontFamily].value,
color: theme.textColor[color].value,
...properties,
size,
+61
View File
@@ -0,0 +1,61 @@
import Theme from "../themes/theme";
import { panel } from "./app";
import { borderColor, text } from "./components";
export default function(theme: Theme) {
const project = {
guestAvatarSpacing: 4,
height: 24,
guestAvatar: {
cornerRadius: 8,
width: 14,
},
name: {
...text(theme, "mono", "secondary"),
margin: {
right: 6,
},
},
padding: {
left: 8,
},
};
const sharedProject = {
...project,
name: {
...project.name,
...text(theme, "mono", "primary"),
},
};
return {
...panel,
hostRowHeight: 28,
treeBranchColor: borderColor(theme, "muted"),
treeBranchWidth: 1,
hostAvatar: {
cornerRadius: 10,
width: 18,
},
hostUsername: {
...text(theme, "mono", "muted"),
padding: {
left: 8,
},
},
project,
sharedProject,
hoveredSharedProject: {
...sharedProject,
background: theme.editor.line.active.value,
cornerRadius: 6,
},
unsharedProject: project,
hoveredUnsharedProject: {
...project,
background: theme.editor.line.active.value,
cornerRadius: 6,
},
}
}
+124 -121
View File
@@ -1,131 +1,134 @@
import Theme from "../themes/theme";
import {
backgroundColor,
border,
iconColor,
player,
text,
TextColor
backgroundColor,
border,
iconColor,
player,
text,
TextColor,
} from "./components";
export default function editor(theme: Theme) {
const autocompleteItem = {
cornerRadius: 6,
padding: {
bottom: 2,
left: 6,
right: 6,
top: 2,
},
};
function diagnostic(theme: Theme, color: TextColor) {
return {
textScaleFactor: 0.857,
header: {
border: border(theme, "primary", {
top: true,
}),
},
message: {
text: text(theme, "sans", color, { size: "sm" }),
highlightText: text(theme, "sans", color, {
size: "sm",
weight: "bold",
}),
},
const autocompleteItem = {
cornerRadius: 6,
padding: {
bottom: 2,
left: 6,
right: 6,
top: 2,
},
};
}
return {
textColor: theme.textColor.secondary.value,
background: backgroundColor(theme, 300),
activeLineBackground: theme.editor.line.active.value,
codeActionsIndicator: iconColor(theme, "secondary"),
diffBackgroundDeleted: backgroundColor(theme, "error"),
diffBackgroundInserted: backgroundColor(theme, "ok"),
documentHighlightReadBackground: theme.editor.highlight.occurrence.value,
documentHighlightWriteBackground: theme.editor.highlight.occurrence.value,
errorColor: theme.textColor.error,
gutterBackground: backgroundColor(theme, 300),
gutterPaddingFactor: 2.5,
highlightedLineBackground: theme.editor.line.highlighted.value,
lineNumber: theme.editor.gutter.primary.value,
lineNumberActive: theme.editor.gutter.active,
renameFade: 0.6,
unnecessaryCodeFade: 0.5,
selection: player(theme, 1).selection,
guestSelections: [
player(theme, 2).selection,
player(theme, 3).selection,
player(theme, 4).selection,
player(theme, 5).selection,
player(theme, 6).selection,
player(theme, 7).selection,
player(theme, 8).selection,
],
autocomplete: {
background: backgroundColor(theme, 100),
cornerRadius: 6,
padding: 6,
border: border(theme, "secondary"),
item: autocompleteItem,
hoveredItem: {
...autocompleteItem,
background: backgroundColor(theme, 100, "hovered"),
},
margin: {
left: -14,
},
matchHighlight: {
color: theme.syntax.keyword.color.value,
weight: theme.syntax.keyword.weight.value,
},
selectedItem: {
...autocompleteItem,
background: backgroundColor(theme, 100, "active"),
},
},
diagnosticHeader: {
background: theme.editor.background.value,
iconWidthFactor: 1.5,
textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these.
border: border(theme, "secondary", {
bottom: true,
top: true,
}),
code: {
...text(theme, "mono", "muted", { size: "sm" }),
margin: {
left: 10,
function diagnostic(theme: Theme, color: TextColor) {
return {
textScaleFactor: 0.857,
header: {
border: border(theme, "primary", {
top: true,
}),
},
message: {
text: text(theme, "sans", color, { size: "sm" }),
highlightText: text(theme, "sans", color, {
size: "sm",
weight: "bold",
}),
},
};
}
return {
textColor: theme.textColor.secondary.value,
background: backgroundColor(theme, 300),
activeLineBackground: theme.editor.line.active.value,
codeActionsIndicator: iconColor(theme, "secondary"),
diffBackgroundDeleted: backgroundColor(theme, "error"),
diffBackgroundInserted: backgroundColor(theme, "ok"),
documentHighlightReadBackground: theme.editor.highlight.occurrence.value,
documentHighlightWriteBackground: theme.editor.highlight.occurrence.value,
errorColor: theme.textColor.error.value,
gutterBackground: backgroundColor(theme, 300),
gutterPaddingFactor: 2.5,
highlightedLineBackground: theme.editor.line.highlighted.value,
lineNumber: theme.editor.gutter.primary.value,
lineNumberActive: theme.editor.gutter.active.value,
renameFade: 0.6,
unnecessaryCodeFade: 0.5,
selection: player(theme, 1).selection,
guestSelections: [
player(theme, 2).selection,
player(theme, 3).selection,
player(theme, 4).selection,
player(theme, 5).selection,
player(theme, 6).selection,
player(theme, 7).selection,
player(theme, 8).selection,
],
autocomplete: {
background: backgroundColor(theme, 100),
cornerRadius: 6,
padding: 6,
border: border(theme, "secondary"),
item: autocompleteItem,
hoveredItem: {
...autocompleteItem,
background: backgroundColor(theme, 100, "hovered"),
},
margin: {
left: -14,
},
matchHighlight: {
color: theme.syntax.keyword.color.value,
weight: theme.syntax.keyword.weight.value,
},
selectedItem: {
...autocompleteItem,
background: backgroundColor(theme, 100, "active"),
},
},
},
message: {
highlightText: text(theme, "sans", "primary", {
size: "sm",
weight: "bold",
}),
text: text(theme, "sans", "secondary", { size: "sm" }),
},
},
diagnosticPathHeader: {
background: theme.editor.line.active,
textScaleFactor: 0.857,
filename: text(theme, "mono", "primary", { size: "sm" }),
path: {
...text(theme, "mono", "muted", { size: "sm" }),
margin: {
left: 12,
diagnosticHeader: {
background: theme.editor.background.value,
iconWidthFactor: 1.5,
textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these.
border: border(theme, "secondary", {
bottom: true,
top: true,
}),
code: {
...text(theme, "mono", "muted", { size: "sm" }),
margin: {
left: 10,
},
},
message: {
highlightText: text(theme, "sans", "primary", {
size: "sm",
weight: "bold",
}),
text: text(theme, "sans", "secondary", { size: "sm" }),
},
},
},
},
errorDiagnostic: diagnostic(theme, "error"),
warningDiagnostic: diagnostic(theme, "warning"),
informationDiagnostic: diagnostic(theme, "info"),
hintDiagnostic: diagnostic(theme, "info"),
invalidErrorDiagnostic: diagnostic(theme, "muted"),
invalidHintDiagnostic: diagnostic(theme, "muted"),
invalidInformationDiagnostic: diagnostic(theme, "muted"),
invalidWarningDiagnostic: diagnostic(theme, "muted"),
};
diagnosticPathHeader: {
background: theme.editor.line.active.value,
textScaleFactor: 0.857,
filename: text(theme, "mono", "primary", { size: "sm" }),
path: {
...text(theme, "mono", "muted", { size: "sm" }),
margin: {
left: 12,
},
},
},
errorDiagnostic: diagnostic(theme, "error"),
warningDiagnostic: diagnostic(theme, "warning"),
informationDiagnostic: diagnostic(theme, "info"),
hintDiagnostic: diagnostic(theme, "info"),
invalidErrorDiagnostic: diagnostic(theme, "muted"),
invalidHintDiagnostic: diagnostic(theme, "muted"),
invalidInformationDiagnostic: diagnostic(theme, "muted"),
invalidWarningDiagnostic: diagnostic(theme, "muted"),
syntax: {
}
};
}
+5 -1
View File
@@ -24,7 +24,11 @@ export default function projectPanel(theme: Theme) {
backgroundColor(theme, 300, "hovered")
),
selectedEntry: entry(theme, "primary"),
hoveredSelectedEntry: entry(theme, "primary", "hovered"),
hoveredSelectedEntry: entry(
theme,
"primary",
backgroundColor(theme, 300, "hovered")
),
padding: {
top: 6,
},
+23 -21
View File
@@ -19,8 +19,28 @@ export default function search(theme: Theme) {
},
};
const editor = {
background: backgroundColor(theme, 500),
cornerRadius: 6,
minWidth: 200,
maxWidth: 500,
placeholderText: text(theme, "mono", "placeholder"),
selection: player(theme, 1).selection,
text: text(theme, "mono", "primary"),
border: border(theme, "primary"),
margin: {
right: 5,
},
padding: {
top: 3,
bottom: 3,
left: 14,
right: 14,
},
};
return {
matchBackground: theme.editor.highlight.match,
matchBackground: theme.editor.highlight.match.value,
tabIconSpacing: 4,
tabIconWidth: 14,
activeHoveredOptionButton: {
@@ -31,31 +51,13 @@ export default function search(theme: Theme) {
...optionButton,
background: backgroundColor(theme, 100),
},
editor: {
background: backgroundColor(theme, 500),
cornerRadius: 6,
minWidth: 200,
maxWidth: 500,
placeholderText: text(theme, "mono", "placeholder"),
selection: player(theme, 1).selection,
text: text(theme, "mono", "primary"),
border: border(theme, "primary"),
margin: {
right: 5,
},
padding: {
top: 3,
bottom: 3,
left: 14,
right: 14,
},
},
editor,
hoveredOptionButton: {
...optionButton,
background: backgroundColor(theme, 100),
},
invalidEditor: {
extends: "$search.editor",
...editor,
border: border(theme, "error"),
},
matchIndex: {
+5
View File
@@ -137,5 +137,10 @@ export default function workspace(theme: Theme) {
...text(theme, "mono", "secondary"),
padding: { left: 6 },
},
disconnectedOverlay: {
...text(theme, "sans", "primary"),
color: "#ffffff",
background: "#000000aa",
},
};
}
+243 -219
View File
@@ -1,249 +1,273 @@
import core from "../tokens/core";
import Theme, { NumberToken, Syntax } from "./theme";
const { color } = core;
import { colors, fontWeights, NumberToken } from "../tokens";
import Theme, { Syntax } from "./theme";
const backgroundColor = {
100: {
base: color.neutral[750],
hovered: color.neutral[750],
active: color.neutral[750],
focused: color.neutral[750],
},
300: {
base: color.neutral[800],
hovered: color.neutral[800],
active: color.neutral[800],
focused: color.neutral[800],
},
500: {
base: color.neutral[900],
hovered: color.neutral[900],
active: color.neutral[900],
focused: color.neutral[900],
},
ok: {
base: color.green[600],
hovered: color.green[600],
active: color.green[600],
focused: color.green[600],
},
error: {
base: color.red[400],
hovered: color.red[400],
active: color.red[400],
focused: color.red[400],
},
warning: {
base: color.amber[300],
hovered: color.amber[300],
active: color.amber[300],
focused: color.amber[300],
},
info: {
base: color.blue[500],
hovered: color.blue[500],
active: color.blue[500],
focused: color.blue[500],
},
100: {
base: colors.neutral[750],
hovered: colors.neutral[750],
active: colors.neutral[750],
focused: colors.neutral[750],
},
300: {
base: colors.neutral[800],
hovered: colors.neutral[800],
active: colors.neutral[800],
focused: colors.neutral[800],
},
500: {
base: colors.neutral[900],
hovered: colors.neutral[900],
active: colors.neutral[900],
focused: colors.neutral[900],
},
ok: {
base: colors.green[600],
hovered: colors.green[600],
active: colors.green[600],
focused: colors.green[600],
},
error: {
base: colors.red[400],
hovered: colors.red[400],
active: colors.red[400],
focused: colors.red[400],
},
warning: {
base: colors.amber[300],
hovered: colors.amber[300],
active: colors.amber[300],
focused: colors.amber[300],
},
info: {
base: colors.blue[500],
hovered: colors.blue[500],
active: colors.blue[500],
focused: colors.blue[500],
},
};
const borderColor = {
primary: color.neutral[850],
secondary: color.neutral[700],
muted: color.neutral[750],
focused: color.neutral[100],
active: color.neutral[500],
ok: color.neutral[1000],
error: color.neutral[1000],
warning: color.neutral[1000],
info: color.neutral[1000],
primary: colors.neutral[850],
secondary: colors.neutral[700],
muted: colors.neutral[750],
focused: colors.neutral[100],
active: colors.neutral[500],
ok: colors.neutral[1000],
error: colors.neutral[1000],
warning: colors.neutral[1000],
info: colors.neutral[1000],
};
const textColor = {
primary: color.neutral[150],
secondary: color.neutral[350],
muted: color.neutral[550],
placeholder: color.neutral[750],
active: color.neutral[0],
//TODO: (design) define feature and it's correct value
feature: color.sky[500],
ok: color.green[600],
error: color.red[400],
warning: color.amber[300],
info: color.blue[500],
primary: colors.neutral[150],
secondary: colors.neutral[350],
muted: colors.neutral[550],
placeholder: colors.neutral[750],
active: colors.neutral[0],
//TODO: (design) define feature and it's correct value
feature: colors.sky[500],
ok: colors.green[600],
error: colors.red[400],
warning: colors.amber[300],
info: colors.blue[500],
};
const iconColor = {
primary: color.neutral[300],
secondary: color.neutral[500],
muted: color.neutral[600],
placeholder: color.neutral[700],
active: color.neutral[50],
//TODO: (design) define feature and it's correct value
feature: color.sky[500],
ok: color.green[600],
error: color.red[400],
warning: color.amber[300],
info: color.blue[500],
primary: colors.neutral[300],
secondary: colors.neutral[500],
muted: colors.neutral[600],
placeholder: colors.neutral[700],
active: colors.neutral[50],
//TODO: (design) define feature and it's correct value
feature: colors.sky[500],
ok: colors.green[600],
error: colors.red[400],
warning: colors.amber[300],
info: colors.blue[500],
};
const player = {
1: {
baseColor: color.blue[600],
cursorColor: color.blue[600],
selectionColor: color.blue[600],
borderColor: color.blue[600],
},
2: {
baseColor: color.indigo[500],
cursorColor: color.indigo[500],
selectionColor: color.indigo[500],
borderColor: color.indigo[500],
},
3: {
baseColor: color.green[500],
cursorColor: color.green[500],
selectionColor: color.green[500],
borderColor: color.green[500],
},
4: {
baseColor: color.orange[500],
cursorColor: color.orange[500],
selectionColor: color.orange[500],
borderColor: color.orange[500],
},
5: {
baseColor: color.purple[500],
cursorColor: color.purple[500],
selectionColor: color.purple[500],
borderColor: color.purple[500],
},
6: {
baseColor: color.teal[400],
cursorColor: color.teal[400],
selectionColor: color.teal[400],
borderColor: color.teal[400],
},
7: {
baseColor: color.pink[400],
cursorColor: color.pink[400],
selectionColor: color.pink[400],
borderColor: color.pink[400],
},
8: {
baseColor: color.yellow[400],
cursorColor: color.yellow[400],
selectionColor: color.yellow[400],
borderColor: color.yellow[400],
},
1: {
baseColor: colors.blue[600],
cursorColor: colors.blue[600],
selectionColor: colors.blue[600],
borderColor: colors.blue[600],
},
2: {
baseColor: colors.indigo[500],
cursorColor: colors.indigo[500],
selectionColor: colors.indigo[500],
borderColor: colors.indigo[500],
},
3: {
baseColor: colors.green[500],
cursorColor: colors.green[500],
selectionColor: colors.green[500],
borderColor: colors.green[500],
},
4: {
baseColor: colors.orange[500],
cursorColor: colors.orange[500],
selectionColor: colors.orange[500],
borderColor: colors.orange[500],
},
5: {
baseColor: colors.purple[500],
cursorColor: colors.purple[500],
selectionColor: colors.purple[500],
borderColor: colors.purple[500],
},
6: {
baseColor: colors.teal[400],
cursorColor: colors.teal[400],
selectionColor: colors.teal[400],
borderColor: colors.teal[400],
},
7: {
baseColor: colors.pink[400],
cursorColor: colors.pink[400],
selectionColor: colors.pink[400],
borderColor: colors.pink[400],
},
8: {
baseColor: colors.yellow[400],
cursorColor: colors.yellow[400],
selectionColor: colors.yellow[400],
borderColor: colors.yellow[400],
},
};
// TODO: Fixup
const editor = {
background: backgroundColor[500].base,
indent_guide: borderColor.muted,
indent_guide_active: borderColor.secondary,
line: {
active: color.neutral[0],
highlighted: color.neutral[0],
inserted: backgroundColor.ok.active,
deleted: backgroundColor.error.active,
modified: backgroundColor.info.active,
},
highlight: {
selection: player[1].selectionColor,
occurrence: backgroundColor[500].active,
activeOccurrence: color.neutral[0],
matchingBracket: color.neutral[0],
match: color.neutral[0],
activeMatch: color.neutral[0],
related: color.neutral[0],
},
gutter: {
primary: color.neutral[0],
active: color.neutral[0],
},
background: backgroundColor[500].base,
indent_guide: borderColor.muted,
indent_guide_active: borderColor.secondary,
line: {
active: colors.neutral[0],
highlighted: colors.neutral[0],
inserted: backgroundColor.ok.active,
deleted: backgroundColor.error.active,
modified: backgroundColor.info.active,
},
highlight: {
selection: player[1].selectionColor,
occurrence: backgroundColor[500].active,
activeOccurrence: colors.neutral[0],
matchingBracket: colors.neutral[0],
match: colors.neutral[0],
activeMatch: colors.neutral[0],
related: colors.neutral[0],
},
gutter: {
primary: colors.neutral[0],
active: colors.neutral[0],
},
};
const syntax: Syntax = {
primary: {
color: textColor.primary,
weight: { value: "normal", type: "fontWeight" },
},
comment: {
color: color.lime[200],
weight: { value: "normal", type: "fontWeight" },
},
punctuation: {
color: textColor.primary,
weight: { value: "normal", type: "fontWeight" },
},
constant: {
color: color.neutral[150],
weight: { value: "normal", type: "fontWeight" },
},
keyword: {
color: color.sky[400],
weight: { value: "normal", type: "fontWeight" },
},
function: {
color: color.yellow[200],
weight: { value: "normal", type: "fontWeight" },
},
type: {
color: color.teal[300],
weight: { value: "normal", type: "fontWeight" },
},
variant: {
color: color.teal[300],
weight: { value: "normal", type: "fontWeight" },
},
property: {
color: color.sky[300],
weight: { value: "normal", type: "fontWeight" },
},
enum: {
color: color.sky[400],
weight: { value: "normal", type: "fontWeight" },
},
operator: {
color: color.sky[400],
weight: { value: "normal", type: "fontWeight" },
},
string: {
color: color.orange[300],
weight: { value: "normal", type: "fontWeight" },
},
number: {
color: color.neutral[150],
weight: { value: "normal", type: "fontWeight" },
},
boolean: {
color: color.neutral[150],
weight: { value: "normal", type: "fontWeight" },
},
predictive: {
color: textColor.muted,
weight: { value: "normal", type: "fontWeight" },
},
primary: {
color: textColor.primary,
weight: fontWeights.normal,
},
comment: {
color: colors.lime[200],
weight: fontWeights.normal,
},
punctuation: {
color: textColor.primary,
weight: fontWeights.normal,
},
constant: {
color: colors.neutral[150],
weight: fontWeights.normal,
},
keyword: {
color: colors.sky[400],
weight: fontWeights.normal,
},
function: {
color: colors.yellow[200],
weight: fontWeights.normal,
},
type: {
color: colors.teal[300],
weight: fontWeights.normal,
},
variant: {
color: colors.teal[300],
weight: fontWeights.normal,
},
property: {
color: colors.sky[300],
weight: fontWeights.normal,
},
enum: {
color: colors.sky[400],
weight: fontWeights.normal,
},
operator: {
color: colors.sky[400],
weight: fontWeights.normal,
},
string: {
color: colors.orange[300],
weight: fontWeights.normal,
},
number: {
color: colors.neutral[150],
weight: fontWeights.normal,
},
boolean: {
color: colors.neutral[150],
weight: fontWeights.normal,
},
predictive: {
color: textColor.muted,
weight: fontWeights.normal,
},
title: {
color: colors.sky[500],
weight: fontWeights.bold,
},
emphasis: {
color: textColor.active,
weight: fontWeights.normal,
},
emphasisStrong: {
color: textColor.active,
weight: fontWeights.bold,
},
linkUrl: {
color: colors.lime[500],
weight: fontWeights.normal,
// TODO: add underline
},
linkText: {
color: colors.orange[500],
weight: fontWeights.normal,
// TODO: add italic
},
listMarker: {
color: colors.sky[400],
weight: fontWeights.normal,
}
};
const shadowAlpha: NumberToken = {
value: 0.32,
type: "number",
value: 0.32,
type: "number",
};
const theme: Theme = {
name: "dark",
backgroundColor,
borderColor,
textColor,
iconColor,
editor,
syntax,
player,
shadowAlpha,
name: "dark",
backgroundColor,
borderColor,
textColor,
iconColor,
editor,
syntax,
player,
shadowAlpha,
};
export default theme;
+161 -137
View File
@@ -1,143 +1,141 @@
import core from "../tokens/core";
import Theme, { NumberToken, Syntax } from "./theme";
const { color } = core;
import { colors, fontWeights, NumberToken } from "../tokens";
import Theme, { Syntax } from "./theme";
// TODO: Replace with light values
const backgroundColor = {
100: {
base: color.neutral[750],
hovered: color.neutral[750],
active: color.neutral[750],
focused: color.neutral[750],
base: colors.neutral[750],
hovered: colors.neutral[750],
active: colors.neutral[750],
focused: colors.neutral[750],
},
300: {
base: color.neutral[800],
hovered: color.neutral[800],
active: color.neutral[800],
focused: color.neutral[800],
base: colors.neutral[800],
hovered: colors.neutral[800],
active: colors.neutral[800],
focused: colors.neutral[800],
},
500: {
base: color.neutral[900],
hovered: color.neutral[900],
active: color.neutral[900],
focused: color.neutral[900],
base: colors.neutral[900],
hovered: colors.neutral[900],
active: colors.neutral[900],
focused: colors.neutral[900],
},
ok: {
base: color.green[600],
hovered: color.green[600],
active: color.green[600],
focused: color.green[600],
base: colors.green[600],
hovered: colors.green[600],
active: colors.green[600],
focused: colors.green[600],
},
error: {
base: color.red[400],
hovered: color.red[400],
active: color.red[400],
focused: color.red[400],
base: colors.red[400],
hovered: colors.red[400],
active: colors.red[400],
focused: colors.red[400],
},
warning: {
base: color.amber[300],
hovered: color.amber[300],
active: color.amber[300],
focused: color.amber[300],
base: colors.amber[300],
hovered: colors.amber[300],
active: colors.amber[300],
focused: colors.amber[300],
},
info: {
base: color.blue[500],
hovered: color.blue[500],
active: color.blue[500],
focused: color.blue[500],
base: colors.blue[500],
hovered: colors.blue[500],
active: colors.blue[500],
focused: colors.blue[500],
},
};
const borderColor = {
primary: color.neutral[850],
secondary: color.neutral[700],
muted: color.neutral[750],
focused: color.neutral[100],
active: color.neutral[500],
ok: color.neutral[1000],
error: color.neutral[1000],
warning: color.neutral[1000],
info: color.neutral[1000],
primary: colors.neutral[850],
secondary: colors.neutral[700],
muted: colors.neutral[750],
focused: colors.neutral[100],
active: colors.neutral[500],
ok: colors.neutral[1000],
error: colors.neutral[1000],
warning: colors.neutral[1000],
info: colors.neutral[1000],
};
const textColor = {
primary: color.neutral[150],
secondary: color.neutral[350],
muted: color.neutral[550],
placeholder: color.neutral[750],
active: color.neutral[0],
primary: colors.neutral[150],
secondary: colors.neutral[350],
muted: colors.neutral[550],
placeholder: colors.neutral[750],
active: colors.neutral[0],
//TODO: (design) define feature and it's correct value
feature: color.sky[500],
ok: color.green[600],
error: color.red[400],
warning: color.amber[300],
info: color.blue[500],
feature: colors.sky[500],
ok: colors.green[600],
error: colors.red[400],
warning: colors.amber[300],
info: colors.blue[500],
};
const iconColor = {
primary: color.neutral[300],
secondary: color.neutral[500],
muted: color.neutral[600],
placeholder: color.neutral[700],
active: color.neutral[50],
primary: colors.neutral[300],
secondary: colors.neutral[500],
muted: colors.neutral[600],
placeholder: colors.neutral[700],
active: colors.neutral[50],
//TODO: (design) define feature and it's correct value
feature: color.sky[500],
ok: color.green[600],
error: color.red[400],
warning: color.amber[300],
info: color.blue[500],
feature: colors.sky[500],
ok: colors.green[600],
error: colors.red[400],
warning: colors.amber[300],
info: colors.blue[500],
};
const player = {
1: {
baseColor: color.blue[600],
cursorColor: color.blue[600],
selectionColor: color.blue[600],
borderColor: color.blue[600],
baseColor: colors.blue[600],
cursorColor: colors.blue[600],
selectionColor: colors.blue[600],
borderColor: colors.blue[600],
},
2: {
baseColor: color.indigo[500],
cursorColor: color.indigo[500],
selectionColor: color.indigo[500],
borderColor: color.indigo[500],
baseColor: colors.indigo[500],
cursorColor: colors.indigo[500],
selectionColor: colors.indigo[500],
borderColor: colors.indigo[500],
},
3: {
baseColor: color.green[500],
cursorColor: color.green[500],
selectionColor: color.green[500],
borderColor: color.green[500],
baseColor: colors.green[500],
cursorColor: colors.green[500],
selectionColor: colors.green[500],
borderColor: colors.green[500],
},
4: {
baseColor: color.orange[500],
cursorColor: color.orange[500],
selectionColor: color.orange[500],
borderColor: color.orange[500],
baseColor: colors.orange[500],
cursorColor: colors.orange[500],
selectionColor: colors.orange[500],
borderColor: colors.orange[500],
},
5: {
baseColor: color.purple[500],
cursorColor: color.purple[500],
selectionColor: color.purple[500],
borderColor: color.purple[500],
baseColor: colors.purple[500],
cursorColor: colors.purple[500],
selectionColor: colors.purple[500],
borderColor: colors.purple[500],
},
6: {
baseColor: color.teal[400],
cursorColor: color.teal[400],
selectionColor: color.teal[400],
borderColor: color.teal[400],
baseColor: colors.teal[400],
cursorColor: colors.teal[400],
selectionColor: colors.teal[400],
borderColor: colors.teal[400],
},
7: {
baseColor: color.pink[400],
cursorColor: color.pink[400],
selectionColor: color.pink[400],
borderColor: color.pink[400],
baseColor: colors.pink[400],
cursorColor: colors.pink[400],
selectionColor: colors.pink[400],
borderColor: colors.pink[400],
},
8: {
baseColor: color.yellow[400],
cursorColor: color.yellow[400],
selectionColor: color.yellow[400],
borderColor: color.yellow[400],
baseColor: colors.yellow[400],
cursorColor: colors.yellow[400],
selectionColor: colors.yellow[400],
borderColor: colors.yellow[400],
},
};
@@ -147,88 +145,114 @@ const editor = {
indent_guide: borderColor.muted,
indent_guide_active: borderColor.secondary,
line: {
active: color.neutral[0],
highlighted: color.neutral[0],
inserted: backgroundColor.ok.active,
deleted: backgroundColor.error.active,
modified: backgroundColor.info.active,
active: colors.neutral[0],
highlighted: colors.neutral[0],
inserted: backgroundColor.ok.active,
deleted: backgroundColor.error.active,
modified: backgroundColor.info.active,
},
highlight: {
selection: player[1].selectionColor,
occurrence: backgroundColor[500].active,
activeOccurrence: color.neutral[0],
matchingBracket: color.neutral[0],
match: color.neutral[0],
activeMatch: color.neutral[0],
related: color.neutral[0],
selection: player[1].selectionColor,
occurrence: backgroundColor[500].active,
activeOccurrence: colors.neutral[0],
matchingBracket: colors.neutral[0],
match: colors.neutral[0],
activeMatch: colors.neutral[0],
related: colors.neutral[0],
},
gutter: {
primary: color.neutral[0],
active: color.neutral[0],
primary: colors.neutral[0],
active: colors.neutral[0],
},
};
const syntax: Syntax = {
primary: {
color: textColor.primary,
weight: { value: "normal", type: "fontWeight" },
color: textColor.primary,
weight: fontWeights.normal,
},
comment: {
color: color.lime[200],
weight: { value: "normal", type: "fontWeight" },
color: colors.lime[200],
weight: fontWeights.normal,
},
punctuation: {
color: textColor.primary,
weight: { value: "normal", type: "fontWeight" },
color: textColor.primary,
weight: fontWeights.normal,
},
constant: {
color: color.neutral[150],
weight: { value: "normal", type: "fontWeight" },
color: colors.neutral[150],
weight: fontWeights.normal,
},
keyword: {
color: color.sky[400],
weight: { value: "normal", type: "fontWeight" },
color: colors.sky[400],
weight: fontWeights.normal,
},
function: {
color: color.yellow[200],
weight: { value: "normal", type: "fontWeight" },
color: colors.yellow[200],
weight: fontWeights.normal,
},
type: {
color: color.teal[300],
weight: { value: "normal", type: "fontWeight" },
color: colors.teal[300],
weight: fontWeights.normal,
},
variant: {
color: color.teal[300],
weight: { value: "normal", type: "fontWeight" },
color: colors.teal[300],
weight: fontWeights.normal,
},
property: {
color: color.sky[300],
weight: { value: "normal", type: "fontWeight" },
color: colors.sky[300],
weight: fontWeights.normal,
},
enum: {
color: color.sky[400],
weight: { value: "normal", type: "fontWeight" },
color: colors.sky[400],
weight: fontWeights.normal,
},
operator: {
color: color.sky[400],
weight: { value: "normal", type: "fontWeight" },
color: colors.sky[400],
weight: fontWeights.normal,
},
string: {
color: color.orange[300],
weight: { value: "normal", type: "fontWeight" },
color: colors.orange[300],
weight: fontWeights.normal,
},
number: {
color: color.neutral[150],
weight: { value: "normal", type: "fontWeight" },
color: colors.neutral[150],
weight: fontWeights.normal,
},
boolean: {
color: color.neutral[150],
weight: { value: "normal", type: "fontWeight" },
color: colors.neutral[150],
weight: fontWeights.normal,
},
predictive: {
color: textColor.muted,
weight: { value: "normal", type: "fontWeight" },
color: textColor.muted,
weight: fontWeights.normal,
},
title: {
color: colors.sky[500],
weight: fontWeights.bold,
},
emphasis: {
color: textColor.active,
weight: fontWeights.normal,
},
emphasisStrong: {
color: textColor.active,
weight: fontWeights.bold,
},
linkUrl: {
color: colors.lime[500],
weight: fontWeights.normal,
// TODO: add underline
},
linkText: {
color: colors.orange[500],
weight: fontWeights.normal,
// TODO: add italic
},
listMarker: {
color: colors.sky[400],
weight: fontWeights.normal,
}
};
const shadowAlpha: NumberToken = {
+10 -27
View File
@@ -1,32 +1,8 @@
export interface NumberToken {
value: number,
type: "number"
}
export type Color = string;
export interface ColorToken {
value: Color;
type: "color";
step?: number
}
export type Weight =
| "thin"
| "extra_light"
| "light"
| "normal"
| "medium"
| "semibold"
| "bold"
| "extra_bold"
| "black";
export interface WeightToken {
value: Weight,
type: "fontWeight"
}
import { FontWeightToken, ColorToken, NumberToken } from "../tokens";
export interface SyntaxHighlightStyle {
color: ColorToken;
weight: WeightToken;
weight: FontWeightToken;
}
export interface Player {
@@ -43,7 +19,7 @@ export interface BackgroundColor {
focused: ColorToken;
}
export interface Syntax {
export interface Syntax {
primary: SyntaxHighlightStyle;
comment: SyntaxHighlightStyle;
punctuation: SyntaxHighlightStyle;
@@ -59,6 +35,13 @@ export interface Syntax {
number: SyntaxHighlightStyle;
boolean: SyntaxHighlightStyle;
predictive: SyntaxHighlightStyle;
// TODO: Either move the following or rename
title: SyntaxHighlightStyle;
emphasis: SyntaxHighlightStyle;
emphasisStrong: SyntaxHighlightStyle;
linkUrl: SyntaxHighlightStyle;
linkText: SyntaxHighlightStyle;
listMarker: SyntaxHighlightStyle;
};
export default interface Theme {
+102
View File
@@ -0,0 +1,102 @@
import { colorRamp } from "./utils/color";
interface Token<V, T> {
value: V,
type: T
}
export type FontFamily = string;
export type FontFamilyToken = Token<FontFamily, "fontFamily">;
function fontFamily(value: FontFamily): FontFamilyToken {
return {
value,
type: "fontFamily"
}
}
export const fontFamilies = {
sans: fontFamily("Zed Sans"),
mono: fontFamily("Zed Mono"),
}
export type FontSize = number;
export type FontSizeToken = Token<FontSize, "fontSize">;
function fontSize(value: FontSize) {
return {
value,
type: "fontSize"
};
}
export const fontSizes = {
"3xs": fontSize(8),
"2xs": fontSize(10),
xs: fontSize(12),
sm: fontSize(14),
md: fontSize(16),
lg: fontSize(18),
xl: fontSize(20),
};
export type FontWeight =
| "thin"
| "extra_light"
| "light"
| "normal"
| "medium"
| "semibold"
| "bold"
| "extra_bold"
| "black";
export type FontWeightToken = Token<FontWeight, "fontWeight">;
function fontWeight(value: FontWeight): FontWeightToken {
return {
value,
type: "fontWeight"
};
}
export const fontWeights = {
"thin": fontWeight("thin"),
"extra_light": fontWeight("extra_light"),
"light": fontWeight("light"),
"normal": fontWeight("normal"),
"medium": fontWeight("medium"),
"semibold": fontWeight("semibold"),
"bold": fontWeight("bold"),
"extra_bold": fontWeight("extra_bold"),
"black": fontWeight("black"),
}
export type Color = string;
export interface ColorToken {
value: Color,
type: "color",
step?: number,
}
export const colors = {
neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }),
rose: colorRamp("#F43F5EFF"),
red: colorRamp("#EF4444FF"),
orange: colorRamp("#F97316FF"),
amber: colorRamp("#F59E0BFF"),
yellow: colorRamp("#EAB308FF"),
lime: colorRamp("#84CC16FF"),
green: colorRamp("#22C55EFF"),
emerald: colorRamp("#10B981FF"),
teal: colorRamp("#14B8A6FF"),
cyan: colorRamp("#06BBD4FF"),
sky: colorRamp("#0EA5E9FF"),
blue: colorRamp("#3B82F6FF"),
indigo: colorRamp("#6366F1FF"),
violet: colorRamp("#8B5CF6FF"),
purple: colorRamp("#A855F7FF"),
fuschia: colorRamp("#D946E4FF"),
pink: colorRamp("#EC4899FF"),
}
export type NumberToken = Token<number, "number">;
export default {
fontFamilies,
fontSizes,
fontWeights,
colors,
};
-58
View File
@@ -1,58 +0,0 @@
import { colorRamp } from "../utils/color";
export default {
fontFamily: {
sans: "Zed Sans",
mono: "Zed Mono",
},
fontSize: {
"3xs": {
value: "8",
type: "fontSizes",
},
"2xs": {
value: "10",
type: "fontSizes",
},
xs: {
value: "12",
type: "fontSizes",
},
sm: {
value: "14",
type: "fontSizes",
},
md: {
value: "16",
type: "fontSizes",
},
lg: {
value: "18",
type: "fontSizes",
},
xl: {
value: "20",
type: "fontSizes",
},
},
color: {
neutral: colorRamp(["black", "white"], { steps: 21, increment: 50 }),
rose: colorRamp("#F43F5EFF"),
red: colorRamp("#EF4444FF"),
orange: colorRamp("#F97316FF"),
amber: colorRamp("#F59E0BFF"),
yellow: colorRamp("#EAB308FF"),
lime: colorRamp("#84CC16FF"),
green: colorRamp("#22C55EFF"),
emerald: colorRamp("#10B981FF"),
teal: colorRamp("#14B8A6FF"),
cyan: colorRamp("#06BBD4FF"),
sky: colorRamp("#0EA5E9FF"),
blue: colorRamp("#3B82F6FF"),
indigo: colorRamp("#6366F1FF"),
violet: colorRamp("#8B5CF6FF"),
purple: colorRamp("#A855F7FF"),
fuschia: colorRamp("#D946E4FF"),
pink: colorRamp("#EC4899FF"),
},
};