diff --git a/packages/studio/src/components/editor/propertyPanelFxSection.test.tsx b/packages/studio/src/components/editor/propertyPanelFxSection.test.tsx index 345d3574d9..c6a35307f7 100644 --- a/packages/studio/src/components/editor/propertyPanelFxSection.test.tsx +++ b/packages/studio/src/components/editor/propertyPanelFxSection.test.tsx @@ -163,6 +163,55 @@ describe("FxSection chain", () => { expect(next.nodes.map((n) => n.type)).toEqual(["reverb", "peaking"]); }); + it("keeps a half-typed value with its own effect across a reorder", () => { + // Rows used to be keyed `${type}-${index}`, so two effects of the same type + // kept their keys through a reorder and React reused each row where it + // stood. The controls hold real state — a number field mid-edit is held as + // text — so the buffer stayed at the position and landed on whichever + // effect moved into it. + const peaking = (id: string, frequency: number) => ({ + type: "peaking", + id, + enabled: true, + params: { ...defaultAudioFxParams("peaking"), frequency }, + }); + const a = peaking("pa", 400); + const b = peaking("pb", 1600); + const chainOfNodes = (...nodes: unknown[]): HfAudioFxChain => + ({ version: 1, nodes }) as HfAudioFxChain; + + const host = document.createElement("div"); + document.body.append(host); + const root = createRoot(host); + const render = (chain: HfAudioFxChain) => + act(() => { + root.render( + , + ); + }); + + render(chainOfNodes(a, b)); + // Only the first card is open, which is the one being edited. + const openFrequency = (): HTMLInputElement => + host.querySelector(".hf-fx-node .hf-fx-number")!; + + expect(openFrequency().value).toBe("400"); + typeInto(openFrequency(), "123"); + expect(openFrequency().value).toBe("123"); + + // The author moves that effect down; the other one takes the open slot. + render(chainOfNodes(b, a)); + + expect(openFrequency().value).toBe("1600"); + }); + it("cannot move the ends past themselves", () => { const { host } = mount({ chain: chainOf("peaking", "reverb") }); const ups = host.querySelectorAll('.hf-fx-move[title="Move up"]'); diff --git a/packages/studio/src/components/editor/propertyPanelFxSection.tsx b/packages/studio/src/components/editor/propertyPanelFxSection.tsx index ab696119af..33fda26891 100644 --- a/packages/studio/src/components/editor/propertyPanelFxSection.tsx +++ b/packages/studio/src/components/editor/propertyPanelFxSection.tsx @@ -795,7 +795,13 @@ export function FxSection({ handBuilt.map(({ node, i }) => { return (