Skip to content

A tab dragged out of the overflow menu and let go outside the layout takes over the next drag #528

Description

@dongshunyao

Describe the bug

After a tab is dragged out of the overflow menu and let go outside the layout, the next drag of anything into the layout is taken for that tab's drag. When text is then dragged from one input to another inside a tab, the text is not dropped, and the tab from the overflow menu is moved to where the text was let go.

Your Example Website or App

The component in the steps below; no hosted copy.

Steps to Reproduce the Bug or Issue

  1. Render this component, which puts the layout next to a plain panel:
import { Layout, Model, TabNode } from "flexlayout-react";
import "flexlayout-react/style/light.css";

// A pane with two text fields, and a narrow pane with more tabs than fit.
const model = Model.fromJson({
  global: {},
  borders: [],
  layout: {
    type: "row",
    children: [
      { type: "tabset", weight: 70, children: [{ type: "tab", name: "Form", component: "form" }] },
      {
        type: "tabset",
        weight: 30,
        children: Array.from({ length: 12 }, (_, i) => ({
          type: "tab",
          name: `Tab ${i}`,
          component: "text",
        })),
      },
    ],
  },
});

function factory(node: TabNode) {
  return node.getComponent() === "form" ? (
    <div style={{ padding: 16 }}>
      <input defaultValue="drag me" /> <input />
    </div>
  ) : (
    <div style={{ padding: 16 }}>{node.getName()}</div>
  );
}

// The layout sits next to a plain panel, so there is somewhere outside it to
// let go of a drag.
export default function App() {
  return (
    <>
      <div style={{ position: "absolute", left: 0, top: 0, bottom: 0, width: 200, background: "#eee" }}>
        Outside the layout
      </div>
      <div style={{ position: "absolute", left: 200, top: 0, right: 0, bottom: 0 }}>
        <Layout model={model} factory={factory} />
      </div>
    </>
  );
}
  1. Open the overflow menu of the narrow pane, drag one of its items over the grey panel on the left, and let go there.
  2. In the Form pane, select the text of the first input ("drag me") and drag it into the second input.

Expected behavior

The text lands in the second input and the layout does not change, as happens when step 2 is skipped.

Operating System

Windows 10 (10.0.19045)

Browser Type?

Chromium (the build that comes with Playwright 1.63; other browsers not tried)

Browser Version

153.0.8010.12

Screenshots or Videos

None. What the page holds after step 3:

  • step 2 skipped: the second input holds "drag me"; the panes hold Form and Tab 0 to Tab 11
  • after step 2 with "Tab 3": the second input is empty; the panes hold Tab 3 (a new pane), Form, and the other eleven tabs

Additional context

flexlayout-react 0.11.0, React 18.3.1.

The menu item's onDragStart calls setDragNode and then closes the menu with setTimeout(() => api.close(), 0) (src/view/PopupMenu.tsx:393). The menu's root unmounts with the dragged item in it, so the item's onDragEnd never runs and DragDropManager.dragState is never cleared; onDragEnter and onDrop then treat the next drag as that tab's.

Closing the menu when the drag ends fixes it. I checked this against the steps above with the same change made to a copy of dist/index.js, and a tab dragged out of the menu into the layout still docks, with the menu closing afterwards:

                 onDragStart={(event) => {
                     event.stopPropagation(); // prevent starting a tabset drag as well
                     controller.getDragDropManager().setDragNode(event.nativeEvent, it.node);
-                    setTimeout(() => api.close(), 0);
                 }}
-                onDragEnd={() => controller.getDragDropManager().onDragEnded()}
+                onDragEnd={() => {
+                    controller.getDragDropManager().onDragEnded();
+                    api.close();
+                }}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions