Run oxfmt across repo, add format script and docs

Add .oxfmtignore to skip generated bindings and wasm-pack output.
Add npm format script, update DEVELOPMENT.md for Vite+ toolchain,
and format all non-generated files with oxfmt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-03-13 10:15:49 -07:00
parent 45262edfbd
commit b4a1c418bb
664 changed files with 13638 additions and 13492 deletions

View File

@@ -1,10 +1,10 @@
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import { fireAndForget } from '../fireAndForget';
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { fireAndForget } from "../fireAndForget";
export type Appearance = 'light' | 'dark';
export type Appearance = "light" | "dark";
export function getCSSAppearance(): Appearance {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
export async function getWindowAppearance(): Promise<Appearance> {
@@ -23,13 +23,15 @@ export function subscribeToWindowAppearanceChange(
unsubscribe: () => {},
};
fireAndForget(getCurrentWebviewWindow()
.onThemeChanged((t) => {
cb(t.payload);
})
.then((l) => {
container.unsubscribe = l;
}));
fireAndForget(
getCurrentWebviewWindow()
.onThemeChanged((t) => {
cb(t.payload);
})
.then((l) => {
container.unsubscribe = l;
}),
);
return () => container.unsubscribe();
}
@@ -38,8 +40,8 @@ export function resolveAppearance(
preferredAppearance: Appearance,
appearanceSetting: string,
): Appearance {
const appearance = appearanceSetting === 'system' ? preferredAppearance : appearanceSetting;
return appearance === 'dark' ? 'dark' : 'light';
const appearance = appearanceSetting === "system" ? preferredAppearance : appearanceSetting;
return appearance === "dark" ? "dark" : "light";
}
export function subscribeToPreferredAppearance(cb: (a: Appearance) => void) {

View File

@@ -1,10 +1,10 @@
import type { GetThemesResponse } from '@yaakapp-internal/plugins';
import { invokeCmd } from '../tauri';
import type { Appearance } from './appearance';
import { resolveAppearance } from './appearance';
import type { GetThemesResponse } from "@yaakapp-internal/plugins";
import { invokeCmd } from "../tauri";
import type { Appearance } from "./appearance";
import { resolveAppearance } from "./appearance";
export async function getThemes() {
const themes = (await invokeCmd<GetThemesResponse[]>('cmd_get_themes')).flatMap((t) => t.themes);
const themes = (await invokeCmd<GetThemesResponse[]>("cmd_get_themes")).flatMap((t) => t.themes);
themes.sort((a, b) => a.label.localeCompare(b.label));
// Remove duplicates, in case multiple plugins provide the same theme
const uniqueThemes = Array.from(new Map(themes.map((t) => [t.id, t])).values());
@@ -26,82 +26,82 @@ export async function getResolvedTheme(
const dark = darkThemes.find((t) => t.id === themeDark) ?? darkThemes[0] ?? yaakDark;
const light = lightThemes.find((t) => t.id === themeLight) ?? lightThemes[0] ?? yaakLight;
const active = appearance === 'dark' ? dark : light;
const active = appearance === "dark" ? dark : light;
return { dark, light, active };
}
const yaakDark = {
id: 'yaak-dark',
label: 'Yaak',
id: "yaak-dark",
label: "Yaak",
dark: true,
base: {
surface: 'hsl(244,23%,14%)',
surfaceHighlight: 'hsl(244,23%,20%)',
text: 'hsl(245,23%,85%)',
textSubtle: 'hsl(245,18%,58%)',
textSubtlest: 'hsl(245,18%,45%)',
border: 'hsl(244,23%,25%)',
primary: 'hsl(266,100%,79%)',
secondary: 'hsl(245,23%,60%)',
info: 'hsl(206,100%,63%)',
success: 'hsl(150,99%,44%)',
notice: 'hsl(48,80%,63%)',
warning: 'hsl(28,100%,61%)',
danger: 'hsl(342,90%,68%)',
surface: "hsl(244,23%,14%)",
surfaceHighlight: "hsl(244,23%,20%)",
text: "hsl(245,23%,85%)",
textSubtle: "hsl(245,18%,58%)",
textSubtlest: "hsl(245,18%,45%)",
border: "hsl(244,23%,25%)",
primary: "hsl(266,100%,79%)",
secondary: "hsl(245,23%,60%)",
info: "hsl(206,100%,63%)",
success: "hsl(150,99%,44%)",
notice: "hsl(48,80%,63%)",
warning: "hsl(28,100%,61%)",
danger: "hsl(342,90%,68%)",
},
components: {
button: {
primary: 'hsl(266,100%,71.1%)',
secondary: 'hsl(244,23%,54%)',
info: 'hsl(206,100%,56.7%)',
success: 'hsl(150,99%,37.4%)',
notice: 'hsl(48,80%,50.4%)',
warning: 'hsl(28,100%,54.9%)',
danger: 'hsl(342,90%,61.2%)',
primary: "hsl(266,100%,71.1%)",
secondary: "hsl(244,23%,54%)",
info: "hsl(206,100%,56.7%)",
success: "hsl(150,99%,37.4%)",
notice: "hsl(48,80%,50.4%)",
warning: "hsl(28,100%,54.9%)",
danger: "hsl(342,90%,61.2%)",
},
dialog: {
border: 'hsl(244,23%,24%)',
border: "hsl(244,23%,24%)",
},
sidebar: {
surface: 'hsl(243,23%,16%)',
border: 'hsl(244,23%,22%)',
surface: "hsl(243,23%,16%)",
border: "hsl(244,23%,22%)",
},
responsePane: {
surface: 'hsl(243,23%,16%)',
border: 'hsl(246,23%,23%)',
surface: "hsl(243,23%,16%)",
border: "hsl(246,23%,23%)",
},
appHeader: {
surface: 'hsl(244,23%,12%)',
border: 'hsl(244,23%,21%)',
surface: "hsl(244,23%,12%)",
border: "hsl(244,23%,21%)",
},
},
};
const yaakLight = {
id: 'yaak-light',
label: 'Yaak',
id: "yaak-light",
label: "Yaak",
dark: false,
base: {
surface: 'hsl(0,0%,100%)',
surfaceHighlight: 'hsl(218,24%,87%)',
text: 'hsl(217,24%,10%)',
textSubtle: 'hsl(217,24%,40%)',
textSubtlest: 'hsl(217,24%,58%)',
border: 'hsl(217,22%,90%)',
primary: 'hsl(266,100%,60%)',
secondary: 'hsl(220,24%,50%)',
info: 'hsl(206,100%,40%)',
success: 'hsl(139,66%,34%)',
notice: 'hsl(45,100%,34%)',
warning: 'hsl(30,100%,36%)',
danger: 'hsl(335,75%,48%)',
surface: "hsl(0,0%,100%)",
surfaceHighlight: "hsl(218,24%,87%)",
text: "hsl(217,24%,10%)",
textSubtle: "hsl(217,24%,40%)",
textSubtlest: "hsl(217,24%,58%)",
border: "hsl(217,22%,90%)",
primary: "hsl(266,100%,60%)",
secondary: "hsl(220,24%,50%)",
info: "hsl(206,100%,40%)",
success: "hsl(139,66%,34%)",
notice: "hsl(45,100%,34%)",
warning: "hsl(30,100%,36%)",
danger: "hsl(335,75%,48%)",
},
components: {
sidebar: {
surface: 'hsl(220,20%,98%)',
border: 'hsl(217,22%,88%)',
surfaceHighlight: 'hsl(217,25%,90%)',
surface: "hsl(220,20%,98%)",
border: "hsl(217,22%,88%)",
surfaceHighlight: "hsl(217,25%,90%)",
},
},
};

View File

@@ -1,6 +1,6 @@
import type { Theme, ThemeComponentColors } from '@yaakapp-internal/plugins';
import { defaultDarkTheme, defaultLightTheme } from './themes';
import { YaakColor } from './yaakColor';
import type { Theme, ThemeComponentColors } from "@yaakapp-internal/plugins";
import { defaultDarkTheme, defaultLightTheme } from "./themes";
import { YaakColor } from "./yaakColor";
export type YaakColors = {
surface: YaakColor;
@@ -50,7 +50,7 @@ export type YaakTheme = {
export type YaakColorKey = keyof ThemeComponentColors;
type ComponentName = keyof NonNullable<YaakTheme['components']>;
type ComponentName = keyof NonNullable<YaakTheme["components"]>;
type CSSVariables = Record<YaakColorKey, string | undefined>;
@@ -155,7 +155,7 @@ function buttonSolidColorVariables(
if (color == null) return {};
const theme: Partial<ThemeComponentColors> = {
text: 'white',
text: "white",
surface: color.lower(0.3).css(),
surfaceHighlight: color.lower(0.1).css(),
border: color.css(),
@@ -204,7 +204,7 @@ function variablesToCSS(
const css = Object.entries(vars ?? {})
.filter(([, value]) => value)
.map(([name, value]) => `--${name}: ${value};`)
.join('\n');
.join("\n");
return selector == null ? css : `${selector} {\n${indent(css)}\n}`;
}
@@ -231,7 +231,7 @@ function buttonCSS(
return [
variablesToCSS(`.x-theme-button--solid--${color}`, buttonSolidColorVariables(yaakColor)),
variablesToCSS(`.x-theme-button--border--${color}`, buttonBorderColorVariables(yaakColor)),
].join('\n\n');
].join("\n\n");
}
function bannerCSS(
@@ -245,7 +245,7 @@ function bannerCSS(
}
return [variablesToCSS(`.x-theme-banner--${color}`, bannerColorVariables(yaakColor))].join(
'\n\n',
"\n\n",
);
}
@@ -255,7 +255,7 @@ function toastCSS(theme: Theme, color: YaakColorKey, colors?: ThemeComponentColo
return null;
}
return [variablesToCSS(`.x-theme-toast--${color}`, toastColorVariables(yaakColor))].join('\n\n');
return [variablesToCSS(`.x-theme-toast--${color}`, toastColorVariables(yaakColor))].join("\n\n");
}
function templateTagCSS(
@@ -270,7 +270,7 @@ function templateTagCSS(
return [
variablesToCSS(`.x-theme-templateTag--${color}`, templateTagColorVariables(yaakColor)),
].join('\n\n');
].join("\n\n");
}
export function getThemeCSS(theme: Theme): string {
@@ -283,18 +283,18 @@ export function getThemeCSS(theme: Theme): string {
return { ...prev, [key]: theme.base[key as YaakColorKey] };
}, {}) as ThemeComponentColors;
let themeCSS = '';
let themeCSS = "";
try {
const baseCss = variablesToCSS(null, themeVariables(theme));
themeCSS = [
baseCss,
...Object.keys(components ?? {}).map((key) => componentCSS(theme, key as ComponentName)),
variablesToCSS(
'.x-theme-button--solid--default',
".x-theme-button--solid--default",
buttonSolidColorVariables(yc(theme, theme.base.surface), true),
),
variablesToCSS(
'.x-theme-button--border--default',
".x-theme-button--border--default",
buttonBorderColorVariables(yc(theme, theme.base.surface), true),
),
...Object.keys(colors ?? {}).map((key) =>
@@ -309,46 +309,46 @@ export function getThemeCSS(theme: Theme): string {
...Object.keys(colors ?? {}).map((key) =>
templateTagCSS(theme, key as YaakColorKey, theme.components?.templateTag ?? colors),
),
].join('\n\n');
].join("\n\n");
} catch (err) {
console.error('Failed to generate CSS', err);
console.error("Failed to generate CSS", err);
}
return [`/* ${label} */`, `[data-theme="${id}"] {`, indent(themeCSS), '}'].join('\n');
return [`/* ${label} */`, `[data-theme="${id}"] {`, indent(themeCSS), "}"].join("\n");
}
export function addThemeStylesToDocument(rawTheme: Theme | null) {
if (rawTheme == null) {
console.error('Failed to add theme styles: theme is null');
console.error("Failed to add theme styles: theme is null");
return;
}
const theme = completeTheme(rawTheme);
let styleEl = document.head.querySelector('style[data-theme]');
let styleEl = document.head.querySelector("style[data-theme]");
if (!styleEl) {
styleEl = document.createElement('style');
styleEl = document.createElement("style");
document.head.appendChild(styleEl);
}
styleEl.setAttribute('data-theme', theme.id);
styleEl.setAttribute('data-updated-at', new Date().toISOString());
styleEl.setAttribute("data-theme", theme.id);
styleEl.setAttribute("data-updated-at", new Date().toISOString());
styleEl.textContent = getThemeCSS(theme);
}
export function setThemeOnDocument(theme: Theme | null) {
if (theme == null) {
console.error('Failed to set theme: theme is null');
console.error("Failed to set theme: theme is null");
return;
}
document.documentElement.setAttribute('data-theme', theme.id);
document.documentElement.setAttribute("data-theme", theme.id);
}
export function indent(text: string, space = ' '): string {
export function indent(text: string, space = " "): string {
return text
.split('\n')
.split("\n")
.map((line) => space + line)
.join('\n');
.join("\n");
}
function yc<T extends string | null | undefined>(
@@ -356,7 +356,7 @@ function yc<T extends string | null | undefined>(
s: T,
): T extends string ? YaakColor : null {
if (s == null) return null as never;
return new YaakColor(s, theme.dark ? 'dark' : 'light') as never;
return new YaakColor(s, theme.dark ? "dark" : "light") as never;
}
export function completeTheme(theme: Theme): Theme {

View File

@@ -1,37 +1,37 @@
import parseColor from 'parse-color';
import parseColor from "parse-color";
export class YaakColor {
private readonly appearance: 'dark' | 'light' = 'light';
private readonly appearance: "dark" | "light" = "light";
private hue = 0;
private saturation = 0;
private lightness = 0;
private alpha = 1;
constructor(cssColor: string, appearance: 'dark' | 'light' = 'light') {
constructor(cssColor: string, appearance: "dark" | "light" = "light") {
try {
this.set(cssColor);
this.appearance = appearance;
} catch (err) {
console.log('Failed to parse CSS color', cssColor, err);
console.log("Failed to parse CSS color", cssColor, err);
}
}
static transparent(): YaakColor {
return new YaakColor('rgb(0,0,0)', 'light').translucify(1);
return new YaakColor("rgb(0,0,0)", "light").translucify(1);
}
static white(): YaakColor {
return new YaakColor('rgb(0,0,0)', 'light').lower(1);
return new YaakColor("rgb(0,0,0)", "light").lower(1);
}
static black(): YaakColor {
return new YaakColor('rgb(0,0,0)', 'light').lift(1);
return new YaakColor("rgb(0,0,0)", "light").lift(1);
}
set(cssColor: string): YaakColor {
let fixedCssColor = cssColor;
if (cssColor.startsWith('#') && cssColor.length === 9) {
if (cssColor.startsWith("#") && cssColor.length === 9) {
const [r, g, b, a] = hexToRgba(cssColor);
fixedCssColor = `rgba(${r},${g},${b},${a})`;
}
@@ -48,11 +48,11 @@ export class YaakColor {
}
lower(mod: number): YaakColor {
return this.appearance === 'dark' ? this._darken(mod) : this._lighten(mod);
return this.appearance === "dark" ? this._darken(mod) : this._lighten(mod);
}
lift(mod: number): YaakColor {
return this.appearance === 'dark' ? this._lighten(mod) : this._darken(mod);
return this.appearance === "dark" ? this._lighten(mod) : this._darken(mod);
}
minLightness(n: number): YaakColor {
@@ -132,7 +132,7 @@ function rgbaToHex(r: number, g: number, b: number, a: number): string {
const hex = Number(Math.round(n)).toString(16);
return hex.length === 1 ? `0${hex}` : hex;
};
return `#${[toHex(r), toHex(g), toHex(b), toHex(a * 255)].join('').toUpperCase()}`;
return `#${[toHex(r), toHex(g), toHex(b), toHex(a * 255)].join("").toUpperCase()}`;
}
function rgbaToHexNoAlpha(r: number, g: number, b: number): string {
@@ -140,12 +140,12 @@ function rgbaToHexNoAlpha(r: number, g: number, b: number): string {
const hex = Number(Math.round(n)).toString(16);
return hex.length === 1 ? `0${hex}` : hex;
};
return `#${[toHex(r), toHex(g), toHex(b)].join('').toUpperCase()}`;
return `#${[toHex(r), toHex(g), toHex(b)].join("").toUpperCase()}`;
}
function hexToRgba(hex: string): [number, number, number, number] {
const fromHex = (h: string): number => {
if (h === '') return 255;
if (h === "") return 255;
return Number(`0x${h}`);
};