Skip to content
New issue

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

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

Already on GitHub? # to your account

fix(extension-suggestion): get client rect by anchor. #5395

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
55 changes: 44 additions & 11 deletions packages/suggestion/src/suggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,49 @@ export function Suggestion<I = any, TSelected = any>({
`[data-decoration-id="${state.decorationId}"]`,
)

const getClientRectByDecorationNode = () => {
if (!this.key) {
return null
}

// because of `items` can be asynchrounous we’ll search for the current decoration node
const { decorationId } = this.key.getState(editor.state) // eslint-disable-line
const currentDecorationNode = view.dom.querySelector(
`[data-decoration-id="${decorationId}"]`,
)

if (!currentDecorationNode) {
return null
}

return currentDecorationNode.getBoundingClientRect()
}

const getClientRectByAnchor = () => {
const pos = editor.state.selection.$anchor.pos
const coords = editor.view.coordsAtPos(pos)
const {
top, right, bottom, left,
} = coords

try {
const rect = new DOMRect(left, top, right - left, bottom - top)

return rect
} catch (e) {
return null
}
}

const getClientRect = () => {
const rect = getClientRectByDecorationNode()
|| getClientRectByAnchor()

return rect
? () => rect
: null
}

props = {
editor,
range: state.range,
Expand All @@ -225,17 +268,7 @@ export function Suggestion<I = any, TSelected = any>({
decorationNode,
// virtual node for popper.js or tippy.js
// this can be used for building popups without a DOM node
clientRect: decorationNode
? () => {
// because of `items` can be asynchrounous we’ll search for the current decoration node
const { decorationId } = this.key?.getState(editor.state) // eslint-disable-line
const currentDecorationNode = view.dom.querySelector(
`[data-decoration-id="${decorationId}"]`,
)

return currentDecorationNode?.getBoundingClientRect() || null
}
: null,
clientRect: getClientRect(),
}

if (handleStart) {
Expand Down