@react-spectrum/list 3.0.1-nightly.3451 → 3.0.1-nightly.3458

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/ListView.tsx CHANGED
@@ -15,7 +15,7 @@ import type {DraggableCollectionState, DroppableCollectionState} from '@react-st
15
15
  import {DragHooks, DropHooks} from '@react-spectrum/dnd';
16
16
  import type {DroppableCollectionResult} from '@react-aria/dnd';
17
17
  import {filterDOMProps, useLayoutEffect} from '@react-aria/utils';
18
- import {FocusRing} from '@react-aria/focus';
18
+ import {FocusRing, FocusScope} from '@react-aria/focus';
19
19
  import InsertionIndicator from './InsertionIndicator';
20
20
  // @ts-ignore
21
21
  import intlMessages from '../intl/*.json';
@@ -180,84 +180,86 @@ function ListView<T extends object>(props: SpectrumListViewProps<T>, ref: DOMRef
180
180
 
181
181
  return (
182
182
  <ListViewContext.Provider value={{state, dragState, dropState, dragHooks, dropHooks, onAction, isListDraggable, isListDroppable, layout, loadingState}}>
183
- <FocusRing focusRingClass={classNames(listStyles, 'focus-ring')}>
184
- <Virtualizer
185
- {...mergeProps(isListDroppable && droppableCollection?.collectionProps, gridProps)}
186
- {...filterDOMProps(otherProps)}
187
- {...gridProps}
188
- {...styleProps}
189
- isLoading={isLoading}
190
- onLoadMore={onLoadMore}
191
- ref={domRef}
192
- focusedKey={focusedKey}
193
- scrollDirection="vertical"
194
- className={
195
- classNames(
196
- listStyles,
197
- 'react-spectrum-ListView',
198
- `react-spectrum-ListView--${density}`,
199
- 'react-spectrum-ListView--emphasized',
200
- {
201
- 'react-spectrum-ListView--quiet': isQuiet,
202
- 'react-spectrum-ListView--loadingMore': loadingState === 'loadingMore',
203
- 'react-spectrum-ListView--draggable': !!isListDraggable,
204
- 'react-spectrum-ListView--dropTarget': !!isRootDropTarget,
205
- 'react-spectrum-ListView--isVerticalScrollbarVisible': isVerticalScrollbarVisible,
206
- 'react-spectrum-ListView--isHorizontalScrollbarVisible': isHorizontalScrollbarVisible,
207
- 'react-spectrum-ListView--hasAnyChildren': hasAnyChildren,
208
- 'react-spectrum-ListView--wrap': overflowMode === 'wrap'
209
- },
210
- styleProps.className
211
- )
212
- }
213
- layout={layout}
214
- collection={collection}
215
- transitionDuration={isLoading ? 160 : 220}>
216
- {(type, item) => {
217
- if (type === 'item') {
218
- return (
219
- <>
220
- {isListDroppable && collection.getKeyBefore(item.key) == null &&
221
- <RootDropIndicator key="root" />
222
- }
223
- {isListDroppable &&
224
- <InsertionIndicator
225
- key={`${item.key}-before`}
226
- target={{key: item.key, type: 'item', dropPosition: 'before'}} />
227
- }
228
- <ListViewItem item={item} isEmphasized hasActions={!!onAction} />
229
- {isListDroppable &&
230
- <InsertionIndicator
231
- key={`${item.key}-after`}
232
- target={{key: item.key, type: 'item', dropPosition: 'after'}}
233
- isPresentationOnly={collection.getKeyAfter(item.key) != null} />
234
- }
235
- </>
236
- );
237
- } else if (type === 'loader') {
238
- return (
239
- <CenteredWrapper>
240
- <ProgressCircle
241
- isIndeterminate
242
- aria-label={collection.size > 0 ? stringFormatter.format('loadingMore') : stringFormatter.format('loading')} />
243
- </CenteredWrapper>
244
- );
245
- } else if (type === 'placeholder') {
246
- let emptyState = props.renderEmptyState ? props.renderEmptyState() : null;
247
- if (emptyState == null) {
248
- return null;
249
- }
250
-
251
- return (
252
- <CenteredWrapper>
253
- {emptyState}
254
- </CenteredWrapper>
255
- );
183
+ <FocusScope>
184
+ <FocusRing focusRingClass={classNames(listStyles, 'focus-ring')}>
185
+ <Virtualizer
186
+ {...mergeProps(isListDroppable && droppableCollection?.collectionProps, gridProps)}
187
+ {...filterDOMProps(otherProps)}
188
+ {...gridProps}
189
+ {...styleProps}
190
+ isLoading={isLoading}
191
+ onLoadMore={onLoadMore}
192
+ ref={domRef}
193
+ focusedKey={focusedKey}
194
+ scrollDirection="vertical"
195
+ className={
196
+ classNames(
197
+ listStyles,
198
+ 'react-spectrum-ListView',
199
+ `react-spectrum-ListView--${density}`,
200
+ 'react-spectrum-ListView--emphasized',
201
+ {
202
+ 'react-spectrum-ListView--quiet': isQuiet,
203
+ 'react-spectrum-ListView--loadingMore': loadingState === 'loadingMore',
204
+ 'react-spectrum-ListView--draggable': !!isListDraggable,
205
+ 'react-spectrum-ListView--dropTarget': !!isRootDropTarget,
206
+ 'react-spectrum-ListView--isVerticalScrollbarVisible': isVerticalScrollbarVisible,
207
+ 'react-spectrum-ListView--isHorizontalScrollbarVisible': isHorizontalScrollbarVisible,
208
+ 'react-spectrum-ListView--hasAnyChildren': hasAnyChildren,
209
+ 'react-spectrum-ListView--wrap': overflowMode === 'wrap'
210
+ },
211
+ styleProps.className
212
+ )
256
213
  }
214
+ layout={layout}
215
+ collection={collection}
216
+ transitionDuration={isLoading ? 160 : 220}>
217
+ {(type, item) => {
218
+ if (type === 'item') {
219
+ return (
220
+ <>
221
+ {isListDroppable && collection.getKeyBefore(item.key) == null &&
222
+ <RootDropIndicator key="root" />
223
+ }
224
+ {isListDroppable &&
225
+ <InsertionIndicator
226
+ key={`${item.key}-before`}
227
+ target={{key: item.key, type: 'item', dropPosition: 'before'}} />
228
+ }
229
+ <ListViewItem item={item} isEmphasized hasActions={!!onAction} />
230
+ {isListDroppable &&
231
+ <InsertionIndicator
232
+ key={`${item.key}-after`}
233
+ target={{key: item.key, type: 'item', dropPosition: 'after'}}
234
+ isPresentationOnly={collection.getKeyAfter(item.key) != null} />
235
+ }
236
+ </>
237
+ );
238
+ } else if (type === 'loader') {
239
+ return (
240
+ <CenteredWrapper>
241
+ <ProgressCircle
242
+ isIndeterminate
243
+ aria-label={collection.size > 0 ? stringFormatter.format('loadingMore') : stringFormatter.format('loading')} />
244
+ </CenteredWrapper>
245
+ );
246
+ } else if (type === 'placeholder') {
247
+ let emptyState = props.renderEmptyState ? props.renderEmptyState() : null;
248
+ if (emptyState == null) {
249
+ return null;
250
+ }
257
251
 
258
- }}
259
- </Virtualizer>
260
- </FocusRing>
252
+ return (
253
+ <CenteredWrapper>
254
+ {emptyState}
255
+ </CenteredWrapper>
256
+ );
257
+ }
258
+
259
+ }}
260
+ </Virtualizer>
261
+ </FocusRing>
262
+ </FocusScope>
261
263
  {DragPreview && isListDraggable &&
262
264
  <DragPreview ref={preview}>
263
265
  {() => {
@@ -73,7 +73,7 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
73
73
  let draggableItem: DraggableItemResult;
74
74
  if (isListDraggable) {
75
75
  // eslint-disable-next-line react-hooks/rules-of-hooks
76
- draggableItem = dragHooks.useDraggableItem({key: item.key}, dragState);
76
+ draggableItem = dragHooks.useDraggableItem({key: item.key, hasDragButton: true}, dragState);
77
77
  if (isDisabled) {
78
78
  draggableItem = null;
79
79
  }
@@ -86,7 +86,6 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
86
86
  let target = {type: 'item', key: item.key, dropPosition: 'on'} as DropTarget;
87
87
  isDropTarget = dropState.isDropTarget(target);
88
88
  // eslint-disable-next-line react-hooks/rules-of-hooks
89
- droppableItem = dropHooks.useDroppableItem({target}, dropState, rowRef);
90
89
  dropIndicator = dropHooks.useDropIndicator({target}, dropState, dropIndicatorRef);
91
90
  }
92
91
 
@@ -136,7 +135,10 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
136
135
  dropProps,
137
136
  hoverProps,
138
137
  focusWithinProps,
139
- focusProps
138
+ focusProps,
139
+ // Remove tab index from list row if performing a screenreader drag. This prevents TalkBack from focusing the row,
140
+ // allowing for single swipe navigation between row drop indicator
141
+ dropHooks?.isVirtualDragging() && {tabIndex: null}
140
142
  );
141
143
 
142
144
  let isFirstRow = item.prevKey == null;
@@ -226,7 +228,7 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
226
228
  }
227
229
  </div>
228
230
  }
229
- {isDropTarget && !dropIndicator?.dropIndicatorProps['aria-hidden'] &&
231
+ {isListDroppable && !dropIndicator?.isHidden &&
230
232
  <div role="button" {...visuallyHiddenProps} {...dropIndicator?.dropIndicatorProps} ref={dropIndicatorRef} />
231
233
  }
232
234
  <CSSTransition