From aab536059b41c4657ab758681e02b9dfbc605d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Tue, 1 Sep 2026 08:48:51 +0100 Subject: [PATCH] the empty size option names the size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Inherit (default)" answers a question nobody asked. What somebody wants from that dropdown is what it is now — and a label that will not say makes them change the setting to find out, which is the one way to lose the answer. It reads Default (4xl) at the smallest width and Inherit (2xl) above it. The stylesheet's own sizes come from the API, which reads them out of styles.css. Co-Authored-By: Claude Opus 5 (1M context) --- web/sections/FontSizesTab.tsx | 24 ++++++++++++++++++------ web/sections/LayoutPanel.tsx | 3 +++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/web/sections/FontSizesTab.tsx b/web/sections/FontSizesTab.tsx index 2b6938e..e73827c 100644 --- a/web/sections/FontSizesTab.tsx +++ b/web/sections/FontSizesTab.tsx @@ -13,8 +13,16 @@ import { ROLES } from './roles'; * ── One value per field ── * * The tabs at the top of the panel say which width. Unset inherits the smaller one, so "the same - * everywhere" is one choice; the option names what it is inheriting rather than leaving it to be - * worked out. + * everywhere" is one choice. + * + * ── The empty option NAMES the size ── + * + * It said "Inherit (default)", which answers a question nobody asked. What somebody wants from that + * dropdown is "what is it now", and a label that does not say makes them change the setting to find + * out — which is the one way to lose the answer. + * + * So it names the size that will actually apply: the nearest smaller width that has one, or the + * stylesheet's own, which the API reads out of styles.css rather than this file guessing. */ export type FontSizes = Partial>>>; @@ -36,11 +44,14 @@ const inherited = ( export const FontSizesTab = ({ sizes, steps, + defaults, onChange, }: { sizes: FontSizes; /** The scale, sent by the API so this file holds no copy of it. */ steps: string[]; + /** What each role is with nothing chosen, read from the site's stylesheet. */ + defaults: Record; onChange: (sizes: FontSizes) => void; }) => { const [device] = useDevice(); @@ -64,7 +75,8 @@ export const FontSizesTab = ({ {ROLES.map((role) => { const current = sizes[role.size]; const own = current?.[key]; - const from = inherited(current, key); + // The nearest smaller width that has one, or the stylesheet's. Either way, a size to read. + const from = inherited(current, key) ?? defaults[role.size]; return (
@@ -74,10 +86,10 @@ export const FontSizesTab = ({ onChange={(event) => set(role.size, event.currentTarget.value)} className="h-8 rounded-md border border-input bg-transparent px-2 text-xs" > - {/* Mobile is the smallest, so there is nothing below it to inherit from — and nothing - chosen there means the stylesheet's own size. */} + {/* Mobile is the smallest, so nothing below it: what it falls back to is the + stylesheet's own size rather than another breakpoint's. */} {steps.map((step) => (