Every heading — a band's and a block's — was `type-title`, so the only way to make one bigger was to resize Headings for the whole site. A ROLE rather than a size. The four are named and sized under Layout, so a heading set to Titles follows whatever Titles is set to and keeps following it. Offering point sizes here would be a second place to change one, and the two would part company the first time somebody used the panel that exists for it. Same `ROLES` list Fonts and Font Sizes read, so all three name the same four things in the same order. Choosing Headings stores nothing. A heading nobody has thought about and one deliberately set to the default should not be two different rows. Disabled with no heading, because the size of a heading that does not exist is not a question — and written on its own rather than through the draft, because a select has one value and waiting 600ms to watch a heading change size reads as a control that has not responded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
49 lines
1.7 KiB
TypeScript
49 lines
1.7 KiB
TypeScript
import { ROLES } from './roles';
|
|
|
|
/**
|
|
* Which type role a heading is drawn at.
|
|
*
|
|
* ── A role, not a size ──
|
|
*
|
|
* The four are named and sized under Layout, so a heading set to Titles follows whatever Titles is set
|
|
* to and keeps following it. Offering point sizes here would be a second place to change one, and the
|
|
* two would part company the first time somebody used the panel that exists for it.
|
|
*
|
|
* The same `ROLES` list Fonts and Font Sizes read, so all three name the same four things in the same
|
|
* order — which is the only reason somebody moving between them can trust what they see.
|
|
*
|
|
* Disabled with no heading, because the size of a heading that does not exist is not a question. The
|
|
* field above it is where one starts.
|
|
*/
|
|
export const TitleSize = ({
|
|
value,
|
|
disabled,
|
|
onChange,
|
|
}: {
|
|
/** `display`, `title`, `body`, `sub` — or null for the default, which is Headings. */
|
|
value: string | null | undefined;
|
|
disabled?: boolean;
|
|
onChange: (next: string | null) => void;
|
|
}) => (
|
|
<div className="flex flex-col gap-1">
|
|
<label className="text-xs">Heading size</label>
|
|
<select
|
|
value={value ?? 'title'}
|
|
disabled={disabled}
|
|
onChange={(event) => {
|
|
const next = event.currentTarget.value;
|
|
// `title` IS the default, so choosing it stores nothing — a heading nobody has thought about
|
|
// and one deliberately set to Headings should not be two different rows.
|
|
onChange(next === 'title' ? null : next);
|
|
}}
|
|
className="h-9 rounded-md border border-input bg-background px-2 text-sm disabled:opacity-50"
|
|
>
|
|
{ROLES.map((role) => (
|
|
<option key={role.size} value={role.size}>
|
|
{role.label}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
);
|