@@ -9,21 +9,18 @@ import {
99 TrashBin ,
1010 Xmark ,
1111} from '@gravity-ui/icons' ;
12- import { Button , DropdownMenu , Icon } from '@gravity-ui/uikit' ;
13- import { NodeWithPos , findChildren , findParentNodeClosestToPos } from 'prosemirror-utils ' ;
14- import { EditorView , NodeView , NodeViewConstructor } from 'prosemirror-view ' ;
15- import { createPortal } from 'react-dom ' ;
12+ import { Button , DropdownMenu , Icon , Portal } from '@gravity-ui/uikit' ;
13+ import type { Node } from 'prosemirror-model ' ;
14+ import { NodeWithPos , findParentNodeClosestToPos } from 'prosemirror-utils ' ;
15+ import type { EditorView , NodeView , NodeViewConstructor } from 'prosemirror-view ' ;
1616
1717import { cn } from '../../../../../classname' ;
1818import { bindActions } from '../../../../../core' ;
1919import { i18n } from '../../../../../i18n/yfm-table' ;
2020import { ErrorLoggerBoundary } from '../../../../../react-utils/ErrorBoundary' ;
21- import {
22- getTableDimensions ,
23- isTableCellNode ,
24- isTableNode ,
25- isTableRowNode ,
26- } from '../../../../../table-utils' ;
21+ import { getTableDimensions , isTableNode } from '../../../../../table-utils' ;
22+ import { getChildByNode } from '../../../../../utils/node-children' ;
23+ import { getChildrenOfNode } from '../../../../../utils/nodes' ;
2724import { getReactRendererFromState } from '../../../../behavior/ReactRenderer' ;
2825
2926import { controlActions } from './actions' ;
@@ -204,60 +201,53 @@ const Controls: React.FC<Props> = function Controls({
204201} ;
205202
206203export const yfmTableCellView : NodeViewConstructor = ( node , view , getPos ) : NodeView => {
207- const dom = document . createElement ( 'td' ) ;
208- const contentDOM = document . createElement ( 'div' ) ;
209- const control = document . createElement ( 'span' ) ;
210- control . setAttribute ( 'style' , 'width: 0; height: 0; float: left;' ) ;
211-
212- dom . setAttribute ( 'style' , 'position: relative; overflow: visible;' ) ;
213-
214204 const getParentTable = ( ) =>
215205 findParentNodeClosestToPos ( view . state . doc . resolve ( getPos ( ) ! ) , isTableNode ) ;
216- const parentTable = getParentTable ( ) ;
217206
218- // @ts -expect-error
219- if ( ! parentTable ) return { } ;
220-
221- const rowNodes = findChildren ( parentTable ?. node , isTableRowNode ) ;
207+ const parentTable = getParentTable ( ) ;
222208
223- const relativeCelPos = getPos ( ) ! - parentTable ?. pos ;
209+ const cellCoords = parentTable ? findCellCoords ( parentTable . node , node ) : null ;
224210
225- const rowNumber = rowNodes . findIndex (
226- ( _v , i ) =>
227- relativeCelPos > rowNodes [ i ] . pos &&
228- relativeCelPos < ( rowNodes [ i + 1 ] ?. pos || Number . MAX_SAFE_INTEGER ) ,
229- ) ;
211+ // @ts -expect-error
212+ if ( ! cellCoords ) return { } ;
230213
231- const parentRow = rowNodes [ rowNumber ] ;
214+ const { cellIndex, rowIndex} = cellCoords ;
215+ const isFirstRow = rowIndex === 0 ;
216+ const isFirstColumn = cellIndex === 0 ;
232217
233- const columnNumber = findChildren ( parentRow . node , isTableCellNode ) . findIndex ( ( c ) => {
234- return c . pos === relativeCelPos - parentRow . pos - 2 ;
235- } ) ;
218+ if ( ! isFirstRow && ! isFirstColumn ) {
219+ // in this case, we don't need custom nodeView.
220+ // @ts -expect-error
221+ return { } ;
222+ }
236223
237- const isFirstInRow = rowNodes . findIndex ( ( r ) => r . pos === relativeCelPos - 2 ) >= 0 ;
224+ const dom = document . createElement ( 'td' ) ;
225+ const contentDOM = document . createElement ( 'div' ) ;
226+ const control = document . createElement ( 'span' ) ;
227+ control . setAttribute ( 'style' , 'width: 0; height: 0; float: left;' ) ;
228+ dom . setAttribute ( 'style' , 'position: relative; overflow: visible;' ) ;
238229
239230 dom . appendChild ( contentDOM ) ;
240231 dom . appendChild ( control ) ;
241232
242- const renderItem = getReactRendererFromState ( view . state ) . createItem ( 'yfm-table-cell-view' , ( ) =>
243- createPortal (
244- < ErrorLoggerBoundary >
245- < Controls
246- columnNumber = { columnNumber }
247- rowNumber = { rowNumber }
248- isFirstInRow = { isFirstInRow }
249- isInFirstRow = { rowNumber === 0 }
250- getParentTable = { getParentTable }
251- view = { view }
252- />
253- </ ErrorLoggerBoundary > ,
254- control ,
233+ const renderItem = getReactRendererFromState ( view . state ) . createItem (
234+ 'yfm-table-cell-view' ,
235+ ( ) => (
236+ < Portal container = { control } >
237+ < ErrorLoggerBoundary >
238+ < Controls
239+ columnNumber = { cellIndex }
240+ rowNumber = { rowIndex }
241+ isFirstInRow = { isFirstColumn }
242+ isInFirstRow = { isFirstRow }
243+ getParentTable = { getParentTable }
244+ view = { view }
245+ />
246+ </ ErrorLoggerBoundary >
247+ </ Portal >
255248 ) ,
256249 ) ;
257250
258- contentDOM . setAttribute ( 'data-row-number' , String ( rowNumber ) ) ;
259- contentDOM . setAttribute ( 'data-col-number' , String ( columnNumber ) ) ;
260-
261251 return {
262252 dom,
263253 contentDOM,
@@ -275,3 +265,18 @@ export const yfmTableCellView: NodeViewConstructor = (node, view, getPos): NodeV
275265 } ,
276266 } ;
277267} ;
268+
269+ function findCellCoords ( table : Node , cell : Node ) {
270+ if ( ! table . lastChild ) return null ;
271+ const rows = getChildrenOfNode ( table . lastChild ) ; // children of tBody
272+ for ( const row of rows ) {
273+ const node = getChildByNode ( row . node , cell ) ;
274+ if ( node ) {
275+ return {
276+ rowIndex : row . index ,
277+ cellIndex : node . index ,
278+ } ;
279+ }
280+ }
281+ return null ;
282+ }
0 commit comments