Add component asks what kind, even with one to choose
It opened the text editor straight away, and I had argued for that: Free Text is the only kind that works, so a picker offering it is a click asking to be got past. That was wrong in the way a shortcut usually is. It optimised the state of the app today and hid its shape — somebody adding a component could not see what a component IS, or that there will be others, and the day the second kind lands the interaction changes underneath them. It is also the pattern this admin already uses. The nav lists unbuilt sections as `soon` rather than hiding them, because a list of only what is finished gives no sense of what the thing is for. The same argument applied here and I had not noticed. Image, Video and Gallery are named and disabled. Those three are things the site already HAS — media, video and galleries all exist as concepts here — which is the difference between saying what is coming and inventing a roadmap. The list lives in the plugin rather than the API. The API decides what may be STORED; this decides what may be OFFERED, and it has to be here because every kind needs a label, an icon and an editor that only exists in this plugin. A kind the server would accept and this has never heard of is not creatable anyway. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { usePreviewable, useViewMode } from '../ViewMode';
|
||||
import { paintCanvas, type CanvasComponent, type CanvasSection } from '../canvas';
|
||||
import { AddSectionDialog, type SectionLayout } from './AddSectionDialog';
|
||||
import { FreeTextDialog } from './FreeTextDialog';
|
||||
import { AddComponentDialog, type ComponentKind } from './AddComponentDialog';
|
||||
import { pageFromParam, usePages, type Page } from '../usePages';
|
||||
|
||||
/**
|
||||
@@ -60,6 +61,8 @@ export const PageBuilderPanel = () => {
|
||||
}>({ add: () => {}, remove: () => {}, addComponent: () => {}, editComponent: () => {}, removeComponent: () => {} });
|
||||
const [adding, setAdding] = useState(false);
|
||||
const [creating, setCreating] = useState(false);
|
||||
/** Where a component is about to be added, while the kind is being chosen. */
|
||||
const [choosing, setChoosing] = useState<{ sectionId: number; column: number } | null>(null);
|
||||
/** The component being written, and where a new one would go. Null when the dialog is shut. */
|
||||
const [editing, setEditing] = useState<{ id: number | null; sectionId: number; column: number; html: string } | null>(
|
||||
null,
|
||||
@@ -177,14 +180,22 @@ export const PageBuilderPanel = () => {
|
||||
// Assigned on every render, after both functions above exist, so the ref always holds the current
|
||||
// pair without either being part of `onDocument`'s identity.
|
||||
/*
|
||||
Free Text is the only kind, so Add component opens the editor straight away.
|
||||
Add component asks WHAT, even though only one kind can be chosen today.
|
||||
|
||||
No picker in between: one option is not a choice, and a dialog that offers it is a click asking to
|
||||
be got past. The picker arrives with the second kind, which is the moment it starts meaning
|
||||
something.
|
||||
It opened the text editor straight away, on the reasoning that one option is not a choice. That
|
||||
optimised the state of the app rather than its shape: somebody adding a component could not see what
|
||||
a component is or that there will be others, and the day the second kind lands the interaction
|
||||
changes underneath them. The picker names the ones that are coming, the way the nav does.
|
||||
*/
|
||||
const addComponent = (section: CanvasSection, column: number) =>
|
||||
setEditing({ id: null, sectionId: section.id, column, html: '' });
|
||||
setChoosing({ sectionId: section.id, column });
|
||||
|
||||
const chooseKind = (kind: ComponentKind) => {
|
||||
if (!choosing) return;
|
||||
setChoosing(null);
|
||||
// Only one kind reaches here today. When there are more, this is where each one's editor opens.
|
||||
if (kind === 'free-text') setEditing({ id: null, ...choosing, html: '' });
|
||||
};
|
||||
|
||||
const editComponent = (component: CanvasComponent) => {
|
||||
const owner = sections.find((section) => section.components.some((one) => one.id === component.id));
|
||||
@@ -263,6 +274,8 @@ export const PageBuilderPanel = () => {
|
||||
onCreate={(values) => void createSection(values)}
|
||||
/>
|
||||
|
||||
<AddComponentDialog open={choosing !== null} onCancel={() => setChoosing(null)} onChoose={chooseKind} />
|
||||
|
||||
<FreeTextDialog
|
||||
open={editing !== null}
|
||||
busy={creating}
|
||||
|
||||
Reference in New Issue
Block a user