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
+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",
},
};
}