diff --git a/docs/src/demos/Nodes/Table/index.vue b/docs/src/demos/Nodes/Table/index.vue index 5f0bda14..81cd9cbe 100644 --- a/docs/src/demos/Nodes/Table/index.vue +++ b/docs/src/demos/Nodes/Table/index.vue @@ -39,13 +39,13 @@ ✅ toggleHeaderCell - - ⚠️ fixTables + + ❓️ fixTables ⚠️ toggleCellMerge - + ⚠️ setCellAttr @@ -115,12 +115,59 @@ export default { diff --git a/packages/extension-table/src/TableView.ts b/packages/extension-table/src/TableView.ts new file mode 100644 index 00000000..ace41fef --- /dev/null +++ b/packages/extension-table/src/TableView.ts @@ -0,0 +1,61 @@ +// @ts-nocheck + +export class TableView { + constructor(node, cellMinWidth) { + this.node = node + this.cellMinWidth = cellMinWidth + this.dom = document.createElement('div') + this.dom.className = 'tableWrapper' + this.table = this.dom.appendChild(document.createElement('table')) + this.colgroup = this.table.appendChild(document.createElement('colgroup')) + updateColumns(node, this.colgroup, this.table, cellMinWidth) + this.contentDOM = this.table.appendChild(document.createElement('tbody')) + } + + update(node) { + if (node.type != this.node.type) return false + this.node = node + updateColumns(node, this.colgroup, this.table, this.cellMinWidth) + return true + } + + ignoreMutation(record) { + return record.type == 'attributes' && (record.target == this.table || this.colgroup.contains(record.target)) + } +} + +export function updateColumns(node, colgroup, table, cellMinWidth, overrideCol, overrideValue) { + let totalWidth = 0; let + fixedWidth = true + let nextDOM = colgroup.firstChild; const + row = node.firstChild + for (let i = 0, col = 0; i < row.childCount; i++) { + const { colspan, colwidth } = row.child(i).attrs + for (let j = 0; j < colspan; j++, col++) { + const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j] + const cssWidth = hasWidth ? `${hasWidth}px` : '' + totalWidth += hasWidth || cellMinWidth + if (!hasWidth) fixedWidth = false + if (!nextDOM) { + colgroup.appendChild(document.createElement('col')).style.width = cssWidth + } else { + if (nextDOM.style.width != cssWidth) nextDOM.style.width = cssWidth + nextDOM = nextDOM.nextSibling + } + } + } + + while (nextDOM) { + const after = nextDOM.nextSibling + nextDOM.parentNode.removeChild(nextDOM) + nextDOM = after + } + + if (fixedWidth) { + table.style.width = `${totalWidth}px` + table.style.minWidth = '' + } else { + table.style.width = '' + table.style.minWidth = `${totalWidth}px` + } +} diff --git a/packages/extension-table/src/table.ts b/packages/extension-table/src/table.ts index df3830cb..72e79130 100644 --- a/packages/extension-table/src/table.ts +++ b/packages/extension-table/src/table.ts @@ -1,3 +1,4 @@ +// @ts-nocheck import { Command, Node, mergeAttributes } from '@tiptap/core' import { tableEditing, @@ -15,9 +16,10 @@ import { toggleHeaderColumn, toggleHeaderRow, toggleHeaderCell, - // setCellAttr, - // fixTables, + setCellAttr, + fixTables, } from 'prosemirror-tables' +import { TableView } from './TableView' export interface TableOptions { HTMLAttributes: { @@ -113,10 +115,18 @@ export const Table = Node.create({ console.log('toggleHeaderCell') return toggleHeaderCell(state, dispatch) }, - // fixTables: (): Command => ({ state, dispatch }) => { - // console.log('fixTables') - // return fixTables(state, dispatch) - // }, + fixTables: (): Command => ({ state, dispatch }) => { + console.log('fixTables') + const transaction = fixTables(state) + + console.log(transaction) + if (transaction) { + // @ts-ignore + return dispatch(transaction) + } + + return false + }, // toggleCellMerge: () => ( // (state, dispatch) => { // if (mergeCells(state, dispatch)) { @@ -125,14 +135,32 @@ export const Table = Node.create({ // splitCell(state, dispatch) // } // ), - // setCellAttr: ({ name, value }) => setCellAttr(name, value), + // setCellAttr: ({ name, value }): Command => () => { + // console.log('setCellAttr') + // return setCellAttr(name, value) + // }, } }, addProseMirrorPlugins() { + const columnResizingOptions = { + handleWidth: 5, + cellMinWidth: 25, + View: TableView, + lastColumnResizable: true, + } + + const tableEditingOptions = { + allowTableNodeSelection: false, + } + return [ - ...(this.options.resizable ? [columnResizing({})] : []), - tableEditing({}), + ...(this.options.resizable + // @ts-ignore + ? [columnResizing(columnResizingOptions)] + : [] + ), + tableEditing(tableEditingOptions), ] }, })