use-key-value-list.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { useCallback, useEffect, useState } from 'react'
  2. import { useBoolean } from 'ahooks'
  3. import { uniqueId } from 'lodash'
  4. import type { KeyValue } from '../types'
  5. const UNIQUE_ID_PREFIX = 'key-value-'
  6. const strToKeyValueList = (value: string) => {
  7. return value.split('\n').map((item) => {
  8. const [key, ...others] = item.split(':')
  9. return {
  10. id: uniqueId(UNIQUE_ID_PREFIX),
  11. key: key.trim(),
  12. value: others.join(':').trim(),
  13. }
  14. })
  15. }
  16. const useKeyValueList = (value: string, onChange: (value: string) => void, noFilter?: boolean) => {
  17. const [list, doSetList] = useState<KeyValue[]>(value ? strToKeyValueList(value) : [])
  18. const setList = (l: KeyValue[]) => {
  19. doSetList(l.map((item) => {
  20. return {
  21. ...item,
  22. id: item.id || uniqueId(UNIQUE_ID_PREFIX),
  23. }
  24. }))
  25. }
  26. useEffect(() => {
  27. if (noFilter)
  28. return
  29. const newValue = list.filter(item => item.key && item.value).map(item => `${item.key}:${item.value}`).join('\n')
  30. if (newValue !== value)
  31. onChange(newValue)
  32. // eslint-disable-next-line react-hooks/exhaustive-deps
  33. }, [list, noFilter])
  34. const addItem = useCallback(() => {
  35. setList([...list, {
  36. id: uniqueId(UNIQUE_ID_PREFIX),
  37. key: '',
  38. value: '',
  39. }])
  40. }, [list])
  41. const [isKeyValueEdit, {
  42. toggle: toggleIsKeyValueEdit,
  43. }] = useBoolean(true)
  44. return {
  45. list: list.length === 0 ? [{ id: uniqueId(UNIQUE_ID_PREFIX), key: '', value: '' }] : list, // no item can not add new item
  46. setList,
  47. addItem,
  48. isKeyValueEdit,
  49. toggleIsKeyValueEdit,
  50. }
  51. }
  52. export default useKeyValueList