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
@@ -20,116 +20,120 @@ interface TransferPaginationProps {
20
20
  }
21
21
 
22
22
  /** Transfer分页组件 */
23
- export const TransferPagination: React.FC<TransferPaginationProps> = memo(({
24
- pagination,
25
- currentPage,
26
- total,
27
- onPageChange,
28
- disabled,
29
- }) => {
30
- // 获取分页配置
31
- const getPaginationConfig = useCallback(() => {
32
- if (pagination === false) return null;
33
-
34
- if (pagination === true) {
35
- return { pageSize: 10, simple: false, showSizeChanger: false, showQuickJumper: false };
36
- }
37
-
38
- return {
39
- pageSize: pagination?.pageSize || 10,
40
- simple: pagination?.simple || false,
41
- showSizeChanger: pagination?.showSizeChanger || false,
42
- showQuickJumper: pagination?.showQuickJumper || false,
43
- };
44
- }, [pagination]);
45
-
46
- const config = getPaginationConfig();
47
- if (!config) return null;
48
-
49
- const { pageSize, simple, showQuickJumper } = config;
50
- const totalPages = Math.ceil(total / pageSize);
51
-
52
- // 如果只有一页,不显示分页
53
- if (totalPages <= 1) {
54
- return null;
55
- }
56
-
57
- // 处理页码变化
58
- const handlePageChange = useCallback((newPage: number) => {
59
- if (newPage >= 1 && newPage <= totalPages && !disabled) {
60
- onPageChange(newPage);
61
- }
62
- }, [totalPages, disabled, onPageChange]);
23
+ export const TransferPagination: React.FC<TransferPaginationProps> = memo(
24
+ ({ pagination, currentPage, total, onPageChange, disabled }) => {
25
+ // 获取分页配置
26
+ const getPaginationConfig = useCallback(() => {
27
+ if (pagination === false) return null;
28
+
29
+ if (pagination === true) {
30
+ return { pageSize: 10, simple: false, showSizeChanger: false, showQuickJumper: false };
31
+ }
32
+
33
+ return {
34
+ pageSize: pagination?.pageSize || 10,
35
+ simple: pagination?.simple || false,
36
+ showSizeChanger: pagination?.showSizeChanger || false,
37
+ showQuickJumper: pagination?.showQuickJumper || false,
38
+ };
39
+ }, [pagination]);
63
40
 
64
- // 处理快速跳转输入
65
- const handleQuickJumperChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
66
- const newPage = parseInt(e.target.value);
67
- if (!isNaN(newPage) && newPage >= 1 && newPage <= totalPages) {
68
- handlePageChange(newPage);
41
+ const config = getPaginationConfig();
42
+ if (!config) return null;
43
+
44
+ const { pageSize, simple, showQuickJumper } = config;
45
+ const totalPages = Math.ceil(total / pageSize);
46
+
47
+ // 如果只有一页,不显示分页
48
+ if (totalPages <= 1) {
49
+ return null;
69
50
  }
70
- }, [totalPages, handlePageChange]);
71
-
72
- // 分页按钮
73
- const PaginationButton: React.FC<{
74
- onClick: () => void;
75
- disabled: boolean;
76
- children: React.ReactNode;
77
- ariaLabel: string;
78
- }> = memo(({ onClick, disabled, children, ariaLabel }) => (
79
- <View
80
- style={{
81
- ...TransferStyles['getPaginationButtonStyle'](disabled),
82
- ...(disabled ? {} : TransferStyles['getPaginationButtonHoverStyle']()),
83
- }}
84
- onClick={onClick}
85
- aria-disabled={disabled}
86
- aria-label={ariaLabel}
87
- role="button"
88
- >
89
- <Text>{children}</Text>
90
- </View>
91
- ));
92
-
93
- PaginationButton.displayName = 'PaginationButton';
94
-
95
- return (
96
- <View style={TransferStyles['getPaginationStyle']()} role="navigation" aria-label="分页导航">
97
- <Text style={TransferStyles['getPaginationInfoStyle']()}>
98
- {simple ? `${currentPage} / ${totalPages}` : `${(currentPage - 1) * pageSize + 1}-${Math.min(currentPage * pageSize, total)} / ${total}`}
99
- </Text>
100
-
101
- {!simple && (
102
- <View style={{ display: 'flex', gap: '4px' }} role="group" aria-label="分页按钮组">
103
- <PaginationButton
104
- onClick={() => handlePageChange(currentPage - 1)}
105
- disabled={currentPage === 1 || disabled}
106
- ariaLabel="上一页"
107
- >
108
-
109
- </PaginationButton>
110
-
111
- {showQuickJumper && (
112
- <Input
113
- type="number"
114
- style={TransferStyles['getPaginationSelectStyle']()}
115
- value={currentPage.toString()}
116
- onInput={handleQuickJumperChange as any}
117
- accessibilityLabel="跳转到指定页"
118
- disabled={disabled}
119
- />
120
- )}
121
-
122
- <PaginationButton
123
- onClick={() => handlePageChange(currentPage + 1)}
124
- disabled={currentPage === totalPages || disabled}
125
- ariaLabel="下一页"
126
- >
127
-
128
- </PaginationButton>
129
- </View>
130
- )}
131
- </View>
132
- );
133
- });
134
-
135
- TransferPagination.displayName = 'TransferPagination';
51
+
52
+ // 处理页码变化
53
+ const handlePageChange = useCallback(
54
+ (newPage: number) => {
55
+ if (newPage >= 1 && newPage <= totalPages && !disabled) {
56
+ onPageChange(newPage);
57
+ }
58
+ },
59
+ [totalPages, disabled, onPageChange],
60
+ );
61
+
62
+ // 处理快速跳转输入
63
+ const handleQuickJumperChange = useCallback(
64
+ (e: React.ChangeEvent<HTMLInputElement>) => {
65
+ const newPage = parseInt(e.target.value);
66
+ if (!isNaN(newPage) && newPage >= 1 && newPage <= totalPages) {
67
+ handlePageChange(newPage);
68
+ }
69
+ },
70
+ [totalPages, handlePageChange],
71
+ );
72
+
73
+ // 分页按钮
74
+ const PaginationButton: React.FC<{
75
+ onClick: () => void;
76
+ disabled: boolean;
77
+ children: React.ReactNode;
78
+ ariaLabel: string;
79
+ }> = memo(({ onClick, disabled, children, ariaLabel }) => (
80
+ <View
81
+ style={{
82
+ ...TransferStyles['getPaginationButtonStyle'](disabled),
83
+ ...(disabled ? {} : TransferStyles['getPaginationButtonHoverStyle']()),
84
+ }}
85
+ onClick={onClick}
86
+ aria-disabled={disabled}
87
+ aria-label={ariaLabel}
88
+ role="button"
89
+ >
90
+ <Text>{children}</Text>
91
+ </View>
92
+ ));
93
+
94
+ PaginationButton.displayName = 'PaginationButton';
95
+
96
+ return (
97
+ <View style={TransferStyles['getPaginationStyle']()} role="navigation" aria-label="分页导航">
98
+ <Text style={TransferStyles['getPaginationInfoStyle']()}>
99
+ {simple
100
+ ? `${currentPage} / ${totalPages}`
101
+ : `${(currentPage - 1) * pageSize + 1}-${Math.min(currentPage * pageSize, total)} / ${total}`}
102
+ </Text>
103
+
104
+ {!simple && (
105
+ <View style={{ display: 'flex', gap: '4px' }} role="group" aria-label="分页按钮组">
106
+ <PaginationButton
107
+ onClick={() => handlePageChange(currentPage - 1)}
108
+ disabled={currentPage === 1 || disabled}
109
+ ariaLabel="上一页"
110
+ >
111
+
112
+ </PaginationButton>
113
+
114
+ {showQuickJumper && (
115
+ <Input
116
+ type="number"
117
+ style={TransferStyles['getPaginationSelectStyle']()}
118
+ value={currentPage.toString()}
119
+ onInput={handleQuickJumperChange as any}
120
+ accessibilityLabel="跳转到指定页"
121
+ disabled={disabled}
122
+ />
123
+ )}
124
+
125
+ <PaginationButton
126
+ onClick={() => handlePageChange(currentPage + 1)}
127
+ disabled={currentPage === totalPages || disabled}
128
+ ariaLabel="下一页"
129
+ >
130
+
131
+ </PaginationButton>
132
+ </View>
133
+ )}
134
+ </View>
135
+ );
136
+ },
137
+ );
138
+
139
+ TransferPagination.displayName = 'TransferPagination';
@@ -22,67 +22,64 @@ interface TransferSearchProps {
22
22
  }
23
23
 
24
24
  /** Transfer搜索组件 */
25
- export const TransferSearch: React.FC<TransferSearchProps> = memo(({
26
- direction,
27
- showSearch,
28
- searchValue,
29
- searchPlaceholder,
30
- onSearch,
31
- searchRender,
32
- disabled,
33
- }) => {
34
- // 处理搜索输入
35
- const handleSearchInput = useCallback((value: string) => {
36
- onSearch(direction, value);
37
- }, [direction, onSearch]);
25
+ export const TransferSearch: React.FC<TransferSearchProps> = memo(
26
+ ({ direction, showSearch, searchValue, searchPlaceholder, onSearch, searchRender, disabled }) => {
27
+ // 处理搜索输入
28
+ const handleSearchInput = useCallback(
29
+ (value: string) => {
30
+ onSearch(direction, value);
31
+ },
32
+ [direction, onSearch],
33
+ );
34
+
35
+ // 处理输入框聚焦
36
+ const handleFocus = useCallback(() => {
37
+ // Taro doesn't provide direct access to input element styling
38
+ // Focus handling is handled by the native component
39
+ }, []);
38
40
 
39
- // 处理输入框聚焦
40
- const handleFocus = useCallback(() => {
41
- // Taro doesn't provide direct access to input element styling
42
- // Focus handling is handled by the native component
43
- }, []);
41
+ // 处理输入框失焦
42
+ const handleBlur = useCallback(() => {
43
+ // Taro doesn't provide direct access to input element styling
44
+ // Blur handling is handled by the native component
45
+ }, []);
44
46
 
45
- // 处理输入框失焦
46
- const handleBlur = useCallback(() => {
47
- // Taro doesn't provide direct access to input element styling
48
- // Blur handling is handled by the native component
49
- }, []);
47
+ // 如果不显示搜索框,返回null
48
+ if (!showSearch) {
49
+ return null;
50
+ }
50
51
 
51
- // 如果不显示搜索框,返回null
52
- if (!showSearch) {
53
- return null;
54
- }
52
+ // 使用自定义搜索渲染
53
+ if (searchRender) {
54
+ return (
55
+ <View style={TransferStyles['getSearchStyle']()}>
56
+ {searchRender({
57
+ placeholder: searchPlaceholder,
58
+ value: searchValue,
59
+ onChange: handleSearchInput,
60
+ direction,
61
+ })}
62
+ </View>
63
+ );
64
+ }
55
65
 
56
- // 使用自定义搜索渲染
57
- if (searchRender) {
66
+ // 默认搜索渲染
58
67
  return (
59
68
  <View style={TransferStyles['getSearchStyle']()}>
60
- {searchRender({
61
- placeholder: searchPlaceholder,
62
- value: searchValue,
63
- onChange: handleSearchInput,
64
- direction,
65
- })}
69
+ <Input
70
+ style={TransferStyles['getSearchInputStyle']()}
71
+ value={searchValue}
72
+ placeholder={searchPlaceholder}
73
+ onInput={(e: any) => handleSearchInput(e.detail.value)}
74
+ onFocus={handleFocus}
75
+ onBlur={handleBlur}
76
+ disabled={disabled}
77
+ aria-label={searchPlaceholder}
78
+ role="searchbox"
79
+ />
66
80
  </View>
67
81
  );
68
- }
69
-
70
- // 默认搜索渲染
71
- return (
72
- <View style={TransferStyles['getSearchStyle']()}>
73
- <Input
74
- style={TransferStyles['getSearchInputStyle']()}
75
- value={searchValue}
76
- placeholder={searchPlaceholder}
77
- onInput={(e: any) => handleSearchInput(e.detail.value)}
78
- onFocus={handleFocus}
79
- onBlur={handleBlur}
80
- disabled={disabled}
81
- aria-label={searchPlaceholder}
82
- role="searchbox"
83
- />
84
- </View>
85
- );
86
- });
82
+ },
83
+ );
87
84
 
88
- TransferSearch.displayName = 'TransferSearch';
85
+ TransferSearch.displayName = 'TransferSearch';
@@ -4,21 +4,21 @@ import type {
4
4
  TransferDataSource,
5
5
  TransferValue,
6
6
  TransferPaginationConfig,
7
- TransferProps
7
+ TransferProps,
8
8
  } from '../Transfer.types';
9
9
 
10
10
  /** Transfer数据处理Hook */
11
11
  export function useTransferData(
12
12
  dataSource: TransferDataSource,
13
13
  targetKeys: TransferValue,
14
- filterOption?: TransferProps['filterOption']
14
+ filterOption?: TransferProps['filterOption'],
15
15
  ) {
16
16
  // 分割数据源
17
17
  const splitDataSource = useMemo(() => {
18
18
  const leftDataSource: TransferOption[] = [];
19
19
  const rightDataSource: TransferOption[] = [];
20
20
 
21
- dataSource.forEach(item => {
21
+ dataSource.forEach((item) => {
22
22
  if (targetKeys.includes(item.key)) {
23
23
  rightDataSource.push(item);
24
24
  } else {
@@ -30,30 +30,33 @@ export function useTransferData(
30
30
  }, [dataSource, targetKeys]);
31
31
 
32
32
  // 过滤数据源
33
- const filterDataSource = useCallback((data: TransferDataSource, searchValue: string) => {
34
- if (!searchValue) return data;
35
-
36
- return data.filter(item => {
37
- if (filterOption) {
38
- return filterOption(searchValue, item);
39
- }
40
-
41
- const searchText = searchValue.toLowerCase();
42
- const title = String(item.title).toLowerCase();
43
- const description = item.description ? String(item.description).toLowerCase() : '';
44
-
45
- return title.includes(searchText) || description.includes(searchText);
46
- });
47
- }, [filterOption]);
33
+ const filterDataSource = useCallback(
34
+ (data: TransferDataSource, searchValue: string) => {
35
+ if (!searchValue) return data;
36
+
37
+ return data.filter((item) => {
38
+ if (filterOption) {
39
+ return filterOption(searchValue, item);
40
+ }
41
+
42
+ const searchText = searchValue.toLowerCase();
43
+ const title = String(item.title).toLowerCase();
44
+ const description = item.description ? String(item.description).toLowerCase() : '';
45
+
46
+ return title.includes(searchText) || description.includes(searchText);
47
+ });
48
+ },
49
+ [filterOption],
50
+ );
48
51
 
49
52
  // 获取分页配置
50
53
  const getPaginationConfig = useCallback((pagination?: boolean | TransferPaginationConfig) => {
51
54
  if (pagination === false) return null;
52
-
55
+
53
56
  if (pagination === true) {
54
57
  return { pageSize: 10, simple: false, showSizeChanger: false, showQuickJumper: false };
55
58
  }
56
-
59
+
57
60
  return {
58
61
  pageSize: pagination?.pageSize || 10,
59
62
  simple: pagination?.simple || false,
@@ -63,61 +66,69 @@ export function useTransferData(
63
66
  }, []);
64
67
 
65
68
  // 获取分页数据
66
- const getPaginatedData = useCallback((
67
- data: TransferDataSource,
68
- page: number,
69
- pagination?: boolean | TransferPaginationConfig
70
- ) => {
71
- const config = getPaginationConfig(pagination);
72
- if (!config) return { data, total: data.length, page, totalPages: 1 };
73
-
74
- const { pageSize } = config;
75
- const total = data.length;
76
- const totalPages = Math.ceil(total / pageSize);
77
- const startIndex = (page - 1) * pageSize;
78
- const endIndex = startIndex + pageSize;
79
- const paginatedData = data.slice(startIndex, endIndex);
80
-
81
- return { data: paginatedData, total, page, totalPages };
82
- }, [getPaginationConfig]);
69
+ const getPaginatedData = useCallback(
70
+ (data: TransferDataSource, page: number, pagination?: boolean | TransferPaginationConfig) => {
71
+ const config = getPaginationConfig(pagination);
72
+ if (!config) return { data, total: data.length, page, totalPages: 1 };
73
+
74
+ const { pageSize } = config;
75
+ const total = data.length;
76
+ const totalPages = Math.ceil(total / pageSize);
77
+ const startIndex = (page - 1) * pageSize;
78
+ const endIndex = startIndex + pageSize;
79
+ const paginatedData = data.slice(startIndex, endIndex);
80
+
81
+ return { data: paginatedData, total, page, totalPages };
82
+ },
83
+ [getPaginationConfig],
84
+ );
83
85
 
84
86
  // 查找选项
85
- const findOptions = useCallback((keys: TransferValue) => {
86
- return dataSource.filter(item => keys.includes(item.key));
87
- }, [dataSource]);
87
+ const findOptions = useCallback(
88
+ (keys: TransferValue) => {
89
+ return dataSource.filter((item) => keys.includes(item.key));
90
+ },
91
+ [dataSource],
92
+ );
88
93
 
89
94
  // 验证值
90
- const validateValue = useCallback((value: TransferValue) => {
91
- const validKeys = dataSource.map(option => option.key);
92
- return value.every(key => validKeys.includes(key));
93
- }, [dataSource]);
95
+ const validateValue = useCallback(
96
+ (value: TransferValue) => {
97
+ const validKeys = dataSource.map((option) => option.key);
98
+ return value.every((key) => validKeys.includes(key));
99
+ },
100
+ [dataSource],
101
+ );
94
102
 
95
103
  // 获取选中的选项
96
- const getSelectedOptions = useCallback((selectedKeys: TransferValue) => {
97
- return dataSource.filter(item => selectedKeys.includes(item.key));
98
- }, [dataSource]);
104
+ const getSelectedOptions = useCallback(
105
+ (selectedKeys: TransferValue) => {
106
+ return dataSource.filter((item) => selectedKeys.includes(item.key));
107
+ },
108
+ [dataSource],
109
+ );
99
110
 
100
111
  // 获取目标选项
101
112
  const getTargetOptions = useCallback(() => {
102
- return dataSource.filter(item => targetKeys.includes(item.key));
113
+ return dataSource.filter((item) => targetKeys.includes(item.key));
103
114
  }, [dataSource, targetKeys]);
104
115
 
105
116
  // 获取源选项
106
117
  const getSourceOptions = useCallback(() => {
107
- return dataSource.filter(item => !targetKeys.includes(item.key));
118
+ return dataSource.filter((item) => !targetKeys.includes(item.key));
108
119
  }, [dataSource, targetKeys]);
109
120
 
110
121
  // 获取禁用的选项
111
122
  const getDisabledOptions = useCallback(() => {
112
- return dataSource.filter(item => item.disabled);
123
+ return dataSource.filter((item) => item.disabled);
113
124
  }, [dataSource]);
114
125
 
115
126
  // 计算选中状态
116
127
  const calculateSelectionState = useCallback((data: TransferDataSource, selectedKeys: TransferValue) => {
117
- const enabledData = data.filter(item => !item.disabled);
128
+ const enabledData = data.filter((item) => !item.disabled);
118
129
  const totalCount = enabledData.length;
119
- const selectedCount = enabledData.filter(item => selectedKeys.includes(item.key)).length;
120
-
130
+ const selectedCount = enabledData.filter((item) => selectedKeys.includes(item.key)).length;
131
+
121
132
  const allSelected = totalCount > 0 && selectedCount === totalCount;
122
133
  const noneSelected = selectedCount === 0;
123
134
  const partiallySelected = !allSelected && !noneSelected;
@@ -132,23 +143,23 @@ export function useTransferData(
132
143
  }, []);
133
144
 
134
145
  // 批量更新选项状态
135
- const updateOptionsStatus = useCallback((
136
- options: TransferDataSource,
137
- updates: { key: string | number; disabled?: boolean; selected?: boolean }[]
138
- ) => {
139
- return options.map(option => {
140
- const update = updates.find(u => u.key === option.key);
141
- if (update) {
142
- return { ...option, ...update };
143
- }
144
- return option;
145
- });
146
- }, []);
146
+ const updateOptionsStatus = useCallback(
147
+ (options: TransferDataSource, updates: { key: string | number; disabled?: boolean; selected?: boolean }[]) => {
148
+ return options.map((option) => {
149
+ const update = updates.find((u) => u.key === option.key);
150
+ if (update) {
151
+ return { ...option, ...update };
152
+ }
153
+ return option;
154
+ });
155
+ },
156
+ [],
157
+ );
147
158
 
148
159
  // 去重选项
149
160
  const uniqueOptions = useCallback((options: TransferDataSource) => {
150
161
  const seen = new Set();
151
- return options.filter(option => {
162
+ return options.filter((option) => {
152
163
  if (seen.has(option.key)) {
153
164
  return false;
154
165
  }
@@ -158,20 +169,19 @@ export function useTransferData(
158
169
  }, []);
159
170
 
160
171
  // 排序选项
161
- const sortOptions = useCallback((
162
- options: TransferDataSource,
163
- sortBy: keyof TransferOption,
164
- order: 'asc' | 'desc' = 'asc'
165
- ) => {
166
- return [...options].sort((a, b) => {
167
- const aValue = a[sortBy];
168
- const bValue = b[sortBy];
169
-
170
- if (aValue < bValue) return order === 'asc' ? -1 : 1;
171
- if (aValue > bValue) return order === 'asc' ? 1 : -1;
172
- return 0;
173
- });
174
- }, []);
172
+ const sortOptions = useCallback(
173
+ (options: TransferDataSource, sortBy: keyof TransferOption, order: 'asc' | 'desc' = 'asc') => {
174
+ return [...options].sort((a, b) => {
175
+ const aValue = a[sortBy];
176
+ const bValue = b[sortBy];
177
+
178
+ if (aValue < bValue) return order === 'asc' ? -1 : 1;
179
+ if (aValue > bValue) return order === 'asc' ? 1 : -1;
180
+ return 0;
181
+ });
182
+ },
183
+ [],
184
+ );
175
185
 
176
186
  return {
177
187
  splitDataSource,
@@ -189,4 +199,4 @@ export function useTransferData(
189
199
  uniqueOptions,
190
200
  sortOptions,
191
201
  };
192
- }
202
+ }