taro-uno-ui 0.9.0 → 1.0.1

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 (312) hide show
  1. package/README.md +21 -0
  2. package/dist/js/{index-DffLRSro.js → index-CDFsvu80.js} +15369 -10741
  3. package/dist/js/index-CDFsvu80.js.map +1 -0
  4. package/dist/js/index-DFdcksbe.js.map +1 -1
  5. package/dist/js/index-DXRIkWX1.js.map +1 -1
  6. package/dist/js/{index-6NJ3A1Dn.js → index-JffnTUrv.js} +15430 -10801
  7. package/dist/js/index-JffnTUrv.js.map +1 -0
  8. package/dist/utils/http/request.d.ts +280 -0
  9. package/package.json +14 -10
  10. package/src/components/basic/Button/Button.tsx +53 -13
  11. package/src/components/basic/Button/Button.types.ts +45 -9
  12. package/src/components/basic/Divider/Divider.tsx +60 -29
  13. package/src/components/basic/Icon/Icon.data.ts +474 -0
  14. package/src/components/basic/Icon/Icon.test.tsx +2 -2
  15. package/src/components/basic/Icon/Icon.tsx +48 -35
  16. package/src/components/basic/Icon/IconManager.ts +229 -0
  17. package/src/components/basic/Text/Text.styles.ts +3 -3
  18. package/src/components/basic/Text/Text.types.ts +14 -4
  19. package/src/components/basic/Typography/Typography.styles.ts +10 -9
  20. package/src/components/basic/Typography/Typography.tsx +15 -13
  21. package/src/components/basic/Typography/Typography.types.ts +41 -41
  22. package/src/components/basic/Typography/index.tsx +1 -1
  23. package/src/components/basic/Video/Video.styles.ts +777 -0
  24. package/src/components/basic/Video/Video.test.tsx +490 -0
  25. package/src/components/basic/Video/Video.tsx +1468 -0
  26. package/src/components/basic/Video/Video.types.ts +500 -0
  27. package/src/components/basic/Video/index.tsx +26 -0
  28. package/src/components/basic/index.tsx +13 -15
  29. package/src/components/common/ErrorBoundary.tsx +1 -1
  30. package/src/components/common/LazyComponent.tsx +9 -8
  31. package/src/components/common/SecurityProvider.tsx +2 -14
  32. package/src/components/common/ThemeProvider.tsx +43 -56
  33. package/src/components/common/VirtualList.tsx +187 -205
  34. package/src/components/common/index.tsx +25 -0
  35. package/src/components/display/Avatar/Avatar.styles.ts +1 -1
  36. package/src/components/display/Avatar/Avatar.tsx +6 -19
  37. package/src/components/display/Avatar/Avatar.types.ts +1 -1
  38. package/src/components/display/Avatar/index.ts +1 -1
  39. package/src/components/display/Badge/Badge.tsx +3 -16
  40. package/src/components/display/Badge/Badge.types.ts +1 -1
  41. package/src/components/display/Badge/index.ts +1 -1
  42. package/src/components/display/Calendar/Calendar.styles.ts +36 -36
  43. package/src/components/display/Calendar/Calendar.test.tsx +27 -15
  44. package/src/components/display/Calendar/Calendar.tsx +56 -35
  45. package/src/components/display/Calendar/Calendar.types.ts +1 -1
  46. package/src/components/display/Calendar/index.ts +1 -1
  47. package/src/components/display/Card/Card.styles.ts +2 -2
  48. package/src/components/display/Card/Card.test.tsx +6 -4
  49. package/src/components/display/Card/Card.tsx +1 -1
  50. package/src/components/display/Card/Card.types.ts +4 -4
  51. package/src/components/display/Card/index.ts +1 -1
  52. package/src/components/display/Carousel/Carousel.styles.ts +31 -31
  53. package/src/components/display/Carousel/Carousel.tsx +34 -39
  54. package/src/components/display/Carousel/Carousel.types.ts +1 -1
  55. package/src/components/display/Carousel/index.ts +1 -1
  56. package/src/components/display/List/List.styles.ts +3 -3
  57. package/src/components/display/List/List.tsx +0 -1
  58. package/src/components/display/List/index.ts +1 -1
  59. package/src/components/display/Rate/Rate.styles.ts +5 -17
  60. package/src/components/display/Rate/Rate.tsx +6 -14
  61. package/src/components/display/Rate/Rate.types.ts +4 -3
  62. package/src/components/display/Rate/index.ts +3 -11
  63. package/src/components/display/Table/Table.test.tsx +2 -0
  64. package/src/components/display/Table/Table.tsx +3 -7
  65. package/src/components/display/Table/Table.types.ts +3 -2
  66. package/src/components/display/Tag/Tag.styles.ts +31 -31
  67. package/src/components/display/Tag/Tag.tsx +9 -26
  68. package/src/components/display/Tag/Tag.types.ts +1 -1
  69. package/src/components/display/Tag/index.ts +1 -1
  70. package/src/components/display/Timeline/Timeline.styles.ts +32 -32
  71. package/src/components/display/Timeline/Timeline.tsx +23 -42
  72. package/src/components/display/Timeline/Timeline.types.ts +1 -1
  73. package/src/components/display/Timeline/index.ts +1 -1
  74. package/src/components/display/index.tsx +33 -29
  75. package/src/components/feedback/Loading/Loading.tsx +6 -1
  76. package/src/components/feedback/Loading/index.ts +2 -5
  77. package/src/components/feedback/Message/Message.styles.ts +3 -3
  78. package/src/components/feedback/Message/index.ts +2 -5
  79. package/src/components/feedback/Modal/Modal.styles.ts +1 -1
  80. package/src/components/feedback/Modal/Modal.tsx +9 -31
  81. package/src/components/feedback/Modal/Modal.types.ts +12 -2
  82. package/src/components/feedback/Notification/Notification.styles.ts +49 -39
  83. package/src/components/feedback/Notification/Notification.test.tsx +1 -1
  84. package/src/components/feedback/Notification/Notification.tsx +97 -120
  85. package/src/components/feedback/Notification/Notification.types.ts +11 -8
  86. package/src/components/feedback/Notification/NotificationManager.tsx +135 -106
  87. package/src/components/feedback/Notification/index.ts +10 -3
  88. package/src/components/feedback/Notification/index.tsx +16 -26
  89. package/src/components/feedback/Progress/Progress.styles.ts +23 -14
  90. package/src/components/feedback/Progress/Progress.tsx +93 -113
  91. package/src/components/feedback/Progress/Progress.types.ts +1 -1
  92. package/src/components/feedback/Progress/index.ts +1 -1
  93. package/src/components/feedback/Progress/utils/animation.ts +12 -23
  94. package/src/components/feedback/Progress/utils/index.ts +2 -2
  95. package/src/components/feedback/Progress/utils/progress-calculator.ts +14 -32
  96. package/src/components/feedback/Result/Result.styles.ts +29 -29
  97. package/src/components/feedback/Result/Result.tsx +8 -20
  98. package/src/components/feedback/Result/Result.types.ts +7 -7
  99. package/src/components/feedback/Result/index.tsx +1 -1
  100. package/src/components/feedback/Toast/Toast.styles.ts +1 -1
  101. package/src/components/feedback/Toast/Toast.tsx +25 -13
  102. package/src/components/feedback/Tooltip/Tooltip.examples.tsx +21 -44
  103. package/src/components/feedback/Tooltip/Tooltip.styles.ts +16 -22
  104. package/src/components/feedback/Tooltip/Tooltip.test.tsx +1 -1
  105. package/src/components/feedback/Tooltip/Tooltip.tsx +65 -46
  106. package/src/components/feedback/Tooltip/Tooltip.types.ts +14 -20
  107. package/src/components/feedback/Tooltip/index.ts +1 -1
  108. package/src/components/feedback/Tooltip/index.tsx +12 -24
  109. package/src/components/feedback/index.tsx +54 -42
  110. package/src/components/form/Cascader/Cascader.styles.ts +2 -2
  111. package/src/components/form/Cascader/Cascader.tsx +84 -88
  112. package/src/components/form/Cascader/Cascader.types.ts +49 -50
  113. package/src/components/form/Cascader/hooks/useCascaderFieldNames.ts +11 -8
  114. package/src/components/form/Cascader/hooks/useCascaderOptions.ts +73 -55
  115. package/src/components/form/Cascader/hooks/useCascaderState.ts +31 -25
  116. package/src/components/form/Cascader/index.ts +1 -1
  117. package/src/components/form/Cascader/utils/formatDisplayValue.ts +4 -4
  118. package/src/components/form/Checkbox/Checkbox.styles.ts +83 -84
  119. package/src/components/form/Checkbox/Checkbox.tsx +2 -9
  120. package/src/components/form/Checkbox/CheckboxGroup.tsx +7 -7
  121. package/src/components/form/DatePicker/DatePicker.test.tsx +1 -1
  122. package/src/components/form/DatePicker/DatePicker.tsx +91 -75
  123. package/src/components/form/DatePicker/DatePicker.types.ts +4 -1
  124. package/src/components/form/Form/Form.tsx +66 -504
  125. package/src/components/form/Form/Form.types.ts +16 -1
  126. package/src/components/form/Form/useFormLogic.ts +497 -0
  127. package/src/components/form/Input/Input.styles.ts +8 -1
  128. package/src/components/form/Input/Input.tsx +55 -291
  129. package/src/components/form/Input/Input.types.ts +13 -1
  130. package/src/components/form/Input/useInputLogic.test.ts +82 -0
  131. package/src/components/form/Input/useInputLogic.ts +260 -0
  132. package/src/components/form/InputNumber/InputNumber.styles.ts +76 -25
  133. package/src/components/form/InputNumber/InputNumber.tsx +53 -21
  134. package/src/components/form/InputNumber/InputNumber.types.ts +21 -3
  135. package/src/components/form/InputNumber/components/InputNumberClearButton.tsx +3 -11
  136. package/src/components/form/InputNumber/components/InputNumberControls.tsx +3 -12
  137. package/src/components/form/InputNumber/hooks/index.ts +1 -1
  138. package/src/components/form/InputNumber/hooks/useInputNumberState.ts +7 -9
  139. package/src/components/form/InputNumber/hooks/useInputNumberValidation.ts +18 -17
  140. package/src/components/form/InputNumber/index.ts +7 -7
  141. package/src/components/form/Radio/Radio.styles.ts +1 -8
  142. package/src/components/form/Radio/Radio.tsx +3 -9
  143. package/src/components/form/Radio/Radio.types.ts +5 -1
  144. package/src/components/form/Select/Select.styles.ts +5 -1
  145. package/src/components/form/Select/Select.tsx +15 -15
  146. package/src/components/form/Select/Select.types.ts +2 -1
  147. package/src/components/form/Slider/Slider.styles.ts +13 -13
  148. package/src/components/form/Slider/Slider.tsx +19 -33
  149. package/src/components/form/Slider/Slider.types.ts +14 -12
  150. package/src/components/form/Slider/index.tsx +2 -9
  151. package/src/components/form/Switch/Switch.styles.ts +1 -7
  152. package/src/components/form/Switch/Switch.tsx +7 -13
  153. package/src/components/form/Textarea/Textarea.styles.ts +4 -4
  154. package/src/components/form/Textarea/Textarea.tsx +7 -1
  155. package/src/components/form/Textarea/Textarea.types.ts +4 -1
  156. package/src/components/form/TimePicker/TimePicker.styles.ts +8 -12
  157. package/src/components/form/TimePicker/TimePicker.tsx +122 -100
  158. package/src/components/form/TimePicker/TimePicker.types.ts +2 -2
  159. package/src/components/form/TimePicker/index.ts +1 -1
  160. package/src/components/form/Transfer/Transfer.styles.ts +3 -15
  161. package/src/components/form/Transfer/Transfer.tsx +146 -134
  162. package/src/components/form/Transfer/Transfer.types.ts +34 -26
  163. package/src/components/form/Transfer/components/TransferItem.tsx +55 -62
  164. package/src/components/form/Transfer/components/TransferList.tsx +212 -199
  165. package/src/components/form/Transfer/components/TransferOperations.tsx +52 -55
  166. package/src/components/form/Transfer/components/TransferPagination.tsx +115 -111
  167. package/src/components/form/Transfer/components/TransferSearch.tsx +52 -55
  168. package/src/components/form/Transfer/hooks/useTransferData.ts +91 -81
  169. package/src/components/form/Transfer/hooks/useTransferState.ts +22 -16
  170. package/src/components/form/Transfer/index.ts +2 -8
  171. package/src/components/form/Upload/Upload.styles.ts +21 -21
  172. package/src/components/form/Upload/Upload.tsx +189 -142
  173. package/src/components/form/Upload/Upload.types.ts +31 -31
  174. package/src/components/form/Upload/index.tsx +1 -1
  175. package/src/components/form/index.tsx +60 -29
  176. package/src/components/index.tsx +0 -1
  177. package/src/components/layout/Affix/Affix.styles.ts +16 -11
  178. package/src/components/layout/Affix/Affix.tsx +67 -75
  179. package/src/components/layout/Affix/Affix.types.ts +18 -18
  180. package/src/components/layout/Affix/index.tsx +1 -1
  181. package/src/components/layout/Col/Col.styles.ts +17 -17
  182. package/src/components/layout/Col/Col.test.tsx +7 -5
  183. package/src/components/layout/Col/Col.tsx +3 -21
  184. package/src/components/layout/Col/Col.types.ts +1 -1
  185. package/src/components/layout/Container/Container.styles.ts +3 -1
  186. package/src/components/layout/Container/Container.tsx +2 -11
  187. package/src/components/layout/Grid/Grid.tsx +3 -53
  188. package/src/components/layout/Layout/Content.tsx +24 -32
  189. package/src/components/layout/Layout/Footer.tsx +24 -32
  190. package/src/components/layout/Layout/Header.tsx +24 -32
  191. package/src/components/layout/Layout/Layout.styles.ts +17 -17
  192. package/src/components/layout/Layout/Layout.tsx +14 -25
  193. package/src/components/layout/Layout/Layout.types.ts +29 -29
  194. package/src/components/layout/Layout/Sider.tsx +44 -56
  195. package/src/components/layout/Layout/index.tsx +16 -2
  196. package/src/components/layout/Row/Row.tsx +15 -43
  197. package/src/components/layout/Space/Space.tsx +3 -11
  198. package/src/components/layout/Space/Space.types.ts +1 -1
  199. package/src/components/layout/index.tsx +29 -19
  200. package/src/components/navigation/Menu/Menu.constants.ts +69 -0
  201. package/src/components/navigation/Menu/Menu.stories.tsx +107 -0
  202. package/src/components/navigation/Menu/Menu.styles.ts +25 -37
  203. package/src/components/navigation/Menu/Menu.tsx +8 -11
  204. package/src/components/navigation/Menu/Menu.types.ts +2 -2
  205. package/src/components/navigation/Menu/Menu.utils.ts +17 -17
  206. package/src/components/navigation/Menu/MenuItem.tsx +9 -11
  207. package/src/components/navigation/Menu/SubMenu.tsx +8 -6
  208. package/src/components/navigation/Menu/index.tsx +4 -69
  209. package/src/components/navigation/NavBar/NavBar.styles.ts +1 -1
  210. package/src/components/navigation/NavBar/NavBar.tsx +7 -10
  211. package/src/components/navigation/NavBar/NavBar.types.ts +3 -3
  212. package/src/components/navigation/NavBar/index.tsx +1 -1
  213. package/src/components/navigation/Pagination/Pagination.test.tsx +2 -3
  214. package/src/components/navigation/Pagination/Pagination.tsx +3 -3
  215. package/src/components/navigation/Pagination/Pagination.types.ts +3 -2
  216. package/src/components/navigation/Pagination/index.ts +9 -3
  217. package/src/components/navigation/Steps/Step.tsx +24 -44
  218. package/src/components/navigation/Steps/Steps.styles.ts +28 -13
  219. package/src/components/navigation/Steps/Steps.test.tsx +2 -0
  220. package/src/components/navigation/Steps/Steps.tsx +88 -89
  221. package/src/components/navigation/Steps/Steps.types.ts +30 -30
  222. package/src/components/navigation/Steps/index.tsx +1 -1
  223. package/src/components/navigation/Tabs/Tabs.test.tsx +3 -2
  224. package/src/components/navigation/Tabs/Tabs.types.ts +4 -3
  225. package/src/components/navigation/index.tsx +21 -16
  226. package/src/constants/index.ts +1 -1
  227. package/src/hooks/index.ts +52 -102
  228. package/src/hooks/types.ts +4 -5
  229. package/src/hooks/useAsync.ts +46 -47
  230. package/src/hooks/useClickOutside.ts +52 -0
  231. package/src/hooks/useCounter.ts +87 -0
  232. package/src/hooks/useDebounce.ts +150 -0
  233. package/src/hooks/useDeepCompareEffect.ts +88 -0
  234. package/src/hooks/useEventListener.ts +77 -0
  235. package/src/hooks/useMediaQuery.ts +75 -0
  236. package/src/hooks/useMutation.ts +233 -0
  237. package/src/hooks/usePerformance.ts +1 -64
  238. package/src/hooks/usePlatform.ts +3 -1
  239. package/src/hooks/usePrevious.ts +25 -0
  240. package/src/hooks/useRequest.ts +12 -7
  241. package/src/hooks/useStateManagement.ts +1 -1
  242. package/src/hooks/useStorage.ts +169 -0
  243. package/src/hooks/useStyle.ts +8 -2
  244. package/src/hooks/useToggle.ts +54 -0
  245. package/src/index.ts +34 -9
  246. package/src/theme/ThemeProvider.tsx +3 -7
  247. package/src/theme/ThemeProvider.types.ts +1 -1
  248. package/src/theme/defaults.ts +1 -1
  249. package/src/theme/design-system.ts +2 -2
  250. package/src/theme/design-tokens.ts +85 -99
  251. package/src/theme/generated/dark-theme.scss +1 -1
  252. package/src/theme/generated/tokens.scss +82 -18
  253. package/src/theme/index.ts +8 -29
  254. package/src/theme/responsive.tsx +36 -34
  255. package/src/theme/styles.ts +1 -1
  256. package/src/theme/useThemeUtils.ts +43 -43
  257. package/src/theme/utils.ts +32 -32
  258. package/src/theme/variables.ts +70 -51
  259. package/src/types/accessibility.ts +36 -37
  260. package/src/types/button.ts +25 -27
  261. package/src/types/component-props.ts +6 -1
  262. package/src/types/glob.d.ts +4 -0
  263. package/src/types/index.ts +2 -2
  264. package/src/types/standardized-components.ts +9 -3
  265. package/src/types/utils.ts +13 -23
  266. package/src/utils/__tests__/responsiveUtils.test.ts +5 -4
  267. package/src/utils/abort-controller.ts +48 -0
  268. package/src/utils/cache.ts +2 -6
  269. package/src/utils/createNamespace.ts +4 -4
  270. package/src/utils/environment.ts +26 -6
  271. package/src/utils/error-handler.ts +2 -2
  272. package/src/utils/errorLogger.ts +16 -20
  273. package/src/utils/formatUtils.ts +38 -70
  274. package/src/utils/http/error-codes.ts +314 -0
  275. package/src/utils/http/http-client.test.ts +63 -0
  276. package/src/utils/{network → http}/http-client.ts +45 -35
  277. package/src/utils/http/request-cache.ts +127 -0
  278. package/src/utils/http/request.ts +954 -0
  279. package/src/utils/http/taro-adapter.test.ts +74 -0
  280. package/src/utils/http/taro-adapter.ts +24 -0
  281. package/src/utils/http/types.ts +414 -0
  282. package/src/utils/http/web-adapter.ts +33 -0
  283. package/src/utils/index.ts +5 -8
  284. package/src/utils/inputValidator.ts +17 -14
  285. package/src/utils/performance/performance.ts +60 -71
  286. package/src/utils/responsiveUtils.ts +7 -16
  287. package/src/utils/rtl-support.ts +29 -19
  288. package/src/utils/security/api-security.ts +47 -39
  289. package/src/utils/securityHeaders.ts +61 -67
  290. package/src/utils/typeHelpers.ts +10 -10
  291. package/src/utils/types/dataProcessing.ts +93 -92
  292. package/src/utils/types/typeHelpers.ts +31 -21
  293. package/src/utils/xssProtection.ts +96 -48
  294. package/dist/js/index-6NJ3A1Dn.js.map +0 -1
  295. package/dist/js/index-DffLRSro.js.map +0 -1
  296. package/src/components/form/Input/Input.enhanced.tsx +0 -732
  297. package/src/components/navigation/Menu/__tests__/Menu.test.tsx +0 -687
  298. package/src/components/navigation/Tree/Tree.styles.ts +0 -553
  299. package/src/components/navigation/Tree/Tree.test.basic.tsx +0 -7
  300. package/src/components/navigation/Tree/Tree.test.functional.tsx +0 -496
  301. package/src/components/navigation/Tree/Tree.test.import.check.tsx +0 -6
  302. package/src/components/navigation/Tree/Tree.test.import.tsx +0 -6
  303. package/src/components/navigation/Tree/Tree.test.minimal.tsx +0 -5
  304. package/src/components/navigation/Tree/Tree.test.simple.tsx +0 -30
  305. package/src/components/navigation/Tree/Tree.test.tsx +0 -908
  306. package/src/components/navigation/Tree/Tree.test.working.tsx +0 -673
  307. package/src/components/navigation/Tree/Tree.tsx +0 -600
  308. package/src/components/navigation/Tree/Tree.types.ts +0 -909
  309. package/src/components/navigation/Tree/Tree.utils.ts +0 -452
  310. package/src/components/navigation/Tree/index.ts +0 -33
  311. package/src/components/navigation/Tree/index.tsx +0 -23
  312. package/src/utils/network/http-client.test.ts +0 -18
@@ -64,136 +64,145 @@ export const TransferComponent = forwardRef<TransferRef, TransferProps>((props,
64
64
  setSearchValue,
65
65
  setPage,
66
66
  reset,
67
- } = useTransferState(
68
- controlledTargetKeys,
69
- defaultTargetKeys,
70
- controlledSelectedKeys,
71
- defaultSelectedKeys,
72
- disabled
73
- );
67
+ } = useTransferState(controlledTargetKeys, defaultTargetKeys, controlledSelectedKeys, defaultSelectedKeys, disabled);
74
68
 
75
69
  // 处理选项点击
76
- const handleItemClick = useCallback((item: TransferOption, _direction: TransferDirection) => {
77
- if (item.disabled || internalDisabled) return;
78
-
79
- const itemKey = item.key;
80
- const newSelectedKeys = selectedKeys.includes(itemKey)
81
- ? selectedKeys.filter(key => key !== itemKey)
82
- : [...selectedKeys, itemKey];
83
-
84
- updateSelectedKeys(newSelectedKeys);
85
- updateLeftRightSelectedKeys(newSelectedKeys, targetKeys);
86
-
87
- onSelectChange?.(
88
- newSelectedKeys.filter(key => !targetKeys.includes(key)),
89
- newSelectedKeys.filter(key => targetKeys.includes(key))
90
- );
91
- }, [selectedKeys, targetKeys, internalDisabled, updateSelectedKeys, updateLeftRightSelectedKeys, onSelectChange]);
70
+ const handleItemClick = useCallback(
71
+ (item: TransferOption, _direction: TransferDirection) => {
72
+ if (item.disabled || internalDisabled) return;
73
+
74
+ const itemKey = item.key;
75
+ const newSelectedKeys = selectedKeys.includes(itemKey)
76
+ ? selectedKeys.filter((key) => key !== itemKey)
77
+ : [...selectedKeys, itemKey];
78
+
79
+ updateSelectedKeys(newSelectedKeys);
80
+ updateLeftRightSelectedKeys(newSelectedKeys, targetKeys);
81
+
82
+ onSelectChange?.(
83
+ newSelectedKeys.filter((key) => !targetKeys.includes(key)),
84
+ newSelectedKeys.filter((key) => targetKeys.includes(key)),
85
+ );
86
+ },
87
+ [selectedKeys, targetKeys, internalDisabled, updateSelectedKeys, updateLeftRightSelectedKeys, onSelectChange],
88
+ );
92
89
 
93
90
  // 处理全选
94
- const handleSelectAll = useCallback((direction: TransferDirection) => {
95
- if (internalDisabled) return;
96
-
97
- const sourceData = direction === 'left'
98
- ? dataSource.filter((item: TransferOption) => !targetKeys.includes(item.key))
99
- : dataSource.filter((item: TransferOption) => targetKeys.includes(item.key));
100
-
101
- const searchValue = direction === 'left' ? leftSearchValue : rightSearchValue;
102
-
103
- // 过滤数据
104
- const filteredData = searchValue
105
- ? sourceData.filter((item: TransferOption) => {
106
- if (filterOption) {
107
- return filterOption(searchValue, item);
108
- }
109
- const searchText = searchValue.toLowerCase();
110
- const title = String(item.title).toLowerCase();
111
- const description = item.description ? String(item.description).toLowerCase() : '';
112
- return title.includes(searchText) || description.includes(searchText);
113
- })
114
- : sourceData;
115
-
116
- const enabledData = filteredData.filter((item: TransferOption) => !item.disabled);
117
- const currentSelectedKeys = direction === 'left' ? leftSelectedKeys : rightSelectedKeys;
118
-
119
- const allSelected = enabledData.every((item: TransferOption) => currentSelectedKeys.includes(item.key));
120
- const newSelectedKeys = allSelected
121
- ? selectedKeys.filter(key => !enabledData.some((item: TransferOption) => item.key === key))
122
- : [...selectedKeys, ...enabledData.map((item: TransferOption) => item.key)];
123
-
124
- updateSelectedKeys(newSelectedKeys);
125
- updateLeftRightSelectedKeys(newSelectedKeys, targetKeys);
126
-
127
- onSelectChange?.(
128
- newSelectedKeys.filter(key => !targetKeys.includes(key)),
129
- newSelectedKeys.filter(key => targetKeys.includes(key))
130
- );
131
- }, [
132
- dataSource,
133
- targetKeys,
134
- leftSearchValue,
135
- rightSearchValue,
136
- leftSelectedKeys,
137
- rightSelectedKeys,
138
- selectedKeys,
139
- internalDisabled,
140
- filterOption,
141
- updateSelectedKeys,
142
- updateLeftRightSelectedKeys,
143
- onSelectChange
144
- ]);
91
+ const handleSelectAll = useCallback(
92
+ (direction: TransferDirection) => {
93
+ if (internalDisabled) return;
94
+
95
+ const sourceData =
96
+ direction === 'left'
97
+ ? dataSource.filter((item: TransferOption) => !targetKeys.includes(item.key))
98
+ : dataSource.filter((item: TransferOption) => targetKeys.includes(item.key));
99
+
100
+ const searchValue = direction === 'left' ? leftSearchValue : rightSearchValue;
101
+
102
+ // 过滤数据
103
+ const filteredData = searchValue
104
+ ? sourceData.filter((item: TransferOption) => {
105
+ if (filterOption) {
106
+ return filterOption(searchValue, item);
107
+ }
108
+ const searchText = searchValue.toLowerCase();
109
+ const title = String(item.title).toLowerCase();
110
+ const description = item.description ? String(item.description).toLowerCase() : '';
111
+ return title.includes(searchText) || description.includes(searchText);
112
+ })
113
+ : sourceData;
114
+
115
+ const enabledData = filteredData.filter((item: TransferOption) => !item.disabled);
116
+ const currentSelectedKeys = direction === 'left' ? leftSelectedKeys : rightSelectedKeys;
117
+
118
+ const allSelected = enabledData.every((item: TransferOption) => currentSelectedKeys.includes(item.key));
119
+ const newSelectedKeys = allSelected
120
+ ? selectedKeys.filter((key) => !enabledData.some((item: TransferOption) => item.key === key))
121
+ : [...selectedKeys, ...enabledData.map((item: TransferOption) => item.key)];
122
+
123
+ updateSelectedKeys(newSelectedKeys);
124
+ updateLeftRightSelectedKeys(newSelectedKeys, targetKeys);
125
+
126
+ onSelectChange?.(
127
+ newSelectedKeys.filter((key) => !targetKeys.includes(key)),
128
+ newSelectedKeys.filter((key) => targetKeys.includes(key)),
129
+ );
130
+ },
131
+ [
132
+ dataSource,
133
+ targetKeys,
134
+ leftSearchValue,
135
+ rightSearchValue,
136
+ leftSelectedKeys,
137
+ rightSelectedKeys,
138
+ selectedKeys,
139
+ internalDisabled,
140
+ filterOption,
141
+ updateSelectedKeys,
142
+ updateLeftRightSelectedKeys,
143
+ onSelectChange,
144
+ ],
145
+ );
145
146
 
146
147
  // 处理移动
147
- const handleMove = useCallback((direction: TransferDirection) => {
148
- if (internalDisabled) return;
149
-
150
- const moveKeys = direction === 'right' ? leftSelectedKeys : rightSelectedKeys;
151
- if (moveKeys.length === 0) return;
152
-
153
- const newTargetKeys = direction === 'right'
154
- ? [...targetKeys, ...moveKeys]
155
- : targetKeys.filter(key => !moveKeys.includes(key));
156
-
157
- updateTargetKeys(newTargetKeys);
158
-
159
- // 清空移动方向的选中状态
160
- const newSelectedKeys = selectedKeys.filter(key => !moveKeys.includes(key));
161
- updateSelectedKeys(newSelectedKeys);
162
-
163
- if (direction === 'right') {
164
- updateLeftRightSelectedKeys(newSelectedKeys, newTargetKeys);
165
- } else {
166
- updateLeftRightSelectedKeys(newSelectedKeys, newTargetKeys);
167
- }
168
-
169
- onChange?.(newTargetKeys, direction, moveKeys);
170
- onSelectChange?.(
171
- newSelectedKeys.filter(key => !newTargetKeys.includes(key)),
172
- newSelectedKeys.filter(key => newTargetKeys.includes(key))
173
- );
174
- }, [
175
- targetKeys,
176
- leftSelectedKeys,
177
- rightSelectedKeys,
178
- selectedKeys,
179
- internalDisabled,
180
- updateTargetKeys,
181
- updateSelectedKeys,
182
- updateLeftRightSelectedKeys,
183
- onChange,
184
- onSelectChange
185
- ]);
148
+ const handleMove = useCallback(
149
+ (direction: TransferDirection) => {
150
+ if (internalDisabled) return;
151
+
152
+ const moveKeys = direction === 'right' ? leftSelectedKeys : rightSelectedKeys;
153
+ if (moveKeys.length === 0) return;
154
+
155
+ const newTargetKeys =
156
+ direction === 'right' ? [...targetKeys, ...moveKeys] : targetKeys.filter((key) => !moveKeys.includes(key));
157
+
158
+ updateTargetKeys(newTargetKeys);
159
+
160
+ // 清空移动方向的选中状态
161
+ const newSelectedKeys = selectedKeys.filter((key) => !moveKeys.includes(key));
162
+ updateSelectedKeys(newSelectedKeys);
163
+
164
+ if (direction === 'right') {
165
+ updateLeftRightSelectedKeys(newSelectedKeys, newTargetKeys);
166
+ } else {
167
+ updateLeftRightSelectedKeys(newSelectedKeys, newTargetKeys);
168
+ }
169
+
170
+ onChange?.(newTargetKeys, direction, moveKeys);
171
+ onSelectChange?.(
172
+ newSelectedKeys.filter((key) => !newTargetKeys.includes(key)),
173
+ newSelectedKeys.filter((key) => newTargetKeys.includes(key)),
174
+ );
175
+ },
176
+ [
177
+ targetKeys,
178
+ leftSelectedKeys,
179
+ rightSelectedKeys,
180
+ selectedKeys,
181
+ internalDisabled,
182
+ updateTargetKeys,
183
+ updateSelectedKeys,
184
+ updateLeftRightSelectedKeys,
185
+ onChange,
186
+ onSelectChange,
187
+ ],
188
+ );
186
189
 
187
190
  // 处理搜索
188
- const handleSearch = useCallback((direction: TransferDirection, value: string) => {
189
- setSearchValue(direction, value);
190
- onSearch?.(direction, value);
191
- }, [setSearchValue, onSearch]);
191
+ const handleSearch = useCallback(
192
+ (direction: TransferDirection, value: string) => {
193
+ setSearchValue(direction, value);
194
+ onSearch?.(direction, value);
195
+ },
196
+ [setSearchValue, onSearch],
197
+ );
192
198
 
193
199
  // 处理页码变化
194
- const handlePageChange = useCallback((direction: TransferDirection, page: number) => {
195
- setPage(direction, page);
196
- }, [setPage]);
200
+ const handlePageChange = useCallback(
201
+ (direction: TransferDirection, page: number) => {
202
+ setPage(direction, page);
203
+ },
204
+ [setPage],
205
+ );
197
206
 
198
207
  // 暴露给外部的引用方法
199
208
  React.useImperativeHandle(
@@ -202,15 +211,19 @@ export const TransferComponent = forwardRef<TransferRef, TransferProps>((props,
202
211
  getTargetKeys: () => targetKeys,
203
212
  setTargetKeys: (keys: TransferValue) => {
204
213
  updateTargetKeys(keys);
205
- onChange?.(keys, 'right', keys.filter(key => !targetKeys.includes(key)));
214
+ onChange?.(
215
+ keys,
216
+ 'right',
217
+ keys.filter((key) => !targetKeys.includes(key)),
218
+ );
206
219
  },
207
220
  getSelectedKeys: () => selectedKeys,
208
221
  setSelectedKeys: (keys: TransferValue) => {
209
222
  updateSelectedKeys(keys);
210
223
  updateLeftRightSelectedKeys(keys, targetKeys);
211
224
  onSelectChange?.(
212
- keys.filter(key => !targetKeys.includes(key)),
213
- keys.filter(key => targetKeys.includes(key))
225
+ keys.filter((key) => !targetKeys.includes(key)),
226
+ keys.filter((key) => targetKeys.includes(key)),
214
227
  );
215
228
  },
216
229
  getDataSource: () => dataSource,
@@ -220,10 +233,9 @@ export const TransferComponent = forwardRef<TransferRef, TransferProps>((props,
220
233
  console.warn('setDataSource should be updated through props');
221
234
  },
222
235
  moveTo: (direction: TransferDirection, keys: TransferValue) => {
223
- const newTargetKeys = direction === 'right'
224
- ? [...targetKeys, ...keys]
225
- : targetKeys.filter(key => !keys.includes(key));
226
-
236
+ const newTargetKeys =
237
+ direction === 'right' ? [...targetKeys, ...keys] : targetKeys.filter((key) => !keys.includes(key));
238
+
227
239
  updateTargetKeys(newTargetKeys);
228
240
  onChange?.(newTargetKeys, direction, keys);
229
241
  },
@@ -231,20 +243,20 @@ export const TransferComponent = forwardRef<TransferRef, TransferProps>((props,
231
243
  handleSelectAll(direction);
232
244
  },
233
245
  clearSelect: (direction: TransferDirection) => {
234
- const newSelectedKeys = selectedKeys.filter(key => {
246
+ const newSelectedKeys = selectedKeys.filter((key) => {
235
247
  if (direction === 'left') {
236
248
  return targetKeys.includes(key);
237
249
  } else {
238
250
  return !targetKeys.includes(key);
239
251
  }
240
252
  });
241
-
253
+
242
254
  updateSelectedKeys(newSelectedKeys);
243
255
  updateLeftRightSelectedKeys(newSelectedKeys, targetKeys);
244
-
256
+
245
257
  onSelectChange?.(
246
- newSelectedKeys.filter(key => !targetKeys.includes(key)),
247
- newSelectedKeys.filter(key => targetKeys.includes(key))
258
+ newSelectedKeys.filter((key) => !targetKeys.includes(key)),
259
+ newSelectedKeys.filter((key) => targetKeys.includes(key)),
248
260
  );
249
261
  },
250
262
  search: (direction: TransferDirection, value: string) => {
@@ -286,7 +298,7 @@ export const TransferComponent = forwardRef<TransferRef, TransferProps>((props,
286
298
  handleSelectAll,
287
299
  handleSearch,
288
300
  reset,
289
- ]
301
+ ],
290
302
  );
291
303
 
292
304
  // 生成容器样式
@@ -399,4 +411,4 @@ TransferComponent.displayName = 'Transfer';
399
411
 
400
412
  /** 导出Transfer组件 */
401
413
  export const Transfer = TransferComponent;
402
- export default Transfer;
414
+ export default Transfer;
@@ -262,18 +262,29 @@ export interface TransferConfig {
262
262
  /** 穿梭框工具函数接口 */
263
263
  export interface TransferUtils {
264
264
  /** 过滤选项 */
265
- filterOptions: (options: TransferDataSource, inputValue: string, filterOption?: TransferProps['filterOption']) => TransferDataSource;
265
+ filterOptions: (
266
+ options: TransferDataSource,
267
+ inputValue: string,
268
+ filterOption?: TransferProps['filterOption'],
269
+ ) => TransferDataSource;
266
270
  /** 查找选项 */
267
271
  findOptions: (options: TransferDataSource, keys: TransferValue) => TransferOption[];
268
272
  /** 验证值 */
269
273
  validateValue: (value: TransferValue, options: TransferDataSource) => boolean;
270
274
  /** 分割数据源 */
271
- splitDataSource: (dataSource: TransferDataSource, targetKeys: TransferValue) => {
275
+ splitDataSource: (
276
+ dataSource: TransferDataSource,
277
+ targetKeys: TransferValue,
278
+ ) => {
272
279
  leftDataSource: TransferDataSource;
273
280
  rightDataSource: TransferDataSource;
274
281
  };
275
282
  /** 生成分页数据 */
276
- generatePaginationData: (data: TransferDataSource, currentPage: number, pageSize: number) => {
283
+ generatePaginationData: (
284
+ data: TransferDataSource,
285
+ currentPage: number,
286
+ pageSize: number,
287
+ ) => {
277
288
  data: TransferDataSource;
278
289
  total: number;
279
290
  currentPage: number;
@@ -348,11 +359,11 @@ export class TransferTools {
348
359
  static filterOptions(
349
360
  options: TransferDataSource,
350
361
  inputValue: string,
351
- filterOption?: TransferProps['filterOption']
362
+ filterOption?: TransferProps['filterOption'],
352
363
  ): TransferDataSource {
353
364
  if (!inputValue) return options;
354
365
 
355
- return options.filter(option => {
366
+ return options.filter((option) => {
356
367
  if (filterOption) {
357
368
  return filterOption(inputValue, option);
358
369
  }
@@ -367,19 +378,19 @@ export class TransferTools {
367
378
 
368
379
  /** 查找选项 */
369
380
  static findOptions(options: TransferDataSource, keys: TransferValue): TransferOption[] {
370
- return options.filter(option => keys.includes(option.key));
381
+ return options.filter((option) => keys.includes(option.key));
371
382
  }
372
383
 
373
384
  /** 验证值 */
374
385
  static validateValue(value: TransferValue, options: TransferDataSource): boolean {
375
- const validKeys = options.map(option => option.key);
376
- return value.every(key => validKeys.includes(key));
386
+ const validKeys = options.map((option) => option.key);
387
+ return value.every((key) => validKeys.includes(key));
377
388
  }
378
389
 
379
390
  /** 分割数据源 */
380
391
  static splitDataSource(
381
392
  dataSource: TransferDataSource,
382
- targetKeys: TransferValue
393
+ targetKeys: TransferValue,
383
394
  ): {
384
395
  leftDataSource: TransferDataSource;
385
396
  rightDataSource: TransferDataSource;
@@ -387,7 +398,7 @@ export class TransferTools {
387
398
  const leftDataSource: TransferDataSource = [];
388
399
  const rightDataSource: TransferDataSource = [];
389
400
 
390
- dataSource.forEach(option => {
401
+ dataSource.forEach((option) => {
391
402
  if (targetKeys.includes(option.key)) {
392
403
  rightDataSource.push(option);
393
404
  } else {
@@ -402,7 +413,7 @@ export class TransferTools {
402
413
  static generatePaginationData(
403
414
  data: TransferDataSource,
404
415
  currentPage: number,
405
- pageSize: number
416
+ pageSize: number,
406
417
  ): {
407
418
  data: TransferDataSource;
408
419
  total: number;
@@ -426,23 +437,20 @@ export class TransferTools {
426
437
  }
427
438
 
428
439
  /** 获取选中的选项 */
429
- static getSelectedOptions(
430
- options: TransferDataSource,
431
- selectedKeys: TransferValue
432
- ): TransferOption[] {
433
- return options.filter(option => selectedKeys.includes(option.key));
440
+ static getSelectedOptions(options: TransferDataSource, selectedKeys: TransferValue): TransferOption[] {
441
+ return options.filter((option) => selectedKeys.includes(option.key));
434
442
  }
435
443
 
436
444
  /** 获取禁用的选项 */
437
445
  static getDisabledOptions(options: TransferDataSource): TransferOption[] {
438
- return options.filter(option => option.disabled);
446
+ return options.filter((option) => option.disabled);
439
447
  }
440
448
 
441
449
  /** 排序选项 */
442
450
  static sortOptions(
443
451
  options: TransferDataSource,
444
452
  sortBy: keyof TransferOption,
445
- order: 'asc' | 'desc' = 'asc'
453
+ order: 'asc' | 'desc' = 'asc',
446
454
  ): TransferDataSource {
447
455
  return [...options].sort((a, b) => {
448
456
  const aValue = a[sortBy];
@@ -457,7 +465,7 @@ export class TransferTools {
457
465
  /** 去重选项 */
458
466
  static uniqueOptions(options: TransferDataSource): TransferDataSource {
459
467
  const seen = new Set();
460
- return options.filter(option => {
468
+ return options.filter((option) => {
461
469
  if (seen.has(option.key)) {
462
470
  return false;
463
471
  }
@@ -469,10 +477,10 @@ export class TransferTools {
469
477
  /** 批量更新选项状态 */
470
478
  static updateOptionsStatus(
471
479
  options: TransferDataSource,
472
- updates: { key: string | number; disabled?: boolean; selected?: boolean }[]
480
+ updates: { key: string | number; disabled?: boolean; selected?: boolean }[],
473
481
  ): TransferDataSource {
474
- return options.map(option => {
475
- const update = updates.find(u => u.key === option.key);
482
+ return options.map((option) => {
483
+ const update = updates.find((u) => u.key === option.key);
476
484
  if (update) {
477
485
  return { ...option, ...update };
478
486
  }
@@ -483,7 +491,7 @@ export class TransferTools {
483
491
  /** 计算选中状态 */
484
492
  static calculateSelectionState(
485
493
  options: TransferDataSource,
486
- selectedKeys: TransferValue
494
+ selectedKeys: TransferValue,
487
495
  ): {
488
496
  allSelected: boolean;
489
497
  partiallySelected: boolean;
@@ -491,9 +499,9 @@ export class TransferTools {
491
499
  selectedCount: number;
492
500
  totalCount: number;
493
501
  } {
494
- const enabledOptions = options.filter(option => !option.disabled);
502
+ const enabledOptions = options.filter((option) => !option.disabled);
495
503
  const totalCount = enabledOptions.length;
496
- const selectedCount = enabledOptions.filter(option => selectedKeys.includes(option.key)).length;
504
+ const selectedCount = enabledOptions.filter((option) => selectedKeys.includes(option.key)).length;
497
505
 
498
506
  const allSelected = totalCount > 0 && selectedCount === totalCount;
499
507
  const noneSelected = selectedCount === 0;
@@ -554,4 +562,4 @@ export class TransferTools {
554
562
  showQuickJumper: pagination.showQuickJumper || false,
555
563
  };
556
564
  }
557
- }
565
+ }
@@ -23,79 +23,72 @@ interface TransferItemProps {
23
23
  }
24
24
 
25
25
  /** Transfer选项组件 */
26
- export const TransferItem: React.FC<TransferItemProps> = memo(({
27
- item,
28
- direction,
29
- isSelected,
30
- disabled,
31
- onClick,
32
- optionRender,
33
- rowRender,
34
- index = 0,
35
- }) => {
36
- // 处理点击事件
37
- const handleClick = useCallback(() => {
38
- if (!disabled) {
39
- onClick(item, direction);
26
+ export const TransferItem: React.FC<TransferItemProps> = memo(
27
+ ({ item, direction, isSelected, disabled, onClick, optionRender, rowRender, index = 0 }) => {
28
+ // 处理点击事件
29
+ const handleClick = useCallback(() => {
30
+ if (!disabled) {
31
+ onClick(item, direction);
32
+ }
33
+ }, [item, direction, disabled, onClick]);
34
+
35
+ // 移除了鼠标事件处理函数,因为在Taro环境中可能不支持
36
+
37
+ // 使用自定义行渲染
38
+ if (rowRender) {
39
+ return (
40
+ <View
41
+ key={String(item.key)}
42
+ style={TransferStyles['getListItemStyle'](disabled, isSelected)}
43
+ className={item.className}
44
+ onClick={handleClick}
45
+ accessibilityState={{ selected: isSelected, disabled: disabled }}
46
+ role="option"
47
+ >
48
+ {rowRender(item, index, direction)}
49
+ </View>
50
+ );
40
51
  }
41
- }, [item, direction, disabled, onClick]);
42
52
 
43
- // 移除了鼠标事件处理函数,因为在Taro环境中可能不支持
53
+ // 默认渲染
54
+ const itemStyle = {
55
+ ...TransferStyles['getListItemStyle'](disabled, isSelected),
56
+ ...(item.style || {}),
57
+ };
58
+
59
+ const checkboxStyle = {
60
+ ...TransferStyles['getListItemCheckboxStyle'](),
61
+ ...(isSelected ? TransferStyles['getListItemCheckboxSelectedStyle']() : {}),
62
+ ...(disabled ? TransferStyles['getListItemCheckboxDisabledStyle']() : {}),
63
+ };
44
64
 
45
- // 使用自定义行渲染
46
- if (rowRender) {
47
65
  return (
48
66
  <View
49
67
  key={String(item.key)}
50
- style={TransferStyles['getListItemStyle'](disabled, isSelected)}
68
+ style={itemStyle}
51
69
  className={item.className}
52
70
  onClick={handleClick}
53
- accessibilityState={{ selected: isSelected, disabled: disabled }}
71
+ accessibilityState={{ selected: isSelected, disabled: disabled }}
54
72
  role="option"
55
73
  >
56
- {rowRender(item, index, direction)}
74
+ <View style={checkboxStyle} hidden={true}>
75
+ {isSelected && <Text accessibilityLabel="已选中">✓</Text>}
76
+ </View>
77
+ <View style={TransferStyles['getListItemContentStyle']()}>
78
+ {optionRender ? (
79
+ optionRender(item)
80
+ ) : (
81
+ <View>
82
+ <Text>{item.title}</Text>
83
+ {item.description && (
84
+ <Text style={TransferStyles['getListItemDescriptionStyle']()}>{item.description}</Text>
85
+ )}
86
+ </View>
87
+ )}
88
+ </View>
57
89
  </View>
58
90
  );
59
- }
60
-
61
- // 默认渲染
62
- const itemStyle = {
63
- ...TransferStyles['getListItemStyle'](disabled, isSelected),
64
- ...(item.style || {}),
65
- };
66
-
67
- const checkboxStyle = {
68
- ...TransferStyles['getListItemCheckboxStyle'](),
69
- ...(isSelected ? TransferStyles['getListItemCheckboxSelectedStyle']() : {}),
70
- ...(disabled ? TransferStyles['getListItemCheckboxDisabledStyle']() : {}),
71
- };
72
-
73
- return (
74
- <View
75
- key={String(item.key)}
76
- style={itemStyle}
77
- className={item.className}
78
- onClick={handleClick}
79
- accessibilityState={{ selected: isSelected, disabled: disabled }}
80
- role="option"
81
- >
82
- <View style={checkboxStyle} hidden={true}>
83
- {isSelected && <Text accessibilityLabel="已选中">✓</Text>}
84
- </View>
85
- <View style={TransferStyles['getListItemContentStyle']()}>
86
- {optionRender ? optionRender(item) : (
87
- <View>
88
- <Text>{item.title}</Text>
89
- {item.description && (
90
- <Text style={TransferStyles['getListItemDescriptionStyle']()}>
91
- {item.description}
92
- </Text>
93
- )}
94
- </View>
95
- )}
96
- </View>
97
- </View>
98
- );
99
- });
91
+ },
92
+ );
100
93
 
101
94
  TransferItem.displayName = 'TransferItem';