diff --git a/web/DeviceToggle.tsx b/web/DeviceToggle.tsx index 24bc0e7..2c45c35 100644 --- a/web/DeviceToggle.tsx +++ b/web/DeviceToggle.tsx @@ -60,12 +60,20 @@ const OPTIONS: { value: DeviceName; Icon: typeof Monitor }[] = [ * choice legible without hovering for a tooltip. * * The label comes from DEVICES, which is also what the preview names in its own caption. One list. + * + * ── Narrow, it goes back to icons ── + * + * A CONTAINER query, not a screen one: this sits in a workspace panel whose width is a divider the + * user drags, so the window's width says nothing about the room there is. `@container` on the row + * makes the row itself the thing measured. + * + * The word is then the `title`, so the answer is still one hover away rather than gone. */ export const DeviceToggle = () => { const [device, setDevice] = useDevice(); return ( -
+
{OPTIONS.map(({ value, Icon }) => ( ))}
diff --git a/web/sections/LayoutPanel.tsx b/web/sections/LayoutPanel.tsx index 3d5ce12..c01f003 100644 --- a/web/sections/LayoutPanel.tsx +++ b/web/sections/LayoutPanel.tsx @@ -1,6 +1,5 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'; -import { useSearchParams } from 'react-router'; import { useClient } from 'hooks/useClient'; import { readableError } from '../errors'; import { useFlash } from '../useFlash'; @@ -110,6 +109,9 @@ const themeProperties = (draft: Layout): Record => ({ '--font-display': draft.font_display && `"${draft.font_display}", sans-serif`, }); +/** Every section, open from the start. The values below must match the AccordionItems. */ +const SECTIONS_OPEN = ['colours', 'typefaces', 'padding']; + const COLOURS = [ { key: 'background' as const, label: 'Background', fallback: '#ffffff' }, { key: 'foreground' as const, label: 'Text', fallback: '#000000' }, @@ -124,23 +126,7 @@ export const LayoutPanel = () => { const [stored, setStored] = useState(null); const [draft, setDraft] = useState(null); const [busy, setBusy] = useState(false); - const [params, setParams] = useSearchParams(); const devPort = useDevPort(); - /** Controlled, because the grid stack below decides visibility rather than Radix unmounting. */ - /* - The open tab, in the URL — `?tab=padding`. - - Same rule as the mode and the device: it is addressable. "Look at the typefaces" is a link somebody - sends, and a reload that drops you back on Colours loses the place you were working in. - - Absent means Colours, the first one, so an ordinary link carries nothing. - */ - const tab = params.get('tab') ?? 'colours'; - const setTab = (next: string) => { - const search = new URLSearchParams(params); - search.set('tab', next); - setParams(search, { replace: true }); - }; const [error, setError] = useState(null); const [saved, flashSaved] = useFlash(); @@ -263,7 +249,14 @@ export const LayoutPanel = () => { } setEditorRef.current( - + /* + Every section open to begin with. + + It opened on one, from `?tab=`, which is what a set of TABS wants — one at a time, and which + one is addressable. These are not tabs: they are the whole of what this screen decides, and a + column that starts collapsed asks somebody to go looking for the setting they came for. + */ + Colors @@ -357,7 +350,7 @@ export const LayoutPanel = () => { ); - }, [draft, tab, device]); + }, [draft, device]); // Cleared on unmount, or the panel goes on offering Layout's controls over somebody else's page. useEffect(() => () => setEditorRef.current(null), []);