@yoka-ui/ui 1.0.4 → 1.0.5

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.
Files changed (232) hide show
  1. package/@Docs-yoka/exports.generated.md +71 -63
  2. package/README.md +6 -4
  3. package/dist/es/business/AiChat/index.js.map +1 -1
  4. package/dist/es/business/AiChat/intentRecognizer.js.map +1 -1
  5. package/dist/es/business/AiChat/navigationManager.js +6 -6
  6. package/dist/es/business/AiChat/navigationManager.js.map +2 -2
  7. package/dist/es/business/DrawerPageInfo/index.js +2 -2
  8. package/dist/es/business/DrawerPageInfo/index.js.map +2 -2
  9. package/dist/es/business/Editor/index.d.ts +1 -1
  10. package/dist/es/business/Editor/index.js.map +2 -2
  11. package/dist/es/business/Empty/index.js +1 -1
  12. package/dist/es/business/Empty/index.js.map +1 -1
  13. package/dist/es/business/ModCommonFilter/components/PopoverContent/Category.js +2 -2
  14. package/dist/es/business/ModCommonFilter/components/PopoverContent/Category.js.map +2 -2
  15. package/dist/es/business/ModCommonFilter/components/PopoverContent/Content.js +3 -3
  16. package/dist/es/business/ModCommonFilter/components/PopoverContent/Content.js.map +2 -2
  17. package/dist/es/business/ModCommonFilter/components/PopoverContent/Selected.js +2 -2
  18. package/dist/es/business/ModCommonFilter/components/PopoverContent/Selected.js.map +2 -2
  19. package/dist/es/business/ModCommonFilter/index.d.ts +1 -1
  20. package/dist/es/business/ModCommonFilter/index.js.map +2 -2
  21. package/dist/es/business/YkPorjectSelect/index.d.ts +1 -1
  22. package/dist/es/business/YkPorjectSelect/index.js +2 -2
  23. package/dist/es/business/YkPorjectSelect/index.js.map +2 -2
  24. package/dist/es/components/DebounceInput/index.js.map +2 -2
  25. package/dist/es/components/MultipleSelect/index.d.ts +14 -0
  26. package/dist/es/components/MultipleSelect/index.js +1 -1
  27. package/dist/es/components/MultipleSelect/index.js.map +2 -2
  28. package/dist/es/components/RefreshButton/index.js.map +2 -2
  29. package/dist/es/components/SearchWithHistory/index.js +1 -1
  30. package/dist/es/components/SearchWithHistory/index.js.map +2 -2
  31. package/dist/es/components/TextWithToolTip/index.d.ts +1 -1
  32. package/dist/es/components/TextWithToolTip/index.js.map +2 -2
  33. package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.d.ts +1 -24
  34. package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.js +2 -2
  35. package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.js.map +2 -2
  36. package/dist/es/components/TreeTransfer/index.d.ts +1 -24
  37. package/dist/es/components/TreeTransfer/index.js +8 -8
  38. package/dist/es/components/TreeTransfer/index.js.map +2 -2
  39. package/dist/es/components/TreeTransfer/utils/index.d.ts +1 -1
  40. package/dist/es/components/TreeTransfer/utils/index.js.map +2 -2
  41. package/dist/es/components/YkDateRangePicker/index.d.ts +1 -1
  42. package/dist/es/components/YkDateRangePicker/index.js +1 -1
  43. package/dist/es/components/YkDateRangePicker/index.js.map +2 -2
  44. package/dist/es/components/YkDateRangePicker/index.module.less +2 -1
  45. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.d.ts +1 -1
  46. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js +3 -2
  47. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js.map +2 -2
  48. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.d.ts +1 -1
  49. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js +60 -9
  50. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js.map +3 -3
  51. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.d.ts +1 -1
  52. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.js.map +2 -2
  53. package/dist/es/components/YkRangeDateWithVS/index.d.ts +4 -4
  54. package/dist/es/components/YkRangeDateWithVS/index.js +2 -3
  55. package/dist/es/components/YkRangeDateWithVS/index.js.map +2 -2
  56. package/dist/es/components/YkRangeDateWithVS/index.module.less +23 -4
  57. package/dist/es/components/YkRangeTimeWithRecent/index.d.ts +1 -18
  58. package/dist/es/components/YkRangeTimeWithRecent/index.js +27 -7
  59. package/dist/es/components/YkRangeTimeWithRecent/index.js.map +2 -2
  60. package/dist/es/creative/ArcCheckbox/index.d.ts +12 -0
  61. package/dist/es/creative/ArcCheckbox/index.js +49 -0
  62. package/dist/es/creative/ArcCheckbox/index.js.map +7 -0
  63. package/dist/es/creative/ArcCheckbox/index.module.less +102 -0
  64. package/dist/es/creative/ButtonRadioWithInfo/index.js.map +1 -1
  65. package/dist/es/creative/ButtonWithProgress/index.d.ts +1 -1
  66. package/dist/es/creative/ButtonWithProgress/index.js.map +2 -2
  67. package/dist/es/creative/GlassSegmentedRadio/index.d.ts +24 -0
  68. package/dist/es/creative/GlassSegmentedRadio/index.js +75 -0
  69. package/dist/es/creative/GlassSegmentedRadio/index.js.map +7 -0
  70. package/dist/es/creative/GlassSegmentedRadio/index.module.less +241 -0
  71. package/dist/es/index.d.ts +30 -26
  72. package/dist/es/index.js +86 -82
  73. package/dist/es/index.js.map +2 -2
  74. package/dist/es/index.less +3 -1
  75. package/dist/es/layout/FlexGrid/index.d.ts +1 -1
  76. package/dist/es/layout/FlexGrid/index.js.map +2 -2
  77. package/dist/es/layout/YkContainer/index.js.map +1 -1
  78. package/dist/es/layout/YkDrawer/index.d.ts +1 -1
  79. package/dist/es/layout/YkDrawer/index.js +2 -1
  80. package/dist/es/layout/YkDrawer/index.js.map +2 -2
  81. package/dist/es/ui/LabelSelect/demo.js +1 -1
  82. package/dist/es/ui/LabelSelect/demo.js.map +2 -2
  83. package/dist/es/ui/LabelSelect/index.d.ts +1 -1
  84. package/dist/es/ui/LabelSelect/index.js +1 -1
  85. package/dist/es/ui/LabelSelect/index.js.map +2 -2
  86. package/dist/es/ui/LogicOperator/index.d.ts +1 -1
  87. package/dist/es/ui/LogicOperator/index.js.map +2 -2
  88. package/dist/es/ui/YkButton/index.d.ts +1 -1
  89. package/dist/es/ui/YkButton/index.js.map +2 -2
  90. package/dist/es/ui/YkCard/index.d.ts +1 -1
  91. package/dist/es/ui/YkCard/index.js +1 -1
  92. package/dist/es/ui/YkCard/index.js.map +2 -2
  93. package/dist/es/ui/YkCheckbox/index.d.ts +1 -1
  94. package/dist/es/ui/YkCheckbox/index.js.map +2 -2
  95. package/dist/es/ui/YkDescriptions/index.d.ts +1 -1
  96. package/dist/es/ui/YkDescriptions/index.js.map +2 -2
  97. package/dist/es/ui/YkPagination/index.d.ts +1 -1
  98. package/dist/es/ui/YkPagination/index.js.map +2 -2
  99. package/dist/es/ui/YkRadio/index.d.ts +1 -1
  100. package/dist/es/ui/YkRadio/index.js.map +2 -2
  101. package/dist/es/ui/YkSegmented/index.d.ts +1 -1
  102. package/dist/es/ui/YkSegmented/index.js.map +2 -2
  103. package/dist/es/ui/YkSelect/index.d.ts +1 -1
  104. package/dist/es/ui/YkSelect/index.js.map +2 -2
  105. package/dist/es/ui/YkSpin/index.d.ts +1 -1
  106. package/dist/es/ui/YkSpin/index.js.map +2 -2
  107. package/dist/es/ui/YkStatistic/index.d.ts +1 -1
  108. package/dist/es/ui/YkStatistic/index.js.map +2 -2
  109. package/dist/es/ui/YkSwitch/index.d.ts +1 -1
  110. package/dist/es/ui/YkSwitch/index.js.map +2 -2
  111. package/dist/es/ui/YkTabs/index.d.ts +1 -1
  112. package/dist/es/ui/YkTabs/index.js.map +2 -2
  113. package/dist/es/ui/YkTooltip/index.d.ts +1 -1
  114. package/dist/es/ui/YkTooltip/index.js.map +2 -2
  115. package/dist/es/utils/styleUtils.js.map +2 -2
  116. package/dist/es/utils/ykStorybookDoc.js +1 -1
  117. package/dist/es/utils/ykStorybookDoc.js.map +1 -1
  118. package/dist/lib/business/AiChat/index.js.map +1 -1
  119. package/dist/lib/business/AiChat/intentRecognizer.js.map +1 -1
  120. package/dist/lib/business/AiChat/navigationManager.js +6 -6
  121. package/dist/lib/business/AiChat/navigationManager.js.map +2 -2
  122. package/dist/lib/business/DrawerPageInfo/index.js +1 -1
  123. package/dist/lib/business/DrawerPageInfo/index.js.map +2 -2
  124. package/dist/lib/business/Editor/index.d.ts +1 -1
  125. package/dist/lib/business/Editor/index.js.map +2 -2
  126. package/dist/lib/business/Empty/index.js +1 -1
  127. package/dist/lib/business/Empty/index.js.map +1 -1
  128. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Category.js +3 -3
  129. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Category.js.map +2 -2
  130. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Content.js +4 -4
  131. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Content.js.map +2 -2
  132. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Selected.js +3 -3
  133. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Selected.js.map +2 -2
  134. package/dist/lib/business/ModCommonFilter/index.d.ts +1 -1
  135. package/dist/lib/business/ModCommonFilter/index.js.map +2 -2
  136. package/dist/lib/business/YkPorjectSelect/index.d.ts +1 -1
  137. package/dist/lib/business/YkPorjectSelect/index.js +3 -3
  138. package/dist/lib/business/YkPorjectSelect/index.js.map +2 -2
  139. package/dist/lib/components/DebounceInput/index.js.map +2 -2
  140. package/dist/lib/components/MultipleSelect/index.d.ts +14 -0
  141. package/dist/lib/components/MultipleSelect/index.js +1 -1
  142. package/dist/lib/components/MultipleSelect/index.js.map +2 -2
  143. package/dist/lib/components/RefreshButton/index.js.map +2 -2
  144. package/dist/lib/components/SearchWithHistory/index.js +1 -1
  145. package/dist/lib/components/SearchWithHistory/index.js.map +2 -2
  146. package/dist/lib/components/TextWithToolTip/index.d.ts +1 -1
  147. package/dist/lib/components/TextWithToolTip/index.js.map +2 -2
  148. package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.d.ts +1 -24
  149. package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.js +2 -2
  150. package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.js.map +2 -2
  151. package/dist/lib/components/TreeTransfer/index.d.ts +1 -24
  152. package/dist/lib/components/TreeTransfer/index.js +3 -3
  153. package/dist/lib/components/TreeTransfer/index.js.map +2 -2
  154. package/dist/lib/components/TreeTransfer/utils/index.d.ts +1 -1
  155. package/dist/lib/components/TreeTransfer/utils/index.js.map +2 -2
  156. package/dist/lib/components/YkDateRangePicker/index.d.ts +1 -1
  157. package/dist/lib/components/YkDateRangePicker/index.js +1 -1
  158. package/dist/lib/components/YkDateRangePicker/index.js.map +2 -2
  159. package/dist/lib/components/YkDateRangePicker/index.module.less +2 -1
  160. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.d.ts +1 -1
  161. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js +3 -2
  162. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js.map +2 -2
  163. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.d.ts +1 -1
  164. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js +59 -8
  165. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js.map +3 -3
  166. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.d.ts +1 -1
  167. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.js.map +2 -2
  168. package/dist/lib/components/YkRangeDateWithVS/index.d.ts +4 -4
  169. package/dist/lib/components/YkRangeDateWithVS/index.js +4 -5
  170. package/dist/lib/components/YkRangeDateWithVS/index.js.map +3 -3
  171. package/dist/lib/components/YkRangeDateWithVS/index.module.less +23 -4
  172. package/dist/lib/components/YkRangeTimeWithRecent/index.d.ts +1 -18
  173. package/dist/lib/components/YkRangeTimeWithRecent/index.js +27 -7
  174. package/dist/lib/components/YkRangeTimeWithRecent/index.js.map +2 -2
  175. package/dist/lib/creative/ArcCheckbox/index.d.ts +12 -0
  176. package/dist/lib/creative/ArcCheckbox/index.js +50 -0
  177. package/dist/lib/creative/ArcCheckbox/index.js.map +7 -0
  178. package/dist/lib/creative/ArcCheckbox/index.module.less +102 -0
  179. package/dist/lib/creative/ButtonRadioWithInfo/index.js.map +1 -1
  180. package/dist/lib/creative/ButtonWithProgress/index.d.ts +1 -1
  181. package/dist/lib/creative/ButtonWithProgress/index.js.map +2 -2
  182. package/dist/lib/creative/GlassSegmentedRadio/index.d.ts +24 -0
  183. package/dist/lib/creative/GlassSegmentedRadio/index.js +78 -0
  184. package/dist/lib/creative/GlassSegmentedRadio/index.js.map +7 -0
  185. package/dist/lib/creative/GlassSegmentedRadio/index.module.less +241 -0
  186. package/dist/lib/index.d.ts +30 -26
  187. package/dist/lib/index.js +31 -25
  188. package/dist/lib/index.js.map +2 -2
  189. package/dist/lib/index.less +3 -1
  190. package/dist/lib/layout/FlexGrid/index.d.ts +1 -1
  191. package/dist/lib/layout/FlexGrid/index.js.map +2 -2
  192. package/dist/lib/layout/YkContainer/index.js.map +1 -1
  193. package/dist/lib/layout/YkDrawer/index.d.ts +1 -1
  194. package/dist/lib/layout/YkDrawer/index.js +2 -1
  195. package/dist/lib/layout/YkDrawer/index.js.map +2 -2
  196. package/dist/lib/ui/LabelSelect/demo.js +1 -1
  197. package/dist/lib/ui/LabelSelect/demo.js.map +2 -2
  198. package/dist/lib/ui/LabelSelect/index.d.ts +1 -1
  199. package/dist/lib/ui/LabelSelect/index.js +1 -1
  200. package/dist/lib/ui/LabelSelect/index.js.map +2 -2
  201. package/dist/lib/ui/LogicOperator/index.d.ts +1 -1
  202. package/dist/lib/ui/LogicOperator/index.js.map +2 -2
  203. package/dist/lib/ui/YkButton/index.d.ts +1 -1
  204. package/dist/lib/ui/YkButton/index.js.map +2 -2
  205. package/dist/lib/ui/YkCard/index.d.ts +1 -1
  206. package/dist/lib/ui/YkCard/index.js.map +2 -2
  207. package/dist/lib/ui/YkCheckbox/index.d.ts +1 -1
  208. package/dist/lib/ui/YkCheckbox/index.js.map +2 -2
  209. package/dist/lib/ui/YkDescriptions/index.d.ts +1 -1
  210. package/dist/lib/ui/YkDescriptions/index.js.map +2 -2
  211. package/dist/lib/ui/YkPagination/index.d.ts +1 -1
  212. package/dist/lib/ui/YkPagination/index.js.map +2 -2
  213. package/dist/lib/ui/YkRadio/index.d.ts +1 -1
  214. package/dist/lib/ui/YkRadio/index.js.map +2 -2
  215. package/dist/lib/ui/YkSegmented/index.d.ts +1 -1
  216. package/dist/lib/ui/YkSegmented/index.js.map +2 -2
  217. package/dist/lib/ui/YkSelect/index.d.ts +1 -1
  218. package/dist/lib/ui/YkSelect/index.js.map +2 -2
  219. package/dist/lib/ui/YkSpin/index.d.ts +1 -1
  220. package/dist/lib/ui/YkSpin/index.js.map +2 -2
  221. package/dist/lib/ui/YkStatistic/index.d.ts +1 -1
  222. package/dist/lib/ui/YkStatistic/index.js.map +2 -2
  223. package/dist/lib/ui/YkSwitch/index.d.ts +1 -1
  224. package/dist/lib/ui/YkSwitch/index.js.map +2 -2
  225. package/dist/lib/ui/YkTabs/index.d.ts +1 -1
  226. package/dist/lib/ui/YkTabs/index.js.map +2 -2
  227. package/dist/lib/ui/YkTooltip/index.d.ts +1 -1
  228. package/dist/lib/ui/YkTooltip/index.js.map +2 -2
  229. package/dist/lib/utils/styleUtils.js.map +2 -2
  230. package/dist/lib/utils/ykStorybookDoc.js +1 -1
  231. package/dist/lib/utils/ykStorybookDoc.js.map +1 -1
  232. package/package.json +137 -144
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/DebounceInput/index.tsx"],
4
- "sourcesContent": ["/**\n * 组件名称:DebouncedInput\n * 组件描述:一个用于搜索的输入框组件,支持防抖\n * 组件使用场景:在需要搜索的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - noDebounced: 是否不使用防抖\n * - currentValue: 当前值\n * - placeholder: 输入框提示文字\n * - onChange: 值改变时的回调\n * - delay: 防抖时间\n * - inputClass: 输入框样式类名\n * - allowClear: 是否允许清空\n * - style: 组件样式\n */\nimport { useDebounceFn } from 'ahooks';\nimport { Input } from 'antd';\nimport classNames from 'classnames';\nimport React, { useEffect, useRef, useState } from 'react';\nimport styles from './index.module.less';\ntype PropsType = {\n noDebounced?: boolean;\n currentValue: string | undefined;\n placeholder?: string;\n onChange: (value: string) => void;\n delay?: number;\n inputClass?: any;\n allowClear?: boolean;\n style?: React.CSSProperties;\n noPrefixIcon?: boolean;\n disabled?: boolean;\n icon?: React.ReactNode;\n};\nconst DebouncedInput: React.FC<PropsType> = ({\n noDebounced = false,\n currentValue = '',\n placeholder = '搜索',\n onChange = (value: string) => {},\n delay = 150,\n inputClass,\n allowClear = true,\n style = {},\n noPrefixIcon = false,\n disabled = false,\n icon,\n}) => {\n const [value, setValue] = useState(currentValue);\n const lock = useRef(false);\n const changeFlag = useRef(false);\n useEffect(() => {\n if (changeFlag.current) {\n changeFlag.current = false;\n return;\n }\n setValue(currentValue);\n }, [currentValue]);\n\n const { run } = useDebounceFn(\n () => {\n onChange(value);\n },\n { wait: delay },\n );\n function handleChange(e: any) {\n const type = e.type;\n if (type === 'compositionstart') {\n lock.current = true;\n return;\n }\n const value = e.target.value;\n setValue(value);\n if (e.type === 'compositionend') {\n lock.current = false;\n }\n if (!lock.current) {\n changeFlag.current = true;\n if (noDebounced) {\n onChange(value);\n } else {\n run();\n }\n }\n }\n return (\n <Input\n allowClear={allowClear}\n style={style}\n className={classNames(styles.search, inputClass)}\n placeholder={placeholder}\n prefix={\n !noPrefixIcon &&\n (icon || <i className='iconfont icon-sousuo' style={{ fontSize: 14, lineHeight: '28px', color: '#999' }} />)\n }\n value={value}\n onChange={handleChange}\n onCompositionStart={handleChange}\n onCompositionEnd={handleChange}\n disabled={disabled}\n />\n );\n};\n\nexport default DebouncedInput;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,oBAA8B;AAC9B,kBAAsB;AACtB,wBAAuB;AACvB,mBAAmD;AACnD,0BAAmB;AAcnB,IAAM,iBAAsC,CAAC;AAAA,EAC3C,cAAc;AAAA,EACd,eAAe;AAAA,EACf,cAAc;AAAA,EACd,WAAW,CAAC,UAAkB;AAAA,EAAC;AAAA,EAC/B,QAAQ;AAAA,EACR;AAAA,EACA,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,YAAY;AAC/C,QAAM,WAAO,qBAAO,KAAK;AACzB,QAAM,iBAAa,qBAAO,KAAK;AAC/B,8BAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,iBAAW,UAAU;AACrB;AAAA,IACF;AACA,aAAS,YAAY;AAAA,EACvB,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,EAAE,IAAI,QAAI;AAAA,IACd,MAAM;AACJ,eAAS,KAAK;AAAA,IAChB;AAAA,IACA,EAAE,MAAM,MAAM;AAAA,EAChB;AACA,WAAS,aAAa,GAAQ;AAC5B,UAAM,OAAO,EAAE;AACf,QAAI,SAAS,oBAAoB;AAC/B,WAAK,UAAU;AACf;AAAA,IACF;AACA,UAAMA,SAAQ,EAAE,OAAO;AACvB,aAASA,MAAK;AACd,QAAI,EAAE,SAAS,kBAAkB;AAC/B,WAAK,UAAU;AAAA,IACjB;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,iBAAW,UAAU;AACrB,UAAI,aAAa;AACf,iBAASA,MAAK;AAAA,MAChB,OAAO;AACL,YAAI;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SACE,6BAAAC,QAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,eAAW,kBAAAC,SAAW,oBAAAC,QAAO,QAAQ,UAAU;AAAA,MAC/C;AAAA,MACA,QACE,CAAC,iBACA,QAAQ,6BAAAF,QAAA,cAAC,OAAE,WAAU,wBAAuB,OAAO,EAAE,UAAU,IAAI,YAAY,QAAQ,OAAO,OAAO,GAAG;AAAA,MAE3G;AAAA,MACA,UAAU;AAAA,MACV,oBAAoB;AAAA,MACpB,kBAAkB;AAAA,MAClB;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,wBAAQ;",
4
+ "sourcesContent": ["/**\n * 组件名称:DebouncedInput\n * 组件描述:一个用于搜索的输入框组件,支持防抖\n * 组件使用场景:在需要搜索的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - noDebounced: 是否不使用防抖\n * - currentValue: 当前值\n * - placeholder: 输入框提示文字\n * - onChange: 值改变时的回调\n * - delay: 防抖时间\n * - inputClass: 输入框样式类名\n * - allowClear: 是否允许清空\n * - style: 组件样式\n */\nimport { useDebounceFn } from 'ahooks';\nimport { Input } from 'antd';\nimport classNames from 'classnames';\nimport React, { useEffect, useRef, useState } from 'react';\nimport styles from './index.module.less';\n\ntype PropsType = {\n noDebounced?: boolean;\n currentValue: string | undefined;\n placeholder?: string;\n onChange: (value: string) => void;\n delay?: number;\n inputClass?: any;\n allowClear?: boolean;\n style?: React.CSSProperties;\n noPrefixIcon?: boolean;\n disabled?: boolean;\n icon?: React.ReactNode;\n};\nconst DebouncedInput: React.FC<PropsType> = ({\n noDebounced = false,\n currentValue = '',\n placeholder = '搜索',\n onChange = (value: string) => {},\n delay = 150,\n inputClass,\n allowClear = true,\n style = {},\n noPrefixIcon = false,\n disabled = false,\n icon,\n}) => {\n const [value, setValue] = useState(currentValue);\n const lock = useRef(false);\n const changeFlag = useRef(false);\n useEffect(() => {\n if (changeFlag.current) {\n changeFlag.current = false;\n return;\n }\n setValue(currentValue);\n }, [currentValue]);\n\n const { run } = useDebounceFn(\n () => {\n onChange(value);\n },\n { wait: delay },\n );\n function handleChange(e: any) {\n const type = e.type;\n if (type === 'compositionstart') {\n lock.current = true;\n return;\n }\n const value = e.target.value;\n setValue(value);\n if (e.type === 'compositionend') {\n lock.current = false;\n }\n if (!lock.current) {\n changeFlag.current = true;\n if (noDebounced) {\n onChange(value);\n } else {\n run();\n }\n }\n }\n return (\n <Input\n allowClear={allowClear}\n style={style}\n className={classNames(styles.search, inputClass)}\n placeholder={placeholder}\n prefix={\n !noPrefixIcon &&\n (icon || <i className='iconfont icon-sousuo' style={{ fontSize: 14, lineHeight: '28px', color: '#999' }} />)\n }\n value={value}\n onChange={handleChange}\n onCompositionStart={handleChange}\n onCompositionEnd={handleChange}\n disabled={disabled}\n />\n );\n};\n\nexport default DebouncedInput;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,oBAA8B;AAC9B,kBAAsB;AACtB,wBAAuB;AACvB,mBAAmD;AACnD,0BAAmB;AAenB,IAAM,iBAAsC,CAAC;AAAA,EAC3C,cAAc;AAAA,EACd,eAAe;AAAA,EACf,cAAc;AAAA,EACd,WAAW,CAAC,UAAkB;AAAA,EAAC;AAAA,EAC/B,QAAQ;AAAA,EACR;AAAA,EACA,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,YAAY;AAC/C,QAAM,WAAO,qBAAO,KAAK;AACzB,QAAM,iBAAa,qBAAO,KAAK;AAC/B,8BAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,iBAAW,UAAU;AACrB;AAAA,IACF;AACA,aAAS,YAAY;AAAA,EACvB,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,EAAE,IAAI,QAAI;AAAA,IACd,MAAM;AACJ,eAAS,KAAK;AAAA,IAChB;AAAA,IACA,EAAE,MAAM,MAAM;AAAA,EAChB;AACA,WAAS,aAAa,GAAQ;AAC5B,UAAM,OAAO,EAAE;AACf,QAAI,SAAS,oBAAoB;AAC/B,WAAK,UAAU;AACf;AAAA,IACF;AACA,UAAMA,SAAQ,EAAE,OAAO;AACvB,aAASA,MAAK;AACd,QAAI,EAAE,SAAS,kBAAkB;AAC/B,WAAK,UAAU;AAAA,IACjB;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,iBAAW,UAAU;AACrB,UAAI,aAAa;AACf,iBAASA,MAAK;AAAA,MAChB,OAAO;AACL,YAAI;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SACE,6BAAAC,QAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,eAAW,kBAAAC,SAAW,oBAAAC,QAAO,QAAQ,UAAU;AAAA,MAC/C;AAAA,MACA,QACE,CAAC,iBACA,QAAQ,6BAAAF,QAAA,cAAC,OAAE,WAAU,wBAAuB,OAAO,EAAE,UAAU,IAAI,YAAY,QAAQ,OAAO,OAAO,GAAG;AAAA,MAE3G;AAAA,MACA,UAAU;AAAA,MACV,oBAAoB;AAAA,MACpB,kBAAkB;AAAA,MAClB;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,wBAAQ;",
6
6
  "names": ["value", "React", "classNames", "styles"]
7
7
  }
@@ -1,3 +1,17 @@
1
+ /**
2
+ * 组件名称:MultipleSelect
3
+ * 组件描述:一个用于多选的组件,支持搜索和选择
4
+ * 组件使用场景:在需要选择多个值的场景中使用,如筛选、排序等
5
+ * 组件参数说明:
6
+ * - name: 组件名称
7
+ * - value: 选中的值
8
+ * - onChange: 值改变时的回调
9
+ * - options: 选项列表
10
+ * - style: 组件样式
11
+ * - popoverStyle: 弹窗样式
12
+ * - icon: 组件图标
13
+ * - autoConfirm: 是否自动确认,默认为true。如果为false,则显示确定和取消按钮,点击确定后触发onChange
14
+ */
1
15
  import type { FC } from 'react';
2
16
  import React from 'react';
3
17
  type PageTypes = {
@@ -32,11 +32,11 @@ __export(MultipleSelect_exports, {
32
32
  default: () => MultipleSelect_default
33
33
  });
34
34
  module.exports = __toCommonJS(MultipleSelect_exports);
35
- var import_TextWithToolTip = __toESM(require("../TextWithToolTip"));
36
35
  var import_antd = require("antd");
37
36
  var import_classnames = __toESM(require("classnames"));
38
37
  var import_react = __toESM(require("react"));
39
38
  var import_react_virtualized = require("react-virtualized");
39
+ var import_TextWithToolTip = __toESM(require("../TextWithToolTip"));
40
40
  var import_DebounceInput = __toESM(require("../DebounceInput"));
41
41
  var import_index_module = __toESM(require("./index.module.less"));
42
42
  var MultipleSelect = ({
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/MultipleSelect/index.tsx"],
4
- "sourcesContent": ["/**\n * 组件名称:MultipleSelect\n * 组件描述:一个用于多选的组件,支持搜索和选择\n * 组件使用场景:在需要选择多个值的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - name: 组件名称\n * - value: 选中的值\n * - onChange: 值改变时的回调\n * - options: 选项列表\n * - style: 组件样式\n * - popoverStyle: 弹窗样式\n * - icon: 组件图标\n * - autoConfirm: 是否自动确认,默认为true。如果为false,则显示确定和取消按钮,点击确定后触发onChange\n */\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport { Button, Checkbox, ConfigProvider, Flex, message, Popover, Tooltip } from 'antd';\nimport classNames from 'classnames';\nimport type { FC } from 'react';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { AutoSizer, List } from 'react-virtualized';\nimport DebounceInput from '../DebounceInput';\nimport styles from './index.module.less';\n\ntype PageTypes = {\n name?: string;\n value: (string | number)[];\n onChange: (value: (string | number)[]) => void;\n options: { label: string; value: string | number; isSelectAll?: boolean }[];\n style?: React.CSSProperties;\n popoverStyle?: React.CSSProperties;\n icon?: React.ReactNode;\n noXiala?: boolean;\n minCount?: number;\n disabledItems?: (string | number)[] | undefined; // 禁用选项\n disabledMessages?: string; // 禁用提示\n noAllSelect?: boolean; // 是否不显示全选选项\n autoConfirm?: boolean; // 是否自动确认,默认为true,如果为false则显示确定和取消按钮\n};\n\nconst MultipleSelect: FC<PageTypes> = ({\n name,\n value = [],\n onChange,\n options = [],\n style,\n popoverStyle,\n icon,\n noXiala = false,\n minCount = 0,\n disabledItems,\n disabledMessages,\n noAllSelect = false,\n autoConfirm = true,\n}) => {\n const [searchKey, setSearchKey] = useState('');\n const [open, setOpen] = useState(false);\n const [tempValue, setTempValue] = useState<(string | number)[]>([]); // 临时存储选中的值\n const listRef = useRef(null);\n\n useEffect(() => {\n setTimeout(() => {\n setSearchKey('');\n }, 200);\n }, [open]);\n\n // 当弹窗打开时,初始化临时值\n useEffect(() => {\n if (open) {\n setTempValue(value);\n }\n }, [open, value]);\n\n const handlePopOpen = (visible: boolean) => {\n setOpen(visible);\n };\n\n const itemClick = (v: string | number, checked: boolean) => {\n const currentValue = autoConfirm ? value : tempValue;\n\n if (checked && currentValue.filter((f) => f !== v).length < minCount) {\n message.warning(`至少选择${minCount}个`);\n return;\n }\n\n const newValue = checked ? currentValue?.filter((f) => f !== v) : [...currentValue, v];\n\n if (autoConfirm) {\n // 自动确认模式,直接触发onChange\n onChange(newValue);\n } else {\n // 非自动确认模式,更新临时值\n setTempValue(newValue);\n }\n };\n\n const filterOptions = useMemo(() => {\n const key = searchKey.trim().toUpperCase();\n const filtered = options.filter((m) => {\n if (key) {\n return m.label.toUpperCase().includes(key);\n }\n return true;\n });\n // 添加全选选项到列表开头\n return noAllSelect ? filtered : [{ label: '全选', value: '__selectAll__', isSelectAll: true }, ...filtered];\n }, [searchKey, options]);\n\n const rowRenderer = ({ index, key, style }: { index: number; key: string; style: React.CSSProperties }) => {\n const m = filterOptions[index];\n const currentValue = autoConfirm ? value : tempValue;\n\n // 处理全选选项\n if (m.isSelectAll) {\n return (\n <div key={key} style={style} className={styles.checkAll}>\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n checked={currentValue.length === options.length}\n indeterminate={currentValue.length > 0 && currentValue.length < options.length}\n onChange={(e) => {\n const newValue = e.target.checked ? options.map((m) => m.value) : [];\n if (autoConfirm) {\n onChange(newValue);\n } else {\n setTempValue(newValue);\n }\n }}\n >\n 全选\n </Checkbox>\n </ConfigProvider>\n </div>\n );\n }\n\n // 处理普通选项\n return (\n <Tooltip\n title={disabledItems?.includes(m.value) ? disabledMessages || '该选项不能改变状态' : ''}\n color='#fff'\n styles={{ body: { color: '#333', fontSize: 12 } }}\n key={key}\n style={style}\n >\n <div\n style={style}\n className={classNames(styles.optionItem, currentValue?.includes(m.value) ? styles.active : null)}\n // 可以保留整行点击\n onClick={() => {\n if (disabledItems?.includes(m.value)) {\n return;\n }\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n >\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n disabled={disabledItems?.includes(m.value)}\n checked={currentValue?.includes(m.value)}\n onChange={() => {\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n // 阻止点击Checkbox时冒泡到整行\n onClick={(e) => e.stopPropagation()}\n style={{ marginRight: 8 }}\n />\n </ConfigProvider>\n <TextWithTooltip\n text={m.label}\n style={{ color: disabledItems?.includes(m.value) ? '#999' : '#333' }}\n width='100%'\n maxWidth='100%'\n className={styles.label}\n highlight={searchKey}\n />\n </div>\n </Tooltip>\n );\n };\n\n const PopoverContent = (\n <div className={styles.popoverContent} style={popoverStyle}>\n <DebounceInput\n allowClear={true}\n inputClass={styles.searchInput}\n placeholder='搜索'\n currentValue={searchKey}\n onChange={(value) => {\n setSearchKey(value);\n }}\n ></DebounceInput>\n <div className={styles.popoverContentList}>\n {filterOptions.length === 0 ? (\n <div className={styles.emptyItem}>当前搜索条件无数据</div>\n ) : (\n <AutoSizer\n style={{\n background: '#fff',\n width: '100%',\n // maxHeight: 400,\n minHeight: 35,\n height: 'auto',\n }}\n >\n {({ width }: { width: number }) => {\n let height = 35;\n if (filterOptions.length <= 10) {\n height = 35 * filterOptions.length || 35;\n } else {\n height = 35 * 10;\n }\n return (\n <List\n ref={listRef}\n overscanRowCount={5}\n width={width}\n height={height}\n rowCount={filterOptions.length}\n rowHeight={35}\n rowRenderer={rowRenderer}\n />\n );\n }}\n </AutoSizer>\n )}\n </div>\n {!autoConfirm && (\n <div className={styles.popoverFooter}>\n <Button\n size='small'\n type='primary'\n onClick={() => {\n onChange(tempValue);\n setOpen(false);\n }}\n >\n 确定\n </Button>\n <Button\n size='small'\n // className={styles.cancelButton}\n onClick={() => {\n setTempValue(value);\n setOpen(false);\n }}\n >\n 取消\n </Button>\n </div>\n )}\n </div>\n );\n\n return (\n <Popover\n open={open}\n onOpenChange={handlePopOpen}\n fresh={true}\n title={false}\n arrow={false}\n content={PopoverContent}\n trigger='click'\n placement='bottomLeft'\n styles={{ body: { borderRadius: 2, padding: 0 } }}\n >\n <Button\n className={styles.button}\n style={style}\n icon={\n noXiala ? null : <i className='iconfont icon-xiala1' style={open ? { transform: 'rotate(180deg)' } : {}} />\n }\n iconPosition='end'\n onClick={() => {\n setOpen(!open);\n }}\n >\n <Flex justify='space-between' style={{ flex: 1, overflow: 'hidden' }}>\n {icon && icon}\n {name && <span className={styles.nameText}>{name}:</span>}\n <span className={styles.valueText} style={{ flex: 1 }}>\n {value?.length === 1 && options?.length === 1\n ? options?.find((m) => m.value === value?.[0])?.label\n : (value?.length || 0) + '/' + options?.length}\n </span>\n </Flex>\n </Button>\n </Popover>\n );\n};\n\nexport default MultipleSelect;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * 组件名称:MultipleSelect\n * 组件描述:一个用于多选的组件,支持搜索和选择\n * 组件使用场景:在需要选择多个值的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - name: 组件名称\n * - value: 选中的值\n * - onChange: 值改变时的回调\n * - options: 选项列表\n * - style: 组件样式\n * - popoverStyle: 弹窗样式\n * - icon: 组件图标\n * - autoConfirm: 是否自动确认,默认为true。如果为false,则显示确定和取消按钮,点击确定后触发onChange\n */\n\nimport { Button, Checkbox, ConfigProvider, Flex, message, Popover, Tooltip } from 'antd';\nimport classNames from 'classnames';\nimport type { FC } from 'react';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { AutoSizer, List } from 'react-virtualized';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport DebounceInput from '../DebounceInput';\nimport styles from './index.module.less';\n\ntype PageTypes = {\n name?: string;\n value: (string | number)[];\n onChange: (value: (string | number)[]) => void;\n options: { label: string; value: string | number; isSelectAll?: boolean }[];\n style?: React.CSSProperties;\n popoverStyle?: React.CSSProperties;\n icon?: React.ReactNode;\n noXiala?: boolean;\n minCount?: number;\n disabledItems?: (string | number)[] | undefined; // 禁用选项\n disabledMessages?: string; // 禁用提示\n noAllSelect?: boolean; // 是否不显示全选选项\n autoConfirm?: boolean; // 是否自动确认,默认为true,如果为false则显示确定和取消按钮\n};\n\nconst MultipleSelect: FC<PageTypes> = ({\n name,\n value = [],\n onChange,\n options = [],\n style,\n popoverStyle,\n icon,\n noXiala = false,\n minCount = 0,\n disabledItems,\n disabledMessages,\n noAllSelect = false,\n autoConfirm = true,\n}) => {\n const [searchKey, setSearchKey] = useState('');\n const [open, setOpen] = useState(false);\n const [tempValue, setTempValue] = useState<(string | number)[]>([]); // 临时存储选中的值\n const listRef = useRef(null);\n\n useEffect(() => {\n setTimeout(() => {\n setSearchKey('');\n }, 200);\n }, [open]);\n\n // 当弹窗打开时,初始化临时值\n useEffect(() => {\n if (open) {\n setTempValue(value);\n }\n }, [open, value]);\n\n const handlePopOpen = (visible: boolean) => {\n setOpen(visible);\n };\n\n const itemClick = (v: string | number, checked: boolean) => {\n const currentValue = autoConfirm ? value : tempValue;\n\n if (checked && currentValue.filter((f) => f !== v).length < minCount) {\n message.warning(`至少选择${minCount}个`);\n return;\n }\n\n const newValue = checked ? currentValue?.filter((f) => f !== v) : [...currentValue, v];\n\n if (autoConfirm) {\n // 自动确认模式,直接触发onChange\n onChange(newValue);\n } else {\n // 非自动确认模式,更新临时值\n setTempValue(newValue);\n }\n };\n\n const filterOptions = useMemo(() => {\n const key = searchKey.trim().toUpperCase();\n const filtered = options.filter((m) => {\n if (key) {\n return m.label.toUpperCase().includes(key);\n }\n return true;\n });\n // 添加全选选项到列表开头\n return noAllSelect ? filtered : [{ label: '全选', value: '__selectAll__', isSelectAll: true }, ...filtered];\n }, [searchKey, options]);\n\n const rowRenderer = ({ index, key, style }: { index: number; key: string; style: React.CSSProperties }) => {\n const m = filterOptions[index];\n const currentValue = autoConfirm ? value : tempValue;\n\n // 处理全选选项\n if (m.isSelectAll) {\n return (\n <div key={key} style={style} className={styles.checkAll}>\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n checked={currentValue.length === options.length}\n indeterminate={currentValue.length > 0 && currentValue.length < options.length}\n onChange={(e) => {\n const newValue = e.target.checked ? options.map((m) => m.value) : [];\n if (autoConfirm) {\n onChange(newValue);\n } else {\n setTempValue(newValue);\n }\n }}\n >\n 全选\n </Checkbox>\n </ConfigProvider>\n </div>\n );\n }\n\n // 处理普通选项\n return (\n <Tooltip\n title={disabledItems?.includes(m.value) ? disabledMessages || '该选项不能改变状态' : ''}\n color='#fff'\n styles={{ body: { color: '#333', fontSize: 12 } }}\n key={key}\n style={style}\n >\n <div\n style={style}\n className={classNames(styles.optionItem, currentValue?.includes(m.value) ? styles.active : null)}\n // 可以保留整行点击\n onClick={() => {\n if (disabledItems?.includes(m.value)) {\n return;\n }\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n >\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n disabled={disabledItems?.includes(m.value)}\n checked={currentValue?.includes(m.value)}\n onChange={() => {\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n // 阻止点击Checkbox时冒泡到整行\n onClick={(e) => e.stopPropagation()}\n style={{ marginRight: 8 }}\n />\n </ConfigProvider>\n <TextWithTooltip\n text={m.label}\n style={{ color: disabledItems?.includes(m.value) ? '#999' : '#333' }}\n width='100%'\n maxWidth='100%'\n className={styles.label}\n highlight={searchKey}\n />\n </div>\n </Tooltip>\n );\n };\n\n const PopoverContent = (\n <div className={styles.popoverContent} style={popoverStyle}>\n <DebounceInput\n allowClear={true}\n inputClass={styles.searchInput}\n placeholder='搜索'\n currentValue={searchKey}\n onChange={(value) => {\n setSearchKey(value);\n }}\n ></DebounceInput>\n <div className={styles.popoverContentList}>\n {filterOptions.length === 0 ? (\n <div className={styles.emptyItem}>当前搜索条件无数据</div>\n ) : (\n <AutoSizer\n style={{\n background: '#fff',\n width: '100%',\n // maxHeight: 400,\n minHeight: 35,\n height: 'auto',\n }}\n >\n {({ width }: { width: number }) => {\n let height = 35;\n if (filterOptions.length <= 10) {\n height = 35 * filterOptions.length || 35;\n } else {\n height = 35 * 10;\n }\n return (\n <List\n ref={listRef}\n overscanRowCount={5}\n width={width}\n height={height}\n rowCount={filterOptions.length}\n rowHeight={35}\n rowRenderer={rowRenderer}\n />\n );\n }}\n </AutoSizer>\n )}\n </div>\n {!autoConfirm && (\n <div className={styles.popoverFooter}>\n <Button\n size='small'\n type='primary'\n onClick={() => {\n onChange(tempValue);\n setOpen(false);\n }}\n >\n 确定\n </Button>\n <Button\n size='small'\n // className={styles.cancelButton}\n onClick={() => {\n setTempValue(value);\n setOpen(false);\n }}\n >\n 取消\n </Button>\n </div>\n )}\n </div>\n );\n\n return (\n <Popover\n open={open}\n onOpenChange={handlePopOpen}\n fresh={true}\n title={false}\n arrow={false}\n content={PopoverContent}\n trigger='click'\n placement='bottomLeft'\n styles={{ body: { borderRadius: 2, padding: 0 } }}\n >\n <Button\n className={styles.button}\n style={style}\n icon={\n noXiala ? null : <i className='iconfont icon-xiala1' style={open ? { transform: 'rotate(180deg)' } : {}} />\n }\n iconPosition='end'\n onClick={() => {\n setOpen(!open);\n }}\n >\n <Flex justify='space-between' style={{ flex: 1, overflow: 'hidden' }}>\n {icon && icon}\n {name && <span className={styles.nameText}>{name}:</span>}\n <span className={styles.valueText} style={{ flex: 1 }}>\n {value?.length === 1 && options?.length === 1\n ? options?.find((m) => m.value === value?.[0])?.label\n : (value?.length || 0) + '/' + options?.length}\n </span>\n </Flex>\n </Button>\n </Popover>\n );\n};\n\nexport default MultipleSelect;\n"],
5
+ "mappings": "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",
6
6
  "names": ["style", "React", "styles", "m", "classNames", "TextWithTooltip", "DebounceInput", "value"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/RefreshButton/index.tsx"],
4
- "sourcesContent": ["import { Button } from 'antd';\nimport React from 'react';\ntype Props = {\n handleRefresh: () => void;\n text?: string;\n style?: React.CSSProperties;\n};\n\nconst RefreshButton: React.FC<Props> = ({ handleRefresh, text = '刷新', style }) => {\n return (\n <Button\n style={style}\n onClick={() => {\n handleRefresh();\n }}\n icon={<i className='iconfont icon-refresh' style={{ color: '#3B86F9', fontSize: 14 }} />}\n >\n {text}\n </Button>\n );\n};\n\nexport default RefreshButton;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAuB;AACvB,mBAAkB;AAOlB,IAAM,gBAAiC,CAAC,EAAE,eAAe,OAAO,MAAM,MAAM,MAAM;AAChF,SACE,6BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS,MAAM;AACb,sBAAc;AAAA,MAChB;AAAA,MACA,MAAM,6BAAAA,QAAA,cAAC,OAAE,WAAU,yBAAwB,OAAO,EAAE,OAAO,WAAW,UAAU,GAAG,GAAG;AAAA;AAAA,IAErF;AAAA,EACH;AAEJ;AAEA,IAAO,wBAAQ;",
4
+ "sourcesContent": ["import { Button } from 'antd';\nimport React from 'react';\n\ntype Props = {\n handleRefresh: () => void;\n text?: string;\n style?: React.CSSProperties;\n};\n\nconst RefreshButton: React.FC<Props> = ({ handleRefresh, text = '刷新', style }) => {\n return (\n <Button\n style={style}\n onClick={() => {\n handleRefresh();\n }}\n icon={<i className='iconfont icon-refresh' style={{ color: '#3B86F9', fontSize: 14 }} />}\n >\n {text}\n </Button>\n );\n};\n\nexport default RefreshButton;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAuB;AACvB,mBAAkB;AAQlB,IAAM,gBAAiC,CAAC,EAAE,eAAe,OAAO,MAAM,MAAM,MAAM;AAChF,SACE,6BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS,MAAM;AACb,sBAAc;AAAA,MAChB;AAAA,MACA,MAAM,6BAAAA,QAAA,cAAC,OAAE,WAAU,yBAAwB,OAAO,EAAE,OAAO,WAAW,UAAU,GAAG,GAAG;AAAA;AAAA,IAErF;AAAA,EACH;AAEJ;AAEA,IAAO,wBAAQ;",
6
6
  "names": ["React"]
7
7
  }
@@ -32,11 +32,11 @@ __export(SearchWithHistory_exports, {
32
32
  default: () => SearchWithHistory_default
33
33
  });
34
34
  module.exports = __toCommonJS(SearchWithHistory_exports);
35
- var import_TextWithToolTip = __toESM(require("../TextWithToolTip"));
36
35
  var import_icons = require("@ant-design/icons");
37
36
  var import_ahooks = require("ahooks");
38
37
  var import_antd = require("antd");
39
38
  var import_react = __toESM(require("react"));
39
+ var import_TextWithToolTip = __toESM(require("../TextWithToolTip"));
40
40
  var import_index_module = __toESM(require("./index.module.less"));
41
41
  var INPUT_THEME = {
42
42
  token: { colorText: "rgba(191, 199, 209, 1)" },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/SearchWithHistory/index.tsx"],
4
- "sourcesContent": ["import TextWithTooltip from '@/components/TextWithToolTip';\nimport { ClockCircleOutlined, SearchOutlined } from '@ant-design/icons';\nimport { useLocalStorageState } from 'ahooks';\nimport { ConfigProvider, Input, Popover } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport styles from './index.module.less';\n\ntype SearchWithHistoryProps = {\n /** localStorage 存储 key */\n localstorageKey: string;\n /** 可搜索的选项列表(含菜单路由、看板等) */\n list: { label: string; value: string; tag?: string }[];\n placeholder?: string;\n /** 选中项回调,value 为路由 path 或看板 id 等 */\n onClick: (value: string) => void;\n};\n\nconst INPUT_THEME = {\n token: { colorText: 'rgba(191, 199, 209, 1)' },\n components: {\n Input: {\n colorBgContainer: 'rgba(45, 56, 86, 1)',\n colorBorder: '#2D3856',\n borderRadius: 18,\n boxShadow: 'inset 0px -0.5px 0px 0px rgba(20, 31, 62, 0.5)',\n hoverBorderColor: 'rgba(0, 85, 255, 1)',\n paddingBlock: 6,\n },\n },\n};\n\n/**\n * 带历史记录的搜索弹层\n * - 无输入时展示最近搜索(localStorage 持久化)\n * - 有输入时展示匹配的菜单/看板列表\n */\nconst SearchWithHistory: React.FC<SearchWithHistoryProps> = ({\n localstorageKey = 'yk_search_history',\n list,\n placeholder = '搜索',\n onClick,\n}) => {\n const [open, setOpen] = useState(false);\n const [searchValue, setSearchValue] = useState('');\n const [historyList, setHistoryList] = useLocalStorageState<{ label: string; value: string; tag?: string }[]>(\n localstorageKey,\n { defaultValue: [] },\n );\n\n /** 选中项:执行回调并更新历史(同 value 则置顶) */\n const menuItemClick = useCallback(\n (item: { label: string; value: string; tag?: string }) => {\n onClick(item.value);\n setOpen(false);\n setHistoryList((prev = []) => [item, ...prev.filter((h) => h.value !== item.value)]);\n },\n [onClick, setHistoryList],\n );\n\n /** 清空历史 */\n const clearHistory = useCallback(() => {\n setOpen(false);\n setTimeout(() => setHistoryList([]), 100);\n }, [setHistoryList]);\n\n /** 匹配的选项列表(按 label 包含搜索词过滤) */\n const menuList = useMemo(() => list.filter((item) => item.label.includes(searchValue)), [list, searchValue]);\n\n /** 最近搜索列表 DOM */\n const historyContent = useMemo(\n () => (\n <div>\n <div className={styles.historyHeader}>\n <ClockCircleOutlined style={{ marginRight: 10, transform: 'translateY(-1px)' }} />\n <span>最近搜索</span>\n <i className='iconfont icon-lajitong' onClick={clearHistory} />\n </div>\n <div className={styles.historyList}>\n {historyList.map((item) => (\n <div className={styles.item} key={item.value} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n </div>\n ),\n [historyList, clearHistory, menuItemClick],\n );\n\n /** 搜索结果列表 DOM */\n const listContent = useMemo(\n () => (\n <div>\n {menuList.map((item) => (\n <div key={item.value} className={styles.item} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} highlight={searchValue} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n ),\n [menuList, searchValue, menuItemClick],\n );\n\n /**\n * 弹层内容:根据输入与历史决定\n * 1. 无历史 → null(不展示弹层)\n * 2. 有历史且无输入 → 最近搜索\n * 3. 有输入且无匹配 → 暂无搜索结果\n * 4. 有输入且匹配 → 菜单列表\n */\n const content = useMemo(() => {\n if (!searchValue) {\n if (historyList.length === 0) return null;\n return <div>{historyContent}</div>;\n }\n if (menuList.length === 0) return <div style={{ color: '#999' }}>暂无搜索结果</div>;\n return listContent;\n }, [searchValue, historyList, historyContent, menuList, listContent]);\n\n /** 内容为空时关闭弹层(如清空输入且无历史) */\n useEffect(() => {\n if (!content) setOpen(false);\n }, [content]);\n\n /** 有输入或有历史时显示弹层 */\n const shouldOpen = (value: string) => {\n if (value) return true;\n return historyList.length > 0;\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(nextOpen) => {\n if (nextOpen && !content) return; // 无内容时不打开,避免空白弹层\n setOpen(nextOpen);\n }}\n className={styles.popover}\n styles={{ body: { borderRadius: 4, width: 250, paddingRight: 0 } }}\n fresh\n title={false}\n trigger='click'\n placement='bottomLeft'\n arrow={false}\n content={content}\n getPopupContainer={(triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement}\n autoAdjustOverflow={false}\n >\n <ConfigProvider theme={INPUT_THEME}>\n <Input\n className={styles.inputContainer}\n classNames={{ input: styles.input }}\n placeholder={placeholder}\n prefix={<SearchOutlined />}\n value={searchValue}\n onFocus={() => historyList.length > 0 && setOpen(true)}\n onChange={(e) => {\n const val = e.target.value;\n setSearchValue(val);\n setOpen(shouldOpen(val));\n }}\n />\n </ConfigProvider>\n </Popover>\n );\n};\n\nexport default SearchWithHistory;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { ClockCircleOutlined, SearchOutlined } from '@ant-design/icons';\nimport { useLocalStorageState } from 'ahooks';\nimport { ConfigProvider, Input, Popover } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport styles from './index.module.less';\n\ntype SearchWithHistoryProps = {\n /** localStorage 存储 key */\n localstorageKey: string;\n /** 可搜索的选项列表(含菜单路由、看板等) */\n list: { label: string; value: string; tag?: string }[];\n placeholder?: string;\n /** 选中项回调,value 为路由 path 或看板 id 等 */\n onClick: (value: string) => void;\n};\n\nconst INPUT_THEME = {\n token: { colorText: 'rgba(191, 199, 209, 1)' },\n components: {\n Input: {\n colorBgContainer: 'rgba(45, 56, 86, 1)',\n colorBorder: '#2D3856',\n borderRadius: 18,\n boxShadow: 'inset 0px -0.5px 0px 0px rgba(20, 31, 62, 0.5)',\n hoverBorderColor: 'rgba(0, 85, 255, 1)',\n paddingBlock: 6,\n },\n },\n};\n\n/**\n * 带历史记录的搜索弹层\n * - 无输入时展示最近搜索(localStorage 持久化)\n * - 有输入时展示匹配的菜单/看板列表\n */\nconst SearchWithHistory: React.FC<SearchWithHistoryProps> = ({\n localstorageKey = 'yk_search_history',\n list,\n placeholder = '搜索',\n onClick,\n}) => {\n const [open, setOpen] = useState(false);\n const [searchValue, setSearchValue] = useState('');\n const [historyList, setHistoryList] = useLocalStorageState<{ label: string; value: string; tag?: string }[]>(\n localstorageKey,\n { defaultValue: [] },\n );\n\n /** 选中项:执行回调并更新历史(同 value 则置顶) */\n const menuItemClick = useCallback(\n (item: { label: string; value: string; tag?: string }) => {\n onClick(item.value);\n setOpen(false);\n setHistoryList((prev = []) => [item, ...prev.filter((h) => h.value !== item.value)]);\n },\n [onClick, setHistoryList],\n );\n\n /** 清空历史 */\n const clearHistory = useCallback(() => {\n setOpen(false);\n setTimeout(() => setHistoryList([]), 100);\n }, [setHistoryList]);\n\n /** 匹配的选项列表(按 label 包含搜索词过滤) */\n const menuList = useMemo(() => list.filter((item) => item.label.includes(searchValue)), [list, searchValue]);\n\n /** 最近搜索列表 DOM */\n const historyContent = useMemo(\n () => (\n <div>\n <div className={styles.historyHeader}>\n <ClockCircleOutlined style={{ marginRight: 10, transform: 'translateY(-1px)' }} />\n <span>最近搜索</span>\n <i className='iconfont icon-lajitong' onClick={clearHistory} />\n </div>\n <div className={styles.historyList}>\n {historyList.map((item) => (\n <div className={styles.item} key={item.value} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n </div>\n ),\n [historyList, clearHistory, menuItemClick],\n );\n\n /** 搜索结果列表 DOM */\n const listContent = useMemo(\n () => (\n <div>\n {menuList.map((item) => (\n <div key={item.value} className={styles.item} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} highlight={searchValue} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n ),\n [menuList, searchValue, menuItemClick],\n );\n\n /**\n * 弹层内容:根据输入与历史决定\n * 1. 无历史 → null(不展示弹层)\n * 2. 有历史且无输入 → 最近搜索\n * 3. 有输入且无匹配 → 暂无搜索结果\n * 4. 有输入且匹配 → 菜单列表\n */\n const content = useMemo(() => {\n if (!searchValue) {\n if (historyList.length === 0) return null;\n return <div>{historyContent}</div>;\n }\n if (menuList.length === 0) return <div style={{ color: '#999' }}>暂无搜索结果</div>;\n return listContent;\n }, [searchValue, historyList, historyContent, menuList, listContent]);\n\n /** 内容为空时关闭弹层(如清空输入且无历史) */\n useEffect(() => {\n if (!content) setOpen(false);\n }, [content]);\n\n /** 有输入或有历史时显示弹层 */\n const shouldOpen = (value: string) => {\n if (value) return true;\n return historyList.length > 0;\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(nextOpen) => {\n if (nextOpen && !content) return; // 无内容时不打开,避免空白弹层\n setOpen(nextOpen);\n }}\n className={styles.popover}\n styles={{ body: { borderRadius: 4, width: 250, paddingRight: 0 } }}\n fresh\n title={false}\n trigger='click'\n placement='bottomLeft'\n arrow={false}\n content={content}\n getPopupContainer={(triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement}\n autoAdjustOverflow={false}\n >\n <ConfigProvider theme={INPUT_THEME}>\n <Input\n className={styles.inputContainer}\n classNames={{ input: styles.input }}\n placeholder={placeholder}\n prefix={<SearchOutlined />}\n value={searchValue}\n onFocus={() => historyList.length > 0 && setOpen(true)}\n onChange={(e) => {\n const val = e.target.value;\n setSearchValue(val);\n setOpen(shouldOpen(val));\n }}\n />\n </ConfigProvider>\n </Popover>\n );\n};\n\nexport default SearchWithHistory;\n"],
5
+ "mappings": "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",
6
6
  "names": ["React", "styles", "TextWithTooltip"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import { TooltipProps } from 'antd';
1
+ import { type TooltipProps } from 'antd';
2
2
  import React from 'react';
3
3
  type PropsType = {
4
4
  text: number | string | React.ReactNode;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/TextWithToolTip/index.tsx"],
4
- "sourcesContent": ["import { Tooltip, TooltipProps } from 'antd';\nimport React, { useRef, useState } from 'react';\n\ntype PropsType = {\n text: number | string | React.ReactNode;\n placement?: 'top' | 'left' | 'right' | 'bottom';\n zIndex?: number;\n color?: string;\n styles?: TooltipProps['styles'];\n width: number | string;\n maxWidth?: number | string;\n className?: string;\n style?: React.CSSProperties;\n highlight?: string; // 高亮的关键字\n arrow?: boolean;\n};\n\nconst TextWithTooltip: React.FC<PropsType> = ({\n text,\n placement = 'top',\n zIndex,\n width,\n maxWidth,\n className,\n style = {},\n color,\n styles,\n highlight = '',\n arrow = false,\n}) => {\n const [showTooltip, setShowTooltip] = useState(false);\n const textRef = useRef(null);\n\n const handleMouseEnter = () => {\n if (textRef.current) {\n const range = document.createRange();\n range.selectNodeContents(textRef.current);\n const rangeWidth = range.getBoundingClientRect().width;\n const actualWidth = (textRef.current as HTMLElement).getBoundingClientRect().width;\n setShowTooltip(rangeWidth > actualWidth);\n }\n };\n\n // 将text按照高亮关键字拆分成数组\n function splitString(str: string, delimiter: string) {\n const result = [];\n let match;\n const escapedDelimiter = delimiter.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n const regex = new RegExp(`(${escapedDelimiter})`, 'gi');\n let remaining = str; // 新建变量存储剩余字符串\n\n while ((match = regex.exec(remaining)) !== null) {\n const index = match.index;\n if (index !== 0) {\n result.push(remaining.slice(0, index));\n }\n result.push(match[1]);\n remaining = remaining.slice(index + match[1].length);\n regex.lastIndex = 0;\n }\n if (remaining.length > 0) {\n result.push(remaining);\n }\n return result;\n }\n\n // text是ReactNode时,不处理高亮\n const highlightedText = (text: number | string | React.ReactNode): React.ReactNode => {\n if (highlight && (typeof text === 'string' || typeof text === 'number')) {\n return splitString(text.toString(), highlight).map((part, index) => {\n if (part.toUpperCase() === highlight.toUpperCase()) {\n return (\n <span key={index} style={{ color: '#ffb401' }}>\n {part}\n </span>\n );\n } else {\n return <span key={index}>{part}</span>;\n }\n });\n } else {\n return text;\n }\n };\n\n // 处理宽度值,确保字符串数字能正确转换为带单位的 CSS 值\n const formatWidth = (value: number | string): number | string => {\n if (typeof value === 'string' && /^\\d+$/.test(value)) {\n // 如果是纯数字字符串,添加 px 单位\n return `${value}px`;\n }\n return value;\n };\n\n return (\n <Tooltip\n open={showTooltip}\n title={text}\n placement={placement}\n arrow={arrow}\n destroyOnHidden={true}\n color={color ? color : '#fff'}\n styles={styles ? styles : { body: { color: '#333', fontSize: 12 } }}\n {...(zIndex ? { zIndex } : {})}\n >\n <span\n ref={textRef}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={() => setShowTooltip(false)}\n className={className}\n style={{\n display: 'inline-block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom',\n ...style,\n ...(maxWidth ? { maxWidth: formatWidth(maxWidth) } : { width: formatWidth(width) }),\n }}\n >\n {highlightedText(text)}\n </span>\n </Tooltip>\n );\n};\n\nexport default TextWithTooltip;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAsC;AACtC,mBAAwC;AAgBxC,IAAM,kBAAuC,CAAC;AAAA,EAC5C;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,CAAC;AAAA,EACT;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,QAAQ;AACV,MAAM;AACJ,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,KAAK;AACpD,QAAM,cAAU,qBAAO,IAAI;AAE3B,QAAM,mBAAmB,MAAM;AAC7B,QAAI,QAAQ,SAAS;AACnB,YAAM,QAAQ,SAAS,YAAY;AACnC,YAAM,mBAAmB,QAAQ,OAAO;AACxC,YAAM,aAAa,MAAM,sBAAsB,EAAE;AACjD,YAAM,cAAe,QAAQ,QAAwB,sBAAsB,EAAE;AAC7E,qBAAe,aAAa,WAAW;AAAA,IACzC;AAAA,EACF;AAGA,WAAS,YAAY,KAAa,WAAmB;AACnD,UAAM,SAAS,CAAC;AAChB,QAAI;AACJ,UAAM,mBAAmB,UAAU,QAAQ,yBAAyB,MAAM;AAC1E,UAAM,QAAQ,IAAI,OAAO,IAAI,qBAAqB,IAAI;AACtD,QAAI,YAAY;AAEhB,YAAQ,QAAQ,MAAM,KAAK,SAAS,OAAO,MAAM;AAC/C,YAAM,QAAQ,MAAM;AACpB,UAAI,UAAU,GAAG;AACf,eAAO,KAAK,UAAU,MAAM,GAAG,KAAK,CAAC;AAAA,MACvC;AACA,aAAO,KAAK,MAAM,CAAC,CAAC;AACpB,kBAAY,UAAU,MAAM,QAAQ,MAAM,CAAC,EAAE,MAAM;AACnD,YAAM,YAAY;AAAA,IACpB;AACA,QAAI,UAAU,SAAS,GAAG;AACxB,aAAO,KAAK,SAAS;AAAA,IACvB;AACA,WAAO;AAAA,EACT;AAGA,QAAM,kBAAkB,CAACA,UAA6D;AACpF,QAAI,cAAc,OAAOA,UAAS,YAAY,OAAOA,UAAS,WAAW;AACvE,aAAO,YAAYA,MAAK,SAAS,GAAG,SAAS,EAAE,IAAI,CAAC,MAAM,UAAU;AAClE,YAAI,KAAK,YAAY,MAAM,UAAU,YAAY,GAAG;AAClD,iBACE,6BAAAC,QAAA,cAAC,UAAK,KAAK,OAAO,OAAO,EAAE,OAAO,UAAU,KACzC,IACH;AAAA,QAEJ,OAAO;AACL,iBAAO,6BAAAA,QAAA,cAAC,UAAK,KAAK,SAAQ,IAAK;AAAA,QACjC;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,aAAOD;AAAA,IACT;AAAA,EACF;AAGA,QAAM,cAAc,CAAC,UAA4C;AAC/D,QAAI,OAAO,UAAU,YAAY,QAAQ,KAAK,KAAK,GAAG;AAEpD,aAAO,GAAG;AAAA,IACZ;AACA,WAAO;AAAA,EACT;AAEA,SACE,6BAAAC,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,MACjB,OAAO,QAAQ,QAAQ;AAAA,MACvB,QAAQ,SAAS,SAAS,EAAE,MAAM,EAAE,OAAO,QAAQ,UAAU,GAAG,EAAE;AAAA,MACjE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA;AAAA,IAE5B,6BAAAA,QAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,cAAc;AAAA,QACd,cAAc,MAAM,eAAe,KAAK;AAAA,QACxC;AAAA,QACA,OAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,UACV,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,GAAG;AAAA,UACH,GAAI,WAAW,EAAE,UAAU,YAAY,QAAQ,EAAE,IAAI,EAAE,OAAO,YAAY,KAAK,EAAE;AAAA,QACnF;AAAA;AAAA,MAEC,gBAAgB,IAAI;AAAA,IACvB;AAAA,EACF;AAEJ;AAEA,IAAO,0BAAQ;",
4
+ "sourcesContent": ["import { Tooltip, type TooltipProps } from 'antd';\nimport React, { useRef, useState } from 'react';\n\ntype PropsType = {\n text: number | string | React.ReactNode;\n placement?: 'top' | 'left' | 'right' | 'bottom';\n zIndex?: number;\n color?: string;\n styles?: TooltipProps['styles'];\n width: number | string;\n maxWidth?: number | string;\n className?: string;\n style?: React.CSSProperties;\n highlight?: string; // 高亮的关键字\n arrow?: boolean;\n};\n\nconst TextWithTooltip: React.FC<PropsType> = ({\n text,\n placement = 'top',\n zIndex,\n width,\n maxWidth,\n className,\n style = {},\n color,\n styles,\n highlight = '',\n arrow = false,\n}) => {\n const [showTooltip, setShowTooltip] = useState(false);\n const textRef = useRef(null);\n\n const handleMouseEnter = () => {\n if (textRef.current) {\n const range = document.createRange();\n range.selectNodeContents(textRef.current);\n const rangeWidth = range.getBoundingClientRect().width;\n const actualWidth = (textRef.current as HTMLElement).getBoundingClientRect().width;\n setShowTooltip(rangeWidth > actualWidth);\n }\n };\n\n // 将text按照高亮关键字拆分成数组\n function splitString(str: string, delimiter: string) {\n const result = [];\n let match;\n const escapedDelimiter = delimiter.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n const regex = new RegExp(`(${escapedDelimiter})`, 'gi');\n let remaining = str; // 新建变量存储剩余字符串\n\n while ((match = regex.exec(remaining)) !== null) {\n const index = match.index;\n if (index !== 0) {\n result.push(remaining.slice(0, index));\n }\n result.push(match[1]);\n remaining = remaining.slice(index + match[1].length);\n regex.lastIndex = 0;\n }\n if (remaining.length > 0) {\n result.push(remaining);\n }\n return result;\n }\n\n // text是ReactNode时,不处理高亮\n const highlightedText = (text: number | string | React.ReactNode): React.ReactNode => {\n if (highlight && (typeof text === 'string' || typeof text === 'number')) {\n return splitString(text.toString(), highlight).map((part, index) => {\n if (part.toUpperCase() === highlight.toUpperCase()) {\n return (\n <span key={index} style={{ color: '#ffb401' }}>\n {part}\n </span>\n );\n } else {\n return <span key={index}>{part}</span>;\n }\n });\n } else {\n return text;\n }\n };\n\n // 处理宽度值,确保字符串数字能正确转换为带单位的 CSS 值\n const formatWidth = (value: number | string): number | string => {\n if (typeof value === 'string' && /^\\d+$/.test(value)) {\n // 如果是纯数字字符串,添加 px 单位\n return `${value}px`;\n }\n return value;\n };\n\n return (\n <Tooltip\n open={showTooltip}\n title={text}\n placement={placement}\n arrow={arrow}\n destroyOnHidden={true}\n color={color ? color : '#fff'}\n styles={styles ? styles : { body: { color: '#333', fontSize: 12 } }}\n {...(zIndex ? { zIndex } : {})}\n >\n <span\n ref={textRef}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={() => setShowTooltip(false)}\n className={className}\n style={{\n display: 'inline-block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom',\n ...style,\n ...(maxWidth ? { maxWidth: formatWidth(maxWidth) } : { width: formatWidth(width) }),\n }}\n >\n {highlightedText(text)}\n </span>\n </Tooltip>\n );\n};\n\nexport default TextWithTooltip;\n"],
5
+ "mappings": "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",
6
6
  "names": ["text", "React"]
7
7
  }
@@ -1,28 +1,5 @@
1
- /**
2
- * TreeTransferPanel
3
- *
4
- * 树形穿梭框单侧面板:搜索框 + 树形表格 + 分页器。
5
- *
6
- * @example
7
- * ```tsx
8
- * <TreeTransferPanel
9
- * dataSource={data}
10
- * selectedRowKeys={selectedKeys}
11
- * onRowSelect={handleRowSelect}
12
- * searchValue={searchValue}
13
- * setSearchValue={setSearchValue}
14
- * totalCount={totalCount}
15
- * title="待分配项"
16
- * showPagination={true}
17
- * currentPage={currentPage}
18
- * pageSize={20}
19
- * onPageChange={handlePageChange}
20
- * columns={customColumns}
21
- * />
22
- * ```
23
- */
24
1
  import React from 'react';
25
- import { TreeTransferPanelProps } from '../../types';
2
+ import { type TreeTransferPanelProps } from '../../types';
26
3
  import './index.less';
27
4
  declare const TreeTransferPanel: <T>({ dataSource, selectedRowKeys, onRowSelect, searchValue, setSearchValue, totalCount, title, showPagination, currentPage, pageSize, onPageChange, columns: customColumns, customRender, searchPlaceholder, }: TreeTransferPanelProps<T>) => React.JSX.Element;
28
5
  export default TreeTransferPanel;
@@ -32,9 +32,9 @@ __export(TreeTransferPanel_exports, {
32
32
  default: () => TreeTransferPanel_default
33
33
  });
34
34
  module.exports = __toCommonJS(TreeTransferPanel_exports);
35
- var import_react = __toESM(require("react"));
36
- var import_antd = require("antd");
37
35
  var import_icons = require("@ant-design/icons");
36
+ var import_antd = require("antd");
37
+ var import_react = __toESM(require("react"));
38
38
  var import_types = require("../../types");
39
39
  var import_index = require("./index.less");
40
40
  var { Text } = import_antd.Typography;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/components/TreeTransfer/components/TreeTransferPanel/index.tsx"],
4
- "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransferPanel\n *\n * 树形穿梭框单侧面板:搜索框 + 树形表格 + 分页器。\n *\n * @example\n * ```tsx\n * <TreeTransferPanel\n * dataSource={data}\n * selectedRowKeys={selectedKeys}\n * onRowSelect={handleRowSelect}\n * searchValue={searchValue}\n * setSearchValue={setSearchValue}\n * totalCount={totalCount}\n * title=\"待分配项\"\n * showPagination={true}\n * currentPage={currentPage}\n * pageSize={20}\n * onPageChange={handlePageChange}\n * columns={customColumns}\n * />\n * ```\n */\n\nimport React, { useMemo, useRef, useState, useEffect, useCallback } from 'react';\nimport { Table, Input, Empty, Pagination, Typography, Tooltip } from 'antd';\nimport type { ColumnsType } from 'antd/es/table';\nimport { SearchOutlined } from '@ant-design/icons';\nimport { TreeTransferPanelProps, TreeTransferRow, DEFAULT_PAGE_SIZE } from '../../types';\nimport './index.less';\n\nconst { Text } = Typography;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 固定元素高度常量(与 CSS 保持一致)\n// ─────────────────────────────────────────────────────────────────────────────\nconst HEADER_HEIGHT = 34; // .tree-transfer-panel-header padding + border\nconst SEARCH_HEIGHT = 44; // .tree-transfer-panel-search padding + input\nconst PAGINATION_HEIGHT = 36; // .tree-transfer-panel-pagination\nconst MARGIN = 8; // 底部预留间距\nconst EXTRA_PADDING = 60; // 最后一行防遮挡预留空间\nconst MIN_SCROLL_Y = 100; // 表格最小可见高度(px)\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransferPanel\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst TreeTransferPanel = <T,>({\n dataSource,\n selectedRowKeys,\n onRowSelect,\n searchValue,\n setSearchValue,\n totalCount,\n title,\n showPagination = false,\n currentPage = 1,\n pageSize = DEFAULT_PAGE_SIZE,\n onPageChange,\n columns: customColumns,\n customRender,\n searchPlaceholder,\n}: TreeTransferPanelProps<T>) => {\n const panelRef = useRef<HTMLDivElement>(null);\n\n // 表格滚动高度(undefined 表示尚未计算完成,Table 自适应)\n const [tableScrollY, setTableScrollY] = useState<number | undefined>(undefined);\n\n // ── 动态计算表格可滚动高度 ─────────────────────────────────────────────────\n //\n // 计算逻辑:面板总高 - 固定头部/搜索/分页区域高度 = 表格可用高度。\n //\n // 修复说明:\n // 1. 初始值改为 undefined,避免 Table 短暂以 scroll.y=0 渲染导致高度坍塌。\n // 2. MutationObserver 回调中原使用 setTimeout(fn, 150),每次 DOM 变化都会\n // 入队新定时器;树形展开时大量 mutation 会堆积数十个 timer。\n // 修复:改用 requestAnimationFrame,每次只在下一帧执行一次计算。\n // 3. 移除 `dataSource` 出 deps:dataSource 每次 render 都是新数组引用,\n // 导致 observer 被频繁拆卸/重建。表格内容的 DOM 变化已由 MutationObserver 捕获,\n // 无需在数据变化时重建整个 effect。\n //\n useEffect(() => {\n if (!panelRef.current) return undefined;\n\n let rafId: number;\n\n const calculateScrollHeight = () => {\n const panelHeight = panelRef.current?.clientHeight ?? 0;\n const paginationOffset = showPagination ? PAGINATION_HEIGHT : 0;\n const available = panelHeight - HEADER_HEIGHT - SEARCH_HEIGHT - paginationOffset - MARGIN - EXTRA_PADDING;\n setTableScrollY(Math.max(available, MIN_SCROLL_Y));\n };\n\n const scheduleCalc = () => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(calculateScrollHeight);\n };\n\n // 初次计算\n scheduleCalc();\n\n // 监听面板容器尺寸(窗口 resize、flex 布局变化等)\n const resizeObserver = new ResizeObserver(scheduleCalc);\n resizeObserver.observe(panelRef.current);\n\n // 监听表格 DOM 变化(树形行展开 / 收起会增删行节点)\n const mutationObserver = new MutationObserver(scheduleCalc);\n const tableBody = panelRef.current.querySelector('.ant-table-tbody');\n if (tableBody) {\n mutationObserver.observe(tableBody, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n });\n }\n\n return () => {\n cancelAnimationFrame(rafId);\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n }, [showPagination]); // 只在 showPagination 变化时重建(影响固定高度计算)\n\n // ── 默认列配置 ─────────────────────────────────────────────────────────────\n // 第一列:父节点显示 ID,子节点合并到名称列(colSpan:0)\n // 第二列:名称列,子节点 colSpan:2 占满整行\n const defaultColumns: ColumnsType<TreeTransferRow<T>> = useMemo(\n () => [\n {\n title: 'ID',\n dataIndex: 'key',\n key: 'id',\n width: '35%',\n onCell: (record: TreeTransferRow<T>) => (record.isParent ? {} : { colSpan: 0 }),\n render: (_: unknown, record: TreeTransferRow<T>) => (record.isParent ? String(record.key) : ''),\n },\n {\n title: '名称',\n dataIndex: 'data',\n key: 'name',\n width: '65%',\n ellipsis: { showTitle: false },\n onCell: (record: TreeTransferRow<T>) => {\n if (!record.isParent) return { colSpan: 2 };\n return customRender?.onCell ? customRender.onCell(record) : {};\n },\n render: (_: unknown, record: TreeTransferRow<T>, index: number) => {\n if (customRender?.cellRender) return customRender.cellRender(_, record, index);\n const content = JSON.stringify(record.data);\n if (content.length > 20) {\n return (\n <Tooltip placement='topLeft' title={content}>\n {content}\n </Tooltip>\n );\n }\n return content;\n },\n },\n ],\n [customRender],\n );\n\n // 优先使用调用方传入的列配置\n const columns = customColumns ?? defaultColumns;\n\n // ── 行选择配置 ─────────────────────────────────────────────────────────────\n // checkStrictly:false — 选中父节点时自动全选子节点\n const rowSelection = useMemo(\n () => ({\n selectedRowKeys,\n onChange: (selectedKeys: React.Key[], selectedRows: TreeTransferRow<T>[]) => {\n onRowSelect(selectedRows, selectedKeys);\n },\n checkStrictly: false,\n columnWidth: 50,\n }),\n [selectedRowKeys, onRowSelect],\n );\n\n // ── 搜索框 onChange ────────────────────────────────────────────────────────\n const handleSearchChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => setSearchValue(e.target.value),\n [setSearchValue],\n );\n\n // ── 渲染 ──────────────────────────────────────────────────────────────────\n\n return (\n <div ref={panelRef} className='tree-transfer-panel'>\n {/* 头部:标题和数量 */}\n <div className='tree-transfer-panel-header'>\n <Text>{title}</Text>\n <Text type='secondary'>({totalCount})</Text>\n </div>\n\n {/* 搜索框 */}\n <div className='tree-transfer-panel-search'>\n <Input\n placeholder={searchPlaceholder ?? '搜索'}\n prefix={<SearchOutlined />}\n value={searchValue}\n onChange={handleSearchChange}\n allowClear\n />\n </div>\n\n {/* 表格内容区域 */}\n <div className='tree-transfer-panel-content'>\n {dataSource.length > 0 ? (\n <Table\n rowKey='key'\n columns={columns}\n dataSource={dataSource}\n rowSelection={rowSelection}\n expandable={{\n childrenColumnName: 'children',\n defaultExpandAllRows: true,\n indentSize: 30,\n }}\n pagination={false}\n size='small'\n className='tree-transfer-table'\n // tableScrollY 未计算完成时不传 y,Table 自适应高度,避免初始高度坍塌\n scroll={tableScrollY !== undefined ? { y: tableScrollY } : undefined}\n />\n ) : (\n <Empty description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </div>\n\n {/* 分页器:数据超过 1 页才显示 */}\n {showPagination && onPageChange && totalCount > pageSize && (\n <div className='tree-transfer-panel-pagination'>\n <Pagination\n current={currentPage}\n pageSize={pageSize}\n total={totalCount}\n showSizeChanger={false}\n showQuickJumper={false}\n showTitle={false}\n onChange={onPageChange}\n size='small'\n simple\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default TreeTransferPanel;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransferPanel\n *\n * 树形穿梭框单侧面板:搜索框 + 树形表格 + 分页器。\n *\n * @example\n * ```tsx\n * <TreeTransferPanel\n * dataSource={data}\n * selectedRowKeys={selectedKeys}\n * onRowSelect={handleRowSelect}\n * searchValue={searchValue}\n * setSearchValue={setSearchValue}\n * totalCount={totalCount}\n * title=\"待分配项\"\n * showPagination={true}\n * currentPage={currentPage}\n * pageSize={20}\n * onPageChange={handlePageChange}\n * columns={customColumns}\n * />\n * ```\n */\n\nimport { SearchOutlined } from '@ant-design/icons';\nimport { Empty, Input, Pagination, Table, Tooltip, Typography } from 'antd';\nimport type { ColumnsType } from 'antd/es/table';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { DEFAULT_PAGE_SIZE, type TreeTransferPanelProps, type TreeTransferRow } from '../../types';\nimport './index.less';\n\nconst { Text } = Typography;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// 固定元素高度常量(与 CSS 保持一致)\n// ─────────────────────────────────────────────────────────────────────────────\nconst HEADER_HEIGHT = 34; // .tree-transfer-panel-header padding + border\nconst SEARCH_HEIGHT = 44; // .tree-transfer-panel-search padding + input\nconst PAGINATION_HEIGHT = 36; // .tree-transfer-panel-pagination\nconst MARGIN = 8; // 底部预留间距\nconst EXTRA_PADDING = 60; // 最后一行防遮挡预留空间\nconst MIN_SCROLL_Y = 100; // 表格最小可见高度(px)\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransferPanel\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst TreeTransferPanel = <T,>({\n dataSource,\n selectedRowKeys,\n onRowSelect,\n searchValue,\n setSearchValue,\n totalCount,\n title,\n showPagination = false,\n currentPage = 1,\n pageSize = DEFAULT_PAGE_SIZE,\n onPageChange,\n columns: customColumns,\n customRender,\n searchPlaceholder,\n}: TreeTransferPanelProps<T>) => {\n const panelRef = useRef<HTMLDivElement>(null);\n\n // 表格滚动高度(undefined 表示尚未计算完成,Table 自适应)\n const [tableScrollY, setTableScrollY] = useState<number | undefined>(undefined);\n\n // ── 动态计算表格可滚动高度 ─────────────────────────────────────────────────\n //\n // 计算逻辑:面板总高 - 固定头部/搜索/分页区域高度 = 表格可用高度。\n //\n // 修复说明:\n // 1. 初始值改为 undefined,避免 Table 短暂以 scroll.y=0 渲染导致高度坍塌。\n // 2. MutationObserver 回调中原使用 setTimeout(fn, 150),每次 DOM 变化都会\n // 入队新定时器;树形展开时大量 mutation 会堆积数十个 timer。\n // 修复:改用 requestAnimationFrame,每次只在下一帧执行一次计算。\n // 3. 移除 `dataSource` 出 deps:dataSource 每次 render 都是新数组引用,\n // 导致 observer 被频繁拆卸/重建。表格内容的 DOM 变化已由 MutationObserver 捕获,\n // 无需在数据变化时重建整个 effect。\n //\n useEffect(() => {\n if (!panelRef.current) return undefined;\n\n let rafId: number;\n\n const calculateScrollHeight = () => {\n const panelHeight = panelRef.current?.clientHeight ?? 0;\n const paginationOffset = showPagination ? PAGINATION_HEIGHT : 0;\n const available = panelHeight - HEADER_HEIGHT - SEARCH_HEIGHT - paginationOffset - MARGIN - EXTRA_PADDING;\n setTableScrollY(Math.max(available, MIN_SCROLL_Y));\n };\n\n const scheduleCalc = () => {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(calculateScrollHeight);\n };\n\n // 初次计算\n scheduleCalc();\n\n // 监听面板容器尺寸(窗口 resize、flex 布局变化等)\n const resizeObserver = new ResizeObserver(scheduleCalc);\n resizeObserver.observe(panelRef.current);\n\n // 监听表格 DOM 变化(树形行展开 / 收起会增删行节点)\n const mutationObserver = new MutationObserver(scheduleCalc);\n const tableBody = panelRef.current.querySelector('.ant-table-tbody');\n if (tableBody) {\n mutationObserver.observe(tableBody, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['class'],\n });\n }\n\n return () => {\n cancelAnimationFrame(rafId);\n resizeObserver.disconnect();\n mutationObserver.disconnect();\n };\n }, [showPagination]); // 只在 showPagination 变化时重建(影响固定高度计算)\n\n // ── 默认列配置 ─────────────────────────────────────────────────────────────\n // 第一列:父节点显示 ID,子节点合并到名称列(colSpan:0)\n // 第二列:名称列,子节点 colSpan:2 占满整行\n const defaultColumns: ColumnsType<TreeTransferRow<T>> = useMemo(\n () => [\n {\n title: 'ID',\n dataIndex: 'key',\n key: 'id',\n width: '35%',\n onCell: (record: TreeTransferRow<T>) => (record.isParent ? {} : { colSpan: 0 }),\n render: (_: unknown, record: TreeTransferRow<T>) => (record.isParent ? String(record.key) : ''),\n },\n {\n title: '名称',\n dataIndex: 'data',\n key: 'name',\n width: '65%',\n ellipsis: { showTitle: false },\n onCell: (record: TreeTransferRow<T>) => {\n if (!record.isParent) return { colSpan: 2 };\n return customRender?.onCell ? customRender.onCell(record) : {};\n },\n render: (_: unknown, record: TreeTransferRow<T>, index: number) => {\n if (customRender?.cellRender) return customRender.cellRender(_, record, index);\n const content = JSON.stringify(record.data);\n if (content.length > 20) {\n return (\n <Tooltip placement='topLeft' title={content}>\n {content}\n </Tooltip>\n );\n }\n return content;\n },\n },\n ],\n [customRender],\n );\n\n // 优先使用调用方传入的列配置\n const columns = customColumns ?? defaultColumns;\n\n // ── 行选择配置 ─────────────────────────────────────────────────────────────\n // checkStrictly:false — 选中父节点时自动全选子节点\n const rowSelection = useMemo(\n () => ({\n selectedRowKeys,\n onChange: (selectedKeys: React.Key[], selectedRows: TreeTransferRow<T>[]) => {\n onRowSelect(selectedRows, selectedKeys);\n },\n checkStrictly: false,\n columnWidth: 50,\n }),\n [selectedRowKeys, onRowSelect],\n );\n\n // ── 搜索框 onChange ────────────────────────────────────────────────────────\n const handleSearchChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => setSearchValue(e.target.value),\n [setSearchValue],\n );\n\n // ── 渲染 ──────────────────────────────────────────────────────────────────\n\n return (\n <div ref={panelRef} className='tree-transfer-panel'>\n {/* 头部:标题和数量 */}\n <div className='tree-transfer-panel-header'>\n <Text>{title}</Text>\n <Text type='secondary'>({totalCount})</Text>\n </div>\n\n {/* 搜索框 */}\n <div className='tree-transfer-panel-search'>\n <Input\n placeholder={searchPlaceholder ?? '搜索'}\n prefix={<SearchOutlined />}\n value={searchValue}\n onChange={handleSearchChange}\n allowClear\n />\n </div>\n\n {/* 表格内容区域 */}\n <div className='tree-transfer-panel-content'>\n {dataSource.length > 0 ? (\n <Table\n rowKey='key'\n columns={columns}\n dataSource={dataSource}\n rowSelection={rowSelection}\n expandable={{\n childrenColumnName: 'children',\n defaultExpandAllRows: true,\n indentSize: 30,\n }}\n pagination={false}\n size='small'\n className='tree-transfer-table'\n // tableScrollY 未计算完成时不传 y,Table 自适应高度,避免初始高度坍塌\n scroll={tableScrollY !== undefined ? { y: tableScrollY } : undefined}\n />\n ) : (\n <Empty description='暂无数据' image={Empty.PRESENTED_IMAGE_SIMPLE} />\n )}\n </div>\n\n {/* 分页器:数据超过 1 页才显示 */}\n {showPagination && onPageChange && totalCount > pageSize && (\n <div className='tree-transfer-panel-pagination'>\n <Pagination\n current={currentPage}\n pageSize={pageSize}\n total={totalCount}\n showSizeChanger={false}\n showQuickJumper={false}\n showTitle={false}\n onChange={onPageChange}\n size='small'\n simple\n />\n </div>\n )}\n </div>\n );\n};\n\nexport default TreeTransferPanel;\n"],
5
+ "mappings": "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",
6
6
  "names": ["React"]
7
7
  }
@@ -1,28 +1,5 @@
1
- /**
2
- * TreeTransfer
3
- *
4
- * 树形表格穿梭框组件。支持:
5
- * - 树形结构展示,父子联动选择(checkStrictly: false)
6
- * - 前端分页 + 防抖搜索
7
- * - 左右穿梭操作(含多级树正确迁移)
8
- * - 自定义列配置和渲染
9
- * - 完整的 TypeScript 泛型支持
10
- *
11
- * @template T - 行数据的自定义业务类型
12
- *
13
- * @example
14
- * ```tsx
15
- * <TreeTransfer
16
- * leftDataSource={leftData}
17
- * rightDataSource={rightData}
18
- * leftTitle="待分配"
19
- * rightTitle="已分配"
20
- * onChange={({ leftData, rightData }) => { ... }}
21
- * />
22
- * ```
23
- */
24
1
  import React from 'react';
25
- import { TreeTransferProps } from './types';
2
+ import { type TreeTransferProps } from './types';
26
3
  import './index.less';
27
4
  declare function TreeTransfer<T>({ leftDataSource, rightDataSource, loading, leftTitle, rightTitle, pageSize, columns, customRender, searchFields, searchPlaceholder, onChange, }: TreeTransferProps<T>): React.JSX.Element;
28
5
  export default TreeTransfer;
@@ -32,12 +32,12 @@ __export(TreeTransfer_exports, {
32
32
  default: () => TreeTransfer_default
33
33
  });
34
34
  module.exports = __toCommonJS(TreeTransfer_exports);
35
- var import_react = __toESM(require("react"));
36
- var import_antd = require("antd");
37
35
  var import_icons = require("@ant-design/icons");
36
+ var import_antd = require("antd");
37
+ var import_react = __toESM(require("react"));
38
+ var import_TreeTransferPanel = __toESM(require("./components/TreeTransferPanel"));
38
39
  var import_types = require("./types");
39
40
  var import_utils = require("./utils");
40
- var import_TreeTransferPanel = __toESM(require("./components/TreeTransferPanel"));
41
41
  var import_index = require("./index.less");
42
42
  function useDebounce(callback, delay) {
43
43
  const callbackRef = (0, import_react.useRef)(callback);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/TreeTransfer/index.tsx"],
4
- "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransfer\n *\n * 树形表格穿梭框组件。支持:\n * - 树形结构展示,父子联动选择(checkStrictly: false)\n * - 前端分页 + 防抖搜索\n * - 左右穿梭操作(含多级树正确迁移)\n * - 自定义列配置和渲染\n * - 完整的 TypeScript 泛型支持\n *\n * @template T - 行数据的自定义业务类型\n *\n * @example\n * ```tsx\n * <TreeTransfer\n * leftDataSource={leftData}\n * rightDataSource={rightData}\n * leftTitle=\"待分配\"\n * rightTitle=\"已分配\"\n * onChange={({ leftData, rightData }) => { ... }}\n * />\n * ```\n */\n\nimport React, { useState, useMemo, useCallback, useEffect, useRef } from 'react';\nimport { Spin, Button, Space } from 'antd';\nimport { RightOutlined, LeftOutlined } from '@ant-design/icons';\nimport { TreeTransferProps, DEFAULT_PAGE_SIZE } from './types';\nimport {\n sliceDataByPage,\n filterData,\n getAllDescendantKeys,\n removeNodesFromTree,\n addNodesToTree,\n countParentNodes,\n extractTopLevelSelectedNodes,\n} from './utils';\nimport TreeTransferPanel from './components/TreeTransferPanel';\nimport './index.less';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useDebounce\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 防抖 Hook\n *\n * 修复说明:\n * 原实现将 `callback` 放入 `useCallback` 的 deps,导致每次渲染(callback 为\n * 新引用)都重新创建防抖函数,使 timeout 重置,防抖完全失效。\n * 修复方案:将最新 callback 存入 ref,useCallback 仅依赖 delay,保证\n * 防抖函数引用稳定,timeout 不被意外清除。\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number): T {\n // 存储最新 callback,避免 stale closure\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n return useCallback(\n (...args: Parameters<T>) => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);\n },\n [delay], // callback 通过 ref 读取,不需要放入 deps\n ) as T;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransfer\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 面板选择/分页状态(不含 dataSource,数据源来自 props + memo 计算)\n */\ninterface PanelState {\n selectedRowKeys: React.Key[];\n searchValue: string;\n currentPage: number;\n totalCount: number;\n}\n\nfunction TreeTransfer<T>({\n leftDataSource,\n rightDataSource,\n loading = false,\n leftTitle = '待分配项',\n rightTitle = '已分配项',\n pageSize = DEFAULT_PAGE_SIZE,\n columns,\n customRender,\n searchFields,\n searchPlaceholder,\n onChange,\n}: TreeTransferProps<T>) {\n // ── 面板状态(选择、搜索、分页) ─────────────────────────────────────────────\n // 注意:dataSource 不存储在 state 中;显示数据通过 memo 从 props 实时计算,\n // 避免 state 与 props 不同步的问题。\n const [leftPanel, setLeftPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n const [rightPanel, setRightPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n // ── 过滤后的完整数据(先 filter,再由 slice 分页) ──────────────────────────\n // 合并 filter + count,避免对同一搜索词调用两次 filterData(原来的问题)。\n\n const filteredLeft = useMemo(\n () => filterData<T>(leftDataSource, leftPanel.searchValue, searchFields),\n [leftDataSource, leftPanel.searchValue, searchFields],\n );\n\n const filteredRight = useMemo(\n () => filterData<T>(rightDataSource, rightPanel.searchValue, searchFields),\n [rightDataSource, rightPanel.searchValue, searchFields],\n );\n\n /** 当前页展示数据(供左侧面板渲染) */\n const filteredLeftData = useMemo(\n () => sliceDataByPage<T>(filteredLeft, leftPanel.currentPage, pageSize),\n [filteredLeft, leftPanel.currentPage, pageSize],\n );\n\n /** 当前页展示数据(供右侧面板渲染) */\n const filteredRightData = useMemo(\n () => sliceDataByPage<T>(filteredRight, rightPanel.currentPage, pageSize),\n [filteredRight, rightPanel.currentPage, pageSize],\n );\n\n /** 搜索后的顶层节点数(用于分页器 total) */\n const filteredLeftTotalCount = useMemo(() => countParentNodes(filteredLeft), [filteredLeft]);\n const filteredRightTotalCount = useMemo(() => countParentNodes(filteredRight), [filteredRight]);\n\n // ── 数据源变化时更新 totalCount,同时重置到第 1 页 ──────────────────────────\n useEffect(() => {\n setLeftPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(leftDataSource),\n }));\n }, [leftDataSource]);\n\n useEffect(() => {\n setRightPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(rightDataSource),\n }));\n }, [rightDataSource]);\n\n // ── 防抖搜索 ─────────────────────────────────────────────────────────────────\n\n const handleLeftSearchChange = useDebounce((value: string) => {\n setLeftPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n const handleRightSearchChange = useDebounce((value: string) => {\n setRightPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n // ── 分页 ─────────────────────────────────────────────────────────────────────\n\n const handleLeftPageChange = useCallback((page: number) => {\n setLeftPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n const handleRightPageChange = useCallback((page: number) => {\n setRightPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n // ── 穿梭操作 ─────────────────────────────────────────────────────────────────\n\n /**\n * 右移:将左侧选中项移到右侧\n *\n * 修复说明:\n * 原实现通过 `dataSource.filter(item => item.key === key)` 只查根节点,\n * 导致仅选中子节点时 nodesToAdd 为空,数据静默丢失。\n * 修复:使用 `extractTopLevelSelectedNodes` 递归提取选中的顶层节点(含 children)。\n */\n const handleMoveRight = useCallback(() => {\n if (leftPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(leftPanel.selectedRowKeys.map(String));\n // 提取选中的顶层节点(子节点随父一起携带)\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, leftDataSource);\n // 删除所有相关 key(含后代)\n const keysToRemove = new Set(getAllDescendantKeys(leftPanel.selectedRowKeys, leftDataSource));\n const newLeftData = removeNodesFromTree(leftDataSource, keysToRemove);\n const newRightData = addNodesToTree(rightDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [leftPanel.selectedRowKeys, leftDataSource, rightDataSource, onChange]);\n\n /**\n * 左移:将右侧选中项移到左侧\n */\n const handleMoveLeft = useCallback(() => {\n if (rightPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(rightPanel.selectedRowKeys.map(String));\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, rightDataSource);\n const keysToRemove = new Set(getAllDescendantKeys(rightPanel.selectedRowKeys, rightDataSource));\n const newRightData = removeNodesFromTree(rightDataSource, keysToRemove);\n const newLeftData = addNodesToTree(leftDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [rightPanel.selectedRowKeys, rightDataSource, leftDataSource, onChange]);\n\n // ── 渲染 ─────────────────────────────────────────────────────────────────────\n\n return (\n <div className='tree-transfer-wrapper'>\n <Spin spinning={loading}>\n <div className='tree-transfer-content'>\n {/* 左侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredLeftData}\n selectedRowKeys={leftPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setLeftPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={leftPanel.searchValue}\n setSearchValue={handleLeftSearchChange}\n totalCount={leftPanel.searchValue ? filteredLeftTotalCount : leftPanel.totalCount}\n title={leftTitle}\n showPagination={true}\n currentPage={leftPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleLeftPageChange}\n columns={columns}\n customRender={customRender}\n searchPlaceholder={searchPlaceholder}\n />\n\n {/* 中间操作按钮 */}\n <div className='tree-transfer-operations'>\n <Space direction='vertical' size={8}>\n <Button\n className='tree-transfer-operation-btn'\n type={leftPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<RightOutlined />}\n onClick={handleMoveRight}\n disabled={leftPanel.selectedRowKeys.length === 0}\n />\n <Button\n className='tree-transfer-operation-btn'\n type={rightPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<LeftOutlined />}\n onClick={handleMoveLeft}\n disabled={rightPanel.selectedRowKeys.length === 0}\n />\n </Space>\n </div>\n\n {/* 右侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredRightData}\n selectedRowKeys={rightPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setRightPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={rightPanel.searchValue}\n setSearchValue={handleRightSearchChange}\n totalCount={rightPanel.searchValue ? filteredRightTotalCount : rightPanel.totalCount}\n title={rightTitle}\n showPagination={true}\n currentPage={rightPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleRightPageChange}\n columns={columns}\n customRender={customRender}\n />\n </div>\n </Spin>\n </div>\n );\n}\n\nexport default TreeTransfer;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransfer\n *\n * 树形表格穿梭框组件。支持:\n * - 树形结构展示,父子联动选择(checkStrictly: false)\n * - 前端分页 + 防抖搜索\n * - 左右穿梭操作(含多级树正确迁移)\n * - 自定义列配置和渲染\n * - 完整的 TypeScript 泛型支持\n *\n * @template T - 行数据的自定义业务类型\n *\n * @example\n * ```tsx\n * <TreeTransfer\n * leftDataSource={leftData}\n * rightDataSource={rightData}\n * leftTitle=\"待分配\"\n * rightTitle=\"已分配\"\n * onChange={({ leftData, rightData }) => { ... }}\n * />\n * ```\n */\n\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\nimport { Button, Space, Spin } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport TreeTransferPanel from './components/TreeTransferPanel';\nimport { DEFAULT_PAGE_SIZE, type TreeTransferProps } from './types';\nimport {\n addNodesToTree,\n countParentNodes,\n extractTopLevelSelectedNodes,\n filterData,\n getAllDescendantKeys,\n removeNodesFromTree,\n sliceDataByPage,\n} from './utils';\nimport './index.less';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useDebounce\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 防抖 Hook\n *\n * 修复说明:\n * 原实现将 `callback` 放入 `useCallback` 的 deps,导致每次渲染(callback 为\n * 新引用)都重新创建防抖函数,使 timeout 重置,防抖完全失效。\n * 修复方案:将最新 callback 存入 ref,useCallback 仅依赖 delay,保证\n * 防抖函数引用稳定,timeout 不被意外清除。\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number): T {\n // 存储最新 callback,避免 stale closure\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n return useCallback(\n (...args: Parameters<T>) => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);\n },\n [delay], // callback 通过 ref 读取,不需要放入 deps\n ) as T;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransfer\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 面板选择/分页状态(不含 dataSource,数据源来自 props + memo 计算)\n */\ninterface PanelState {\n selectedRowKeys: React.Key[];\n searchValue: string;\n currentPage: number;\n totalCount: number;\n}\n\nfunction TreeTransfer<T>({\n leftDataSource,\n rightDataSource,\n loading = false,\n leftTitle = '待分配项',\n rightTitle = '已分配项',\n pageSize = DEFAULT_PAGE_SIZE,\n columns,\n customRender,\n searchFields,\n searchPlaceholder,\n onChange,\n}: TreeTransferProps<T>) {\n // ── 面板状态(选择、搜索、分页) ─────────────────────────────────────────────\n // 注意:dataSource 不存储在 state 中;显示数据通过 memo 从 props 实时计算,\n // 避免 state 与 props 不同步的问题。\n const [leftPanel, setLeftPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n const [rightPanel, setRightPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n // ── 过滤后的完整数据(先 filter,再由 slice 分页) ──────────────────────────\n // 合并 filter + count,避免对同一搜索词调用两次 filterData(原来的问题)。\n\n const filteredLeft = useMemo(\n () => filterData<T>(leftDataSource, leftPanel.searchValue, searchFields),\n [leftDataSource, leftPanel.searchValue, searchFields],\n );\n\n const filteredRight = useMemo(\n () => filterData<T>(rightDataSource, rightPanel.searchValue, searchFields),\n [rightDataSource, rightPanel.searchValue, searchFields],\n );\n\n /** 当前页展示数据(供左侧面板渲染) */\n const filteredLeftData = useMemo(\n () => sliceDataByPage<T>(filteredLeft, leftPanel.currentPage, pageSize),\n [filteredLeft, leftPanel.currentPage, pageSize],\n );\n\n /** 当前页展示数据(供右侧面板渲染) */\n const filteredRightData = useMemo(\n () => sliceDataByPage<T>(filteredRight, rightPanel.currentPage, pageSize),\n [filteredRight, rightPanel.currentPage, pageSize],\n );\n\n /** 搜索后的顶层节点数(用于分页器 total) */\n const filteredLeftTotalCount = useMemo(() => countParentNodes(filteredLeft), [filteredLeft]);\n const filteredRightTotalCount = useMemo(() => countParentNodes(filteredRight), [filteredRight]);\n\n // ── 数据源变化时更新 totalCount,同时重置到第 1 页 ──────────────────────────\n useEffect(() => {\n setLeftPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(leftDataSource),\n }));\n }, [leftDataSource]);\n\n useEffect(() => {\n setRightPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(rightDataSource),\n }));\n }, [rightDataSource]);\n\n // ── 防抖搜索 ─────────────────────────────────────────────────────────────────\n\n const handleLeftSearchChange = useDebounce((value: string) => {\n setLeftPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n const handleRightSearchChange = useDebounce((value: string) => {\n setRightPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n // ── 分页 ─────────────────────────────────────────────────────────────────────\n\n const handleLeftPageChange = useCallback((page: number) => {\n setLeftPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n const handleRightPageChange = useCallback((page: number) => {\n setRightPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n // ── 穿梭操作 ─────────────────────────────────────────────────────────────────\n\n /**\n * 右移:将左侧选中项移到右侧\n *\n * 修复说明:\n * 原实现通过 `dataSource.filter(item => item.key === key)` 只查根节点,\n * 导致仅选中子节点时 nodesToAdd 为空,数据静默丢失。\n * 修复:使用 `extractTopLevelSelectedNodes` 递归提取选中的顶层节点(含 children)。\n */\n const handleMoveRight = useCallback(() => {\n if (leftPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(leftPanel.selectedRowKeys.map(String));\n // 提取选中的顶层节点(子节点随父一起携带)\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, leftDataSource);\n // 删除所有相关 key(含后代)\n const keysToRemove = new Set(getAllDescendantKeys(leftPanel.selectedRowKeys, leftDataSource));\n const newLeftData = removeNodesFromTree(leftDataSource, keysToRemove);\n const newRightData = addNodesToTree(rightDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [leftPanel.selectedRowKeys, leftDataSource, rightDataSource, onChange]);\n\n /**\n * 左移:将右侧选中项移到左侧\n */\n const handleMoveLeft = useCallback(() => {\n if (rightPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(rightPanel.selectedRowKeys.map(String));\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, rightDataSource);\n const keysToRemove = new Set(getAllDescendantKeys(rightPanel.selectedRowKeys, rightDataSource));\n const newRightData = removeNodesFromTree(rightDataSource, keysToRemove);\n const newLeftData = addNodesToTree(leftDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [rightPanel.selectedRowKeys, rightDataSource, leftDataSource, onChange]);\n\n // ── 渲染 ─────────────────────────────────────────────────────────────────────\n\n return (\n <div className='tree-transfer-wrapper'>\n <Spin spinning={loading}>\n <div className='tree-transfer-content'>\n {/* 左侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredLeftData}\n selectedRowKeys={leftPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setLeftPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={leftPanel.searchValue}\n setSearchValue={handleLeftSearchChange}\n totalCount={leftPanel.searchValue ? filteredLeftTotalCount : leftPanel.totalCount}\n title={leftTitle}\n showPagination={true}\n currentPage={leftPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleLeftPageChange}\n columns={columns}\n customRender={customRender}\n searchPlaceholder={searchPlaceholder}\n />\n\n {/* 中间操作按钮 */}\n <div className='tree-transfer-operations'>\n <Space direction='vertical' size={8}>\n <Button\n className='tree-transfer-operation-btn'\n type={leftPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<RightOutlined />}\n onClick={handleMoveRight}\n disabled={leftPanel.selectedRowKeys.length === 0}\n />\n <Button\n className='tree-transfer-operation-btn'\n type={rightPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<LeftOutlined />}\n onClick={handleMoveLeft}\n disabled={rightPanel.selectedRowKeys.length === 0}\n />\n </Space>\n </div>\n\n {/* 右侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredRightData}\n selectedRowKeys={rightPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setRightPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={rightPanel.searchValue}\n setSearchValue={handleRightSearchChange}\n totalCount={rightPanel.searchValue ? filteredRightTotalCount : rightPanel.totalCount}\n title={rightTitle}\n showPagination={true}\n currentPage={rightPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleRightPageChange}\n columns={columns}\n customRender={customRender}\n />\n </div>\n </Spin>\n </div>\n );\n}\n\nexport default TreeTransfer;\n"],
5
+ "mappings": "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",
6
6
  "names": ["React", "TreeTransferPanel"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { TreeTransferRow } from '../types';
2
+ import { type TreeTransferRow } from '../types';
3
3
  /**
4
4
  * 从平铺的数据构建树形结构
5
5
  *