@react-spectrum/list 3.0.0-alpha.1 → 3.0.0-alpha.10
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/dist/main.css +1 -2
- package/dist/main.js +725 -372
- package/dist/main.js.map +1 -1
- package/dist/module.js +738 -326
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +33 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +39 -30
- package/src/DragPreview.tsx +72 -0
- package/src/ListView.tsx +152 -29
- package/src/ListViewItem.tsx +149 -17
- package/src/listview.css +322 -10
- package/dist/main.css.map +0 -1
package/src/ListView.tsx
CHANGED
|
@@ -9,9 +9,22 @@
|
|
|
9
9
|
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
AriaLabelingProps,
|
|
14
|
+
AsyncLoadable,
|
|
15
|
+
CollectionBase,
|
|
16
|
+
DOMProps,
|
|
17
|
+
DOMRef,
|
|
18
|
+
LoadingState,
|
|
19
|
+
MultipleSelection,
|
|
20
|
+
SpectrumSelectionProps,
|
|
21
|
+
StyleProps
|
|
22
|
+
} from '@react-types/shared';
|
|
13
23
|
import {classNames, useDOMRef, useStyleProps} from '@react-spectrum/utils';
|
|
14
|
-
import {
|
|
24
|
+
import type {DraggableCollectionState} from '@react-stately/dnd';
|
|
25
|
+
import {DragHooks} from '@react-spectrum/dnd';
|
|
26
|
+
import {DragPreview} from './DragPreview';
|
|
27
|
+
import {GridCollection, GridState, useGridState} from '@react-stately/grid';
|
|
15
28
|
import {GridKeyboardDelegate, useGrid} from '@react-aria/grid';
|
|
16
29
|
// @ts-ignore
|
|
17
30
|
import intlMessages from '../intl/*.json';
|
|
@@ -20,71 +33,158 @@ import {ListState, useListState} from '@react-stately/list';
|
|
|
20
33
|
import listStyles from './listview.css';
|
|
21
34
|
import {ListViewItem} from './ListViewItem';
|
|
22
35
|
import {ProgressCircle} from '@react-spectrum/progress';
|
|
23
|
-
import React, {ReactElement, useContext, useMemo} from 'react';
|
|
36
|
+
import React, {ReactElement, useContext, useMemo, useRef} from 'react';
|
|
24
37
|
import {useCollator, useLocale, useMessageFormatter} from '@react-aria/i18n';
|
|
25
38
|
import {useProvider} from '@react-spectrum/provider';
|
|
26
39
|
import {Virtualizer} from '@react-aria/virtualizer';
|
|
27
40
|
|
|
41
|
+
interface ListViewContextValue<T> {
|
|
42
|
+
state: GridState<T, GridCollection<any>>,
|
|
43
|
+
keyboardDelegate: GridKeyboardDelegate<T, GridCollection<any>>,
|
|
44
|
+
dragState: DraggableCollectionState,
|
|
45
|
+
onAction:(key: string) => void,
|
|
46
|
+
isListDraggable: boolean,
|
|
47
|
+
layout: ListLayout<T>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const ListViewContext = React.createContext<ListViewContextValue<unknown>>(null);
|
|
28
51
|
|
|
29
|
-
|
|
52
|
+
const ROW_HEIGHTS = {
|
|
53
|
+
compact: {
|
|
54
|
+
medium: 32,
|
|
55
|
+
large: 40
|
|
56
|
+
},
|
|
57
|
+
regular: {
|
|
58
|
+
medium: 40,
|
|
59
|
+
large: 50
|
|
60
|
+
},
|
|
61
|
+
spacious: {
|
|
62
|
+
medium: 48,
|
|
63
|
+
large: 60
|
|
64
|
+
}
|
|
65
|
+
};
|
|
30
66
|
|
|
31
|
-
export function useListLayout<T>(state: ListState<T>) {
|
|
67
|
+
export function useListLayout<T>(state: ListState<T>, density: ListViewProps<T>['density']) {
|
|
32
68
|
let {scale} = useProvider();
|
|
33
69
|
let collator = useCollator({usage: 'search', sensitivity: 'base'});
|
|
70
|
+
let isEmpty = state.collection.size === 0;
|
|
34
71
|
let layout = useMemo(() =>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
72
|
+
new ListLayout<T>({
|
|
73
|
+
estimatedRowHeight: ROW_HEIGHTS[density][scale],
|
|
74
|
+
padding: 0,
|
|
75
|
+
collator,
|
|
76
|
+
loaderHeight: isEmpty ? null : ROW_HEIGHTS[density][scale]
|
|
77
|
+
})
|
|
78
|
+
, [collator, scale, density, isEmpty]);
|
|
41
79
|
|
|
42
80
|
layout.collection = state.collection;
|
|
43
81
|
layout.disabledKeys = state.disabledKeys;
|
|
44
82
|
return layout;
|
|
45
83
|
}
|
|
46
84
|
|
|
47
|
-
interface ListViewProps<T> extends CollectionBase<T>, DOMProps, AriaLabelingProps, StyleProps {
|
|
48
|
-
|
|
85
|
+
interface ListViewProps<T> extends CollectionBase<T>, DOMProps, AriaLabelingProps, StyleProps, MultipleSelection, SpectrumSelectionProps, Omit<AsyncLoadable, 'isLoading'> {
|
|
86
|
+
/**
|
|
87
|
+
* Sets the amount of vertical padding within each cell.
|
|
88
|
+
* @default 'regular'
|
|
89
|
+
*/
|
|
90
|
+
density?: 'compact' | 'regular' | 'spacious',
|
|
91
|
+
/** Whether the ListView should be displayed with a quiet style. */
|
|
92
|
+
isQuiet?: boolean,
|
|
93
|
+
/** The current loading state of the ListView. Determines whether or not the progress circle should be shown. */
|
|
94
|
+
loadingState?: LoadingState,
|
|
95
|
+
/** Sets what the ListView should render when there is no content to display. */
|
|
49
96
|
renderEmptyState?: () => JSX.Element,
|
|
50
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The duration of animated layout changes, in milliseconds. Used by the Virtualizer.
|
|
99
|
+
* @default 0
|
|
100
|
+
*/
|
|
101
|
+
transitionDuration?: number,
|
|
102
|
+
/**
|
|
103
|
+
* Handler that is called when a user performs an action on an item. The exact user event depends on
|
|
104
|
+
* the collection's `selectionBehavior` prop and the interaction modality.
|
|
105
|
+
*/
|
|
106
|
+
onAction?: (key: string) => void,
|
|
107
|
+
/**
|
|
108
|
+
* The drag hooks returned by `useDragHooks` used to enable drag and drop behavior for the ListView. See the
|
|
109
|
+
* [docs](https://react-spectrum.adobe.com/react-spectrum/useDragHooks.html) for more info.
|
|
110
|
+
*/
|
|
111
|
+
dragHooks?: DragHooks
|
|
51
112
|
}
|
|
52
113
|
|
|
53
114
|
function ListView<T extends object>(props: ListViewProps<T>, ref: DOMRef<HTMLDivElement>) {
|
|
54
115
|
let {
|
|
55
|
-
|
|
116
|
+
density = 'regular',
|
|
117
|
+
onLoadMore,
|
|
118
|
+
loadingState,
|
|
119
|
+
isQuiet,
|
|
120
|
+
transitionDuration = 0,
|
|
121
|
+
onAction,
|
|
122
|
+
dragHooks
|
|
56
123
|
} = props;
|
|
124
|
+
let isListDraggable = !!dragHooks;
|
|
125
|
+
let dragHooksProvided = useRef(isListDraggable);
|
|
126
|
+
if (dragHooksProvided.current !== isListDraggable) {
|
|
127
|
+
console.warn('Drag hooks were provided during one render, but not another. This should be avoided as it may produce unexpected behavior.');
|
|
128
|
+
}
|
|
57
129
|
let domRef = useDOMRef(ref);
|
|
58
130
|
let {collection} = useListState(props);
|
|
59
131
|
let formatMessage = useMessageFormatter(intlMessages);
|
|
132
|
+
let isLoading = loadingState === 'loading' || loadingState === 'loadingMore';
|
|
60
133
|
|
|
61
134
|
let {styleProps} = useStyleProps(props);
|
|
62
|
-
let {direction} = useLocale();
|
|
135
|
+
let {direction, locale} = useLocale();
|
|
63
136
|
let collator = useCollator({usage: 'search', sensitivity: 'base'});
|
|
64
137
|
let gridCollection = useMemo(() => new GridCollection({
|
|
65
138
|
columnCount: 1,
|
|
66
139
|
items: [...collection].map(item => ({
|
|
67
|
-
|
|
140
|
+
...item,
|
|
141
|
+
hasChildNodes: true,
|
|
68
142
|
childNodes: [{
|
|
69
|
-
|
|
143
|
+
key: `cell-${item.key}`,
|
|
144
|
+
type: 'cell',
|
|
70
145
|
index: 0,
|
|
71
|
-
|
|
146
|
+
value: null,
|
|
147
|
+
level: 0,
|
|
148
|
+
rendered: null,
|
|
149
|
+
textValue: item.textValue,
|
|
150
|
+
hasChildNodes: false,
|
|
151
|
+
childNodes: []
|
|
72
152
|
}]
|
|
73
153
|
}))
|
|
74
154
|
}), [collection]);
|
|
75
155
|
let state = useGridState({
|
|
76
156
|
...props,
|
|
77
|
-
collection: gridCollection
|
|
157
|
+
collection: gridCollection,
|
|
158
|
+
focusMode: 'cell',
|
|
159
|
+
selectionBehavior: props.selectionStyle === 'highlight' ? 'replace' : 'toggle'
|
|
78
160
|
});
|
|
79
|
-
let layout = useListLayout(state);
|
|
161
|
+
let layout = useListLayout(state, props.density || 'regular');
|
|
80
162
|
let keyboardDelegate = useMemo(() => new GridKeyboardDelegate({
|
|
81
163
|
collection: state.collection,
|
|
82
164
|
disabledKeys: state.disabledKeys,
|
|
83
165
|
ref: domRef,
|
|
84
166
|
direction,
|
|
85
167
|
collator,
|
|
168
|
+
// Focus the ListView cell instead of the row so that focus doesn't change with left/right arrow keys when there aren't any
|
|
169
|
+
// focusable children in the cell.
|
|
86
170
|
focusMode: 'cell'
|
|
87
171
|
}), [state, domRef, direction, collator]);
|
|
172
|
+
|
|
173
|
+
let provider = useProvider();
|
|
174
|
+
let dragState: DraggableCollectionState;
|
|
175
|
+
if (isListDraggable) {
|
|
176
|
+
dragState = dragHooks.useDraggableCollectionState({
|
|
177
|
+
collection: state.collection,
|
|
178
|
+
selectionManager: state.selectionManager,
|
|
179
|
+
renderPreview(draggingKeys, draggedKey) {
|
|
180
|
+
let item = state.collection.getItem(draggedKey);
|
|
181
|
+
let itemCount = draggingKeys.size;
|
|
182
|
+
let itemHeight = layout.getLayoutInfo(draggedKey).rect.height;
|
|
183
|
+
return <DragPreview item={item} itemCount={itemCount} itemHeight={itemHeight} provider={provider} locale={locale} />;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
88
188
|
let {gridProps} = useGrid({
|
|
89
189
|
...props,
|
|
90
190
|
isVirtualized: true,
|
|
@@ -92,31 +192,45 @@ function ListView<T extends object>(props: ListViewProps<T>, ref: DOMRef<HTMLDiv
|
|
|
92
192
|
}, state, domRef);
|
|
93
193
|
|
|
94
194
|
// Sync loading state into the layout.
|
|
95
|
-
layout.isLoading =
|
|
195
|
+
layout.isLoading = isLoading;
|
|
196
|
+
|
|
197
|
+
let focusedKey = state.selectionManager.focusedKey;
|
|
198
|
+
let focusedItem = gridCollection.getItem(state.selectionManager.focusedKey);
|
|
199
|
+
if (focusedItem?.parentKey != null) {
|
|
200
|
+
focusedKey = focusedItem.parentKey;
|
|
201
|
+
}
|
|
96
202
|
|
|
97
203
|
return (
|
|
98
|
-
<ListViewContext.Provider value={{state, keyboardDelegate}}>
|
|
204
|
+
<ListViewContext.Provider value={{state, keyboardDelegate, dragState, onAction, isListDraggable, layout}}>
|
|
99
205
|
<Virtualizer
|
|
100
206
|
{...gridProps}
|
|
101
207
|
{...styleProps}
|
|
208
|
+
isLoading={isLoading}
|
|
209
|
+
onLoadMore={onLoadMore}
|
|
102
210
|
ref={domRef}
|
|
103
|
-
focusedKey={
|
|
104
|
-
sizeToFit="height"
|
|
211
|
+
focusedKey={focusedKey}
|
|
105
212
|
scrollDirection="vertical"
|
|
106
213
|
className={
|
|
107
214
|
classNames(
|
|
108
215
|
listStyles,
|
|
109
216
|
'react-spectrum-ListView',
|
|
217
|
+
`react-spectrum-ListView--${density}`,
|
|
218
|
+
'react-spectrum-ListView--emphasized',
|
|
219
|
+
{
|
|
220
|
+
'react-spectrum-ListView--quiet': isQuiet,
|
|
221
|
+
'react-spectrum-ListView--draggable': isListDraggable,
|
|
222
|
+
'react-spectrum-ListView--loadingMore': loadingState === 'loadingMore'
|
|
223
|
+
},
|
|
110
224
|
styleProps.className
|
|
111
225
|
)
|
|
112
226
|
}
|
|
113
227
|
layout={layout}
|
|
114
|
-
collection={
|
|
228
|
+
collection={gridCollection}
|
|
115
229
|
transitionDuration={transitionDuration}>
|
|
116
230
|
{(type, item) => {
|
|
117
231
|
if (type === 'item') {
|
|
118
232
|
return (
|
|
119
|
-
<ListViewItem item={item} />
|
|
233
|
+
<ListViewItem item={item} isEmphasized dragHooks={dragHooks} />
|
|
120
234
|
);
|
|
121
235
|
} else if (type === 'loader') {
|
|
122
236
|
return (
|
|
@@ -145,14 +259,20 @@ function ListView<T extends object>(props: ListViewProps<T>, ref: DOMRef<HTMLDiv
|
|
|
145
259
|
);
|
|
146
260
|
}
|
|
147
261
|
|
|
148
|
-
|
|
149
262
|
function CenteredWrapper({children}) {
|
|
150
263
|
let {state} = useContext(ListViewContext);
|
|
151
264
|
return (
|
|
152
265
|
<div
|
|
153
266
|
role="row"
|
|
154
267
|
aria-rowindex={state.collection.size + 1}
|
|
155
|
-
className={
|
|
268
|
+
className={
|
|
269
|
+
classNames(
|
|
270
|
+
listStyles,
|
|
271
|
+
'react-spectrum-ListView-centeredWrapper',
|
|
272
|
+
{
|
|
273
|
+
'react-spectrum-ListView-centeredWrapper--loadingMore': state.collection.size > 0
|
|
274
|
+
}
|
|
275
|
+
)}>
|
|
156
276
|
<div role="gridcell">
|
|
157
277
|
{children}
|
|
158
278
|
</div>
|
|
@@ -160,5 +280,8 @@ function CenteredWrapper({children}) {
|
|
|
160
280
|
);
|
|
161
281
|
}
|
|
162
282
|
|
|
283
|
+
/**
|
|
284
|
+
* Lists display a linear collection of data. They allow users to quickly scan, sort, compare, and take action on large amounts of data.
|
|
285
|
+
*/
|
|
163
286
|
const _ListView = React.forwardRef(ListView) as <T>(props: ListViewProps<T> & {ref?: DOMRef<HTMLDivElement>}) => ReactElement;
|
|
164
287
|
export {_ListView as ListView};
|
package/src/ListViewItem.tsx
CHANGED
|
@@ -9,60 +9,192 @@
|
|
|
9
9
|
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
12
|
+
import {Checkbox} from '@react-spectrum/checkbox';
|
|
13
|
+
import ChevronLeftMedium from '@spectrum-icons/ui/ChevronLeftMedium';
|
|
14
|
+
import ChevronRightMedium from '@spectrum-icons/ui/ChevronRightMedium';
|
|
15
|
+
import {classNames, ClearSlots, SlotProvider} from '@react-spectrum/utils';
|
|
16
|
+
import {Content} from '@react-spectrum/view';
|
|
17
|
+
import type {DraggableItemResult} from '@react-aria/dnd';
|
|
18
|
+
import {FocusRing, useFocusRing} from '@react-aria/focus';
|
|
19
|
+
import {Grid} from '@react-spectrum/layout';
|
|
20
|
+
import ListGripper from '@spectrum-icons/ui/ListGripper';
|
|
13
21
|
import listStyles from './listview.css';
|
|
14
22
|
import {ListViewContext} from './ListView';
|
|
15
23
|
import {mergeProps} from '@react-aria/utils';
|
|
16
24
|
import React, {useContext, useRef} from 'react';
|
|
17
|
-
import {
|
|
18
|
-
import {useGridCell, useGridRow} from '@react-aria/grid';
|
|
19
|
-
import {useHover} from '@react-aria/interactions';
|
|
20
|
-
|
|
25
|
+
import {useButton} from '@react-aria/button';
|
|
26
|
+
import {useGridCell, useGridRow, useGridSelectionCheckbox} from '@react-aria/grid';
|
|
27
|
+
import {useHover, usePress} from '@react-aria/interactions';
|
|
28
|
+
import {useLocale} from '@react-aria/i18n';
|
|
29
|
+
import {useVisuallyHidden} from '@react-aria/visually-hidden';
|
|
21
30
|
|
|
22
31
|
export function ListViewItem(props) {
|
|
23
32
|
let {
|
|
24
|
-
item
|
|
33
|
+
item,
|
|
34
|
+
isEmphasized,
|
|
35
|
+
dragHooks
|
|
25
36
|
} = props;
|
|
26
|
-
let
|
|
27
|
-
let
|
|
37
|
+
let cellNode = [...item.childNodes][0];
|
|
38
|
+
let {state, dragState, onAction, isListDraggable, layout} = useContext(ListViewContext);
|
|
39
|
+
|
|
40
|
+
let {direction} = useLocale();
|
|
41
|
+
let rowRef = useRef<HTMLDivElement>();
|
|
42
|
+
let cellRef = useRef<HTMLDivElement>();
|
|
28
43
|
let {
|
|
29
44
|
isFocusVisible: isFocusVisibleWithin,
|
|
30
45
|
focusProps: focusWithinProps
|
|
31
46
|
} = useFocusRing({within: true});
|
|
32
47
|
let {isFocusVisible, focusProps} = useFocusRing();
|
|
33
|
-
let
|
|
48
|
+
let allowsInteraction = state.selectionManager.selectionMode !== 'none' || onAction;
|
|
49
|
+
let isDisabled = !allowsInteraction || state.disabledKeys.has(item.key);
|
|
50
|
+
let isDraggable = dragState?.isDraggable(item.key) && !isDisabled;
|
|
51
|
+
let {hoverProps, isHovered} = useHover({isDisabled});
|
|
52
|
+
let {pressProps, isPressed} = usePress({isDisabled});
|
|
34
53
|
let {rowProps} = useGridRow({
|
|
35
54
|
node: item,
|
|
36
|
-
isVirtualized: true
|
|
37
|
-
|
|
55
|
+
isVirtualized: true,
|
|
56
|
+
onAction: onAction ? () => onAction(item.key) : undefined,
|
|
57
|
+
shouldSelectOnPressUp: isListDraggable
|
|
58
|
+
}, state, rowRef);
|
|
38
59
|
let {gridCellProps} = useGridCell({
|
|
39
|
-
node:
|
|
60
|
+
node: cellNode,
|
|
40
61
|
focusMode: 'cell'
|
|
41
|
-
}, state,
|
|
62
|
+
}, state, cellRef);
|
|
63
|
+
let draggableItem: DraggableItemResult;
|
|
64
|
+
if (isListDraggable) {
|
|
65
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
66
|
+
draggableItem = dragHooks.useDraggableItem({key: item.key}, dragState);
|
|
67
|
+
}
|
|
42
68
|
const mergedProps = mergeProps(
|
|
43
69
|
gridCellProps,
|
|
44
70
|
hoverProps,
|
|
45
71
|
focusWithinProps,
|
|
46
72
|
focusProps
|
|
47
73
|
);
|
|
74
|
+
let {checkboxProps} = useGridSelectionCheckbox({...props, key: item.key}, state);
|
|
75
|
+
|
|
76
|
+
let dragButtonRef = React.useRef();
|
|
77
|
+
let {buttonProps} = useButton({
|
|
78
|
+
...draggableItem?.dragButtonProps,
|
|
79
|
+
elementType: 'div'
|
|
80
|
+
}, dragButtonRef);
|
|
81
|
+
|
|
82
|
+
let chevron = null;
|
|
83
|
+
if (item.props.hasChildItems) {
|
|
84
|
+
chevron = direction === 'ltr'
|
|
85
|
+
? (
|
|
86
|
+
<ChevronRightMedium
|
|
87
|
+
aria-hidden="true"
|
|
88
|
+
UNSAFE_className={listStyles['react-spectrum-ListViewItem-parentIndicator']} />
|
|
89
|
+
)
|
|
90
|
+
: (
|
|
91
|
+
<ChevronLeftMedium
|
|
92
|
+
aria-hidden="true"
|
|
93
|
+
UNSAFE_className={listStyles['react-spectrum-ListViewItem-parentIndicator']} />
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let showCheckbox = state.selectionManager.selectionMode !== 'none' && state.selectionManager.selectionBehavior === 'toggle';
|
|
98
|
+
let isSelected = state.selectionManager.isSelected(item.key);
|
|
99
|
+
let showDragHandle = isDraggable && isFocusVisibleWithin;
|
|
100
|
+
let {visuallyHiddenProps} = useVisuallyHidden();
|
|
101
|
+
let isFirstRow = item.prevKey == null;
|
|
102
|
+
let isLastRow = item.nextKey == null;
|
|
103
|
+
// Figure out if the ListView content is equal or greater in height to the container. If so, we'll need to round the bottom
|
|
104
|
+
// border corners of the last row when selected and we can get rid of the bottom border if it isn't selected to avoid border overlap
|
|
105
|
+
// with bottom border
|
|
106
|
+
let isFlushWithContainerBottom = false;
|
|
107
|
+
if (isLastRow) {
|
|
108
|
+
if (layout.getContentSize()?.height >= layout.virtualizer?.getVisibleRect().height) {
|
|
109
|
+
isFlushWithContainerBottom = true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
48
112
|
|
|
49
113
|
return (
|
|
50
|
-
<div
|
|
114
|
+
<div
|
|
115
|
+
{...mergeProps(rowProps, pressProps, isDraggable && draggableItem?.dragProps)}
|
|
116
|
+
className={
|
|
117
|
+
classNames(
|
|
118
|
+
listStyles,
|
|
119
|
+
'react-spectrum-ListView-row',
|
|
120
|
+
{
|
|
121
|
+
'focus-ring': isFocusVisible
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
ref={rowRef}>
|
|
51
126
|
<div
|
|
52
127
|
className={
|
|
53
128
|
classNames(
|
|
54
129
|
listStyles,
|
|
55
130
|
'react-spectrum-ListViewItem',
|
|
56
131
|
{
|
|
132
|
+
'is-active': isPressed,
|
|
57
133
|
'is-focused': isFocusVisibleWithin,
|
|
58
134
|
'focus-ring': isFocusVisible,
|
|
59
|
-
'is-hovered': isHovered
|
|
135
|
+
'is-hovered': isHovered,
|
|
136
|
+
'is-selected': isSelected,
|
|
137
|
+
'is-next-selected': state.selectionManager.isSelected(item.nextKey),
|
|
138
|
+
'react-spectrum-ListViewItem--highlightSelection': state.selectionManager.selectionBehavior === 'replace' && (isSelected || state.selectionManager.isSelected(item.nextKey)),
|
|
139
|
+
'react-spectrum-ListViewItem--draggable': isDraggable,
|
|
140
|
+
'react-spectrum-ListViewItem--firstRow': isFirstRow,
|
|
141
|
+
'react-spectrum-ListViewItem--lastRow': isLastRow,
|
|
142
|
+
'react-spectrum-ListViewItem--isFlushBottom': isFlushWithContainerBottom
|
|
60
143
|
}
|
|
61
144
|
)
|
|
62
145
|
}
|
|
63
|
-
ref={
|
|
146
|
+
ref={cellRef}
|
|
64
147
|
{...mergedProps}>
|
|
65
|
-
{
|
|
148
|
+
<Grid UNSAFE_className={listStyles['react-spectrum-ListViewItem-grid']}>
|
|
149
|
+
{isListDraggable &&
|
|
150
|
+
<div className={listStyles['react-spectrum-ListViewItem-draghandle-container']}>
|
|
151
|
+
{isDraggable &&
|
|
152
|
+
<FocusRing focusRingClass={classNames(listStyles, 'focus-ring')}>
|
|
153
|
+
<div
|
|
154
|
+
{...buttonProps as React.HTMLAttributes<HTMLElement>}
|
|
155
|
+
className={
|
|
156
|
+
classNames(
|
|
157
|
+
listStyles,
|
|
158
|
+
'react-spectrum-ListViewItem-draghandle-button'
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
style={!showDragHandle ? {...visuallyHiddenProps.style} : {}}
|
|
162
|
+
ref={dragButtonRef}
|
|
163
|
+
draggable="true">
|
|
164
|
+
<ListGripper />
|
|
165
|
+
</div>
|
|
166
|
+
</FocusRing>
|
|
167
|
+
}
|
|
168
|
+
</div>
|
|
169
|
+
}
|
|
170
|
+
{showCheckbox &&
|
|
171
|
+
<Checkbox
|
|
172
|
+
UNSAFE_className={listStyles['react-spectrum-ListViewItem-checkbox']}
|
|
173
|
+
{...checkboxProps}
|
|
174
|
+
isEmphasized={isEmphasized} />
|
|
175
|
+
}
|
|
176
|
+
<SlotProvider
|
|
177
|
+
slots={{
|
|
178
|
+
content: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-content']},
|
|
179
|
+
text: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-content']},
|
|
180
|
+
description: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-description']},
|
|
181
|
+
icon: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-icon'], size: 'M'},
|
|
182
|
+
image: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-image']},
|
|
183
|
+
link: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-content'], isQuiet: true},
|
|
184
|
+
actionButton: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-actions'], isQuiet: true},
|
|
185
|
+
actionGroup: {
|
|
186
|
+
UNSAFE_className: listStyles['react-spectrum-ListViewItem-actions'],
|
|
187
|
+
isQuiet: true,
|
|
188
|
+
density: 'compact'
|
|
189
|
+
},
|
|
190
|
+
actionMenu: {UNSAFE_className: listStyles['react-spectrum-ListViewItem-actionmenu'], isQuiet: true}
|
|
191
|
+
}}>
|
|
192
|
+
{typeof item.rendered === 'string' ? <Content>{item.rendered}</Content> : item.rendered}
|
|
193
|
+
<ClearSlots>
|
|
194
|
+
{chevron}
|
|
195
|
+
</ClearSlots>
|
|
196
|
+
</SlotProvider>
|
|
197
|
+
</Grid>
|
|
66
198
|
</div>
|
|
67
199
|
</div>
|
|
68
200
|
);
|