@@ -6,11 +6,86 @@ import { compose } from 'redux';
66import { inject } from 'lib/Injector' ;
77import classNames from 'classnames' ;
88import i18n from 'i18n' ;
9- import { DndContext , closestCenter , PointerSensor , useSensor , useSensors } from '@dnd-kit/core' ;
10- import { SortableContext , verticalListSortingStrategy } from '@dnd-kit/sortable' ;
9+ import {
10+ DndContext ,
11+ closestCenter ,
12+ PointerSensor ,
13+ KeyboardSensor ,
14+ KeyboardCode ,
15+ useSensor ,
16+ useSensors
17+ } from '@dnd-kit/core' ;
18+ import { SortableContext , verticalListSortingStrategy , arrayMove } from '@dnd-kit/sortable' ;
1119import { restrictToVerticalAxis , restrictToParentElement } from '@dnd-kit/modifiers' ;
1220import { getElementTypeConfig } from 'state/editor/elementConfig' ;
1321
22+ export const keyboardCoordinateGetter = ( event , args ) => {
23+ event . preventDefault ( ) ;
24+ const { active, over, droppableContainers } = args . context ;
25+ if ( ! droppableContainers ) {
26+ return undefined ;
27+ }
28+ if ( ! active || ! active . data || ! active . data . current ) {
29+ return undefined ;
30+ }
31+ const { sortable } = active . data . current ;
32+ if ( ! sortable || ! Array . isArray ( sortable . items ) ) {
33+ return undefined ;
34+ }
35+ const items = sortable . items ;
36+ const overId = over ? over . id : active . id ;
37+ const overIndex = items . indexOf ( overId ) ;
38+ const activeIndex = items . indexOf ( active . id ) ;
39+ if ( overIndex === - 1 || activeIndex === - 1 ) {
40+ return undefined ;
41+ }
42+ const directionUp = - 1 ;
43+ const directionDown = 1 ;
44+ let nextIndex = overIndex ;
45+ let direction = directionDown ;
46+ switch ( event . code ) {
47+ case KeyboardCode . Down :
48+ case KeyboardCode . Right :
49+ nextIndex = Math . min ( overIndex + 1 , items . length - 1 ) ;
50+ break ;
51+ case KeyboardCode . Up :
52+ case KeyboardCode . Left :
53+ nextIndex = Math . max ( 0 , overIndex - 1 ) ;
54+ direction = directionUp ;
55+ break ;
56+ default :
57+ return undefined ;
58+ }
59+ if ( overIndex === nextIndex ) {
60+ return undefined ;
61+ }
62+ const sortedItems = arrayMove ( items , activeIndex , overIndex ) ;
63+ const currentNodeIdAtNextIndex = sortedItems [ nextIndex ] ;
64+ if ( ! droppableContainers . has ( currentNodeIdAtNextIndex ) ) {
65+ return undefined ;
66+ }
67+ if ( ! droppableContainers . has ( active . id ) ) {
68+ return undefined ;
69+ }
70+ const activeNode = droppableContainers . get ( active . id ) . node ?. current ;
71+ if ( ! activeNode ) {
72+ return undefined ;
73+ }
74+ const newNode = droppableContainers . get ( currentNodeIdAtNextIndex ) . node ?. current ;
75+ if ( ! newNode ) {
76+ return undefined ;
77+ }
78+ const activeRect = activeNode . getBoundingClientRect ( ) ;
79+ const newRect = newNode . getBoundingClientRect ( ) ;
80+ const offset = direction === directionDown
81+ ? newRect . top - activeRect . bottom
82+ : activeRect . top - newRect . bottom ;
83+ return {
84+ x : 0 ,
85+ y : activeRect . top + direction * ( newRect . height + offset ) ,
86+ } ;
87+ } ;
88+
1489function ElementList ( {
1590 elements = [ ] ,
1691 sharedObject = {
@@ -35,7 +110,6 @@ function ElementList({
35110 const [ increment , setIncrement ] = useState ( 0 ) ;
36111 const [ hasUnsavedChangesBlockIDs , setHasUnsavedChangesBlockIDs ] = useState ( { } ) ;
37112 const [ validBlockIDs , setValidBlockIDs ] = useState ( { } ) ;
38-
39113 // Update the sharedObject so state can be set from entwine.js
40114 sharedObject . setIncrement = setIncrement ;
41115 sharedObject . setSaveAllElements = setSaveAllElements ;
@@ -139,8 +213,23 @@ function ElementList({
139213 distance : 10
140214 }
141215 } ) ,
216+ useSensor ( KeyboardSensor , {
217+ coordinateGetter : keyboardCoordinateGetter
218+ } )
142219 ) ;
143220
221+ const handleDragStart = ( event ) => {
222+ if ( onDragStart ) {
223+ onDragStart ( event ) ;
224+ }
225+ } ;
226+
227+ const handleDragEnd = ( event ) => {
228+ if ( onDragEnd ) {
229+ onDragEnd ( event ) ;
230+ }
231+ } ;
232+
144233 const handleChangeHasUnsavedChanges = ( elementID , hasUnsavedChanges ) => {
145234 setHasUnsavedChangesBlockIDs ( {
146235 ...hasUnsavedChangesBlockIDs ,
@@ -215,8 +304,8 @@ function ElementList({
215304 modifiers = { [ restrictToVerticalAxis , restrictToParentElement ] }
216305 sensors = { sensors }
217306 collisionDetection = { closestCenter }
218- onDragStart = { onDragStart }
219- onDragEnd = { onDragEnd }
307+ onDragStart = { handleDragStart }
308+ onDragEnd = { handleDragEnd }
220309 >
221310 < SortableContext
222311 items = { elements . map ( element => element . id ) }
@@ -244,6 +333,7 @@ function ElementList({
244333 { 'elemental-editor-list--empty' : ! elements || ! elements . length }
245334 ) ;
246335
336+ // return <div className={listClassNames} ref={listRef}>
247337 return < div className = { listClassNames } >
248338 { renderLoading ( ) }
249339 { renderBlocks ( ) }
0 commit comments