"use client"; import { useEffect, useRef, useState } from "react"; import { UI_SCALES } from "@/lib/ui-scale"; /** * Text-size picker. Controlled: AppShell owns the value and handles applying * and persisting it, because the same setting is edited from two places (the * appbar popover and the mobile drawer) and reconciled against the account on * load. * * `variant="menu"` is the compact appbar popover; `variant="inline"` is the * flat row used inside the mobile drawer, where a popover inside a popover * would be awkward. */ export function FontScaleControl({ value, onChange, variant = "menu", }: { value: number; onChange: (scale: number) => void; variant?: "menu" | "inline"; }) { const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return; function onPointerDown(event: MouseEvent) { if (ref.current && !ref.current.contains(event.target as Node)) { setOpen(false); } } function onKeyDown(event: KeyboardEvent) { if (event.key === "Escape") setOpen(false); } document.addEventListener("mousedown", onPointerDown); document.addEventListener("keydown", onKeyDown); return () => { document.removeEventListener("mousedown", onPointerDown); document.removeEventListener("keydown", onKeyDown); }; }, [open]); function choose(next: number) { onChange(next); setOpen(false); } const options = UI_SCALES.map((option) => ({ ...option, selected: Math.abs(value - option.value) < 0.001, })); if (variant === "inline") { return (
Tamaño de texto
{options.map((option) => ( ))}
); } return (
{open && (
{options.map((option) => ( ))}
)}
); }