[PE-255] fix: remove drag handles from content within table cells (#6487)

* fix: remove drag handles from content within table cells

* style: table cell padding

* style: table cell padding

* fix: insert resizable tables

---------

Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
This commit is contained in:
M. Palanikannan 2025-01-28 20:20:40 +05:30 committed by GitHub
parent 940b5e4e44
commit 421839ec51
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 28 additions and 22 deletions

View file

@ -134,10 +134,6 @@ const SideMenu = (options: SideMenuPluginProps) => {
rect.left -= 8; rect.left -= 8;
} }
if (node.parentElement?.matches("td") || node.parentElement?.matches("th")) {
rect.left += 8;
}
rect.width = options.dragHandleWidth; rect.width = options.dragHandleWidth;
if (!editorSideMenu) return; if (!editorSideMenu) return;

View file

@ -39,7 +39,12 @@ export interface TableOptions {
declare module "@tiptap/core" { declare module "@tiptap/core" {
interface Commands<ReturnType> { interface Commands<ReturnType> {
table: { table: {
insertTable: (options?: { rows?: number; cols?: number; withHeaderRow?: boolean }) => ReturnType; insertTable: (options?: {
rows?: number;
cols?: number;
withHeaderRow?: boolean;
columnWidth?: number;
}) => ReturnType;
addColumnBefore: () => ReturnType; addColumnBefore: () => ReturnType;
addColumnAfter: () => ReturnType; addColumnAfter: () => ReturnType;
deleteColumn: () => ReturnType; deleteColumn: () => ReturnType;
@ -108,9 +113,9 @@ export const Table = Node.create({
addCommands() { addCommands() {
return { return {
insertTable: insertTable:
({ rows = 3, cols = 3, withHeaderRow = false } = {}) => ({ rows = 3, cols = 3, withHeaderRow = false, columnWidth = 150 } = {}) =>
({ tr, dispatch, editor }) => { ({ tr, dispatch, editor }) => {
const node = createTable(editor.schema, rows, cols, withHeaderRow); const node = createTable(editor.schema, rows, cols, withHeaderRow, undefined, columnWidth);
if (dispatch) { if (dispatch) {
const offset = tr.selection.anchor + 1; const offset = tr.selection.anchor + 1;

View file

@ -2,11 +2,12 @@ import { Fragment, Node as ProsemirrorNode, NodeType } from "@tiptap/pm/model";
export function createCell( export function createCell(
cellType: NodeType, cellType: NodeType,
cellContent?: Fragment | ProsemirrorNode | Array<ProsemirrorNode> cellContent?: Fragment | ProsemirrorNode | Array<ProsemirrorNode>,
attrs?: Record<string, any>
): ProsemirrorNode | null | undefined { ): ProsemirrorNode | null | undefined {
if (cellContent) { if (cellContent) {
return cellType.createChecked(null, cellContent); return cellType.createChecked(attrs, cellContent);
} }
return cellType.createAndFill(); return cellType.createAndFill(attrs);
} }

View file

@ -8,21 +8,22 @@ export function createTable(
rowsCount: number, rowsCount: number,
colsCount: number, colsCount: number,
withHeaderRow: boolean, withHeaderRow: boolean,
cellContent?: Fragment | ProsemirrorNode | Array<ProsemirrorNode> cellContent?: Fragment | ProsemirrorNode | Array<ProsemirrorNode>,
columnWidth: number = 100
): ProsemirrorNode { ): ProsemirrorNode {
const types = getTableNodeTypes(schema); const types = getTableNodeTypes(schema);
const headerCells: ProsemirrorNode[] = []; const headerCells: ProsemirrorNode[] = [];
const cells: ProsemirrorNode[] = []; const cells: ProsemirrorNode[] = [];
for (let index = 0; index < colsCount; index += 1) { for (let index = 0; index < colsCount; index += 1) {
const cell = createCell(types.cell, cellContent); const cell = createCell(types.cell, cellContent, { colwidth: [columnWidth] });
if (cell) { if (cell) {
cells.push(cell); cells.push(cell);
} }
if (withHeaderRow) { if (withHeaderRow) {
const headerCell = createCell(types.header_cell, cellContent); const headerCell = createCell(types.header_cell, cellContent, { colwidth: [columnWidth] });
if (headerCell) { if (headerCell) {
headerCells.push(headerCell); headerCells.push(headerCell);

View file

@ -138,8 +138,9 @@ export const insertTableCommand = (editor: Editor, range?: Range) => {
} }
} }
} }
if (range) editor.chain().focus().deleteRange(range).clearNodes().insertTable({ rows: 3, cols: 3 }).run(); if (range)
else editor.chain().focus().clearNodes().insertTable({ rows: 3, cols: 3 }).run(); editor.chain().focus().deleteRange(range).clearNodes().insertTable({ rows: 3, cols: 3, columnWidth: 150 }).run();
else editor.chain().focus().clearNodes().insertTable({ rows: 3, cols: 3, columnWidth: 150 }).run();
}; };
export const insertImage = ({ export const insertImage = ({

View file

@ -88,16 +88,18 @@ export const nodeDOMAtCoords = (coords: { x: number; y: number }) => {
const elements = document.elementsFromPoint(coords.x, coords.y); const elements = document.elementsFromPoint(coords.x, coords.y);
for (const elem of elements) { for (const elem of elements) {
// Check for table wrapper first
if (elem.matches(".table-wrapper")) {
return elem;
}
if (elem.matches("p:first-child") && elem.parentElement?.matches(".ProseMirror")) { if (elem.matches("p:first-child") && elem.parentElement?.matches(".ProseMirror")) {
return elem; return elem;
} }
// if the element is a <p> tag that is the first child of a td or th // Skip table cells
if ( if (elem.closest(".table-wrapper")) {
(elem.matches("td > p:first-child") || elem.matches("th > p:first-child")) && continue;
elem?.textContent?.trim() !== ""
) {
return elem; // Return only if p tag is not empty in td or th
} }
// apply general selector // apply general selector

View file

@ -16,7 +16,7 @@
.table-wrapper table th { .table-wrapper table th {
min-width: 1em; min-width: 1em;
border: 1px solid rgba(var(--color-border-200)); border: 1px solid rgba(var(--color-border-200));
padding: 10px 20px; padding: 7px 10px;
vertical-align: top; vertical-align: top;
box-sizing: border-box; box-sizing: border-box;
position: relative; position: relative;