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>
This commit is contained in:
01zulfi
2026-03-26 12:11:09 +05:00
parent 00a20dda48
commit 8eca88a054

View File

@@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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<HTMLTableColElement>(null);
const tableRef = useRef<HTMLTableElement>();
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<HTMLDivElement>(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 (
<Flex