Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/table #3089

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/swift-eggs-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@udecode/plate-table": patch
---

fix can not remove table column when selection is expanded
6 changes: 6 additions & 0 deletions packages/table/src/merge/deleteColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
getAboveNode,
getPluginOptions,
getPluginType,
isExpanded,
PlateEditor,
removeNodes,
setNodes,
Expand All @@ -15,6 +16,7 @@ import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin';
import { getColSpan } from '../queries/getColSpan';
import { TablePlugin, TTableCellElement, TTableElement } from '../types';
import { getCellTypes } from '../utils';
import { deleteColumnWhenExpanded } from './deleteColumnWhenExpanded';
import { findCellByIndexes } from './findCellByIndexes';
import { getCellIndices } from './getCellIndices';
import { getCellPath } from './getCellPath';
Expand All @@ -36,6 +38,10 @@ export const deleteTableMergeColumn = <V extends Value>(
match: { type: getPluginType(editor, ELEMENT_TABLE) },
});
if (!tableEntry) return;

if (isExpanded(editor.selection))
return deleteColumnWhenExpanded(editor, tableEntry);

const table = tableEntry[0] as TTableElement;

const selectedCellEntry = getAboveNode(editor, {
Expand Down
46 changes: 46 additions & 0 deletions packages/table/src/merge/deleteColumnWhenExpanded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {
createPathRef,
PlateEditor,
removeNodes,
TNodeEntry,
Value,
} from '@udecode/plate-common';
import { PathRef } from 'slate';

import { getTableGridAbove } from '../queries';
import { TTableCellElement } from '../types';
import { getCellRowIndexByPath } from '../utils/getCellRowIndexByPath';

export const deleteColumnWhenExpanded = <V extends Value>(
editor: PlateEditor<V>,
tableEntry: TNodeEntry<TTableCellElement>
) => {
const rowCount = tableEntry[0].children.length;

const cells = getTableGridAbove(editor, {
format: 'cell',
}) as TNodeEntry<TTableCellElement>[];

let lastCellRowIndex = -1;
let selectionRowCount = 0;

const pathRefs: PathRef[] = [];

cells.forEach(([cell, cellPath], index) => {
const currentCellRowIndex = getCellRowIndexByPath(cellPath);

// not on the same line
if (currentCellRowIndex !== lastCellRowIndex) {
selectionRowCount += cell.rowSpan ?? 1;
}

pathRefs.push(createPathRef(editor, cellPath));
lastCellRowIndex = currentCellRowIndex;
});

if (rowCount === selectionRowCount) {
pathRefs.forEach((pathRef) => {
removeNodes(editor, { at: pathRef.unref()! });
});
}
};
6 changes: 6 additions & 0 deletions packages/table/src/merge/deleteRow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getPluginOptions,
getPluginType,
insertElements,
isExpanded,
PlateEditor,
removeNodes,
setNodes,
Expand All @@ -21,6 +22,7 @@ import {
TTableRowElement,
} from '../types';
import { getCellTypes } from '../utils';
import { deleteRowWhenExpanded } from './deleteRowWhenExpanded';
import { findCellByIndexes } from './findCellByIndexes';
import { getCellIndices } from './getCellIndices';

Expand All @@ -41,6 +43,10 @@ export const deleteTableMergeRow = <V extends Value>(
match: { type: getPluginType(editor, ELEMENT_TABLE) },
});
if (!currentTableItem) return;

if (isExpanded(editor.selection))
return deleteRowWhenExpanded(editor, currentTableItem);

const table = currentTableItem[0] as TTableElement;

const selectedCellEntry = getAboveNode(editor, {
Expand Down
39 changes: 39 additions & 0 deletions packages/table/src/merge/deleteRowWhenExpanded.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
PlateEditor,
removeNodes,
TNodeEntry,
Value,
} from '@udecode/plate-common';

import { getTableGridAbove } from '../queries';
import { TTableCellElement } from '../types';

export const deleteRowWhenExpanded = <V extends Value>(
editor: PlateEditor<V>,
[table, tablePath]: TNodeEntry<TTableCellElement>
) => {
const rowCount = table.children.length;

const cells = getTableGridAbove(editor, {
format: 'cell',
}) as TNodeEntry<TTableCellElement>[];

const firsRowIndex = cells[0][1].at(-2) ?? null;

if (firsRowIndex === null) return;

let acrossColumn = 0;

cells.forEach(([cell, cellPath], index) => {
if (cellPath.at(-2) === firsRowIndex) {
acrossColumn += cell.colSpan ?? 1;
}
});

if (acrossColumn === rowCount) {
for (let i = firsRowIndex; i <= acrossColumn; i++) {
const removedPath = tablePath.concat(i);
removeNodes(editor, { at: removedPath });
}
}
};
138 changes: 74 additions & 64 deletions packages/table/src/transforms/deleteColumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
getAboveNode,
getPluginOptions,
getPluginType,
isExpanded,
PlateEditor,
removeNodes,
setNodes,
Expand All @@ -18,6 +19,7 @@ import {
ELEMENT_TR,
} from '../createTablePlugin';
import { deleteTableMergeColumn } from '../merge/deleteColumn';
import { deleteColumnWhenExpanded } from '../merge/deleteColumnWhenExpanded';
import { TablePlugin, TTableElement } from '../types';

export const deleteColumn = <V extends Value>(editor: PlateEditor<V>) => {
Expand All @@ -30,75 +32,83 @@ export const deleteColumn = <V extends Value>(editor: PlateEditor<V>) => {
}

if (
someNode(editor, {
!someNode(editor, {
match: { type: getPluginType(editor, ELEMENT_TABLE) },
})
) {
const tdEntry = getAboveNode(editor, {
match: {
type: [
getPluginType(editor, ELEMENT_TD),
getPluginType(editor, ELEMENT_TH),
],
},
});
const trEntry = getAboveNode(editor, {
match: { type: getPluginType(editor, ELEMENT_TR) },
});
const tableEntry = getAboveNode<TTableElement>(editor, {
match: { type: getPluginType(editor, ELEMENT_TABLE) },
});
return;
}

if (
tdEntry &&
trEntry &&
tableEntry &&
// Cannot delete the last cell
trEntry[0].children.length > 1
) {
const [tableNode, tablePath] = tableEntry;

const tdPath = tdEntry[1];
const colIndex = tdPath.at(-1)!;

const pathToDelete = tdPath.slice();
const replacePathPos = pathToDelete.length - 2;

withoutNormalizing(editor, () => {
tableNode.children.forEach((row, rowIdx) => {
pathToDelete[replacePathPos] = rowIdx;

// for tables containing rows of different lengths
// - don't delete if only one cell in row
// - don't delete if row doesn't have this cell
if (
(row.children as TElement[]).length === 1 ||
colIndex > (row.children as TElement[]).length - 1
)
return;

removeNodes(editor, {
at: pathToDelete,
});
});
const tableEntry = getAboveNode<TTableElement>(editor, {
match: { type: getPluginType(editor, ELEMENT_TABLE) },
});

const { colSizes } = tableNode;

if (colSizes) {
const newColSizes = [...colSizes];
newColSizes.splice(colIndex, 1);

setNodes<TTableElement>(
editor,
{
colSizes: newColSizes,
},
{
at: tablePath,
}
);
}
if (!tableEntry) return;

if (isExpanded(editor.selection))
return deleteColumnWhenExpanded(editor, tableEntry);

const tdEntry = getAboveNode(editor, {
match: {
type: [
getPluginType(editor, ELEMENT_TD),
getPluginType(editor, ELEMENT_TH),
],
},
});
const trEntry = getAboveNode(editor, {
match: { type: getPluginType(editor, ELEMENT_TR) },
});

if (
tdEntry &&
trEntry &&
tableEntry &&
// Cannot delete the last cell
trEntry[0].children.length > 1
) {
const [tableNode, tablePath] = tableEntry;

const tdPath = tdEntry[1];
const colIndex = tdPath.at(-1)!;

const pathToDelete = tdPath.slice();
const replacePathPos = pathToDelete.length - 2;

withoutNormalizing(editor, () => {
tableNode.children.forEach((row, rowIdx) => {
pathToDelete[replacePathPos] = rowIdx;

// for tables containing rows of different lengths
// - don't delete if only one cell in row
// - don't delete if row doesn't have this cell
if (
(row.children as TElement[]).length === 1 ||
colIndex > (row.children as TElement[]).length - 1
)
return;

removeNodes(editor, {
at: pathToDelete,
});
});
}

const { colSizes } = tableNode;

if (colSizes) {
const newColSizes = [...colSizes];
newColSizes.splice(colIndex, 1);

setNodes<TTableElement>(
editor,
{
colSizes: newColSizes,
},
{
at: tablePath,
}
);
}
});
}
};
7 changes: 7 additions & 0 deletions packages/table/src/transforms/deleteRow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
getAboveNode,
getPluginOptions,
getPluginType,
isExpanded,
PlateEditor,
removeNodes,
someNode,
Expand All @@ -10,6 +11,7 @@ import {

import { ELEMENT_TABLE, ELEMENT_TR } from '../createTablePlugin';
import { deleteTableMergeRow } from '../merge/deleteRow';
import { deleteRowWhenExpanded } from '../merge/deleteRowWhenExpanded';
import { TablePlugin, TTableElement } from '../types';

export const deleteRow = <V extends Value>(editor: PlateEditor<V>) => {
Expand All @@ -29,6 +31,11 @@ export const deleteRow = <V extends Value>(editor: PlateEditor<V>) => {
const currentTableItem = getAboveNode<TTableElement>(editor, {
match: { type: getPluginType(editor, ELEMENT_TABLE) },
});
if (!currentTableItem) return;

if (isExpanded(editor.selection))
return deleteRowWhenExpanded(editor, currentTableItem);

const currentRowItem = getAboveNode(editor, {
match: { type: getPluginType(editor, ELEMENT_TR) },
});
Expand Down
5 changes: 5 additions & 0 deletions packages/table/src/utils/getCellRowIndexByPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Path } from 'slate';

export const getCellRowIndexByPath = (cellPath: Path): number => {
return cellPath.at(-2) ?? -1;
};
6 changes: 3 additions & 3 deletions packages/table/src/withMarkTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
isText,
PlateEditor,
setNodes,
TElement,
unsetNodes,
Value,
} from '@udecode/plate-common';
Expand All @@ -27,9 +28,8 @@ export const withMarkTable = <
if (matchesCell.length === 0) return addMark(key, value);

matchesCell.forEach(([cell, cellPath]) => {
setNodes(
setNodes<TElement>(
editor,
//@ts-ignore
{
[key]: value,
},
Expand Down Expand Up @@ -85,7 +85,7 @@ export const withMarkTable = <
keys.splice(keys.indexOf('text'), 1);

keys.forEach((k) => {
totalMarks[k] = true;
totalMarks[k] = item[k];
});
});
});
Expand Down