Skip to content

Commit

Permalink
fix: table dnd cannot work sometimes (#1411)
Browse files Browse the repository at this point in the history
* fix: table dnd cannot work sometimes

* refactor: extract computer for handles

* chore: remove unneeded changes
  • Loading branch information
Saul-Mirone authored Jul 10, 2024
1 parent 77d0c44 commit 0319b83
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 74 deletions.
28 changes: 15 additions & 13 deletions e2e/stories/components/table-block.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,17 @@ milkdown-table-block .handle {
cursor: grab;
font-size: 14px;
}

milkdown-table-block .cell-handle {
left: -999px;
top: -999px;
z-index: 100;
}
milkdown-table-block .cell-handle[data-show="false"] {
opacity: 0;
}
milkdown-table-block .line-handle[data-show="false"] {
opacity: 0;
}
milkdown-table-block .handle:hover {
opacity: 1;
}

milkdown-table-block .cell-handle {
height: 24px;
transition: opacity 0.2s ease-in-out 0.2s;
transition: opacity 0.2s ease 0.2s;
background-color: #FFB4AB;
padding: 0 8px;
border-radius: 8px;
position: absolute;
}

milkdown-table-block .cell-handle[data-role="col-drag-handle"] {
Expand All @@ -55,6 +45,18 @@ milkdown-table-block .cell-handle[data-role="row-drag-handle"] {
transform: translateX(50%);
}

milkdown-table-block .cell-handle[data-show="false"] {
opacity: 0;
}

milkdown-table-block .line-handle[data-show="false"] {
opacity: 0;
}

milkdown-table-block .handle:hover {
opacity: 1;
}

milkdown-table-block .cell-handle .button-group {
position: absolute;
height: 30px;
Expand Down
32 changes: 27 additions & 5 deletions packages/components/src/table-block/view/drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { useEffect, useHost, useMemo } from 'atomico'
import { commandsCtx } from '@milkdown/core'
import { moveColCommand, moveRowCommand } from '@milkdown/preset-gfm'
import type { Ctx } from '@milkdown/ctx'
import { getRelatedDOM } from './utils'
import type { DragContext, Refs } from './types'
import { computeColHandlePositionByIndex, computeRowHandlePositionByIndex, getRelatedDOM } from './utils'
import type { CellIndex, DragContext, Refs } from './types'

function prepareDndContext(refs: Refs): DragContext | undefined {
const {
Expand Down Expand Up @@ -71,7 +71,11 @@ function handleDrag(refs: Refs, event: DragEvent, fn: (context: DragContext) =>
if (!context)
return

fn(context)
// This is to avoid a chrome bug:
// https://stackoverflow.com/questions/14203734/dragend-dragenter-and-dragleave-firing-off-immediately-when-i-drag
requestAnimationFrame(() => {
fn(context)
})
}

export function createDragRowHandler(refs: Refs) {
Expand Down Expand Up @@ -371,6 +375,12 @@ export function useDragHandlers(
return
if (preview.dataset.show === 'false')
return
const colHandle = refs.colHandleRef.current
if (!colHandle)
return
const rowHandle = refs.rowHandleRef.current
if (!rowHandle)
return

yHandle.dataset.show = 'false'
xHandle.dataset.show = 'false'
Expand All @@ -384,10 +394,22 @@ export function useDragHandlers(
to: info.endIndex,
pos: (getPos?.() ?? 0) + 1,
}
if (info.type === 'col')
if (info.type === 'col') {
commands.call(moveColCommand.key, payload)
else
const index: CellIndex = [0, info.endIndex]
computeColHandlePositionByIndex({
refs,
index,
})
}
else {
commands.call(moveRowCommand.key, payload)
const index: CellIndex = [info.endIndex, 0]
computeRowHandlePositionByIndex({
refs,
index,
})
}
}
const onDragOver = createDragOverHandler(refs)

Expand Down
29 changes: 12 additions & 17 deletions packages/components/src/table-block/view/pointer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import type { EditorView } from '@milkdown/prose/view'
import throttle from 'lodash.throttle'
import { useMemo } from 'atomico'
import type { Refs } from './types'
import { findPointerIndex, getRelatedDOM } from './utils'
import {
computeColHandlePositionByIndex,
computeRowHandlePositionByIndex,
findPointerIndex,
getRelatedDOM,
} from './utils'

export function createPointerMoveHandler(refs: Refs, view?: EditorView): (e: PointerEvent) => void {
return throttle((e: PointerEvent) => {
Expand Down Expand Up @@ -115,23 +120,13 @@ export function createPointerMoveHandler(refs: Refs, view?: EditorView): (e: Poi
rowHandle.dataset.show = 'true'
colHandle.dataset.show = 'true'

const {
row,
headerCol: col,
} = dom
computePosition(row, rowHandle, { placement: 'left' }).then(({ x, y }) => {
rowHandle.dataset.show = 'true'
Object.assign(rowHandle.style, {
left: `${x}px`,
top: `${y}px`,
})
computeRowHandlePositionByIndex({
refs,
index,
})
computePosition(col, colHandle, { placement: 'top' }).then(({ x, y }) => {
colHandle.dataset.show = 'true'
Object.assign(colHandle.style, {
left: `${x}px`,
top: `${y}px`,
})
computeColHandlePositionByIndex({
refs,
index,
})
hoverIndex.current = index
}, 200)
Expand Down
122 changes: 83 additions & 39 deletions packages/components/src/table-block/view/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,34 +93,15 @@ export function recoveryStateBetweenUpdate(
if (!table || table.node !== node)
return

const {
hoverIndex,
colHandleRef,
rowHandleRef,
contentWrapperRef,
} = refs

if (selection.isColSelection()) {
const { $head } = selection
const colIndex = $head.index($head.depth - 1)
const index: CellIndex = [0, colIndex]
hoverIndex.current = index
const colHandle = colHandleRef.current
if (!colHandle)
return
const dom = getRelatedDOM(contentWrapperRef, index)
if (!dom)
return
const { headerCol: col } = dom
colHandle.dataset.show = 'true'

colHandle.querySelector('.button-group')?.setAttribute('data-show', 'true')

computePosition(col, colHandle, { placement: 'top' }).then(({ x, y }) => {
Object.assign(colHandle.style, {
left: `${x}px`,
top: `${y}px`,
})
computeColHandlePositionByIndex({
refs,
index: [0, colIndex],
before: (handleDOM) => {
handleDOM.querySelector('.button-group')?.setAttribute('data-show', 'true')
},
})
return
}
Expand All @@ -130,25 +111,88 @@ export function recoveryStateBetweenUpdate(
if (!rowNode)
return
const rowIndex = findNodeIndex(table.node, rowNode.node)
const index: CellIndex = [rowIndex, 0]
hoverIndex.current = index
const rowHandle = rowHandleRef.current
if (!rowHandle)
return
const dom = getRelatedDOM(contentWrapperRef, index)
if (!dom)
return
const { row } = dom
rowHandle.dataset.show = 'true'
computeRowHandlePositionByIndex({
refs,
index: [rowIndex, 0],
before: (handleDOM) => {
if (rowIndex > 0)
handleDOM.querySelector('.button-group')?.setAttribute('data-show', 'true')
},
})
}
}

if (rowIndex > 0)
rowHandle.querySelector('.button-group')?.setAttribute('data-show', 'true')
interface ComputeHandlePositionByIndexProps {
refs: Refs
index: CellIndex
before?: (handleDOM: HTMLDivElement) => void
after?: (handleDOM: HTMLDivElement) => void
}

computePosition(row, rowHandle, { placement: 'left' }).then(({ x, y }) => {
export function computeColHandlePositionByIndex({
refs,
index,
before,
after,
}: ComputeHandlePositionByIndexProps) {
const {
contentWrapperRef,
colHandleRef,
hoverIndex,
} = refs
const colHandle = colHandleRef.current
if (!colHandle)
return

hoverIndex.current = index
const dom = getRelatedDOM(contentWrapperRef, index)
if (!dom)
return
const { headerCol: col } = dom
colHandle.dataset.show = 'true'
if (before)
before(colHandle)
computePosition(col, colHandle, { placement: 'top' })
.then(({ x, y }) => {
Object.assign(colHandle.style, {
left: `${x}px`,
top: `${y}px`,
})
if (after)
after(colHandle)
})
}

export function computeRowHandlePositionByIndex({
refs,
index,
before,
after,
}: ComputeHandlePositionByIndexProps) {
const {
contentWrapperRef,
rowHandleRef,
hoverIndex,
} = refs
const rowHandle = rowHandleRef.current
if (!rowHandle)
return

hoverIndex.current = index
const dom = getRelatedDOM(contentWrapperRef, index)
if (!dom)
return
const { row } = dom
rowHandle.dataset.show = 'true'
if (before)
before(rowHandle)
computePosition(row, rowHandle, { placement: 'left' })
.then(({ x, y }) => {
Object.assign(rowHandle.style, {
left: `${x}px`,
top: `${y}px`,
})
if (after)
after(rowHandle)
})
}
}

0 comments on commit 0319b83

Please sign in to comment.