This commit is contained in:
Nate Butler
2023-06-21 13:58:54 -04:00
parent a845e82173
commit 9d9bbfdabf
14 changed files with 387 additions and 412 deletions
+44 -42
View File
@@ -1,13 +1,13 @@
import * as fs from "fs";
import * as path from "path";
import { ColorScheme, createColorScheme } from "./common";
import { themes } from "./themes";
import { slugify } from "./utils/slugify";
import { colorSchemeTokens } from "./theme/tokens/colorScheme";
import * as fs from "fs"
import * as path from "path"
import { ColorScheme, createColorScheme } from "./common"
import { themes } from "./themes"
import { slugify } from "./utils/slugify"
import { colorSchemeTokens } from "./theme/tokens/colorScheme"
const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens");
const TOKENS_FILE = path.join(TOKENS_DIRECTORY, "$themes.json");
const METADATA_FILE = path.join(TOKENS_DIRECTORY, "$metadata.json");
const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens")
const TOKENS_FILE = path.join(TOKENS_DIRECTORY, "$themes.json")
const METADATA_FILE = path.join(TOKENS_DIRECTORY, "$metadata.json")
function clearTokens(tokensDirectory: string) {
if (!fs.existsSync(tokensDirectory)) {
@@ -22,64 +22,66 @@ function clearTokens(tokensDirectory: string) {
}
type TokenSet = {
id: string;
name: string;
selectedTokenSets: { [key: string]: "enabled" };
};
id: string
name: string
selectedTokenSets: { [key: string]: "enabled" }
}
function buildTokenSetOrder(colorSchemes: ColorScheme[]): { tokenSetOrder: string[] } {
const tokenSetOrder: string[] = colorSchemes.map(
(scheme) => scheme.name.toLowerCase().replace(/\s+/g, "_")
);
return { tokenSetOrder };
function buildTokenSetOrder(colorSchemes: ColorScheme[]): {
tokenSetOrder: string[]
} {
const tokenSetOrder: string[] = colorSchemes.map((scheme) =>
scheme.name.toLowerCase().replace(/\s+/g, "_")
)
return { tokenSetOrder }
}
function buildThemesIndex(colorSchemes: ColorScheme[]): TokenSet[] {
const themesIndex: TokenSet[] = colorSchemes.map((scheme, index) => {
const id = `${scheme.isLight ? "light" : "dark"}_${scheme.name
.toLowerCase()
.replace(/\s+/g, "_")}_${index}`;
const selectedTokenSets: { [key: string]: "enabled" } = {};
const tokenSet = scheme.name.toLowerCase().replace(/\s+/g, "_");
selectedTokenSets[tokenSet] = "enabled";
.replace(/\s+/g, "_")}_${index}`
const selectedTokenSets: { [key: string]: "enabled" } = {}
const tokenSet = scheme.name.toLowerCase().replace(/\s+/g, "_")
selectedTokenSets[tokenSet] = "enabled"
return {
id,
name: `${scheme.name} - ${scheme.isLight ? "Light" : "Dark"}`,
selectedTokenSets,
};
});
}
})
return themesIndex;
return themesIndex
}
function writeTokens(colorSchemes: ColorScheme[], tokensDirectory: string) {
clearTokens(tokensDirectory);
clearTokens(tokensDirectory)
for (const colorScheme of colorSchemes) {
const fileName = slugify(colorScheme.name) + ".json";
const tokens = colorSchemeTokens(colorScheme);
const tokensJSON = JSON.stringify(tokens, null, 2);
const outPath = path.join(tokensDirectory, fileName);
fs.writeFileSync(outPath, tokensJSON, { mode: 0o644 });
console.log(`- ${outPath} created`);
const fileName = slugify(colorScheme.name) + ".json"
const tokens = colorSchemeTokens(colorScheme)
const tokensJSON = JSON.stringify(tokens, null, 2)
const outPath = path.join(tokensDirectory, fileName)
fs.writeFileSync(outPath, tokensJSON, { mode: 0o644 })
console.log(`- ${outPath} created`)
}
const themeIndexData = buildThemesIndex(colorSchemes);
const themeIndexData = buildThemesIndex(colorSchemes)
const themesJSON = JSON.stringify(themeIndexData, null, 2);
fs.writeFileSync(TOKENS_FILE, themesJSON, { mode: 0o644 });
console.log(`- ${TOKENS_FILE} created`);
const themesJSON = JSON.stringify(themeIndexData, null, 2)
fs.writeFileSync(TOKENS_FILE, themesJSON, { mode: 0o644 })
console.log(`- ${TOKENS_FILE} created`)
const tokenSetOrderData = buildTokenSetOrder(colorSchemes);
const tokenSetOrderData = buildTokenSetOrder(colorSchemes)
const metadataJSON = JSON.stringify(tokenSetOrderData, null, 2);
fs.writeFileSync(METADATA_FILE, metadataJSON, { mode: 0o644 });
console.log(`- ${METADATA_FILE} created`);
const metadataJSON = JSON.stringify(tokenSetOrderData, null, 2)
fs.writeFileSync(METADATA_FILE, metadataJSON, { mode: 0o644 })
console.log(`- ${METADATA_FILE} created`)
}
const colorSchemes: ColorScheme[] = themes.map((theme) =>
createColorScheme(theme)
);
)
writeTokens(colorSchemes, TOKENS_DIRECTORY);
writeTokens(colorSchemes, TOKENS_DIRECTORY)
+59 -59
View File
@@ -2,28 +2,28 @@ import merge from "ts-deepmerge"
import { DeepPartial } from "utility-types"
type InteractiveState =
| "default"
| "hovered"
| "clicked"
| "selected"
| "disabled"
| "default"
| "hovered"
| "clicked"
| "selected"
| "disabled"
type Interactive<T> = {
default: T
hovered?: T
clicked?: T
selected?: T
disabled?: T
default: T
hovered?: T
clicked?: T
selected?: T
disabled?: T
}
export const NO_DEFAULT_OR_BASE_ERROR =
"An interactive object must have a default state, or a base property."
"An interactive object must have a default state, or a base property."
export const NOT_ENOUGH_STATES_ERROR =
"An interactive object must have a default and at least one other state."
"An interactive object must have a default and at least one other state."
interface InteractiveProps<T> {
base?: T
state: Partial<Record<InteractiveState, DeepPartial<T>>>
base?: T
state: Partial<Record<InteractiveState, DeepPartial<T>>>
}
/**
@@ -38,60 +38,60 @@ interface InteractiveProps<T> {
* @returns Interactive<T> object with fields from `base` and `state`.
*/
export function interactive<T extends Object>({
base,
state,
base,
state,
}: InteractiveProps<T>): Interactive<T> {
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR)
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR)
let defaultState: T
let defaultState: T
if (state.default && base) {
defaultState = merge(base, state.default) as T
} else {
defaultState = base ? base : (state.default as T)
}
if (state.default && base) {
defaultState = merge(base, state.default) as T
} else {
defaultState = base ? base : (state.default as T)
}
let interactiveObj: Interactive<T> = {
default: defaultState,
}
let interactiveObj: Interactive<T> = {
default: defaultState,
}
let stateCount = 0
let stateCount = 0
if (state.hovered !== undefined) {
interactiveObj.hovered = merge(
interactiveObj.default,
state.hovered
) as T
stateCount++
}
if (state.hovered !== undefined) {
interactiveObj.hovered = merge(
interactiveObj.default,
state.hovered
) as T
stateCount++
}
if (state.clicked !== undefined) {
interactiveObj.clicked = merge(
interactiveObj.default,
state.clicked
) as T
stateCount++
}
if (state.clicked !== undefined) {
interactiveObj.clicked = merge(
interactiveObj.default,
state.clicked
) as T
stateCount++
}
if (state.selected !== undefined) {
interactiveObj.selected = merge(
interactiveObj.default,
state.selected
) as T
stateCount++
}
if (state.selected !== undefined) {
interactiveObj.selected = merge(
interactiveObj.default,
state.selected
) as T
stateCount++
}
if (state.disabled !== undefined) {
interactiveObj.disabled = merge(
interactiveObj.default,
state.disabled
) as T
stateCount++
}
if (state.disabled !== undefined) {
interactiveObj.disabled = merge(
interactiveObj.default,
state.disabled
) as T
stateCount++
}
if (stateCount < 1) {
throw new Error(NOT_ENOUGH_STATES_ERROR)
}
if (stateCount < 1) {
throw new Error(NOT_ENOUGH_STATES_ERROR)
}
return interactiveObj
return interactiveObj
}
+15 -15
View File
@@ -6,12 +6,12 @@ type ToggleState = "inactive" | "active"
type Toggleable<T> = Record<ToggleState, T>
export const NO_INACTIVE_OR_BASE_ERROR =
"A toggleable object must have an inactive state, or a base property."
"A toggleable object must have an inactive state, or a base property."
export const NO_ACTIVE_ERROR = "A toggleable object must have an active state."
interface ToggleableProps<T> {
base?: T
state: Partial<Record<ToggleState, DeepPartial<T>>>
base?: T
state: Partial<Record<ToggleState, DeepPartial<T>>>
}
/**
@@ -28,20 +28,20 @@ interface ToggleableProps<T> {
* ```
*/
export function toggleable<T extends object>(
props: ToggleableProps<T>
props: ToggleableProps<T>
): Toggleable<T> {
const { base, state } = props
const { base, state } = props
if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR)
if (!state.active) throw new Error(NO_ACTIVE_ERROR)
if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR)
if (!state.active) throw new Error(NO_ACTIVE_ERROR)
const inactiveState = base
? ((state.inactive ? merge(base, state.inactive) : base) as T)
: (state.inactive as T)
const inactiveState = base
? ((state.inactive ? merge(base, state.inactive) : base) as T)
: (state.inactive as T)
const toggleObj: Toggleable<T> = {
inactive: inactiveState,
active: merge(base ?? {}, state.active) as T,
}
return toggleObj
const toggleObj: Toggleable<T> = {
inactive: inactiveState,
active: merge(base ?? {}, state.active) as T,
}
return toggleObj
}
+3 -3
View File
@@ -27,8 +27,8 @@ export default function commandPalette(colorScheme: ColorScheme) {
active: {
text: text(layer, "mono", "on", "default", { size: "xs" }),
background: withOpacity(background(layer, "on"), 0.2),
}
}
},
},
})
return {
@@ -37,6 +37,6 @@ export default function commandPalette(colorScheme: ColorScheme) {
key: {
inactive: { ...key.inactive },
active: key.active,
}
},
}
}
+37 -41
View File
@@ -88,7 +88,7 @@ export default function contactsPanel(colorScheme: ColorScheme) {
},
clicked: {
background: background(layer, "pressed"),
}
},
}, // hack, we want headerRow to be interactive for whatever reason. It probably shouldn't be interactive in the first place.
}),
state: {
@@ -102,9 +102,9 @@ export default function contactsPanel(colorScheme: ColorScheme) {
},
clicked: {
background: background(layer, "pressed"),
}
}
}
},
},
},
}),
leaveCall: interactive({
base: {
@@ -190,55 +190,51 @@ export default function contactsPanel(colorScheme: ColorScheme) {
...text(layer, "mono", "variant", { size: "xs" }),
},
treeBranch: toggleable({
base:
interactive({
base: {
base: interactive({
base: {
color: borderColor(layer),
width: 1,
},
state: {
hovered: {
color: borderColor(layer),
width: 1,
},
state: {
hovered: {
color: borderColor(layer),
},
},
}),
},
}),
state: {
active: {
default: {
color: borderColor(layer),
},
}
}
}
),
},
},
}),
projectRow: toggleable({
base:
interactive({
base: {
...projectRow,
background: background(layer),
icon: {
margin: { left: nameMargin },
color: foreground(layer, "variant"),
width: 12,
},
name: {
...projectRow.name,
...text(layer, "mono", { size: "sm" }),
},
base: interactive({
base: {
...projectRow,
background: background(layer),
icon: {
margin: { left: nameMargin },
color: foreground(layer, "variant"),
width: 12,
},
state: {
hovered: {
background: background(layer, "hovered"),
},
name: {
...projectRow.name,
...text(layer, "mono", { size: "sm" }),
},
}),
},
state: {
hovered: {
background: background(layer, "hovered"),
},
},
}),
state: {
active: {
default: { background: background(layer, "active") },
}
}
}
),
},
},
}),
}
}
+27 -29
View File
@@ -12,39 +12,38 @@ export default function contextMenu(colorScheme: ColorScheme) {
border: border(layer),
keystrokeMargin: 30,
item: toggleable({
base:
interactive({
base: {
iconSpacing: 8,
iconWidth: 14,
padding: { left: 6, right: 6, top: 2, bottom: 2 },
cornerRadius: 6,
label: text(layer, "sans", { size: "sm" }),
base: interactive({
base: {
iconSpacing: 8,
iconWidth: 14,
padding: { left: 6, right: 6, top: 2, bottom: 2 },
cornerRadius: 6,
label: text(layer, "sans", { size: "sm" }),
keystroke: {
...text(layer, "sans", "variant", {
size: "sm",
weight: "bold",
}),
padding: { left: 3, right: 3 },
},
},
state: {
hovered: {
background: background(layer, "hovered"),
label: text(layer, "sans", "hovered", { size: "sm" }),
keystroke: {
...text(layer, "sans", "variant", {
...text(layer, "sans", "hovered", {
size: "sm",
weight: "bold",
}),
padding: { left: 3, right: 3 },
},
},
state: {
hovered: {
background: background(layer, "hovered"),
label: text(layer, "sans", "hovered", { size: "sm" }),
keystroke: {
...text(layer, "sans", "hovered", {
size: "sm",
weight: "bold",
}),
padding: { left: 3, right: 3 },
},
},
clicked: {
background: background(layer, "pressed"),
},
clicked: {
background: background(layer, "pressed"),
},
}),
},
}),
state: {
active: {
default: {
@@ -56,10 +55,9 @@ export default function contextMenu(colorScheme: ColorScheme) {
clicked: {
background: background(layer, "pressed"),
},
}
}
}
),
},
},
}),
separator: {
background: borderColor(layer),
+28 -32
View File
@@ -50,20 +50,19 @@ export default function editor(colorScheme: ColorScheme) {
suggestion: syntax.predictive,
codeActions: {
indicator: toggleable({
base:
interactive({
base: {
color: foreground(layer, "variant"),
base: interactive({
base: {
color: foreground(layer, "variant"),
},
state: {
hovered: {
color: foreground(layer, "variant", "hovered"),
},
state: {
hovered: {
color: foreground(layer, "variant", "hovered"),
},
clicked: {
color: foreground(layer, "variant", "pressed"),
},
clicked: {
color: foreground(layer, "variant", "pressed"),
},
}),
},
}),
state: {
active: {
default: {
@@ -75,10 +74,9 @@ export default function editor(colorScheme: ColorScheme) {
clicked: {
color: foreground(layer, "accent", "pressed"),
},
}
}
}
),
},
},
}),
verticalScale: 0.55,
},
@@ -87,20 +85,19 @@ export default function editor(colorScheme: ColorScheme) {
foldedIcon: "icons/chevron_right_8.svg",
foldableIcon: "icons/chevron_down_8.svg",
indicator: toggleable({
base:
interactive({
base: {
color: foreground(layer, "variant"),
base: interactive({
base: {
color: foreground(layer, "variant"),
},
state: {
hovered: {
color: foreground(layer, "on"),
},
state: {
hovered: {
color: foreground(layer, "on"),
},
clicked: {
color: foreground(layer, "base"),
},
clicked: {
color: foreground(layer, "base"),
},
}),
},
}),
state: {
active: {
default: {
@@ -109,10 +106,9 @@ export default function editor(colorScheme: ColorScheme) {
hovered: {
color: foreground(layer, "variant"),
},
}
}
}
),
},
},
}),
ellipses: {
textColor: colorScheme.ramps.neutral(0.71).hex(),
cornerRadiusFactor: 0.15,
+35 -37
View File
@@ -40,41 +40,40 @@ export default function picker(colorScheme: ColorScheme): any {
padding: {},
},
item: toggleable({
base:
interactive({
base: {
padding: {
bottom: 4,
left: 12,
right: 12,
top: 4,
},
margin: {
top: 1,
left: 4,
right: 4,
},
cornerRadius: 8,
text: text(layer, "sans", "variant"),
highlightText: text(layer, "sans", "accent", {
weight: "bold",
}),
base: interactive({
base: {
padding: {
bottom: 4,
left: 12,
right: 12,
top: 4,
},
state: {
hovered: {
background: withOpacity(
background(layer, "hovered"),
0.5
),
},
clicked: {
background: withOpacity(
background(layer, "pressed"),
0.5
),
},
margin: {
top: 1,
left: 4,
right: 4,
},
}),
cornerRadius: 8,
text: text(layer, "sans", "variant"),
highlightText: text(layer, "sans", "accent", {
weight: "bold",
}),
},
state: {
hovered: {
background: withOpacity(
background(layer, "hovered"),
0.5
),
},
clicked: {
background: withOpacity(
background(layer, "pressed"),
0.5
),
},
},
}),
state: {
active: {
default: {
@@ -95,10 +94,9 @@ export default function picker(colorScheme: ColorScheme): any {
0.5
),
},
}
}
}
),
},
},
}),
inputEditor,
emptyInputEditor,
+5 -6
View File
@@ -43,7 +43,7 @@ export default function projectPanel(colorScheme: ColorScheme) {
},
clicked: {
background: background(layer, "variant", "pressed"),
}
},
},
})
@@ -52,7 +52,7 @@ export default function projectPanel(colorScheme: ColorScheme) {
state: {
active: interactive({
base: {
...default_entry
...default_entry,
},
state: {
default: {
@@ -66,9 +66,8 @@ export default function projectPanel(colorScheme: ColorScheme) {
},
},
}),
}
}
)
},
})
return {
openProjectButton: interactive({
@@ -99,7 +98,7 @@ export default function projectPanel(colorScheme: ColorScheme) {
...text(layer, "sans", "default", { size: "sm" }),
background: background(layer, "pressed"),
border: border(layer, "active"),
}
},
},
}),
background: background(layer),
+30 -32
View File
@@ -37,36 +37,35 @@ export default function search(colorScheme: ColorScheme) {
// TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
optionButton: toggleable({
base:
interactive({
base: {
...text(layer, "mono", "on"),
background: background(layer, "on"),
cornerRadius: 6,
border: border(layer, "on"),
margin: {
right: 4,
},
padding: {
bottom: 2,
left: 10,
right: 10,
top: 2,
},
base: interactive({
base: {
...text(layer, "mono", "on"),
background: background(layer, "on"),
cornerRadius: 6,
border: border(layer, "on"),
margin: {
right: 4,
},
state: {
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
clicked: {
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
padding: {
bottom: 2,
left: 10,
right: 10,
top: 2,
},
}),
},
state: {
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
clicked: {
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
},
}),
state: {
active: {
default: {
@@ -78,10 +77,9 @@ export default function search(colorScheme: ColorScheme) {
clicked: {
...text(layer, "mono", "accent", "pressed"),
},
}
}
}
),
},
},
}),
editor,
invalidEditor: {
...editor,
+19 -22
View File
@@ -108,25 +108,24 @@ export default function statusBar(colorScheme: ColorScheme) {
groupBottom: {},
groupRight: {},
button: toggleable({
base:
interactive({
base: {
...statusContainer,
iconSize: 16,
iconColor: foreground(layer, "variant"),
label: {
margin: { left: 6 },
...text(layer, "sans", { size: "sm" }),
},
base: interactive({
base: {
...statusContainer,
iconSize: 16,
iconColor: foreground(layer, "variant"),
label: {
margin: { left: 6 },
...text(layer, "sans", { size: "sm" }),
},
state: {
hovered: {
iconColor: foreground(layer, "hovered"),
background: background(layer, "variant"),
},
},
state: {
hovered: {
iconColor: foreground(layer, "hovered"),
background: background(layer, "variant"),
},
}), state:
{
},
}),
state: {
active: {
default: {
iconColor: foreground(layer, "active"),
@@ -140,11 +139,9 @@ export default function statusBar(colorScheme: ColorScheme) {
iconColor: foreground(layer, "pressed"),
background: background(layer, "pressed"),
},
}
}
}
),
},
},
}),
badge: {
cornerRadius: 3,
padding: 2,
+17 -20
View File
@@ -89,24 +89,22 @@ export default function tabBar(colorScheme: ColorScheme) {
},
draggedTab,
paneButton: toggleable({
base:
interactive({
base: {
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: activePaneActiveTab.height,
base: interactive({
base: {
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: activePaneActiveTab.height,
},
state: {
hovered: {
color: foreground(layer, "hovered"),
},
state: {
hovered: {
color: foreground(layer, "hovered"),
},
clicked: {
color: foreground(layer, "pressed"),
},
clicked: {
color: foreground(layer, "pressed"),
},
}),
state:
{
},
}),
state: {
active: {
default: {
color: foreground(layer, "accent"),
@@ -117,10 +115,9 @@ export default function tabBar(colorScheme: ColorScheme) {
clicked: {
color: foreground(layer, "pressed"),
},
}
}
}
),
},
},
}),
paneButtonContainer: {
background: tab.background,
border: {
+17 -19
View File
@@ -19,7 +19,7 @@ export default function dropdownMenu(colorScheme: ColorScheme) {
secondaryTextSpacing: 10,
padding: { left: 8, right: 8, top: 2, bottom: 2 },
cornerRadius: 6,
background: background(layer, "on")
background: background(layer, "on"),
},
state: {
hovered: {
@@ -35,21 +35,20 @@ export default function dropdownMenu(colorScheme: ColorScheme) {
padding: { left: 8, right: 8, top: 8, bottom: 8 },
},
item: toggleable({
base:
interactive({
base: {
...text(layer, "sans", { size: "sm" }),
secondaryTextSpacing: 10,
secondaryText: text(layer, "sans", { size: "sm" }),
padding: { left: 18, right: 18, top: 2, bottom: 2 },
base: interactive({
base: {
...text(layer, "sans", { size: "sm" }),
secondaryTextSpacing: 10,
secondaryText: text(layer, "sans", { size: "sm" }),
padding: { left: 18, right: 18, top: 2, bottom: 2 },
},
state: {
hovered: {
background: background(layer, "hovered"),
...text(layer, "sans", "hovered", { size: "sm" }),
},
state: {
hovered: {
background: background(layer, "hovered"),
...text(layer, "sans", "hovered", { size: "sm" }),
},
},
}),
},
}),
state: {
active: {
default: {
@@ -58,9 +57,8 @@ export default function dropdownMenu(colorScheme: ColorScheme) {
hovered: {
background: background(layer, "hovered"),
},
}
}
}
),
},
},
}),
}
}
+51 -55
View File
@@ -18,37 +18,36 @@ export default function workspace(colorScheme: ColorScheme) {
const isLight = colorScheme.isLight
const itemSpacing = 8
const titlebarButton = toggleable({
base:
interactive({
base: {
cornerRadius: 6,
padding: {
top: 1,
bottom: 1,
left: 8,
right: 8,
},
...text(layer, "sans", "variant", { size: "xs" }),
background: background(layer, "variant"),
border: border(layer),
base: interactive({
base: {
cornerRadius: 6,
padding: {
top: 1,
bottom: 1,
left: 8,
right: 8,
},
state: {
hovered: {
...text(layer, "sans", "variant", "hovered", {
size: "xs",
}),
background: background(layer, "variant", "hovered"),
border: border(layer, "variant", "hovered"),
},
clicked: {
...text(layer, "sans", "variant", "pressed", {
size: "xs",
}),
background: background(layer, "variant", "pressed"),
border: border(layer, "variant", "pressed"),
},
...text(layer, "sans", "variant", { size: "xs" }),
background: background(layer, "variant"),
border: border(layer),
},
state: {
hovered: {
...text(layer, "sans", "variant", "hovered", {
size: "xs",
}),
background: background(layer, "variant", "hovered"),
border: border(layer, "variant", "hovered"),
},
}),
clicked: {
...text(layer, "sans", "variant", "pressed", {
size: "xs",
}),
background: background(layer, "variant", "pressed"),
border: border(layer, "variant", "pressed"),
},
},
}),
state: {
active: {
default: {
@@ -56,10 +55,9 @@ export default function workspace(colorScheme: ColorScheme) {
background: background(layer, "variant", "active"),
border: border(layer, "variant", "active"),
},
}
}
}
)
},
},
})
const avatarWidth = 18
const avatarOuterWidth = avatarWidth + 4
const followerAvatarWidth = 14
@@ -275,25 +273,24 @@ export default function workspace(colorScheme: ColorScheme) {
},
}),
toggleContactsButton: toggleable({
base:
interactive({
base: {
margin: { left: itemSpacing },
cornerRadius: 6,
color: foreground(layer, "variant"),
iconWidth: 14,
buttonWidth: 20,
base: interactive({
base: {
margin: { left: itemSpacing },
cornerRadius: 6,
color: foreground(layer, "variant"),
iconWidth: 14,
buttonWidth: 20,
},
state: {
clicked: {
background: background(layer, "variant", "pressed"),
},
state: {
clicked: {
background: background(layer, "variant", "pressed"),
},
hovered: {
background: background(layer, "variant", "hovered"),
},
hovered: {
background: background(layer, "variant", "hovered"),
},
}), state:
{
},
}),
state: {
active: {
default: {
background: background(layer, "on", "default"),
@@ -303,11 +300,10 @@ export default function workspace(colorScheme: ColorScheme) {
},
clicked: {
background: background(layer, "on", "pressed"),
}
}
}
}
),
},
},
},
}),
userMenuButton: merge(titlebarButton, {
inactive: {
default: {