This commit is contained in:
Nate Butler 2023-06-16 01:01:51 -04:00 committed by Mikayla Maki
parent 1f3feacb21
commit 5c034ab63c
No known key found for this signature in database
31 changed files with 978 additions and 860 deletions

View File

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

View File

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

View File

@ -1,20 +1,27 @@
import merge from "ts-deepmerge" import merge from "ts-deepmerge"
type InteractiveState = "default" | "hovered" | "clicked" | "selected" | "disabled"; type InteractiveState =
| "default"
| "hovered"
| "clicked"
| "selected"
| "disabled"
type Interactive<T> = { type Interactive<T> = {
default: T, default: T
hovered?: T, hovered?: T
clicked?: T, clicked?: T
selected?: T, selected?: T
disabled?: T, disabled?: T
}; }
export const NO_DEFAULT_OR_BASE_ERROR = "An interactive object must have a default state, or a base property." export const NO_DEFAULT_OR_BASE_ERROR =
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 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> { interface InteractiveProps<T> {
base?: T, base?: T
state: Partial<Record<InteractiveState, T>> state: Partial<Record<InteractiveState, T>>
} }
@ -29,46 +36,61 @@ interface InteractiveProps<T> {
* @param state Object containing optional modified fields to be included in the resulting object for each state. * @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`. * @returns Interactive<T> object with fields from `base` and `state`.
*/ */
export function interactive<T extends Object>({ base, state }: InteractiveProps<T>): Interactive<T> { export function interactive<T extends Object>({
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR); base,
state,
}: InteractiveProps<T>): Interactive<T> {
if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR)
let defaultState: T; let defaultState: T
if (state.default && base) { if (state.default && base) {
defaultState = merge(base, state.default) as T; defaultState = merge(base, state.default) as T
} else { } else {
defaultState = base ? base : state.default as T; defaultState = base ? base : (state.default as T)
} }
let interactiveObj: Interactive<T> = { let interactiveObj: Interactive<T> = {
default: defaultState, default: defaultState,
}; }
let stateCount = 0; let stateCount = 0
if (state.hovered !== undefined) { if (state.hovered !== undefined) {
interactiveObj.hovered = merge(interactiveObj.default, state.hovered) as T; interactiveObj.hovered = merge(
stateCount++; interactiveObj.default,
state.hovered
) as T
stateCount++
} }
if (state.clicked !== undefined) { if (state.clicked !== undefined) {
interactiveObj.clicked = merge(interactiveObj.default, state.clicked) as T; interactiveObj.clicked = merge(
stateCount++; interactiveObj.default,
state.clicked
) as T
stateCount++
} }
if (state.selected !== undefined) { if (state.selected !== undefined) {
interactiveObj.selected = merge(interactiveObj.default, state.selected) as T; interactiveObj.selected = merge(
stateCount++; interactiveObj.default,
state.selected
) as T
stateCount++
} }
if (state.disabled !== undefined) { if (state.disabled !== undefined) {
interactiveObj.disabled = merge(interactiveObj.default, state.disabled) as T; interactiveObj.disabled = merge(
stateCount++; interactiveObj.default,
state.disabled
) as T
stateCount++
} }
if (stateCount < 1) { if (stateCount < 1) {
throw new Error(NOT_ENOUGH_STATES_ERROR); throw new Error(NOT_ENOUGH_STATES_ERROR)
} }
return interactiveObj; return interactiveObj
} }

View File

@ -1,4 +1,3 @@
import { text } from "./components"
import contactFinder from "./contactFinder" import contactFinder from "./contactFinder"
import contactsPopover from "./contactsPopover" import contactsPopover from "./contactsPopover"
import commandPalette from "./commandPalette" import commandPalette from "./commandPalette"

View File

@ -16,17 +16,27 @@ export default function assistant(colorScheme: ColorScheme) {
background: editor(colorScheme).background, background: editor(colorScheme).background,
}, },
userSender: { userSender: {
default: default: {
{ ...text(layer, "sans", "default", { size: "sm", weight: "bold" }) }, ...text(layer, "sans", "default", {
size: "sm",
weight: "bold",
}),
},
}, },
assistantSender: { assistantSender: {
default: { default: {
...text(layer, "sans", "accent", { size: "sm", weight: "bold" }) ...text(layer, "sans", "accent", {
size: "sm",
weight: "bold",
}),
}, },
}, },
systemSender: { systemSender: {
default: { default: {
...text(layer, "sans", "variant", { size: "sm", weight: "bold" }) ...text(layer, "sans", "variant", {
size: "sm",
weight: "bold",
}),
}, },
}, },
sentAt: { sentAt: {
@ -43,11 +53,12 @@ export default function assistant(colorScheme: ColorScheme) {
padding: 4, padding: 4,
cornerRadius: 4, cornerRadius: 4,
...text(layer, "sans", "default", { size: "xs" }), ...text(layer, "sans", "default", { size: "xs" }),
}, state: { },
state: {
hovered: { hovered: {
background: background(layer, "on", "hovered"), background: background(layer, "on", "hovered"),
} },
} },
}), }),
remainingTokens: { remainingTokens: {
background: background(layer, "on"), background: background(layer, "on"),

View File

@ -8,10 +8,12 @@ export default function commandPalette(colorScheme: ColorScheme) {
let layer = colorScheme.highest let layer = colorScheme.highest
return { return {
keystrokeSpacing: 8, keystrokeSpacing: 8,
key: key: toggleable(
toggleable(interactive({ interactive({
base: { base: {
text: text(layer, "mono", "variant", "default", { size: "xs" }), text: text(layer, "mono", "variant", "default", {
size: "xs",
}),
cornerRadius: 2, cornerRadius: 2,
background: background(layer, "on"), background: background(layer, "on"),
padding: { padding: {
@ -25,15 +27,15 @@ export default function commandPalette(colorScheme: ColorScheme) {
bottom: 1, bottom: 1,
left: 2, left: 2,
}, },
}, state: { hovered: { cornerRadius: 4, padding: { top: 17 } } } },
}), { state: { hovered: { cornerRadius: 4, padding: { top: 17 } } },
}),
{
default: { default: {
text: text(layer, "mono", "on", "default", { size: "xs" }), text: text(layer, "mono", "on", "default", { size: "xs" }),
background: withOpacity(background(layer, "on"), 0.2), background: withOpacity(background(layer, "on"), 0.2),
} },
}
}) ),
,
} }
} }

View File

@ -2,297 +2,297 @@ import { fontFamilies, fontSizes, FontWeight } from "../common"
import { Layer, Styles, StyleSets, Style } from "../theme/colorScheme" import { Layer, Styles, StyleSets, Style } from "../theme/colorScheme"
function isStyleSet(key: any): key is StyleSets { function isStyleSet(key: any): key is StyleSets {
return [ return [
"base", "base",
"variant", "variant",
"on", "on",
"accent", "accent",
"positive", "positive",
"warning", "warning",
"negative", "negative",
].includes(key) ].includes(key)
} }
function isStyle(key: any): key is Styles { function isStyle(key: any): key is Styles {
return [ return [
"default", "default",
"active", "active",
"disabled", "disabled",
"hovered", "hovered",
"pressed", "pressed",
"inverted", "inverted",
].includes(key) ].includes(key)
} }
function getStyle( function getStyle(
layer: Layer, layer: Layer,
possibleStyleSetOrStyle?: any, possibleStyleSetOrStyle?: any,
possibleStyle?: any possibleStyle?: any
): Style { ): Style {
let styleSet: StyleSets = "base" let styleSet: StyleSets = "base"
let style: Styles = "default" let style: Styles = "default"
if (isStyleSet(possibleStyleSetOrStyle)) { if (isStyleSet(possibleStyleSetOrStyle)) {
styleSet = possibleStyleSetOrStyle styleSet = possibleStyleSetOrStyle
} else if (isStyle(possibleStyleSetOrStyle)) { } else if (isStyle(possibleStyleSetOrStyle)) {
style = possibleStyleSetOrStyle style = possibleStyleSetOrStyle
} }
if (isStyle(possibleStyle)) { if (isStyle(possibleStyle)) {
style = possibleStyle style = possibleStyle
} }
return layer[styleSet][style] return layer[styleSet][style]
} }
export function background(layer: Layer, style?: Styles): string export function background(layer: Layer, style?: Styles): string
export function background( export function background(
layer: Layer, layer: Layer,
styleSet?: StyleSets, styleSet?: StyleSets,
style?: Styles style?: Styles
): string ): string
export function background( export function background(
layer: Layer, layer: Layer,
styleSetOrStyles?: StyleSets | Styles, styleSetOrStyles?: StyleSets | Styles,
style?: Styles style?: Styles
): string { ): string {
return getStyle(layer, styleSetOrStyles, style).background return getStyle(layer, styleSetOrStyles, style).background
} }
export function borderColor(layer: Layer, style?: Styles): string export function borderColor(layer: Layer, style?: Styles): string
export function borderColor( export function borderColor(
layer: Layer, layer: Layer,
styleSet?: StyleSets, styleSet?: StyleSets,
style?: Styles style?: Styles
): string ): string
export function borderColor( export function borderColor(
layer: Layer, layer: Layer,
styleSetOrStyles?: StyleSets | Styles, styleSetOrStyles?: StyleSets | Styles,
style?: Styles style?: Styles
): string { ): string {
return getStyle(layer, styleSetOrStyles, style).border return getStyle(layer, styleSetOrStyles, style).border
} }
export function foreground(layer: Layer, style?: Styles): string export function foreground(layer: Layer, style?: Styles): string
export function foreground( export function foreground(
layer: Layer, layer: Layer,
styleSet?: StyleSets, styleSet?: StyleSets,
style?: Styles style?: Styles
): string ): string
export function foreground( export function foreground(
layer: Layer, layer: Layer,
styleSetOrStyles?: StyleSets | Styles, styleSetOrStyles?: StyleSets | Styles,
style?: Styles style?: Styles
): string { ): string {
return getStyle(layer, styleSetOrStyles, style).foreground return getStyle(layer, styleSetOrStyles, style).foreground
} }
interface Text extends Object { interface Text extends Object {
family: keyof typeof fontFamilies family: keyof typeof fontFamilies
color: string color: string
size: number size: number
weight?: FontWeight weight?: FontWeight
underline?: boolean underline?: boolean
} }
export interface TextProperties { export interface TextProperties {
size?: keyof typeof fontSizes size?: keyof typeof fontSizes
weight?: FontWeight weight?: FontWeight
underline?: boolean underline?: boolean
color?: string color?: string
features?: FontFeatures features?: FontFeatures
} }
interface FontFeatures { interface FontFeatures {
/** Contextual Alternates: Applies a second substitution feature based on a match of a character pattern within a context of surrounding patterns */ /** Contextual Alternates: Applies a second substitution feature based on a match of a character pattern within a context of surrounding patterns */
calt?: boolean calt?: boolean
/** Case-Sensitive Forms: Shifts various punctuation marks up to a position that works better with all-capital sequences */ /** Case-Sensitive Forms: Shifts various punctuation marks up to a position that works better with all-capital sequences */
case?: boolean case?: boolean
/** Capital Spacing: Adjusts inter-glyph spacing for all-capital text */ /** Capital Spacing: Adjusts inter-glyph spacing for all-capital text */
cpsp?: boolean cpsp?: boolean
/** Fractions: Replaces figures separated by a slash with diagonal fractions */ /** Fractions: Replaces figures separated by a slash with diagonal fractions */
frac?: boolean frac?: boolean
/** Standard Ligatures: Replaces a sequence of glyphs with a single glyph which is preferred for typographic purposes */ /** Standard Ligatures: Replaces a sequence of glyphs with a single glyph which is preferred for typographic purposes */
liga?: boolean liga?: boolean
/** Oldstyle Figures: Changes selected figures from the default or lining style to oldstyle form. */ /** Oldstyle Figures: Changes selected figures from the default or lining style to oldstyle form. */
onum?: boolean onum?: boolean
/** Ordinals: Replaces default alphabetic glyphs with the corresponding ordinal forms for use after figures */ /** Ordinals: Replaces default alphabetic glyphs with the corresponding ordinal forms for use after figures */
ordn?: boolean ordn?: boolean
/** Proportional Figures: Replaces figure glyphs set on uniform (tabular) widths with corresponding glyphs set on proportional widths */ /** Proportional Figures: Replaces figure glyphs set on uniform (tabular) widths with corresponding glyphs set on proportional widths */
pnum?: boolean pnum?: boolean
/** Stylistic set 01 */ /** Stylistic set 01 */
ss01?: boolean ss01?: boolean
/** Stylistic set 02 */ /** Stylistic set 02 */
ss02?: boolean ss02?: boolean
/** Stylistic set 03 */ /** Stylistic set 03 */
ss03?: boolean ss03?: boolean
/** Stylistic set 04 */ /** Stylistic set 04 */
ss04?: boolean ss04?: boolean
/** Stylistic set 05 */ /** Stylistic set 05 */
ss05?: boolean ss05?: boolean
/** Stylistic set 06 */ /** Stylistic set 06 */
ss06?: boolean ss06?: boolean
/** Stylistic set 07 */ /** Stylistic set 07 */
ss07?: boolean ss07?: boolean
/** Stylistic set 08 */ /** Stylistic set 08 */
ss08?: boolean ss08?: boolean
/** Stylistic set 09 */ /** Stylistic set 09 */
ss09?: boolean ss09?: boolean
/** Stylistic set 10 */ /** Stylistic set 10 */
ss10?: boolean ss10?: boolean
/** Stylistic set 11 */ /** Stylistic set 11 */
ss11?: boolean ss11?: boolean
/** Stylistic set 12 */ /** Stylistic set 12 */
ss12?: boolean ss12?: boolean
/** Stylistic set 13 */ /** Stylistic set 13 */
ss13?: boolean ss13?: boolean
/** Stylistic set 14 */ /** Stylistic set 14 */
ss14?: boolean ss14?: boolean
/** Stylistic set 15 */ /** Stylistic set 15 */
ss15?: boolean ss15?: boolean
/** Stylistic set 16 */ /** Stylistic set 16 */
ss16?: boolean ss16?: boolean
/** Stylistic set 17 */ /** Stylistic set 17 */
ss17?: boolean ss17?: boolean
/** Stylistic set 18 */ /** Stylistic set 18 */
ss18?: boolean ss18?: boolean
/** Stylistic set 19 */ /** Stylistic set 19 */
ss19?: boolean ss19?: boolean
/** Stylistic set 20 */ /** Stylistic set 20 */
ss20?: boolean ss20?: boolean
/** Subscript: Replaces default glyphs with subscript glyphs */ /** Subscript: Replaces default glyphs with subscript glyphs */
subs?: boolean subs?: boolean
/** Superscript: Replaces default glyphs with superscript glyphs */ /** Superscript: Replaces default glyphs with superscript glyphs */
sups?: boolean sups?: boolean
/** Swash: Replaces default glyphs with swash glyphs for stylistic purposes */ /** Swash: Replaces default glyphs with swash glyphs for stylistic purposes */
swsh?: boolean swsh?: boolean
/** Titling: Replaces default glyphs with titling glyphs for use in large-size settings */ /** Titling: Replaces default glyphs with titling glyphs for use in large-size settings */
titl?: boolean titl?: boolean
/** Tabular Figures: Replaces figure glyphs set on proportional widths with corresponding glyphs set on uniform (tabular) widths */ /** Tabular Figures: Replaces figure glyphs set on proportional widths with corresponding glyphs set on uniform (tabular) widths */
tnum?: boolean tnum?: boolean
/** Slashed Zero: Replaces default zero with a slashed zero for better distinction between "0" and "O" */ /** Slashed Zero: Replaces default zero with a slashed zero for better distinction between "0" and "O" */
zero?: boolean zero?: boolean
} }
export function text( export function text(
layer: Layer, layer: Layer,
fontFamily: keyof typeof fontFamilies, fontFamily: keyof typeof fontFamilies,
styleSet: StyleSets, styleSet: StyleSets,
style: Styles, style: Styles,
properties?: TextProperties properties?: TextProperties
): Text ): Text
export function text( export function text(
layer: Layer, layer: Layer,
fontFamily: keyof typeof fontFamilies, fontFamily: keyof typeof fontFamilies,
styleSet: StyleSets, styleSet: StyleSets,
properties?: TextProperties properties?: TextProperties
): Text ): Text
export function text( export function text(
layer: Layer, layer: Layer,
fontFamily: keyof typeof fontFamilies, fontFamily: keyof typeof fontFamilies,
style: Styles, style: Styles,
properties?: TextProperties properties?: TextProperties
): Text ): Text
export function text( export function text(
layer: Layer, layer: Layer,
fontFamily: keyof typeof fontFamilies, fontFamily: keyof typeof fontFamilies,
properties?: TextProperties properties?: TextProperties
): Text ): Text
export function text( export function text(
layer: Layer, layer: Layer,
fontFamily: keyof typeof fontFamilies, fontFamily: keyof typeof fontFamilies,
styleSetStyleOrProperties?: StyleSets | Styles | TextProperties, styleSetStyleOrProperties?: StyleSets | Styles | TextProperties,
styleOrProperties?: Styles | TextProperties, styleOrProperties?: Styles | TextProperties,
properties?: TextProperties properties?: TextProperties
) { ) {
let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties) let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
if (typeof styleSetStyleOrProperties === "object") { if (typeof styleSetStyleOrProperties === "object") {
properties = styleSetStyleOrProperties properties = styleSetStyleOrProperties
} }
if (typeof styleOrProperties === "object") { if (typeof styleOrProperties === "object") {
properties = styleOrProperties properties = styleOrProperties
} }
let size = fontSizes[properties?.size || "sm"] let size = fontSizes[properties?.size || "sm"]
let color = properties?.color || style.foreground let color = properties?.color || style.foreground
return { return {
family: fontFamilies[fontFamily], family: fontFamilies[fontFamily],
...properties, ...properties,
color, color,
size, size,
} }
} }
export interface Border { export interface Border {
color: string color: string
width: number width: number
top?: boolean top?: boolean
bottom?: boolean bottom?: boolean
left?: boolean left?: boolean
right?: boolean right?: boolean
overlay?: boolean overlay?: boolean
} }
export interface BorderProperties { export interface BorderProperties {
width?: number width?: number
top?: boolean top?: boolean
bottom?: boolean bottom?: boolean
left?: boolean left?: boolean
right?: boolean right?: boolean
overlay?: boolean overlay?: boolean
} }
export function border( export function border(
layer: Layer, layer: Layer,
styleSet: StyleSets, styleSet: StyleSets,
style: Styles, style: Styles,
properties?: BorderProperties properties?: BorderProperties
): Border ): Border
export function border( export function border(
layer: Layer, layer: Layer,
styleSet: StyleSets, styleSet: StyleSets,
properties?: BorderProperties properties?: BorderProperties
): Border ): Border
export function border( export function border(
layer: Layer, layer: Layer,
style: Styles, style: Styles,
properties?: BorderProperties properties?: BorderProperties
): Border ): Border
export function border(layer: Layer, properties?: BorderProperties): Border export function border(layer: Layer, properties?: BorderProperties): Border
export function border( export function border(
layer: Layer, layer: Layer,
styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties, styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties,
styleOrProperties?: Styles | BorderProperties, styleOrProperties?: Styles | BorderProperties,
properties?: BorderProperties properties?: BorderProperties
): Border { ): Border {
let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties) let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
if (typeof styleSetStyleOrProperties === "object") { if (typeof styleSetStyleOrProperties === "object") {
properties = styleSetStyleOrProperties properties = styleSetStyleOrProperties
} }
if (typeof styleOrProperties === "object") { if (typeof styleOrProperties === "object") {
properties = styleOrProperties properties = styleOrProperties
} }
return { return {
color: style.border, color: style.border,
width: 1, width: 1,
...properties, ...properties,
} }
} }
export function svg( export function svg(
color: string, color: string,
asset: String, asset: String,
width: Number, width: Number,
height: Number height: Number
) { ) {
return { return {
color, color,
asset, asset,
dimensions: { dimensions: {
width, width,
height, height,
}, },
} }
} }

View File

@ -72,24 +72,28 @@ export default function contactsPanel(colorScheme: ColorScheme) {
}, },
rowHeight: 28, rowHeight: 28,
sectionIconSize: 8, sectionIconSize: 8,
headerRow: toggleable(interactive({ headerRow: toggleable(
base: { interactive({
...text(layer, "mono", { size: "sm" }), base: {
margin: { top: 14 }, ...text(layer, "mono", { size: "sm" }),
padding: { margin: { top: 14 },
left: sidePadding, padding: {
right: sidePadding, left: sidePadding,
right: sidePadding,
},
background: background(layer, "default"), // posiewic: breaking change
}, },
background: background(layer, "default"),// posiewic: breaking change state: {
} hovered: { background: background(layer, "default") },
, 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. }, // hack, we want headerRow to be interactive for whatever reason. It probably shouldn't be interactive in the first place.
}), }),
{ {
default: { default: {
...text(layer, "mono", "active", { size: "sm" }), ...text(layer, "mono", "active", { size: "sm" }),
background: background(layer, "active"), background: background(layer, "active"),
}, },
}), }
),
leaveCall: interactive({ leaveCall: interactive({
base: { base: {
background: background(layer), background: background(layer),
@ -105,24 +109,22 @@ export default function contactsPanel(colorScheme: ColorScheme) {
right: 7, right: 7,
}, },
...text(layer, "sans", "variant", { size: "xs" }), ...text(layer, "sans", "variant", { size: "xs" }),
} },
,
state: { state: {
hovered: { hovered: {
...text(layer, "sans", "hovered", { size: "xs" }), ...text(layer, "sans", "hovered", { size: "xs" }),
background: background(layer, "hovered"), background: background(layer, "hovered"),
border: border(layer, "hovered"), border: border(layer, "hovered"),
} },
} },
} }),
),
contactRow: { contactRow: {
inactive: { inactive: {
default: { default: {
padding: { padding: {
left: sidePadding, left: sidePadding,
right: sidePadding, right: sidePadding,
} },
}, },
}, },
active: { active: {
@ -131,8 +133,8 @@ export default function contactsPanel(colorScheme: ColorScheme) {
padding: { padding: {
left: sidePadding, left: sidePadding,
right: sidePadding, right: sidePadding,
} },
} },
}, },
}, },
@ -165,7 +167,7 @@ export default function contactsPanel(colorScheme: ColorScheme) {
hovered: { hovered: {
background: background(layer, "hovered"), background: background(layer, "hovered"),
}, },
} },
}), }),
disabledButton: { disabledButton: {
...contactButton, ...contactButton,
@ -175,44 +177,48 @@ export default function contactsPanel(colorScheme: ColorScheme) {
callingIndicator: { callingIndicator: {
...text(layer, "mono", "variant", { size: "xs" }), ...text(layer, "mono", "variant", { size: "xs" }),
}, },
treeBranch: toggleable(interactive({ treeBranch: toggleable(
base: { interactive({
color: borderColor(layer), base: {
width: 1,
},
state: {
hovered: {
color: borderColor(layer), color: borderColor(layer),
width: 1,
}, },
} state: {
}), hovered: {
color: borderColor(layer),
},
},
}),
{ {
default: { default: {
color: borderColor(layer), color: borderColor(layer),
}, },
} }
), ),
projectRow: toggleable(interactive({ projectRow: toggleable(
base: { interactive({
...projectRow, base: {
background: background(layer), ...projectRow,
icon: { background: background(layer),
margin: { left: nameMargin }, icon: {
color: foreground(layer, "variant"), margin: { left: nameMargin },
width: 12, color: foreground(layer, "variant"),
width: 12,
},
name: {
...projectRow.name,
...text(layer, "mono", { size: "sm" }),
},
}, },
name: { state: {
...projectRow.name, hovered: {
...text(layer, "mono", { size: "sm" }), background: background(layer, "hovered"),
},
}, },
}, state: { }),
hovered: {
background: background(layer, "hovered"),
},
}
}),
{ {
default: { background: background(layer, "active") } default: { background: background(layer, "active") },
}) }
),
} }
} }

View File

@ -21,22 +21,21 @@ export default function contactNotification(colorScheme: ColorScheme): Object {
...text(layer, "sans", { size: "xs" }), ...text(layer, "sans", { size: "xs" }),
margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 }, margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 },
}, },
button: button: interactive({
interactive({ base: {
base: { ...text(layer, "sans", "on", { size: "xs" }),
...text(layer, "sans", "on", { size: "xs" }), background: background(layer, "on"),
background: background(layer, "on"), padding: 4,
padding: 4, cornerRadius: 6,
cornerRadius: 6, margin: { left: 6 },
margin: { left: 6 } },
},
state: { state: {
hovered: { hovered: {
background: background(layer, "on", "hovered"), background: background(layer, "on", "hovered"),
} },
} },
}), }),
dismissButton: { dismissButton: {
default: { default: {
@ -48,7 +47,7 @@ export default function contactNotification(colorScheme: ColorScheme): Object {
hover: { hover: {
color: foreground(layer, "hovered"), color: foreground(layer, "hovered"),
}, },
} },
}, },
} }
} }

View File

@ -12,41 +12,45 @@ export default function contextMenu(colorScheme: ColorScheme) {
shadow: colorScheme.popoverShadow, shadow: colorScheme.popoverShadow,
border: border(layer), border: border(layer),
keystrokeMargin: 30, keystrokeMargin: 30,
item: toggleable(interactive({ item: toggleable(
base: { interactive({
iconSpacing: 8, base: {
iconWidth: 14, iconSpacing: 8,
padding: { left: 6, right: 6, top: 2, bottom: 2 }, iconWidth: 14,
cornerRadius: 6, padding: { left: 6, right: 6, top: 2, bottom: 2 },
label: text(layer, "sans", { size: "sm" }), cornerRadius: 6,
keystroke: { label: text(layer, "sans", { size: "sm" }),
...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: { keystroke: {
...text(layer, "sans", "hovered", { ...text(layer, "sans", "variant", {
size: "sm", size: "sm",
weight: "bold", weight: "bold",
}), }),
padding: { left: 3, right: 3 }, 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"),
},
} }
}), { ),
default: {
background: background(layer, "active"),
},
hovered: {
background: background(layer, "active"),
},
}),
separator: { separator: {
background: borderColor(layer), background: borderColor(layer),

View File

@ -25,7 +25,7 @@ export default function copilot(colorScheme: ColorScheme) {
left: 7, left: 7,
right: 7, right: 7,
}, },
...text(layer, "sans", "default", { size: "sm" }) ...text(layer, "sans", "default", { size: "sm" }),
}, },
state: { state: {
hovered: { hovered: {
@ -33,39 +33,37 @@ export default function copilot(colorScheme: ColorScheme) {
background: background(layer, "hovered"), background: background(layer, "hovered"),
border: border(layer, "active"), border: border(layer, "active"),
}, },
} },
}); })
return { return {
outLinkIcon: outLinkIcon: interactive({
interactive({ base: {
base: { icon: svg(
icon: svg( foreground(layer, "variant"),
foreground(layer, "variant"), "icons/link_out_12.svg",
"icons/link_out_12.svg", 12,
12, 12
12 ),
), container: {
container: { cornerRadius: 6,
cornerRadius: 6, padding: { left: 6 },
padding: { left: 6 }, },
},
state: {
hovered: {
icon: {
color: foreground(layer, "hovered"),
}, },
}, },
state: { },
hovered: { }),
icon: {
color:
foreground(layer, "hovered")
}
},
}
}),
modal: { modal: {
titleText: { titleText: {
default: { default: {
...text(layer, "sans", { size: "xs", weight: "bold" }) ...text(layer, "sans", { size: "xs", weight: "bold" }),
} },
}, },
titlebar: { titlebar: {
background: background(colorScheme.lowest), background: background(colorScheme.lowest),
@ -87,8 +85,7 @@ export default function copilot(colorScheme: ColorScheme) {
}, },
}, },
closeIcon: interactive({ closeIcon: interactive({
base: base: {
{
icon: svg( icon: svg(
foreground(layer, "variant"), foreground(layer, "variant"),
"icons/x_mark_8.svg", "icons/x_mark_8.svg",
@ -106,7 +103,7 @@ export default function copilot(colorScheme: ColorScheme) {
margin: { margin: {
right: 0, right: 0,
}, },
} },
}, },
state: { state: {
hovered: { hovered: {
@ -125,7 +122,7 @@ export default function copilot(colorScheme: ColorScheme) {
8 8
), ),
}, },
} },
}), }),
dimensions: { dimensions: {
width: 280, width: 280,
@ -214,8 +211,9 @@ export default function copilot(colorScheme: ColorScheme) {
bottom: 5, bottom: 5,
left: 8, left: 8,
right: 0, right: 0,
} },
}, state: { },
state: {
hovered: { hovered: {
border: border(layer, "active", { border: border(layer, "active", {
bottom: false, bottom: false,
@ -224,8 +222,8 @@ export default function copilot(colorScheme: ColorScheme) {
left: true, left: true,
}), }),
}, },
} },
}) }),
}, },
}, },

View File

@ -50,23 +50,26 @@ export default function editor(colorScheme: ColorScheme) {
// Inline autocomplete suggestions, Co-pilot suggestions, etc. // Inline autocomplete suggestions, Co-pilot suggestions, etc.
suggestion: syntax.predictive, suggestion: syntax.predictive,
codeActions: { codeActions: {
indicator: toggleable(interactive({ indicator: toggleable(
base: { interactive({
color: foreground(layer, "variant"), base: {
}, state: { color: foreground(layer, "variant"),
clicked: {
color: foreground(layer, "base"),
}, },
hovered: { state: {
color: foreground(layer, "on"), clicked: {
color: foreground(layer, "base"),
},
hovered: {
color: foreground(layer, "on"),
},
}, },
} }),
}),
{ {
default: { default: {
color: foreground(layer, "on"), color: foreground(layer, "on"),
} },
}), }
),
verticalScale: 0.55, verticalScale: 0.55,
}, },
@ -74,29 +77,34 @@ export default function editor(colorScheme: ColorScheme) {
iconMarginScale: 2.5, iconMarginScale: 2.5,
foldedIcon: "icons/chevron_right_8.svg", foldedIcon: "icons/chevron_right_8.svg",
foldableIcon: "icons/chevron_down_8.svg", foldableIcon: "icons/chevron_down_8.svg",
indicator: toggleable(interactive({ indicator: toggleable(
base: { interactive({
color: foreground(layer, "variant"), base: {
}, state: { color: foreground(layer, "variant"),
clicked: {
color: foreground(layer, "base"),
}, },
hovered: { state: {
color: foreground(layer, "on"), clicked: {
color: foreground(layer, "base"),
},
hovered: {
color: foreground(layer, "on"),
},
}, },
} }),
}),
{ {
default: { default: {
color: foreground(layer, "on"), color: foreground(layer, "on"),
} },
}), }
),
ellipses: { ellipses: {
textColor: colorScheme.ramps.neutral(0.71).hex(), textColor: colorScheme.ramps.neutral(0.71).hex(),
cornerRadiusFactor: 0.15, cornerRadiusFactor: 0.15,
background: { background: {
// Copied from hover_popover highlight // Copied from hover_popover highlight
default: { color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex() }, default: {
color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex(),
},
hover: { hover: {
color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(), color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(),
@ -245,12 +253,13 @@ export default function editor(colorScheme: ColorScheme) {
bottom: 6, bottom: 6,
left: 6, left: 6,
right: 6, right: 6,
} },
}, state: { },
state: {
hovered: { hovered: {
background: background(layer, "on", "hovered"), background: background(layer, "on", "hovered"),
} },
} },
}), }),
scrollbar: { scrollbar: {

View File

@ -20,8 +20,9 @@ export default function feedback(colorScheme: ColorScheme) {
left: 10, left: 10,
right: 10, right: 10,
top: 2, top: 2,
} },
}, state: { },
state: {
clicked: { clicked: {
...text(layer, "mono", "on", "pressed"), ...text(layer, "mono", "on", "pressed"),
background: background(layer, "on", "pressed"), background: background(layer, "on", "pressed"),
@ -32,7 +33,7 @@ export default function feedback(colorScheme: ColorScheme) {
background: background(layer, "on", "hovered"), background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"), border: border(layer, "on", "hovered"),
}, },
} },
}), }),
button_margin: 8, button_margin: 8,
info_text_default: text(layer, "sans", "default", { size: "xs" }), info_text_default: text(layer, "sans", "default", { size: "xs" }),

View File

@ -40,29 +40,35 @@ export default function picker(colorScheme: ColorScheme): any {
...container, ...container,
padding: {}, padding: {},
}, },
item: toggleable(interactive({ item: toggleable(
base: { interactive({
padding: { base: {
bottom: 4, padding: {
left: 12, bottom: 4,
right: 12, left: 12,
top: 4, 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",
}),
}, },
margin: { state: {
top: 1, hovered: {
left: 4, background: withOpacity(
right: 4, background(layer, "hovered"),
0.5
),
},
}, },
cornerRadius: 8, }),
text: text(layer, "sans", "variant"),
highlightText: text(layer, "sans", "accent", { weight: "bold" }),
}
, state: {
hovered: {
background: withOpacity(background(layer, "hovered"), 0.5),
}
}
}),
{ {
default: { default: {
background: withOpacity( background: withOpacity(
@ -70,9 +76,9 @@ export default function picker(colorScheme: ColorScheme): any {
0.5 0.5
), ),
//text: text(layer, "sans", "base", "active"), //text: text(layer, "sans", "base", "active"),
} },
}), }
),
inputEditor, inputEditor,
emptyInputEditor, emptyInputEditor,

View File

@ -29,18 +29,19 @@ export default function projectPanel(colorScheme: ColorScheme) {
}, },
} }
let entry = toggleable(interactive({ let entry = toggleable(
base: { interactive({
...baseEntry, base: {
text: text(layer, "mono", "variant", { size: "sm" }), ...baseEntry,
status, text: text(layer, "mono", "variant", { size: "sm" }),
}, state: status,
{ },
hovered: { state: {
background: background(layer, "variant", "hovered"), hovered: {
} background: background(layer, "variant", "hovered"),
} },
}), },
}),
{ {
default: { default: {
/*background: colorScheme.isLight /*background: colorScheme.isLight
@ -52,8 +53,8 @@ export default function projectPanel(colorScheme: ColorScheme) {
//background: background(layer, "active"), //background: background(layer, "active"),
text: text(layer, "mono", "active", { size: "sm" }), text: text(layer, "mono", "active", { size: "sm" }),
}, },
}
}); )
return { return {
openProjectButton: interactive({ openProjectButton: interactive({
@ -72,14 +73,15 @@ export default function projectPanel(colorScheme: ColorScheme) {
left: 7, left: 7,
right: 7, right: 7,
}, },
...text(layer, "sans", "default", { size: "sm" }) ...text(layer, "sans", "default", { size: "sm" }),
}, state: { },
state: {
hovered: { hovered: {
...text(layer, "sans", "default", { size: "sm" }), ...text(layer, "sans", "default", { size: "sm" }),
background: background(layer, "hovered"), background: background(layer, "hovered"),
border: border(layer, "active"), border: border(layer, "active"),
}, },
} },
}), }),
background: background(layer), background: background(layer),
padding: { left: 6, right: 6, top: 0, bottom: 6 }, padding: { left: 6, right: 6, top: 0, bottom: 6 },
@ -111,7 +113,6 @@ export default function projectPanel(colorScheme: ColorScheme) {
background: background(layer, "active"), background: background(layer, "active"),
text: text(layer, "mono", "disabled", { size: "sm" }), text: text(layer, "mono", "disabled", { size: "sm" }),
}, },
}, },
}, },
filenameEditor: { filenameEditor: {

View File

@ -37,41 +37,44 @@ export default function search(colorScheme: ColorScheme) {
return { return {
// TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive // TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
matchBackground: withOpacity(foreground(layer, "accent"), 0.4), matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
optionButton: toggleable(interactive({ optionButton: toggleable(
base: { interactive({
...text(layer, "mono", "on"), base: {
background: background(layer, "on"), ...text(layer, "mono", "on"),
cornerRadius: 6, background: background(layer, "on"),
border: border(layer, "on"), cornerRadius: 6,
margin: { border: border(layer, "on"),
right: 4, margin: {
right: 4,
},
padding: {
bottom: 2,
left: 10,
right: 10,
top: 2,
},
}, },
padding: { state: {
bottom: 2, clicked: {
left: 10, ...text(layer, "mono", "on", "pressed"),
right: 10, background: background(layer, "on", "pressed"),
top: 2, border: border(layer, "on", "pressed"),
},
hovered: {
...text(layer, "mono", "on", "hovered"),
background: background(layer, "on", "hovered"),
border: border(layer, "on", "hovered"),
},
}, },
}, state: { }),
clicked: { {
...text(layer, "mono", "on", "pressed"), default: {
background: background(layer, "on", "pressed"), ...text(layer, "mono", "on", "inverted"),
border: border(layer, "on", "pressed"), background: background(layer, "on", "inverted"),
}, border: border(layer, "on", "inverted"),
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, editor,
invalidEditor: { invalidEditor: {
...editor, ...editor,
@ -113,11 +116,12 @@ export default function search(colorScheme: ColorScheme) {
left: 10, left: 10,
right: 10, right: 10,
}, },
}, state: { },
state: {
hovered: { hovered: {
color: foreground(layer, "hovered"), color: foreground(layer, "hovered"),
} },
} },
}), }),
} }
} }

View File

@ -26,13 +26,14 @@ export default function simpleMessageNotification(
}, },
margin: { left: headerPadding, top: 6, bottom: 6 }, margin: { left: headerPadding, top: 6, bottom: 6 },
}, state: { },
state: {
hovered: { hovered: {
...text(layer, "sans", "default", { size: "xs" }), ...text(layer, "sans", "default", { size: "xs" }),
background: background(layer, "hovered"), background: background(layer, "hovered"),
border: border(layer, "active"), border: border(layer, "active"),
}, },
} },
}), }),
dismissButton: interactive({ dismissButton: interactive({
base: { base: {
@ -41,11 +42,12 @@ export default function simpleMessageNotification(
iconHeight: 8, iconHeight: 8,
buttonWidth: 8, buttonWidth: 8,
buttonHeight: 8, buttonHeight: 8,
}, state: { },
state: {
hovered: { hovered: {
color: foreground(layer, "hovered"), color: foreground(layer, "hovered"),
}, },
} },
}) }),
} }
} }

View File

@ -29,15 +29,14 @@ export default function statusBar(colorScheme: ColorScheme) {
activeLanguage: interactive({ activeLanguage: interactive({
base: { base: {
padding: { left: 6, right: 6 }, padding: { left: 6, right: 6 },
...text(layer, "sans", "variant") ...text(layer, "sans", "variant"),
}, },
state: { state: {
hovered: { hovered: {
...text(layer, "sans", "on"), ...text(layer, "sans", "on"),
} },
} },
}, }),
),
autoUpdateProgressMessage: text(layer, "sans", "variant"), autoUpdateProgressMessage: text(layer, "sans", "variant"),
autoUpdateDoneMessage: text(layer, "sans", "variant"), autoUpdateDoneMessage: text(layer, "sans", "variant"),
lspStatus: interactive({ lspStatus: interactive({
@ -47,92 +46,93 @@ export default function statusBar(colorScheme: ColorScheme) {
iconWidth: 14, iconWidth: 14,
height: 18, height: 18,
message: text(layer, "sans"), message: text(layer, "sans"),
iconColor: foreground(layer) iconColor: foreground(layer),
}, },
state: { state: {
hovered: { hovered: {
message: text(layer, "sans"), message: text(layer, "sans"),
iconColor: foreground(layer), iconColor: foreground(layer),
background: background(layer, "hovered"), background: background(layer, "hovered"),
} },
} },
}), }),
diagnosticMessage: interactive({ diagnosticMessage: interactive({
base: { base: {
...text(layer, "sans") ...text(layer, "sans"),
}, },
state: { hovered: text(layer, "sans", "hovered") } state: { hovered: text(layer, "sans", "hovered") },
}, }),
), diagnosticSummary: interactive({
diagnosticSummary: base: {
interactive({ height: 20,
base: { iconWidth: 16,
height: 20, iconSpacing: 2,
iconWidth: 16, summarySpacing: 6,
iconSpacing: 2, text: text(layer, "sans", { size: "sm" }),
summarySpacing: 6, iconColorOk: foreground(layer, "variant"),
text: text(layer, "sans", { size: "sm" }), iconColorWarning: foreground(layer, "warning"),
iconColorOk: foreground(layer, "variant"), iconColorError: foreground(layer, "negative"),
iconColorWarning: foreground(layer, "warning"), containerOk: {
iconColorError: foreground(layer, "negative"), 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: { containerOk: {
cornerRadius: 6, background: background(layer, "on", "hovered"),
padding: { top: 3, bottom: 3, left: 7, right: 7 },
}, },
containerWarning: { containerWarning: {
...diagnosticStatusContainer, background: background(layer, "warning", "hovered"),
background: background(layer, "warning"), border: border(layer, "warning", "hovered"),
border: border(layer, "warning"),
}, },
containerError: { containerError: {
...diagnosticStatusContainer, background: background(layer, "negative", "hovered"),
background: background(layer, "negative"), border: border(layer, "negative", "hovered"),
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: { panelButtons: {
groupLeft: {}, groupLeft: {},
groupBottom: {}, groupBottom: {},
groupRight: {}, groupRight: {},
button: toggleable(interactive({ button: toggleable(
base: { interactive({
...statusContainer, base: {
iconSize: 16, ...statusContainer,
iconColor: foreground(layer, "variant"), iconSize: 16,
label: { iconColor: foreground(layer, "variant"),
margin: { left: 6 }, label: {
...text(layer, "sans", { size: "sm" }), margin: { left: 6 },
...text(layer, "sans", { size: "sm" }),
},
}, },
}, state: { state: {
hovered: { hovered: {
iconColor: foreground(layer, "hovered"), iconColor: foreground(layer, "hovered"),
background: background(layer, "variant"), background: background(layer, "variant"),
} },
} },
}), }),
{ {
default: { default: {
iconColor: foreground(layer, "active"), iconColor: foreground(layer, "active"),
background: background(layer, "active"), background: background(layer, "active"),
} },
}), }
),
badge: { badge: {
cornerRadius: 3, cornerRadius: 3,
padding: 2, padding: 2,

View File

@ -89,23 +89,24 @@ export default function tabBar(colorScheme: ColorScheme) {
inactiveTab: inactivePaneInactiveTab, inactiveTab: inactivePaneInactiveTab,
}, },
draggedTab, draggedTab,
paneButton: toggleable(interactive({ paneButton: toggleable(
base: { interactive({
color: foreground(layer, "variant"), base: {
iconWidth: 12, color: foreground(layer, "variant"),
buttonWidth: activePaneActiveTab.height, iconWidth: 12,
}, buttonWidth: activePaneActiveTab.height,
state: { },
hovered: { state: {
color: foreground(layer, "hovered"), hovered: {
} color: foreground(layer, "hovered"),
} },
}), },
}),
{ {
default: { default: {
color: foreground(layer, "accent"), color: foreground(layer, "accent"),
} },
}, }
), ),
paneButtonContainer: { paneButtonContainer: {
background: tab.background, background: tab.background,

View File

@ -1,41 +1,47 @@
import { DeepPartial } from 'utility-types'; import merge from "ts-deepmerge"
import merge from 'ts-deepmerge';
interface Toggleable<T> { type ToggleState = "inactive" | "active"
inactive: T
active: T, type Toggleable<T> = Record<ToggleState, T>
const NO_INACTIVE_OR_BASE_ERROR =
"A toggleable object must have an inactive state, or a base property."
const NO_ACTIVE_ERROR = "A toggleable object must have an active state."
interface ToggleableProps<T> {
base?: T
state: Partial<Record<ToggleState, T>>
} }
/** /**
* Helper function for creating Toggleable objects. * Helper function for creating Toggleable objects.
* @template T The type of the object being toggled. * @template T The type of the object being toggled.
* @param inactive The initial state of the toggleable object. * @param props Object containing the base (inactive) state and state modifications to create the active state.
* @param modifications The modifications to be applied to the initial state to create the active state.
* @returns A Toggleable object containing both the inactive and active states. * @returns A Toggleable object containing both the inactive and active states.
* @example * @example
* ``` * ```
* toggleable({day: 1, month: "January"}, {day: 3}) * toggleable({
* ``` * base: { background: "#000000", text: "#CCCCCC" },
* This returns the following object: * state: { active: { text: "#CCCCCC" } },
* ``` * })
* Toggleable<_>{
* inactive: { day: 1, month: "January" },
* active: { day: 3, month: "January" }
* }
* ```
* The function also works for nested structures:
* ```
* toggleable({first_level: "foo", second_level: {nested_member: "nested"}}, {second_level: {nested_member: "another nested thing"}})
* ```
* Which returns:
* ```
* Toggleable<_> {
* inactive: {first_level: "foo", second_level: {nested_member: "nested"}},
* active: { first_level: "foo", second_level: {nested_member: "another nested thing"}}
* }
* ``` * ```
*/ */
export function toggleable<T extends Object>(inactive: T, modifications: DeepPartial<T>): Toggleable<T> { export function toggleable<T extends object>(
let active: T = merge(inactive, modifications) as T; props: ToggleableProps<T>
return { active: active, inactive: inactive }; ): Toggleable<T> {
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)
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
} }

View File

@ -13,44 +13,50 @@ export default function dropdownMenu(colorScheme: ColorScheme) {
header: interactive({ header: interactive({
base: { base: {
...text(layer, "sans", { size: "sm" }), ...text(layer, "sans", { size: "sm" }),
secondaryText: text(layer, "sans", { size: "sm", color: "#aaaaaa" }), secondaryText: text(layer, "sans", {
size: "sm",
color: "#aaaaaa",
}),
secondaryTextSpacing: 10, secondaryTextSpacing: 10,
padding: { left: 8, right: 8, top: 2, bottom: 2 }, padding: { left: 8, right: 8, top: 2, bottom: 2 },
cornerRadius: 6, cornerRadius: 6,
background: background(layer, "on"), background: background(layer, "on"),
border: border(layer, "on", { overlay: true }) border: border(layer, "on", { overlay: true }),
}, },
state: { state: {
hovered: { hovered: {
background: background(layer, "hovered"), background: background(layer, "hovered"),
...text(layer, "sans", "hovered", { size: "sm" }), ...text(layer, "sans", "hovered", { size: "sm" }),
} },
} },
}) }),
,
sectionHeader: { sectionHeader: {
...text(layer, "sans", { size: "sm" }), ...text(layer, "sans", { size: "sm" }),
padding: { left: 8, right: 8, top: 8, bottom: 8 }, padding: { left: 8, right: 8, top: 8, bottom: 8 },
}, },
item: toggleable(interactive({ item: toggleable(
base: { interactive({
...text(layer, "sans", { size: "sm" }), base: {
secondaryTextSpacing: 10, ...text(layer, "sans", { size: "sm" }),
secondaryText: text(layer, "sans", { size: "sm" }), secondaryTextSpacing: 10,
padding: { left: 18, right: 18, top: 2, bottom: 2 } secondaryText: text(layer, "sans", { size: "sm" }),
}, state: { 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: { hovered: {
background: background(layer, "hovered"), background: background(layer, "active"),
...text(layer, "sans", "hovered", { size: "sm" }), },
}
} }
}), { ),
default: {
background: background(layer, "active"),
},
hovered: {
background: background(layer, "active"),
},
})
} }
} }

View File

@ -14,12 +14,13 @@ export default function updateNotification(colorScheme: ColorScheme): Object {
actionMessage: interactive({ actionMessage: interactive({
base: { base: {
...text(layer, "sans", { size: "xs" }), ...text(layer, "sans", { size: "xs" }),
margin: { left: headerPadding, top: 6, bottom: 6 } margin: { left: headerPadding, top: 6, bottom: 6 },
}, state: { },
state: {
hovered: { hovered: {
color: foreground(layer, "hovered"), color: foreground(layer, "hovered"),
} },
} },
}), }),
dismissButton: interactive({ dismissButton: interactive({
base: { base: {
@ -27,13 +28,13 @@ export default function updateNotification(colorScheme: ColorScheme): Object {
iconWidth: 8, iconWidth: 8,
iconHeight: 8, iconHeight: 8,
buttonWidth: 8, buttonWidth: 8,
buttonHeight: 8 buttonHeight: 8,
}, state: { },
state: {
hovered: { hovered: {
color: foreground(layer, "hovered"), color: foreground(layer, "hovered"),
}, },
}, },
}) }),
} }
} }

View File

@ -79,13 +79,14 @@ export default function welcome(colorScheme: ColorScheme) {
left: 7, left: 7,
right: 7, right: 7,
}, },
...text(layer, "sans", "default", interactive_text_size) ...text(layer, "sans", "default", interactive_text_size),
}, state: { },
state: {
hovered: { hovered: {
...text(layer, "sans", "default", interactive_text_size), ...text(layer, "sans", "default", interactive_text_size),
background: background(layer, "hovered"), background: background(layer, "hovered"),
} },
} },
}), }),
usageNote: { usageNote: {

View File

@ -12,44 +12,50 @@ import {
import statusBar from "./statusBar" import statusBar from "./statusBar"
import tabBar from "./tabBar" import tabBar from "./tabBar"
import { interactive } from "../element" import { interactive } from "../element"
import merge from 'ts-deepmerge'; import merge from "ts-deepmerge"
export default function workspace(colorScheme: ColorScheme) { export default function workspace(colorScheme: ColorScheme) {
const layer = colorScheme.lowest const layer = colorScheme.lowest
const isLight = colorScheme.isLight const isLight = colorScheme.isLight
const itemSpacing = 8 const itemSpacing = 8
const titlebarButton = toggleable(interactive({ const titlebarButton = toggleable(
base: { interactive({
cornerRadius: 6, base: {
padding: { cornerRadius: 6,
top: 1, padding: {
bottom: 1, top: 1,
left: 8, bottom: 1,
right: 8, left: 8,
right: 8,
},
...text(layer, "sans", "variant", { size: "xs" }),
background: background(layer, "variant"),
border: border(layer),
}, },
...text(layer, "sans", "variant", { size: "xs" }), state: {
background: background(layer, "variant"), hovered: {
border: border(layer), ...text(layer, "sans", "variant", "hovered", {
}, state: { size: "xs",
hovered: { }),
...text(layer, "sans", "variant", "hovered", { size: "xs" }), background: background(layer, "variant", "hovered"),
background: background(layer, "variant", "hovered"), border: border(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"),
},
}, },
clicked: { }),
...text(layer, "sans", "variant", "pressed", { size: "xs" }),
background: background(layer, "variant", "pressed"),
border: border(layer, "variant", "pressed"),
}
}
}),
{ {
default: { default: {
...text(layer, "sans", "variant", "active", { size: "xs" }), ...text(layer, "sans", "variant", "active", { size: "xs" }),
background: background(layer, "variant", "active"), background: background(layer, "variant", "active"),
border: border(layer, "variant", "active"), border: border(layer, "variant", "active"),
} },
}, }
); )
const avatarWidth = 18 const avatarWidth = 18
const avatarOuterWidth = avatarWidth + 4 const avatarOuterWidth = avatarWidth + 4
const followerAvatarWidth = 14 const followerAvatarWidth = 14
@ -86,23 +92,23 @@ export default function workspace(colorScheme: ColorScheme) {
}, },
cornerRadius: 4, cornerRadius: 4,
}, },
keyboardHint: keyboardHint: interactive({
interactive({ base: {
base: { ...text(layer, "sans", "variant", { size: "sm" }),
...text(layer, "sans", "variant", { size: "sm" }), padding: {
padding: { top: 3,
top: 3, left: 8,
left: 8, right: 8,
right: 8, bottom: 3,
bottom: 3, },
}, cornerRadius: 8,
cornerRadius: 8 },
}, state: { state: {
hovered: { hovered: {
...text(layer, "sans", "active", { size: "sm" }), ...text(layer, "sans", "active", { size: "sm" }),
} },
} },
}), }),
keyboardHintWidth: 320, keyboardHintWidth: 320,
}, },
@ -214,18 +220,15 @@ export default function workspace(colorScheme: ColorScheme) {
// Sign in buttom // Sign in buttom
// FlatButton, Variant // FlatButton, Variant
signInPrompt: signInPrompt: merge(titlebarButton, {
merge(titlebarButton, inactive: {
{ default: {
inactive: { margin: {
default: { left: itemSpacing,
margin: { },
left: itemSpacing, },
}, },
} }),
}
}),
// Offline Indicator // Offline Indicator
offlineIcon: { offlineIcon: {
@ -259,54 +262,57 @@ export default function workspace(colorScheme: ColorScheme) {
color: foreground(layer, "variant"), color: foreground(layer, "variant"),
iconWidth: 12, iconWidth: 12,
buttonWidth: 20, 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: { state: {
clicked: {
background: background(layer, "variant", "pressed"),
color: foreground(layer, "variant", "pressed"),
},
hovered: { hovered: {
background: background(layer, "variant", "hovered"), background: background(layer, "variant", "hovered"),
color: foreground(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: { default: {
background: background(layer, "variant", "active"), background: background(layer, "variant", "active"),
color: foreground(layer, "variant", "active") color: foreground(layer, "variant", "active"),
} },
}, }
), ),
userMenuButton: merge(titlebarButton, { userMenuButton: merge(titlebarButton, {
inactive: { inactive: {
default: { default: {
buttonWidth: 20, buttonWidth: 20,
iconWidth: 12 iconWidth: 12,
} },
}, active: { // posiewic: these properties are not currently set on main },
active: {
// posiewic: these properties are not currently set on main
default: { default: {
iconWidth: 12, iconWidth: 12,
button_width: 20, button_width: 20,
} },
} },
}), }),
toggleContactsBadge: { toggleContactsBadge: {
cornerRadius: 3, cornerRadius: 3,
padding: 2, padding: 2,
@ -324,27 +330,31 @@ export default function workspace(colorScheme: ColorScheme) {
background: background(colorScheme.highest), background: background(colorScheme.highest),
border: border(colorScheme.highest, { bottom: true }), border: border(colorScheme.highest, { bottom: true }),
itemSpacing: 8, itemSpacing: 8,
navButton: interactive( navButton: interactive({
{ base: {
base: { color: foreground(colorScheme.highest, "on"),
color: foreground(colorScheme.highest, "on"), iconWidth: 12,
iconWidth: 12, buttonWidth: 24,
buttonWidth: 24, cornerRadius: 6,
cornerRadius: 6, },
}, state: { state: {
hovered: { hovered: {
color: foreground(colorScheme.highest, "on", "hovered"), color: foreground(colorScheme.highest, "on", "hovered"),
background: background( background: background(
colorScheme.highest, colorScheme.highest,
"on", "on",
"hovered" "hovered"
), ),
}, },
disabled: { disabled: {
color: foreground(colorScheme.highest, "on", "disabled"), color: foreground(
}, colorScheme.highest,
} "on",
}), "disabled"
),
},
},
}),
padding: { left: 8, right: 8, top: 4, bottom: 4 }, padding: { left: 8, right: 8, top: 4, bottom: 4 },
}, },
breadcrumbHeight: 24, breadcrumbHeight: 24,
@ -355,13 +365,18 @@ export default function workspace(colorScheme: ColorScheme) {
padding: { padding: {
left: 6, left: 6,
right: 6, right: 6,
} },
}, state: { },
state: {
hovered: { hovered: {
color: foreground(colorScheme.highest, "on", "hovered"), color: foreground(colorScheme.highest, "on", "hovered"),
background: background(colorScheme.highest, "on", "hovered"), background: background(
colorScheme.highest,
"on",
"hovered"
),
}, },
} },
}), }),
disconnectedOverlay: { disconnectedOverlay: {
...text(layer, "sans"), ...text(layer, "sans"),

View File

@ -1,9 +1,19 @@
import { SingleBoxShadowToken, SingleColorToken, SingleOtherToken, TokenTypes } from "@tokens-studio/types" import {
import { ColorScheme, Shadow, SyntaxHighlightStyle, ThemeSyntax } from "../colorScheme" SingleBoxShadowToken,
SingleColorToken,
SingleOtherToken,
TokenTypes,
} from "@tokens-studio/types"
import {
ColorScheme,
Shadow,
SyntaxHighlightStyle,
ThemeSyntax,
} from "../colorScheme"
import { LayerToken, layerToken } from "./layer" import { LayerToken, layerToken } from "./layer"
import { PlayersToken, playersToken } from "./players" import { PlayersToken, playersToken } from "./players"
import { colorToken } from "./token" import { colorToken } from "./token"
import { Syntax } from "../syntax"; import { Syntax } from "../syntax"
import editor from "../../styleTree/editor" import editor from "../../styleTree/editor"
interface ColorSchemeTokens { interface ColorSchemeTokens {
@ -18,27 +28,32 @@ interface ColorSchemeTokens {
syntax?: Partial<ThemeSyntaxColorTokens> syntax?: Partial<ThemeSyntaxColorTokens>
} }
const createShadowToken = (shadow: Shadow, tokenName: string): SingleBoxShadowToken => { const createShadowToken = (
shadow: Shadow,
tokenName: string
): SingleBoxShadowToken => {
return { return {
name: tokenName, name: tokenName,
type: TokenTypes.BOX_SHADOW, type: TokenTypes.BOX_SHADOW,
value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}` value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}`,
}; }
}; }
const popoverShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => { const popoverShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
const shadow = colorScheme.popoverShadow; const shadow = colorScheme.popoverShadow
return createShadowToken(shadow, "popoverShadow"); return createShadowToken(shadow, "popoverShadow")
}; }
const modalShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => { const modalShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
const shadow = colorScheme.modalShadow; const shadow = colorScheme.modalShadow
return createShadowToken(shadow, "modalShadow"); return createShadowToken(shadow, "modalShadow")
}; }
type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken> type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
function syntaxHighlightStyleColorTokens(syntax: Syntax): ThemeSyntaxColorTokens { function syntaxHighlightStyleColorTokens(
syntax: Syntax
): ThemeSyntaxColorTokens {
const styleKeys = Object.keys(syntax) as (keyof Syntax)[] const styleKeys = Object.keys(syntax) as (keyof Syntax)[]
return styleKeys.reduce((acc, styleKey) => { return styleKeys.reduce((acc, styleKey) => {
@ -46,13 +61,16 @@ function syntaxHighlightStyleColorTokens(syntax: Syntax): ThemeSyntaxColorTokens
// This can happen because we have a "constructor" property on the syntax object // This can happen because we have a "constructor" property on the syntax object
// and a "constructor" property on the prototype of the syntax object // and a "constructor" property on the prototype of the syntax object
// To work around this just assert that the type of the style is not a function // To work around this just assert that the type of the style is not a function
if (!syntax[styleKey] || typeof syntax[styleKey] === 'function') return acc; if (!syntax[styleKey] || typeof syntax[styleKey] === "function")
const { color } = syntax[styleKey] as Required<SyntaxHighlightStyle>; return acc
return { ...acc, [styleKey]: colorToken(styleKey, color) }; const { color } = syntax[styleKey] as Required<SyntaxHighlightStyle>
}, {} as ThemeSyntaxColorTokens); return { ...acc, [styleKey]: colorToken(styleKey, color) }
}, {} as ThemeSyntaxColorTokens)
} }
const syntaxTokens = (colorScheme: ColorScheme): ColorSchemeTokens['syntax'] => { const syntaxTokens = (
colorScheme: ColorScheme
): ColorSchemeTokens["syntax"] => {
const syntax = editor(colorScheme).syntax const syntax = editor(colorScheme).syntax
return syntaxHighlightStyleColorTokens(syntax) return syntaxHighlightStyleColorTokens(syntax)

View File

@ -1,11 +1,11 @@
import { SingleColorToken } from "@tokens-studio/types"; import { SingleColorToken } from "@tokens-studio/types"
import { Layer, Style, StyleSet } from "../colorScheme"; import { Layer, Style, StyleSet } from "../colorScheme"
import { colorToken } from "./token"; import { colorToken } from "./token"
interface StyleToken { interface StyleToken {
background: SingleColorToken, background: SingleColorToken
border: SingleColorToken, border: SingleColorToken
foreground: SingleColorToken, foreground: SingleColorToken
} }
interface StyleSetToken { interface StyleSetToken {
@ -37,24 +37,27 @@ export const styleToken = (style: Style, name: string): StyleToken => {
return token return token
} }
export const styleSetToken = (styleSet: StyleSet, name: string): StyleSetToken => { export const styleSetToken = (
const token: StyleSetToken = {} as StyleSetToken; styleSet: StyleSet,
name: string
): StyleSetToken => {
const token: StyleSetToken = {} as StyleSetToken
for (const style in styleSet) { for (const style in styleSet) {
const s = style as keyof StyleSet; const s = style as keyof StyleSet
token[s] = styleToken(styleSet[s], `${name}${style}`); token[s] = styleToken(styleSet[s], `${name}${style}`)
} }
return token; return token
} }
export const layerToken = (layer: Layer, name: string): LayerToken => { export const layerToken = (layer: Layer, name: string): LayerToken => {
const token: LayerToken = {} as LayerToken; const token: LayerToken = {} as LayerToken
for (const styleSet in layer) { for (const styleSet in layer) {
const s = styleSet as keyof Layer; const s = styleSet as keyof Layer
token[s] = styleSetToken(layer[s], `${name}${styleSet}`); token[s] = styleSetToken(layer[s], `${name}${styleSet}`)
} }
return token; return token
} }

View File

@ -6,13 +6,21 @@ export type PlayerToken = Record<"selection" | "cursor", SingleColorToken>
export type PlayersToken = Record<keyof Players, PlayerToken> export type PlayersToken = Record<keyof Players, PlayerToken>
function buildPlayerToken(colorScheme: ColorScheme, index: number): PlayerToken { function buildPlayerToken(
colorScheme: ColorScheme,
index: number
): PlayerToken {
const playerNumber = index.toString() as keyof Players const playerNumber = index.toString() as keyof Players
return { return {
selection: colorToken(`player${index}Selection`, colorScheme.players[playerNumber].selection), selection: colorToken(
cursor: colorToken(`player${index}Cursor`, colorScheme.players[playerNumber].cursor), `player${index}Selection`,
colorScheme.players[playerNumber].selection
),
cursor: colorToken(
`player${index}Cursor`,
colorScheme.players[playerNumber].cursor
),
} }
} }
@ -24,5 +32,5 @@ export const playersToken = (colorScheme: ColorScheme): PlayersToken => ({
"4": buildPlayerToken(colorScheme, 4), "4": buildPlayerToken(colorScheme, 4),
"5": buildPlayerToken(colorScheme, 5), "5": buildPlayerToken(colorScheme, 5),
"6": buildPlayerToken(colorScheme, 6), "6": buildPlayerToken(colorScheme, 6),
"7": buildPlayerToken(colorScheme, 7) "7": buildPlayerToken(colorScheme, 7),
}) })

View File

@ -1,6 +1,10 @@
import { SingleColorToken, TokenTypes } from "@tokens-studio/types" import { SingleColorToken, TokenTypes } from "@tokens-studio/types"
export function colorToken(name: string, value: string, description?: string): SingleColorToken { export function colorToken(
name: string,
value: string,
description?: string
): SingleColorToken {
const token: SingleColorToken = { const token: SingleColorToken = {
name, name,
type: TokenTypes.COLOR, type: TokenTypes.COLOR,
@ -8,7 +12,8 @@ export function colorToken(name: string, value: string, description?: string): S
description, description,
} }
if (!token.value || token.value === '') throw new Error("Color token must have a value") if (!token.value || token.value === "")
throw new Error("Color token must have a value")
return token return token
} }

View File

@ -1 +1,10 @@
export function slugify(t: string): string { return t.toString().toLowerCase().replace(/\s+/g, '-').replace(/[^\w\-]+/g, '').replace(/\-\-+/g, '-').replace(/^-+/, '').replace(/-+$/, '') } export function slugify(t: string): string {
return t
.toString()
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^\w\-]+/g, "")
.replace(/\-\-+/g, "-")
.replace(/^-+/, "")
.replace(/-+$/, "")
}

View File

@ -23,30 +23,14 @@
"skipLibCheck": true, "skipLibCheck": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": [ "@/*": ["./*"],
"./*" "@element/*": ["./src/element/*"],
], "@component/*": ["./src/component/*"],
"@element/*": [ "@styleTree/*": ["./src/styleTree/*"],
"./src/element/*" "@theme/*": ["./src/theme/*"],
], "@themes/*": ["./src/themes/*"],
"@component/*": [ "@util/*": ["./src/util/*"]
"./src/component/*"
],
"@styleTree/*": [
"./src/styleTree/*"
],
"@theme/*": [
"./src/theme/*"
],
"@themes/*": [
"./src/themes/*"
],
"@util/*": [
"./src/util/*"
]
} }
}, },
"exclude": [ "exclude": ["node_modules"]
"node_modules"
]
} }

View File

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