Merge branch 'main' into screen-sharing

# Conflicts:
#	crates/collab/src/integration_tests.rs
#	crates/collab/src/main.rs
#	styles/src/styleTree/workspace.ts
This commit is contained in:
Antonio Scandurra
2022-10-21 14:29:45 +02:00
75 changed files with 2438 additions and 1903 deletions
+37 -28
View File
@@ -1,5 +1,3 @@
import Theme from "../themes/common/theme";
import chatPanel from "./chatPanel";
import { text } from "./components";
import contactFinder from "./contactFinder";
import contactsPopover from "./contactsPopover";
@@ -18,40 +16,51 @@ 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 = {
padding: { top: 12, bottom: 12 },
};
export default function app(theme: Theme): Object {
export default function app(colorScheme: ColorScheme): Object {
return {
meta: {
name: theme.name,
isLight: theme.isLight
name: colorScheme.name,
isLight: colorScheme.isLight,
},
picker: picker(theme),
workspace: workspace(theme),
contextMenu: contextMenu(theme),
editor: editor(theme),
projectDiagnostics: projectDiagnostics(theme),
commandPalette: commandPalette(theme),
projectPanel: projectPanel(theme),
chatPanel: chatPanel(theme),
contactsPopover: contactsPopover(theme),
contactList: contactList(theme),
contactFinder: contactFinder(theme),
search: search(theme),
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),
projectPanel: projectPanel(colorScheme),
contactsPopover: contactsPopover(colorScheme),
contactFinder: contactFinder(colorScheme),
contactList: contactList(colorScheme),
search: search(colorScheme),
breadcrumbs: {
...text(theme, "sans", "secondary"),
...text(colorScheme.highest, "sans", "variant"),
padding: {
left: 6,
},
},
contactNotification: contactNotification(theme),
updateNotification: updateNotification(theme),
projectSharedNotification: projectSharedNotification(theme),
incomingCallNotification: incomingCallNotification(theme),
tooltip: tooltip(theme),
terminal: terminal(theme),
updateNotification: updateNotification(colorScheme),
tooltip: tooltip(colorScheme),
terminal: terminal(colorScheme),
colorScheme: {
...colorScheme,
players: Object.values(colorScheme.players),
ramps: {
neutral: colorScheme.ramps.neutral.colors(100, "hex"),
red: colorScheme.ramps.red.colors(100, "hex"),
orange: colorScheme.ramps.orange.colors(100, "hex"),
yellow: colorScheme.ramps.yellow.colors(100, "hex"),
green: colorScheme.ramps.green.colors(100, "hex"),
cyan: colorScheme.ramps.cyan.colors(100, "hex"),
blue: colorScheme.ramps.blue.colors(100, "hex"),
violet: colorScheme.ramps.violet.colors(100, "hex"),
magenta: colorScheme.ramps.magenta.colors(100, "hex"),
},
},
};
}
-108
View File
@@ -1,108 +0,0 @@
import Theme from "../themes/common/theme";
import { panel } from "./app";
import {
backgroundColor,
border,
player,
text,
TextColor,
popoverShadow,
} from "./components";
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", { size: "sm" }),
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: popoverShadow(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,
},
sender: {
...message.sender,
color: theme.textColor.muted,
},
timestamp: {
...message.timestamp,
color: theme.textColor.muted,
},
},
inputEditor: {
background: backgroundColor(theme, 500),
cornerRadius: 6,
text: text(theme, "mono", "primary"),
placeholderText: text(theme, "mono", "placeholder", { size: "sm" }),
selection: player(theme, 1).selection,
border: border(theme, "secondary"),
padding: {
bottom: 7,
left: 8,
right: 8,
top: 7,
},
},
};
}
+16 -12
View File
@@ -1,25 +1,29 @@
import Theme from "../themes/common/theme";
import { text, backgroundColor, border } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { withOpacity } from "../utils/color";
import { text, background } from "./components";
export default function commandPalette(theme: Theme) {
export default function commandPalette(colorScheme: ColorScheme) {
let layer = colorScheme.highest;
return {
keystrokeSpacing: 8,
key: {
text: text(theme, "mono", "secondary", { size: "xs" }),
cornerRadius: 4,
background: backgroundColor(theme, "on300"),
border: border(theme, "secondary"),
text: text(layer, "mono", "variant", "default", { size: "xs" }),
cornerRadius: 2,
background: background(layer, "on"),
padding: {
top: 2,
bottom: 2,
left: 8,
right: 8,
top: 1,
bottom: 1,
left: 6,
right: 6,
},
margin: {
top: 1,
bottom: 1,
left: 2,
},
active: {
text: text(theme, "mono", "active", { size: "xs" }),
text: text(layer, "mono", "on", "default", { size: "xs" }),
background: withOpacity(background(layer, "on"), 0.2),
},
},
};
+175 -79
View File
@@ -1,31 +1,157 @@
import Theme, { BackgroundColorSet } from "../themes/common/theme";
import { fontFamilies, fontSizes, FontWeight } from "../common";
import { Layer, Styles, StyleSets, Style } from "../themes/common/colorScheme";
export type TextColor = keyof Theme["textColor"];
export function text(
theme: Theme,
fontFamily: keyof typeof fontFamilies,
color: TextColor,
properties?: {
size?: keyof typeof fontSizes;
weight?: FontWeight;
underline?: boolean;
function isStyleSet(key: any): key is StyleSets {
return [
"base",
"variant",
"on",
"accent",
"positive",
"warning",
"negative",
].includes(key);
}
function isStyle(key: any): key is Styles {
return ["default", "active", "disabled", "hovered", "pressed", "inverted"].includes(key);
}
function getStyle(
layer: Layer,
possibleStyleSetOrStyle?: any,
possibleStyle?: any
): Style {
let styleSet: StyleSets = "base";
let style: Styles = "default";
if (isStyleSet(possibleStyleSetOrStyle)) {
styleSet = possibleStyleSetOrStyle;
} else if (isStyle(possibleStyleSetOrStyle)) {
style = possibleStyleSetOrStyle;
}
if (isStyle(possibleStyle)) {
style = possibleStyle;
}
return layer[styleSet][style];
}
export function background(layer: Layer, style?: Styles): string;
export function background(
layer: Layer,
styleSet?: StyleSets,
style?: Styles
): string;
export function background(
layer: Layer,
styleSetOrStyles?: StyleSets | Styles,
style?: Styles
): string {
return getStyle(layer, styleSetOrStyles, style).background;
}
export function borderColor(layer: Layer, style?: Styles): string;
export function borderColor(
layer: Layer,
styleSet?: StyleSets,
style?: Styles
): string;
export function borderColor(
layer: Layer,
styleSetOrStyles?: StyleSets | Styles,
style?: Styles
): string {
return getStyle(layer, styleSetOrStyles, style).border;
}
export function foreground(layer: Layer, style?: Styles): string;
export function foreground(
layer: Layer,
styleSet?: StyleSets,
style?: Styles
): string;
export function foreground(
layer: Layer,
styleSetOrStyles?: StyleSets | Styles,
style?: Styles
): string {
return getStyle(layer, styleSetOrStyles, style).foreground;
}
interface Text {
family: keyof typeof fontFamilies;
color: string;
size: number;
weight?: FontWeight;
underline?: boolean;
}
interface TextProperties {
size?: keyof typeof fontSizes;
weight?: FontWeight;
underline?: boolean;
}
export function text(
layer: Layer,
fontFamily: keyof typeof fontFamilies,
styleSet: StyleSets,
style: Styles,
properties?: TextProperties
): Text;
export function text(
layer: Layer,
fontFamily: keyof typeof fontFamilies,
styleSet: StyleSets,
properties?: TextProperties
): Text;
export function text(
layer: Layer,
fontFamily: keyof typeof fontFamilies,
style: Styles,
properties?: TextProperties
): Text;
export function text(
layer: Layer,
fontFamily: keyof typeof fontFamilies,
properties?: TextProperties
): Text;
export function text(
layer: Layer,
fontFamily: keyof typeof fontFamilies,
styleSetStyleOrProperties?: StyleSets | Styles | TextProperties,
styleOrProperties?: Styles | TextProperties,
properties?: TextProperties
) {
let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties);
if (typeof styleSetStyleOrProperties === "object") {
properties = styleSetStyleOrProperties;
}
if (typeof styleOrProperties === "object") {
properties = styleOrProperties;
}
let size = fontSizes[properties?.size || "sm"];
return {
family: fontFamilies[fontFamily],
color: theme.textColor[color],
color: style.foreground,
...properties,
size,
};
}
export function textColor(theme: Theme, color: TextColor) {
return theme.textColor[color];
export interface Border {
color: string;
width: number;
top?: boolean;
bottom?: boolean;
left?: boolean;
right?: boolean;
overlay?: boolean;
}
export type BorderColor = keyof Theme["borderColor"];
export interface BorderOptions {
export interface BorderProperties {
width?: number;
top?: boolean;
bottom?: boolean;
@@ -33,72 +159,42 @@ export interface BorderOptions {
right?: boolean;
overlay?: boolean;
}
export function border(
theme: Theme,
color: BorderColor,
options?: BorderOptions
) {
layer: Layer,
styleSet: StyleSets,
style: Styles,
properties?: BorderProperties
): Border;
export function border(
layer: Layer,
styleSet: StyleSets,
properties?: BorderProperties
): Border;
export function border(
layer: Layer,
style: Styles,
properties?: BorderProperties
): Border;
export function border(layer: Layer, properties?: BorderProperties): Border;
export function border(
layer: Layer,
styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties,
styleOrProperties?: Styles | BorderProperties,
properties?: BorderProperties
): Border {
let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties);
if (typeof styleSetStyleOrProperties === "object") {
properties = styleSetStyleOrProperties;
}
if (typeof styleOrProperties === "object") {
properties = styleOrProperties;
}
return {
color: borderColor(theme, color),
color: style.border,
width: 1,
...options,
};
}
export function borderColor(theme: Theme, color: BorderColor) {
return theme.borderColor[color];
}
export type IconColor = keyof Theme["iconColor"];
export function iconColor(theme: Theme, color: IconColor) {
return theme.iconColor[color];
}
export type PlayerIndex = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
export interface Player {
selection: {
cursor: string;
selection: string;
};
}
export function player(theme: Theme, playerNumber: PlayerIndex): Player {
return {
selection: {
cursor: theme.player[playerNumber].cursorColor,
selection: theme.player[playerNumber].selectionColor,
},
};
}
export type BackgroundColor = keyof Theme["backgroundColor"];
export type BackgroundState = keyof BackgroundColorSet;
export function backgroundColor(
theme: Theme,
name: BackgroundColor,
state?: BackgroundState
): string {
return theme.backgroundColor[name][state || "base"];
}
export function modalShadow(theme: Theme) {
return {
blur: 16,
color: theme.shadow,
offset: [0, 2],
};
}
export function popoverShadow(theme: Theme) {
return {
blur: 4,
color: theme.shadow,
offset: [1, 2],
};
}
export function draggedShadow(theme: Theme) {
return {
blur: 6,
color: theme.shadow,
offset: [1, 2],
...properties,
};
}
+17 -15
View File
@@ -1,12 +1,14 @@
import Theme from "../themes/common/theme";
import picker from "./picker";
import { backgroundColor, border, iconColor, player, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, foreground, text } from "./components";
export default function contactFinder(colorScheme: ColorScheme) {
let layer = colorScheme.highest;
export default function contactFinder(theme: Theme) {
const sideMargin = 6;
const contactButton = {
background: backgroundColor(theme, 100),
color: iconColor(theme, "primary"),
background: background(layer, "variant"),
color: foreground(layer, "variant"),
iconWidth: 8,
buttonWidth: 16,
cornerRadius: 8,
@@ -15,17 +17,17 @@ export default function contactFinder(theme: Theme) {
return {
picker: {
item: {
...picker(theme).item,
...picker(colorScheme).item,
margin: { left: sideMargin, right: sideMargin }
},
empty: picker(theme).empty,
empty: picker(colorScheme).empty,
inputEditor: {
background: backgroundColor(theme, 500),
background: background(layer, "on"),
cornerRadius: 6,
text: text(theme, "mono", "primary"),
placeholderText: text(theme, "mono", "placeholder", { size: "sm" }),
selection: player(theme, 1).selection,
border: border(theme, "secondary"),
text: text(layer, "mono",),
placeholderText: text(layer, "mono", "variant", { size: "sm" }),
selection: colorScheme.players[0],
border: border(layer),
padding: {
bottom: 4,
left: 8,
@@ -51,13 +53,13 @@ export default function contactFinder(theme: Theme) {
contactButton: {
...contactButton,
hover: {
background: backgroundColor(theme, 100, "hovered"),
background: background(layer, "variant", "hovered"),
},
},
disabledContactButton: {
...contactButton,
background: backgroundColor(theme, 100),
color: iconColor(theme, "muted"),
background: background(layer, "disabled"),
color: foreground(layer, "disabled"),
},
};
}
+48 -37
View File
@@ -1,13 +1,21 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, borderColor, iconColor, player, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import {
background,
border,
borderColor,
foreground,
text,
} from "./components";
export default function contactList(theme: Theme) {
export default function contactsPanel(colorScheme: ColorScheme) {
const nameMargin = 8;
const sidePadding = 12;
let layer = colorScheme.middle;
const contactButton = {
background: backgroundColor(theme, 100),
color: iconColor(theme, "primary"),
background: background(layer, "on"),
color: foreground(layer, "on"),
iconWidth: 8,
buttonWidth: 16,
cornerRadius: 8,
@@ -20,7 +28,7 @@ export default function contactList(theme: Theme) {
width: 14,
},
name: {
...text(theme, "mono", "placeholder", { size: "sm" }),
...text(layer, "mono", { size: "sm" }),
margin: {
left: nameMargin,
right: 6,
@@ -39,13 +47,15 @@ export default function contactList(theme: Theme) {
};
return {
background: background(layer),
padding: { top: 12, bottom: 0 },
userQueryEditor: {
background: backgroundColor(theme, 500),
background: background(layer, "on"),
cornerRadius: 6,
text: text(theme, "mono", "primary"),
placeholderText: text(theme, "mono", "placeholder", { size: "sm" }),
selection: player(theme, 1).selection,
border: border(theme, "secondary"),
text: text(layer, "mono", "on"),
placeholderText: text(layer, "mono", "on", "disabled", { size: "sm" }),
selection: colorScheme.players[0],
border: border(layer, "on"),
padding: {
bottom: 4,
left: 8,
@@ -58,27 +68,28 @@ export default function contactList(theme: Theme) {
},
userQueryEditorHeight: 33,
addContactButton: {
color: iconColor(theme, "primary"),
margin: { left: 6, right: 12 },
color: foreground(layer, "on"),
buttonWidth: 28,
iconWidth: 16,
},
rowHeight: 28,
sectionIconSize: 8,
headerRow: {
...text(theme, "mono", "secondary", { size: "sm" }),
margin: { top: 6 },
...text(layer, "mono", { size: "sm" }),
margin: { top: 14 },
padding: {
left: sidePadding,
right: sidePadding,
},
active: {
...text(theme, "mono", "primary", { size: "sm" }),
background: backgroundColor(theme, 100, "active"),
...text(layer, "mono", "active", { size: "sm" }),
background: background(layer, "active"),
},
},
leaveCall: {
background: backgroundColor(theme, 100),
border: border(theme, "secondary"),
background: background(layer),
border: border(layer),
cornerRadius: 6,
margin: {
top: 1,
@@ -89,11 +100,11 @@ export default function contactList(theme: Theme) {
left: 7,
right: 7,
},
...text(theme, "sans", "secondary", { size: "xs" }),
...text(layer, "sans", "variant", { size: "xs" }),
hover: {
...text(theme, "sans", "active", { size: "xs" }),
background: backgroundColor(theme, "on300", "hovered"),
border: border(theme, "primary"),
...text(layer, "sans", "hovered", { size: "xs" }),
background: background(layer, "hovered"),
border: border(layer, "hovered"),
},
},
contactRow: {
@@ -102,7 +113,7 @@ export default function contactList(theme: Theme) {
right: sidePadding,
},
active: {
background: backgroundColor(theme, 100, "active"),
background: background(layer, "active"),
},
},
contactAvatar: {
@@ -113,16 +124,16 @@ export default function contactList(theme: Theme) {
cornerRadius: 4,
padding: 4,
margin: { top: 12, left: 12 },
background: iconColor(theme, "ok"),
background: foreground(layer, "positive"),
},
contactStatusBusy: {
cornerRadius: 4,
padding: 4,
margin: { top: 12, left: 12 },
background: iconColor(theme, "error"),
background: foreground(layer, "negative"),
},
contactUsername: {
...text(theme, "mono", "primary", { size: "sm" }),
...text(layer, "mono", { size: "sm" }),
margin: {
left: nameMargin,
},
@@ -131,39 +142,39 @@ export default function contactList(theme: Theme) {
contactButton: {
...contactButton,
hover: {
background: backgroundColor(theme, "on300", "hovered"),
background: background(layer, "hovered"),
},
},
disabledButton: {
...contactButton,
background: backgroundColor(theme, 100),
color: iconColor(theme, "muted"),
background: background(layer, "on"),
color: foreground(layer, "on"),
},
callingIndicator: {
...text(theme, "mono", "muted", { size: "xs" })
...text(layer, "mono", "variant", { size: "xs" })
},
treeBranch: {
color: borderColor(theme, "active"),
color: borderColor(layer),
width: 1,
hover: {
color: borderColor(theme, "active"),
color: borderColor(layer),
},
active: {
color: borderColor(theme, "active"),
color: borderColor(layer),
},
},
projectRow: {
...projectRow,
background: backgroundColor(theme, 300),
background: background(layer, "on"),
name: {
...projectRow.name,
...text(theme, "mono", "secondary", { size: "sm" }),
...text(layer, "mono", { size: "sm" }),
},
hover: {
background: backgroundColor(theme, 300, "hovered"),
background: background(layer, "on", "hovered"),
},
active: {
background: backgroundColor(theme, 300, "active"),
background: background(layer, "on", "active"),
},
},
}
+11 -10
View File
@@ -1,10 +1,11 @@
import Theme from "../themes/common/theme";
import { backgroundColor, iconColor, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, foreground, text } from "./components";
const avatarSize = 12;
const headerPadding = 8;
export default function contactNotification(theme: Theme): Object {
export default function contactNotification(colorScheme: ColorScheme): Object {
let layer = colorScheme.lowest;
return {
headerAvatar: {
height: avatarSize,
@@ -12,32 +13,32 @@ export default function contactNotification(theme: Theme): Object {
cornerRadius: 6,
},
headerMessage: {
...text(theme, "sans", "primary", { size: "xs" }),
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
headerHeight: 18,
bodyMessage: {
...text(theme, "sans", "secondary", { size: "xs" }),
...text(layer, "sans", { size: "xs" }),
margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 },
},
button: {
...text(theme, "sans", "primary", { size: "xs" }),
background: backgroundColor(theme, "on300"),
...text(layer, "sans", "on", { size: "xs" }),
background: background(layer, "on"),
padding: 4,
cornerRadius: 6,
margin: { left: 6 },
hover: {
background: backgroundColor(theme, "on300", "hovered"),
background: background(layer, "on", "hovered"),
},
},
dismissButton: {
color: iconColor(theme, "secondary"),
color: foreground(layer, "on"),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8,
hover: {
color: iconColor(theme, "primary"),
color: foreground(layer, "on", "hovered"),
},
},
};
+10 -9
View File
@@ -1,15 +1,16 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, borderColor, popoverShadow, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function contactsPopover(theme: Theme) {
export default function contactsPopover(colorScheme: ColorScheme) {
let layer = colorScheme.middle;
const sidePadding = 12;
return {
background: backgroundColor(theme, 300, "base"),
background: background(layer),
cornerRadius: 6,
padding: { top: 6 },
margin: { top: -6 },
shadow: popoverShadow(theme),
border: border(theme, "primary"),
shadow: colorScheme.popoverShadow,
border: border(layer),
width: 300,
height: 400,
inviteRowHeight: 28,
@@ -18,10 +19,10 @@ export default function contactsPopover(theme: Theme) {
left: sidePadding,
right: sidePadding,
},
border: { top: true, width: 1, color: borderColor(theme, "primary") },
text: text(theme, "sans", "secondary", { size: "sm" }),
border: border(layer, { top: true }),
text: text(layer, "sans", "variant", { size: "sm" }),
hover: {
text: text(theme, "sans", "active", { size: "sm" }),
text: text(layer, "sans", "hovered", { size: "sm" }),
},
},
}
+19 -24
View File
@@ -1,45 +1,40 @@
import Theme from "../themes/common/theme";
import {
backgroundColor,
border,
borderColor,
popoverShadow,
text,
} from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, borderColor, text } from "./components";
export default function contextMenu(theme: Theme) {
export default function contextMenu(colorScheme: ColorScheme) {
let layer = colorScheme.middle;
return {
background: backgroundColor(theme, 300, "base"),
cornerRadius: 6,
padding: 6,
shadow: popoverShadow(theme),
border: border(theme, "primary"),
background: background(layer),
cornerRadius: 10,
padding: 4,
shadow: colorScheme.popoverShadow,
border: border(layer),
keystrokeMargin: 30,
item: {
iconSpacing: 8,
iconWidth: 14,
padding: { left: 4, right: 4, top: 2, bottom: 2 },
padding: { left: 6, right: 6, top: 2, bottom: 2 },
cornerRadius: 6,
label: text(theme, "sans", "primary", { size: "sm" }),
label: text(layer, "sans", { size: "sm" }),
keystroke: {
...text(theme, "sans", "muted", { size: "sm", weight: "bold" }),
...text(layer, "sans", "variant", { size: "sm", weight: "bold" }),
padding: { left: 3, right: 3 },
},
hover: {
background: backgroundColor(theme, 300, "hovered"),
text: text(theme, "sans", "primary", { size: "sm" }),
background: background(layer, "hovered"),
label: text(layer, "sans", "hovered", { size: "sm" }),
},
active: {
background: backgroundColor(theme, 300, "active"),
text: text(theme, "sans", "active", { size: "sm" }),
background: background(layer, "active"),
label: text(layer, "sans", "active", { size: "sm" }),
},
activeHover: {
background: backgroundColor(theme, 300, "hovered"),
text: text(theme, "sans", "active", { size: "sm" }),
background: background(layer, "active"),
label: text(layer, "sans", "active", { size: "sm" }),
},
},
separator: {
background: borderColor(theme, "primary"),
background: borderColor(layer),
margin: { top: 2, bottom: 2 },
},
};
+171 -86
View File
@@ -1,19 +1,22 @@
import Theme from "../themes/common/theme";
import { fontWeights } from "../common";
import { withOpacity } from "../utils/color";
import {
backgroundColor,
ColorScheme,
Layer,
StyleSets,
} from "../themes/common/colorScheme";
import {
background,
border,
borderColor,
iconColor,
player,
popoverShadow,
foreground,
text,
textColor,
TextColor,
} from "./components";
import hoverPopover from "./hoverPopover";
export default function editor(theme: Theme) {
export default function editor(colorScheme: ColorScheme) {
let layer = colorScheme.highest;
const autocompleteItem = {
cornerRadius: 6,
padding: {
@@ -24,17 +27,17 @@ export default function editor(theme: Theme) {
},
};
function diagnostic(theme: Theme, color: TextColor) {
function diagnostic(layer: Layer, styleSet: StyleSets) {
return {
textScaleFactor: 0.857,
header: {
border: border(theme, "primary", {
border: border(layer, {
top: true,
}),
},
message: {
text: text(theme, "sans", color, { size: "sm" }),
highlightText: text(theme, "sans", color, {
text: text(layer, "sans", styleSet, "inverted", { size: "sm" }),
highlightText: text(layer, "sans", styleSet, "inverted", {
size: "sm",
weight: "bold",
}),
@@ -42,121 +45,207 @@ export default function editor(theme: Theme) {
};
}
const syntax: any = {};
for (const syntaxKey in theme.syntax) {
const style = theme.syntax[syntaxKey];
syntax[syntaxKey] = {
color: style.color,
weight: style.weight,
underline: style.underline,
italic: style.italic,
};
}
const syntax = {
primary: {
color: colorScheme.ramps.neutral(1).hex(),
weight: fontWeights.normal,
},
comment: {
color: colorScheme.ramps.neutral(0.71).hex(),
weight: fontWeights.normal,
},
punctuation: {
color: colorScheme.ramps.neutral(0.86).hex(),
weight: fontWeights.normal,
},
constant: {
color: colorScheme.ramps.green(0.5).hex(),
weight: fontWeights.normal,
},
keyword: {
color: colorScheme.ramps.blue(0.5).hex(),
weight: fontWeights.normal,
},
function: {
color: colorScheme.ramps.yellow(0.5).hex(),
weight: fontWeights.normal,
},
type: {
color: colorScheme.ramps.cyan(0.5).hex(),
weight: fontWeights.normal,
},
constructor: {
color: colorScheme.ramps.blue(0.5).hex(),
weight: fontWeights.normal,
},
variant: {
color: colorScheme.ramps.blue(0.5).hex(),
weight: fontWeights.normal,
},
property: {
color: colorScheme.ramps.blue(0.5).hex(),
weight: fontWeights.normal,
},
enum: {
color: colorScheme.ramps.orange(0.5).hex(),
weight: fontWeights.normal,
},
operator: {
color: colorScheme.ramps.orange(0.5).hex(),
weight: fontWeights.normal,
},
string: {
color: colorScheme.ramps.orange(0.5).hex(),
weight: fontWeights.normal,
},
number: {
color: colorScheme.ramps.green(0.5).hex(),
weight: fontWeights.normal,
},
boolean: {
color: colorScheme.ramps.green(0.5).hex(),
weight: fontWeights.normal,
},
predictive: {
color: colorScheme.ramps.neutral(0.57).hex(),
weight: fontWeights.normal,
},
title: {
color: colorScheme.ramps.yellow(0.5).hex(),
weight: fontWeights.bold,
},
emphasis: {
color: colorScheme.ramps.blue(0.5).hex(),
weight: fontWeights.normal,
},
"emphasis.strong": {
color: colorScheme.ramps.blue(0.5).hex(),
weight: fontWeights.bold,
},
linkUri: {
color: colorScheme.ramps.green(0.5).hex(),
weight: fontWeights.normal,
underline: true,
},
linkText: {
color: colorScheme.ramps.orange(0.5).hex(),
weight: fontWeights.normal,
italic: true,
},
};
return {
textColor: theme.syntax.primary.color,
background: backgroundColor(theme, 500),
activeLineBackground: theme.editor.line.active,
textColor: syntax.primary.color,
background: background(layer),
activeLineBackground: background(layer, "on"),
highlightedLineBackground: background(layer, "on"),
codeActions: {
indicator: iconColor(theme, "secondary"),
verticalScale: 0.618
indicator: foreground(layer, "variant"),
verticalScale: 0.55,
},
diff: {
deleted: theme.iconColor.error,
inserted: theme.iconColor.ok,
modified: theme.iconColor.warning,
deleted: foreground(layer, "negative"),
modified: foreground(layer, "warning"),
inserted: foreground(layer, "positive"),
removedWidthEm: 0.275,
widthEm: 0.16,
cornerRadius: 0.05,
},
documentHighlightReadBackground: theme.editor.highlight.occurrence,
documentHighlightWriteBackground: theme.editor.highlight.activeOccurrence,
errorColor: theme.textColor.error,
gutterBackground: backgroundColor(theme, 500),
documentHighlightReadBackground: colorScheme.ramps
.neutral(0.5)
.alpha(0.2)
.hex(), // TODO: This was blend
documentHighlightWriteBackground: colorScheme.ramps
.neutral(0.5)
.alpha(0.4)
.hex(), // TODO: This was blend * 2
errorColor: background(layer, "negative"),
gutterBackground: background(layer),
gutterPaddingFactor: 3.5,
highlightedLineBackground: theme.editor.line.highlighted,
lineNumber: theme.editor.gutter.primary,
lineNumberActive: theme.editor.gutter.active,
lineNumber: foreground(layer, "disabled"),
lineNumberActive: foreground(layer),
renameFade: 0.6,
unnecessaryCodeFade: 0.5,
selection: player(theme, 1).selection,
selection: colorScheme.players[0],
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,
colorScheme.players[1],
colorScheme.players[2],
colorScheme.players[3],
colorScheme.players[4],
colorScheme.players[5],
colorScheme.players[6],
colorScheme.players[7],
],
autocomplete: {
background: backgroundColor(theme, 500),
background: background(colorScheme.middle),
cornerRadius: 8,
padding: 4,
border: border(theme, "secondary"),
shadow: popoverShadow(theme),
item: autocompleteItem,
hoveredItem: {
...autocompleteItem,
background: backgroundColor(theme, 500, "hovered"),
},
margin: {
left: -14,
},
matchHighlight: text(theme, "mono", "feature"),
border: border(colorScheme.middle),
shadow: colorScheme.popoverShadow,
matchHighlight: foreground(colorScheme.middle, "accent"),
item: autocompleteItem,
hoveredItem: {
...autocompleteItem,
matchHighlight: foreground(colorScheme.middle, "accent", "hovered"),
background: background(colorScheme.middle, "hovered"),
},
selectedItem: {
...autocompleteItem,
background: backgroundColor(theme, 500, "active"),
matchHighlight: foreground(colorScheme.middle, "accent", "active"),
background: background(colorScheme.middle, "active"),
},
},
diagnosticHeader: {
background: backgroundColor(theme, 300),
background: background(colorScheme.middle),
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", {
textScaleFactor: 0.857,
border: border(colorScheme.middle, {
bottom: true,
top: true,
}),
code: {
...text(theme, "mono", "secondary", { size: "sm" }),
...text(colorScheme.middle, "mono", { size: "sm" }),
margin: {
left: 10,
},
},
message: {
highlightText: text(theme, "sans", "primary", {
highlightText: text(colorScheme.middle, "sans", {
size: "sm",
weight: "bold",
}),
text: text(theme, "sans", "secondary", { size: "sm" }),
text: text(colorScheme.middle, "sans", { size: "sm" }),
},
},
diagnosticPathHeader: {
background: theme.editor.line.active,
background: background(colorScheme.middle),
textScaleFactor: 0.857,
filename: text(theme, "mono", "primary", { size: "sm" }),
filename: text(colorScheme.middle, "mono", { size: "sm" }),
path: {
...text(theme, "mono", "muted", { size: "sm" }),
...text(colorScheme.middle, "mono", { size: "sm" }),
margin: {
left: 12,
},
},
},
errorDiagnostic: diagnostic(theme, "error"),
warningDiagnostic: diagnostic(theme, "warning"),
informationDiagnostic: diagnostic(theme, "info"),
hintDiagnostic: diagnostic(theme, "info"),
invalidErrorDiagnostic: diagnostic(theme, "secondary"),
invalidHintDiagnostic: diagnostic(theme, "secondary"),
invalidInformationDiagnostic: diagnostic(theme, "secondary"),
invalidWarningDiagnostic: diagnostic(theme, "secondary"),
hoverPopover: hoverPopover(theme),
errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
hoverPopover: hoverPopover(colorScheme),
linkDefinition: {
color: theme.syntax.linkUri.color,
underline: theme.syntax.linkUri.underline,
color: syntax.linkUri.color,
underline: syntax.linkUri.underline,
},
jumpIcon: {
color: iconColor(theme, "secondary"),
color: foreground(layer, "on"),
iconWidth: 20,
buttonWidth: 20,
cornerRadius: 6,
@@ -167,32 +256,28 @@ export default function editor(theme: Theme) {
right: 6,
},
hover: {
color: iconColor(theme, "active"),
background: backgroundColor(theme, "on500"),
color: foreground(layer, "on", "hovered"),
background: background(layer, "on", "hovered"),
},
},
scrollbar: {
width: 12,
minHeightFactor: 1.0,
track: {
border: {
left: true,
width: 1,
color: borderColor(theme, "secondary"),
},
border: border(layer, "variant", { left: true }),
},
thumb: {
background: withOpacity(borderColor(theme, "secondary"), 0.5),
background: withOpacity(borderColor(layer, "variant"), 0.5),
border: {
width: 1,
color: withOpacity(borderColor(theme, 'muted'), 0.5),
color: withOpacity(borderColor(layer, 'variant'), 0.5),
}
}
},
compositionMark: {
underline: {
thickness: 1.0,
color: borderColor(theme, "active")
color: borderColor(layer),
},
},
syntax,
+16 -24
View File
@@ -1,18 +1,19 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, popoverShadow, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function HoverPopover(theme: Theme) {
export default function HoverPopover(colorScheme: ColorScheme) {
let layer = colorScheme.middle;
let baseContainer = {
background: backgroundColor(theme, "on500"),
background: background(layer),
cornerRadius: 8,
padding: {
left: 8,
right: 8,
top: 4,
bottom: 4
bottom: 4,
},
shadow: popoverShadow(theme),
border: border(theme, "secondary"),
shadow: colorScheme.popoverShadow,
border: border(layer),
margin: {
left: -8,
},
@@ -22,32 +23,23 @@ export default function HoverPopover(theme: Theme) {
container: baseContainer,
infoContainer: {
...baseContainer,
background: backgroundColor(theme, "on500Info"),
border: {
color: theme.ramps.blue(0).hex(),
width: 1,
},
background: background(layer, "accent"),
border: border(layer, "accent"),
},
warningContainer: {
...baseContainer,
background: backgroundColor(theme, "on500Warning"),
border: {
color: theme.ramps.yellow(0).hex(),
width: 1,
},
background: background(layer, "warning"),
border: border(layer, "warning"),
},
errorContainer: {
...baseContainer,
background: backgroundColor(theme, "on500Error"),
border: {
color: theme.ramps.red(0).hex(),
width: 1,
}
background: background(layer, "negative"),
border: border(layer, "negative"),
},
block_style: {
padding: { top: 4 },
},
prose: text(theme, "sans", "primary", { size: "sm" }),
highlight: theme.editor.highlight.occurrence,
prose: text(layer, "sans", { size: "sm" }),
highlight: colorScheme.ramps.neutral(0.5).alpha(0.2).hex(), // TODO: blend was used here. Replace with something better
};
}
@@ -1,12 +1,13 @@
import Theme from "../themes/common/theme";
import { backgroundColor, borderColor, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function incomingCallNotification(theme: Theme): Object {
export default function incomingCallNotification(colorScheme: ColorScheme): Object {
let layer = colorScheme.middle;
const avatarSize = 48;
return {
windowHeight: 74,
windowWidth: 380,
background: backgroundColor(theme, 300),
background: background(layer),
callerContainer: {
padding: 12,
},
@@ -19,26 +20,26 @@ export default function incomingCallNotification(theme: Theme): Object {
margin: { left: 10 },
},
callerUsername: {
...text(theme, "sans", "active", { size: "sm", weight: "bold" }),
...text(layer, "sans", { size: "sm", weight: "bold" }),
margin: { top: -3 },
},
callerMessage: {
...text(theme, "sans", "secondary", { size: "xs" }),
...text(layer, "sans", "variant", { size: "xs" }),
margin: { top: -3 },
},
worktreeRoots: {
...text(theme, "sans", "secondary", { size: "xs", weight: "bold" }),
...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
margin: { top: -3 },
},
buttonWidth: 96,
acceptButton: {
background: backgroundColor(theme, "ok", "active"),
border: { left: true, bottom: true, width: 1, color: borderColor(theme, "primary") },
...text(theme, "sans", "ok", { size: "xs", weight: "extra_bold" })
background: background(layer, "accent"),
border: border(layer, { left: true, bottom: true }),
...text(layer, "sans", "positive", { size: "xs", weight: "extra_bold" })
},
declineButton: {
border: { left: true, width: 1, color: borderColor(theme, "primary") },
...text(theme, "sans", "error", { size: "xs", weight: "extra_bold" })
border: border(layer, { left: true }),
...text(layer, "sans", "negative", { size: "xs", weight: "extra_bold" })
},
};
}
+37 -31
View File
@@ -1,17 +1,16 @@
import Theme from "../themes/common/theme";
import {
backgroundColor,
border,
player,
modalShadow,
text,
} from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function picker(theme: Theme) {
export default function picker(colorScheme: ColorScheme) {
let layer = colorScheme.lowest;
return {
background: backgroundColor(theme, 300),
cornerRadius: 8,
padding: 8,
background: background(layer),
border: border(layer),
shadow: colorScheme.modalShadow,
cornerRadius: 12,
padding: {
bottom: 4,
},
item: {
padding: {
bottom: 4,
@@ -19,41 +18,48 @@ export default function picker(theme: Theme) {
right: 12,
top: 4,
},
margin: {
top: 1,
left: 4,
right: 4,
},
cornerRadius: 8,
text: text(theme, "sans", "secondary"),
highlightText: text(theme, "sans", "feature", { weight: "bold" }),
text: text(layer, "sans", "variant"),
highlightText: text(layer, "sans", "accent", { weight: "bold" }),
active: {
background: backgroundColor(theme, 300, "active"),
text: text(theme, "sans", "active"),
background: background(layer, "base", "active"),
text: text(layer, "sans", "base", "active"),
highlightText: text(layer, "sans", "accent", {
weight: "bold",
}),
},
hover: {
background: backgroundColor(theme, 300, "hovered"),
background: background(layer, "hovered"),
},
},
border: border(theme, "primary"),
empty: {
text: text(theme, "sans", "muted"),
text: text(layer, "sans", "variant"),
padding: {
bottom: 4,
left: 12,
right: 12,
bottom: 8,
left: 16,
right: 16,
top: 8,
},
},
inputEditor: {
background: backgroundColor(theme, 500),
cornerRadius: 8,
placeholderText: text(theme, "sans", "placeholder"),
selection: player(theme, 1).selection,
text: text(theme, "mono", "primary"),
border: border(theme, "secondary"),
placeholderText: text(layer, "sans", "on", "disabled"),
selection: colorScheme.players[0],
text: text(layer, "mono", "on"),
border: border(layer, { bottom: true }),
padding: {
bottom: 7,
bottom: 8,
left: 16,
right: 16,
top: 7,
top: 8,
},
margin: {
bottom: 4,
},
},
shadow: modalShadow(theme),
};
}
+6 -5
View File
@@ -1,12 +1,13 @@
import Theme from "../themes/common/theme";
import { backgroundColor, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, text } from "./components";
export default function projectDiagnostics(theme: Theme) {
export default function projectDiagnostics(colorScheme: ColorScheme) {
let layer = colorScheme.highest;
return {
background: backgroundColor(theme, 500),
background: background(layer),
tabIconSpacing: 4,
tabIconWidth: 13,
tabSummarySpacing: 10,
emptyMessage: text(theme, "sans", "secondary", { size: "md" }),
emptyMessage: text(layer, "sans", "variant", { size: "md" }),
};
}
+15 -15
View File
@@ -1,36 +1,36 @@
import Theme from "../themes/common/theme";
import { panel } from "./app";
import { backgroundColor, iconColor, player, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, foreground, text } from "./components";
export default function projectPanel(theme: Theme) {
export default function projectPanel(colorScheme: ColorScheme) {
let layer = colorScheme.middle;
return {
...panel,
background: background(layer),
padding: { left: 12, right: 12, top: 6, bottom: 6 },
indentWidth: 8,
entry: {
height: 24,
iconColor: iconColor(theme, "muted"),
iconColor: foreground(layer, "variant"),
iconSize: 8,
iconSpacing: 8,
text: text(theme, "mono", "secondary", { size: "sm" }),
text: text(layer, "mono", "variant", { size: "sm" }),
hover: {
background: backgroundColor(theme, 300, "hovered"),
background: background(layer, "variant", "hovered"),
},
active: {
background: backgroundColor(theme, 300, "active"),
text: text(theme, "mono", "active", { size: "sm" }),
background: background(layer, "active"),
text: text(layer, "mono", "active", { size: "sm" }),
},
activeHover: {
background: backgroundColor(theme, 300, "active"),
text: text(theme, "mono", "active", { size: "sm" }),
background: background(layer, "active"),
text: text(layer, "mono", "active", { size: "sm" }),
},
},
cutEntryFade: 0.4,
ignoredEntryFade: 0.6,
filenameEditor: {
background: backgroundColor(theme, "on300"),
text: text(theme, "mono", "active", { size: "sm" }),
selection: player(theme, 1).selection,
background: background(layer, "on"),
text: text(layer, "mono", "on", { size: "sm" }),
selection: colorScheme.players[0],
},
};
}
@@ -1,12 +1,14 @@
import Theme from "../themes/common/theme";
import { backgroundColor, borderColor, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function projectSharedNotification(colorScheme: ColorScheme): Object {
let layer = colorScheme.middle;
export default function projectSharedNotification(theme: Theme): Object {
const avatarSize = 48;
return {
windowHeight: 74,
windowWidth: 380,
background: backgroundColor(theme, 300),
background: background(layer),
ownerContainer: {
padding: 12,
},
@@ -19,26 +21,26 @@ export default function projectSharedNotification(theme: Theme): Object {
margin: { left: 10 },
},
ownerUsername: {
...text(theme, "sans", "active", { size: "sm", weight: "bold" }),
...text(layer, "sans", { size: "sm", weight: "bold" }),
margin: { top: -3 },
},
message: {
...text(theme, "sans", "secondary", { size: "xs" }),
...text(layer, "sans", "variant", { size: "xs" }),
margin: { top: -3 },
},
worktreeRoots: {
...text(theme, "sans", "secondary", { size: "xs", weight: "bold" }),
...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
margin: { top: -3 },
},
buttonWidth: 96,
openButton: {
background: backgroundColor(theme, "info", "active"),
border: { left: true, bottom: true, width: 1, color: borderColor(theme, "primary") },
...text(theme, "sans", "info", { size: "xs", weight: "extra_bold" })
background: background(layer, "accent"),
border: border(layer, { left: true, bottom: true, }),
...text(layer, "sans", "accent", { size: "xs", weight: "extra_bold" })
},
dismissButton: {
border: { left: true, width: 1, color: borderColor(theme, "primary") },
...text(theme, "sans", "secondary", { size: "xs", weight: "extra_bold" })
border: border(layer, { left: true }),
...text(layer, "sans", "variant", { size: "xs", weight: "extra_bold" })
},
};
}
+26 -24
View File
@@ -1,17 +1,19 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, player, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function search(colorScheme: ColorScheme) {
let layer = colorScheme.highest;
export default function search(theme: Theme) {
// Search input
const editor = {
background: backgroundColor(theme, 500),
background: background(layer),
cornerRadius: 8,
minWidth: 200,
maxWidth: 500,
placeholderText: text(theme, "mono", "placeholder"),
selection: player(theme, 1).selection,
text: text(theme, "mono", "active"),
border: border(theme, "secondary"),
placeholderText: text(layer, "mono", "disabled"),
selection: colorScheme.players[0],
text: text(layer, "mono", "default"),
border: border(layer),
margin: {
right: 12,
},
@@ -24,14 +26,14 @@ export default function search(theme: Theme) {
};
return {
matchBackground: theme.editor.highlight.match,
matchBackground: background(layer), // theme.editor.highlight.match,
tabIconSpacing: 8,
tabIconWidth: 14,
optionButton: {
...text(theme, "mono", "secondary"),
background: backgroundColor(theme, "on500"),
...text(layer, "mono", "on"),
background: background(layer, "on"),
cornerRadius: 6,
border: border(theme, "secondary"),
border: border(layer, "on"),
margin: {
right: 4,
},
@@ -42,28 +44,28 @@ export default function search(theme: Theme) {
top: 2,
},
active: {
...text(theme, "mono", "active"),
background: backgroundColor(theme, "on500", "active"),
border: border(theme, "muted"),
...text(layer, "mono", "on", "inverted"),
background: background(layer, "on", "inverted"),
border: border(layer, "on", "inverted"),
},
clicked: {
...text(theme, "mono", "active"),
background: backgroundColor(theme, "on300", "active"),
border: border(theme, "secondary"),
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
hover: {
...text(theme, "mono", "active"),
background: backgroundColor(theme, "on500", "hovered"),
border: border(theme, "muted"),
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
},
editor,
invalidEditor: {
...editor,
border: border(theme, "error"),
border: border(layer, "negative"),
},
matchIndex: {
...text(theme, "mono", "muted"),
...text(layer, "mono", "variant"),
padding: 6,
},
optionButtonGroup: {
@@ -73,7 +75,7 @@ export default function search(theme: Theme) {
},
},
resultsStatus: {
...text(theme, "mono", "primary"),
...text(layer, "mono", "on"),
size: 18,
},
};
+40 -39
View File
@@ -1,8 +1,9 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, iconColor, text } from "./components";
import { workspaceBackground } from "./workspace";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, foreground, text } from "./components";
export default function statusBar(colorScheme: ColorScheme) {
let layer = colorScheme.lowest;
export default function statusBar(theme: Theme) {
const statusContainer = {
cornerRadius: 6,
padding: { top: 3, bottom: 3, left: 6, right: 6 },
@@ -22,70 +23,70 @@ export default function statusBar(theme: Theme) {
left: 6,
right: 6,
},
border: border(theme, "primary", { top: true, overlay: true }),
cursorPosition: text(theme, "sans", "secondary"),
autoUpdateProgressMessage: text(theme, "sans", "secondary"),
autoUpdateDoneMessage: text(theme, "sans", "secondary"),
border: border(layer, { top: true, overlay: true }),
cursorPosition: text(layer, "sans", "variant"),
autoUpdateProgressMessage: text(layer, "sans", "variant"),
autoUpdateDoneMessage: text(layer, "sans", "variant"),
lspStatus: {
...diagnosticStatusContainer,
iconSpacing: 4,
iconWidth: 14,
height: 18,
message: text(theme, "sans", "secondary"),
iconColor: iconColor(theme, "muted"),
message: text(layer, "sans"),
iconColor: foreground(layer),
hover: {
message: text(theme, "sans", "primary"),
iconColor: iconColor(theme, "primary"),
background: backgroundColor(theme, 300, "hovered"),
message: text(layer, "sans"),
iconColor: foreground(layer),
background: background(layer),
},
},
diagnosticMessage: {
...text(theme, "sans", "secondary"),
hover: text(theme, "sans", "active"),
...text(layer, "sans"),
hover: text(layer, "sans", "hovered"),
},
feedback: {
...text(theme, "sans", "secondary"),
hover: text(theme, "sans", "active"),
...text(layer, "sans", "variant"),
hover: text(layer, "sans", "hovered"),
},
diagnosticSummary: {
height: 16,
height: 20,
iconWidth: 16,
iconSpacing: 2,
summarySpacing: 6,
text: text(theme, "sans", "primary", { size: "sm" }),
iconColorOk: iconColor(theme, "muted"),
iconColorWarning: iconColor(theme, "warning"),
iconColorError: iconColor(theme, "error"),
text: text(layer, "sans", { size: "sm" }),
iconColorOk: foreground(layer, "variant"),
iconColorWarning: foreground(layer, "warning"),
iconColorError: foreground(layer, "negative"),
containerOk: {
cornerRadius: 6,
padding: { top: 3, bottom: 3, left: 7, right: 7 },
},
containerWarning: {
...diagnosticStatusContainer,
background: backgroundColor(theme, "warning"),
border: border(theme, "warning"),
background: background(layer, "warning"),
border: border(layer, "warning"),
},
containerError: {
...diagnosticStatusContainer,
background: backgroundColor(theme, "error"),
border: border(theme, "error"),
background: background(layer, "negative"),
border: border(layer, "negative"),
},
hover: {
iconColorOk: iconColor(theme, "active"),
iconColorOk: foreground(layer, "on"),
containerOk: {
cornerRadius: 6,
padding: { top: 3, bottom: 3, left: 7, right: 7 },
background: backgroundColor(theme, 300, "hovered"),
background: background(layer, "on", "hovered"),
},
containerWarning: {
...diagnosticStatusContainer,
background: backgroundColor(theme, "warning", "hovered"),
border: border(theme, "warning"),
background: background(layer, "warning", "hovered"),
border: border(layer, "warning", "hovered"),
},
containerError: {
...diagnosticStatusContainer,
background: backgroundColor(theme, "error", "hovered"),
border: border(theme, "error"),
background: background(layer, "negative", "hovered"),
border: border(layer, "negative", "hovered"),
},
},
},
@@ -95,22 +96,22 @@ export default function statusBar(theme: Theme) {
item: {
...statusContainer,
iconSize: 16,
iconColor: iconColor(theme, "muted"),
iconColor: foreground(layer, "variant"),
hover: {
iconColor: iconColor(theme, "active"),
background: backgroundColor(theme, 300, "hovered"),
iconColor: foreground(layer, "hovered"),
background: background(layer, "variant"),
},
active: {
iconColor: iconColor(theme, "active"),
background: backgroundColor(theme, 300, "active"),
iconColor: foreground(layer, "active"),
background: background(layer, "active"),
},
},
badge: {
cornerRadius: 3,
padding: 2,
margin: { bottom: -1, right: -1 },
border: { width: 1, color: workspaceBackground(theme) },
background: iconColor(theme, "feature"),
border: border(layer),
background: background(layer, "accent"),
},
},
};
+50 -42
View File
@@ -1,76 +1,84 @@
import Theme from "../themes/common/theme";
import { ColorScheme } from "../themes/common/colorScheme";
import { withOpacity } from "../utils/color";
import { iconColor, text, border, backgroundColor, draggedShadow } from "./components";
import { text, border, background, foreground } from "./components";
export default function tabBar(theme: Theme) {
export default function tabBar(colorScheme: ColorScheme) {
const height = 32;
let activeLayer = colorScheme.highest;
let layer = colorScheme.middle;
const tab = {
height,
background: backgroundColor(theme, 300),
border: border(theme, "primary", {
left: true,
text: text(layer, "sans", "variant", { size: "sm" }),
background: background(layer),
border: border(layer, {
right: true,
bottom: true,
overlay: true,
}),
iconClose: iconColor(theme, "muted"),
iconCloseActive: iconColor(theme, "active"),
iconConflict: iconColor(theme, "warning"),
iconDirty: iconColor(theme, "info"),
iconWidth: 8,
spacing: 8,
text: text(theme, "sans", "secondary", { size: "sm" }),
padding: {
left: 8,
right: 8,
right: 12,
},
spacing: 8,
// Close icons
iconWidth: 8,
iconClose: foreground(layer, "variant"),
iconCloseActive: foreground(layer),
// Indicators
iconConflict: foreground(layer, "warning"),
iconDirty: foreground(layer, "accent"),
// When two tabs of the same name are open, a label appears next to them
description: {
margin: { left: 6, top: 1 },
...text(theme, "sans", "muted", { size: "2xs" })
}
margin: { left: 8 },
...text(layer, "sans", "disabled", { size: "2xs" }),
},
};
const activePaneActiveTab = {
...tab,
background: backgroundColor(theme, 500),
text: text(theme, "sans", "active", { size: "sm" }),
background: background(activeLayer),
text: text(activeLayer, "sans", "active", { size: "sm" }),
border: {
...tab.border,
bottom: false
bottom: false,
},
};
const inactivePaneInactiveTab = {
...tab,
background: backgroundColor(theme, 300),
text: text(theme, "sans", "muted", { size: "sm" }),
background: background(layer),
text: text(layer, "sans", "variant", { size: "sm" }),
};
const inactivePaneActiveTab = {
...tab,
background: backgroundColor(theme, 500),
text: text(theme, "sans", "secondary", { size: "sm" }),
background: background(activeLayer),
text: text(layer, "sans", "variant", { size: "sm" }),
border: {
...tab.border,
bottom: false
bottom: false,
},
}
};
const draggedTab = {
...activePaneActiveTab,
background: withOpacity(tab.background, 0.8),
border: undefined as any, // Remove border
shadow: draggedShadow(theme),
}
background: withOpacity(tab.background, 0.95),
border: undefined as any,
shadow: colorScheme.popoverShadow,
};
return {
height,
background: backgroundColor(theme, 300),
dropTargetOverlayColor: withOpacity(theme.textColor.muted, 0.6),
border: border(theme, "primary", {
bottom: true,
overlay: true,
}),
background: background(layer),
dropTargetOverlayColor: withOpacity(
foreground(layer),
0.6
),
activePane: {
activeTab: activePaneActiveTab,
inactiveTab: tab,
@@ -81,11 +89,11 @@ export default function tabBar(theme: Theme) {
},
draggedTab,
paneButton: {
color: iconColor(theme, "secondary"),
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: activePaneActiveTab.height,
hover: {
color: iconColor(theme, "active"),
color: foreground(layer, "hovered"),
},
},
paneButtonContainer: {
@@ -93,7 +101,7 @@ export default function tabBar(theme: Theme) {
border: {
...tab.border,
right: false,
}
}
}
}
},
},
};
}
+39 -52
View File
@@ -1,65 +1,52 @@
import Theme from "../themes/common/theme";
import { border, modalShadow, player } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
export default function terminal(theme: Theme) {
export default function terminal(colorScheme: ColorScheme) {
/**
* Colors are controlled per-cell in the terminal grid.
* Cells can be set to any of these more 'theme-capable' colors
* or can be set directly with RGB values.
* Here are the common interpretations of these names:
* https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
*/
let colors = {
black: theme.ramps.neutral(0).hex(),
red: theme.ramps.red(0.5).hex(),
green: theme.ramps.green(0.5).hex(),
yellow: theme.ramps.yellow(0.5).hex(),
blue: theme.ramps.blue(0.5).hex(),
magenta: theme.ramps.magenta(0.5).hex(),
cyan: theme.ramps.cyan(0.5).hex(),
white: theme.ramps.neutral(7).hex(),
brightBlack: theme.ramps.neutral(4).hex(),
brightRed: theme.ramps.red(0.25).hex(),
brightGreen: theme.ramps.green(0.25).hex(),
brightYellow: theme.ramps.yellow(0.25).hex(),
brightBlue: theme.ramps.blue(0.25).hex(),
brightMagenta: theme.ramps.magenta(0.25).hex(),
brightCyan: theme.ramps.cyan(0.25).hex(),
brightWhite: theme.ramps.neutral(7).hex(),
* Colors are controlled per-cell in the terminal grid.
* Cells can be set to any of these more 'theme-capable' colors
* or can be set directly with RGB values.
* Here are the common interpretations of these names:
* https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
*/
return {
black: colorScheme.ramps.neutral(0).hex(),
red: colorScheme.ramps.red(0.5).hex(),
green: colorScheme.ramps.green(0.5).hex(),
yellow: colorScheme.ramps.yellow(0.5).hex(),
blue: colorScheme.ramps.blue(0.5).hex(),
magenta: colorScheme.ramps.magenta(0.5).hex(),
cyan: colorScheme.ramps.cyan(0.5).hex(),
white: colorScheme.ramps.neutral(1).hex(),
brightBlack: colorScheme.ramps.neutral(0.4).hex(),
brightRed: colorScheme.ramps.red(0.25).hex(),
brightGreen: colorScheme.ramps.green(0.25).hex(),
brightYellow: colorScheme.ramps.yellow(0.25).hex(),
brightBlue: colorScheme.ramps.blue(0.25).hex(),
brightMagenta: colorScheme.ramps.magenta(0.25).hex(),
brightCyan: colorScheme.ramps.cyan(0.25).hex(),
brightWhite: colorScheme.ramps.neutral(1).hex(),
/**
* Default color for characters
*/
foreground: theme.ramps.neutral(7).hex(),
foreground: colorScheme.ramps.neutral(1).hex(),
/**
* Default color for the rectangle background of a cell
*/
background: theme.ramps.neutral(0).hex(),
modalBackground: theme.ramps.neutral(1).hex(),
background: colorScheme.ramps.neutral(0).hex(),
modalBackground: colorScheme.ramps.neutral(0.1).hex(),
/**
* Default color for the cursor
*/
cursor: player(theme, 1).selection.cursor,
dimBlack: theme.ramps.neutral(7).hex(),
dimRed: theme.ramps.red(0.75).hex(),
dimGreen: theme.ramps.green(0.75).hex(),
dimYellow: theme.ramps.yellow(0.75).hex(),
dimBlue: theme.ramps.blue(0.75).hex(),
dimMagenta: theme.ramps.magenta(0.75).hex(),
dimCyan: theme.ramps.cyan(0.75).hex(),
dimWhite: theme.ramps.neutral(5).hex(),
brightForeground: theme.ramps.neutral(7).hex(),
dimForeground: theme.ramps.neutral(0).hex(),
};
return {
colors,
modalContainer: {
background: colors.modalBackground,
cornerRadius: 8,
padding: 8,
margin: 25,
border: border(theme, "primary"),
shadow: modalShadow(theme),
},
cursor: colorScheme.players[0].cursor,
dimBlack: colorScheme.ramps.neutral(1).hex(),
dimRed: colorScheme.ramps.red(0.75).hex(),
dimGreen: colorScheme.ramps.green(0.75).hex(),
dimYellow: colorScheme.ramps.yellow(0.75).hex(),
dimBlue: colorScheme.ramps.blue(0.75).hex(),
dimMagenta: colorScheme.ramps.magenta(0.75).hex(),
dimCyan: colorScheme.ramps.cyan(0.75).hex(),
dimWhite: colorScheme.ramps.neutral(0.6).hex(),
brightForeground: colorScheme.ramps.neutral(1).hex(),
dimForeground: colorScheme.ramps.neutral(0).hex(),
};
}
+10 -9
View File
@@ -1,21 +1,22 @@
import Theme from "../themes/common/theme";
import { backgroundColor, border, popoverShadow, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { background, border, text } from "./components";
export default function tooltip(theme: Theme) {
export default function tooltip(colorScheme: ColorScheme) {
let layer = colorScheme.middle;
return {
background: backgroundColor(theme, 500),
border: border(theme, "secondary"),
background: background(layer),
border: border(layer),
padding: { top: 4, bottom: 4, left: 8, right: 8 },
margin: { top: 6, left: 6 },
shadow: popoverShadow(theme),
shadow: colorScheme.popoverShadow,
cornerRadius: 6,
text: text(theme, "sans", "primary", { size: "xs" }),
text: text(layer, "sans", { size: "xs" }),
keystroke: {
background: backgroundColor(theme, "on500"),
background: background(layer, "on"),
cornerRadius: 4,
margin: { left: 6 },
padding: { left: 4, right: 4 },
...text(theme, "mono", "secondary", { size: "xs", weight: "bold" }),
...text(layer, "mono", "on", { size: "xs", weight: "bold" }),
},
maxTextWidth: 200,
};
+9 -8
View File
@@ -1,29 +1,30 @@
import Theme from "../themes/common/theme";
import { iconColor, text } from "./components";
import { ColorScheme } from "../themes/common/colorScheme";
import { foreground, text } from "./components";
const headerPadding = 8;
export default function updateNotification(theme: Theme): Object {
export default function updateNotification(colorScheme: ColorScheme): Object {
let layer = colorScheme.middle;
return {
message: {
...text(theme, "sans", "primary", { size: "xs" }),
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
actionMessage: {
...text(theme, "sans", "secondary", { size: "xs" }),
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, top: 6, bottom: 6 },
hover: {
color: theme.textColor["active"],
color: foreground(layer, "hovered"),
},
},
dismissButton: {
color: iconColor(theme, "secondary"),
color: foreground(layer),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8,
hover: {
color: iconColor(theme, "primary"),
color: foreground(layer, "hovered"),
},
},
};
+75 -78
View File
@@ -1,64 +1,58 @@
import Theme from "../themes/common/theme";
import { ColorScheme } from "../themes/common/colorScheme";
import { withOpacity } from "../utils/color";
import {
backgroundColor,
background,
border,
iconColor,
modalShadow,
borderColor,
foreground,
text,
} from "./components";
import statusBar from "./statusBar";
import tabBar from "./tabBar";
export function workspaceBackground(theme: Theme) {
return backgroundColor(theme, 300);
}
export default function workspace(theme: Theme) {
export default function workspace(colorScheme: ColorScheme) {
const layer = colorScheme.lowest;
const titlebarPadding = 6;
const titlebarButton = {
background: backgroundColor(theme, 100),
border: border(theme, "secondary"),
cornerRadius: 6,
margin: {
top: 1,
},
padding: {
top: 1,
bottom: 1,
left: 7,
right: 7,
left: 8,
right: 8,
},
...text(theme, "sans", "secondary", { size: "xs" }),
...text(layer, "sans", "variant", { size: "xs" }),
background: background(layer, "variant"),
border: border(layer),
hover: {
...text(theme, "sans", "active", { size: "xs" }),
background: backgroundColor(theme, "on300", "hovered"),
border: border(theme, "primary"),
...text(layer, "sans", "variant", "hovered", { size: "xs" }),
background: background(layer, "variant", "hovered"),
border: border(layer, "variant", "hovered"),
},
};
const avatarWidth = 18;
return {
background: backgroundColor(theme, 300),
background: background(layer),
joiningProjectAvatar: {
cornerRadius: 40,
width: 80,
},
joiningProjectMessage: {
padding: 12,
...text(theme, "sans", "primary", { size: "lg" }),
...text(layer, "sans", { size: "lg" }),
},
externalLocationMessage: {
background: backgroundColor(theme, "on500Info"),
border: border(theme, "secondary"),
background: background(colorScheme.middle, "accent"),
border: border(colorScheme.middle, "accent"),
cornerRadius: 6,
padding: 12,
margin: { bottom: 8, right: 8 },
...text(theme, "sans", "secondary", { size: "xs" }),
...text(colorScheme.middle, "sans", "accent", { size: "xs" }),
},
leaderBorderOpacity: 0.7,
leaderBorderWidth: 2.0,
tabBar: tabBar(theme),
tabBar: tabBar(colorScheme),
modal: {
margin: {
bottom: 52,
@@ -68,28 +62,28 @@ export default function workspace(theme: Theme) {
},
sidebar: {
initialSize: 240,
border: {
color: border(theme, "primary").color,
width: 1,
left: true,
right: true,
}
border: border(layer, { left: true, right: true }),
},
paneDivider: {
color: border(theme, "secondary").color,
color: borderColor(layer),
width: 1,
},
statusBar: statusBar(theme),
statusBar: statusBar(colorScheme),
titlebar: {
avatarWidth,
avatarMargin: 8,
height: 33,
background: backgroundColor(theme, 100),
height: 33, // 32px + 1px for overlaid border
background: background(layer),
border: border(layer, { bottom: true, overlay: true }),
padding: {
left: 80,
right: titlebarPadding,
},
title: text(theme, "sans", "primary"),
// Project
title: text(layer, "sans", "variant"),
// Collaborators
avatar: {
cornerRadius: avatarWidth / 2,
border: {
@@ -108,15 +102,18 @@ export default function workspace(theme: Theme) {
avatarRibbon: {
height: 3,
width: 12,
// TODO: The background for this ideally should be
// set with a token, not hardcoded in rust
// TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
},
border: border(theme, "primary", { bottom: true, overlay: true }),
// Sign in buttom
// FlatButton, Variant
signInPrompt: {
...titlebarButton
},
// Offline Indicator
offlineIcon: {
color: iconColor(theme, "secondary"),
color: foreground(layer, "variant"),
width: 16,
margin: {
left: titlebarPadding,
@@ -125,90 +122,93 @@ export default function workspace(theme: Theme) {
right: 4,
},
},
// Notice that the collaboration server is out of date
outdatedWarning: {
...text(theme, "sans", "warning", { size: "xs" }),
background: backgroundColor(theme, "warning"),
border: border(theme, "warning"),
...text(layer, "sans", "warning", { size: "xs" }),
background: withOpacity(background(layer, "warning"), 0.3),
border: border(layer, "warning"),
margin: {
left: titlebarPadding,
},
padding: {
left: 6,
right: 6,
left: 8,
right: 8,
},
cornerRadius: 6,
},
callControl: {
cornerRadius: 6,
color: iconColor(theme, "secondary"),
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: 20,
hover: {
background: backgroundColor(theme, "on300", "hovered"),
color: iconColor(theme, "active"),
background: background(layer, "variant", "hovered"),
color: foreground(layer, "variant", "hovered"),
},
},
toggleContactsButton: {
margin: { left: 6 },
cornerRadius: 6,
color: iconColor(theme, "secondary"),
color: foreground(layer, "variant"),
iconWidth: 8,
buttonWidth: 20,
active: {
background: backgroundColor(theme, "on300", "active"),
color: iconColor(theme, "active"),
background: background(layer, "variant", "active"),
color: foreground(layer, "variant", "active"),
},
hover: {
background: backgroundColor(theme, "on300", "hovered"),
color: iconColor(theme, "active"),
background: background(layer, "variant", "hovered"),
color: foreground(layer, "variant", "hovered"),
},
},
toggleContactsBadge: {
cornerRadius: 3,
padding: 2,
margin: { top: 3, left: 3 },
border: { width: 1, color: workspaceBackground(theme) },
background: iconColor(theme, "feature"),
border: border(layer),
background: foreground(layer, "accent"),
},
shareButton: {
...titlebarButton
}
},
toolbar: {
height: 34,
background: backgroundColor(theme, 500),
border: border(theme, "secondary", { bottom: true }),
background: background(colorScheme.highest),
border: border(colorScheme.highest, { bottom: true }),
itemSpacing: 8,
navButton: {
color: iconColor(theme, "primary"),
color: foreground(colorScheme.highest, "on"),
iconWidth: 12,
buttonWidth: 24,
cornerRadius: 6,
hover: {
color: iconColor(theme, "active"),
background: backgroundColor(theme, "on500", "hovered"),
color: foreground(colorScheme.highest, "on", "hovered"),
background: background(colorScheme.highest, "on", "hovered"),
},
disabled: {
color: withOpacity(iconColor(theme, "muted"), 0.6),
color: foreground(colorScheme.highest, "on", "disabled"),
},
},
padding: { left: 8, right: 8, top: 4, bottom: 4 },
},
breadcrumbs: {
...text(theme, "mono", "secondary"),
...text(layer, "mono", "variant"),
padding: { left: 6 },
},
disconnectedOverlay: {
...text(theme, "sans", "active"),
background: withOpacity(theme.backgroundColor[500].base, 0.8),
...text(layer, "sans"),
background: withOpacity(background(layer), 0.8),
},
notification: {
margin: { top: 10 },
background: backgroundColor(theme, 300),
background: background(colorScheme.middle),
cornerRadius: 6,
padding: 12,
border: border(theme, "primary"),
shadow: modalShadow(theme),
border: border(colorScheme.middle),
shadow: colorScheme.popoverShadow,
},
notifications: {
width: 400,
@@ -217,18 +217,15 @@ export default function workspace(theme: Theme) {
dock: {
initialSizeRight: 640,
initialSizeBottom: 480,
wash_color: withOpacity(theme.backgroundColor[500].base, 0.5),
wash_color: withOpacity(background(colorScheme.highest), 0.5),
panel: {
border: {
...border(theme, "secondary"),
width: 1
},
border: border(colorScheme.highest),
},
maximized: {
margin: 24,
border: border(theme, "secondary", { "overlay": true }),
shadow: modalShadow(theme),
}
}
margin: 32,
border: border(colorScheme.highest, { overlay: true }),
shadow: colorScheme.modalShadow,
},
},
};
}