@@ -11,6 +11,7 @@ import { Portal } from '@cloudscape-design/component-toolkit/internal';
11
11
12
12
import { fireNonCancelableEvent } from '../../events' ;
13
13
import { joinStrings } from '../../utils/strings' ;
14
+ import { Direction } from '../drag-handle-wrapper/interfaces' ;
14
15
import { SortableAreaProps } from './interfaces' ;
15
16
import useDragAndDropReorder from './use-drag-and-drop-reorder' ;
16
17
import useLiveAnnouncements from './use-live-announcements' ;
@@ -65,14 +66,23 @@ export default function SortableArea<Item>({
65
66
items = { items . map ( item => itemDefinition . id ( item ) ) }
66
67
strategy = { verticalListSortingStrategy }
67
68
>
68
- { items . map ( item => (
69
+ { items . map ( ( item , index ) => (
69
70
< DraggableItem
70
71
key = { itemDefinition . id ( item ) }
71
72
item = { item }
72
73
itemDefinition = { itemDefinition }
74
+ isFirst = { index === 0 }
75
+ isLast = { index === items . length - 1 }
73
76
renderItem = { renderItem }
74
77
onKeyDown = { handleKeyDown }
75
78
dragHandleAriaLabel = { i18nStrings ?. dragHandleAriaLabel }
79
+ onDirectionClick = { direction => {
80
+ const movedItem = item ;
81
+ const oldIndex = items . indexOf ( item ) ;
82
+ const newIndex = direction === 'block-end' ? oldIndex + 1 : oldIndex - 1 ;
83
+ fireNonCancelableEvent ( onItemsChange , { items : arrayMove ( [ ...items ] , oldIndex , newIndex ) , movedItem } ) ;
84
+ i18nStrings ?. liveAnnouncementDndItemCommitted ?.( oldIndex + 1 , newIndex + 1 , items . length ) ;
85
+ } }
76
86
/>
77
87
) ) }
78
88
</ SortableContext >
@@ -126,13 +136,19 @@ function DraggableItem<Item>({
126
136
item,
127
137
itemDefinition,
128
138
dragHandleAriaLabel,
139
+ isFirst,
140
+ isLast,
129
141
onKeyDown,
142
+ onDirectionClick,
130
143
renderItem,
131
144
} : {
132
145
item : Item ;
133
146
itemDefinition : SortableAreaProps . ItemDefinition < Item > ;
134
147
dragHandleAriaLabel ?: string ;
148
+ isFirst : boolean ;
149
+ isLast : boolean ;
135
150
onKeyDown : ( event : React . KeyboardEvent ) => void ;
151
+ onDirectionClick : ( direction : Direction ) => void ;
136
152
renderItem : ( props : SortableAreaProps . RenderItemProps < Item > ) => React . ReactNode ;
137
153
} ) {
138
154
const id = itemDefinition . id ( item ) ;
@@ -173,6 +189,12 @@ function DraggableItem<Item>({
173
189
ariaLabel : joinStrings ( dragHandleAriaLabel , itemDefinition . label ( item ) ) ?? '' ,
174
190
ariaDescribedby : attributes [ 'aria-describedby' ] ,
175
191
disabled : attributes [ 'aria-disabled' ] ,
192
+ directions : {
193
+ 'block-start' : isFirst ? 'disabled' : 'active' ,
194
+ 'block-end' : isLast ? 'disabled' : 'active' ,
195
+ } ,
196
+ triggerMode : 'keyboard-activate' ,
197
+ onDirectionClick,
176
198
} ,
177
199
} ) }
178
200
</ >
0 commit comments