Merge branch 'main' into elevations
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { text } from "./components";
|
||||
import contactFinder from "./contactFinder";
|
||||
import contactsPanel from "./contactsPanel";
|
||||
import contactsPopover from "./contactsPopover";
|
||||
import commandPalette from "./commandPalette";
|
||||
import editor from "./editor";
|
||||
@@ -12,8 +11,11 @@ import contextMenu from "./contextMenu";
|
||||
import projectDiagnostics from "./projectDiagnostics";
|
||||
import contactNotification from "./contactNotification";
|
||||
import updateNotification from "./updateNotification";
|
||||
import projectSharedNotification from "./projectSharedNotification";
|
||||
import tooltip from "./tooltip";
|
||||
import terminal from "./terminal";
|
||||
import contactList from "./contactList";
|
||||
import incomingCallNotification from "./incomingCallNotification";
|
||||
import { ColorScheme } from "../themes/common/colorScheme";
|
||||
|
||||
// export const panel = {
|
||||
@@ -26,16 +28,19 @@ export default function app(colorScheme: ColorScheme): Object {
|
||||
name: colorScheme.name,
|
||||
isLight: colorScheme.isLight,
|
||||
},
|
||||
commandPalette: commandPalette(colorScheme),
|
||||
contactNotification: contactNotification(colorScheme),
|
||||
projectSharedNotification: projectSharedNotification(colorScheme),
|
||||
incomingCallNotification: incomingCallNotification(colorScheme),
|
||||
picker: picker(colorScheme),
|
||||
workspace: workspace(colorScheme),
|
||||
contextMenu: contextMenu(colorScheme),
|
||||
editor: editor(colorScheme),
|
||||
projectDiagnostics: projectDiagnostics(colorScheme),
|
||||
commandPalette: commandPalette(colorScheme),
|
||||
projectPanel: projectPanel(colorScheme),
|
||||
contactsPopover: contactsPopover(colorScheme),
|
||||
contactsPanel: contactsPanel(colorScheme),
|
||||
contactFinder: contactFinder(colorScheme),
|
||||
contactList: contactList(colorScheme),
|
||||
search: search(colorScheme),
|
||||
breadcrumbs: {
|
||||
...text(colorScheme.lowest.top, "sans", "variant"),
|
||||
@@ -43,7 +48,6 @@ export default function app(colorScheme: ColorScheme): Object {
|
||||
left: 6,
|
||||
},
|
||||
},
|
||||
contactNotification: contactNotification(colorScheme),
|
||||
updateNotification: updateNotification(colorScheme),
|
||||
tooltip: tooltip(colorScheme),
|
||||
terminal: terminal(colorScheme.lowest),
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import picker from "./picker";
|
||||
import { ColorScheme } from "../themes/common/colorScheme";
|
||||
import { background, foreground } from "./components";
|
||||
import { background, border, foreground, text } from "./components";
|
||||
|
||||
export default function contactFinder(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.highest.top;
|
||||
|
||||
const sideMargin = 6;
|
||||
const contactButton = {
|
||||
background: background(layer, "variant"),
|
||||
color: foreground(layer, "variant"),
|
||||
@@ -13,7 +15,31 @@ export default function contactFinder(colorScheme: ColorScheme) {
|
||||
};
|
||||
|
||||
return {
|
||||
...picker(colorScheme),
|
||||
picker: {
|
||||
item: {
|
||||
...picker(colorScheme).item,
|
||||
margin: { left: sideMargin, right: sideMargin }
|
||||
},
|
||||
empty: picker(colorScheme).empty,
|
||||
inputEditor: {
|
||||
background: background(layer, "on"),
|
||||
cornerRadius: 6,
|
||||
text: text(layer, "mono",),
|
||||
placeholderText: text(layer, "mono", "variant", { size: "sm" }),
|
||||
selection: colorScheme.players[0],
|
||||
border: border(layer),
|
||||
padding: {
|
||||
bottom: 4,
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 4,
|
||||
},
|
||||
margin: {
|
||||
left: sideMargin,
|
||||
right: sideMargin,
|
||||
}
|
||||
}
|
||||
},
|
||||
rowHeight: 28,
|
||||
contactAvatar: {
|
||||
cornerRadius: 10,
|
||||
|
||||
@@ -13,6 +13,13 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
|
||||
let layer = colorScheme.lowest.middle;
|
||||
|
||||
const contactButton = {
|
||||
background: background(layer, "on"),
|
||||
color: foreground(layer, "on"),
|
||||
iconWidth: 8,
|
||||
buttonWidth: 16,
|
||||
cornerRadius: 8,
|
||||
};
|
||||
const projectRow = {
|
||||
guestAvatarSpacing: 4,
|
||||
height: 24,
|
||||
@@ -39,14 +46,6 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
},
|
||||
};
|
||||
|
||||
const contactButton = {
|
||||
background: background(layer, "on"),
|
||||
color: foreground(layer, "on"),
|
||||
iconWidth: 8,
|
||||
buttonWidth: 16,
|
||||
cornerRadius: 8,
|
||||
};
|
||||
|
||||
return {
|
||||
background: background(layer),
|
||||
padding: { top: 12, bottom: 0 },
|
||||
@@ -64,23 +63,16 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
top: 4,
|
||||
},
|
||||
margin: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
left: 6
|
||||
},
|
||||
},
|
||||
userQueryEditorHeight: 32,
|
||||
userQueryEditorHeight: 33,
|
||||
addContactButton: {
|
||||
margin: { left: 6, right: 12 },
|
||||
color: foreground(layer, "on"),
|
||||
buttonWidth: 16,
|
||||
buttonWidth: 28,
|
||||
iconWidth: 16,
|
||||
},
|
||||
privateButton: {
|
||||
iconWidth: 12,
|
||||
color: foreground(layer, "on"),
|
||||
cornerRadius: 5,
|
||||
buttonWidth: 12,
|
||||
},
|
||||
rowHeight: 28,
|
||||
sectionIconSize: 8,
|
||||
headerRow: {
|
||||
@@ -95,6 +87,26 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
background: background(layer, "active"),
|
||||
},
|
||||
},
|
||||
leaveCall: {
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
cornerRadius: 6,
|
||||
margin: {
|
||||
top: 1,
|
||||
},
|
||||
padding: {
|
||||
top: 1,
|
||||
bottom: 1,
|
||||
left: 7,
|
||||
right: 7,
|
||||
},
|
||||
...text(layer, "sans", "variant", { size: "xs" }),
|
||||
hover: {
|
||||
...text(layer, "sans", "hovered", { size: "xs" }),
|
||||
background: background(layer, "hovered"),
|
||||
border: border(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
contactRow: {
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
@@ -104,20 +116,22 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
background: background(layer, "active"),
|
||||
},
|
||||
},
|
||||
treeBranch: {
|
||||
color: borderColor(layer),
|
||||
width: 1,
|
||||
hover: {
|
||||
color: borderColor(layer, "hovered"),
|
||||
},
|
||||
active: {
|
||||
color: borderColor(layer, "active"),
|
||||
},
|
||||
},
|
||||
contactAvatar: {
|
||||
cornerRadius: 10,
|
||||
width: 18,
|
||||
},
|
||||
contactStatusFree: {
|
||||
cornerRadius: 4,
|
||||
padding: 4,
|
||||
margin: { top: 12, left: 12 },
|
||||
background: foreground(layer, "positive"),
|
||||
},
|
||||
contactStatusBusy: {
|
||||
cornerRadius: 4,
|
||||
padding: 4,
|
||||
margin: { top: 12, left: 12 },
|
||||
background: foreground(layer, "negative"),
|
||||
},
|
||||
contactUsername: {
|
||||
...text(layer, "mono", { size: "sm" }),
|
||||
margin: {
|
||||
@@ -136,6 +150,19 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
background: background(layer, "on"),
|
||||
color: foreground(layer, "on"),
|
||||
},
|
||||
callingIndicator: {
|
||||
...text(layer, "mono", "variant", { size: "xs" })
|
||||
},
|
||||
treeBranch: {
|
||||
color: borderColor(layer),
|
||||
width: 1,
|
||||
hover: {
|
||||
color: borderColor(layer),
|
||||
},
|
||||
active: {
|
||||
color: borderColor(layer),
|
||||
},
|
||||
},
|
||||
projectRow: {
|
||||
...projectRow,
|
||||
background: background(layer, "on"),
|
||||
@@ -144,22 +171,11 @@ export default function contactsPanel(colorScheme: ColorScheme) {
|
||||
...text(layer, "mono", { size: "sm" }),
|
||||
},
|
||||
hover: {
|
||||
background: background(layer, "hovered"),
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
active: {
|
||||
background: background(layer, "active"),
|
||||
background: background(layer, "on", "active"),
|
||||
},
|
||||
},
|
||||
inviteRow: {
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
},
|
||||
border: border(layer, { top: true }),
|
||||
text: text(layer, "sans", { size: "sm" }),
|
||||
hover: {
|
||||
text: text(layer, "sans", "hovered", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,29 @@
|
||||
import { ColorScheme } from "../themes/common/colorScheme";
|
||||
import { background } from "./components";
|
||||
import { background, border, text } from "./components";
|
||||
|
||||
export default function workspace(colorScheme: ColorScheme) {
|
||||
export default function contactsPopover(colorScheme: ColorScheme) {
|
||||
let layer = colorScheme.middle.middle;
|
||||
const sidePadding = 12;
|
||||
return {
|
||||
background: background(colorScheme.lowest.middle),
|
||||
};
|
||||
background: background(layer),
|
||||
cornerRadius: 6,
|
||||
padding: { top: 6 },
|
||||
margin: { top: -6 },
|
||||
shadow: colorScheme.middle.shadow,
|
||||
border: border(layer),
|
||||
width: 300,
|
||||
height: 400,
|
||||
inviteRowHeight: 28,
|
||||
inviteRow: {
|
||||
padding: {
|
||||
left: sidePadding,
|
||||
right: sidePadding,
|
||||
},
|
||||
border: border(layer, { top: true }),
|
||||
text: text(layer, "sans", "variant", { size: "sm" }),
|
||||
hover: {
|
||||
text: text(layer, "sans", "hovered", { size: "sm" }),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { fontWeights } from "../common";
|
||||
import { withOpacity } from "../utils/color";
|
||||
import {
|
||||
ColorScheme,
|
||||
Layer,
|
||||
@@ -143,8 +144,14 @@ export default function editor(colorScheme: ColorScheme) {
|
||||
indicator: foreground(layer, "variant"),
|
||||
verticalScale: 0.55,
|
||||
},
|
||||
diffBackgroundDeleted: background(layer, "negative"),
|
||||
diffBackgroundInserted: background(layer, "positive"),
|
||||
diff: {
|
||||
deleted: foreground(layer, "negative"),
|
||||
modified: foreground(layer, "warning"),
|
||||
inserted: foreground(layer, "positive"),
|
||||
removedWidthEm: 0.275,
|
||||
widthEm: 0.16,
|
||||
cornerRadius: 0.05,
|
||||
},
|
||||
documentHighlightReadBackground: elevation.ramps
|
||||
.neutral(0.5)
|
||||
.alpha(0.2)
|
||||
@@ -252,6 +259,20 @@ export default function editor(colorScheme: ColorScheme) {
|
||||
background: background(layer, "on", "hovered"),
|
||||
},
|
||||
},
|
||||
scrollbar: {
|
||||
width: 12,
|
||||
minHeightFactor: 1.0,
|
||||
track: {
|
||||
border: border(layer, "variant", { left: true }),
|
||||
},
|
||||
thumb: {
|
||||
background: withOpacity(borderColor(layer, "variant"), 0.5),
|
||||
border: {
|
||||
width: 1,
|
||||
color: withOpacity(borderColor(layer, 'variant'), 0.5),
|
||||
}
|
||||
}
|
||||
},
|
||||
compositionMark: {
|
||||
underline: {
|
||||
thickness: 1.0,
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { ColorScheme } from "../themes/common/colorScheme";
|
||||
import { background, border, text } from "./components";
|
||||
|
||||
export default function incomingCallNotification(colorScheme: ColorScheme): Object {
|
||||
let layer = colorScheme.middle.middle;
|
||||
const avatarSize = 48;
|
||||
return {
|
||||
windowHeight: 74,
|
||||
windowWidth: 380,
|
||||
background: background(layer),
|
||||
callerContainer: {
|
||||
padding: 12,
|
||||
},
|
||||
callerAvatar: {
|
||||
height: avatarSize,
|
||||
width: avatarSize,
|
||||
cornerRadius: avatarSize / 2,
|
||||
},
|
||||
callerMetadata: {
|
||||
margin: { left: 10 },
|
||||
},
|
||||
callerUsername: {
|
||||
...text(layer, "sans", { size: "sm", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
callerMessage: {
|
||||
...text(layer, "sans", "variant", { size: "xs" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
worktreeRoots: {
|
||||
...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
buttonWidth: 96,
|
||||
acceptButton: {
|
||||
background: background(layer, "accent"),
|
||||
border: border(layer, { left: true, bottom: true }),
|
||||
...text(layer, "sans", "positive", { size: "xs", weight: "extra_bold" })
|
||||
},
|
||||
declineButton: {
|
||||
border: border(layer, { left: true }),
|
||||
...text(layer, "sans", "negative", { size: "xs", weight: "extra_bold" })
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ColorScheme } from "../themes/common/colorScheme";
|
||||
import { background, border, text } from "./components";
|
||||
|
||||
export default function projectSharedNotification(colorScheme: ColorScheme): Object {
|
||||
let elevation = colorScheme.middle;
|
||||
let layer = elevation.middle;
|
||||
|
||||
const avatarSize = 48;
|
||||
return {
|
||||
windowHeight: 74,
|
||||
windowWidth: 380,
|
||||
background: background(layer,),
|
||||
ownerContainer: {
|
||||
padding: 12,
|
||||
},
|
||||
ownerAvatar: {
|
||||
height: avatarSize,
|
||||
width: avatarSize,
|
||||
cornerRadius: avatarSize / 2,
|
||||
},
|
||||
ownerMetadata: {
|
||||
margin: { left: 10 },
|
||||
},
|
||||
ownerUsername: {
|
||||
...text(layer, "sans", { size: "sm", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
message: {
|
||||
...text(layer, "sans", "variant", { size: "xs" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
worktreeRoots: {
|
||||
...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
|
||||
margin: { top: -3 },
|
||||
},
|
||||
buttonWidth: 96,
|
||||
openButton: {
|
||||
background: background(layer, "accent"),
|
||||
border: border(layer, { left: true, bottom: true, }),
|
||||
...text(layer, "sans", "accent", { size: "xs", weight: "extra_bold" })
|
||||
},
|
||||
dismissButton: {
|
||||
border: border(layer, { left: true }),
|
||||
...text(layer, "sans", "variant", { size: "xs", weight: "extra_bold" })
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -14,6 +14,24 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||
const elevation = colorScheme.lowest;
|
||||
const layer = elevation.bottom;
|
||||
const titlebarPadding = 6;
|
||||
const titlebarButton = {
|
||||
cornerRadius: 6,
|
||||
padding: {
|
||||
top: 1,
|
||||
bottom: 1,
|
||||
left: 8,
|
||||
right: 8,
|
||||
},
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
hover: {
|
||||
...text(layer, "sans", "hovered", { size: "xs" }),
|
||||
background: background(layer, "hovered"),
|
||||
border: border(elevation.top, "hovered"),
|
||||
},
|
||||
};
|
||||
const avatarWidth = 18;
|
||||
|
||||
return {
|
||||
background: background(layer),
|
||||
@@ -25,6 +43,14 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||
padding: 12,
|
||||
...text(layer, "sans", { size: "lg" }),
|
||||
},
|
||||
externalLocationMessage: {
|
||||
background: background(elevation.middle, "accent"),
|
||||
border: border(elevation.middle, "accent"),
|
||||
cornerRadius: 6,
|
||||
padding: 12,
|
||||
margin: { bottom: 8, right: 8 },
|
||||
...text(elevation.middle, "sans", "accent", { size: "xs" }),
|
||||
},
|
||||
leaderBorderOpacity: 0.7,
|
||||
leaderBorderWidth: 2.0,
|
||||
tabBar: tabBar(colorScheme),
|
||||
@@ -45,6 +71,8 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||
},
|
||||
statusBar: statusBar(colorScheme),
|
||||
titlebar: {
|
||||
avatarWidth,
|
||||
avatarMargin: 8,
|
||||
height: 33, // 32px + 1px for overlaid border
|
||||
background: background(layer),
|
||||
border: border(layer, { bottom: true, overlay: true }),
|
||||
@@ -57,15 +85,21 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||
title: text(layer, "sans", "variant"),
|
||||
|
||||
// Collaborators
|
||||
avatarWidth: 18,
|
||||
avatarMargin: 8,
|
||||
avatar: {
|
||||
cornerRadius: 10,
|
||||
cornerRadius: avatarWidth / 2,
|
||||
border: {
|
||||
color: "#00000088",
|
||||
width: 1,
|
||||
},
|
||||
},
|
||||
inactiveAvatar: {
|
||||
cornerRadius: avatarWidth / 2,
|
||||
border: {
|
||||
color: "#00000088",
|
||||
width: 1,
|
||||
},
|
||||
grayscale: true,
|
||||
},
|
||||
avatarRibbon: {
|
||||
height: 3,
|
||||
width: 12,
|
||||
@@ -75,20 +109,7 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||
// Sign in buttom
|
||||
// FlatButton, Variant
|
||||
signInPrompt: {
|
||||
...text(layer, "sans", { size: "xs" }),
|
||||
background: background(layer),
|
||||
border: border(layer),
|
||||
cornerRadius: 6,
|
||||
padding: {
|
||||
top: 1,
|
||||
bottom: 1,
|
||||
left: 8,
|
||||
right: 8,
|
||||
},
|
||||
hover: {
|
||||
...text(layer, "sans", "hovered", { size: "xs" }),
|
||||
background: background(layer, "hovered"),
|
||||
},
|
||||
...titlebarButton
|
||||
},
|
||||
|
||||
// Offline Indicator
|
||||
@@ -117,6 +138,30 @@ export default function workspace(colorScheme: ColorScheme) {
|
||||
},
|
||||
cornerRadius: 6,
|
||||
},
|
||||
toggleContactsButton: {
|
||||
cornerRadius: 6,
|
||||
color: foreground(layer),
|
||||
iconWidth: 8,
|
||||
buttonWidth: 20,
|
||||
active: {
|
||||
background: background(layer, "active"),
|
||||
color: foreground(layer, "active"),
|
||||
},
|
||||
hover: {
|
||||
background: background(layer, "hovered"),
|
||||
color: foreground(layer, "hovered"),
|
||||
},
|
||||
},
|
||||
toggleContactsBadge: {
|
||||
cornerRadius: 3,
|
||||
padding: 2,
|
||||
margin: { top: 3, left: 3 },
|
||||
border: border(layer),
|
||||
background: foreground(layer, "accent"),
|
||||
},
|
||||
shareButton: {
|
||||
...titlebarButton
|
||||
}
|
||||
},
|
||||
|
||||
toolbar: {
|
||||
|
||||
@@ -0,0 +1,293 @@
|
||||
import chroma, { Color, Scale } from "chroma-js";
|
||||
import { fontWeights } from "../../common";
|
||||
import { withOpacity } from "../../utils/color";
|
||||
import Theme, { buildPlayer, Syntax } from "./theme";
|
||||
|
||||
export function colorRamp(color: Color): Scale {
|
||||
let hue = color.hsl()[0];
|
||||
let endColor = chroma.hsl(hue, 0.88, 0.96);
|
||||
let startColor = chroma.hsl(hue, 0.68, 0.12);
|
||||
return chroma.scale([startColor, color, endColor]).mode("hsl");
|
||||
}
|
||||
|
||||
export function createTheme(
|
||||
name: string,
|
||||
isLight: boolean,
|
||||
color_ramps: { [rampName: string]: Scale }
|
||||
): Theme {
|
||||
let ramps: typeof color_ramps = {};
|
||||
// Chromajs mutates the underlying ramp when you call domain. This causes problems because
|
||||
// we now store the ramps object in the theme so that we can pull colors out of them.
|
||||
// So instead of calling domain and storing the result, we have to construct new ramps for each
|
||||
// theme so that we don't modify the passed in ramps.
|
||||
// This combined with an error in the type definitions for chroma js means we have to cast the colors
|
||||
// function to any in order to get the colors back out from the original ramps.
|
||||
if (isLight) {
|
||||
for (var rampName in color_ramps) {
|
||||
ramps[rampName] = chroma
|
||||
.scale((color_ramps[rampName].colors as any)())
|
||||
.domain([1, 0]);
|
||||
}
|
||||
ramps.neutral = chroma
|
||||
.scale((color_ramps.neutral.colors as any)())
|
||||
.domain([7, 0]);
|
||||
} else {
|
||||
for (var rampName in color_ramps) {
|
||||
ramps[rampName] = chroma
|
||||
.scale((color_ramps[rampName].colors as any)())
|
||||
.domain([0, 1]);
|
||||
}
|
||||
ramps.neutral = chroma
|
||||
.scale((color_ramps.neutral.colors as any)())
|
||||
.domain([0, 7]);
|
||||
}
|
||||
|
||||
let blend = isLight ? 0.12 : 0.24;
|
||||
|
||||
function sample(ramp: Scale, index: number): string {
|
||||
return ramp(index).hex();
|
||||
}
|
||||
const darkest = ramps.neutral(isLight ? 7 : 0).hex();
|
||||
|
||||
const backgroundColor = {
|
||||
// Title bar
|
||||
100: {
|
||||
base: sample(ramps.neutral, 1.25),
|
||||
hovered: sample(ramps.neutral, 1.5),
|
||||
active: sample(ramps.neutral, 1.75),
|
||||
},
|
||||
// Midground (panels, etc)
|
||||
300: {
|
||||
base: sample(ramps.neutral, 1),
|
||||
hovered: sample(ramps.neutral, 1.25),
|
||||
active: sample(ramps.neutral, 1.5),
|
||||
},
|
||||
// Editor
|
||||
500: {
|
||||
base: sample(ramps.neutral, 0),
|
||||
hovered: sample(ramps.neutral, 0.25),
|
||||
active: sample(ramps.neutral, 0.5),
|
||||
},
|
||||
on300: {
|
||||
base: sample(ramps.neutral, 0),
|
||||
hovered: sample(ramps.neutral, 0.5),
|
||||
active: sample(ramps.neutral, 1),
|
||||
},
|
||||
on500: {
|
||||
base: sample(ramps.neutral, 1),
|
||||
hovered: sample(ramps.neutral, 1.5),
|
||||
active: sample(ramps.neutral, 2),
|
||||
},
|
||||
ok: {
|
||||
base: withOpacity(sample(ramps.green, 0.5), 0.15),
|
||||
hovered: withOpacity(sample(ramps.green, 0.5), 0.2),
|
||||
active: withOpacity(sample(ramps.green, 0.5), 0.25),
|
||||
},
|
||||
error: {
|
||||
base: withOpacity(sample(ramps.red, 0.5), 0.15),
|
||||
hovered: withOpacity(sample(ramps.red, 0.5), 0.2),
|
||||
active: withOpacity(sample(ramps.red, 0.5), 0.25),
|
||||
},
|
||||
on500Error: {
|
||||
base: sample(ramps.red, 0.05),
|
||||
hovered: sample(ramps.red, 0.1),
|
||||
active: sample(ramps.red, 0.15),
|
||||
},
|
||||
warning: {
|
||||
base: withOpacity(sample(ramps.yellow, 0.5), 0.15),
|
||||
hovered: withOpacity(sample(ramps.yellow, 0.5), 0.2),
|
||||
active: withOpacity(sample(ramps.yellow, 0.5), 0.25),
|
||||
},
|
||||
on500Warning: {
|
||||
base: sample(ramps.yellow, 0.05),
|
||||
hovered: sample(ramps.yellow, 0.1),
|
||||
active: sample(ramps.yellow, 0.15),
|
||||
},
|
||||
info: {
|
||||
base: withOpacity(sample(ramps.blue, 0.5), 0.15),
|
||||
hovered: withOpacity(sample(ramps.blue, 0.5), 0.2),
|
||||
active: withOpacity(sample(ramps.blue, 0.5), 0.25),
|
||||
},
|
||||
on500Info: {
|
||||
base: sample(ramps.blue, 0.05),
|
||||
hovered: sample(ramps.blue, 0.1),
|
||||
active: sample(ramps.blue, 0.15),
|
||||
},
|
||||
on500Ok: {
|
||||
base: sample(ramps.green, 0.05),
|
||||
hovered: sample(ramps.green, 0.1),
|
||||
active: sample(ramps.green, 0.15)
|
||||
}
|
||||
};
|
||||
|
||||
const borderColor = {
|
||||
primary: sample(ramps.neutral, isLight ? 1.5 : 0),
|
||||
secondary: sample(ramps.neutral, isLight ? 1.25 : 1),
|
||||
muted: sample(ramps.neutral, isLight ? 1.25 : 3),
|
||||
active: sample(ramps.neutral, isLight ? 4 : 3),
|
||||
onMedia: withOpacity(darkest, 0.1),
|
||||
ok: sample(ramps.green, 0.3),
|
||||
error: sample(ramps.red, 0.3),
|
||||
warning: sample(ramps.yellow, 0.3),
|
||||
info: sample(ramps.blue, 0.3),
|
||||
};
|
||||
|
||||
const textColor = {
|
||||
primary: sample(ramps.neutral, 6),
|
||||
secondary: sample(ramps.neutral, 5),
|
||||
muted: sample(ramps.neutral, 4),
|
||||
placeholder: sample(ramps.neutral, 3),
|
||||
active: sample(ramps.neutral, 7),
|
||||
feature: sample(ramps.blue, 0.5),
|
||||
ok: sample(ramps.green, 0.5),
|
||||
error: sample(ramps.red, 0.5),
|
||||
warning: sample(ramps.yellow, 0.5),
|
||||
info: sample(ramps.blue, 0.5),
|
||||
onMedia: darkest,
|
||||
};
|
||||
|
||||
const player = {
|
||||
1: buildPlayer(sample(ramps.blue, 0.5)),
|
||||
2: buildPlayer(sample(ramps.green, 0.5)),
|
||||
3: buildPlayer(sample(ramps.magenta, 0.5)),
|
||||
4: buildPlayer(sample(ramps.orange, 0.5)),
|
||||
5: buildPlayer(sample(ramps.violet, 0.5)),
|
||||
6: buildPlayer(sample(ramps.cyan, 0.5)),
|
||||
7: buildPlayer(sample(ramps.red, 0.5)),
|
||||
8: buildPlayer(sample(ramps.yellow, 0.5)),
|
||||
};
|
||||
|
||||
const editor = {
|
||||
background: backgroundColor[500].base,
|
||||
indent_guide: borderColor.muted,
|
||||
indent_guide_active: borderColor.secondary,
|
||||
line: {
|
||||
active: sample(ramps.neutral, 1),
|
||||
highlighted: sample(ramps.neutral, 1.25), // TODO: Where is this used?
|
||||
},
|
||||
highlight: {
|
||||
selection: player[1].selectionColor,
|
||||
occurrence: withOpacity(sample(ramps.neutral, 3.5), blend),
|
||||
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
|
||||
match: sample(ramps.violet, 0.15),
|
||||
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,
|
||||
},
|
||||
gutter: {
|
||||
primary: textColor.placeholder,
|
||||
active: textColor.active,
|
||||
},
|
||||
};
|
||||
|
||||
const syntax: Syntax = {
|
||||
primary: {
|
||||
color: sample(ramps.neutral, 7),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
"variable.special": {
|
||||
color: sample(ramps.blue, 0.80),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
comment: {
|
||||
color: sample(ramps.neutral, 5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
punctuation: {
|
||||
color: sample(ramps.neutral, 6),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
constant: {
|
||||
color: sample(ramps.neutral, 4),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
keyword: {
|
||||
color: sample(ramps.blue, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
function: {
|
||||
color: sample(ramps.yellow, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
type: {
|
||||
color: sample(ramps.cyan, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
constructor: {
|
||||
color: sample(ramps.cyan, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
property: {
|
||||
color: sample(ramps.blue, 0.6),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
enum: {
|
||||
color: sample(ramps.orange, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
operator: {
|
||||
color: sample(ramps.orange, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
string: {
|
||||
color: sample(ramps.orange, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
number: {
|
||||
color: sample(ramps.green, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
boolean: {
|
||||
color: sample(ramps.green, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
predictive: {
|
||||
color: textColor.muted,
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
title: {
|
||||
color: sample(ramps.yellow, 0.5),
|
||||
weight: fontWeights.bold,
|
||||
},
|
||||
emphasis: {
|
||||
color: textColor.feature,
|
||||
weight: fontWeights.normal,
|
||||
},
|
||||
"emphasis.strong": {
|
||||
color: textColor.feature,
|
||||
weight: fontWeights.bold,
|
||||
},
|
||||
linkUri: {
|
||||
color: sample(ramps.green, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
underline: true,
|
||||
},
|
||||
linkText: {
|
||||
color: sample(ramps.orange, 0.5),
|
||||
weight: fontWeights.normal,
|
||||
italic: true,
|
||||
},
|
||||
};
|
||||
|
||||
const shadow = withOpacity(
|
||||
ramps
|
||||
.neutral(isLight ? 7 : 0)
|
||||
.darken()
|
||||
.hex(),
|
||||
blend
|
||||
);
|
||||
|
||||
return {
|
||||
name,
|
||||
isLight,
|
||||
backgroundColor,
|
||||
borderColor,
|
||||
textColor,
|
||||
iconColor: textColor,
|
||||
editor,
|
||||
syntax,
|
||||
player,
|
||||
shadow,
|
||||
ramps,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import { Scale } from "chroma-js";
|
||||
import { FontWeight } from "../../common";
|
||||
import { withOpacity } from "../../utils/color";
|
||||
|
||||
export interface SyntaxHighlightStyle {
|
||||
color: string;
|
||||
weight?: FontWeight;
|
||||
underline?: boolean;
|
||||
italic?: boolean;
|
||||
}
|
||||
|
||||
export interface Player {
|
||||
baseColor: string;
|
||||
cursorColor: string;
|
||||
selectionColor: string;
|
||||
borderColor: string;
|
||||
}
|
||||
export function buildPlayer(
|
||||
color: string,
|
||||
cursorOpacity?: number,
|
||||
selectionOpacity?: number,
|
||||
borderOpacity?: number
|
||||
) {
|
||||
return {
|
||||
baseColor: color,
|
||||
cursorColor: withOpacity(color, cursorOpacity || 1.0),
|
||||
selectionColor: withOpacity(color, selectionOpacity || 0.24),
|
||||
borderColor: withOpacity(color, borderOpacity || 0.8),
|
||||
};
|
||||
}
|
||||
|
||||
export interface BackgroundColorSet {
|
||||
base: string;
|
||||
hovered: string;
|
||||
active: string;
|
||||
}
|
||||
|
||||
export interface Syntax {
|
||||
primary: SyntaxHighlightStyle;
|
||||
comment: SyntaxHighlightStyle;
|
||||
punctuation: SyntaxHighlightStyle;
|
||||
constant: SyntaxHighlightStyle;
|
||||
keyword: SyntaxHighlightStyle;
|
||||
function: SyntaxHighlightStyle;
|
||||
type: SyntaxHighlightStyle;
|
||||
constructor: SyntaxHighlightStyle;
|
||||
property: SyntaxHighlightStyle;
|
||||
enum: SyntaxHighlightStyle;
|
||||
operator: SyntaxHighlightStyle;
|
||||
string: SyntaxHighlightStyle;
|
||||
number: SyntaxHighlightStyle;
|
||||
boolean: SyntaxHighlightStyle;
|
||||
predictive: SyntaxHighlightStyle;
|
||||
title: SyntaxHighlightStyle;
|
||||
emphasis: SyntaxHighlightStyle;
|
||||
linkUri: SyntaxHighlightStyle;
|
||||
linkText: SyntaxHighlightStyle;
|
||||
|
||||
[key: string]: SyntaxHighlightStyle;
|
||||
}
|
||||
|
||||
export default interface Theme {
|
||||
name: string;
|
||||
isLight: boolean;
|
||||
backgroundColor: {
|
||||
// Basically just Title Bar
|
||||
// Lowest background level
|
||||
100: BackgroundColorSet;
|
||||
// Tab bars, panels, popovers
|
||||
// Mid-ground
|
||||
300: BackgroundColorSet;
|
||||
// The editor
|
||||
// Foreground
|
||||
500: BackgroundColorSet;
|
||||
// Hacks for elements on top of the midground
|
||||
// Buttons in a panel, tab bar, or panel
|
||||
on300: BackgroundColorSet;
|
||||
// Hacks for elements on top of the editor
|
||||
on500: BackgroundColorSet;
|
||||
ok: BackgroundColorSet;
|
||||
on500Ok: BackgroundColorSet;
|
||||
error: BackgroundColorSet;
|
||||
on500Error: BackgroundColorSet;
|
||||
warning: BackgroundColorSet;
|
||||
on500Warning: BackgroundColorSet;
|
||||
info: BackgroundColorSet;
|
||||
on500Info: BackgroundColorSet;
|
||||
};
|
||||
borderColor: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
active: string;
|
||||
/**
|
||||
* Used for rendering borders on top of media like avatars, images, video, etc.
|
||||
*/
|
||||
onMedia: string;
|
||||
ok: string;
|
||||
error: string;
|
||||
warning: string;
|
||||
info: string;
|
||||
};
|
||||
textColor: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
placeholder: string;
|
||||
active: string;
|
||||
feature: string;
|
||||
ok: string;
|
||||
error: string;
|
||||
warning: string;
|
||||
info: string;
|
||||
onMedia: string;
|
||||
};
|
||||
iconColor: {
|
||||
primary: string;
|
||||
secondary: string;
|
||||
muted: string;
|
||||
placeholder: string;
|
||||
active: string;
|
||||
feature: string;
|
||||
ok: string;
|
||||
error: string;
|
||||
warning: string;
|
||||
info: string;
|
||||
};
|
||||
editor: {
|
||||
background: string;
|
||||
indent_guide: string;
|
||||
indent_guide_active: string;
|
||||
line: {
|
||||
active: string;
|
||||
highlighted: string;
|
||||
};
|
||||
highlight: {
|
||||
selection: string;
|
||||
occurrence: string;
|
||||
activeOccurrence: string;
|
||||
matchingBracket: string;
|
||||
match: string;
|
||||
activeMatch: string;
|
||||
related: string;
|
||||
};
|
||||
gutter: {
|
||||
primary: string;
|
||||
active: string;
|
||||
};
|
||||
};
|
||||
|
||||
syntax: Syntax;
|
||||
|
||||
player: {
|
||||
1: Player;
|
||||
2: Player;
|
||||
3: Player;
|
||||
4: Player;
|
||||
5: Player;
|
||||
6: Player;
|
||||
7: Player;
|
||||
8: Player;
|
||||
};
|
||||
shadow: string;
|
||||
ramps: { [rampName: string]: Scale };
|
||||
}
|
||||
Reference in New Issue
Block a user