@zydon/common 2.8.36 → 2.8.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/form/Address/index.d.ts +1 -1
- package/dist/components/form/Address/index.js +4 -4
- package/dist/components/form/Address/index.js.map +1 -1
- package/dist/hooks/useDynamicAutocomplete.d.ts +3 -0
- package/dist/hooks/useDynamicAutocomplete.js +2 -2
- package/dist/hooks/useDynamicAutocomplete.js.map +1 -1
- package/dist/types/addressProps.d.ts +1 -0
- package/package.json +1 -1
|
@@ -4,6 +4,6 @@ import '@mui/material/Stack';
|
|
|
4
4
|
import '../../../types/baseField.js';
|
|
5
5
|
import 'react-hook-form';
|
|
6
6
|
|
|
7
|
-
declare const Address: ({ name, containerProps, required, rules, tabIndex, }: AddressProps) => react_jsx_runtime.JSX.Element;
|
|
7
|
+
declare const Address: ({ name, containerProps, required, rules, tabIndex, onZipCodeChange, }: AddressProps) => react_jsx_runtime.JSX.Element;
|
|
8
8
|
|
|
9
9
|
export { Address as default };
|
|
@@ -5,12 +5,12 @@ import { a as a$3 } from '../../../chunk-UB3AKGVA.js';
|
|
|
5
5
|
import '../../../chunk-HELCCAF2.js';
|
|
6
6
|
import '../../../chunk-ET6H3IRG.js';
|
|
7
7
|
import '../../../chunk-ICEDOBLM.js';
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import C from '@mui/material/CircularProgress';
|
|
9
|
+
import E from '@mui/material/InputAdornment';
|
|
10
10
|
import a from '@mui/material/Stack';
|
|
11
11
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var D=({name:t,containerProps:l,required:i,rules:c,tabIndex:e,onZipCodeChange:x})=>{let u=`${t}.zipCode`,f=`${t}.publicPlace`,w=`${t}.number`,h=`${t}.district`,P=`${t}.complement`,b=`${t}.state`,g=`${t}.city`,r=m=>{m.key==="Enter"&&m.preventDefault();};return jsxs(a,{gap:1.5,...l,children:[jsxs(a,{direction:{xs:"column",md:"row"},gap:1.5,flexWrap:"wrap",children:[jsx(a$1,{name:u,label:"CEP",mask:[{mask:"00000-000"}],InputProps:{endAdornment:jsx(E,{position:"end",children:jsx(C,{size:24})})},rules:c,onKeyDown:r,required:i,sx:{width:"auto",flex:1,minWidth:160},tabIndex:e,onChange:x}),jsxs(a,{direction:{xs:"column",sm:"row"},gap:1.5,flex:{xs:1,md:"1 1 50%"},children:[jsx(a$2,{name:f,label:"Logradouro",onKeyDown:r,inputProps:{maxLength:70},sx:{width:"auto",minWidth:250,flex:1},tabIndex:e}),jsx(a$2,{name:w,label:"N\xFAmero",onKeyDown:r,inputProps:{maxLength:6},sx:{width:"auto",minWidth:100},tabIndex:e})]})]}),jsxs(a,{direction:{xs:"column",md:"row"},gap:1.5,flexWrap:"wrap",children:[jsx(a$2,{name:h,label:"Bairro",onKeyDown:r,inputProps:{maxLength:20},sx:{width:"auto",flex:{xs:1,md:"1 1 100px"}},tabIndex:e}),jsx(a$2,{name:P,label:"Complemento",onKeyDown:r,inputProps:{maxLength:30},sx:{minWidth:200,width:"auto",flex:{xs:1,md:"1 1 500px"}},tabIndex:e})]}),jsxs(a,{gap:1.5,flexWrap:"wrap",direction:{xs:"column",sm:"row"},children:[jsx(a$3,{name:b,label:"Estado",options:[],disabled:!0,required:i,sx:{flex:1},tabIndex:e}),jsx(a$2,{name:g,label:"Cidade",disabled:!0,required:i,sx:{flex:1},tabIndex:e})]})]})},K=D;
|
|
14
14
|
|
|
15
|
-
export {
|
|
15
|
+
export { K as default };
|
|
16
16
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/form/Address/index.tsx"],"names":["CircularProgress","InputAdornment","Stack","jsx","jsxs","Address","name","containerProps","required","rules","tabIndex","ZIP_CODE_FIELD","PUBLIC_PLACE","NUMBER","DISTRICT","COMPLEMENT","STATE","CITY","handleKeyDown","e","MaskedInput_default","Field_default","Autocomplete_default","Address_default"],"mappings":"yRACA,OAAOA,MAAsB,iCAC7B,OAAOC,MAAoB,+BAC3B,OAAOC,MAAW,
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/form/Address/index.tsx"],"names":["CircularProgress","InputAdornment","Stack","jsx","jsxs","Address","name","containerProps","required","rules","tabIndex","onZipCodeChange","ZIP_CODE_FIELD","PUBLIC_PLACE","NUMBER","DISTRICT","COMPLEMENT","STATE","CITY","handleKeyDown","e","MaskedInput_default","Field_default","Autocomplete_default","Address_default"],"mappings":"yRACA,OAAOA,MAAsB,iCAC7B,OAAOC,MAAoB,+BAC3B,OAAOC,MAAW,sBAiDF,cAAAC,EAgBR,QAAAC,MAhBQ,oBAzChB,IAAMC,EAAU,CAAC,CACf,KAAAC,EACA,eAAAC,EACA,SAAAC,EACA,MAAAC,EACA,SAAAC,EACA,gBAAAC,CACF,IAAoB,CAClB,IAAMC,EAAiB,GAAGN,YACpBO,EAAe,GAAGP,gBAClBQ,EAAS,GAAGR,WACZS,EAAW,GAAGT,aACdU,EAAa,GAAGV,eAChBW,EAAQ,GAAGX,UACXY,EAAO,GAAGZ,SAEVa,EAAiBC,GAA2C,CAC5DA,EAAE,MAAQ,SAASA,EAAE,eAAe,CAC1C,EAEA,OACEhB,EAACF,EAAA,CAAM,IAAK,IAAM,GAAGK,EACnB,UAAAH,EAACF,EAAA,CACC,UAAW,CACT,GAAI,SACJ,GAAI,KACN,EACA,IAAK,IACL,SAAS,OAET,UAAAC,EAACkB,EAAA,CACC,KAAMT,EACN,MAAM,MACN,KAAM,CACJ,CACE,KAAM,WACR,CACF,EACA,WAAY,CACV,aACET,EAACF,EAAA,CAAe,SAAS,MACvB,SAAAE,EAACH,EAAA,CAAiB,KAAM,GAAI,EAC9B,CAEJ,EACA,MAAOS,EACP,UAAWU,EACX,SAAUX,EACV,GAAI,CACF,MAAO,OACP,KAAM,EACN,SAAU,GACZ,EACA,SAAUE,EACV,SAAUC,EACZ,EAEAP,EAACF,EAAA,CACC,UAAW,CACT,GAAI,SACJ,GAAI,KACN,EACA,IAAK,IACL,KAAM,CACJ,GAAI,EACJ,GAAI,SACN,EAEA,UAAAC,EAACmB,EAAA,CACC,KAAMT,EACN,MAAM,aACN,UAAWM,EACX,WAAY,CAAE,UAAW,EAAG,EAC5B,GAAI,CACF,MAAO,OACP,SAAU,IACV,KAAM,CACR,EACA,SAAUT,EACZ,EAEAP,EAACmB,EAAA,CACC,KAAMR,EACN,MAAM,YACN,UAAWK,EACX,WAAY,CAAE,UAAW,CAAE,EAC3B,GAAI,CACF,MAAO,OACP,SAAU,GACZ,EACA,SAAUT,EACZ,GACF,GACF,EAEAN,EAACF,EAAA,CACC,UAAW,CACT,GAAI,SACJ,GAAI,KACN,EACA,IAAK,IACL,SAAS,OAET,UAAAC,EAACmB,EAAA,CACC,KAAMP,EACN,MAAM,SACN,UAAWI,EACX,WAAY,CAAE,UAAW,EAAG,EAC5B,GAAI,CACF,MAAO,OACP,KAAM,CACJ,GAAI,EACJ,GAAI,WACN,CACF,EACA,SAAUT,EACZ,EAEAP,EAACmB,EAAA,CACC,KAAMN,EACN,MAAM,cACN,UAAWG,EACX,WAAY,CAAE,UAAW,EAAG,EAC5B,GAAI,CACF,SAAU,IACV,MAAO,OACP,KAAM,CACJ,GAAI,EACJ,GAAI,WACN,CACF,EACA,SAAUT,EACZ,GACF,EAEAN,EAACF,EAAA,CACC,IAAK,IACL,SAAS,OACT,UAAW,CACT,GAAI,SACJ,GAAI,KACN,EAEA,UAAAC,EAACoB,EAAA,CACC,KAAMN,EACN,MAAM,SACN,QAAS,CAAC,EACV,SAAQ,GACR,SAAUT,EACV,GAAI,CAAE,KAAM,CAAE,EACd,SAAUE,EACZ,EAEAP,EAACmB,EAAA,CACC,KAAMJ,EACN,MAAM,SACN,SAAQ,GACR,SAAUV,EACV,GAAI,CAAE,KAAM,CAAE,EACd,SAAUE,EACZ,GACF,GACF,CAEJ,EAEOc,EAAQnB","sourcesContent":["import React from 'react';\nimport CircularProgress from '@mui/material/CircularProgress';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport Stack from '@mui/material/Stack';\n\nimport { AddressProps } from 'types/addressProps';\n\nimport Autocomplete from '../Autocomplete';\nimport Field from '../Field';\nimport MaskedInput from '../MaskedInput';\n\nconst Address = ({\n name,\n containerProps,\n required,\n rules,\n tabIndex,\n onZipCodeChange,\n}: AddressProps) => {\n const ZIP_CODE_FIELD = `${name}.zipCode`;\n const PUBLIC_PLACE = `${name}.publicPlace`;\n const NUMBER = `${name}.number`;\n const DISTRICT = `${name}.district`;\n const COMPLEMENT = `${name}.complement`;\n const STATE = `${name}.state`;\n const CITY = `${name}.city`;\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Enter') e.preventDefault();\n };\n\n return (\n <Stack gap={1.5} {...containerProps}>\n <Stack\n direction={{\n xs: 'column',\n md: 'row',\n }}\n gap={1.5}\n flexWrap=\"wrap\"\n >\n <MaskedInput\n name={ZIP_CODE_FIELD}\n label=\"CEP\"\n mask={[\n {\n mask: '00000-000',\n },\n ]}\n InputProps={{\n endAdornment: (\n <InputAdornment position=\"end\">\n <CircularProgress size={24} />\n </InputAdornment>\n ),\n }}\n rules={rules}\n onKeyDown={handleKeyDown}\n required={required}\n sx={{\n width: 'auto',\n flex: 1,\n minWidth: 160,\n }}\n tabIndex={tabIndex}\n onChange={onZipCodeChange}\n />\n\n <Stack\n direction={{\n xs: 'column',\n sm: 'row',\n }}\n gap={1.5}\n flex={{\n xs: 1,\n md: '1 1 50%',\n }}\n >\n <Field\n name={PUBLIC_PLACE}\n label=\"Logradouro\"\n onKeyDown={handleKeyDown}\n inputProps={{ maxLength: 70 }}\n sx={{\n width: 'auto',\n minWidth: 250,\n flex: 1,\n }}\n tabIndex={tabIndex}\n />\n\n <Field\n name={NUMBER}\n label=\"Número\"\n onKeyDown={handleKeyDown}\n inputProps={{ maxLength: 6 }}\n sx={{\n width: 'auto',\n minWidth: 100,\n }}\n tabIndex={tabIndex}\n />\n </Stack>\n </Stack>\n\n <Stack\n direction={{\n xs: 'column',\n md: 'row',\n }}\n gap={1.5}\n flexWrap=\"wrap\"\n >\n <Field\n name={DISTRICT}\n label=\"Bairro\"\n onKeyDown={handleKeyDown}\n inputProps={{ maxLength: 20 }}\n sx={{\n width: 'auto',\n flex: {\n xs: 1,\n md: '1 1 100px',\n },\n }}\n tabIndex={tabIndex}\n />\n\n <Field\n name={COMPLEMENT}\n label=\"Complemento\"\n onKeyDown={handleKeyDown}\n inputProps={{ maxLength: 30 }}\n sx={{\n minWidth: 200,\n width: 'auto',\n flex: {\n xs: 1,\n md: '1 1 500px',\n },\n }}\n tabIndex={tabIndex}\n />\n </Stack>\n\n <Stack\n gap={1.5}\n flexWrap=\"wrap\"\n direction={{\n xs: 'column',\n sm: 'row',\n }}\n >\n <Autocomplete\n name={STATE}\n label=\"Estado\"\n options={[]}\n disabled\n required={required}\n sx={{ flex: 1 }}\n tabIndex={tabIndex}\n />\n\n <Field\n name={CITY}\n label=\"Cidade\"\n disabled\n required={required}\n sx={{ flex: 1 }}\n tabIndex={tabIndex}\n />\n </Stack>\n </Stack>\n );\n};\n\nexport default Address;\n"]}
|
|
@@ -19,6 +19,9 @@ interface UseDynamicAutocompleteConfig<TItem> {
|
|
|
19
19
|
onSelect?: (value: string, item?: TItem) => void;
|
|
20
20
|
}
|
|
21
21
|
declare const useDynamicAutocomplete: <TItem>({ fieldPath, useQuery, queryParams, mapOption, onSelect, }: UseDynamicAutocompleteConfig<TItem>) => {
|
|
22
|
+
data: {
|
|
23
|
+
items: TItem[];
|
|
24
|
+
} | undefined;
|
|
22
25
|
options: Option[];
|
|
23
26
|
loading: boolean;
|
|
24
27
|
onSearch: (term?: string) => void;
|
|
@@ -2,7 +2,7 @@ import { a } from '../chunk-GNNZB7DN.js';
|
|
|
2
2
|
import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
import { useFormContext, useWatch } from 'react-hook-form';
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var X=n=>n,Y={value:"id",label:"name"},Z=n=>{if(typeof n=="function")return n;let u=n??Y;return s=>({label:String(s[u.label]??""),value:String(s[u.value]??"")})},_=({fieldPath:n,useQuery:u,queryParams:s={},mapOption:i,onSelect:p})=>{let g=useMemo(()=>Z(i),[i]),U=typeof i=="object"&&i!==null?i.label:"name",{control:w,setValue:x}=useFormContext(),[h,F]=useState(!1),[I,S]=useState(0),[m,b]=useState([]),[A,y]=useState(!0),T=useRef(!1),D=s.perPage||25,j=`${n}.id`,C=`${n}.${U}`,f=useWatch({control:w,name:j}),O=useWatch({control:w,name:C}),[P,V]=useState(),v=a(P,400),q=P!==v,H=useCallback(e=>{V(e||void 0);},[]),E=useCallback(()=>{V(void 0);},[]),{data:M,isLoading:N,isFetching:r}=u({...s,search:v,page:I},{skip:!h}),d=useMemo(()=>M?.items||[],[M]);useEffect(()=>{S(0),b([]),y(!0);},[v]),useEffect(()=>{r||!h||(b(e=>{if(I===0)return d;let t=new Set(e.map(l=>String(l.id??""))),a=d.filter(l=>!t.has(String(l.id??"")));return [...e,...a]}),y(d.length>=D),T.current=!1);},[d,r,I,D,h]);let k=useMemo(()=>{let e=m.map(g);return f&&O&&!e.some(t=>String(t.value)===String(f))&&e.unshift({label:O,value:f}),e.filter(t=>t.value!==null&&t.value!==void 0)},[m,f,O,g]),Q=useCallback(e=>{let t=k.find(a=>String(a.value)===String(e))?.label;if(x(C,t),p){let a=m.find(l=>String(g(l).value)===String(e));p(e,a);}},[k,x,C,p,m,g]),W=useCallback(()=>{F(!0);},[]),z=useCallback(()=>{F(!1),S(0),b([]),y(!0),E();},[E]),B=useCallback(()=>{!r&&!T.current&&A&&(T.current=!0,S(e=>e+1));},[r,A]);return {data:M,options:k,loading:N||r,onSearch:H,onSelectOption:Q,onOpen:W,onClose:z,onScrollEnd:B,filterOptions:X,noOptionsText:q?"Carregando...":void 0}},oe=_;
|
|
6
6
|
|
|
7
|
-
export {
|
|
7
|
+
export { oe as default };
|
|
8
8
|
//# sourceMappingURL=useDynamicAutocomplete.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/useDynamicAutocomplete.ts"],"names":["useCallback","useEffect","useMemo","useRef","useState","useFormContext","useWatch","passthrough","o","defaultMapKeys","resolveMapper","mapOption","keys","item","useDynamicAutocomplete","fieldPath","useQuery","queryParams","onSelect","mapper","labelKey","control","setValue","open","setOpen","page","setPage","allItems","setAllItems","hasMore","setHasMore","loadingMoreRef","perPage","idField","nameField","entityId","entityName","inputValue","setInputValue","search","useDebounceValue_default","searching","onSearch","term","finishSearch","
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useDynamicAutocomplete.ts"],"names":["useCallback","useEffect","useMemo","useRef","useState","useFormContext","useWatch","passthrough","o","defaultMapKeys","resolveMapper","mapOption","keys","item","useDynamicAutocomplete","fieldPath","useQuery","queryParams","onSelect","mapper","labelKey","control","setValue","open","setOpen","page","setPage","allItems","setAllItems","hasMore","setHasMore","loadingMoreRef","perPage","idField","nameField","entityId","entityName","inputValue","setInputValue","search","useDebounceValue_default","searching","onSearch","term","finishSearch","data","isLoading","isFetching","currentPageItems","prev","existingIds","i","unique","options","list","opt","handleSelectOption","value","label","option","handleOpen","handleClose","handleScrollEnd","p","useDynamicAutocomplete_default"],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { useFormContext, useWatch } from 'react-hook-form';\n\nimport { Option } from 'types/option';\n\nimport useDebounceValue from './useDebounceValue';\n\nconst passthrough = (o: Option[]) => o;\n\ntype MapOptionConfig = { value: string; label: string };\n\nconst defaultMapKeys: MapOptionConfig = { value: 'id', label: 'name' };\n\nconst resolveMapper = <TItem>(\n mapOption?: ((item: TItem) => Option) | MapOptionConfig,\n): ((item: TItem) => Option) => {\n if (typeof mapOption === 'function') return mapOption;\n const keys = mapOption ?? defaultMapKeys;\n return (item: TItem) => ({\n label: String((item as Record<string, unknown>)[keys.label] ?? ''),\n value: String((item as Record<string, unknown>)[keys.value] ?? ''),\n });\n};\n\nexport interface UseDynamicAutocompleteConfig<TItem> {\n /** Form field path — watches `${fieldPath}.id` and `${fieldPath}.{mapOption.label}` */\n fieldPath: string;\n /** RTK Query hook (e.g. useGetCategoriesQuery) */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n useQuery: (...args: any[]) => {\n data?: { items: TItem[] };\n isLoading: boolean;\n isFetching: boolean;\n };\n /** Static query params merged with { search } on each call */\n queryParams?: Record<string, unknown>;\n /**\n * Map an API entity to an Option { label, value }.\n * Also determines the form field name: `${fieldPath}.${mapOption.label}`.\n * - Config: `{ value: 'code', label: 'description' }`\n * - Function: falls back to `${fieldPath}.name`\n * - Omit: defaults to `{ value: 'id', label: 'name' }`\n */\n mapOption?: ((item: TItem) => Option) | MapOptionConfig;\n /** Called after an option is selected, with the raw item if found. */\n onSelect?: (value: string, item?: TItem) => void;\n}\n\nconst useDynamicAutocomplete = <TItem>({\n fieldPath,\n useQuery,\n queryParams = {},\n mapOption,\n onSelect,\n}: UseDynamicAutocompleteConfig<TItem>) => {\n const mapper = useMemo(() => resolveMapper(mapOption), [mapOption]);\n const labelKey =\n typeof mapOption === 'object' && mapOption !== null\n ? mapOption.label\n : 'name';\n const { control, setValue } = useFormContext();\n const [open, setOpen] = useState(false);\n const [page, setPage] = useState(0);\n const [allItems, setAllItems] = useState<TItem[]>([]);\n const [hasMore, setHasMore] = useState(true);\n const loadingMoreRef = useRef(false);\n\n const perPage = (queryParams.perPage as number) || 25;\n\n const idField = `${fieldPath}.id`;\n const nameField = `${fieldPath}.${labelKey}`;\n\n const entityId = useWatch({ control, name: idField });\n const entityName = useWatch({ control, name: nameField });\n\n // Simple debounced search\n const [inputValue, setInputValue] = useState<string>();\n const search = useDebounceValue(inputValue, 400);\n const searching = inputValue !== search;\n\n const onSearch = useCallback((term?: string) => {\n setInputValue(term || undefined);\n }, []);\n\n const finishSearch = useCallback(() => {\n setInputValue(undefined);\n }, []);\n\n const {\n data,\n isLoading,\n isFetching,\n } = useQuery({ ...queryParams, search, page }, { skip: !open });\n\n const currentPageItems = useMemo(() => data?.items || [], [data]);\n\n useEffect(() => {\n setPage(0);\n setAllItems([]);\n setHasMore(true);\n }, [search]);\n\n useEffect(() => {\n if (isFetching || !open) return;\n\n setAllItems(prev => {\n if (page === 0) return currentPageItems;\n const existingIds = new Set(\n prev.map(i => String((i as Record<string, unknown>).id ?? '')),\n );\n const unique = currentPageItems.filter(\n i => !existingIds.has(String((i as Record<string, unknown>).id ?? '')),\n );\n return [...prev, ...unique];\n });\n\n setHasMore(currentPageItems.length >= perPage);\n loadingMoreRef.current = false;\n }, [currentPageItems, isFetching, page, perPage, open]);\n\n const options = useMemo(() => {\n const list = allItems.map(mapper);\n\n if (\n entityId &&\n entityName &&\n !list.some(item => String(item.value) === String(entityId))\n ) {\n list.unshift({ label: entityName, value: entityId });\n }\n\n return list.filter(\n opt => opt.value !== null && opt.value !== undefined,\n );\n }, [allItems, entityId, entityName, mapper]);\n\n const handleSelectOption = useCallback(\n (value: string) => {\n const label = options.find(\n option => String(option.value) === String(value),\n )?.label;\n setValue(nameField, label);\n\n if (onSelect) {\n const item = allItems.find(\n i => String(mapper(i).value) === String(value),\n );\n onSelect(value, item);\n }\n },\n [options, setValue, nameField, onSelect, allItems, mapper],\n );\n\n const handleOpen = useCallback(() => {\n setOpen(true);\n }, []);\n\n const handleClose = useCallback(() => {\n setOpen(false);\n setPage(0);\n setAllItems([]);\n setHasMore(true);\n finishSearch();\n }, [finishSearch]);\n\n const handleScrollEnd = useCallback(() => {\n if (!isFetching && !loadingMoreRef.current && hasMore) {\n loadingMoreRef.current = true;\n setPage(p => p + 1);\n }\n }, [isFetching, hasMore]);\n\n return {\n data,\n options,\n loading: isLoading || isFetching,\n onSearch,\n onSelectOption: handleSelectOption,\n onOpen: handleOpen,\n onClose: handleClose,\n onScrollEnd: handleScrollEnd,\n filterOptions: passthrough,\n noOptionsText: searching ? 'Carregando...' : undefined,\n };\n};\n\nexport default useDynamicAutocomplete;\n"]}
|