@@ -3,19 +3,29 @@ import type { ElementFormatType } from 'lexical'
3
3
4
4
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'
5
5
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection.js'
6
+ import { mergeRegister } from '@lexical/utils'
6
7
import { getTranslation } from '@payloadcms/translations'
7
8
import { Button } from '@payloadcms/ui/elements/Button'
8
9
import { useDocumentDrawer } from '@payloadcms/ui/elements/DocumentDrawer'
9
10
import usePayloadAPI from '@payloadcms/ui/hooks/usePayloadAPI'
10
11
import { useConfig } from '@payloadcms/ui/providers/Config'
11
12
import { useTranslation } from '@payloadcms/ui/providers/Translation'
13
+ import {
14
+ $getSelection ,
15
+ $isNodeSelection ,
16
+ CLICK_COMMAND ,
17
+ COMMAND_PRIORITY_LOW ,
18
+ KEY_BACKSPACE_COMMAND ,
19
+ KEY_DELETE_COMMAND ,
20
+ } from 'lexical'
12
21
import { $getNodeByKey } from 'lexical'
13
- import React , { useCallback , useReducer , useState } from 'react'
22
+ import React , { useCallback , useEffect , useReducer , useRef , useState } from 'react'
14
23
15
24
import type { RelationshipData } from '../RelationshipNode.js'
16
25
17
26
import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js'
18
27
import { INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND } from '../../drawer/commands.js'
28
+ import { $isRelationshipNode } from '../RelationshipNode.js'
19
29
import './index.scss'
20
30
21
31
const baseClass = 'lexical-relationship'
@@ -39,6 +49,8 @@ const Component: React.FC<Props> = (props) => {
39
49
nodeKey,
40
50
} = props
41
51
52
+ const relationshipElemRef = useRef < HTMLDivElement | null > ( null )
53
+
42
54
const [ editor ] = useLexicalComposerContext ( )
43
55
const [ isSelected , setSelected , clearSelection ] = useLexicalNodeSelection ( nodeKey )
44
56
const { field } = useEditorConfigContext ( )
@@ -83,10 +95,57 @@ const Component: React.FC<Props> = (props) => {
83
95
[ cacheBust , setParams , closeDrawer ] ,
84
96
)
85
97
98
+ const onDelete = useCallback (
99
+ ( payload : KeyboardEvent ) => {
100
+ if ( isSelected && $isNodeSelection ( $getSelection ( ) ) ) {
101
+ const event : KeyboardEvent = payload
102
+ event . preventDefault ( )
103
+ const node = $getNodeByKey ( nodeKey )
104
+ if ( $isRelationshipNode ( node ) ) {
105
+ node . remove ( )
106
+ return true
107
+ }
108
+ }
109
+ return false
110
+ } ,
111
+ [ isSelected , nodeKey ] ,
112
+ )
113
+ const onClick = useCallback (
114
+ ( payload : MouseEvent ) => {
115
+ const event = payload
116
+ // Check if relationshipElemRef.target or anything WITHIN relationshipElemRef.target was clicked
117
+ if (
118
+ event . target === relationshipElemRef . current ||
119
+ relationshipElemRef . current ?. contains ( event . target as Node )
120
+ ) {
121
+ if ( event . shiftKey ) {
122
+ setSelected ( ! isSelected )
123
+ } else {
124
+ clearSelection ( )
125
+ setSelected ( true )
126
+ }
127
+ return true
128
+ }
129
+
130
+ return false
131
+ } ,
132
+ [ isSelected , setSelected , clearSelection ] ,
133
+ )
134
+
135
+ useEffect ( ( ) => {
136
+ return mergeRegister (
137
+ editor . registerCommand < MouseEvent > ( CLICK_COMMAND , onClick , COMMAND_PRIORITY_LOW ) ,
138
+
139
+ editor . registerCommand ( KEY_DELETE_COMMAND , onDelete , COMMAND_PRIORITY_LOW ) ,
140
+ editor . registerCommand ( KEY_BACKSPACE_COMMAND , onDelete , COMMAND_PRIORITY_LOW ) ,
141
+ )
142
+ } , [ clearSelection , editor , isSelected , nodeKey , onDelete , setSelected , onClick ] )
143
+
86
144
return (
87
145
< div
88
146
className = { [ baseClass , isSelected && `${ baseClass } --selected` ] . filter ( Boolean ) . join ( ' ' ) }
89
147
contentEditable = { false }
148
+ ref = { relationshipElemRef }
90
149
>
91
150
< div className = { `${ baseClass } __wrap` } >
92
151
< p className = { `${ baseClass } __label` } >
0 commit comments