{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "useDynamicList", "title": "useDynamicList", "description": "useDynamicList hook", "registryDependencies": [ "https://shadcn-ahooks.vercel.app/r/utils.json" ], "files": [ { "path": "packages/hooks/src/useDynamicList/index.ts", "content": "import { useCallback, useRef, useState } from 'react';\nimport isDev from '../utils/isDev';\n\nconst useDynamicList = (initialList: T[] = []) => {\n const counterRef = useRef(-1);\n\n const keyList = useRef([]);\n\n const setKey = useCallback((index: number) => {\n counterRef.current += 1;\n keyList.current.splice(index, 0, counterRef.current);\n }, []);\n\n const [list, setList] = useState(() => {\n initialList.forEach((_, index) => {\n setKey(index);\n });\n return initialList;\n });\n\n const resetList = useCallback((newList: T[]) => {\n keyList.current = [];\n setList(() => {\n newList.forEach((_, index) => {\n setKey(index);\n });\n return newList;\n });\n }, []);\n\n const insert = useCallback((index: number, item: T) => {\n setList((l) => {\n const temp = [...l];\n temp.splice(index, 0, item);\n setKey(index);\n return temp;\n });\n }, []);\n\n const getKey = useCallback((index: number) => keyList.current[index], []);\n\n const getIndex = useCallback(\n (key: number) => keyList.current.findIndex((ele) => ele === key),\n [],\n );\n\n const merge = useCallback((index: number, items: T[]) => {\n setList((l) => {\n const temp = [...l];\n items.forEach((_, i) => {\n setKey(index + i);\n });\n temp.splice(index, 0, ...items);\n return temp;\n });\n }, []);\n\n const replace = useCallback((index: number, item: T) => {\n setList((l) => {\n const temp = [...l];\n temp[index] = item;\n return temp;\n });\n }, []);\n\n const remove = useCallback((index: number) => {\n setList((l) => {\n const temp = [...l];\n temp.splice(index, 1);\n\n // remove keys if necessary\n try {\n keyList.current.splice(index, 1);\n } catch (e) {\n console.error(e);\n }\n return temp;\n });\n }, []);\n\n const batchRemove = useCallback((indexes: number[]) => {\n if (!Array.isArray(indexes)) {\n if (isDev) {\n console.error(\n `\\`indexes\\` parameter of \\`batchRemove\\` function expected to be an array, but got \"${typeof indexes}\".`,\n );\n }\n return;\n }\n if (!indexes.length) {\n return;\n }\n\n setList((prevList) => {\n const newKeyList: number[] = [];\n const newList = prevList.filter((item, index) => {\n const shouldKeep = !indexes.includes(index);\n\n if (shouldKeep) {\n newKeyList.push(getKey(index));\n }\n\n return shouldKeep;\n });\n\n keyList.current = newKeyList;\n\n return newList;\n });\n }, []);\n\n const move = useCallback((oldIndex: number, newIndex: number) => {\n if (oldIndex === newIndex) {\n return;\n }\n setList((l) => {\n const newList = [...l];\n const temp = newList.filter((_, index: number) => index !== oldIndex);\n temp.splice(newIndex, 0, newList[oldIndex]);\n\n // move keys if necessary\n try {\n const keyTemp = keyList.current.filter((_, index: number) => index !== oldIndex);\n keyTemp.splice(newIndex, 0, keyList.current[oldIndex]);\n keyList.current = keyTemp;\n } catch (e) {\n console.error(e);\n }\n\n return temp;\n });\n }, []);\n\n const push = useCallback((item: T) => {\n setList((l) => {\n setKey(l.length);\n return l.concat([item]);\n });\n }, []);\n\n const pop = useCallback(() => {\n // remove keys if necessary\n try {\n keyList.current = keyList.current.slice(0, keyList.current.length - 1);\n } catch (e) {\n console.error(e);\n }\n\n setList((l) => l.slice(0, l.length - 1));\n }, []);\n\n const unshift = useCallback((item: T) => {\n setList((l) => {\n setKey(0);\n return [item].concat(l);\n });\n }, []);\n\n const shift = useCallback(() => {\n // remove keys if necessary\n try {\n keyList.current = keyList.current.slice(1, keyList.current.length);\n } catch (e) {\n console.error(e);\n }\n setList((l) => l.slice(1, l.length));\n }, []);\n\n const sortList = useCallback(\n (result: T[]) =>\n result\n .map((item, index) => ({ key: index, item })) // add index into obj\n .sort((a, b) => getIndex(a.key) - getIndex(b.key)) // sort based on the index of table\n .filter((item) => !!item.item) // remove undefined(s)\n .map((item) => item.item), // retrive the data\n [],\n );\n\n return {\n list,\n insert,\n merge,\n replace,\n remove,\n batchRemove,\n getKey,\n getIndex,\n move,\n push,\n pop,\n unshift,\n shift,\n sortList,\n resetList,\n };\n};\n\nexport default useDynamicList;\n", "type": "registry:file", "target": "src/hooks/ahooks/useDynamicList/index.ts" } ], "type": "registry:hook" }