UNPKG

@workday/canvas-kit-react

Version:

The parent module that contains all Workday Canvas Kit React components

59 lines (58 loc) 2.13 kB
import React from 'react'; import { useListLoader } from '@workday/canvas-kit-react/collection'; const useDebounce = () => { const debounceTimer = React.useRef(-1); React.useEffect(() => { return () => { // We want to clear any timeout on unload. We disable the ESLint rule because this is actually // what we want // eslint-disable-next-line react-hooks/exhaustive-deps clearTimeout(debounceTimer.current); }; }, []); return (fn, wait) => { clearTimeout(debounceTimer.current); debounceTimer.current = setTimeout(fn, wait); // We don't actually care what the real return type of setTimeout is. It is a number in the browser and something else in Node }; }; /** * Creates a `Combobox` data loader and a model. The `Combobox` loader extends the * {@link useListLoader} and connects a {@link ComboboxInput Combobox.Input} to the filter of the * data loader. A simple loader using * [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) could look like the * following: * * ```ts * const {model, loader} = useComboboxLoader( * { * total: 0, * pageSize: 20, * async load({pageNumber, pageSize, filter}) { * // `filter` will be a `string` * return fetch(`/myUrl?filter=${filter}`) * .then(response => response.json()) * .then(response => { * return {total: response.total, items: response.items}; * }); * }, * }, * useComboboxModel * ); * ``` */ export const useComboboxLoader = (config, modelHook) => { const debounce = useDebounce(); const list = useListLoader({ shouldLoad(params, state) { return ((config.shouldLoad ? config.shouldLoad(params, state) : true) && state.visibility !== 'hidden'); }, ...modelHook.mergeConfig(config, { onFilterChange(event) { const value = event.currentTarget.value; debounce(() => list.loader.updateFilter(value), 150); }, }), }, modelHook); return list; };