fix(builder): emit Container cssId/cssClass with live panel controls (D1a)

Container.craft.props collected cssId/cssClass since before Phase E1 but
nothing rendered or exported them. Add live "CSS ID" / "CSS Class" text
inputs to ContainerStylePanel (guarded on nodeProps.cssId/cssClass
!== undefined) and emit id=/class= in both the editor render and toHtml.
cssId takes precedence over the existing anchorId prop when both are set
(only one id attribute can be emitted); anchorId is used as a fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 13:46:23 -07:00
parent cf56f2a388
commit 36ce256760
3 changed files with 86 additions and 4 deletions
@@ -11,6 +11,9 @@ import {
ColorSwatchGrid,
GradientSwatchGrid,
PresetButtonGrid,
labelStyle,
inputStyle,
sectionGap,
} from './shared';
/* ---------- CONTAINER / SECTION ---------- */
@@ -27,8 +30,39 @@ export const ContainerStylePanel: React.FC<StylePanelProps> = ({ selectedId, nod
[actions, selectedId],
);
const setProp = useCallback(
(key: string, value: string) => {
actions.setProp(selectedId, (props: any) => { props[key] = value; });
},
[actions, selectedId],
);
return (
<>
{nodeProps.cssId !== undefined && (
<div style={sectionGap}>
<label style={labelStyle}>CSS ID</label>
<input
type="text"
value={nodeProps.cssId || ''}
onChange={(e) => setProp('cssId', e.target.value)}
placeholder="my-element-id"
style={inputStyle}
/>
</div>
)}
{nodeProps.cssClass !== undefined && (
<div style={sectionGap}>
<label style={labelStyle}>CSS Class</label>
<input
type="text"
value={nodeProps.cssClass || ''}
onChange={(e) => setProp('cssClass', e.target.value)}
placeholder="my-custom-class"
style={inputStyle}
/>
</div>
)}
<div className="guided-section">
<SectionLabel>Background Color</SectionLabel>
<ColorSwatchGrid