Set up vitest and add tests for interactive

This commit is contained in:
Nate Butler 2023-06-15 18:42:48 -04:00 committed by Mikayla Maki
parent 4bd89c4c8c
commit 5369f2c25a
No known key found for this signature in database
25 changed files with 4546 additions and 2163 deletions

1
styles/.gitignore vendored
View File

@ -1 +1,2 @@
node_modules/
coverage/

2306
styles/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,8 @@
"scripts": {
"build": "ts-node ./src/buildThemes.ts",
"build-licenses": "ts-node ./src/buildLicenses.ts",
"build-tokens": "ts-node ./src/buildTokens.ts"
"build-tokens": "ts-node ./src/buildTokens.ts",
"test": "vitest"
},
"author": "",
"license": "ISC",
@ -22,12 +23,16 @@
"toml": "^3.0.0",
"ts-deepmerge": "^6.0.3",
"ts-node": "^10.9.1",
"utility-types": "^3.10.0"
"utility-types": "^3.10.0",
"vitest": "^0.32.0"
},
"prettier": {
"semi": false,
"printWidth": 80,
"htmlWhitespaceSensitivity": "strict",
"tabWidth": 4
},
"devDependencies": {
"@vitest/coverage-v8": "^0.32.0"
}
}

View File

@ -0,0 +1,3 @@
import { interactive } from "./interactive";
export { interactive }

View File

@ -0,0 +1,59 @@
import { NOT_ENOUGH_STATES_ERROR, NO_DEFAULT_OR_BASE_ERROR, interactive } from './interactive'
import { describe, it, expect } from 'vitest'
describe('interactive', () => {
it('creates an Interactive<Element> with base properties and states', () => {
const result = interactive({
base: { fontSize: 10, color: '#FFFFFF' },
state: {
hovered: { color: '#EEEEEE' },
clicked: { color: '#CCCCCC' },
}
})
expect(result).toEqual({
default: { color: '#FFFFFF', fontSize: 10 },
hovered: { color: '#EEEEEE', fontSize: 10 },
clicked: { color: '#CCCCCC', fontSize: 10 },
})
})
it('creates an Interactive<Element> with no base properties', () => {
const result = interactive({
state: {
default: { color: '#FFFFFF', fontSize: 10 },
hovered: { color: '#EEEEEE' },
clicked: { color: '#CCCCCC' },
}
})
expect(result).toEqual({
default: { color: '#FFFFFF', fontSize: 10 },
hovered: { color: '#EEEEEE', fontSize: 10 },
clicked: { color: '#CCCCCC', fontSize: 10 },
})
})
it('throws error when both default and base are missing', () => {
const state = {
hovered: { color: 'blue' },
}
expect(() => interactive({ state })).toThrow(
NO_DEFAULT_OR_BASE_ERROR
)
})
it('throws error when no other state besides default is present', () => {
const state = {
default: { fontSize: 10 },
}
expect(() => interactive({ state })).toThrow(
NOT_ENOUGH_STATES_ERROR
)
})
})

View File

@ -10,24 +10,27 @@ type Interactive<T> = {
disabled?: T,
};
export const NO_DEFAULT_OR_BASE_ERROR = "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."
interface InteractiveProps<T> {
base?: T,
state: Partial<Record<InteractiveState, T>>
}
/**
* Helper function for creating Interactive<T> objects that works pretty much like Toggle<T>.
* It takes a object to be used as a value for `default` field and then fills out other fields
* with fields from either `base` or `modifications`.
* Notably, it does not touch `hover`, `clicked` and `disabled` if there are no modifications for it.
* Helper function for creating Interactive<T> objects that works with Toggle<T>-like behavior.
* It takes a default object to be used as the value for `default` field and fills out other fields
* with fields from either `base` or from the `state` object which contains values for specific states.
* Notably, it does not touch `hover`, `clicked`, `selected` and `disabled` states if there are no modifications for them.
*
* @param defaultObj Object to be used as the value for `default` field.
* @param base Object containing base fields to be included in the resulting object.
* @param modifications Object containing modified fields to be included in the resulting object.
* @returns Interactive<T> object with fields from `base` and `modifications`.
* @param defaultObj Object to be used as the value for the `default` field.
* @param base Optional object containing base fields to be included in the resulting object.
* @param state Object containing optional modified fields to be included in the resulting object for each state.
* @returns Interactive<T> object with fields from `base` and `state`.
*/
export function interactive<T extends Object>({ base, state }: InteractiveProps<T>): Interactive<T> {
if (!base && !state.default) throw new Error("An interactive object must have a default state, or a base property.");
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR);
let defaultState: T;
@ -64,7 +67,7 @@ export function interactive<T extends Object>({ base, state }: InteractiveProps<
}
if (stateCount < 1) {
throw new Error("An interactive object must have a default and at least one other state.");
throw new Error(NOT_ENOUGH_STATES_ERROR);
}
return interactiveObj;

View File

@ -1,94 +1,94 @@
import { ColorScheme } from "../theme/colorScheme"
import { text, border, background, foreground } from "./components"
import editor from "./editor"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function assistant(colorScheme: ColorScheme) {
const layer = colorScheme.highest
return {
container: {
background: editor(colorScheme).background,
padding: { left: 12 },
},
header: {
border: border(layer, "default", { bottom: true, top: true }),
margin: { bottom: 6, top: 6 },
background: editor(colorScheme).background,
},
userSender: {
default:
{ ...text(layer, "sans", "default", { size: "sm", weight: "bold" }) },
},
assistantSender: {
default: {
...text(layer, "sans", "accent", { size: "sm", weight: "bold" })
},
},
systemSender: {
default: {
...text(layer, "sans", "variant", { size: "sm", weight: "bold" })
},
},
sentAt: {
margin: { top: 2, left: 8 },
...text(layer, "sans", "default", { size: "2xs" }),
},
modelInfoContainer: {
margin: { right: 16, top: 4 },
},
model: interactive({
base: {
background: background(layer, "on"),
border: border(layer, "on", { overlay: true }),
padding: 4,
cornerRadius: 4,
...text(layer, "sans", "default", { size: "xs" }),
}, state: {
hovered: {
background: background(layer, "on", "hovered"),
}
}
}),
remainingTokens: {
background: background(layer, "on"),
border: border(layer, "on", { overlay: true }),
padding: 4,
margin: { left: 4 },
cornerRadius: 4,
...text(layer, "sans", "positive", { size: "xs" }),
},
noRemainingTokens: {
background: background(layer, "on"),
border: border(layer, "on", { overlay: true }),
padding: 4,
margin: { left: 4 },
cornerRadius: 4,
...text(layer, "sans", "negative", { size: "xs" }),
},
errorIcon: {
margin: { left: 8 },
color: foreground(layer, "negative"),
width: 12,
},
apiKeyEditor: {
background: background(layer, "on"),
cornerRadius: 6,
text: text(layer, "mono", "on"),
placeholderText: text(layer, "mono", "on", "disabled", {
size: "xs",
}),
selection: colorScheme.players[0],
border: border(layer, "on"),
padding: {
bottom: 4,
left: 8,
right: 8,
top: 4,
},
},
apiKeyPrompt: {
padding: 10,
...text(layer, "sans", "default", { size: "xs" }),
},
}
const layer = colorScheme.highest
return {
container: {
background: editor(colorScheme).background,
padding: { left: 12 },
},
header: {
border: border(layer, "default", { bottom: true, top: true }),
margin: { bottom: 6, top: 6 },
background: editor(colorScheme).background,
},
userSender: {
default:
{ ...text(layer, "sans", "default", { size: "sm", weight: "bold" }) },
},
assistantSender: {
default: {
...text(layer, "sans", "accent", { size: "sm", weight: "bold" })
},
},
systemSender: {
default: {
...text(layer, "sans", "variant", { size: "sm", weight: "bold" })
},
},
sentAt: {
margin: { top: 2, left: 8 },
...text(layer, "sans", "default", { size: "2xs" }),
},
modelInfoContainer: {
margin: { right: 16, top: 4 },
},
model: interactive({
base: {
background: background(layer, "on"),
border: border(layer, "on", { overlay: true }),
padding: 4,
cornerRadius: 4,
...text(layer, "sans", "default", { size: "xs" }),
}, state: {
hovered: {
background: background(layer, "on", "hovered"),
}
}
}),
remainingTokens: {
background: background(layer, "on"),
border: border(layer, "on", { overlay: true }),
padding: 4,
margin: { left: 4 },
cornerRadius: 4,
...text(layer, "sans", "positive", { size: "xs" }),
},
noRemainingTokens: {
background: background(layer, "on"),
border: border(layer, "on", { overlay: true }),
padding: 4,
margin: { left: 4 },
cornerRadius: 4,
...text(layer, "sans", "negative", { size: "xs" }),
},
errorIcon: {
margin: { left: 8 },
color: foreground(layer, "negative"),
width: 12,
},
apiKeyEditor: {
background: background(layer, "on"),
cornerRadius: 6,
text: text(layer, "mono", "on"),
placeholderText: text(layer, "mono", "on", "disabled", {
size: "xs",
}),
selection: colorScheme.players[0],
border: border(layer, "on"),
padding: {
bottom: 4,
left: 8,
right: 8,
top: 4,
},
},
apiKeyPrompt: {
padding: 10,
...text(layer, "sans", "default", { size: "xs" }),
},
}
}

View File

@ -2,38 +2,38 @@ import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import { text, background } from "./components"
import { toggleable } from "./toggle"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function commandPalette(colorScheme: ColorScheme) {
let layer = colorScheme.highest
return {
keystrokeSpacing: 8,
key:
toggleable(interactive({
base: {
text: text(layer, "mono", "variant", "default", { size: "xs" }),
cornerRadius: 2,
background: background(layer, "on"),
padding: {
top: 1,
bottom: 1,
left: 6,
right: 6,
},
margin: {
top: 1,
bottom: 1,
left: 2,
},
}, state: { hovered: { cornerRadius: 4, padding: { top: 17 } } }
}), {
default: {
text: text(layer, "mono", "on", "default", { size: "xs" }),
background: withOpacity(background(layer, "on"), 0.2),
}
let layer = colorScheme.highest
return {
keystrokeSpacing: 8,
key:
toggleable(interactive({
base: {
text: text(layer, "mono", "variant", "default", { size: "xs" }),
cornerRadius: 2,
background: background(layer, "on"),
padding: {
top: 1,
bottom: 1,
left: 6,
right: 6,
},
margin: {
top: 1,
bottom: 1,
left: 2,
},
}, state: { hovered: { cornerRadius: 4, padding: { top: 17 } } }
}), {
default: {
text: text(layer, "mono", "on", "default", { size: "xs" }),
background: withOpacity(background(layer, "on"), 0.2),
}
})
,
})
,
}
}
}

View File

@ -1,218 +1,218 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, borderColor, foreground, text } from "./components"
import { toggleable } from "./toggle"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function contactsPanel(colorScheme: ColorScheme) {
const nameMargin = 8
const sidePadding = 12
const nameMargin = 8
const sidePadding = 12
let layer = colorScheme.middle
let layer = colorScheme.middle
const contactButton = {
background: background(layer, "on"),
color: foreground(layer, "on"),
iconWidth: 8,
buttonWidth: 16,
cornerRadius: 8,
}
const projectRow = {
guestAvatarSpacing: 4,
height: 24,
guestAvatar: {
cornerRadius: 8,
width: 14,
},
name: {
...text(layer, "mono", { size: "sm" }),
margin: {
left: nameMargin,
right: 6,
},
},
guests: {
margin: {
left: nameMargin,
right: nameMargin,
},
},
padding: {
left: sidePadding,
right: sidePadding,
},
}
return {
background: background(layer),
padding: { top: 12 },
userQueryEditor: {
background: background(layer, "on"),
cornerRadius: 6,
text: text(layer, "mono", "on"),
placeholderText: text(layer, "mono", "on", "disabled", {
size: "xs",
}),
selection: colorScheme.players[0],
border: border(layer, "on"),
padding: {
bottom: 4,
left: 8,
right: 8,
top: 4,
},
margin: {
left: 6,
},
},
userQueryEditorHeight: 33,
addContactButton: {
margin: { left: 6, right: 12 },
color: foreground(layer, "on"),
buttonWidth: 28,
iconWidth: 16,
},
rowHeight: 28,
sectionIconSize: 8,
headerRow: toggleable(interactive({
base: {
...text(layer, "mono", { size: "sm" }),
margin: { top: 14 },
padding: {
left: sidePadding,
right: sidePadding,
},
background: background(layer, "default"),// posiewic: breaking change
}
, state: { hovered: { background: background(layer, "default") } } // hack, we want headerRow to be interactive for whatever reason. It probably shouldn't be interactive in the first place.
}),
{
default: {
...text(layer, "mono", "active", { size: "sm" }),
background: background(layer, "active"),
},
}),
leaveCall: interactive({
base: {
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" }),
}
,
state: {
hovered: {
...text(layer, "sans", "hovered", { size: "xs" }),
background: background(layer, "hovered"),
border: border(layer, "hovered"),
}
}
const contactButton = {
background: background(layer, "on"),
color: foreground(layer, "on"),
iconWidth: 8,
buttonWidth: 16,
cornerRadius: 8,
}
),
contactRow: {
inactive: {
default: {
padding: {
left: sidePadding,
right: sidePadding,
}
},
},
active: {
default: {
background: background(layer, "active"),
padding: {
left: sidePadding,
right: sidePadding,
}
}
},
},
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: {
left: nameMargin,
},
},
contactButtonSpacing: nameMargin,
contactButton: interactive({
base: { ...contactButton },
state: {
hovered: {
background: background(layer, "hovered"),
},
}
}),
disabledButton: {
...contactButton,
background: background(layer, "on"),
color: foreground(layer, "on"),
},
callingIndicator: {
...text(layer, "mono", "variant", { size: "xs" }),
},
treeBranch: toggleable(interactive({
base: {
color: borderColor(layer),
width: 1,
},
state: {
hovered: {
color: borderColor(layer),
},
}
}),
{
default: {
color: borderColor(layer),
},
}
),
projectRow: toggleable(interactive({
base: {
...projectRow,
background: background(layer),
icon: {
margin: { left: nameMargin },
color: foreground(layer, "variant"),
width: 12,
const projectRow = {
guestAvatarSpacing: 4,
height: 24,
guestAvatar: {
cornerRadius: 8,
width: 14,
},
name: {
...projectRow.name,
...text(layer, "mono", { size: "sm" }),
...text(layer, "mono", { size: "sm" }),
margin: {
left: nameMargin,
right: 6,
},
},
}, state: {
hovered: {
background: background(layer, "hovered"),
guests: {
margin: {
left: nameMargin,
right: nameMargin,
},
},
}
}),
{
default: { background: background(layer, "active") }
})
}
padding: {
left: sidePadding,
right: sidePadding,
},
}
return {
background: background(layer),
padding: { top: 12 },
userQueryEditor: {
background: background(layer, "on"),
cornerRadius: 6,
text: text(layer, "mono", "on"),
placeholderText: text(layer, "mono", "on", "disabled", {
size: "xs",
}),
selection: colorScheme.players[0],
border: border(layer, "on"),
padding: {
bottom: 4,
left: 8,
right: 8,
top: 4,
},
margin: {
left: 6,
},
},
userQueryEditorHeight: 33,
addContactButton: {
margin: { left: 6, right: 12 },
color: foreground(layer, "on"),
buttonWidth: 28,
iconWidth: 16,
},
rowHeight: 28,
sectionIconSize: 8,
headerRow: toggleable(interactive({
base: {
...text(layer, "mono", { size: "sm" }),
margin: { top: 14 },
padding: {
left: sidePadding,
right: sidePadding,
},
background: background(layer, "default"),// posiewic: breaking change
}
, state: { hovered: { background: background(layer, "default") } } // hack, we want headerRow to be interactive for whatever reason. It probably shouldn't be interactive in the first place.
}),
{
default: {
...text(layer, "mono", "active", { size: "sm" }),
background: background(layer, "active"),
},
}),
leaveCall: interactive({
base: {
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" }),
}
,
state: {
hovered: {
...text(layer, "sans", "hovered", { size: "xs" }),
background: background(layer, "hovered"),
border: border(layer, "hovered"),
}
}
}
),
contactRow: {
inactive: {
default: {
padding: {
left: sidePadding,
right: sidePadding,
}
},
},
active: {
default: {
background: background(layer, "active"),
padding: {
left: sidePadding,
right: sidePadding,
}
}
},
},
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: {
left: nameMargin,
},
},
contactButtonSpacing: nameMargin,
contactButton: interactive({
base: { ...contactButton },
state: {
hovered: {
background: background(layer, "hovered"),
},
}
}),
disabledButton: {
...contactButton,
background: background(layer, "on"),
color: foreground(layer, "on"),
},
callingIndicator: {
...text(layer, "mono", "variant", { size: "xs" }),
},
treeBranch: toggleable(interactive({
base: {
color: borderColor(layer),
width: 1,
},
state: {
hovered: {
color: borderColor(layer),
},
}
}),
{
default: {
color: borderColor(layer),
},
}
),
projectRow: toggleable(interactive({
base: {
...projectRow,
background: background(layer),
icon: {
margin: { left: nameMargin },
color: foreground(layer, "variant"),
width: 12,
},
name: {
...projectRow.name,
...text(layer, "mono", { size: "sm" }),
},
}, state: {
hovered: {
background: background(layer, "hovered"),
},
}
}),
{
default: { background: background(layer, "active") }
})
}
}

View File

@ -1,54 +1,54 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, foreground, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
const avatarSize = 12
const headerPadding = 8
export default function contactNotification(colorScheme: ColorScheme): Object {
let layer = colorScheme.lowest
return {
headerAvatar: {
height: avatarSize,
width: avatarSize,
cornerRadius: 6,
},
headerMessage: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
headerHeight: 18,
bodyMessage: {
...text(layer, "sans", { size: "xs" }),
margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 },
},
button:
interactive({
base: {
...text(layer, "sans", "on", { size: "xs" }),
background: background(layer, "on"),
padding: 4,
cornerRadius: 6,
margin: { left: 6 }
let layer = colorScheme.lowest
return {
headerAvatar: {
height: avatarSize,
width: avatarSize,
cornerRadius: 6,
},
state: {
hovered: {
background: background(layer, "on", "hovered"),
}
}
}),
dismissButton: {
default: {
color: foreground(layer, "variant"),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8,
hover: {
color: foreground(layer, "hovered"),
headerMessage: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
}
},
}
headerHeight: 18,
bodyMessage: {
...text(layer, "sans", { size: "xs" }),
margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 },
},
button:
interactive({
base: {
...text(layer, "sans", "on", { size: "xs" }),
background: background(layer, "on"),
padding: 4,
cornerRadius: 6,
margin: { left: 6 }
},
state: {
hovered: {
background: background(layer, "on", "hovered"),
}
}
}),
dismissButton: {
default: {
color: foreground(layer, "variant"),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8,
hover: {
color: foreground(layer, "hovered"),
},
}
},
}
}

View File

@ -1,56 +1,56 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, borderColor, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import { toggleable } from "./toggle"
export default function contextMenu(colorScheme: ColorScheme) {
let layer = colorScheme.middle
return {
background: background(layer),
cornerRadius: 10,
padding: 4,
shadow: colorScheme.popoverShadow,
border: border(layer),
keystrokeMargin: 30,
item: toggleable(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", "hovered", {
size: "sm",
weight: "bold",
}),
padding: { left: 3, right: 3 },
},
}
}
}), {
default: {
background: background(layer, "active"),
},
hovered: {
background: background(layer, "active"),
},
}),
let layer = colorScheme.middle
return {
background: background(layer),
cornerRadius: 10,
padding: 4,
shadow: colorScheme.popoverShadow,
border: border(layer),
keystrokeMargin: 30,
item: toggleable(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", "hovered", {
size: "sm",
weight: "bold",
}),
padding: { left: 3, right: 3 },
},
}
}
}), {
default: {
background: background(layer, "active"),
},
hovered: {
background: background(layer, "active"),
},
}),
separator: {
background: borderColor(layer),
margin: { top: 2, bottom: 2 },
},
}
separator: {
background: borderColor(layer),
margin: { top: 2, bottom: 2 },
},
}
}

View File

@ -1,286 +1,286 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, foreground, svg, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function copilot(colorScheme: ColorScheme) {
let layer = colorScheme.middle
let layer = colorScheme.middle
let content_width = 264
let content_width = 264
let ctaButton =
// Copied from welcome screen. FIXME: Move this into a ZDS component
interactive({
base: {
background: background(layer),
border: border(layer, "default"),
cornerRadius: 4,
margin: {
top: 4,
bottom: 4,
left: 8,
right: 8,
},
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
},
...text(layer, "sans", "default", { size: "sm" })
},
state: {
hovered: {
...text(layer, "sans", "default", { size: "sm" }),
background: background(layer, "hovered"),
border: border(layer, "active"),
},
}
});
return {
outLinkIcon:
interactive({
base: {
icon: svg(
foreground(layer, "variant"),
"icons/link_out_12.svg",
12,
12
),
container: {
cornerRadius: 6,
padding: { left: 6 },
},
},
state: {
hovered: {
icon: {
color:
foreground(layer, "hovered")
}
},
}
}),
modal: {
titleText: {
default: {
...text(layer, "sans", { size: "xs", weight: "bold" })
}
},
titlebar: {
background: background(colorScheme.lowest),
border: border(layer, "active"),
padding: {
top: 4,
bottom: 4,
left: 8,
right: 8,
},
},
container: {
background: background(colorScheme.lowest),
padding: {
top: 0,
left: 0,
right: 0,
bottom: 8,
},
},
closeIcon: interactive({
base:
{
icon: svg(
foreground(layer, "variant"),
"icons/x_mark_8.svg",
8,
8
),
container: {
cornerRadius: 2,
padding: {
top: 4,
bottom: 4,
left: 4,
right: 4,
},
margin: {
right: 0,
},
}
},
state: {
hovered: {
icon: svg(
foreground(layer, "on"),
"icons/x_mark_8.svg",
8,
8
),
},
clicked: {
icon: svg(
foreground(layer, "base"),
"icons/x_mark_8.svg",
8,
8
),
},
}
}),
dimensions: {
width: 280,
height: 280,
},
},
auth: {
content_width,
ctaButton,
header: {
icon: svg(
foreground(layer, "default"),
"icons/zed_plus_copilot_32.svg",
92,
32
),
container: {
margin: {
top: 35,
bottom: 5,
left: 0,
right: 0,
},
},
},
prompting: {
subheading: {
...text(layer, "sans", { size: "xs" }),
margin: {
top: 6,
bottom: 12,
left: 0,
right: 0,
},
},
hint: {
...text(layer, "sans", { size: "xs", color: "#838994" }),
margin: {
top: 6,
bottom: 2,
},
},
deviceCode: {
text: text(layer, "mono", { size: "sm" }),
cta: {
...ctaButton,
background: background(colorScheme.lowest),
border: border(colorScheme.lowest, "inverted"),
padding: {
top: 0,
bottom: 0,
left: 16,
right: 16,
},
margin: {
left: 16,
right: 16,
},
},
left: content_width / 2,
leftContainer: {
padding: {
top: 3,
bottom: 3,
left: 0,
right: 6,
},
},
right: (content_width * 1) / 3,
rightContainer: interactive({
let ctaButton =
// Copied from welcome screen. FIXME: Move this into a ZDS component
interactive({
base: {
border: border(colorScheme.lowest, "inverted", {
bottom: false,
right: false,
top: false,
left: true,
}),
padding: {
top: 3,
bottom: 5,
left: 8,
right: 0,
}
}, state: {
hovered: {
border: border(layer, "active", {
bottom: false,
right: false,
top: false,
left: true,
}),
},
background: background(layer),
border: border(layer, "default"),
cornerRadius: 4,
margin: {
top: 4,
bottom: 4,
left: 8,
right: 8,
},
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
},
...text(layer, "sans", "default", { size: "sm" })
},
state: {
hovered: {
...text(layer, "sans", "default", { size: "sm" }),
background: background(layer, "hovered"),
border: border(layer, "active"),
},
}
})
},
},
});
notAuthorized: {
subheading: {
...text(layer, "sans", { size: "xs" }),
return {
outLinkIcon:
interactive({
base: {
icon: svg(
foreground(layer, "variant"),
"icons/link_out_12.svg",
12,
12
),
container: {
cornerRadius: 6,
padding: { left: 6 },
},
},
state: {
hovered: {
icon: {
color:
foreground(layer, "hovered")
}
},
}
}),
margin: {
top: 16,
bottom: 16,
left: 0,
right: 0,
},
modal: {
titleText: {
default: {
...text(layer, "sans", { size: "xs", weight: "bold" })
}
},
titlebar: {
background: background(colorScheme.lowest),
border: border(layer, "active"),
padding: {
top: 4,
bottom: 4,
left: 8,
right: 8,
},
},
container: {
background: background(colorScheme.lowest),
padding: {
top: 0,
left: 0,
right: 0,
bottom: 8,
},
},
closeIcon: interactive({
base:
{
icon: svg(
foreground(layer, "variant"),
"icons/x_mark_8.svg",
8,
8
),
container: {
cornerRadius: 2,
padding: {
top: 4,
bottom: 4,
left: 4,
right: 4,
},
margin: {
right: 0,
},
}
},
state: {
hovered: {
icon: svg(
foreground(layer, "on"),
"icons/x_mark_8.svg",
8,
8
),
},
clicked: {
icon: svg(
foreground(layer, "base"),
"icons/x_mark_8.svg",
8,
8
),
},
}
}),
dimensions: {
width: 280,
height: 280,
},
},
warning: {
...text(layer, "sans", {
size: "xs",
color: foreground(layer, "warning"),
}),
border: border(layer, "warning"),
background: background(layer, "warning"),
cornerRadius: 2,
padding: {
top: 4,
left: 4,
bottom: 4,
right: 4,
},
margin: {
bottom: 16,
left: 8,
right: 8,
},
},
},
auth: {
content_width,
authorized: {
subheading: {
...text(layer, "sans", { size: "xs" }),
ctaButton,
margin: {
top: 16,
bottom: 16,
},
},
header: {
icon: svg(
foreground(layer, "default"),
"icons/zed_plus_copilot_32.svg",
92,
32
),
container: {
margin: {
top: 35,
bottom: 5,
left: 0,
right: 0,
},
},
},
hint: {
...text(layer, "sans", { size: "xs", color: "#838994" }),
margin: {
top: 24,
bottom: 4,
},
prompting: {
subheading: {
...text(layer, "sans", { size: "xs" }),
margin: {
top: 6,
bottom: 12,
left: 0,
right: 0,
},
},
hint: {
...text(layer, "sans", { size: "xs", color: "#838994" }),
margin: {
top: 6,
bottom: 2,
},
},
deviceCode: {
text: text(layer, "mono", { size: "sm" }),
cta: {
...ctaButton,
background: background(colorScheme.lowest),
border: border(colorScheme.lowest, "inverted"),
padding: {
top: 0,
bottom: 0,
left: 16,
right: 16,
},
margin: {
left: 16,
right: 16,
},
},
left: content_width / 2,
leftContainer: {
padding: {
top: 3,
bottom: 3,
left: 0,
right: 6,
},
},
right: (content_width * 1) / 3,
rightContainer: interactive({
base: {
border: border(colorScheme.lowest, "inverted", {
bottom: false,
right: false,
top: false,
left: true,
}),
padding: {
top: 3,
bottom: 5,
left: 8,
right: 0,
}
}, state: {
hovered: {
border: border(layer, "active", {
bottom: false,
right: false,
top: false,
left: true,
}),
},
}
})
},
},
notAuthorized: {
subheading: {
...text(layer, "sans", { size: "xs" }),
margin: {
top: 16,
bottom: 16,
left: 0,
right: 0,
},
},
warning: {
...text(layer, "sans", {
size: "xs",
color: foreground(layer, "warning"),
}),
border: border(layer, "warning"),
background: background(layer, "warning"),
cornerRadius: 2,
padding: {
top: 4,
left: 4,
bottom: 4,
right: 4,
},
margin: {
bottom: 16,
left: 8,
right: 8,
},
},
},
authorized: {
subheading: {
...text(layer, "sans", { size: "xs" }),
margin: {
top: 16,
bottom: 16,
},
},
hint: {
...text(layer, "sans", { size: "xs", color: "#838994" }),
margin: {
top: 24,
bottom: 4,
},
},
},
},
},
},
}
}
}

View File

@ -4,290 +4,290 @@ import { background, border, borderColor, foreground, text } from "./components"
import hoverPopover from "./hoverPopover"
import { buildSyntax } from "../theme/syntax"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import { toggleable } from "./toggle"
export default function editor(colorScheme: ColorScheme) {
const { isLight } = colorScheme
const { isLight } = colorScheme
let layer = colorScheme.highest
let layer = colorScheme.highest
const autocompleteItem = {
cornerRadius: 6,
padding: {
bottom: 2,
left: 6,
right: 6,
top: 2,
},
}
function diagnostic(layer: Layer, styleSet: StyleSets) {
return {
textScaleFactor: 0.857,
header: {
border: border(layer, {
top: true,
}),
},
message: {
text: text(layer, "sans", styleSet, "default", { size: "sm" }),
highlightText: text(layer, "sans", styleSet, "default", {
size: "sm",
weight: "bold",
}),
},
}
}
const syntax = buildSyntax(colorScheme)
return {
textColor: syntax.primary.color,
background: background(layer),
activeLineBackground: withOpacity(background(layer, "on"), 0.75),
highlightedLineBackground: background(layer, "on"),
// Inline autocomplete suggestions, Co-pilot suggestions, etc.
suggestion: syntax.predictive,
codeActions: {
indicator: toggleable(interactive({
base: {
color: foreground(layer, "variant"),
}, state: {
clicked: {
color: foreground(layer, "base"),
},
hovered: {
color: foreground(layer, "on"),
},
}
}),
{
default: {
color: foreground(layer, "on"),
}
}),
verticalScale: 0.55,
},
folds: {
iconMarginScale: 2.5,
foldedIcon: "icons/chevron_right_8.svg",
foldableIcon: "icons/chevron_down_8.svg",
indicator: toggleable(interactive({
base: {
color: foreground(layer, "variant"),
}, state: {
clicked: {
color: foreground(layer, "base"),
},
hovered: {
color: foreground(layer, "on"),
},
}
}),
{
default: {
color: foreground(layer, "on"),
}
}),
ellipses: {
textColor: colorScheme.ramps.neutral(0.71).hex(),
cornerRadiusFactor: 0.15,
background: {
// Copied from hover_popover highlight
default: { color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex() },
hover: {
color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(),
},
clicked: {
color: colorScheme.ramps.neutral(0.5).alpha(0.7).hex(),
},
},
},
foldBackground: foreground(layer, "variant"),
},
diff: {
deleted: isLight
? colorScheme.ramps.red(0.5).hex()
: colorScheme.ramps.red(0.4).hex(),
modified: isLight
? colorScheme.ramps.yellow(0.5).hex()
: colorScheme.ramps.yellow(0.5).hex(),
inserted: isLight
? colorScheme.ramps.green(0.4).hex()
: colorScheme.ramps.green(0.5).hex(),
removedWidthEm: 0.275,
widthEm: 0.15,
cornerRadius: 0.05,
},
/** Highlights matching occurrences of what is under the cursor
* as well as matched brackets
*/
documentHighlightReadBackground: withOpacity(
foreground(layer, "accent"),
0.1
),
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,
lineNumber: withOpacity(foreground(layer), 0.35),
lineNumberActive: foreground(layer),
renameFade: 0.6,
unnecessaryCodeFade: 0.5,
selection: colorScheme.players[0],
whitespace: colorScheme.ramps.neutral(0.5).hex(),
guestSelections: [
colorScheme.players[1],
colorScheme.players[2],
colorScheme.players[3],
colorScheme.players[4],
colorScheme.players[5],
colorScheme.players[6],
colorScheme.players[7],
],
autocomplete: {
background: background(colorScheme.middle),
cornerRadius: 8,
padding: 4,
margin: {
left: -14,
},
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,
matchHighlight: foreground(
colorScheme.middle,
"accent",
"active"
),
background: background(colorScheme.middle, "active"),
},
},
diagnosticHeader: {
background: background(colorScheme.middle),
iconWidthFactor: 1.5,
textScaleFactor: 0.857,
border: border(colorScheme.middle, {
bottom: true,
top: true,
}),
code: {
...text(colorScheme.middle, "mono", { size: "sm" }),
margin: {
left: 10,
},
},
source: {
text: text(colorScheme.middle, "sans", {
size: "sm",
weight: "bold",
}),
},
message: {
highlightText: text(colorScheme.middle, "sans", {
size: "sm",
weight: "bold",
}),
text: text(colorScheme.middle, "sans", { size: "sm" }),
},
},
diagnosticPathHeader: {
background: background(colorScheme.middle),
textScaleFactor: 0.857,
filename: text(colorScheme.middle, "mono", { size: "sm" }),
path: {
...text(colorScheme.middle, "mono", { size: "sm" }),
margin: {
left: 12,
},
},
},
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: syntax.linkUri.color,
underline: syntax.linkUri.underline,
},
jumpIcon: interactive({
base: {
color: foreground(layer, "on"),
iconWidth: 20,
buttonWidth: 20,
const autocompleteItem = {
cornerRadius: 6,
padding: {
top: 6,
bottom: 6,
left: 6,
right: 6,
}
}, state: {
hovered: {
background: background(layer, "on", "hovered"),
}
}
}),
scrollbar: {
width: 12,
minHeightFactor: 1.0,
track: {
border: border(layer, "variant", { left: true }),
},
thumb: {
background: withOpacity(background(layer, "inverted"), 0.3),
border: {
width: 1,
color: borderColor(layer, "variant"),
top: false,
right: true,
left: true,
bottom: false,
bottom: 2,
left: 6,
right: 6,
top: 2,
},
},
git: {
deleted: isLight
? withOpacity(colorScheme.ramps.red(0.5).hex(), 0.8)
: withOpacity(colorScheme.ramps.red(0.4).hex(), 0.8),
modified: isLight
? withOpacity(colorScheme.ramps.yellow(0.5).hex(), 0.8)
: withOpacity(colorScheme.ramps.yellow(0.4).hex(), 0.8),
inserted: isLight
? withOpacity(colorScheme.ramps.green(0.5).hex(), 0.8)
: withOpacity(colorScheme.ramps.green(0.4).hex(), 0.8),
},
},
compositionMark: {
underline: {
thickness: 1.0,
color: borderColor(layer),
},
},
syntax,
}
}
function diagnostic(layer: Layer, styleSet: StyleSets) {
return {
textScaleFactor: 0.857,
header: {
border: border(layer, {
top: true,
}),
},
message: {
text: text(layer, "sans", styleSet, "default", { size: "sm" }),
highlightText: text(layer, "sans", styleSet, "default", {
size: "sm",
weight: "bold",
}),
},
}
}
const syntax = buildSyntax(colorScheme)
return {
textColor: syntax.primary.color,
background: background(layer),
activeLineBackground: withOpacity(background(layer, "on"), 0.75),
highlightedLineBackground: background(layer, "on"),
// Inline autocomplete suggestions, Co-pilot suggestions, etc.
suggestion: syntax.predictive,
codeActions: {
indicator: toggleable(interactive({
base: {
color: foreground(layer, "variant"),
}, state: {
clicked: {
color: foreground(layer, "base"),
},
hovered: {
color: foreground(layer, "on"),
},
}
}),
{
default: {
color: foreground(layer, "on"),
}
}),
verticalScale: 0.55,
},
folds: {
iconMarginScale: 2.5,
foldedIcon: "icons/chevron_right_8.svg",
foldableIcon: "icons/chevron_down_8.svg",
indicator: toggleable(interactive({
base: {
color: foreground(layer, "variant"),
}, state: {
clicked: {
color: foreground(layer, "base"),
},
hovered: {
color: foreground(layer, "on"),
},
}
}),
{
default: {
color: foreground(layer, "on"),
}
}),
ellipses: {
textColor: colorScheme.ramps.neutral(0.71).hex(),
cornerRadiusFactor: 0.15,
background: {
// Copied from hover_popover highlight
default: { color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex() },
hover: {
color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(),
},
clicked: {
color: colorScheme.ramps.neutral(0.5).alpha(0.7).hex(),
},
},
},
foldBackground: foreground(layer, "variant"),
},
diff: {
deleted: isLight
? colorScheme.ramps.red(0.5).hex()
: colorScheme.ramps.red(0.4).hex(),
modified: isLight
? colorScheme.ramps.yellow(0.5).hex()
: colorScheme.ramps.yellow(0.5).hex(),
inserted: isLight
? colorScheme.ramps.green(0.4).hex()
: colorScheme.ramps.green(0.5).hex(),
removedWidthEm: 0.275,
widthEm: 0.15,
cornerRadius: 0.05,
},
/** Highlights matching occurrences of what is under the cursor
* as well as matched brackets
*/
documentHighlightReadBackground: withOpacity(
foreground(layer, "accent"),
0.1
),
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,
lineNumber: withOpacity(foreground(layer), 0.35),
lineNumberActive: foreground(layer),
renameFade: 0.6,
unnecessaryCodeFade: 0.5,
selection: colorScheme.players[0],
whitespace: colorScheme.ramps.neutral(0.5).hex(),
guestSelections: [
colorScheme.players[1],
colorScheme.players[2],
colorScheme.players[3],
colorScheme.players[4],
colorScheme.players[5],
colorScheme.players[6],
colorScheme.players[7],
],
autocomplete: {
background: background(colorScheme.middle),
cornerRadius: 8,
padding: 4,
margin: {
left: -14,
},
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,
matchHighlight: foreground(
colorScheme.middle,
"accent",
"active"
),
background: background(colorScheme.middle, "active"),
},
},
diagnosticHeader: {
background: background(colorScheme.middle),
iconWidthFactor: 1.5,
textScaleFactor: 0.857,
border: border(colorScheme.middle, {
bottom: true,
top: true,
}),
code: {
...text(colorScheme.middle, "mono", { size: "sm" }),
margin: {
left: 10,
},
},
source: {
text: text(colorScheme.middle, "sans", {
size: "sm",
weight: "bold",
}),
},
message: {
highlightText: text(colorScheme.middle, "sans", {
size: "sm",
weight: "bold",
}),
text: text(colorScheme.middle, "sans", { size: "sm" }),
},
},
diagnosticPathHeader: {
background: background(colorScheme.middle),
textScaleFactor: 0.857,
filename: text(colorScheme.middle, "mono", { size: "sm" }),
path: {
...text(colorScheme.middle, "mono", { size: "sm" }),
margin: {
left: 12,
},
},
},
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: syntax.linkUri.color,
underline: syntax.linkUri.underline,
},
jumpIcon: interactive({
base: {
color: foreground(layer, "on"),
iconWidth: 20,
buttonWidth: 20,
cornerRadius: 6,
padding: {
top: 6,
bottom: 6,
left: 6,
right: 6,
}
}, state: {
hovered: {
background: background(layer, "on", "hovered"),
}
}
}),
scrollbar: {
width: 12,
minHeightFactor: 1.0,
track: {
border: border(layer, "variant", { left: true }),
},
thumb: {
background: withOpacity(background(layer, "inverted"), 0.3),
border: {
width: 1,
color: borderColor(layer, "variant"),
top: false,
right: true,
left: true,
bottom: false,
},
},
git: {
deleted: isLight
? withOpacity(colorScheme.ramps.red(0.5).hex(), 0.8)
: withOpacity(colorScheme.ramps.red(0.4).hex(), 0.8),
modified: isLight
? withOpacity(colorScheme.ramps.yellow(0.5).hex(), 0.8)
: withOpacity(colorScheme.ramps.yellow(0.4).hex(), 0.8),
inserted: isLight
? withOpacity(colorScheme.ramps.green(0.5).hex(), 0.8)
: withOpacity(colorScheme.ramps.green(0.4).hex(), 0.8),
},
},
compositionMark: {
underline: {
thickness: 1.0,
color: borderColor(layer),
},
},
syntax,
}
}

View File

@ -1,48 +1,48 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function feedback(colorScheme: ColorScheme) {
let layer = colorScheme.highest
let layer = colorScheme.highest
return {
submit_button: 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,
}
}, state: {
clicked: {
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
}
}),
button_margin: 8,
info_text_default: text(layer, "sans", "default", { size: "xs" }),
link_text_default: text(layer, "sans", "default", {
size: "xs",
underline: true,
}),
link_text_hover: text(layer, "sans", "hovered", {
size: "xs",
underline: true,
}),
}
return {
submit_button: 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,
}
}, state: {
clicked: {
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
}
}),
button_margin: 8,
info_text_default: text(layer, "sans", "default", { size: "xs" }),
link_text_default: text(layer, "sans", "default", {
size: "xs",
underline: true,
}),
link_text_hover: text(layer, "sans", "hovered", {
size: "xs",
underline: true,
}),
}
}

View File

@ -2,88 +2,88 @@ import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import { background, border, text } from "./components"
import { toggleable } from "./toggle"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function picker(colorScheme: ColorScheme): any {
let layer = colorScheme.lowest
const container = {
background: background(layer),
border: border(layer),
shadow: colorScheme.modalShadow,
cornerRadius: 12,
padding: {
bottom: 4,
},
}
const inputEditor = {
placeholderText: text(layer, "sans", "on", "disabled"),
selection: colorScheme.players[0],
text: text(layer, "mono", "on"),
border: border(layer, { bottom: true }),
padding: {
bottom: 8,
left: 16,
right: 16,
top: 8,
},
margin: {
bottom: 4,
},
}
const emptyInputEditor: any = { ...inputEditor }
delete emptyInputEditor.border
delete emptyInputEditor.margin
return {
...container,
emptyContainer: {
...container,
padding: {},
},
item: toggleable(interactive({
base: {
let layer = colorScheme.lowest
const container = {
background: background(layer),
border: border(layer),
shadow: colorScheme.modalShadow,
cornerRadius: 12,
padding: {
bottom: 4,
left: 12,
right: 12,
top: 4,
bottom: 4,
},
}
const inputEditor = {
placeholderText: text(layer, "sans", "on", "disabled"),
selection: colorScheme.players[0],
text: text(layer, "mono", "on"),
border: border(layer, { bottom: true }),
padding: {
bottom: 8,
left: 16,
right: 16,
top: 8,
},
margin: {
top: 1,
left: 4,
right: 4,
bottom: 4,
},
cornerRadius: 8,
text: text(layer, "sans", "variant"),
highlightText: text(layer, "sans", "accent", { weight: "bold" }),
}
, state: {
hovered: {
background: withOpacity(background(layer, "hovered"), 0.5),
}
}
}),
{
default: {
background: withOpacity(
background(layer, "base", "active"),
0.5
),
//text: text(layer, "sans", "base", "active"),
}
}),
}
const emptyInputEditor: any = { ...inputEditor }
delete emptyInputEditor.border
delete emptyInputEditor.margin
return {
...container,
emptyContainer: {
...container,
padding: {},
},
item: toggleable(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" }),
}
, state: {
hovered: {
background: withOpacity(background(layer, "hovered"), 0.5),
}
}
}),
{
default: {
background: withOpacity(
background(layer, "base", "active"),
0.5
),
//text: text(layer, "sans", "base", "active"),
}
}),
inputEditor,
emptyInputEditor,
noMatches: {
text: text(layer, "sans", "variant"),
padding: {
bottom: 8,
left: 16,
right: 16,
top: 8,
},
},
}
inputEditor,
emptyInputEditor,
noMatches: {
text: text(layer, "sans", "variant"),
padding: {
bottom: 8,
left: 16,
right: 16,
top: 8,
},
},
}
}

View File

@ -1,123 +1,123 @@
import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import { background, border, foreground, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import { toggleable } from "./toggle"
export default function projectPanel(colorScheme: ColorScheme) {
const { isLight } = colorScheme
const { isLight } = colorScheme
let layer = colorScheme.middle
let layer = colorScheme.middle
let baseEntry = {
height: 22,
iconColor: foreground(layer, "variant"),
iconSize: 7,
iconSpacing: 5,
}
let status = {
git: {
modified: isLight
? colorScheme.ramps.yellow(0.6).hex()
: colorScheme.ramps.yellow(0.5).hex(),
inserted: isLight
? colorScheme.ramps.green(0.45).hex()
: colorScheme.ramps.green(0.5).hex(),
conflict: isLight
? colorScheme.ramps.red(0.6).hex()
: colorScheme.ramps.red(0.5).hex(),
},
}
let entry = toggleable(interactive({
base: {
...baseEntry,
text: text(layer, "mono", "variant", { size: "sm" }),
status,
}, state:
{
hovered: {
background: background(layer, "variant", "hovered"),
}
}
}),
{
default: {
/*background: colorScheme.isLight
? withOpacity(background(layer, "active"), 0.5)
: background(layer, "active") ,*/ // todo posiewic
text: text(layer, "mono", "active", { size: "sm" }),
},
hovered: {
//background: background(layer, "active"),
text: text(layer, "mono", "active", { size: "sm" }),
},
});
return {
openProjectButton: interactive({
base: {
background: background(layer),
border: border(layer, "active"),
cornerRadius: 4,
margin: {
top: 16,
left: 16,
right: 16,
},
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
},
...text(layer, "sans", "default", { size: "sm" })
}, state: {
hovered: {
...text(layer, "sans", "default", { size: "sm" }),
background: background(layer, "hovered"),
border: border(layer, "active"),
},
}
}),
background: background(layer),
padding: { left: 6, right: 6, top: 0, bottom: 6 },
indentWidth: 12,
entry,
draggedEntry: {
...baseEntry,
text: text(layer, "mono", "on", { size: "sm" }),
background: withOpacity(background(layer, "on"), 0.9),
border: border(layer),
status,
},
ignoredEntry: {
...entry,
iconColor: foreground(layer, "disabled"),
text: text(layer, "mono", "disabled"),
active: {
...entry.active,
let baseEntry = {
height: 22,
iconColor: foreground(layer, "variant"),
},
},
cutEntry: {
...entry,
text: text(layer, "mono", "disabled"),
active: {
...entry.active,
default: {
...entry.active.default,
background: background(layer, "active"),
text: text(layer, "mono", "disabled", { size: "sm" }),
},
iconSize: 7,
iconSpacing: 5,
}
},
},
filenameEditor: {
background: background(layer, "on"),
text: text(layer, "mono", "on", { size: "sm" }),
selection: colorScheme.players[0],
},
}
let status = {
git: {
modified: isLight
? colorScheme.ramps.yellow(0.6).hex()
: colorScheme.ramps.yellow(0.5).hex(),
inserted: isLight
? colorScheme.ramps.green(0.45).hex()
: colorScheme.ramps.green(0.5).hex(),
conflict: isLight
? colorScheme.ramps.red(0.6).hex()
: colorScheme.ramps.red(0.5).hex(),
},
}
let entry = toggleable(interactive({
base: {
...baseEntry,
text: text(layer, "mono", "variant", { size: "sm" }),
status,
}, state:
{
hovered: {
background: background(layer, "variant", "hovered"),
}
}
}),
{
default: {
/*background: colorScheme.isLight
? withOpacity(background(layer, "active"), 0.5)
: background(layer, "active") ,*/ // todo posiewic
text: text(layer, "mono", "active", { size: "sm" }),
},
hovered: {
//background: background(layer, "active"),
text: text(layer, "mono", "active", { size: "sm" }),
},
});
return {
openProjectButton: interactive({
base: {
background: background(layer),
border: border(layer, "active"),
cornerRadius: 4,
margin: {
top: 16,
left: 16,
right: 16,
},
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
},
...text(layer, "sans", "default", { size: "sm" })
}, state: {
hovered: {
...text(layer, "sans", "default", { size: "sm" }),
background: background(layer, "hovered"),
border: border(layer, "active"),
},
}
}),
background: background(layer),
padding: { left: 6, right: 6, top: 0, bottom: 6 },
indentWidth: 12,
entry,
draggedEntry: {
...baseEntry,
text: text(layer, "mono", "on", { size: "sm" }),
background: withOpacity(background(layer, "on"), 0.9),
border: border(layer),
status,
},
ignoredEntry: {
...entry,
iconColor: foreground(layer, "disabled"),
text: text(layer, "mono", "disabled"),
active: {
...entry.active,
iconColor: foreground(layer, "variant"),
},
},
cutEntry: {
...entry,
text: text(layer, "mono", "disabled"),
active: {
...entry.active,
default: {
...entry.active.default,
background: background(layer, "active"),
text: text(layer, "mono", "disabled", { size: "sm" }),
},
},
},
filenameEditor: {
background: background(layer, "on"),
text: text(layer, "mono", "on", { size: "sm" }),
selection: colorScheme.players[0],
},
}
}

View File

@ -1,123 +1,123 @@
import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import { background, border, foreground, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import { toggleable } from "./toggle"
export default function search(colorScheme: ColorScheme) {
let layer = colorScheme.highest
let layer = colorScheme.highest
// Search input
const editor = {
background: background(layer),
cornerRadius: 8,
minWidth: 200,
maxWidth: 500,
placeholderText: text(layer, "mono", "disabled"),
selection: colorScheme.players[0],
text: text(layer, "mono", "default"),
border: border(layer),
margin: {
right: 12,
},
padding: {
top: 3,
bottom: 3,
left: 12,
right: 8,
},
}
const includeExcludeEditor = {
...editor,
minWidth: 100,
maxWidth: 250,
}
return {
// TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
optionButton: toggleable(interactive({
base: {
...text(layer, "mono", "on"),
background: background(layer, "on"),
cornerRadius: 6,
border: border(layer, "on"),
// Search input
const editor = {
background: background(layer),
cornerRadius: 8,
minWidth: 200,
maxWidth: 500,
placeholderText: text(layer, "mono", "disabled"),
selection: colorScheme.players[0],
text: text(layer, "mono", "default"),
border: border(layer),
margin: {
right: 4,
right: 12,
},
padding: {
bottom: 2,
left: 10,
right: 10,
top: 2,
top: 3,
bottom: 3,
left: 12,
right: 8,
},
}, state: {
clicked: {
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
}
}), {
default: {
...text(layer, "mono", "on", "inverted"),
background: background(layer, "on", "inverted"),
border: border(layer, "on", "inverted"),
},
}
}),
editor,
invalidEditor: {
...editor,
border: border(layer, "negative"),
},
includeExcludeEditor,
invalidIncludeExcludeEditor: {
...includeExcludeEditor,
border: border(layer, "negative"),
},
matchIndex: {
...text(layer, "mono", "variant"),
padding: {
left: 6,
},
},
optionButtonGroup: {
padding: {
left: 12,
right: 12,
},
},
includeExcludeInputs: {
...text(layer, "mono", "variant"),
padding: {
right: 6,
},
},
resultsStatus: {
...text(layer, "mono", "on"),
size: 18,
},
dismissButton: interactive({
base: {
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: 14,
padding: {
left: 10,
right: 10,
const includeExcludeEditor = {
...editor,
minWidth: 100,
maxWidth: 250,
}
return {
// TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
optionButton: toggleable(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,
},
}, state: {
clicked: {
...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"),
border: border(layer, "on", "pressed"),
},
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
}
}), {
default: {
...text(layer, "mono", "on", "inverted"),
background: background(layer, "on", "inverted"),
border: border(layer, "on", "inverted"),
},
}),
editor,
invalidEditor: {
...editor,
border: border(layer, "negative"),
},
}, state: {
hovered: {
color: foreground(layer, "hovered"),
}
}
}),
}
includeExcludeEditor,
invalidIncludeExcludeEditor: {
...includeExcludeEditor,
border: border(layer, "negative"),
},
matchIndex: {
...text(layer, "mono", "variant"),
padding: {
left: 6,
},
},
optionButtonGroup: {
padding: {
left: 12,
right: 12,
},
},
includeExcludeInputs: {
...text(layer, "mono", "variant"),
padding: {
right: 6,
},
},
resultsStatus: {
...text(layer, "mono", "on"),
size: 18,
},
dismissButton: interactive({
base: {
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: 14,
padding: {
left: 10,
right: 10,
},
}, state: {
hovered: {
color: foreground(layer, "hovered"),
}
}
}),
}
}

View File

@ -1,51 +1,51 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, foreground, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
const headerPadding = 8
export default function simpleMessageNotification(
colorScheme: ColorScheme
colorScheme: ColorScheme
): Object {
let layer = colorScheme.middle
return {
message: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
actionMessage: interactive({
base: {
...text(layer, "sans", { size: "xs" }),
border: border(layer, "active"),
cornerRadius: 4,
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
let layer = colorScheme.middle
return {
message: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
actionMessage: interactive({
base: {
...text(layer, "sans", { size: "xs" }),
border: border(layer, "active"),
cornerRadius: 4,
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
},
margin: { left: headerPadding, top: 6, bottom: 6 },
}, state: {
hovered: {
...text(layer, "sans", "default", { size: "xs" }),
background: background(layer, "hovered"),
border: border(layer, "active"),
},
}
}),
dismissButton: interactive({
base: {
color: foreground(layer),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8,
}, state: {
hovered: {
color: foreground(layer, "hovered"),
},
}
})
}
margin: { left: headerPadding, top: 6, bottom: 6 },
}, state: {
hovered: {
...text(layer, "sans", "default", { size: "xs" }),
background: background(layer, "hovered"),
border: border(layer, "active"),
},
}
}),
dismissButton: interactive({
base: {
color: foreground(layer),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8,
}, state: {
hovered: {
color: foreground(layer, "hovered"),
},
}
})
}
}

View File

@ -1,145 +1,145 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, foreground, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import { toggleable } from "./toggle"
export default function statusBar(colorScheme: ColorScheme) {
let layer = colorScheme.lowest
let layer = colorScheme.lowest
const statusContainer = {
cornerRadius: 6,
padding: { top: 3, bottom: 3, left: 6, right: 6 },
}
const statusContainer = {
cornerRadius: 6,
padding: { top: 3, bottom: 3, left: 6, right: 6 },
}
const diagnosticStatusContainer = {
cornerRadius: 6,
padding: { top: 1, bottom: 1, left: 6, right: 6 },
}
const diagnosticStatusContainer = {
cornerRadius: 6,
padding: { top: 1, bottom: 1, left: 6, right: 6 },
}
return {
height: 30,
itemSpacing: 8,
padding: {
top: 1,
bottom: 1,
left: 6,
right: 6,
},
border: border(layer, { top: true, overlay: true }),
cursorPosition: text(layer, "sans", "variant"),
activeLanguage: interactive({
base: {
padding: { left: 6, right: 6 },
...text(layer, "sans", "variant")
},
state: {
hovered: {
...text(layer, "sans", "on"),
}
}
},
),
autoUpdateProgressMessage: text(layer, "sans", "variant"),
autoUpdateDoneMessage: text(layer, "sans", "variant"),
lspStatus: interactive({
base: {
...diagnosticStatusContainer,
iconSpacing: 4,
iconWidth: 14,
height: 18,
message: text(layer, "sans"),
iconColor: foreground(layer)
},
state: {
hovered: {
message: text(layer, "sans"),
iconColor: foreground(layer),
background: background(layer, "hovered"),
}
}
}),
diagnosticMessage: interactive({
base: {
...text(layer, "sans")
},
state: { hovered: text(layer, "sans", "hovered") }
},
),
diagnosticSummary:
interactive({
base: {
height: 20,
iconWidth: 16,
iconSpacing: 2,
summarySpacing: 6,
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: background(layer, "warning"),
border: border(layer, "warning"),
},
containerError: {
...diagnosticStatusContainer,
background: background(layer, "negative"),
border: border(layer, "negative"),
}
}, state: {
hovered: {
iconColorOk: foreground(layer, "on"),
containerOk: {
background: background(layer, "on", "hovered"),
return {
height: 30,
itemSpacing: 8,
padding: {
top: 1,
bottom: 1,
left: 6,
right: 6,
},
border: border(layer, { top: true, overlay: true }),
cursorPosition: text(layer, "sans", "variant"),
activeLanguage: interactive({
base: {
padding: { left: 6, right: 6 },
...text(layer, "sans", "variant")
},
containerWarning: {
background: background(layer, "warning", "hovered"),
border: border(layer, "warning", "hovered"),
},
containerError: {
background: background(layer, "negative", "hovered"),
border: border(layer, "negative", "hovered"),
state: {
hovered: {
...text(layer, "sans", "on"),
}
}
},
),
autoUpdateProgressMessage: text(layer, "sans", "variant"),
autoUpdateDoneMessage: text(layer, "sans", "variant"),
lspStatus: interactive({
base: {
...diagnosticStatusContainer,
iconSpacing: 4,
iconWidth: 14,
height: 18,
message: text(layer, "sans"),
iconColor: foreground(layer)
},
state: {
hovered: {
message: text(layer, "sans"),
iconColor: foreground(layer),
background: background(layer, "hovered"),
}
}
}
}
}
),
panelButtons: {
groupLeft: {},
groupBottom: {},
groupRight: {},
button: toggleable(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"),
}
}
}),
{
default: {
iconColor: foreground(layer, "active"),
background: background(layer, "active"),
}
}),
badge: {
cornerRadius: 3,
padding: 2,
margin: { bottom: -1, right: -1 },
border: border(layer),
background: background(layer, "accent"),
},
},
}
diagnosticMessage: interactive({
base: {
...text(layer, "sans")
},
state: { hovered: text(layer, "sans", "hovered") }
},
),
diagnosticSummary:
interactive({
base: {
height: 20,
iconWidth: 16,
iconSpacing: 2,
summarySpacing: 6,
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: background(layer, "warning"),
border: border(layer, "warning"),
},
containerError: {
...diagnosticStatusContainer,
background: background(layer, "negative"),
border: border(layer, "negative"),
}
}, state: {
hovered: {
iconColorOk: foreground(layer, "on"),
containerOk: {
background: background(layer, "on", "hovered"),
},
containerWarning: {
background: background(layer, "warning", "hovered"),
border: border(layer, "warning", "hovered"),
},
containerError: {
background: background(layer, "negative", "hovered"),
border: border(layer, "negative", "hovered"),
}
}
}
}
),
panelButtons: {
groupLeft: {},
groupBottom: {},
groupRight: {},
button: toggleable(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"),
}
}
}),
{
default: {
iconColor: foreground(layer, "active"),
background: background(layer, "active"),
}
}),
badge: {
cornerRadius: 3,
padding: 2,
margin: { bottom: -1, right: -1 },
border: border(layer),
background: background(layer, "accent"),
},
},
}
}

View File

@ -2,117 +2,117 @@ import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import { text, border, background, foreground } from "./components"
import { toggleable } from "./toggle"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function tabBar(colorScheme: ColorScheme) {
const height = 32
const height = 32
let activeLayer = colorScheme.highest
let layer = colorScheme.middle
let activeLayer = colorScheme.highest
let layer = colorScheme.middle
const tab = {
height,
text: text(layer, "sans", "variant", { size: "sm" }),
background: background(layer),
border: border(layer, {
right: true,
bottom: true,
overlay: true,
}),
padding: {
left: 8,
right: 12,
},
spacing: 8,
const tab = {
height,
text: text(layer, "sans", "variant", { size: "sm" }),
background: background(layer),
border: border(layer, {
right: true,
bottom: true,
overlay: true,
}),
padding: {
left: 8,
right: 12,
},
spacing: 8,
// Tab type icons (e.g. Project Search)
typeIconWidth: 14,
// Tab type icons (e.g. Project Search)
typeIconWidth: 14,
// Close icons
closeIconWidth: 8,
iconClose: foreground(layer, "variant"),
iconCloseActive: foreground(layer, "hovered"),
// Close icons
closeIconWidth: 8,
iconClose: foreground(layer, "variant"),
iconCloseActive: foreground(layer, "hovered"),
// Indicators
iconConflict: foreground(layer, "warning"),
iconDirty: foreground(layer, "accent"),
// 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: 8 },
...text(layer, "sans", "disabled", { size: "2xs" }),
},
}
// When two tabs of the same name are open, a label appears next to them
description: {
margin: { left: 8 },
...text(layer, "sans", "disabled", { size: "2xs" }),
},
}
const activePaneActiveTab = {
...tab,
background: background(activeLayer),
text: text(activeLayer, "sans", "active", { size: "sm" }),
border: {
...tab.border,
bottom: false,
},
}
const activePaneActiveTab = {
...tab,
background: background(activeLayer),
text: text(activeLayer, "sans", "active", { size: "sm" }),
border: {
...tab.border,
bottom: false,
},
}
const inactivePaneInactiveTab = {
...tab,
background: background(layer),
text: text(layer, "sans", "variant", { size: "sm" }),
}
const inactivePaneInactiveTab = {
...tab,
background: background(layer),
text: text(layer, "sans", "variant", { size: "sm" }),
}
const inactivePaneActiveTab = {
...tab,
background: background(activeLayer),
text: text(layer, "sans", "variant", { size: "sm" }),
border: {
...tab.border,
bottom: false,
},
}
const inactivePaneActiveTab = {
...tab,
background: background(activeLayer),
text: text(layer, "sans", "variant", { size: "sm" }),
border: {
...tab.border,
bottom: false,
},
}
const draggedTab = {
...activePaneActiveTab,
background: withOpacity(tab.background, 0.9),
border: undefined as any,
shadow: colorScheme.popoverShadow,
}
const draggedTab = {
...activePaneActiveTab,
background: withOpacity(tab.background, 0.9),
border: undefined as any,
shadow: colorScheme.popoverShadow,
}
return {
height,
background: background(layer),
activePane: {
activeTab: activePaneActiveTab,
inactiveTab: tab,
},
inactivePane: {
activeTab: inactivePaneActiveTab,
inactiveTab: inactivePaneInactiveTab,
},
draggedTab,
paneButton: toggleable(interactive({
base: {
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: activePaneActiveTab.height,
},
state: {
hovered: {
color: foreground(layer, "hovered"),
}
}
}),
{
default: {
color: foreground(layer, "accent"),
}
},
),
paneButtonContainer: {
background: tab.background,
border: {
...tab.border,
right: false,
},
},
}
return {
height,
background: background(layer),
activePane: {
activeTab: activePaneActiveTab,
inactiveTab: tab,
},
inactivePane: {
activeTab: inactivePaneActiveTab,
inactiveTab: inactivePaneInactiveTab,
},
draggedTab,
paneButton: toggleable(interactive({
base: {
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: activePaneActiveTab.height,
},
state: {
hovered: {
color: foreground(layer, "hovered"),
}
}
}),
{
default: {
color: foreground(layer, "accent"),
}
},
),
paneButtonContainer: {
background: tab.background,
border: {
...tab.border,
right: false,
},
},
}
}

View File

@ -1,56 +1,56 @@
import { ColorScheme } from "../theme/colorScheme"
import { background, border, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import { toggleable } from "./toggle"
export default function dropdownMenu(colorScheme: ColorScheme) {
let layer = colorScheme.middle
let layer = colorScheme.middle
return {
rowHeight: 30,
background: background(layer),
border: border(layer),
shadow: colorScheme.popoverShadow,
header: interactive({
base: {
...text(layer, "sans", { size: "sm" }),
secondaryText: text(layer, "sans", { size: "sm", color: "#aaaaaa" }),
secondaryTextSpacing: 10,
padding: { left: 8, right: 8, top: 2, bottom: 2 },
cornerRadius: 6,
background: background(layer, "on"),
border: border(layer, "on", { overlay: true })
},
state: {
hovered: {
background: background(layer, "hovered"),
...text(layer, "sans", "hovered", { size: "sm" }),
}
}
})
,
sectionHeader: {
...text(layer, "sans", { size: "sm" }),
padding: { left: 8, right: 8, top: 8, bottom: 8 },
},
item: toggleable(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" }),
}
}
}), {
default: {
background: background(layer, "active"),
},
hovered: {
background: background(layer, "active"),
},
})
}
return {
rowHeight: 30,
background: background(layer),
border: border(layer),
shadow: colorScheme.popoverShadow,
header: interactive({
base: {
...text(layer, "sans", { size: "sm" }),
secondaryText: text(layer, "sans", { size: "sm", color: "#aaaaaa" }),
secondaryTextSpacing: 10,
padding: { left: 8, right: 8, top: 2, bottom: 2 },
cornerRadius: 6,
background: background(layer, "on"),
border: border(layer, "on", { overlay: true })
},
state: {
hovered: {
background: background(layer, "hovered"),
...text(layer, "sans", "hovered", { size: "sm" }),
}
}
})
,
sectionHeader: {
...text(layer, "sans", { size: "sm" }),
padding: { left: 8, right: 8, top: 8, bottom: 8 },
},
item: toggleable(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" }),
}
}
}), {
default: {
background: background(layer, "active"),
},
hovered: {
background: background(layer, "active"),
},
})
}
}

View File

@ -1,39 +1,39 @@
import { ColorScheme } from "../theme/colorScheme"
import { foreground, text } from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
const headerPadding = 8
export default function updateNotification(colorScheme: ColorScheme): Object {
let layer = colorScheme.middle
return {
message: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
actionMessage: interactive({
base: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, top: 6, bottom: 6 }
}, state: {
hovered: {
color: foreground(layer, "hovered"),
}
}
}),
dismissButton: interactive({
base: {
color: foreground(layer),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8
}, state: {
hovered: {
color: foreground(layer, "hovered"),
let layer = colorScheme.middle
return {
message: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, right: headerPadding },
},
},
})
actionMessage: interactive({
base: {
...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, top: 6, bottom: 6 }
}, state: {
hovered: {
color: foreground(layer, "hovered"),
}
}
}),
dismissButton: interactive({
base: {
color: foreground(layer),
iconWidth: 8,
iconHeight: 8,
buttonWidth: 8,
buttonHeight: 8
}, state: {
hovered: {
color: foreground(layer, "hovered"),
},
},
})
}
}
}

View File

@ -1,133 +1,133 @@
import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import {
border,
background,
foreground,
text,
TextProperties,
svg,
border,
background,
foreground,
text,
TextProperties,
svg,
} from "./components"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
export default function welcome(colorScheme: ColorScheme) {
let layer = colorScheme.highest
let layer = colorScheme.highest
let checkboxBase = {
cornerRadius: 4,
padding: {
left: 3,
right: 3,
top: 3,
bottom: 3,
},
// shadow: colorScheme.popoverShadow,
border: border(layer),
margin: {
right: 8,
top: 5,
bottom: 5,
},
}
let interactive_text_size: TextProperties = { size: "sm" }
return {
pageWidth: 320,
logo: svg(foreground(layer, "default"), "icons/logo_96.svg", 64, 64),
logoSubheading: {
...text(layer, "sans", "variant", { size: "md" }),
margin: {
top: 10,
bottom: 7,
},
},
buttonGroup: {
margin: {
top: 8,
bottom: 16,
},
},
headingGroup: {
margin: {
top: 8,
bottom: 12,
},
},
checkboxGroup: {
border: border(layer, "variant"),
background: withOpacity(background(layer, "hovered"), 0.25),
cornerRadius: 4,
padding: {
left: 12,
top: 2,
bottom: 2,
},
},
button: interactive({
base: {
background: background(layer),
border: border(layer, "active"),
let checkboxBase = {
cornerRadius: 4,
margin: {
top: 4,
bottom: 4,
},
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
left: 3,
right: 3,
top: 3,
bottom: 3,
},
...text(layer, "sans", "default", interactive_text_size)
}, state: {
hovered: {
...text(layer, "sans", "default", interactive_text_size),
background: background(layer, "hovered"),
}
}
}),
// shadow: colorScheme.popoverShadow,
border: border(layer),
margin: {
right: 8,
top: 5,
bottom: 5,
},
}
usageNote: {
...text(layer, "sans", "variant", { size: "2xs" }),
padding: {
top: -4,
},
},
checkboxContainer: {
margin: {
top: 4,
},
padding: {
bottom: 8,
},
},
checkbox: {
label: {
...text(layer, "sans", interactive_text_size),
// Also supports margin, container, border, etc.
},
icon: svg(foreground(layer, "on"), "icons/check_12.svg", 12, 12),
default: {
...checkboxBase,
background: background(layer, "default"),
border: border(layer, "active"),
},
checked: {
...checkboxBase,
background: background(layer, "hovered"),
border: border(layer, "active"),
},
hovered: {
...checkboxBase,
background: background(layer, "hovered"),
border: border(layer, "active"),
},
hoveredAndChecked: {
...checkboxBase,
background: background(layer, "hovered"),
border: border(layer, "active"),
},
},
}
let interactive_text_size: TextProperties = { size: "sm" }
return {
pageWidth: 320,
logo: svg(foreground(layer, "default"), "icons/logo_96.svg", 64, 64),
logoSubheading: {
...text(layer, "sans", "variant", { size: "md" }),
margin: {
top: 10,
bottom: 7,
},
},
buttonGroup: {
margin: {
top: 8,
bottom: 16,
},
},
headingGroup: {
margin: {
top: 8,
bottom: 12,
},
},
checkboxGroup: {
border: border(layer, "variant"),
background: withOpacity(background(layer, "hovered"), 0.25),
cornerRadius: 4,
padding: {
left: 12,
top: 2,
bottom: 2,
},
},
button: interactive({
base: {
background: background(layer),
border: border(layer, "active"),
cornerRadius: 4,
margin: {
top: 4,
bottom: 4,
},
padding: {
top: 3,
bottom: 3,
left: 7,
right: 7,
},
...text(layer, "sans", "default", interactive_text_size)
}, state: {
hovered: {
...text(layer, "sans", "default", interactive_text_size),
background: background(layer, "hovered"),
}
}
}),
usageNote: {
...text(layer, "sans", "variant", { size: "2xs" }),
padding: {
top: -4,
},
},
checkboxContainer: {
margin: {
top: 4,
},
padding: {
bottom: 8,
},
},
checkbox: {
label: {
...text(layer, "sans", interactive_text_size),
// Also supports margin, container, border, etc.
},
icon: svg(foreground(layer, "on"), "icons/check_12.svg", 12, 12),
default: {
...checkboxBase,
background: background(layer, "default"),
border: border(layer, "active"),
},
checked: {
...checkboxBase,
background: background(layer, "hovered"),
border: border(layer, "active"),
},
hovered: {
...checkboxBase,
background: background(layer, "hovered"),
border: border(layer, "active"),
},
hoveredAndChecked: {
...checkboxBase,
background: background(layer, "hovered"),
border: border(layer, "active"),
},
},
}
}

View File

@ -2,383 +2,383 @@ import { ColorScheme } from "../theme/colorScheme"
import { withOpacity } from "../theme/color"
import { toggleable } from "./toggle"
import {
background,
border,
borderColor,
foreground,
svg,
text,
background,
border,
borderColor,
foreground,
svg,
text,
} from "./components"
import statusBar from "./statusBar"
import tabBar from "./tabBar"
import { interactive } from "./interactive"
import { interactive } from "../element/interactive"
import merge from 'ts-deepmerge';
export default function workspace(colorScheme: ColorScheme) {
const layer = colorScheme.lowest
const isLight = colorScheme.isLight
const itemSpacing = 8
const titlebarButton = toggleable(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),
}, 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"),
}
}
}),
{
default: {
...text(layer, "sans", "variant", "active", { size: "xs" }),
background: background(layer, "variant", "active"),
border: border(layer, "variant", "active"),
}
},
);
const avatarWidth = 18
const avatarOuterWidth = avatarWidth + 4
const followerAvatarWidth = 14
const followerAvatarOuterWidth = followerAvatarWidth + 4
return {
background: background(colorScheme.lowest),
blankPane: {
logoContainer: {
width: 256,
height: 256,
},
logo: svg(
withOpacity("#000000", colorScheme.isLight ? 0.6 : 0.8),
"icons/logo_96.svg",
256,
256
),
logoShadow: svg(
withOpacity(
colorScheme.isLight
? "#FFFFFF"
: colorScheme.lowest.base.default.background,
colorScheme.isLight ? 1 : 0.6
),
"icons/logo_96.svg",
256,
256
),
keyboardHints: {
margin: {
top: 96,
},
cornerRadius: 4,
},
keyboardHint:
interactive({
base: {
...text(layer, "sans", "variant", { size: "sm" }),
padding: {
top: 3,
left: 8,
right: 8,
bottom: 3,
},
cornerRadius: 8
}, state: {
hovered: {
...text(layer, "sans", "active", { size: "sm" }),
}
}
}),
keyboardHintWidth: 320,
},
joiningProjectAvatar: {
cornerRadius: 40,
width: 80,
},
joiningProjectMessage: {
padding: 12,
...text(layer, "sans", { size: "lg" }),
},
externalLocationMessage: {
background: background(colorScheme.middle, "accent"),
border: border(colorScheme.middle, "accent"),
cornerRadius: 6,
padding: 12,
margin: { bottom: 8, right: 8 },
...text(colorScheme.middle, "sans", "accent", { size: "xs" }),
},
leaderBorderOpacity: 0.7,
leaderBorderWidth: 2.0,
tabBar: tabBar(colorScheme),
modal: {
margin: {
bottom: 52,
top: 52,
},
cursor: "Arrow",
},
zoomedBackground: {
cursor: "Arrow",
background: isLight
? withOpacity(background(colorScheme.lowest), 0.8)
: withOpacity(background(colorScheme.highest), 0.6),
},
zoomedPaneForeground: {
margin: 16,
shadow: colorScheme.modalShadow,
border: border(colorScheme.lowest, { overlay: true }),
},
zoomedPanelForeground: {
margin: 16,
border: border(colorScheme.lowest, { overlay: true }),
},
dock: {
left: {
border: border(layer, { right: true }),
},
bottom: {
border: border(layer, { top: true }),
},
right: {
border: border(layer, { left: true }),
},
},
paneDivider: {
color: borderColor(layer),
width: 1,
},
statusBar: statusBar(colorScheme),
titlebar: {
itemSpacing,
facePileSpacing: 2,
height: 33, // 32px + 1px border. It's important the content area of the titlebar is evenly sized to vertically center avatar images.
background: background(layer),
border: border(layer, { bottom: true }),
padding: {
left: 80,
right: itemSpacing,
},
// Project
title: text(layer, "sans", "variant"),
highlight_color: text(layer, "sans", "active").color,
// Collaborators
leaderAvatar: {
width: avatarWidth,
outerWidth: avatarOuterWidth,
cornerRadius: avatarWidth / 2,
outerCornerRadius: avatarOuterWidth / 2,
},
followerAvatar: {
width: followerAvatarWidth,
outerWidth: followerAvatarOuterWidth,
cornerRadius: followerAvatarWidth / 2,
outerCornerRadius: followerAvatarOuterWidth / 2,
},
inactiveAvatarGrayscale: true,
followerAvatarOverlap: 8,
leaderSelection: {
margin: {
top: 4,
bottom: 4,
},
padding: {
left: 2,
right: 2,
top: 2,
bottom: 2,
},
cornerRadius: 6,
},
avatarRibbon: {
height: 3,
width: 12,
// TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
},
// Sign in buttom
// FlatButton, Variant
signInPrompt:
merge(titlebarButton,
{
inactive: {
default: {
margin: {
left: itemSpacing,
},
}
}
}),
// Offline Indicator
offlineIcon: {
color: foreground(layer, "variant"),
width: 16,
margin: {
left: itemSpacing,
},
padding: {
right: 4,
},
},
// Notice that the collaboration server is out of date
outdatedWarning: {
...text(layer, "sans", "warning", { size: "xs" }),
background: withOpacity(background(layer, "warning"), 0.3),
border: border(layer, "warning"),
margin: {
left: itemSpacing,
},
padding: {
left: 8,
right: 8,
},
cornerRadius: 6,
},
callControl: interactive({
const layer = colorScheme.lowest
const isLight = colorScheme.isLight
const itemSpacing = 8
const titlebarButton = toggleable(interactive({
base: {
cornerRadius: 6,
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: 20,
}, state: {
hovered: {
background: background(layer, "variant", "hovered"),
color: foreground(layer, "variant", "hovered"),
},
}
}),
toggleContactsButton: toggleable(interactive({
base: {
margin: { left: itemSpacing },
cornerRadius: 6,
color: foreground(layer, "variant"),
iconWidth: 14,
buttonWidth: 20,
},
state: {
clicked: {
background: background(layer, "variant", "pressed"),
color: foreground(layer, "variant", "pressed"),
},
hovered: {
background: background(layer, "variant", "hovered"),
color: foreground(layer, "variant", "hovered"),
}
}
}),
{
default: {
background: background(layer, "variant", "active"),
color: foreground(layer, "variant", "active")
}
},
),
userMenuButton: merge(titlebarButton, {
inactive: {
default: {
buttonWidth: 20,
iconWidth: 12
}
}, active: { // posiewic: these properties are not currently set on main
default: {
iconWidth: 12,
button_width: 20,
}
}
}),
toggleContactsBadge: {
cornerRadius: 3,
padding: 2,
margin: { top: 3, left: 3 },
border: border(layer),
background: foreground(layer, "accent"),
},
shareButton: {
...titlebarButton,
},
},
toolbar: {
height: 34,
background: background(colorScheme.highest),
border: border(colorScheme.highest, { bottom: true }),
itemSpacing: 8,
navButton: interactive(
{
base: {
color: foreground(colorScheme.highest, "on"),
iconWidth: 12,
buttonWidth: 24,
cornerRadius: 6,
}, state: {
padding: {
top: 1,
bottom: 1,
left: 8,
right: 8,
},
...text(layer, "sans", "variant", { size: "xs" }),
background: background(layer, "variant"),
border: border(layer),
}, state: {
hovered: {
color: foreground(colorScheme.highest, "on", "hovered"),
background: background(
colorScheme.highest,
"on",
"hovered"
),
...text(layer, "sans", "variant", "hovered", { size: "xs" }),
background: background(layer, "variant", "hovered"),
border: border(layer, "variant", "hovered"),
},
disabled: {
color: foreground(colorScheme.highest, "on", "disabled"),
},
}
}),
padding: { left: 8, right: 8, top: 4, bottom: 4 },
},
breadcrumbHeight: 24,
breadcrumbs: interactive({
base: {
...text(colorScheme.highest, "sans", "variant"),
cornerRadius: 6,
padding: {
left: 6,
right: 6,
clicked: {
...text(layer, "sans", "variant", "pressed", { size: "xs" }),
background: background(layer, "variant", "pressed"),
border: border(layer, "variant", "pressed"),
}
}
}, state: {
hovered: {
color: foreground(colorScheme.highest, "on", "hovered"),
background: background(colorScheme.highest, "on", "hovered"),
},
}
}),
disconnectedOverlay: {
...text(layer, "sans"),
background: withOpacity(background(layer), 0.8),
},
notification: {
margin: { top: 10 },
background: background(colorScheme.middle),
cornerRadius: 6,
padding: 12,
border: border(colorScheme.middle),
shadow: colorScheme.popoverShadow,
},
notifications: {
width: 400,
margin: { right: 10, bottom: 10 },
},
dropTargetOverlayColor: withOpacity(foreground(layer, "variant"), 0.5),
}
{
default: {
...text(layer, "sans", "variant", "active", { size: "xs" }),
background: background(layer, "variant", "active"),
border: border(layer, "variant", "active"),
}
},
);
const avatarWidth = 18
const avatarOuterWidth = avatarWidth + 4
const followerAvatarWidth = 14
const followerAvatarOuterWidth = followerAvatarWidth + 4
return {
background: background(colorScheme.lowest),
blankPane: {
logoContainer: {
width: 256,
height: 256,
},
logo: svg(
withOpacity("#000000", colorScheme.isLight ? 0.6 : 0.8),
"icons/logo_96.svg",
256,
256
),
logoShadow: svg(
withOpacity(
colorScheme.isLight
? "#FFFFFF"
: colorScheme.lowest.base.default.background,
colorScheme.isLight ? 1 : 0.6
),
"icons/logo_96.svg",
256,
256
),
keyboardHints: {
margin: {
top: 96,
},
cornerRadius: 4,
},
keyboardHint:
interactive({
base: {
...text(layer, "sans", "variant", { size: "sm" }),
padding: {
top: 3,
left: 8,
right: 8,
bottom: 3,
},
cornerRadius: 8
}, state: {
hovered: {
...text(layer, "sans", "active", { size: "sm" }),
}
}
}),
keyboardHintWidth: 320,
},
joiningProjectAvatar: {
cornerRadius: 40,
width: 80,
},
joiningProjectMessage: {
padding: 12,
...text(layer, "sans", { size: "lg" }),
},
externalLocationMessage: {
background: background(colorScheme.middle, "accent"),
border: border(colorScheme.middle, "accent"),
cornerRadius: 6,
padding: 12,
margin: { bottom: 8, right: 8 },
...text(colorScheme.middle, "sans", "accent", { size: "xs" }),
},
leaderBorderOpacity: 0.7,
leaderBorderWidth: 2.0,
tabBar: tabBar(colorScheme),
modal: {
margin: {
bottom: 52,
top: 52,
},
cursor: "Arrow",
},
zoomedBackground: {
cursor: "Arrow",
background: isLight
? withOpacity(background(colorScheme.lowest), 0.8)
: withOpacity(background(colorScheme.highest), 0.6),
},
zoomedPaneForeground: {
margin: 16,
shadow: colorScheme.modalShadow,
border: border(colorScheme.lowest, { overlay: true }),
},
zoomedPanelForeground: {
margin: 16,
border: border(colorScheme.lowest, { overlay: true }),
},
dock: {
left: {
border: border(layer, { right: true }),
},
bottom: {
border: border(layer, { top: true }),
},
right: {
border: border(layer, { left: true }),
},
},
paneDivider: {
color: borderColor(layer),
width: 1,
},
statusBar: statusBar(colorScheme),
titlebar: {
itemSpacing,
facePileSpacing: 2,
height: 33, // 32px + 1px border. It's important the content area of the titlebar is evenly sized to vertically center avatar images.
background: background(layer),
border: border(layer, { bottom: true }),
padding: {
left: 80,
right: itemSpacing,
},
// Project
title: text(layer, "sans", "variant"),
highlight_color: text(layer, "sans", "active").color,
// Collaborators
leaderAvatar: {
width: avatarWidth,
outerWidth: avatarOuterWidth,
cornerRadius: avatarWidth / 2,
outerCornerRadius: avatarOuterWidth / 2,
},
followerAvatar: {
width: followerAvatarWidth,
outerWidth: followerAvatarOuterWidth,
cornerRadius: followerAvatarWidth / 2,
outerCornerRadius: followerAvatarOuterWidth / 2,
},
inactiveAvatarGrayscale: true,
followerAvatarOverlap: 8,
leaderSelection: {
margin: {
top: 4,
bottom: 4,
},
padding: {
left: 2,
right: 2,
top: 2,
bottom: 2,
},
cornerRadius: 6,
},
avatarRibbon: {
height: 3,
width: 12,
// TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
},
// Sign in buttom
// FlatButton, Variant
signInPrompt:
merge(titlebarButton,
{
inactive: {
default: {
margin: {
left: itemSpacing,
},
}
}
}),
// Offline Indicator
offlineIcon: {
color: foreground(layer, "variant"),
width: 16,
margin: {
left: itemSpacing,
},
padding: {
right: 4,
},
},
// Notice that the collaboration server is out of date
outdatedWarning: {
...text(layer, "sans", "warning", { size: "xs" }),
background: withOpacity(background(layer, "warning"), 0.3),
border: border(layer, "warning"),
margin: {
left: itemSpacing,
},
padding: {
left: 8,
right: 8,
},
cornerRadius: 6,
},
callControl: interactive({
base: {
cornerRadius: 6,
color: foreground(layer, "variant"),
iconWidth: 12,
buttonWidth: 20,
}, state: {
hovered: {
background: background(layer, "variant", "hovered"),
color: foreground(layer, "variant", "hovered"),
},
}
}),
toggleContactsButton: toggleable(interactive({
base: {
margin: { left: itemSpacing },
cornerRadius: 6,
color: foreground(layer, "variant"),
iconWidth: 14,
buttonWidth: 20,
},
state: {
clicked: {
background: background(layer, "variant", "pressed"),
color: foreground(layer, "variant", "pressed"),
},
hovered: {
background: background(layer, "variant", "hovered"),
color: foreground(layer, "variant", "hovered"),
}
}
}),
{
default: {
background: background(layer, "variant", "active"),
color: foreground(layer, "variant", "active")
}
},
),
userMenuButton: merge(titlebarButton, {
inactive: {
default: {
buttonWidth: 20,
iconWidth: 12
}
}, active: { // posiewic: these properties are not currently set on main
default: {
iconWidth: 12,
button_width: 20,
}
}
}),
toggleContactsBadge: {
cornerRadius: 3,
padding: 2,
margin: { top: 3, left: 3 },
border: border(layer),
background: foreground(layer, "accent"),
},
shareButton: {
...titlebarButton,
},
},
toolbar: {
height: 34,
background: background(colorScheme.highest),
border: border(colorScheme.highest, { bottom: true }),
itemSpacing: 8,
navButton: interactive(
{
base: {
color: foreground(colorScheme.highest, "on"),
iconWidth: 12,
buttonWidth: 24,
cornerRadius: 6,
}, state: {
hovered: {
color: foreground(colorScheme.highest, "on", "hovered"),
background: background(
colorScheme.highest,
"on",
"hovered"
),
},
disabled: {
color: foreground(colorScheme.highest, "on", "disabled"),
},
}
}),
padding: { left: 8, right: 8, top: 4, bottom: 4 },
},
breadcrumbHeight: 24,
breadcrumbs: interactive({
base: {
...text(colorScheme.highest, "sans", "variant"),
cornerRadius: 6,
padding: {
left: 6,
right: 6,
}
}, state: {
hovered: {
color: foreground(colorScheme.highest, "on", "hovered"),
background: background(colorScheme.highest, "on", "hovered"),
},
}
}),
disconnectedOverlay: {
...text(layer, "sans"),
background: withOpacity(background(layer), 0.8),
},
notification: {
margin: { top: 10 },
background: background(colorScheme.middle),
cornerRadius: 6,
padding: 12,
border: border(colorScheme.middle),
shadow: colorScheme.popoverShadow,
},
notifications: {
width: 400,
margin: { right: 10, bottom: 10 },
},
dropTargetOverlayColor: withOpacity(foreground(layer, "variant"), 0.5),
}
}

8
styles/vitest.config.ts Normal file
View File

@ -0,0 +1,8 @@
import { configDefaults, defineConfig } from 'vitest/config'
export default defineConfig({
test: {
exclude: [...configDefaults.exclude, 'target/*'],
include: ['src/**/*.{spec,test}.ts'],
},
})