treefmt: apply prettier

Pure `nix fmt` output from the commit before this one — no hand edits.
203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs.

Reproduce with `nix develop -c nix fmt` on the parent commit; the result
should be byte-identical to this tree.

None of the 13 `.prettierignore` entries appears here — verified by
intersecting the changed-file list against the ignore file, with a
control proving the intersection finds a match when one exists.
This commit is contained in:
atlas 2026-09-02 14:29:33 +02:00
commit 39b95c2ede
203 changed files with 10090 additions and 6085 deletions

View file

@ -23,16 +23,16 @@
// once, high in its tree, with the SAME key strings passed to this
// component, so the two stay in sync without this component owning any
// page-specific naming decision.
import { useEffect, useRef, useState } from 'preact/hooks';
import type { ComponentChildren } from 'preact';
import { Badge } from '../badge/Badge.js';
import { GearIcon } from '../icons.js';
import { useThemeOverride, type ThemeOverride } from './theme-apply.js';
import { useMotionOverride, type MotionOverride } from './motion-apply.js';
import './SettingsMenu.css';
import { useEffect, useRef, useState } from "preact/hooks";
import type { ComponentChildren } from "preact";
import { Badge } from "../badge/Badge.js";
import { GearIcon } from "../icons.js";
import { useThemeOverride, type ThemeOverride } from "./theme-apply.js";
import { useMotionOverride, type MotionOverride } from "./motion-apply.js";
import "./SettingsMenu.css";
const THEME_OPTIONS: ThemeOverride[] = ['system', 'light', 'dark'];
const MOTION_OPTIONS: MotionOverride[] = ['system', 'allow', 'reduce'];
const THEME_OPTIONS: ThemeOverride[] = ["system", "light", "dark"];
const MOTION_OPTIONS: MotionOverride[] = ["system", "allow", "reduce"];
export interface SettingsMenuProps {
themeKey: string;
@ -51,7 +51,11 @@ export interface SettingsMenuProps {
children?: ComponentChildren;
}
export function SettingsMenu({ themeKey, motionKey, children }: SettingsMenuProps) {
export function SettingsMenu({
themeKey,
motionKey,
children,
}: SettingsMenuProps) {
const [open, setOpen] = useState(false);
const rootRef = useRef<HTMLDivElement>(null);
const [theme, setTheme] = useThemeOverride(themeKey);
@ -61,16 +65,21 @@ export function SettingsMenu({ themeKey, motionKey, children }: SettingsMenuProp
useEffect(() => {
if (!open) return;
function onPointerDown(e: PointerEvent) {
if (rootRef.current && e.target instanceof Node && !rootRef.current.contains(e.target)) setOpen(false);
if (
rootRef.current &&
e.target instanceof Node &&
!rootRef.current.contains(e.target)
)
setOpen(false);
}
function onKeyDown(e: KeyboardEvent) {
if (e.key === 'Escape') setOpen(false);
if (e.key === "Escape") setOpen(false);
}
document.addEventListener('pointerdown', onPointerDown, true);
document.addEventListener('keydown', onKeyDown);
document.addEventListener("pointerdown", onPointerDown, true);
document.addEventListener("keydown", onKeyDown);
return () => {
document.removeEventListener('pointerdown', onPointerDown, true);
document.removeEventListener('keydown', onKeyDown);
document.removeEventListener("pointerdown", onPointerDown, true);
document.removeEventListener("keydown", onKeyDown);
};
}, [open]);
@ -89,7 +98,9 @@ export function SettingsMenu({ themeKey, motionKey, children }: SettingsMenuProp
<span>theme</span>
<select
value={theme}
onChange={(e) => setTheme((e.target as HTMLSelectElement).value as ThemeOverride)}
onChange={(e) =>
setTheme((e.target as HTMLSelectElement).value as ThemeOverride)
}
>
{THEME_OPTIONS.map((o) => (
<option key={o} value={o}>
@ -102,7 +113,11 @@ export function SettingsMenu({ themeKey, motionKey, children }: SettingsMenuProp
<span>motion</span>
<select
value={motion}
onChange={(e) => setMotion((e.target as HTMLSelectElement).value as MotionOverride)}
onChange={(e) =>
setMotion(
(e.target as HTMLSelectElement).value as MotionOverride,
)
}
>
{MOTION_OPTIONS.map((o) => (
<option key={o} value={o}>

View file

@ -12,22 +12,28 @@
// (see swarm-ui's `shell/Shell.css` file-top comment for a worked
// example). A page with no motion-gated animation yet can still mount
// this — the attribute is simply inert until something reads it.
import { useEffect } from 'preact/hooks';
import { useLocalSetting } from './settings-storage.js';
import { useEffect } from "preact/hooks";
import { useLocalSetting } from "./settings-storage.js";
export type MotionOverride = 'system' | 'reduce' | 'allow';
export type MotionOverride = "system" | "reduce" | "allow";
export function useMotionOverride(key: string, fallback: MotionOverride = 'system') {
export function useMotionOverride(
key: string,
fallback: MotionOverride = "system",
) {
return useLocalSetting<MotionOverride>(key, fallback);
}
// Mounted once alongside `useApplyThemeOverride` — same single-mount-
// point rationale.
export function useApplyMotionOverride(key: string, fallback: MotionOverride = 'system'): void {
export function useApplyMotionOverride(
key: string,
fallback: MotionOverride = "system",
): void {
const [override] = useMotionOverride(key, fallback);
useEffect(() => {
const root = document.documentElement;
if (override === 'system') {
if (override === "system") {
delete root.dataset.motion;
} else {
root.dataset.motion = override;

View file

@ -14,7 +14,7 @@
// reading) need their own same-tab signal. The tiny module-level pub/sub
// below is that signal; it's deliberately not exported, callers only see
// the hook.
import { useEffect, useState } from 'preact/hooks';
import { useEffect, useState } from "preact/hooks";
const listeners = new Map<string, Set<() => void>>();
@ -70,10 +70,16 @@ function writeLocalSetting<T>(key: string, value: T): void {
// this component's state through the identical "react to a change"
// path every other subscriber uses — one path, not two that have to
// agree.
export function useLocalSetting<T>(key: string, fallback: T): [T, (value: T) => void] {
export function useLocalSetting<T>(
key: string,
fallback: T,
): [T, (value: T) => void] {
const [value, setValue] = useState<T>(() => readLocalSetting(key, fallback));
useEffect(() => subscribe(key, () => setValue(readLocalSetting(key, fallback))), [key]);
useEffect(
() => subscribe(key, () => setValue(readLocalSetting(key, fallback))),
[key],
);
return [value, (next: T) => writeLocalSetting(key, next)];
}

View file

@ -13,12 +13,15 @@
// — `'system'` as a default silently reads as light-by-default for most
// first-time visitors (mara: "light mode seems to be default"). Still
// fully overridable per caller if a page ever wants a different default.
import { useEffect } from 'preact/hooks';
import { useLocalSetting } from './settings-storage.js';
import { useEffect } from "preact/hooks";
import { useLocalSetting } from "./settings-storage.js";
export type ThemeOverride = 'system' | 'light' | 'dark';
export type ThemeOverride = "system" | "light" | "dark";
export function useThemeOverride(key: string, fallback: ThemeOverride = 'dark') {
export function useThemeOverride(
key: string,
fallback: ThemeOverride = "dark",
) {
return useLocalSetting<ThemeOverride>(key, fallback);
}
@ -27,11 +30,14 @@ export function useThemeOverride(key: string, fallback: ThemeOverride = 'dark')
// same-tab subscription means `SettingsMenu` changing the value re-runs
// this effect without either component needing to know about the other
// directly.
export function useApplyThemeOverride(key: string, fallback: ThemeOverride = 'dark'): void {
export function useApplyThemeOverride(
key: string,
fallback: ThemeOverride = "dark",
): void {
const [override] = useThemeOverride(key, fallback);
useEffect(() => {
const root = document.documentElement;
if (override === 'system') {
if (override === "system") {
delete root.dataset.theme;
} else {
root.dataset.theme = override;