From ac490215ceebd7b48d4ae83f9e15d0e016db253d Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Wed, 7 Oct 2026 09:56:12 -0700 Subject: [PATCH 1/2] fix(site-builder): one undo step per edit (throttle continuous inputs, single setProp for multi-prop toggles) Refs #32 Co-Authored-By: Claude Sonnet 5.5 --- .../panels/right/styles/ArrayItemFields.tsx | 12 +- .../panels/right/styles/ButtonStylePanel.tsx | 13 +- .../right/styles/ContainerStylePanel.tsx | 4 +- .../panels/right/styles/FeaturesEditor.tsx | 9 +- .../panels/right/styles/FormStylePanel.tsx | 11 +- .../styles/FormStylePanel.webhook.test.tsx | 2 +- .../right/styles/ImageStylePanel.test.tsx | 2 +- .../panels/right/styles/ImageStylePanel.tsx | 7 +- .../panels/right/styles/MediaStylePanel.tsx | 11 +- .../styles/MediaStylePanel.video.test.tsx | 2 +- .../right/styles/NavStylePanel.test.tsx | 2 +- .../src/panels/right/styles/NavStylePanel.tsx | 3 +- .../panels/right/styles/PricingStylePanel.tsx | 15 +- .../panels/right/styles/SectionTypePanel.tsx | 8 +- .../panels/right/styles/SocialStylePanel.tsx | 11 +- .../panels/right/styles/TextStylePanel.tsx | 8 +- .../panels/right/styles/containerBoxModel.tsx | 10 +- .../src/panels/right/styles/mediaBoxModel.tsx | 10 +- craft/src/panels/right/styles/shared.tsx | 15 +- .../undo-steps.integration.test.tsx | 131 ++++++++++++++++++ 20 files changed, 209 insertions(+), 77 deletions(-) create mode 100644 craft/src/test-utils/integration/undo-steps.integration.test.tsx diff --git a/craft/src/panels/right/styles/ArrayItemFields.tsx b/craft/src/panels/right/styles/ArrayItemFields.tsx index b2bb96c..056101e 100644 --- a/craft/src/panels/right/styles/ArrayItemFields.tsx +++ b/craft/src/panels/right/styles/ArrayItemFields.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useRef } from 'react'; import { useEditor } from '@craftjs/core'; -import { CollapsibleSection, ArrayPropEditor, smallInputStyle } from './shared'; +import { CollapsibleSection, ArrayPropEditor, smallInputStyle, TYPING_THROTTLE_MS } from './shared'; import { useLayerFocus } from '../../left/LayerFocusContext'; /* ---------- Shared array-item field editor ---------- @@ -52,7 +52,7 @@ export const ArrayItemFieldsEditor: React.FC<{ selectedId: string; propKey: stri data-array-item={`${propKey}:${index}`} value={String(item)} onChange={(e) => { - actions.setProp(selectedId, (props: any) => { + actions.history.throttle(TYPING_THROTTLE_MS).setProp(selectedId, (props: any) => { const updated = [...(props[propKey] || [])]; updated[index] = e.target.value; props[propKey] = updated; @@ -85,7 +85,7 @@ export const ArrayItemFieldsEditor: React.FC<{ selectedId: string; propKey: stri
{ - actions.setProp(selectedId, (props: any) => { + actions.history.throttle(TYPING_THROTTLE_MS).setProp(selectedId, (props: any) => { const updated = [...(props[propKey] || [])]; updated[index] = { ...updated[index], [field]: parseFloat(e.target.value) || 0 }; props[propKey] = updated; @@ -100,7 +100,7 @@ export const ArrayItemFieldsEditor: React.FC<{ selectedId: string; propKey: stri
{ - actions.setProp(selectedId, (props: any) => { + actions.history.throttle(TYPING_THROTTLE_MS).setProp(selectedId, (props: any) => { const updated = [...(props[propKey] || [])]; updated[index] = { ...updated[index], [field]: e.target.value }; props[propKey] = updated; @@ -117,7 +117,7 @@ export const ArrayItemFieldsEditor: React.FC<{ selectedId: string; propKey: stri {isLongField ? (