diff --git a/packages/docs-app/src/examples/select-examples/films.tsx b/packages/docs-app/src/examples/select-examples/films.tsx index 4f94eabf32..329352abf0 100644 --- a/packages/docs-app/src/examples/select-examples/films.tsx +++ b/packages/docs-app/src/examples/select-examples/films.tsx @@ -5,7 +5,7 @@ */ import { Classes, MenuItem } from "@blueprintjs/core"; -import { ItemRenderer } from "@blueprintjs/select"; +import { ItemPredicate, ItemRenderer } from "@blueprintjs/select"; import * as classNames from "classnames"; import * as React from "react"; @@ -141,9 +141,9 @@ export const renderFilm: ItemRenderer = (film, { handleClick, modifiers } ); }; -export function filterFilm(query: string, film: IFilm) { +export const filterFilm: ItemPredicate = (query, film) => { return `${film.rank}. ${film.title.toLowerCase()} ${film.year}`.indexOf(query.toLowerCase()) >= 0; -} +}; export const filmSelectProps = { itemPredicate: filterFilm, diff --git a/packages/select/src/components/query-list/itemRenderer.ts b/packages/select/src/common/itemRenderer.ts similarity index 100% rename from packages/select/src/components/query-list/itemRenderer.ts rename to packages/select/src/common/itemRenderer.ts diff --git a/packages/select/src/common/predicate.ts b/packages/select/src/common/predicate.ts new file mode 100644 index 0000000000..b7e7889a0c --- /dev/null +++ b/packages/select/src/common/predicate.ts @@ -0,0 +1,23 @@ +/* +* Copyright 2018 Palantir Technologies, Inc. All rights reserved. +* +* Licensed under the terms of the LICENSE file distributed with this project. +*/ + +/** + * Customize querying of entire `items` array. Return new list of items. + * This method can reorder, add, or remove items at will. + * (Supports filter algorithms that operate on the entire set, rather than individual items.) + * + * If defined with `itemPredicate`, this prop takes priority and the other will be ignored. + */ +export type ItemListPredicate = (query: string, items: T[]) => T[]; + +/** + * Customize querying of individual items. Return `true` to keep the item, `false` to hide. + * This method will be invoked once for each item, so it should be performant. For more complex + * queries, use `itemListPredicate` to operate once on the entire array. + * + * If defined with `itemListPredicate`, this prop will be ignored. + */ +export type ItemPredicate = (query: string, item: T, index: number) => boolean; diff --git a/packages/select/src/components/index.ts b/packages/select/src/components/index.ts index 1ae0e15f67..8b4d1a561f 100644 --- a/packages/select/src/components/index.ts +++ b/packages/select/src/components/index.ts @@ -5,7 +5,6 @@ */ export * from "./omnibar/omnibar"; -export * from "./query-list/itemRenderer"; export * from "./query-list/queryList"; export * from "./select/multiSelect"; export * from "./select/select"; diff --git a/packages/select/src/components/query-list/queryList.tsx b/packages/select/src/components/query-list/queryList.tsx index 9539bc3de2..b57862bc25 100644 --- a/packages/select/src/components/query-list/queryList.tsx +++ b/packages/select/src/components/query-list/queryList.tsx @@ -7,7 +7,8 @@ import * as React from "react"; import { IProps, Keys, Utils } from "@blueprintjs/core"; -import { IItemModifiers, ItemRenderer } from "./itemRenderer"; +import { IItemModifiers, ItemRenderer } from "../../common/itemRenderer"; +import { ItemListPredicate, ItemPredicate } from "../../common/predicate"; /** Reusable generic props for a component that operates on a filterable, selectable list of `items`. */ export interface IListItemsProps extends IProps { @@ -21,7 +22,7 @@ export interface IListItemsProps extends IProps { * * If defined with `itemPredicate`, this prop takes priority and the other will be ignored. */ - itemListPredicate?: (query: string, items: T[]) => T[]; + itemListPredicate?: ItemListPredicate; /** * Customize querying of individual items. Return `true` to keep the item, `false` to hide. @@ -30,7 +31,7 @@ export interface IListItemsProps extends IProps { * * If defined with `itemListPredicate`, this prop will be ignored. */ - itemPredicate?: (query: string, item: T, index: number) => boolean; + itemPredicate?: ItemPredicate; /** * Custom renderer for an item in the dropdown list. Receives a boolean indicating whether diff --git a/packages/select/src/components/select/select-component.md b/packages/select/src/components/select/select-component.md index 745f8dfe91..a906860c27 100644 --- a/packages/select/src/components/select/select-component.md +++ b/packages/select/src/components/select/select-component.md @@ -43,6 +43,9 @@ Supply a predicate to automatically query items based on the `InputGroup` value. Omitting both `itemPredicate` and `itemListPredicate` props will cause the component to always render all `items`. It will not hide the `InputGroup`; use the `filterable` prop for that. In this case, you can implement your own filtering and simply change the `items` prop. +The __@blueprintjs/select__ package exports `ItemPredicate` and `ItemListPredicate` type aliases to simplify the process of implementing these functions. +See the code sample in [Item Renderer API](#select/select-component.item-renderer-api) below for usage. + @### Non-ideal states If the query returns no results or `items` is empty, then `noResults` will be rendered in place of the usual list. You also have the option to provide `initialContent`, which will render in place of the item list if the query is empty. @@ -76,9 +79,14 @@ or face React's console wrath! ```tsx import { Classes, MenuItem } from "@blueprintjs/core"; -import { ItemRenderer, Select } from "@blueprintjs/select"; +import { ItemRenderer, ItemPredicate, Select } from "@blueprintjs/select"; + const FilmSelect = Select.ofType(); +const filterFilm: ItemPredicate = (query, film) => { + return film.title.toLowerCase().indexOf(query.toLowerCase()) >= 0; +}; + const renderFilm: ItemRenderer = (item, { handleClick, modifiers }) => { if (!modifiers.filtered) { return null; @@ -94,7 +102,7 @@ const renderFilm: ItemRenderer = (item, { handleClick, modifiers }) => { ); }; - + ``` @interface IItemRendererProps diff --git a/packages/select/src/index.ts b/packages/select/src/index.ts index 9eba1a0ecb..8e0af3253a 100644 --- a/packages/select/src/index.ts +++ b/packages/select/src/index.ts @@ -5,4 +5,6 @@ */ export * from "./common/classes"; +export * from "./common/itemRenderer"; +export * from "./common/predicate"; export * from "./components";