mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
[WIKI-543] fix: unable to delete last cell of a table (#7394)
* fix: delete last cell of a table * refactor: last cell selection logic
This commit is contained in:
committed by
GitHub
parent
48f1999c95
commit
7136b3129b
@@ -24,7 +24,7 @@ import { CORE_EXTENSIONS } from "@/constants/extension";
|
||||
import { isCellSelection } from "@/extensions/table/table/utilities/helpers";
|
||||
// types
|
||||
import { TEditorCommands } from "@/types";
|
||||
// local components
|
||||
// local imports
|
||||
import { TextAlignmentSelector } from "./alignment-selector";
|
||||
|
||||
type EditorBubbleMenuProps = Omit<BubbleMenuProps, "children">;
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { mergeAttributes, Node } from "@tiptap/core";
|
||||
import { TableMap } from "@tiptap/pm/tables";
|
||||
// constants
|
||||
import { CORE_EXTENSIONS } from "@/constants/extension";
|
||||
// helpers
|
||||
import { findParentNodeOfType } from "@/helpers/common";
|
||||
// local imports
|
||||
import { TableCellSelectionOutlinePlugin } from "./plugins/selection-outline/plugin";
|
||||
import { DEFAULT_COLUMN_WIDTH } from "./table";
|
||||
import { isCellSelection } from "./table/utilities/helpers";
|
||||
|
||||
export interface TableCellOptions {
|
||||
HTMLAttributes: Record<string, any>;
|
||||
@@ -54,6 +58,47 @@ export const TableCell = Node.create<TableCellOptions>({
|
||||
return [TableCellSelectionOutlinePlugin(this.editor)];
|
||||
},
|
||||
|
||||
addKeyboardShortcuts() {
|
||||
return {
|
||||
Backspace: ({ editor }) => {
|
||||
const { state } = editor.view;
|
||||
const { selection } = state;
|
||||
|
||||
if (isCellSelection(selection)) return false;
|
||||
|
||||
// Check if we're at the start of the cell
|
||||
if (selection.from !== selection.to || selection.$head.parentOffset !== 0) return false;
|
||||
|
||||
// Find table and current cell
|
||||
const tableNode = findParentNodeOfType(selection, [CORE_EXTENSIONS.TABLE])?.node;
|
||||
const currentCellInfo = findParentNodeOfType(selection, [
|
||||
CORE_EXTENSIONS.TABLE_CELL,
|
||||
CORE_EXTENSIONS.TABLE_HEADER,
|
||||
]);
|
||||
const currentCellNode = currentCellInfo?.node;
|
||||
const cellPos = currentCellInfo?.pos;
|
||||
const cellDepth = currentCellInfo?.depth;
|
||||
|
||||
if (!tableNode || !currentCellNode || cellPos === null || cellDepth === null) return false;
|
||||
|
||||
// Check if this is the only cell in the TableMap (1 row, 1 column)
|
||||
const tableMap = TableMap.get(tableNode);
|
||||
const isOnlyCell = tableMap.width === 1 && tableMap.height === 1;
|
||||
if (!isOnlyCell) return false;
|
||||
|
||||
// Cell has content, select the entire cell
|
||||
// Use the position that points to the cell node itself, not its content
|
||||
const cellNodePos = selection.$head.before(cellDepth);
|
||||
|
||||
editor.commands.setCellSelection({
|
||||
anchorCell: cellNodePos,
|
||||
headCell: cellNodePos,
|
||||
});
|
||||
return true;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
return [{ tag: "td" }];
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@ export const insertLineAboveTableAction: KeyboardShortcutCommand = ({ editor })
|
||||
const { selection } = editor.state;
|
||||
|
||||
// Find the table node and its position
|
||||
const tableNode = findParentNodeOfType(selection, CORE_EXTENSIONS.TABLE);
|
||||
const tableNode = findParentNodeOfType(selection, [CORE_EXTENSIONS.TABLE]);
|
||||
if (!tableNode) return false;
|
||||
|
||||
const tablePos = tableNode.pos;
|
||||
|
||||
@@ -13,7 +13,7 @@ export const insertLineBelowTableAction: KeyboardShortcutCommand = ({ editor })
|
||||
const { selection } = editor.state;
|
||||
|
||||
// Find the table node and its position
|
||||
const tableNode = findParentNodeOfType(selection, CORE_EXTENSIONS.TABLE);
|
||||
const tableNode = findParentNodeOfType(selection, [CORE_EXTENSIONS.TABLE]);
|
||||
if (!tableNode) return false;
|
||||
|
||||
const tablePos = tableNode.pos;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
|
||||
import { EditorState, Selection } from "@tiptap/pm/state";
|
||||
// plane imports
|
||||
import { cn } from "@plane/utils";
|
||||
@@ -21,17 +22,28 @@ export const getEditorClassNames = ({ noBorder, borderOnFocus, containerClassNam
|
||||
);
|
||||
|
||||
// Helper function to find the parent node of a specific type
|
||||
export function findParentNodeOfType(selection: Selection, typeName: string) {
|
||||
export const findParentNodeOfType = (
|
||||
selection: Selection,
|
||||
typeName: string[]
|
||||
): {
|
||||
node: ProseMirrorNode;
|
||||
pos: number;
|
||||
depth: number;
|
||||
} | null => {
|
||||
let depth = selection.$anchor.depth;
|
||||
while (depth > 0) {
|
||||
const node = selection.$anchor.node(depth);
|
||||
if (node.type.name === typeName) {
|
||||
return { node, pos: selection.$anchor.start(depth) - 1 };
|
||||
if (typeName.includes(node.type.name)) {
|
||||
return {
|
||||
node,
|
||||
pos: selection.$anchor.start(depth) - 1,
|
||||
depth,
|
||||
};
|
||||
}
|
||||
depth--;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const findTableAncestor = (node: Node | null): HTMLTableElement | null => {
|
||||
while (node !== null && node.nodeName !== "TABLE") {
|
||||
|
||||
Reference in New Issue
Block a user