refactor(builder): extract useNodeProp hook, dedup StylePanel setProp boilerplate

Adopted in BackgroundSectionStylePanel, ButtonStylePanel, ContainerStylePanel,
FormStylePanel, GenericPropsEditor, HeroStylePanel, ImageStylePanel,
MediaStylePanel, NavStylePanel, SectionTypePanel, SocialStylePanel,
TextStylePanel — only where the inline setProp/setPropStyle were behaviorally
identical to the hook. PricingStylePanel and FeaturesEditor keep their own
array-mutation logic since it differs. Behavior-preserving (task E4.1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 15:13:35 -07:00
co-authored by Claude Opus 4.8
parent 3cd4ad0154
commit 4733fe84b5
13 changed files with 46 additions and 132 deletions
+12
View File
@@ -288,6 +288,18 @@ export interface StylePanelProps {
nodeProps: Record<string, any>;
}
/* ---------- useNodeProp ----------
Shared setProp/setPropStyle boilerplate repeated across many *StylePanel.tsx
files. Only adopted where a panel's inline definitions were byte-equivalent
to this (some panels use different param names or extra logic and keep
their own local versions). */
export function useNodeProp(selectedId: string) {
const { actions } = useEditor();
const setProp = useCallback((key: string, value: any) => actions.setProp(selectedId, (p: any) => { p[key] = value; }), [actions, selectedId]);
const setPropStyle = useCallback((prop: string, value: string) => actions.setProp(selectedId, (p: any) => { p.style = { ...p.style, [prop]: value }; }), [actions, selectedId]);
return { setProp, setPropStyle };
}
/* ---------- Array Prop Editor (reusable for features, items, plans, etc.) ---------- */
interface ArrayPropEditorProps {
selectedId: string;