diff --git a/packages/studio/src/hooks/useDomEditTextCommits.test.tsx b/packages/studio/src/hooks/useDomEditTextCommits.test.tsx index 3057120c54..c4aeedc7cf 100644 --- a/packages/studio/src/hooks/useDomEditTextCommits.test.tsx +++ b/packages/studio/src/hooks/useDomEditTextCommits.test.tsx @@ -335,6 +335,29 @@ describe("useDomEditTextCommits", () => { expect(outcome).toEqual({ ok: true, persistence }); }); + it("saves a style map on a selection as one patch, so it is one undo step", async () => { + const { iframe, element } = previewElement("
Original
", "card"); + const persist = vi.fn().mockResolvedValue({ sourceFile: "index.html", changed: true }); + const hook = renderTextCommitHook( + commitParams({ + previewIframeRef: { current: iframe }, + domEditSelection: null, + persistDomEditOperations: persist, + }), + ); + + await act(async () => { + await hook.handleDomStyleCommitForSelection(selectionFor(element), { + "border-width": "4px", + "border-style": "solid", + }); + }); + + expect(persist).toHaveBeenCalledTimes(1); + expect(element.style.borderWidth).toBe("4px"); + expect(element.style.borderStyle).toBe("solid"); + }); + it("declines a style commit with no selection, without reaching the writer", async () => { const persistDomEditOperations = vi.fn().mockResolvedValue(undefined); const hook = renderTextCommitHook( diff --git a/packages/studio/src/hooks/useDomEditTextCommits.ts b/packages/studio/src/hooks/useDomEditTextCommits.ts index 21e26c3ca2..75ef5817bd 100644 --- a/packages/studio/src/hooks/useDomEditTextCommits.ts +++ b/packages/studio/src/hooks/useDomEditTextCommits.ts @@ -105,8 +105,13 @@ export function useDomEditTextCommits({ persistDomEditOperations, }); + // One property, or a map saved as one patch and one undo step. const handleDomStyleCommitForSelection = useCallback( - (selection: DomEditSelection, property: string, value: string): Promise => + ( + selection: DomEditSelection, + property: string | Record, + value = "", + ): Promise => commitDomStyles( { activeCompPath, @@ -118,7 +123,7 @@ export function useDomEditTextCommits({ resync: refreshDomEditSelectionFromPreview, }, selection, - { [property]: value }, + typeof property === "string" ? { [property]: value } : property, ), [ activeCompPath, diff --git a/packages/studio/src/index.ts b/packages/studio/src/index.ts index c6ee950fae..4024a375d1 100644 --- a/packages/studio/src/index.ts +++ b/packages/studio/src/index.ts @@ -201,6 +201,8 @@ export type { DomEditZOrder } from "./components/editor/useDomEditZOrder"; export type { ZOrderAction } from "./components/editor/canvasContextMenuZOrder"; export type { DomEditCapabilities, DomEditSelection } from "./components/editor/domEditingTypes"; export { useDomStyleCommit } from "./hooks/useDomStyleCommit"; +export { ColorField } from "./components/editor/propertyPanelColor"; +export { GradientField } from "./components/editor/propertyPanelFill"; export type { UseDomStyleCommitOptions } from "./hooks/useDomStyleCommit"; export type { DomEditCommitDeclineReason, DomEditCommitOutcome } from "./hooks/domEditCommitRunner"; export { resolveDomEditSelection } from "./components/editor/domEditingLayers";