Skip to content

Commit 3ec3fd6

Browse files
committed
fix tableCollection filter so it doesnt need to call filterChildren directly
1 parent 432a43c commit 3ec3fd6

File tree

9 files changed

+18
-31
lines changed

9 files changed

+18
-31
lines changed

packages/@react-aria/collections/src/BaseCollection.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,19 @@ export class BaseCollection<T> implements ICollection<Node<T>> {
233233
this.frozen = !isSSR;
234234
}
235235

236-
filter(filterFn: (textValue: string) => boolean): BaseCollection<T> {
237-
let newCollection = new BaseCollection<T>();
236+
filter(filterFn: (textValue: string) => boolean, newCollection?: BaseCollection<T>): BaseCollection<T> {
237+
if (newCollection == null) {
238+
newCollection = new BaseCollection<T>();
239+
}
240+
238241
let [firstKey, lastKey] = filterChildren(this, newCollection, this.firstKey, filterFn);
239242
newCollection.firstKey = firstKey;
240243
newCollection.lastKey = lastKey;
241244
return newCollection;
242245
}
243246
}
244247

245-
export function filterChildren<T>(collection: BaseCollection<T>, newCollection: BaseCollection<T>, firstChildKey: Key | null, filterFn: (textValue: string) => boolean): [Key | null, Key | null] {
248+
function filterChildren<T>(collection: BaseCollection<T>, newCollection: BaseCollection<T>, firstChildKey: Key | null, filterFn: (textValue: string) => boolean): [Key | null, Key | null] {
246249
// loop over the siblings for firstChildKey
247250
// create new nodes based on calling node.filter for each child
248251
// if it returns null then don't include it, otherwise update its prev/next keys

packages/@react-aria/collections/src/CollectionBuilder.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,13 @@ function useSSRCollectionNode<T extends Element>(CollectionNodeClass: Collection
140140
// collection by the time we need to use the collection to render to the real DOM.
141141
// After hydration, we switch to client rendering using the portal.
142142
let itemRef = useCallback((element: ElementNode<any> | null) => {
143-
// TODO: check setProps api
144143
element?.setProps(props, ref, rendered, render, CollectionNodeClass);
145144
}, [props, ref, rendered, render, CollectionNodeClass]);
146145
let parentNode = useContext(SSRContext);
147146
if (parentNode) {
148147
// Guard against double rendering in strict mode.
149148
let element = parentNode.ownerDocument.nodesByProps.get(props);
150149
if (!element) {
151-
// TODO: check this, maybe should just pass the CollectionNodeClass as a whole?
152150
element = parentNode.ownerDocument.createElement(CollectionNodeClass.type);
153151
element.setProps(props, ref, rendered, render);
154152
parentNode.appendChild(element);
@@ -161,7 +159,6 @@ function useSSRCollectionNode<T extends Element>(CollectionNodeClass: Collection
161159
: null;
162160
}
163161

164-
// console.log('type', CollectionNodeClass, CollectionNodeClass.type)
165162
// @ts-ignore
166163
// TODO: could just make this a div perhaps, but keep it in line with how it used to work
167164
return <CollectionNodeClass.type ref={itemRef}>{children}</CollectionNodeClass.type>;
@@ -201,7 +198,6 @@ export function createLeafComponent<P extends object, E extends Element>(Collect
201198
return Result;
202199
}
203200

204-
// TODO: check the signature of this too
205201
export function createBranchComponent<T extends object, P extends {children?: any}, E extends Element>(CollectionNodeClass: CollectionNodeClass<any>, render: (props: P, ref: ForwardedRef<E>, node: Node<T>) => ReactElement | null, useChildren: (props: P) => ReactNode = useCollectionChildren): (props: P & React.RefAttributes<E>) => ReactElement | null {
206202
let Component = ({node}) => render(node.props, node.props.ref, node);
207203
let Result = (forwardRef as forwardRefType)((props: P, ref: ForwardedRef<E>) => {

packages/@react-aria/collections/src/Document.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,6 @@ export class ElementNode<T> extends BaseNode<T> {
324324
}
325325
}
326326

327-
// TODO
328327
setProps<E extends Element>(obj: {[key: string]: any}, ref: ForwardedRef<E>, rendered?: ReactNode, render?: (node: Node<T>) => ReactElement, CollectionNodeClass?: CollectionNodeClass<any>): void {
329328
let node = this.getMutableNode();
330329
let {value, textValue, id, ...props} = obj;

packages/@react-aria/collections/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
export {CollectionBuilder, Collection, createLeafComponent, createBranchComponent} from './CollectionBuilder';
1414
export {createHideableComponent, useIsHidden} from './Hidden';
1515
export {useCachedChildren} from './useCachedChildren';
16-
export {BaseCollection, CollectionNode, filterChildren} from './BaseCollection';
16+
export {BaseCollection, CollectionNode} from './BaseCollection';
1717

1818
export type {CollectionBuilderProps, CollectionProps} from './CollectionBuilder';
1919
export type {CachedChildrenOptions} from './useCachedChildren';

packages/@react-stately/table/src/useTableState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export function useTableState<T extends object>(props: TableStateProps<T>): Tabl
109109
}
110110

111111
/**
112-
* Filters a collection using the provided filter function and returns a new ListState.
112+
* Filters a collection using the provided filter function and returns a new TableState.
113113
*/
114114
export function UNSTABLE_useFilteredTableState<T extends object>(state: TableState<T>, filterFn: ((nodeValue: string) => boolean) | null | undefined): TableState<T> {
115115
let collection = useMemo(() => filterFn ? state.collection.filter!(filterFn) : state.collection, [state.collection, filterFn]) as ITableCollection<T>;

packages/react-aria-components/src/Breadcrumbs.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,17 @@ export interface BreadcrumbProps extends RenderProps<BreadcrumbRenderProps>, Glo
7373
id?: Key
7474
}
7575

76-
// TODO: perhaps this should be reuse ItemNode, for now just have it separate
7776
class BreadcrumbNode extends CollectionNode<any> {
7877
static readonly type = 'item';
7978

8079
constructor(key: Key) {
8180
super(BreadcrumbNode.type, key);
8281
}
82+
83+
// For, don't support Breadcrumb filtering
84+
filter(): CollectionNode<any> | null {
85+
return this.clone();
86+
}
8387
}
8488

8589
/**

packages/react-aria-components/src/GridList.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ export interface GridListItemProps<T = object> extends RenderProps<GridListItemR
284284
onAction?: () => void
285285
}
286286

287-
// TODO: reuse?
288287
class GridListNode extends CollectionNode<any> {
289288
static readonly type = 'item';
290289
constructor(key: Key) {
@@ -534,8 +533,6 @@ export interface GridListLoadMoreItemProps extends Omit<LoadMoreSentinelProps, '
534533
isLoading?: boolean
535534
}
536535

537-
// TODO: can probably reuse ListBox's loaderNode, but might keep separate
538-
// add filter logic
539536
class GridListLoaderNode extends CollectionNode<any> {
540537
static readonly type = 'loader';
541538

packages/react-aria-components/src/ListBox.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,6 @@ function ListBoxSectionInner<T extends object>(props: ListBoxSectionProps<T>, re
305305
);
306306
}
307307

308-
309-
// TODO: reuse
310308
export class ListBoxSectionNode<T> extends CollectionNode<T> {
311309
static readonly type = 'section';
312310

@@ -354,7 +352,6 @@ export interface ListBoxItemProps<T = object> extends RenderProps<ListBoxItemRen
354352
onAction?: () => void
355353
}
356354

357-
// TODO: reusue
358355
class ListBoxItemNode<T> extends CollectionNode<T> {
359356
static readonly type = 'item';
360357

@@ -511,7 +508,6 @@ function ListBoxDropIndicator(props: ListBoxDropIndicatorProps, ref: ForwardedRe
511508
);
512509
}
513510

514-
// TODO: can reuse this most likely
515511
class ListBoxLoaderNode extends CollectionNode<any> {
516512
static readonly type = 'loader';
517513

packages/react-aria-components/src/Table.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {AriaLabelingProps, GlobalDOMAttributes, HoverEvents, Key, LinkDOMProps, PressEvents, RefObject} from '@react-types/shared';
2-
import {BaseCollection, Collection, CollectionBuilder, CollectionNode, createBranchComponent, createLeafComponent, filterChildren, useCachedChildren} from '@react-aria/collections';
2+
import {BaseCollection, Collection, CollectionBuilder, CollectionNode, createBranchComponent, createLeafComponent, useCachedChildren} from '@react-aria/collections';
33
import {buildHeaderRows, TableColumnResizeState} from '@react-stately/table';
44
import {ButtonContext} from './Button';
55
import {CheckboxContext} from './RSPContexts';
@@ -165,7 +165,7 @@ class TableCollection<T> extends BaseCollection<T> implements ITableCollection<T
165165
collection.rowHeaderColumnKeys = this.rowHeaderColumnKeys;
166166
collection.head = this.head;
167167
collection.body = this.body;
168-
// TODO clone updateColumns as well but it is private
168+
collection.updateColumns = this.updateColumns;
169169
return collection;
170170
}
171171

@@ -198,17 +198,9 @@ class TableCollection<T> extends BaseCollection<T> implements ITableCollection<T
198198
}
199199

200200
filter(filterFn: (textValue: string) => boolean): TableCollection<T> {
201-
// TODO: ideally we wouldn't need to reimplement this but we need a TableCollection, not a BaseCollection
202-
// Also need to handle the fact that a bunch of properites are private
203-
let clone = this.clone() as Mutable<TableCollection<T>>;
204-
// @ts-ignore
205-
let [firstKey, lastKey] = filterChildren(this, clone, this.firstKey, filterFn);
206-
// @ts-ignore
207-
clone.firstKey = firstKey;
208-
// @ts-ignore
209-
clone.lastKey = lastKey;
210-
// @ts-ignore
211-
return clone;
201+
let clone = this.clone();
202+
return super.filter(filterFn, clone) as TableCollection<T>;
203+
212204
}
213205
}
214206

0 commit comments

Comments
 (0)