Finish dark.ts initial port and restructure files to get ready for build script

Build script currently fails to type check. Not sure whats going on. Will fix in the morning.

Co-authored-by: Nate Butler <nate@zed.dev>
This commit is contained in:
Keith Simmons
2022-04-04 12:13:59 -07:00
co-authored by Nate Butler
parent f11e0aeda9
commit bfeb6abb4b
15 changed files with 396 additions and 128 deletions
+90
View File
@@ -0,0 +1,90 @@
import chatPanel from "./chat-panel";
import { backgroundColor, borderColor, text } from "./components";
import editor from "./editor";
import projectPanel from "./project-panel";
import search from "./search";
import selectorModal from "./selector-modal";
import Theme from "./theme";
import workspace from "./workspace";
export const panel = {
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,
},
},
},
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),
};
}
+108
View File
@@ -0,0 +1,108 @@
import { panel } from "./app";
import {
backgroundColor,
border,
player,
shadow,
text,
TextColor,
} from "./components";
import Theme from "./theme";
export default function chatPanel(theme: Theme) {
function channelSelectItem(
theme: Theme,
textColor: TextColor,
hovered: boolean
) {
return {
name: text(theme, "sans", textColor),
padding: 4,
hash: {
...text(theme, "sans", "muted"),
margin: {
right: 8,
},
},
background: hovered ? backgroundColor(theme, 300, "hovered") : undefined,
cornerRadius: hovered ? 6 : 0,
};
}
const message = {
body: text(theme, "sans", "secondary"),
timestamp: text(theme, "sans", "muted"),
padding: {
bottom: 6,
},
sender: {
...text(theme, "sans", "primary", { weight: "bold" }),
margin: {
right: 8,
},
},
};
return {
...panel,
channelName: text(theme, "sans", "primary", { weight: "bold" }),
channelNameHash: {
...text(theme, "sans", "muted"),
padding: {
right: 8,
},
},
channelSelect: {
header: {
...channelSelectItem(theme, "primary", false),
padding: {
bottom: 4,
left: 0,
},
},
item: channelSelectItem(theme, "secondary", false),
hoveredItem: channelSelectItem(theme, "secondary", true),
activeItem: channelSelectItem(theme, "primary", false),
hoveredActiveItem: channelSelectItem(theme, "primary", true),
menu: {
background: backgroundColor(theme, 500),
cornerRadius: 6,
padding: 4,
border: border(theme, "primary"),
shadow: shadow(theme),
},
},
signInPrompt: text(theme, "sans", "secondary", { underline: true }),
hoveredSignInPrompt: text(theme, "sans", "primary", { underline: true }),
message,
pendingMessage: {
...message,
body: {
...message.body,
color: theme.textColor.muted.value,
},
sender: {
...message.sender,
color: theme.textColor.muted.value,
},
timestamp: {
...message.timestamp,
color: theme.textColor.muted.value,
},
},
inputEditor: {
background: backgroundColor(theme, 300),
cornerRadius: 6,
text: text(theme, "mono", "primary"),
placeholderText: text(theme, "mono", "muted"),
selection: player(theme, 1).selection,
border: border(theme, "primary"),
padding: {
bottom: 7,
left: 8,
right: 8,
top: 7,
},
},
};
}
+91
View File
@@ -0,0 +1,91 @@
import chroma from "chroma-js";
import core from "../tokens/core";
import { Color } from "../utils/color";
import Theme, { BackgroundColor, Weight } from "../themes/theme";
export type TextColor = keyof Theme["textColor"];
export function text(
theme: Theme,
fontFamily: keyof typeof core.fontFamily,
color: TextColor,
properties?: {
size?: keyof typeof core["fontSize"];
weight?: Weight;
underline?: boolean;
}
) {
const sizeKey = properties.size || fontFamily === "sans" ? "sm" : "md";
const size = core.fontSize[sizeKey].value;
return {
family: core.fontFamily[fontFamily],
color: theme.textColor[color].value,
...properties,
size,
};
}
export interface BorderOptions {
width?: number;
top?: boolean;
bottom?: boolean;
left?: boolean;
right?: boolean;
overlay?: boolean;
}
export function border(
theme: Theme,
color: keyof Theme["borderColor"],
options?: BorderOptions
) {
return {
color: borderColor(theme, color),
width: 1,
...options,
};
}
export function borderColor(theme: Theme, color: keyof Theme["borderColor"]) {
return theme.borderColor[color].value;
}
export function iconColor(theme: Theme, color: keyof Theme["iconColor"]) {
return theme.iconColor[color].value;
}
export interface Player {
selection: {
cursor: Color;
selection: Color;
};
}
export function player(
theme: Theme,
playerNumber: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8
): Player {
return {
selection: {
cursor: theme.player[playerNumber].cursorColor.value,
selection: theme.player[playerNumber].selectionColor.value,
},
};
}
export function backgroundColor(
theme: Theme,
name: keyof Theme["backgroundColor"],
state?: keyof BackgroundColor
): Color {
return theme.backgroundColor[name][state || "base"].value;
}
export function shadow(theme: Theme) {
return {
blur: 16,
color: chroma("black").alpha(theme.shadowAlpha.value).hex(),
offset: [0, 2],
};
}
+131
View File
@@ -0,0 +1,131 @@
import {
backgroundColor,
border,
iconColor,
player,
text,
TextColor
} from "./components";
import Theme from "./theme";
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",
}),
},
};
}
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,
},
},
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,
},
},
},
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"),
};
}
+32
View File
@@ -0,0 +1,32 @@
import { panel } from "./app";
import { backgroundColor, iconColor, text, TextColor } from "./components";
import Theme from "../themes/theme";
import { Color } from "../utils/color";
export default function projectPanel(theme: Theme) {
function entry(theme: Theme, textColor: TextColor, background?: Color) {
return {
height: 22,
background,
iconColor: iconColor(theme, "muted"),
iconSize: 8,
iconSpacing: 8,
text: text(theme, "mono", textColor),
};
}
return {
...panel,
entry: entry(theme, "secondary"),
hoveredEntry: entry(
theme,
"secondary",
backgroundColor(theme, 300, "hovered")
),
selectedEntry: entry(theme, "primary"),
hoveredSelectedEntry: entry(theme, "primary", "hovered"),
padding: {
top: 6,
},
};
}
+80
View File
@@ -0,0 +1,80 @@
import { backgroundColor, border, player, text } from "./components";
import Theme from "./theme";
export default function search(theme: Theme) {
const optionButton = {
...text(theme, "mono", "secondary"),
background: backgroundColor(theme, 300),
cornerRadius: 6,
border: border(theme, "primary"),
margin: {
left: 1,
right: 1,
},
padding: {
bottom: 1,
left: 6,
right: 6,
top: 1,
},
};
return {
background: backgroundColor(theme, 300),
matchBackground: theme.editor.highlight.match,
tabIconSpacing: 4,
tabIconWidth: 14,
activeHoveredOptionButton: {
...optionButton,
background: backgroundColor(theme, 100),
},
activeOptionButton: {
...optionButton,
background: backgroundColor(theme, 100),
},
editor: {
background: backgroundColor(theme, 500),
cornerRadius: 6,
maxWidth: 400,
placeholderText: text(theme, "mono", "placeholder"),
selection: player(theme, 1).selection,
text: text(theme, "mono", "primary"),
border: border(theme, "primary"),
margin: {
bottom: 5,
left: 5,
right: 5,
top: 5,
},
padding: {
bottom: 3,
left: 13,
right: 13,
top: 3,
},
},
hoveredOptionButton: {
...optionButton,
background: backgroundColor(theme, 100),
},
invalidEditor: {
extends: "$search.editor",
border: border(theme, "error"),
},
matchIndex: {
...text(theme, "mono", "secondary"),
padding: 6,
},
optionButton,
optionButtonGroup: {
padding: {
left: 2,
right: 2,
},
},
resultsStatus: {
...text(theme, "mono", "primary"),
size: 18,
},
};
}
+59
View File
@@ -0,0 +1,59 @@
import { backgroundColor, border, player, shadow, text } from "./components";
import Theme from "./theme";
export default function selectorModal(theme: Theme): Object {
const item = {
padding: {
bottom: 4,
left: 16,
right: 16,
top: 4,
},
cornerRadius: 6,
text: text(theme, "sans", "secondary"),
highlightText: text(theme, "sans", "feature", { weight: "bold" }),
};
const activeItem = {
...item,
background: backgroundColor(theme, 500, "active"),
text: text(theme, "sans", "primary"),
};
return {
background: backgroundColor(theme, 500),
cornerRadius: 6,
padding: 8,
item,
activeItem,
border: border(theme, "primary"),
empty: {
text: text(theme, "sans", "muted"),
padding: {
bottom: 4,
left: 16,
right: 16,
top: 8,
},
},
inputEditor: {
background: backgroundColor(theme, 300),
corner_radius: 6,
placeholderText: text(theme, "sans", "placeholder"),
selection: player(theme, 1).selection,
text: text(theme, "mono", "primary"),
border: border(theme, "primary"),
padding: {
bottom: 7,
left: 16,
right: 16,
top: 7,
},
},
margin: {
bottom: 52,
top: 52,
},
shadow: shadow(theme),
};
}
+133
View File
@@ -0,0 +1,133 @@
import { backgroundColor, border, iconColor, text } from "./components";
import Theme from "./theme";
export default function workspace(theme: Theme) {
const signInPrompt = {
...text(theme, "sans", "secondary"),
size: 13,
underline: true,
padding: {
right: 8,
},
};
const tab = {
height: 34,
iconClose: iconColor(theme, "secondary"),
iconCloseActive: iconColor(theme, "active"),
iconConflict: iconColor(theme, "warning"),
iconDirty: iconColor(theme, "info"),
iconWidth: 8,
spacing: 10,
text: text(theme, "mono", "secondary"),
border: border(theme, "primary", {
left: true,
bottom: true,
overlay: true,
}),
padding: {
left: 12,
right: 12,
},
};
const activeTab = {
...tab,
background: backgroundColor(theme, 300),
text: text(theme, "mono", "primary"),
border: {
...tab.border,
bottom: false,
},
};
const sidebarItem = {
height: 32,
iconColor: iconColor(theme, "secondary"),
iconSize: 18,
};
const sidebar = {
width: 30,
border: border(theme, "primary", { right: true }),
item: sidebarItem,
activeItem: {
...sidebarItem,
iconColor: iconColor(theme, "primary"),
},
resizeHandle: {
background: border(theme, "primary").color,
padding: {
left: 1,
},
},
};
return {
background: backgroundColor(theme, 500),
leaderBorderOpacity: 0.7,
leaderBorderWidth: 2.0,
tab,
activeTab,
leftSidebar: {
...sidebar,
border: border(theme, "primary", { right: true }),
},
rightSidebar: {
...sidebar,
border: border(theme, "primary", { left: true }),
},
paneDivider: {
color: border(theme, "primary").color,
width: 1,
},
status_bar: {
height: 24,
itemSpacing: 8,
padding: {
left: 6,
right: 6,
},
cursorPosition: text(theme, "sans", "muted"),
diagnosticMessage: text(theme, "sans", "muted"),
lspMessage: text(theme, "sans", "muted"),
},
titlebar: {
avatarWidth: 18,
height: 32,
shareIconColor: iconColor(theme, "secondary"),
shareIconActiveColor: iconColor(theme, "active"),
title: text(theme, "sans", "primary"),
avatar: {
cornerRadius: 10,
border: {
color: "#00000088",
width: 1,
},
},
avatarRibbon: {
height: 3,
width: 12,
},
border: border(theme, "primary", { bottom: true }),
signInPrompt,
hoveredSignInPrompt: {
...signInPrompt,
...text(theme, "mono", "active"),
},
offlineIcon: {
color: iconColor(theme, "muted"),
width: 16,
padding: {
right: 4,
},
},
outdatedWarning: {
...text(theme, "sans", "muted"),
size: 13,
},
},
toolbar: {
height: 44,
},
};
}