@@ -17,12 +17,13 @@ import {CollectionProps, CollectionRendererContext, DefaultCollectionRenderer, I
17
17
import { ContextValue , DEFAULT_SLOT , Provider , RenderProps , SlotProps , StyleProps , StyleRenderProps , useContextProps , useRenderProps } from './utils' ;
18
18
import { DragAndDropContext , DropIndicatorContext , DropIndicatorProps , useDndPersistedKeys , useRenderDropIndicator } from './DragAndDrop' ;
19
19
import { DragAndDropHooks } from './useDragAndDrop' ;
20
- import { DraggableCollectionState , DroppableCollectionState , Collection as ICollection , ListState , Node , SelectionBehavior , useListState } from 'react-stately' ;
20
+ import { DraggableCollectionState , DroppableCollectionState , Collection as ICollection , ListState , Node , SelectionBehavior , UNSTABLE_useFilteredListState , useListState } from 'react-stately' ;
21
21
import { filterDOMProps , inertValue , LoadMoreSentinelProps , useLoadMoreSentinel , useObjectRef } from '@react-aria/utils' ;
22
22
import { forwardRefType , GlobalDOMAttributes , HoverEvents , Key , LinkDOMProps , PressEvents , RefObject } from '@react-types/shared' ;
23
23
import { ListStateContext } from './ListBox' ;
24
24
import React , { createContext , ForwardedRef , forwardRef , HTMLAttributes , JSX , ReactNode , useContext , useEffect , useMemo , useRef } from 'react' ;
25
25
import { TextContext } from './Text' ;
26
+ import { UNSTABLE_InternalAutocompleteContext } from './Autocomplete' ;
26
27
27
28
export interface GridListRenderProps {
28
29
/**
@@ -103,21 +104,25 @@ interface GridListInnerProps<T extends object> {
103
104
}
104
105
105
106
function GridListInner < T extends object > ( { props, collection, gridListRef : ref } : GridListInnerProps < T > ) {
107
+ // TODO: for now, don't grab collection ref and collectionProps from the autocomplete, rely on the user tabbing to the gridlist
108
+ // figure out if we want to support virtual focus for grids when wrapped in an autocomplete
109
+ let { filter} = useContext ( UNSTABLE_InternalAutocompleteContext ) || { } ;
106
110
let { dragAndDropHooks, keyboardNavigationBehavior = 'arrow' , layout = 'stack' } = props ;
107
111
let { CollectionRoot, isVirtualized, layoutDelegate, dropTargetDelegate : ctxDropTargetDelegate } = useContext ( CollectionRendererContext ) ;
108
- let state = useListState ( {
112
+ let gridlistState = useListState ( {
109
113
...props ,
110
114
collection,
111
115
children : undefined ,
112
116
layoutDelegate
113
117
} ) ;
114
118
119
+ let filteredState = UNSTABLE_useFilteredListState ( gridlistState , filter ) ;
115
120
let collator = useCollator ( { usage : 'search' , sensitivity : 'base' } ) ;
116
- let { disabledBehavior, disabledKeys} = state . selectionManager ;
121
+ let { disabledBehavior, disabledKeys} = filteredState . selectionManager ;
117
122
let { direction} = useLocale ( ) ;
118
123
let keyboardDelegate = useMemo ( ( ) => (
119
124
new ListKeyboardDelegate ( {
120
- collection,
125
+ collection : filteredState . collection ,
121
126
collator,
122
127
ref,
123
128
disabledKeys,
@@ -126,7 +131,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
126
131
layout,
127
132
direction
128
133
} )
129
- ) , [ collection , ref , layout , disabledKeys , disabledBehavior , layoutDelegate , collator , direction ] ) ;
134
+ ) , [ filteredState . collection , ref , layout , disabledKeys , disabledBehavior , layoutDelegate , collator , direction ] ) ;
130
135
131
136
let { gridProps} = useGridList ( {
132
137
...props ,
@@ -135,9 +140,9 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
135
140
keyboardNavigationBehavior : layout === 'grid' ? 'tab' : keyboardNavigationBehavior ,
136
141
isVirtualized,
137
142
shouldSelectOnPressUp : props . shouldSelectOnPressUp
138
- } , state , ref ) ;
143
+ } , filteredState , ref ) ;
139
144
140
- let selectionManager = state . selectionManager ;
145
+ let selectionManager = filteredState . selectionManager ;
141
146
let isListDraggable = ! ! dragAndDropHooks ?. useDraggableCollectionState ;
142
147
let isListDroppable = ! ! dragAndDropHooks ?. useDroppableCollectionState ;
143
148
let dragHooksProvided = useRef ( isListDraggable ) ;
@@ -163,7 +168,7 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
163
168
164
169
if ( isListDraggable && dragAndDropHooks ) {
165
170
dragState = dragAndDropHooks . useDraggableCollectionState ! ( {
166
- collection,
171
+ collection : filteredState . collection ,
167
172
selectionManager,
168
173
preview : dragAndDropHooks . renderDragPreview ? preview : undefined
169
174
} ) ;
@@ -177,12 +182,12 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
177
182
178
183
if ( isListDroppable && dragAndDropHooks ) {
179
184
dropState = dragAndDropHooks . useDroppableCollectionState ! ( {
180
- collection,
185
+ collection : filteredState . collection ,
181
186
selectionManager
182
187
} ) ;
183
188
184
189
let keyboardDelegate = new ListKeyboardDelegate ( {
185
- collection,
190
+ collection : filteredState . collection ,
186
191
disabledKeys : selectionManager . disabledKeys ,
187
192
disabledBehavior : selectionManager . disabledBehavior ,
188
193
ref
@@ -197,14 +202,14 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
197
202
}
198
203
199
204
let { focusProps, isFocused, isFocusVisible} = useFocusRing ( ) ;
200
- let isEmpty = state . collection . size === 0 ;
205
+ let isEmpty = filteredState . collection . size === 0 ;
201
206
let renderValues = {
202
207
isDropTarget : isRootDropTarget ,
203
208
isEmpty,
204
209
isFocused,
205
210
isFocusVisible,
206
211
layout,
207
- state
212
+ state : filteredState
208
213
} ;
209
214
let renderProps = useRenderProps ( {
210
215
className : props . className ,
@@ -243,13 +248,13 @@ function GridListInner<T extends object>({props, collection, gridListRef: ref}:
243
248
data-layout = { layout } >
244
249
< Provider
245
250
values = { [
246
- [ ListStateContext , state ] ,
251
+ [ ListStateContext , filteredState ] ,
247
252
[ DragAndDropContext , { dragAndDropHooks, dragState, dropState} ] ,
248
253
[ DropIndicatorContext , { render : GridListDropIndicatorWrapper } ]
249
254
] } >
250
255
{ isListDroppable && < RootDropIndicator /> }
251
256
< CollectionRoot
252
- collection = { collection }
257
+ collection = { filteredState . collection }
253
258
scrollRef = { ref }
254
259
persistedKeys = { useDndPersistedKeys ( selectionManager , dragAndDropHooks , dropState ) }
255
260
renderDropIndicator = { useRenderDropIndicator ( dragAndDropHooks , dropState ) } />
@@ -279,13 +284,20 @@ export interface GridListItemProps<T = object> extends RenderProps<GridListItemR
279
284
onAction ?: ( ) => void
280
285
}
281
286
282
- // TODO: add filter funct to this
287
+ // TODO: reuse?
283
288
class GridListNode extends CollectionNode < any > {
284
289
static readonly type = 'item' ;
285
290
constructor ( key : Key ) {
286
291
super ( GridListNode . type , key ) ;
287
292
}
288
293
294
+ filter ( _ , __ , filterFn : ( textValue : string ) => boolean ) : CollectionNode < any > | null {
295
+ if ( filterFn ( this . textValue ) ) {
296
+ return this . clone ( ) ;
297
+ }
298
+
299
+ return null ;
300
+ }
289
301
}
290
302
291
303
/**
0 commit comments