UNPKG

9.03 kBTypeScriptView Raw
1/// <reference types="react" />
2import { type Props } from "@blueprintjs/core";
3import type { ItemListRenderer } from "./itemListRenderer";
4import type { ItemRenderer } from "./itemRenderer";
5import type { CreateNewItem } from "./listItemsUtils";
6import type { ItemListPredicate, ItemPredicate } from "./predicate";
7/**
8 * Equality test comparator to determine if two {@link ListItemsProps} items are equivalent.
9 *
10 * @return `true` if the two items are equivalent.
11 */
12export type ItemsEqualComparator<T> = (itemA: T, itemB: T) => boolean;
13/**
14 * Union of all possible types for {@link ListItemsProps#itemsEqual}.
15 */
16export type ItemsEqualProp<T> = ItemsEqualComparator<T> | keyof T;
17/** Reusable generic props for a component that operates on a filterable, selectable list of `items`. */
18export interface ListItemsProps<T> extends Props {
19 /**
20 * The currently focused item for keyboard interactions, or `null` to
21 * indicate that no item is active. If omitted or `undefined`, this prop will be
22 * uncontrolled (managed by the component's state). Use `onActiveItemChange`
23 * to listen for updates.
24 */
25 activeItem?: T | CreateNewItem | null;
26 /** Array of items in the list. */
27 items: T[];
28 /**
29 * Specifies how to test if two items are equal. By default, simple strict
30 * equality (`===`) is used to compare two items.
31 *
32 * If your items have a unique identifier field, simply provide the name of
33 * a property on the item that can be compared with strict equality to
34 * determine equivalence: `itemsEqual="id"` will check `a.id === b.id`.
35 *
36 * If more complex comparison logic is required, provide an equality
37 * comparator function that returns `true` if the two items are equal. The
38 * arguments to this function will never be `null` or `undefined`, as those
39 * values are handled before calling the function.
40 */
41 itemsEqual?: ItemsEqualProp<T>;
42 /**
43 * Determine if the given item is disabled. Provide a callback function, or
44 * simply provide the name of a boolean property on the item that exposes
45 * its disabled state.
46 */
47 itemDisabled?: keyof T | ((item: T, index: number) => boolean);
48 /**
49 * Customize querying of entire `items` array. Return new list of items.
50 * This method can reorder, add, or remove items at will.
51 * (Supports filter algorithms that operate on the entire set, rather than individual items.)
52 *
53 * If `itemPredicate` is also defined, this prop takes priority and the other will be ignored.
54 */
55 itemListPredicate?: ItemListPredicate<T>;
56 /**
57 * Customize querying of individual items.
58 *
59 * __Filtering a list of items.__ This function is invoked to filter the
60 * list of items as a query is typed. Return `true` to keep the item, or
61 * `false` to hide. This method is invoked once for each item, so it should
62 * be performant. For more complex queries, use `itemListPredicate` to
63 * operate once on the entire array. For the purposes of filtering the list,
64 * this prop is ignored if `itemListPredicate` is also defined.
65 *
66 * __Matching a pasted value to an item.__ This function is also invoked to
67 * match a pasted value to an existing item if possible. In this case, the
68 * function will receive `exactMatch=true`, and the function should return
69 * true only if the item _exactly_ matches the query. For the purposes of
70 * matching pasted values, this prop will be invoked even if
71 * `itemListPredicate` is defined.
72 */
73 itemPredicate?: ItemPredicate<T>;
74 /**
75 * Custom renderer for an item in the dropdown list. Receives a boolean indicating whether
76 * this item is active (selected by keyboard arrows) and an `onClick` event handler that
77 * should be attached to the returned element.
78 */
79 itemRenderer: ItemRenderer<T>;
80 /**
81 * Custom renderer for the contents of the dropdown.
82 *
83 * The default implementation invokes `itemRenderer` for each item that passes the predicate
84 * and wraps them all in a `Menu` element. If the query is empty then `initialContent` is returned,
85 * and if there are no items that match the predicate then `noResults` is returned.
86 */
87 itemListRenderer?: ItemListRenderer<T>;
88 /**
89 * React content to render when query is empty.
90 * If omitted, all items will be rendered (or result of `itemListPredicate` with empty query).
91 * If explicit `null`, nothing will be rendered when query is empty.
92 *
93 * This prop is ignored if a custom `itemListRenderer` is supplied.
94 */
95 initialContent?: React.ReactNode | null;
96 /**
97 * React content to render when filtering items returns zero results.
98 * If omitted, nothing will be rendered in this case.
99 *
100 * This prop is ignored if a custom `itemListRenderer` is supplied.
101 *
102 * NOTE: if passing a `MenuItem`, ensure it has `roleStructure="listoption"` prop.
103 */
104 noResults?: React.ReactNode;
105 /**
106 * Invoked when user interaction should change the active item: arrow keys
107 * move it up/down in the list, selecting an item makes it active, and
108 * changing the query may reset it to the first item in the list if it no
109 * longer matches the filter.
110 *
111 * If the "Create Item" option is displayed and currently active, then
112 * `isCreateNewItem` will be `true` and `activeItem` will be `null`. In this
113 * case, you should provide a valid `CreateNewItem` object to the
114 * `activeItem` _prop_ in order for the "Create Item" option to appear as
115 * active.
116 *
117 * __Note:__ You can instantiate a `CreateNewItem` object using the
118 * `getCreateNewItem()` utility exported from this package.
119 */
120 onActiveItemChange?: (activeItem: T | null, isCreateNewItem: boolean) => void;
121 /**
122 * Callback invoked when an item from the list is selected,
123 * typically by clicking or pressing `enter` key.
124 */
125 onItemSelect: (item: T, event?: React.SyntheticEvent<HTMLElement>) => void;
126 /**
127 * Callback invoked when multiple items are selected at once via pasting.
128 */
129 onItemsPaste?: (items: T[]) => void;
130 /**
131 * Callback invoked when the query string changes.
132 */
133 onQueryChange?: (query: string, event?: React.ChangeEvent<HTMLInputElement>) => void;
134 /**
135 * If provided, allows new items to be created using the current query
136 * string. This is invoked when user interaction causes one or many items to be
137 * created, either by pressing the `Enter` key or by clicking on the "Create
138 * Item" option. It transforms a query string into one or many items type.
139 */
140 createNewItemFromQuery?: (query: string) => T | T[];
141 /**
142 * Custom renderer to transform the current query string into a selectable
143 * "Create Item" option. If this function is provided, a "Create Item"
144 * option will be rendered at the end of the list of items. If this function
145 * is not provided, a "Create Item" option will not be displayed.
146 */
147 createNewItemRenderer?: (query: string, active: boolean, handleClick: React.MouseEventHandler<HTMLElement>) => React.JSX.Element | undefined;
148 /**
149 * Determines the position of the `createNewItem` within the list: first or
150 * last. Only relevant when `createNewItemRenderer` is defined.
151 *
152 * @default 'last'
153 */
154 createNewItemPosition?: "first" | "last";
155 /**
156 * Whether the active item should be reset to the first matching item _every
157 * time the query changes_ (via prop or by user input).
158 *
159 * @default true
160 */
161 resetOnQuery?: boolean;
162 /**
163 * Whether the active item should be reset to the first matching item _when
164 * an item is selected_. The query will also be reset to the empty string.
165 *
166 * @default false
167 */
168 resetOnSelect?: boolean;
169 /**
170 * When `activeItem` is controlled, whether the active item should _always_
171 * be scrolled into view when the prop changes. If `false`, only changes
172 * that result from built-in interactions (clicking, querying, or using
173 * arrow keys) will scroll the active item into view. Ignored if the
174 * `activeItem` prop is omitted (uncontrolled behavior).
175 *
176 * @default true
177 */
178 scrollToActiveItem?: boolean;
179 /**
180 * Query string passed to `itemListPredicate` or `itemPredicate` to filter items.
181 * This value is controlled: its state must be managed externally by attaching an `onChange`
182 * handler to the relevant element in your `renderer` implementation.
183 */
184 query?: string;
185}
186/**
187 * Utility function for executing the {@link ListItemsProps#itemsEqual} prop to test
188 * for equality between two items.
189 *
190 * @return `true` if the two items are equivalent according to `itemsEqualProp`.
191 */
192export declare function executeItemsEqual<T>(itemsEqualProp: ItemsEqualProp<T> | undefined, itemA: T | null | undefined, itemB: T | null | undefined): boolean;