UNPKG

@availity/mui-autocomplete

Version:

Availity MUI Autocomplete Component - part of the @availity/element design system

364 lines (356 loc) 12.8 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __objRest = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols) for (var prop of __getOwnPropSymbols(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop)) target[prop] = source[prop]; } return target; }; var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/lib/Autocomplete.tsx import { forwardRef } from "react"; import { default as MuiAutocomplete } from "@mui/material/Autocomplete"; import CircularProgress from "@mui/material/CircularProgress"; import { default as MuiIconButton } from "@mui/material/IconButton"; import { TextField } from "@availity/mui-textfield"; import { SelectDivider, SelectExpandIcon } from "@availity/mui-form-utils"; import { createFilterOptions } from "@mui/material/Autocomplete"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var PopupIndicatorWrapper = forwardRef((props, ref) => /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(SelectDivider, { orientation: "vertical", className: "MuiSelect-avEndAdornmentDivider" }), /* @__PURE__ */ jsx(MuiIconButton, __spreadProps(__spreadValues({}, props), { ref })) ] })); var progressSx = { marginRight: ".5rem" }; var LoadingIndicator = () => /* @__PURE__ */ jsx(CircularProgress, { "aria-label": "Loading", size: 20, sx: progressSx }); var Autocomplete = (_a) => { var _b = _a, { FieldProps } = _b, props = __objRest(_b, [ "FieldProps" ]); const defaultProps = { fullWidth: true, size: "small" }; const resolvedProps = (params) => ({ InputProps: __spreadProps(__spreadValues(__spreadValues({}, params == null ? void 0 : params.InputProps), FieldProps == null ? void 0 : FieldProps.InputProps), { endAdornment: props.loading ? /* @__PURE__ */ jsxs(Fragment, { children: [ (params == null ? void 0 : params.InputProps.endAdornment) || null, /* @__PURE__ */ jsx(LoadingIndicator, {}) ] }) : (params == null ? void 0 : params.InputProps.endAdornment) || null }), inputProps: __spreadProps(__spreadValues({}, params == null ? void 0 : params.inputProps), { // appease the Level Access scanning tools "aria-controls": (params == null ? void 0 : params.inputProps["aria-controls"]) || "" }) }); return /* @__PURE__ */ jsx( MuiAutocomplete, __spreadValues(__spreadValues({ renderInput: (params) => { return /* @__PURE__ */ jsx(TextField, __spreadValues(__spreadValues(__spreadValues({}, params), FieldProps), resolvedProps(params))); }, popupIcon: /* @__PURE__ */ jsx(SelectExpandIcon, { className: "MuiSelect-avExpandIcon" }), slotProps: { popupIndicator: { component: PopupIndicatorWrapper } } }, props), defaultProps) ); }; // src/lib/AsyncAutocomplete.tsx import { useState as useState2, useRef, useEffect as useEffect2, useCallback } from "react"; import { useInfiniteQuery } from "@tanstack/react-query"; // src/lib/util.tsx import { useEffect, useState } from "react"; var useDebounce = (value, delay) => { const [debouncedValue, setDebouncedValue] = useState(""); useEffect(() => { const timer = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(timer); }; }, [value]); return debouncedValue; }; // src/lib/AsyncAutocomplete.tsx import { jsx as jsx2 } from "react/jsx-runtime"; var AsyncAutocomplete = (_a) => { var _b = _a, { loadOptions, limit = 50, queryKey, ListboxProps, queryOptions, watchParams, debounceTimeout = 350, FieldProps, onInputChange, prependOptions = [] } = _b, rest = __objRest(_b, [ "loadOptions", "limit", "queryKey", "ListboxProps", "queryOptions", "watchParams", "debounceTimeout", "FieldProps", "onInputChange", "prependOptions" ]); const [inputValue, setInputValue] = useState2(""); const listboxRef = useRef(null); const setListboxRef = useCallback((node) => { listboxRef.current = node; }, []); const handleInputPropsOnChange = (event) => { var _a2; setInputValue(event.target.value); if ((_a2 = FieldProps == null ? void 0 : FieldProps.InputProps) == null ? void 0 : _a2.onChange) FieldProps.InputProps.onChange(event); }; const debouncedInput = useDebounce(inputValue, debounceTimeout); const { isLoading, isFetching, data, hasNextPage, fetchNextPage } = useInfiniteQuery(__spreadValues({ queryKey: [queryKey, limit, debouncedInput, watchParams], queryFn: (_0) => __async(null, [_0], function* ({ pageParam = 0 }) { return loadOptions(pageParam, limit, debouncedInput); }), staleTime: 1e4, getNextPageParam: (lastPage) => lastPage.hasMore ? lastPage.offset + limit : void 0 }, queryOptions)); const options = (data == null ? void 0 : data.pages) ? data.pages.map((page) => page.options).flat() : []; const finalOptions = prependOptions.length > 0 ? [ ...prependOptions, ...options.filter( (option) => !prependOptions.some( (prepended) => rest.isOptionEqualToValue ? rest.isOptionEqualToValue(option, prepended) : option === prepended ) ) ] : options; const handleOnInputChange = (event, value, reason) => { if (reason === "clear") { setInputValue(event.target.value); } else if (reason === "blur") { setInputValue(value); } if (onInputChange) onInputChange(event, value, reason); }; const handleAddingOptions = (event) => __async(null, null, function* () { const listboxNode = event.currentTarget; const difference = listboxNode.scrollHeight - (listboxNode.scrollTop + listboxNode.clientHeight); if (difference <= 5 && !isLoading && !isFetching && hasNextPage) { fetchNextPage(); } }); useEffect2(() => { var _a2; if (hasNextPage) { (_a2 = listboxRef.current) == null ? void 0 : _a2.dispatchEvent(new UIEvent("scroll")); } }, [data == null ? void 0 : data.pages.length, hasNextPage]); return /* @__PURE__ */ jsx2( Autocomplete, __spreadProps(__spreadValues({}, rest), { onInputChange: handleOnInputChange, FieldProps: __spreadProps(__spreadValues({}, FieldProps), { InputProps: __spreadProps(__spreadValues({}, FieldProps == null ? void 0 : FieldProps.InputProps), { onChange: handleInputPropsOnChange }) }), loading: isFetching, options: finalOptions, ListboxProps: __spreadProps(__spreadValues({}, ListboxProps), { ref: setListboxRef, onScroll: handleAddingOptions, onPointerEnter: handleAddingOptions }) }) ); }; // src/lib/CodesAutocomplete.tsx import { avCodesApi } from "@availity/api-axios"; import { jsx as jsx3 } from "react/jsx-runtime"; var fetchCodes = (config) => __async(null, null, function* () { const resp = yield avCodesApi.query(config); return { options: resp.data.codes, hasMore: config.params.offset + config.params.limit < resp.data.totalCount, offset: config.params.offset }; }); var handleGetCodesOptionLabel = (option) => [option.code, option.value].filter(Boolean).join(" - "); var CodesAutocomplete = (_a) => { var _b = _a, { apiConfig = {}, queryOptions, queryKey = "codes-autocomplete", list, watchParams } = _b, rest = __objRest(_b, [ "apiConfig", "queryOptions", "queryKey", "list", "watchParams" ]); const handleLoadOptions = (offset, limit, inputValue) => __async(null, null, function* () { const resp = yield fetchCodes(__spreadProps(__spreadValues({}, apiConfig), { params: __spreadProps(__spreadValues({}, apiConfig.params), { list, offset, limit, q: inputValue }) })); return __spreadProps(__spreadValues({}, resp), { options: resp.options }); }); return /* @__PURE__ */ jsx3( AsyncAutocomplete, __spreadProps(__spreadValues({ getOptionLabel: handleGetCodesOptionLabel, queryKey, queryOptions: __spreadValues({ enabled: !!list }, queryOptions), watchParams: __spreadValues({ list }, watchParams) }, rest), { loadOptions: handleLoadOptions }) ); }; // src/lib/OrganizationAutocomplete.tsx import { avOrganizationsApi } from "@availity/api-axios"; import qs from "qs"; import { jsx as jsx4 } from "react/jsx-runtime"; var fetchOrgs = (config) => __async(null, null, function* () { const configWithParamsSerializer = __spreadProps(__spreadValues({}, config), { paramsSerializer: { serialize: (params) => qs.stringify(params, { arrayFormat: "repeat" }) } }); const resp = yield avOrganizationsApi.getOrganizations(configWithParamsSerializer); return { options: resp.data.organizations, hasMore: config.params.offset + config.params.limit < resp.data.totalCount, offset: config.params.offset }; }); var handleGetOrgOptionLabel = (org) => org.name; var OrganizationAutocomplete = (_a) => { var _b = _a, { apiConfig = {}, queryKey = "org-autocomplete" } = _b, rest = __objRest(_b, [ "apiConfig", "queryKey" ]); const handleLoadOptions = (offset, limit) => __async(null, null, function* () { const resp = yield fetchOrgs(__spreadProps(__spreadValues({}, apiConfig), { params: __spreadProps(__spreadValues({ dropdown: true }, apiConfig.params), { offset, limit }) })); return __spreadProps(__spreadValues({}, resp), { options: resp.options }); }); return /* @__PURE__ */ jsx4( AsyncAutocomplete, __spreadProps(__spreadValues({ getOptionLabel: handleGetOrgOptionLabel, queryKey }, rest), { loadOptions: handleLoadOptions }) ); }; // src/lib/ProviderAutocomplete.tsx import { avProvidersApi } from "@availity/api-axios"; import { jsx as jsx5 } from "react/jsx-runtime"; var fetchProviders = (customerId, config) => __async(null, null, function* () { const resp = yield avProvidersApi.getProviders(customerId, config); return { options: resp.data.providers, hasMore: config.params.offset + config.params.limit < resp.data.totalCount, offset: config.params.offset }; }); var handleGetProviderOptionLabel = (option) => option.uiDisplayName; var ProviderAutocomplete = (_a) => { var _b = _a, { apiConfig = {}, customerId, queryKey = "prov-autocomplete" } = _b, rest = __objRest(_b, [ "apiConfig", "customerId", "queryKey" ]); const handleLoadOptions = (offset, limit, inputValue) => __async(null, null, function* () { const resp = yield fetchProviders(customerId, __spreadProps(__spreadValues({}, apiConfig), { params: __spreadProps(__spreadValues({}, apiConfig.params), { offset, limit, q: inputValue }) })); return __spreadProps(__spreadValues({}, resp), { options: resp.options }); }); return /* @__PURE__ */ jsx5( AsyncAutocomplete, __spreadProps(__spreadValues({ getOptionLabel: handleGetProviderOptionLabel, queryOptions: { enabled: !!customerId }, queryKey, watchParams: { customerId } }, rest), { loadOptions: handleLoadOptions }) ); }; export { AsyncAutocomplete, Autocomplete, CodesAutocomplete, OrganizationAutocomplete, ProviderAutocomplete, createFilterOptions, fetchCodes, fetchOrgs, fetchProviders, handleGetCodesOptionLabel, handleGetOrgOptionLabel, handleGetProviderOptionLabel };