an Alignment control beside Width
Left, Centred, Right on the selected block. Left writes nothing, so a block that has never been touched inherits the page. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -57,6 +57,8 @@ export type CanvasComponent = {
|
||||
title?: string | null;
|
||||
/** `main`, `page` or null — how wide it is allowed to be. See the site's schema. */
|
||||
width?: string | null;
|
||||
/** `center`, `right` or null — how the block's own content sits. See the site's schema. */
|
||||
align?: string | null;
|
||||
/*
|
||||
One optional field per kind that the panel reads back. Not `Record<string, unknown>`: every reader
|
||||
would then need a cast, and the point of naming them is that the compiler knows `free-text` holds
|
||||
|
||||
@@ -33,6 +33,7 @@ export const BlockSettings = ({
|
||||
title?: string | null;
|
||||
title_size?: string | null;
|
||||
width?: string | null;
|
||||
align?: string | null;
|
||||
padding?: Record<string, { x?: number; y?: number }>;
|
||||
};
|
||||
/** The padding scale, sent by the API so this file holds no copy of it. */
|
||||
@@ -49,6 +50,7 @@ export const BlockSettings = ({
|
||||
const [draft, setDraft] = useState({
|
||||
title: block.title ?? '',
|
||||
width: block.width ?? '',
|
||||
align: block.align ?? '',
|
||||
padding: block.padding ?? {},
|
||||
});
|
||||
const [busy, setBusy] = useState(false);
|
||||
@@ -57,7 +59,7 @@ export const BlockSettings = ({
|
||||
|
||||
// Keyed on the id, so re-reading the same block after a save does not throw away what is being typed.
|
||||
useEffect(
|
||||
() => setDraft({ title: block.title ?? '', width: block.width ?? '', padding: block.padding ?? {} }),
|
||||
() => setDraft({ title: block.title ?? '', width: block.width ?? '', align: block.align ?? '', padding: block.padding ?? {} }),
|
||||
[block.id],
|
||||
);
|
||||
|
||||
@@ -100,7 +102,7 @@ export const BlockSettings = ({
|
||||
// Empty is sent as an empty string, which the API reads as "take the heading off".
|
||||
await clientRef.current.patch(
|
||||
`/fofos-admin/pages/${pageId}/sections/${sectionId}/components/${block.id}`,
|
||||
{ title: draft.title, width: draft.width || null, padding: draft.padding, ...extra },
|
||||
{ title: draft.title, width: draft.width || null, align: draft.align || null, padding: draft.padding, ...extra },
|
||||
);
|
||||
flashSaved();
|
||||
onSaved();
|
||||
@@ -114,6 +116,7 @@ export const BlockSettings = ({
|
||||
const stored = JSON.stringify({
|
||||
title: block.title ?? '',
|
||||
width: block.width ?? '',
|
||||
align: block.align ?? '',
|
||||
padding: block.padding ?? {},
|
||||
});
|
||||
const pending = JSON.stringify(draft);
|
||||
@@ -166,6 +169,33 @@ export const BlockSettings = ({
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
How the block's own content sits.
|
||||
|
||||
A property of the BLOCK, not of the words in it: it applies to a title drawn from the subject,
|
||||
a spec table and a photograph, none of which have text you could select and centre. The rich
|
||||
text editor still has its own alignment for a paragraph inside a free-text block, and the two
|
||||
are different questions.
|
||||
|
||||
Left is the absence of a value rather than a value, so a block that has never been touched
|
||||
inherits the page and nothing is written for it.
|
||||
*/}
|
||||
<div className="mt-3 flex flex-col gap-1">
|
||||
<label className="text-xs">Alignment</label>
|
||||
<select
|
||||
value={draft.align}
|
||||
onChange={(event) => {
|
||||
const value = event.currentTarget.value;
|
||||
setDraft((was) => ({ ...was, align: value }));
|
||||
}}
|
||||
className="h-8 rounded-md border border-input bg-transparent px-2 text-xs"
|
||||
>
|
||||
<option value="">Left</option>
|
||||
<option value="center">Centred</option>
|
||||
<option value="right">Right</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/*
|
||||
The block's own spacing, at the width the toggle above is showing.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user