puck icon indicating copy to clipboard operation
puck copied to clipboard

Dispatching `setUi` to update `itemSelector` does not correctly update the selected component in the canvas

Open FedericoBonel opened this issue 9 months ago • 3 comments

Dispatching a reorder action followed by a setUi action to reselect the reordered item doesn't work as expected when called inside an actionBar override. Reordering elements down (increasing their index by one in their dropzone) updates the UI correctly, moving the ActionBar to the new position. However, reordering elements up (decreasing their index by one) moves the item but the ActionBar stays in the previous position until you hover over the item in the canvas.

  • This bug happens in: v0.19.0-canary.0a3e56e
  • This bug doesn't happen in: v0.18.2

Reproduction steps

  1. Render a minimal Puck editor with an actionBar override:
export const usePuckContext = createUsePuck();

overrides={{
  actionBar: () => {
    const dispatch = usePuckContext((state) => state.dispatch);
    const itemSelector = usePuckContext(
      (state) => state.appState.ui.itemSelector
    );

    const handleClickAngle = (type: "up" | "down") => () => {
      const destination = type === "up"
        ? itemSelector?.index - 1
        : itemSelector?.index + 1;

      dispatch({
        type: "reorder",
        sourceIndex: itemSelector?.index,
        destinationIndex: destination,
        destinationZone: itemSelector?.zone,
      });
      dispatch({
        type: "setUi",
        ui: (ui) => ({
          ...ui,
          itemSelector: { ...ui.itemSelector, index: destination },
        }),
      });
    };

    return (
      <ActionBar>
        <ActionBar.Action onClick={handleClickAngle("down")}>Down</ActionBar.Action>
        <ActionBar.Action onClick={handleClickAngle("up")}>Up</ActionBar.Action>
      </ActionBar>
    );
  },
}}
  1. Drag and drop multiple components into the canvas
  2. Select the top component and press "Down"
  3. Select the bottom component and press "Up"

What happens

  • "Move down" (itemSelector.index + 1) works as expected:

    • reorder action correctly moves the item
    • setUi correctly updates the ActionBar position
  • "Move up" (itemSelector.index - 1) fails:

    • reorder action correctly moves the item
    • setUi does not move the ActionBar. It remains visually in the old position until the reordered item is hovered

What I expect to happen

The ActionBar should consistently update its position after setUi, regardless of direction.

Video

https://github.com/user-attachments/assets/8b87159a-4f23-4d28-b391-d2ed652ffd4a

Considerations

FedericoBonel avatar Mar 24 '25 04:03 FedericoBonel

Hi! I can confirm that this issue still exists and it only occurs with version 0.19.x. There is no such problem in the stable version 0.18.3.

Tested on version: 0.19.0-canary.bc5bfff1

The issue reproduces both when using usePuck and createUsePuck.

@FedericoBonel, could you please let me know if we can attach this bug to Milestone 0.19.0?

christian-tchaikovsky avatar May 30 '25 13:05 christian-tchaikovsky

After further testing, I found that this occurs not only within action bar overrides but also when using dispatch anywhere to update the item selector to an index smaller than the current one (e.g., header overrides, header actions, and so on).

FedericoBonel avatar Aug 11 '25 05:08 FedericoBonel

In #1233, @muchisx documented that in their specific use case, the itemSelector did not correctly update in the canvas for any index, not only smaller ones than the current index, but also larger ones.

I could not reproduce it, but I suspect it is directly linked to this issue since the symptom is the same: the itemSelector correctly updates the fields and outline, but it does not update in the canvas until you hover over or interact with the editor.

FedericoBonel avatar Aug 12 '25 02:08 FedericoBonel