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:
parent
5d24bedd60
commit
39b95c2ede
203 changed files with 10090 additions and 6085 deletions
|
|
@ -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}>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue