@react-spectrum/list 3.8.2 → 3.9.0

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.
@@ -14,7 +14,7 @@ import ChevronLeftMedium from '@spectrum-icons/ui/ChevronLeftMedium';
14
14
  import ChevronRightMedium from '@spectrum-icons/ui/ChevronRightMedium';
15
15
  import {classNames, ClearSlots, SlotProvider, useHasChild} from '@react-spectrum/utils';
16
16
  import {CSSTransition} from 'react-transition-group';
17
- import type {DraggableItemResult, DropIndicatorAria, DroppableItemResult} from '@react-aria/dnd';
17
+ import type {DraggableItemResult, DropIndicatorAria} from '@react-aria/dnd';
18
18
  import {DropTarget, Node} from '@react-types/shared';
19
19
  import {FocusRing, useFocusRing} from '@react-aria/focus';
20
20
  import {Grid} from '@react-spectrum/layout';
@@ -51,10 +51,10 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
51
51
  layout,
52
52
  dragAndDropHooks,
53
53
  loadingState
54
- } = useContext(ListViewContext);
54
+ } = useContext(ListViewContext)!;
55
55
  let {direction} = useLocale();
56
- let rowRef = useRef<HTMLDivElement>(undefined);
57
- let checkboxWrapperRef = useRef<HTMLDivElement>(undefined);
56
+ let rowRef = useRef<HTMLDivElement | null>(null);
57
+ let checkboxWrapperRef = useRef<HTMLDivElement | null>(null);
58
58
  let {
59
59
  isFocusVisible: isFocusVisibleWithin,
60
60
  focusProps: focusWithinProps
@@ -74,32 +74,30 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
74
74
  isVirtualized: true,
75
75
  shouldSelectOnPressUp: isListDraggable
76
76
  }, state, rowRef);
77
- let isDroppable = isListDroppable && !isDisabled;
78
77
  let {hoverProps, isHovered} = useHover({isDisabled: !allowsSelection && !hasAction});
79
78
 
80
79
  let {checkboxProps} = useGridListSelectionCheckbox({key: item.key}, state);
81
80
  let hasDescription = useHasChild(`.${listStyles['react-spectrum-ListViewItem-description']}`, rowRef);
82
81
 
83
- let draggableItem: DraggableItemResult;
84
- if (isListDraggable) {
85
- // eslint-disable-next-line react-hooks/rules-of-hooks
86
- draggableItem = dragAndDropHooks.useDraggableItem({key: item.key, hasDragButton: true}, dragState);
82
+ let draggableItem: DraggableItemResult | null = null;
83
+ if (isListDraggable && dragAndDropHooks && dragState) {
84
+
85
+ draggableItem = dragAndDropHooks.useDraggableItem!({key: item.key, hasDragButton: true}, dragState);
87
86
  if (isDisabled) {
88
87
  draggableItem = null;
89
88
  }
90
89
  }
91
- let droppableItem: DroppableItemResult;
92
- let isDropTarget: boolean;
93
- let dropIndicator: DropIndicatorAria;
94
- let dropIndicatorRef = useRef(undefined);
95
- if (isListDroppable) {
90
+ let isDropTarget = false;
91
+ let dropIndicator: DropIndicatorAria | null = null;
92
+ let dropIndicatorRef = useRef<HTMLDivElement | null>(null);
93
+ if (isListDroppable && dragAndDropHooks && dropState) {
96
94
  let target = {type: 'item', key: item.key, dropPosition: 'on'} as DropTarget;
97
95
  isDropTarget = dropState.isDropTarget(target);
98
- // eslint-disable-next-line react-hooks/rules-of-hooks
99
- dropIndicator = dragAndDropHooks.useDropIndicator({target}, dropState, dropIndicatorRef);
96
+
97
+ dropIndicator = dragAndDropHooks.useDropIndicator!({target}, dropState, dropIndicatorRef);
100
98
  }
101
99
 
102
- let dragButtonRef = React.useRef(undefined);
100
+ let dragButtonRef = React.useRef<HTMLDivElement | null>(null);
103
101
  let {buttonProps} = useButton({
104
102
  ...draggableItem?.dragButtonProps,
105
103
  elementType: 'div'
@@ -138,18 +136,19 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
138
136
  let showCheckbox = state.selectionManager.selectionMode !== 'none' && state.selectionManager.selectionBehavior === 'toggle';
139
137
  let {visuallyHiddenProps} = useVisuallyHidden();
140
138
 
141
- let dropProps = isDroppable ? droppableItem?.dropProps : {'aria-hidden': droppableItem?.dropProps['aria-hidden']};
142
139
  const mergedProps = mergeProps(
143
140
  rowProps,
144
141
  draggableItem?.dragProps,
145
- dropProps,
146
142
  hoverProps,
147
143
  focusWithinProps,
148
- focusProps,
149
- // Remove tab index from list row if performing a screenreader drag. This prevents TalkBack from focusing the row,
150
- // allowing for single swipe navigation between row drop indicator
151
- dragAndDropHooks?.isVirtualDragging() && {tabIndex: null}
144
+ focusProps
152
145
  );
146
+
147
+ // Remove tab index from list row if performing a screenreader drag. This prevents TalkBack from focusing the row,
148
+ // allowing for single swipe navigation between row drop indicator
149
+ if (dragAndDropHooks?.isVirtualDragging?.()) {
150
+ mergedProps.tabIndex = undefined;
151
+ }
153
152
 
154
153
  let isFirstRow = item.prevKey == null;
155
154
  let isLastRow = item.nextKey == null;
@@ -158,15 +157,15 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
158
157
  // with bottom border
159
158
  let isFlushWithContainerBottom = false;
160
159
  if (isLastRow && loadingState !== 'loadingMore') {
161
- if (layout.getContentSize()?.height >= layout.virtualizer?.visibleRect.height) {
160
+ if (layout.getContentSize()?.height >= (layout.virtualizer?.visibleRect.height ?? 0)) {
162
161
  isFlushWithContainerBottom = true;
163
162
  }
164
163
  }
165
164
  // previous item isn't selected
166
165
  // and the previous item isn't focused or, if it is focused, then if focus globally isn't visible or just focus isn't in the listview
167
- let roundTops = (!state.selectionManager.isSelected(item.prevKey)
166
+ let roundTops = (!(item.prevKey != null && state.selectionManager.isSelected(item.prevKey))
168
167
  && (state.selectionManager.focusedKey !== item.prevKey || !(isGlobalFocusVisible() && state.selectionManager.isFocused)));
169
- let roundBottoms = (!state.selectionManager.isSelected(item.nextKey)
168
+ let roundBottoms = (!(item.nextKey != null && state.selectionManager.isSelected(item.nextKey))
170
169
  && (state.selectionManager.focusedKey !== item.nextKey || !(isGlobalFocusVisible() && state.selectionManager.isFocused)));
171
170
 
172
171
  let content = typeof item.rendered === 'string' ? <Text>{item.rendered}</Text> : item.rendered;
@@ -204,9 +203,9 @@ export function ListViewItem<T>(props: ListViewItemProps<T>) {
204
203
  'is-hovered': isHovered,
205
204
  'is-selected': isSelected,
206
205
  'is-disabled': isDisabled,
207
- 'is-prev-selected': state.selectionManager.isSelected(item.prevKey),
208
- 'is-next-selected': state.selectionManager.isSelected(item.nextKey),
209
- 'react-spectrum-ListViewItem--highlightSelection': state.selectionManager.selectionBehavior === 'replace' && (isSelected || state.selectionManager.isSelected(item.nextKey)),
206
+ 'is-prev-selected': item.prevKey != null && state.selectionManager.isSelected(item.prevKey),
207
+ 'is-next-selected': item.nextKey != null && state.selectionManager.isSelected(item.nextKey),
208
+ 'react-spectrum-ListViewItem--highlightSelection': state.selectionManager.selectionBehavior === 'replace' && (isSelected || (item.nextKey != null && state.selectionManager.isSelected(item.nextKey))),
210
209
  'react-spectrum-ListViewItem--dropTarget': !!isDropTarget,
211
210
  'react-spectrum-ListViewItem--firstRow': isFirstRow,
212
211
  'react-spectrum-ListViewItem--lastRow': isLastRow,
@@ -30,7 +30,7 @@ export class ListViewLayout<T> extends ListLayout<T, ListViewLayoutProps> {
30
30
  let y = this.contentSize.height;
31
31
 
32
32
  if (this.isLoading) {
33
- let rect = new Rect(0, y, this.virtualizer.visibleRect.width, nodes.length === 0 ? this.virtualizer.visibleRect.height : this.estimatedRowHeight);
33
+ let rect = new Rect(0, y, this.virtualizer!.visibleRect.width, nodes.length === 0 ? this.virtualizer!.visibleRect.height : this.estimatedRowHeight ?? 48);
34
34
  let loader = new LayoutInfo('loader', 'loader', rect);
35
35
  let node = {
36
36
  layoutInfo: loader,
@@ -42,7 +42,7 @@ export class ListViewLayout<T> extends ListLayout<T, ListViewLayoutProps> {
42
42
  }
43
43
 
44
44
  if (nodes.length === 0) {
45
- let rect = new Rect(0, y, this.virtualizer.visibleRect.width, this.virtualizer.visibleRect.height);
45
+ let rect = new Rect(0, y, this.virtualizer!.visibleRect.width, this.virtualizer!.visibleRect.height);
46
46
  let placeholder = new LayoutInfo('placeholder', 'placeholder', rect);
47
47
  let node = {
48
48
  layoutInfo: placeholder,
@@ -3,12 +3,12 @@ import React, {useContext, useRef} from 'react';
3
3
  import {useVisuallyHidden} from '@react-aria/visually-hidden';
4
4
 
5
5
  export default function RootDropIndicator() {
6
- let {dropState, dragAndDropHooks} = useContext(ListViewContext);
7
- let ref = useRef(undefined);
8
- let {dropIndicatorProps} = dragAndDropHooks.useDropIndicator({
6
+ let {dropState, dragAndDropHooks} = useContext(ListViewContext)!;
7
+ let ref = useRef<HTMLDivElement | null>(null);
8
+ let {dropIndicatorProps} = dragAndDropHooks!.useDropIndicator!({
9
9
  target: {type: 'root'}
10
- }, dropState, ref);
11
- let isDropTarget = dropState.isDropTarget({type: 'root'});
10
+ }, dropState!, ref);
11
+ let isDropTarget = dropState!.isDropTarget({type: 'root'});
12
12
  let {visuallyHiddenProps} = useVisuallyHidden();
13
13
 
14
14
  if (!isDropTarget && dropIndicatorProps['aria-hidden']) {