From 8eca88a0540d914ea332fec673d745993b60c9e2 Mon Sep 17 00:00:00 2001
From: 01zulfi <85733202+01zulfi@users.noreply.github.com>
Date: Thu, 26 Mar 2026 12:11:09 +0500
Subject: [PATCH] editor: fix table column toolbar not showing in correct
position * also scroll to the newly created column if it is not visible
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
---
.../editor/src/extensions/table/component.tsx | 51 ++++++++++++++-----
1 file changed, 39 insertions(+), 12 deletions(-)
diff --git a/packages/editor/src/extensions/table/component.tsx b/packages/editor/src/extensions/table/component.tsx
index 43767eb9b..966507c0b 100644
--- a/packages/editor/src/extensions/table/component.tsx
+++ b/packages/editor/src/extensions/table/component.tsx
@@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-import { Box, Flex } from "@theme-ui/components";
+import { Flex } from "@theme-ui/components";
import { ReactNodeView, ReactNodeViewProps } from "../react/index.js";
import { Node as ProsemirrorNode } from "prosemirror-model";
import { Editor } from "../../types.js";
import { Editor as TiptapEditor } from "@tiptap/core";
-import { useCallback, useEffect, useRef } from "react";
+import { useEffect, useRef } from "react";
import { EditorView, NodeView } from "prosemirror-view";
import {
InsertColumnRight,
@@ -31,15 +31,14 @@ import {
TableProperties
} from "../../toolbar/tools/table.js";
import { getToolDefinition } from "../../toolbar/tool-definitions.js";
-import { getPosition, ScrollContainer } from "@notesnook/ui";
+import { getPosition } from "@notesnook/ui";
import {
findSelectedDOMNode,
hasSameAttributes
} from "../../utils/prosemirror.js";
-import { DesktopOnly, MobileOnly } from "../../components/responsive/index.js";
+import { DesktopOnly } from "../../components/responsive/index.js";
import { TextDirections } from "../text-direction/index.js";
import { strings } from "@notesnook/intl";
-import { useIsMobile } from "../../toolbar/stores/toolbar-store.js";
import { updateColumnsOnResize } from "./prosemirror-tables/tableview.js";
export function TableComponent(
@@ -49,7 +48,6 @@ export function TableComponent(
const colgroupRef = useRef(null);
const tableRef = useRef();
const { textDirection } = node.attrs;
- const isMobile = useIsMobile();
useEffect(() => {
if (!colgroupRef.current || !tableRef.current) return;
@@ -62,6 +60,35 @@ export function TableComponent(
);
}, [node, cellMinWidth]);
+ useEffect(() => {
+ function onSelectionUpdate() {
+ if (!tableRef?.current) return;
+
+ const scrollContainer = tableRef.current.parentElement;
+ if (!scrollContainer) return;
+
+ const currentCell = findSelectedDOMNode(editor, [
+ "tableCell",
+ "tableHeader"
+ ]);
+ if (!currentCell || !tableRef.current.contains(currentCell)) return;
+
+ const cellRect = currentCell.getBoundingClientRect();
+ const containerRect = scrollContainer.getBoundingClientRect();
+
+ if (cellRect.right > containerRect.right) {
+ scrollContainer.scrollLeft += cellRect.right - containerRect.right;
+ } else if (cellRect.left < containerRect.left) {
+ scrollContainer.scrollLeft -= containerRect.left - cellRect.left;
+ }
+ }
+
+ editor.on("selectionUpdate", onSelectionUpdate);
+ return () => {
+ editor.off("selectionUpdate", onSelectionUpdate);
+ };
+ }, []);
+
// useEffect(() => {
// function transactionListener({
// editor
@@ -258,7 +285,6 @@ function TableRowToolbar(props: TableToolbarProps) {
function TableColumnToolbar(props: TableToolbarProps) {
const { editor, table } = props;
const columnToolsRef = useRef(null);
- const isMobile = useIsMobile();
useEffect(() => {
function onSelectionUpdate() {
@@ -276,7 +302,6 @@ function TableColumnToolbar(props: TableToolbarProps) {
}
columnToolsRef.current.style.display = "flex";
- // tableRef.current
const pos = getPosition(columnToolsRef.current, {
location: "top",
align: "center",
@@ -285,19 +310,21 @@ function TableColumnToolbar(props: TableToolbarProps) {
yOffset: 2
});
- const scrollLeft = isMobile
- ? table.current.parentElement?.parentElement?.scrollLeft || 0
- : table.current?.closest(".simplebar-content-wrapper")?.scrollLeft || 0;
+ const scrollLeft = table.current?.parentElement?.scrollLeft || 0;
columnToolsRef.current.style.left = `${pos.left - scrollLeft}px`;
columnToolsRef.current.style.top = `${pos.top}px`;
}
+ const scrollContainer = table?.current?.parentElement;
+
editor.on("selectionUpdate", onSelectionUpdate);
+ scrollContainer?.addEventListener("scroll", onSelectionUpdate);
return () => {
editor.off("selectionUpdate", onSelectionUpdate);
+ scrollContainer?.removeEventListener("scroll", onSelectionUpdate);
};
- }, [isMobile]);
+ }, []);
return (