@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
JavaScript
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