-
-
- {titleContent ?? (
- <>
- {icon && {icon}}
-
- {title}
-
- >
- )}
-
-
- {headerExtras}
- {actionsContent}
-
-
+
+ {toolbar ?? (
+
+ )}
);
}
diff --git a/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/components/DefaultHeaderContent/DefaultHeaderContent.tsx b/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/components/DefaultHeaderContent/DefaultHeaderContent.tsx
new file mode 100644
index 00000000000..14261228da5
--- /dev/null
+++ b/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/components/DefaultHeaderContent/DefaultHeaderContent.tsx
@@ -0,0 +1,48 @@
+import { cn } from "@superset/ui/utils";
+import type { ReactNode } from "react";
+
+interface DefaultHeaderContentProps {
+ title: ReactNode;
+ icon?: ReactNode;
+ isActive: boolean;
+ titleContent?: ReactNode;
+ headerExtras?: ReactNode;
+ actionsContent: ReactNode;
+}
+
+export function DefaultHeaderContent({
+ title,
+ icon,
+ isActive,
+ titleContent,
+ headerExtras,
+ actionsContent,
+}: DefaultHeaderContentProps) {
+ return (
+
+
+ {titleContent ?? (
+ <>
+ {icon && {icon}}
+
+ {title}
+
+ >
+ )}
+
+ {/* biome-ignore lint/a11y/noStaticElementInteractions: stop drag from starting on action buttons */}
+
e.stopPropagation()}
+ >
+ {headerExtras}
+ {actionsContent}
+
+
+ );
+}
diff --git a/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/components/DefaultHeaderContent/index.ts b/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/components/DefaultHeaderContent/index.ts
new file mode 100644
index 00000000000..63f7459df15
--- /dev/null
+++ b/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/components/DefaultHeaderContent/index.ts
@@ -0,0 +1 @@
+export { DefaultHeaderContent } from "./DefaultHeaderContent";
diff --git a/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/index.ts b/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/index.ts
index 6aee6da8df3..19afc34df92 100644
--- a/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/index.ts
+++ b/packages/panes/src/react/components/Workspace/components/Tab/components/Pane/components/PaneHeader/index.ts
@@ -1 +1 @@
-export { PaneHeader } from "./PaneHeader";
+export { PANE_DRAG_TYPE, PaneHeader } from "./PaneHeader";
diff --git a/packages/panes/src/react/components/Workspace/components/TabBar/components/TabItem/TabItem.tsx b/packages/panes/src/react/components/Workspace/components/TabBar/components/TabItem/TabItem.tsx
index 4cbec17bece..5ae1981a990 100644
--- a/packages/panes/src/react/components/Workspace/components/TabBar/components/TabItem/TabItem.tsx
+++ b/packages/panes/src/react/components/Workspace/components/TabBar/components/TabItem/TabItem.tsx
@@ -9,8 +9,10 @@ import {
import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip";
import { cn } from "@superset/ui/utils";
import { PencilIcon, XIcon } from "lucide-react";
-import { type ReactNode, useState } from "react";
+import { type ReactNode, useCallback, useRef, useState } from "react";
+import { useDrop } from "react-dnd";
import type { Tab } from "../../../../../../../types";
+import { PANE_DRAG_TYPE } from "../../../Tab/components/Pane/components/PaneHeader";
import { TabRenameInput } from "./components/TabRenameInput";
interface TabItemProps
{
@@ -57,10 +59,38 @@ export function TabItem({
stopEditing();
};
+ const [{ isOver }, connectDrop] = useDrop(
+ () => ({
+ accept: PANE_DRAG_TYPE,
+ hover: () => {
+ if (!isActive) onSelect();
+ },
+ collect: (monitor) => ({
+ isOver: monitor.isOver(),
+ }),
+ }),
+ [isActive, onSelect],
+ );
+
+ const nodeRef = useRef(null);
+ const setDropRef = useCallback(
+ (node: HTMLDivElement | null) => {
+ (nodeRef as React.MutableRefObject).current = node;
+ connectDrop(node);
+ },
+ [connectDrop],
+ );
+
return (
-