@zydon/common 2.8.36 → 2.8.37
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.
|
@@ -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"]}
|