UNPKG

@react-md/autocomplete

Version:

Create an accessible autocomplete component that allows a user to get real-time suggestions as they type within an input. This component can also be hooked up to a backend API that handles additional filtering or sorting.

108 lines 3.48 kB
import { caseInsensitiveFilter, fuzzyFilter } from "@react-md/utils"; /** * Generates an id for each result in the autocomplete's listbox. * * @param id - The listbox's id * @param index - The index of the result in the list * @returns an id string */ export function getResultId(id, index) { return "".concat(id, "-result-").concat(index + 1); } /** * Gets a renderable label for each result in the autocomplete's listbox. This * will be applied as the `children` for the `Option` element. * * @param datum - The current result datum to get a label for * @param labelKey - The key to extract a label from if the datum is an object * @param _query - The current search query. This is useful if you want to * implement text "highlighting" (bold) of all the letters that match in the * item. * @returns a renderable node to display */ export function getResultLabel(datum, labelKey, _query) { if (typeof datum === "string") { return datum; } var label = datum[labelKey]; return datum.children || (typeof label === "undefined" ? null : label); } /** * Gets a value string from each result that can be searched. * * @param datum - The current result datum that should have a string extracted * @param valueKey - The key to use to extract a string value from if the datum * is an object * @returns a searchable string. */ export function getResultValue(datum, valueKey) { if (typeof datum === "string") { return datum; } var value = datum[valueKey]; if (process.env.NODE_ENV !== "production" && typeof value !== "string" && typeof value !== "number") { throw new Error("Unable to extract a result value string"); } return "".concat(value); } /** * This is used to disable filtering and just return the data list immediately. * Useful when the filtering is done somewhere else like a server/API * @internal */ export var noFilter = function (_, data) { return data; }; /** * Gets the filter function to use within the Autocomplete based on the provided * filter prop * * @internal */ export function getFilterFunction(filter) { if (typeof filter === "function") { return filter; } switch (filter) { case "fuzzy": return fuzzyFilter; case "case-insensitive": return caseInsensitiveFilter; case "none": return noFilter; default: if (process.env.NODE_ENV !== "production") { throw new Error("Invalid filter function: \"".concat(filter, "\". Supported values are: \"fuzzy\", \"case-insensitive\", \"none\", or a custom function.")); } return noFilter; } } /** * This is an extremely simple type guard that is useful when using the * `onAutoComplete` handler since I'm terrible at typescript types. This will * ensure that if the result is an object, it will match the provided data type * of your data list. * * Example: * * ```ts * interface Example { * name: string; * value: string; * } * * * const [example, setExample] = useState<Example | null>(null); * const onAutoComplete = useCallback<AuoCompleteHandler>((_name, example) => { * if (isResultOf<Example>(example)) { * setExample(example); * } * }, []) * ``` * * @param datum - The result data to type guard against. */ export function isResultOf(datum) { return !!datum && typeof datum === "object"; } //# sourceMappingURL=utils.js.map