Skip to content

Commit 1ead59b

Browse files
committed
refactor to accept a node rather than a string in the filter function
1 parent 73a1971 commit 1ead59b

File tree

8 files changed

+19
-18
lines changed

8 files changed

+19
-18
lines changed

packages/@react-aria/autocomplete/src/useAutocomplete.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {AriaLabelingProps, BaseEvent, DOMProps, RefObject} from '@react-types/shared';
13+
import {AriaLabelingProps, BaseEvent, DOMProps, Node, RefObject} from '@react-types/shared';
1414
import {AriaTextFieldProps} from '@react-aria/textfield';
1515
import {AutocompleteProps, AutocompleteState} from '@react-stately/autocomplete';
1616
import {CLEAR_FOCUS_EVENT, FOCUS_EVENT, getActiveElement, getOwnerDocument, isCtrlKeyPressed, mergeProps, mergeRefs, useEffectEvent, useEvent, useId, useLabels, useObjectRef} from '@react-aria/utils';
@@ -56,7 +56,7 @@ export interface AutocompleteAria {
5656
/** Ref to attach to the wrapped collection. */
5757
collectionRef: RefObject<HTMLElement | null>,
5858
/** A filter function that returns if the provided collection node should be filtered out of the collection. */
59-
filter?: (nodeTextValue: string) => boolean
59+
filter?: (node: Node<unknown>) => boolean
6060
}
6161

6262
/**
@@ -316,9 +316,9 @@ export function useAutocomplete(props: AriaAutocompleteOptions, state: Autocompl
316316
'aria-label': stringFormatter.format('collectionLabel')
317317
});
318318

319-
let filterFn = useCallback((nodeTextValue: string) => {
319+
let filterFn = useCallback((node: Node<unknown>) => {
320320
if (filter) {
321-
return filter(nodeTextValue, state.inputValue);
321+
return filter(node.textValue, state.inputValue);
322322
}
323323

324324
return true;

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class CollectionNode<T> implements Node<T> {
6969
return node;
7070
}
7171

72-
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (textValue: string) => boolean): CollectionNode<T> | null {
72+
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (node: Node<T>) => boolean): CollectionNode<T> | null {
7373
let [firstKey, lastKey] = filterChildren(collection, newCollection, this.firstChildKey, filterFn);
7474
let newNode: Mutable<CollectionNode<T>> = this.clone();
7575
newNode.firstChildKey = firstKey;
@@ -97,8 +97,8 @@ export class ItemNode<T> extends CollectionNode<T> {
9797

9898
// TODO: resolve this
9999
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
100-
filter(_, __, filterFn: (textValue: string) => boolean): ItemNode<T> | null {
101-
if (filterFn(this.textValue)) {
100+
filter(_, __, filterFn: (node: Node<T>) => boolean): ItemNode<T> | null {
101+
if (filterFn(this)) {
102102
return this.clone();
103103
}
104104

@@ -113,7 +113,7 @@ export class SectionNode<T> extends CollectionNode<T> {
113113
super(SectionNode.type, key);
114114
}
115115

116-
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (textValue: string) => boolean): SectionNode<T> | null {
116+
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (node: Node<T>) => boolean): SectionNode<T> | null {
117117
let filteredSection = super.filter(collection, newCollection, filterFn);
118118
if (filteredSection) {
119119
if (filteredSection.lastChildKey !== null) {
@@ -283,7 +283,7 @@ export class BaseCollection<T> implements ICollection<Node<T>> {
283283
this.frozen = !isSSR;
284284
}
285285

286-
filter(filterFn: (textValue: string) => boolean, newCollection?: BaseCollection<T>): BaseCollection<T> {
286+
filter(filterFn: (node: Node<T>) => boolean, newCollection?: BaseCollection<T>): BaseCollection<T> {
287287
if (newCollection == null) {
288288
newCollection = new BaseCollection<T>();
289289
}
@@ -295,7 +295,7 @@ export class BaseCollection<T> implements ICollection<Node<T>> {
295295
}
296296
}
297297

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

packages/@react-stately/list/src/useListState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function useListState<T extends object>(props: ListProps<T>): ListState<T
7373
/**
7474
* Filters a collection using the provided filter function and returns a new ListState.
7575
*/
76-
export function UNSTABLE_useFilteredListState<T extends object>(state: ListState<T>, filterFn: ((nodeValue: string) => boolean) | null | undefined): ListState<T> {
76+
export function UNSTABLE_useFilteredListState<T extends object>(state: ListState<T>, filterFn: ((node: Node<T>) => boolean) | null | undefined): ListState<T> {
7777
let collection = useMemo(() => filterFn ? state.collection.filter!(filterFn) : state.collection, [state.collection, filterFn]);
7878
let selectionManager = state.selectionManager.withCollection(collection);
7979
useFocusedKeyReset(collection, selectionManager);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export function useTableState<T extends object>(props: TableStateProps<T>): Tabl
111111
/**
112112
* Filters a collection using the provided filter function and returns a new TableState.
113113
*/
114-
export function UNSTABLE_useFilteredTableState<T extends object>(state: TableState<T>, filterFn: ((nodeValue: string) => boolean) | null | undefined): TableState<T> {
114+
export function UNSTABLE_useFilteredTableState<T extends object>(state: TableState<T>, filterFn: ((node: Node<T>) => boolean) | null | undefined): TableState<T> {
115115
let collection = useMemo(() => filterFn ? state.collection.filter!(filterFn) : state.collection, [state.collection, filterFn]) as ITableCollection<T>;
116116
let selectionManager = state.selectionManager.withCollection(collection);
117117
// TODO: handle focus key reset? That logic is in useGridState

packages/@react-types/shared/src/collections.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ export interface Collection<T> extends Iterable<T> {
183183
getTextValue?(key: Key): string,
184184

185185
/** Filters the collection using the given function. */
186-
filter?(filterFn: (nodeValue: string) => boolean): Collection<T>
186+
filter?(filterFn: (node: T) => boolean): Collection<T>
187187
}
188188

189189
export interface Node<T> {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {AriaAutocompleteProps, CollectionOptions, useAutocomplete} from '@react-
1414
import {AutocompleteState, useAutocompleteState} from '@react-stately/autocomplete';
1515
import {InputContext} from './Input';
1616
import {mergeProps} from '@react-aria/utils';
17+
import {Node} from '@react-types/shared';
1718
import {Provider, removeDataAttributes, SlotProps, SlottedContextValue, useSlottedContext} from './utils';
1819
import React, {createContext, JSX, RefObject, useRef} from 'react';
1920
import {SearchFieldContext} from './SearchField';
@@ -22,7 +23,7 @@ import {TextFieldContext} from './TextField';
2223
export interface AutocompleteProps extends AriaAutocompleteProps, SlotProps {}
2324

2425
interface InternalAutocompleteContextValue {
25-
filter?: (nodeTextValue: string) => boolean,
26+
filter?: (node: Node<unknown>) => boolean,
2627
collectionProps: CollectionOptions,
2728
collectionRef: RefObject<HTMLElement | null>
2829
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ class SubmenuTriggerNode<T> extends CollectionNode<T> {
114114
super(SubmenuTriggerNode.type, key);
115115
}
116116

117-
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (textValue: string) => boolean): CollectionNode<T> | null {
117+
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (node: Node<T>) => boolean): CollectionNode<T> | null {
118118
let triggerNode = collection.getItem(this.firstChildKey!);
119-
if (triggerNode && filterFn(triggerNode.textValue)) {
119+
if (triggerNode && filterFn(triggerNode)) {
120120
// TODO: perhaps should call super.filter for correctness, but basically add the menu item child of the submenutrigger
121121
// to the keymap so it renders
122122
newCollection.addNode(triggerNode as CollectionNode<T>);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,10 +1063,10 @@ class TableRowNode<T> extends CollectionNode<T> {
10631063
super(TableRowNode.type, key);
10641064
}
10651065

1066-
filter(collection: BaseCollection<any>, newCollection: BaseCollection<any>, filterFn: (textValue: string) => boolean): TableRowNode<T> | null {
1066+
filter(collection: BaseCollection<T>, newCollection: BaseCollection<T>, filterFn: (node: Node<T>) => boolean): TableRowNode<T> | null {
10671067
let cells = collection.getChildren(this.key);
10681068
for (let cell of cells) {
1069-
if (filterFn(cell.textValue)) {
1069+
if (filterFn(cell)) {
10701070
return this.clone();
10711071
}
10721072
}

0 commit comments

Comments
 (0)