feffery_antd_components 0.4.3-rc6 → 0.4.3

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 (462) hide show
  1. package/CONTRIBUTING.md +4 -4
  2. package/DESCRIPTION +1 -1
  3. package/LICENSE +21 -21
  4. package/MANIFEST.in +6 -6
  5. package/Project.toml +1 -1
  6. package/README-en_US.md +73 -73
  7. package/README.md +87 -87
  8. package/bug_fix.py +21 -36
  9. package/fac-logo.svg +151 -151
  10. package/feffery_antd_components/AntdAccordion.py +7 -7
  11. package/feffery_antd_components/AntdAffix.py +2 -2
  12. package/feffery_antd_components/AntdAlert.py +5 -5
  13. package/feffery_antd_components/AntdAnchor.py +5 -5
  14. package/feffery_antd_components/AntdAvatar.py +4 -4
  15. package/feffery_antd_components/AntdAvatarGroup.py +1 -1
  16. package/feffery_antd_components/AntdBackTop.py +4 -4
  17. package/feffery_antd_components/AntdBadge.py +5 -5
  18. package/feffery_antd_components/AntdBreadcrumb.py +4 -4
  19. package/feffery_antd_components/AntdButton.py +14 -14
  20. package/feffery_antd_components/AntdCalendar.py +4 -4
  21. package/feffery_antd_components/AntdCard.py +5 -5
  22. package/feffery_antd_components/AntdCardGrid.py +3 -3
  23. package/feffery_antd_components/AntdCardMeta.py +1 -1
  24. package/feffery_antd_components/AntdCarousel.py +13 -13
  25. package/feffery_antd_components/AntdCascader.py +16 -17
  26. package/feffery_antd_components/AntdCenter.py +3 -3
  27. package/feffery_antd_components/AntdCheckCard.py +7 -7
  28. package/feffery_antd_components/AntdCheckCardGroup.py +9 -9
  29. package/feffery_antd_components/AntdCheckableTag.py +2 -2
  30. package/feffery_antd_components/AntdCheckbox.py +8 -8
  31. package/feffery_antd_components/AntdCheckboxGroup.py +6 -6
  32. package/feffery_antd_components/AntdCol.py +5 -5
  33. package/feffery_antd_components/AntdCollapse.py +8 -8
  34. package/feffery_antd_components/AntdColorPicker.py +13 -13
  35. package/feffery_antd_components/AntdComment.py +7 -7
  36. package/feffery_antd_components/AntdCompact.py +3 -3
  37. package/feffery_antd_components/AntdConfigProvider.py +6 -6
  38. package/feffery_antd_components/AntdContent.py +1 -1
  39. package/feffery_antd_components/AntdCopyText.py +2 -2
  40. package/feffery_antd_components/AntdCountdown.py +1 -1
  41. package/feffery_antd_components/AntdCountup.py +1 -1
  42. package/feffery_antd_components/AntdCustomSkeleton.py +5 -5
  43. package/feffery_antd_components/AntdDatePicker.py +13 -13
  44. package/feffery_antd_components/AntdDateRangePicker.py +12 -12
  45. package/feffery_antd_components/AntdDescriptionItem.py +2 -2
  46. package/feffery_antd_components/AntdDescriptions.py +6 -6
  47. package/feffery_antd_components/AntdDivider.py +5 -5
  48. package/feffery_antd_components/AntdDraggerUpload.py +15 -15
  49. package/feffery_antd_components/AntdDrawer.py +12 -12
  50. package/feffery_antd_components/AntdDropdown.py +18 -18
  51. package/feffery_antd_components/AntdEmpty.py +2 -2
  52. package/feffery_antd_components/AntdFlex.py +6 -6
  53. package/feffery_antd_components/AntdFloatButton.py +5 -5
  54. package/feffery_antd_components/AntdFloatButtonGroup.py +3 -3
  55. package/feffery_antd_components/AntdFooter.py +1 -1
  56. package/feffery_antd_components/AntdForm.py +10 -6
  57. package/feffery_antd_components/AntdFormItem.py +4 -4
  58. package/feffery_antd_components/AntdFormRender.py +2 -2
  59. package/feffery_antd_components/AntdHappyProvider.py +2 -2
  60. package/feffery_antd_components/AntdHeader.py +1 -1
  61. package/feffery_antd_components/AntdIcon.py +3 -3
  62. package/feffery_antd_components/AntdImage.py +6 -6
  63. package/feffery_antd_components/AntdImageGroup.py +6 -6
  64. package/feffery_antd_components/AntdInput.py +17 -17
  65. package/feffery_antd_components/AntdInputNumber.py +12 -12
  66. package/feffery_antd_components/AntdLayout.py +1 -1
  67. package/feffery_antd_components/AntdMentions.py +9 -9
  68. package/feffery_antd_components/AntdMenu.py +9 -9
  69. package/feffery_antd_components/AntdMessage.py +3 -3
  70. package/feffery_antd_components/AntdModal.py +28 -28
  71. package/feffery_antd_components/AntdNotification.py +9 -9
  72. package/feffery_antd_components/AntdOTP.py +7 -7
  73. package/feffery_antd_components/AntdPageHeader.py +5 -5
  74. package/feffery_antd_components/AntdPagination.py +15 -15
  75. package/feffery_antd_components/AntdParagraph.py +2 -2
  76. package/feffery_antd_components/AntdPictureUpload.py +28 -28
  77. package/feffery_antd_components/AntdPopconfirm.py +21 -21
  78. package/feffery_antd_components/AntdPopover.py +9 -9
  79. package/feffery_antd_components/AntdPopupCard.py +9 -9
  80. package/feffery_antd_components/AntdProgress.py +9 -9
  81. package/feffery_antd_components/AntdQRCode.py +10 -10
  82. package/feffery_antd_components/AntdRadioGroup.py +9 -9
  83. package/feffery_antd_components/AntdRate.py +9 -9
  84. package/feffery_antd_components/AntdResult.py +1 -1
  85. package/feffery_antd_components/AntdRibbon.py +2 -2
  86. package/feffery_antd_components/AntdRow.py +3 -3
  87. package/feffery_antd_components/AntdSegmented.py +9 -9
  88. package/feffery_antd_components/AntdSegmentedColoring.py +11 -11
  89. package/feffery_antd_components/AntdSelect.py +19 -19
  90. package/feffery_antd_components/AntdSider.py +6 -6
  91. package/feffery_antd_components/AntdSkeleton.py +11 -11
  92. package/feffery_antd_components/AntdSkeletonAvatar.py +3 -3
  93. package/feffery_antd_components/AntdSkeletonButton.py +5 -5
  94. package/feffery_antd_components/AntdSkeletonImage.py +1 -1
  95. package/feffery_antd_components/AntdSkeletonInput.py +3 -3
  96. package/feffery_antd_components/AntdSlider.py +10 -10
  97. package/feffery_antd_components/AntdSpace.py +4 -4
  98. package/feffery_antd_components/AntdSpin.py +7 -8
  99. package/feffery_antd_components/AntdSplitter.py +5 -5
  100. package/feffery_antd_components/AntdSpoiler.py +5 -5
  101. package/feffery_antd_components/AntdStatistic.py +2 -2
  102. package/feffery_antd_components/AntdSteps.py +8 -8
  103. package/feffery_antd_components/AntdSwitch.py +8 -8
  104. package/feffery_antd_components/AntdTable.py +64 -63
  105. package/feffery_antd_components/AntdTabs.py +13 -14
  106. package/feffery_antd_components/AntdTag.py +4 -4
  107. package/feffery_antd_components/AntdText.py +2 -2
  108. package/feffery_antd_components/AntdTimePicker.py +16 -16
  109. package/feffery_antd_components/AntdTimeRangePicker.py +15 -15
  110. package/feffery_antd_components/AntdTimeline.py +2 -2
  111. package/feffery_antd_components/AntdTitle.py +2 -2
  112. package/feffery_antd_components/AntdTooltip.py +9 -9
  113. package/feffery_antd_components/AntdTour.py +9 -9
  114. package/feffery_antd_components/AntdTransfer.py +11 -11
  115. package/feffery_antd_components/AntdTree.py +17 -17
  116. package/feffery_antd_components/AntdTreeSelect.py +18 -18
  117. package/feffery_antd_components/AntdUpload.py +18 -18
  118. package/feffery_antd_components/AntdWatermark.py +6 -6
  119. package/feffery_antd_components/Fragment.py +1 -1
  120. package/feffery_antd_components/__init__.py +88 -88
  121. package/feffery_antd_components/_icons.py +559 -559
  122. package/feffery_antd_components/alias.py +222 -222
  123. package/feffery_antd_components/async-antd_table.js +2 -2
  124. package/feffery_antd_components/async-data_display.js +1 -1
  125. package/feffery_antd_components/async-data_entry.js +3 -3
  126. package/feffery_antd_components/async-upload.js +2 -2
  127. package/feffery_antd_components/feffery_antd_components.min.js +8 -8
  128. package/feffery_antd_components/metadata.json +1 -1
  129. package/feffery_antd_components/package-info.json +111 -96
  130. package/feffery_antd_components/utils.py +262 -262
  131. package/package.json +111 -96
  132. package/pytest.ini +5 -5
  133. package/release-to-test-pypi.sh +1 -1
  134. package/requirements.txt +2 -2
  135. package/review_checklist.md +47 -47
  136. package/ruff.toml +4 -4
  137. package/setup.py +33 -33
  138. package/src/jl/'feffery'_antdform.jl +2 -1
  139. package/src/jl/'feffery'_antdtable.jl +7 -6
  140. package/src/lib/components/dataDisplay/AntdAccordion.react.js +232 -232
  141. package/src/lib/components/dataDisplay/AntdAvatar.react.js +177 -177
  142. package/src/lib/components/dataDisplay/AntdAvatarGroup.react.js +133 -133
  143. package/src/lib/components/dataDisplay/AntdBadge.react.js +196 -196
  144. package/src/lib/components/dataDisplay/AntdCarousel.react.js +187 -187
  145. package/src/lib/components/dataDisplay/AntdCheckableTag.react.js +105 -105
  146. package/src/lib/components/dataDisplay/AntdCollapse.react.js +239 -239
  147. package/src/lib/components/dataDisplay/AntdComment.react.js +251 -251
  148. package/src/lib/components/dataDisplay/AntdCountdown.react.js +143 -143
  149. package/src/lib/components/dataDisplay/AntdCountup.react.js +133 -133
  150. package/src/lib/components/dataDisplay/AntdEmpty.react.js +162 -162
  151. package/src/lib/components/dataDisplay/AntdImage.react.js +202 -202
  152. package/src/lib/components/dataDisplay/AntdImageGroup.react.js +181 -181
  153. package/src/lib/components/dataDisplay/AntdPopover.react.js +220 -220
  154. package/src/lib/components/dataDisplay/AntdQRCode.react.js +191 -191
  155. package/src/lib/components/dataDisplay/AntdRibbon.react.js +105 -105
  156. package/src/lib/components/dataDisplay/AntdSegmented.react.js +234 -234
  157. package/src/lib/components/dataDisplay/AntdSpoiler.react.js +154 -154
  158. package/src/lib/components/dataDisplay/AntdStatistic.react.js +168 -168
  159. package/src/lib/components/dataDisplay/AntdTable.react.js +1859 -1858
  160. package/src/lib/components/dataDisplay/AntdTabs.react.js +352 -352
  161. package/src/lib/components/dataDisplay/AntdTag.react.js +135 -135
  162. package/src/lib/components/dataDisplay/AntdTimeline.react.js +136 -136
  163. package/src/lib/components/dataDisplay/AntdTooltip.react.js +230 -230
  164. package/src/lib/components/dataDisplay/AntdTree.react.js +641 -641
  165. package/src/lib/components/dataDisplay/card/AntdCard.react.js +249 -249
  166. package/src/lib/components/dataDisplay/card/AntdCardGrid.react.js +99 -99
  167. package/src/lib/components/dataDisplay/card/AntdCardMeta.react.js +97 -97
  168. package/src/lib/components/dataDisplay/descriptions/AntdDescriptionItem.react.js +130 -130
  169. package/src/lib/components/dataDisplay/descriptions/AntdDescriptions.react.js +237 -237
  170. package/src/lib/components/dataEntry/AntdCalendar.react.js +205 -205
  171. package/src/lib/components/dataEntry/AntdCascader.react.js +435 -435
  172. package/src/lib/components/dataEntry/AntdCheckbox.react.js +182 -182
  173. package/src/lib/components/dataEntry/AntdCheckboxGroup.react.js +193 -193
  174. package/src/lib/components/dataEntry/AntdColorPicker.react.js +240 -240
  175. package/src/lib/components/dataEntry/AntdDatePicker.react.js +432 -432
  176. package/src/lib/components/dataEntry/AntdDateRangePicker.react.js +439 -439
  177. package/src/lib/components/dataEntry/AntdInput.react.js +423 -423
  178. package/src/lib/components/dataEntry/AntdInputNumber.react.js +329 -329
  179. package/src/lib/components/dataEntry/AntdMentions.react.js +236 -236
  180. package/src/lib/components/dataEntry/AntdOTP.react.js +186 -186
  181. package/src/lib/components/dataEntry/AntdRadioGroup.react.js +241 -241
  182. package/src/lib/components/dataEntry/AntdRate.react.js +199 -199
  183. package/src/lib/components/dataEntry/AntdSegmentedColoring.react.js +251 -251
  184. package/src/lib/components/dataEntry/AntdSelect.react.js +492 -492
  185. package/src/lib/components/dataEntry/AntdSlider.react.js +325 -325
  186. package/src/lib/components/dataEntry/AntdSwitch.react.js +210 -210
  187. package/src/lib/components/dataEntry/AntdTimePicker.react.js +344 -344
  188. package/src/lib/components/dataEntry/AntdTimeRangePicker.react.js +325 -325
  189. package/src/lib/components/dataEntry/AntdTransfer.react.js +317 -317
  190. package/src/lib/components/dataEntry/AntdTreeSelect.react.js +573 -573
  191. package/src/lib/components/dataEntry/check-card/AntdCheckCard.react.js +186 -186
  192. package/src/lib/components/dataEntry/check-card/AntdCheckCardGroup.react.js +214 -214
  193. package/src/lib/components/dataEntry/form/AntdForm.react.js +201 -194
  194. package/src/lib/components/dataEntry/form/AntdFormItem.react.js +210 -210
  195. package/src/lib/components/dataEntry/upload/AntdDraggerUpload.react.js +504 -504
  196. package/src/lib/components/dataEntry/upload/AntdPictureUpload.react.js +530 -530
  197. package/src/lib/components/dataEntry/upload/AntdUpload.react.js +537 -537
  198. package/src/lib/components/feedback/AntdAlert.react.js +185 -185
  199. package/src/lib/components/feedback/AntdDrawer.react.js +306 -306
  200. package/src/lib/components/feedback/AntdMessage.react.js +143 -143
  201. package/src/lib/components/feedback/AntdModal.react.js +530 -530
  202. package/src/lib/components/feedback/AntdNotification.react.js +211 -211
  203. package/src/lib/components/feedback/AntdPopconfirm.react.js +433 -433
  204. package/src/lib/components/feedback/AntdPopupCard.react.js +362 -362
  205. package/src/lib/components/feedback/AntdProgress.react.js +300 -300
  206. package/src/lib/components/feedback/AntdResult.react.js +125 -125
  207. package/src/lib/components/feedback/AntdSpin.react.js +273 -273
  208. package/src/lib/components/feedback/skeleton/AntdCustomSkeleton.react.js +197 -197
  209. package/src/lib/components/feedback/skeleton/AntdSkeleton.react.js +291 -291
  210. package/src/lib/components/feedback/skeleton/AntdSkeletonAvatar.react.js +109 -109
  211. package/src/lib/components/feedback/skeleton/AntdSkeletonButton.react.js +114 -114
  212. package/src/lib/components/feedback/skeleton/AntdSkeletonImage.react.js +82 -82
  213. package/src/lib/components/feedback/skeleton/AntdSkeletonInput.react.js +98 -98
  214. package/src/lib/components/formRender/AntdFormRender.react.js +945 -945
  215. package/src/lib/components/general/AntdButton.react.js +328 -328
  216. package/src/lib/components/general/AntdFloatButton.react.js +157 -157
  217. package/src/lib/components/general/AntdFloatButtonGroup.react.js +162 -162
  218. package/src/lib/components/general/AntdIcon.react.js +176 -176
  219. package/src/lib/components/general/typography/AntdParagraph.react.js +202 -202
  220. package/src/lib/components/general/typography/AntdText.react.js +194 -194
  221. package/src/lib/components/general/typography/AntdTitle.react.js +186 -186
  222. package/src/lib/components/icons.react.js +1136 -1136
  223. package/src/lib/components/layout/AntdCenter.react.js +122 -122
  224. package/src/lib/components/layout/AntdCompact.react.js +108 -108
  225. package/src/lib/components/layout/AntdContent.react.js +92 -92
  226. package/src/lib/components/layout/AntdDivider.react.js +219 -219
  227. package/src/lib/components/layout/AntdFlex.react.js +143 -143
  228. package/src/lib/components/layout/AntdFooter.react.js +92 -92
  229. package/src/lib/components/layout/AntdHeader.react.js +92 -92
  230. package/src/lib/components/layout/AntdLayout.react.js +90 -90
  231. package/src/lib/components/layout/AntdSider.react.js +162 -162
  232. package/src/lib/components/layout/AntdSpace.react.js +213 -213
  233. package/src/lib/components/layout/AntdSplitter.react.js +173 -173
  234. package/src/lib/components/layout/grid/AntdCol.react.js +349 -349
  235. package/src/lib/components/layout/grid/AntdRow.react.js +152 -152
  236. package/src/lib/components/locales.react.js +197 -197
  237. package/src/lib/components/navigation/AntdAnchor.react.js +208 -208
  238. package/src/lib/components/navigation/AntdBreadcrumb.react.js +270 -270
  239. package/src/lib/components/navigation/AntdDropdown.react.js +469 -469
  240. package/src/lib/components/navigation/AntdMenu.react.js +573 -649
  241. package/src/lib/components/navigation/AntdPageHeader.react.js +139 -139
  242. package/src/lib/components/navigation/AntdPagination.react.js +303 -303
  243. package/src/lib/components/navigation/AntdSteps.react.js +199 -199
  244. package/src/lib/components/other/AntdAffix.react.js +120 -120
  245. package/src/lib/components/other/AntdBackTop.react.js +128 -128
  246. package/src/lib/components/other/AntdConfigProvider.react.js +246 -246
  247. package/src/lib/components/other/AntdCopyText.react.js +138 -138
  248. package/src/lib/components/other/AntdHappyProvider.react.js +50 -50
  249. package/src/lib/components/other/AntdTour.react.js +277 -277
  250. package/src/lib/components/other/AntdWatermark.react.js +179 -179
  251. package/src/lib/components/other/Fragment.react.js +50 -50
  252. package/src/lib/components/styles.css +513 -513
  253. package/src/lib/components/utils.js +51 -51
  254. package/src/lib/contexts/FormContext.js +4 -4
  255. package/src/lib/contexts/FormItemContext.js +4 -4
  256. package/src/lib/contexts/PropsContext.js +4 -4
  257. package/src/lib/fragments/AntdTable.react.js +2215 -2200
  258. package/src/lib/fragments/dataDisplay/AntdAccordion.react.js +101 -101
  259. package/src/lib/fragments/dataDisplay/AntdAvatar.react.js +127 -127
  260. package/src/lib/fragments/dataDisplay/AntdAvatarGroup.react.js +51 -51
  261. package/src/lib/fragments/dataDisplay/AntdBadge.react.js +73 -73
  262. package/src/lib/fragments/dataDisplay/AntdCarousel.react.js +71 -71
  263. package/src/lib/fragments/dataDisplay/AntdCheckableTag.react.js +57 -57
  264. package/src/lib/fragments/dataDisplay/AntdComment.react.js +178 -178
  265. package/src/lib/fragments/dataDisplay/AntdCountdown.react.js +83 -83
  266. package/src/lib/fragments/dataDisplay/AntdCountup.react.js +70 -70
  267. package/src/lib/fragments/dataDisplay/AntdEmpty.react.js +71 -71
  268. package/src/lib/fragments/dataDisplay/AntdImage.react.js +206 -206
  269. package/src/lib/fragments/dataDisplay/AntdImageGroup.react.js +91 -91
  270. package/src/lib/fragments/dataDisplay/AntdPopover.react.js +106 -106
  271. package/src/lib/fragments/dataDisplay/AntdQRCode.react.js +93 -93
  272. package/src/lib/fragments/dataDisplay/AntdRibbon.react.js +53 -53
  273. package/src/lib/fragments/dataDisplay/AntdSegmented.react.js +129 -129
  274. package/src/lib/fragments/dataDisplay/AntdSpoiler.react.js +96 -96
  275. package/src/lib/fragments/dataDisplay/AntdTabs.react.js +211 -211
  276. package/src/lib/fragments/dataDisplay/AntdTag.react.js +66 -66
  277. package/src/lib/fragments/dataDisplay/AntdTimeline.react.js +67 -67
  278. package/src/lib/fragments/dataDisplay/AntdTooltip.react.js +98 -98
  279. package/src/lib/fragments/dataDisplay/AntdTree.react.js +581 -581
  280. package/src/lib/fragments/dataDisplay/card/AntdCard.react.js +104 -104
  281. package/src/lib/fragments/dataDisplay/card/AntdCardGrid.react.js +54 -54
  282. package/src/lib/fragments/dataDisplay/card/AntdCardMeta.react.js +54 -54
  283. package/src/lib/fragments/dataDisplay/descriptions/AntdDescriptionItem.react.js +56 -56
  284. package/src/lib/fragments/dataDisplay/descriptions/AntdDescriptions.react.js +139 -139
  285. package/src/lib/fragments/dataEntry/AntdCalendar.react.js +178 -178
  286. package/src/lib/fragments/dataEntry/AntdCascader.react.js +319 -319
  287. package/src/lib/fragments/dataEntry/AntdCheckbox.react.js +119 -119
  288. package/src/lib/fragments/dataEntry/AntdCheckboxGroup.react.js +122 -122
  289. package/src/lib/fragments/dataEntry/AntdColorPicker.react.js +244 -244
  290. package/src/lib/fragments/dataEntry/AntdDatePicker.react.js +586 -586
  291. package/src/lib/fragments/dataEntry/AntdDateRangePicker.react.js +628 -628
  292. package/src/lib/fragments/dataEntry/AntdInput.react.js +450 -450
  293. package/src/lib/fragments/dataEntry/AntdInputNumber.react.js +194 -194
  294. package/src/lib/fragments/dataEntry/AntdMentions.react.js +180 -180
  295. package/src/lib/fragments/dataEntry/AntdOTP.react.js +127 -127
  296. package/src/lib/fragments/dataEntry/AntdRadioGroup.react.js +203 -203
  297. package/src/lib/fragments/dataEntry/AntdRate.react.js +131 -131
  298. package/src/lib/fragments/dataEntry/AntdSegmentedColoring.react.js +246 -246
  299. package/src/lib/fragments/dataEntry/AntdSelect.react.js +373 -373
  300. package/src/lib/fragments/dataEntry/AntdSlider.react.js +177 -177
  301. package/src/lib/fragments/dataEntry/AntdSwitch.react.js +132 -132
  302. package/src/lib/fragments/dataEntry/AntdTimePicker.react.js +191 -191
  303. package/src/lib/fragments/dataEntry/AntdTimeRangePicker.react.js +213 -213
  304. package/src/lib/fragments/dataEntry/AntdTransfer.react.js +183 -183
  305. package/src/lib/fragments/dataEntry/AntdTreeSelect.react.js +355 -355
  306. package/src/lib/fragments/dataEntry/check-card/AntdCheckCard.react.js +111 -111
  307. package/src/lib/fragments/dataEntry/check-card/AntdCheckCardGroup.react.js +122 -122
  308. package/src/lib/fragments/dataEntry/form/AntdForm.react.js +126 -120
  309. package/src/lib/fragments/dataEntry/form/AntdFormItem.react.js +85 -84
  310. package/src/lib/fragments/formRender/AntdFormRender.react.js +179 -179
  311. package/src/lib/fragments/upload/AntdDraggerUpload.react.js +622 -622
  312. package/src/lib/fragments/upload/AntdPictureUpload.react.js +577 -577
  313. package/src/lib/fragments/upload/AntdUpload.react.js +613 -613
  314. package/src/lib/hooks/useCss.js +28 -28
  315. package/src/lib/hooks/useStickyOffset.js +115 -115
  316. package/src/lib/index.js +240 -240
  317. package/src/lib/internal_components/UtilsLink.react.js +82 -0
  318. package/src/lib/store/formStore.js +54 -47
  319. package/tests/dash3.0tests/AntdQRCode/347/273/204/344/273/266loading/347/212/266/346/200/201/351/207/215/346/236/204/test.py +51 -51
  320. package/tests/dash3.0tests/AntdTable/345/207/275/346/225/260/345/274/217/346/224/271/351/200/240/test.py +62 -62
  321. package/tests/dash3.0tests/_dashprivate_layout/346/224/271/345/212/250/346/265/213/350/257/225/test.py +50 -50
  322. package/tests/dash3.0tests/loading_state/346/224/271/345/212/250/346/265/213/350/257/225/test.py +38 -38
  323. package/tests/dash3.0tests//345/207/275/346/225/260/345/274/217/347/273/204/344/273/266/351/273/230/350/256/244/345/200/274/351/207/215/346/236/204/test.py +30 -30
  324. package/tests/dash3.0tests//345/212/240/350/275/275/345/212/250/347/224/273/347/261/273/347/273/204/344/273/266/351/207/215/346/236/204/346/265/213/350/257/225/test.py +62 -62
  325. package/tests/dash3.0tests//347/273/204/344/273/266/345/261/236/346/200/247/345/237/272/347/241/200/346/214/201/344/271/205/345/214/226/351/207/215/346/236/204/346/265/213/350/257/225/test.py +25 -25
  326. package/tests/dataDisplay/AntdAccordion/feat_size.py +36 -36
  327. package/tests/dataDisplay/AntdAccordion/feat_styles.py +35 -35
  328. package/tests/dataDisplay/AntdCard/refactor_delete_props.py +83 -83
  329. package/tests/dataDisplay/AntdCarousel/feat_auto_play_dot_duration.py +34 -34
  330. package/tests/dataDisplay/AntdCollapse/feat_size.py +30 -30
  331. package/tests/dataDisplay/AntdCollapse/feat_styles.py +29 -29
  332. package/tests/dataDisplay/AntdCountdown/feat_finish_event.py +41 -41
  333. package/tests/dataDisplay/AntdCountdown/refactor_to_timer.py +57 -57
  334. package/tests/dataDisplay/AntdCountup/refactor_to_timer.py +57 -57
  335. package/tests/dataDisplay/AntdDescriptions/feat_span_filled.py +42 -42
  336. package/tests/dataDisplay/AntdImage/debug_preview_toolbar.py +23 -23
  337. package/tests/dataDisplay/AntdSegmented/feat_shape.py +39 -39
  338. package/tests/dataDisplay/AntdSegmented/feat_simple_options.py +43 -43
  339. package/tests/dataDisplay/AntdSegmented/feat_vertical.py +32 -32
  340. package/tests/dataDisplay/AntdTable/feat_button_mode_like_dcc_link.py +125 -0
  341. package/tests/dataDisplay/AntdTable/feat_button_mode_refactor.py +143 -143
  342. package/tests/dataDisplay/AntdTable/feat_button_mode_tooltip.py +47 -47
  343. package/tests/dataDisplay/AntdTable/feat_columns_fixed_bool.py +40 -40
  344. package/tests/dataDisplay/AntdTable/feat_columns_min_width.py +51 -51
  345. package/tests/dataDisplay/AntdTable/feat_columns_sort_order.py +131 -131
  346. package/tests/dataDisplay/AntdTable/feat_editable_disabled_keys.py +71 -71
  347. package/tests/dataDisplay/AntdTable/feat_header_align.py +38 -38
  348. package/tests/dataDisplay/AntdTable/feat_link_mode_like_dcc_link.py +49 -0
  349. package/tests/dataDisplay/AntdTable/feat_loading.py +76 -76
  350. package/tests/dataDisplay/AntdTable/feat_mini_chart_color.py +139 -139
  351. package/tests/dataDisplay/AntdTable/feat_row_class_name.py +39 -39
  352. package/tests/dataDisplay/AntdTable/feat_row_class_name_func.py +41 -41
  353. package/tests/dataDisplay/AntdTable/feat_select_mode_show_search.py +70 -70
  354. package/tests/dataDisplay/AntdTable/feat_sticky_header.py +81 -81
  355. package/tests/dataDisplay/AntdTable/feat_table_scroll.py +54 -54
  356. package/tests/dataDisplay/AntdTable/feat_tag_mode_tooltip.py +88 -88
  357. package/tests/dataDisplay/AntdTable/feat_title_popover_nodes.py +94 -79
  358. package/tests/dataDisplay/AntdTable/fix_context_locale.py +37 -37
  359. package/tests/dataDisplay/AntdTable/fix_field_bool.py +50 -50
  360. package/tests/dataDisplay/AntdTable/fix_nested_editable.py +115 -115
  361. package/tests/dataDisplay/AntdTable/fix_select_with_editable.py +84 -84
  362. package/tests/dataDisplay/AntdTable/fix_server_side_mode_filter_search.py +194 -194
  363. package/tests/dataDisplay/AntdTable/fix_summary.py +474 -474
  364. package/tests/dataDisplay/AntdTable/fix_summary_multi_level_header.py +85 -85
  365. package/tests/dataDisplay/AntdTable/fix_zero_value_filter.py +34 -34
  366. package/tests/dataDisplay/AntdTable/perf_button_mode_auto_wrap.py +39 -39
  367. package/tests/dataDisplay/AntdTable/perf_editable_column_format_constrait_message.py +65 -65
  368. package/tests/dataDisplay/AntdTable/refactor_mini_progress_mode.py +134 -134
  369. package/tests/dataDisplay/AntdTable/rollback_title_popover_info.py +46 -0
  370. package/tests/dataDisplay/AntdTabs/feat_item_icon.py +39 -39
  371. package/tests/dataDisplay/AntdTabs/feat_placeholder.py +124 -124
  372. package/tests/dataDisplay/AntdTabs/feat_tab_bar_style.py +40 -40
  373. package/tests/dataDisplay/AntdTree/feat_async_data_load.py +71 -71
  374. package/tests/dataDisplay/descriptions/AntdDescriptions/feat_extra.py +83 -83
  375. package/tests/dataEntry/AntdCalendar/feat_custom_cells.py +52 -52
  376. package/tests/dataEntry/AntdCascader/feat_prefix.py +62 -62
  377. package/tests/dataEntry/AntdCascader/feat_suffix_icon.py +62 -62
  378. package/tests/dataEntry/AntdCascader/fix_read_only.py +74 -74
  379. package/tests/dataEntry/AntdDatePicker/feat_custom_cells.py +79 -79
  380. package/tests/dataEntry/AntdDatePicker/feat_picker_value.py +38 -38
  381. package/tests/dataEntry/AntdDatePicker/feat_prefix.py +21 -21
  382. package/tests/dataEntry/AntdDatePicker/feat_suffix_icon.py +21 -21
  383. package/tests/dataEntry/AntdDateRangePicker/feat_custom_cells.py +79 -79
  384. package/tests/dataEntry/AntdDateRangePicker/feat_picker_value.py +38 -38
  385. package/tests/dataEntry/AntdDateRangePicker/feat_prefix.py +21 -21
  386. package/tests/dataEntry/AntdDateRangePicker/feat_suffix_icon.py +21 -21
  387. package/tests/dataEntry/AntdForm/feat_batch_control_tooltips.py +35 -0
  388. package/tests/dataEntry/AntdForm/feat_optional_batch_control.py +62 -62
  389. package/tests/dataEntry/AntdForm/fix_checkbox.py +65 -65
  390. package/tests/dataEntry/AntdRadioGroup/feat_block.py +40 -40
  391. package/tests/dataEntry/AntdSelect/feat_locale_ru.py +24 -24
  392. package/tests/dataEntry/AntdSelect/feat_max_count.py +28 -28
  393. package/tests/dataEntry/AntdSelect/feat_prefix.py +26 -26
  394. package/tests/dataEntry/AntdSelect/feat_show_search.py +32 -32
  395. package/tests/dataEntry/AntdSelect/feat_suffix_icon.py +46 -46
  396. package/tests/dataEntry/AntdSelect/fix_read_only.py +50 -50
  397. package/tests/dataEntry/AntdSelect/fix_read_only_with_allow_clear.py +29 -29
  398. package/tests/dataEntry/AntdSlider/feat_range_editable.py +49 -49
  399. package/tests/dataEntry/AntdTimePicker/feat_prefix.py +21 -21
  400. package/tests/dataEntry/AntdTimePicker/feat_suffix_icon.py +21 -21
  401. package/tests/dataEntry/AntdTimeRangePicker/feat_prefix.py +21 -21
  402. package/tests/dataEntry/AntdTimeRangePicker/feat_suffix_icon.py +21 -21
  403. package/tests/dataEntry/AntdTreeSelect/feat_async_data_load.py +69 -69
  404. package/tests/dataEntry/AntdTreeSelect/feat_max_count.py +71 -71
  405. package/tests/dataEntry/AntdTreeSelect/feat_prefix.py +43 -43
  406. package/tests/dataEntry/AntdTreeSelect/fix_read_only.py +50 -50
  407. package/tests/dataEntry/AntdUpload/feat_pastable.py +22 -22
  408. package/tests/dataEntry/AntdUpload/fix_follow_theme.py +28 -28
  409. package/tests/feat_variant_underlined.py +100 -100
  410. package/tests/feedback/AntdAlert/feat_icon.py +35 -35
  411. package/tests/feedback/AntdMessage/fix_follow_config_provider.py +44 -44
  412. package/tests/feedback/AntdModal/feat_force_render.py +57 -57
  413. package/tests/feedback/AntdModal/feat_loading_title.py +92 -92
  414. package/tests/feedback/AntdModal/feat_prevent_close.py +54 -54
  415. package/tests/feedback/AntdModal/feat_responsive_width.py +31 -31
  416. package/tests/feedback/AntdNotification/feat_component_content.py +64 -64
  417. package/tests/feedback/AntdNotification/feat_number_of_stack.py +40 -40
  418. package/tests/feedback/AntdNotification/feat_show_progress.py +40 -40
  419. package/tests/feedback/AntdNotification/fix_follow_config_provider.py +46 -46
  420. package/tests/feedback/AntdPopupCard/feat_force_render.py +61 -61
  421. package/tests/feedback/AntdProgress/feat_percent_position.py +39 -39
  422. package/tests/feedback/AntdProgress/perf_size.py +26 -26
  423. package/tests/feedback/AntdProgress/perf_steps.py +37 -37
  424. package/tests/feedback/AntdProgress/perf_stroke_color.py +58 -58
  425. package/tests/feedback/AntdResult/feat_extra.py +26 -26
  426. package/tests/feedback/AntdSkeleton/fix_dash3.py +43 -43
  427. package/tests/general/AntdButton/feat_color_and_variant.py +40 -40
  428. package/tests/general/AntdButton/feat_preset_color.py +46 -46
  429. package/tests/general/AntdFloatButtonGroup/feat_placement.py +83 -83
  430. package/tests/general/AntdFloatButtonGroup/feat_tooltip.py +34 -34
  431. package/tests/general/AntdIcon/feat_iconfont.py +41 -41
  432. package/tests/layout/AntdCenter/feat_use_token.py +41 -41
  433. package/tests/layout/AntdDivider/feat_plain.py +21 -21
  434. package/tests/layout/AntdDivider/feat_size.py +36 -36
  435. package/tests/layout/AntdSplitter/feat_AntdSplitter.py +210 -210
  436. package/tests/layout/AntdSplitter/feat_lazy.py +56 -56
  437. package/tests/layout/AntdSplitter/refactor.py +303 -303
  438. package/tests/navigation/AntdAnchor/feat_current_anchor.py +43 -43
  439. package/tests/navigation/AntdAnchor/feat_direction.py +43 -43
  440. package/tests/navigation/AntdAnchor/feat_replace.py +43 -43
  441. package/tests/navigation/AntdBreadcrumb/feat_menu_item_event.py +64 -64
  442. package/tests/navigation/AntdBreadcrumb/refactor_items.py +140 -140
  443. package/tests/navigation/AntdDropdown/feat_extra.py +29 -29
  444. package/tests/navigation/AntdMenu/feat_currentItem.py +85 -85
  445. package/tests/navigation/AntdMenu/feat_currentItemPath.py +85 -85
  446. package/tests/navigation/AntdMenu/feat_currentKeyPath.py +85 -85
  447. package/tests/navigation/AntdMenu/feat_custom_icon.py +57 -57
  448. package/tests/navigation/AntdMenu/feat_expandIcon.py +70 -70
  449. package/tests/navigation/AntdMenu/feat_triggerSubMenuAction.py +67 -67
  450. package/tests/navigation/AntdMenu/fix_onlyExpandCurrentSubMenu.py +57 -57
  451. package/tests/navigation/AntdMenu/fix_with_sider.py +71 -71
  452. package/tests/navigation/AntdPagination/feat_align.py +31 -31
  453. package/tests/other/AntdAffix/feat_listen_affixed.py +41 -41
  454. package/tests/other/AntdBackTop/refactor.py +18 -18
  455. package/tests/other/AntdConfigProvider/feat_use_css.py +67 -67
  456. package/tests/other/AntdCopyText/feat_copy_table.py +67 -67
  457. package/tests/other/AntdCopyText/feat_tooltips.py +61 -61
  458. package/tests/other/AntdHappyProvider/feat_component.py +60 -60
  459. package/tests/other/Fragment/feat_use_token.py +32 -32
  460. package/usage.py +34 -34
  461. package/webpack.config.js +181 -181
  462. package/webpack.serve.config.js +12 -12
@@ -1,578 +1,578 @@
1
- // react核心
2
- import React, { useState, useEffect, useContext } from 'react';
3
- // antd核心
4
- import { Upload, message, Modal, ConfigProvider } from 'antd';
5
- import { PlusOutlined } from '@ant-design/icons';
6
- import ImgCrop from 'antd-img-crop';
7
- // 辅助库
8
- import { str2Locale, locale2text } from '../../components/locales.react';
9
- import { isUndefined, isString } from 'lodash';
10
- import { v4 as uuidv4 } from 'uuid';
11
- import { pickBy } from 'ramda';
12
- import { useLoading } from '../../components/utils';
13
- // 自定义hooks
14
- import useCss from '../../hooks/useCss';
15
- // 上下文
16
- import PropsContext from '../../contexts/PropsContext';
17
- import FormContext from '../../contexts/FormContext';
18
- // 状态管理
19
- import useFormStore from '../../store/formStore';
20
- // 参数类型
21
- import { propTypes, defaultProps } from '../../components/dataEntry/upload/AntdPictureUpload.react';
22
-
23
- // 解析历史任务完成时间信息
24
- const parseHistoryTaskCompleteTime = (e) => {
25
- let uid2CompleteTime = new Map()
26
- e.forEach((item) => {
27
- uid2CompleteTime.set(item.uid, item.completeTimestamp)
28
- })
29
- return uid2CompleteTime
30
- }
31
-
32
- const getBase64 = (file) => {
33
- return new Promise((resolve, reject) => {
34
- const reader = new FileReader();
35
- reader.readAsDataURL(file);
36
- reader.onload = () => resolve(reader.result);
37
- reader.onerror = error => reject(error);
38
- });
39
- }
40
-
41
- const pictureUploadStatus2Style = new Map([
42
- ['warning', {
43
- border: "1px solid #faad14",
44
- borderRadius: "2px",
45
- padding: "6px 10px 0 10px",
46
- transition: "border 0.3s"
47
- }],
48
- ['error', {
49
- border: "1px solid #ff4d4f",
50
- borderRadius: "2px",
51
- padding: "6px 10px 0 10px",
52
- transition: "border 0.3s"
53
- }]
54
- ])
55
-
56
- /**
57
- * 图片上传组件AntdPictureUpload
58
- */
59
- const AntdPictureUpload = (props) => {
60
- let {
61
- id,
62
- className,
63
- style,
64
- key,
65
- name,
66
- enableBatchControl,
67
- locale,
68
- apiUrl,
69
- apiUrlExtraParams,
70
- headers,
71
- withCredentials,
72
- downloadUrl,
73
- downloadUrlExtraParams,
74
- downloadUrlFromBackend,
75
- editable,
76
- editConfig,
77
- uploadId,
78
- fileListMaxLength,
79
- buttonContent,
80
- fileTypes,
81
- fileMaxSize,
82
- failedTooltipInfo,
83
- showRemoveIcon,
84
- showPreviewIcon,
85
- confirmBeforeDelete,
86
- showPercent,
87
- progressProps,
88
- showSuccessMessage,
89
- showErrorMessage,
90
- pastable,
91
- listUploadTaskRecord,
92
- defaultFileList,
93
- disabled,
94
- status,
95
- setProps,
96
- ...others
97
- } = props;
98
-
99
- const [messageApi, messageContextHolder] = message.useMessage();
100
- const [modalApi, modalContextHolder] = Modal.useModal();
101
-
102
- const context = useContext(PropsContext)
103
- const formId = useContext(FormContext)
104
-
105
- const updateItemValue = useFormStore((state) => state.updateItemValue)
106
- const deleteItemValue = useFormStore((state) => state.deleteItemValue)
107
-
108
- locale = (context && context.locale) || locale
109
- downloadUrlFromBackend = downloadUrl ? false : downloadUrlFromBackend
110
-
111
- // 收集当前组件相关表单值
112
- const currentFormValue = useFormStore(state => state.values?.[formId]?.[name || id])
113
-
114
- // 针对上传类组件,特殊处理由表单值控制上传列表的清空
115
- useEffect(() => {
116
- // 若上文中存在有效表单id
117
- if (formId && (name || id) && enableBatchControl) {
118
- if (!currentFormValue || currentFormValue.length === 0) {
119
- // 清空上传列表
120
- updateFileList([])
121
- setProps({
122
- listUploadTaskRecord: [],
123
- lastUploadTaskRecord: null
124
- })
125
- }
126
- }
127
- }, [currentFormValue])
128
-
129
- // 处理组件卸载后,对应表单项值的清除
130
- useEffect(() => {
131
- return () => {
132
- // 若上文中存在有效表单id
133
- if (formId && (name || id) && enableBatchControl) {
134
- // 表单值更新
135
- deleteItemValue(formId, name || id)
136
- }
137
- }
138
- }, [name, id])
139
-
140
- listUploadTaskRecord = listUploadTaskRecord || []
141
-
142
- // 更新已上传文件 -> 上传完成时间映射字典
143
- const uploadedFile2CompleteTime = parseHistoryTaskCompleteTime(listUploadTaskRecord)
144
-
145
- useEffect(() => {
146
- // 初始化uploadId
147
- if (!uploadId) {
148
- if (defaultFileList && defaultFileList.length > 0) {
149
- setProps({ uploadId: defaultFileList[0].taskId || uuidv4() })
150
- } else {
151
- setProps({ uploadId: uuidv4() })
152
- }
153
- }
154
- }, [])
155
-
156
- const [fileList, updateFileList] = useState(defaultFileList || listUploadTaskRecord.map((item) => {
157
- return {
158
- name: item.fileName,
159
- status: item.taskStatus,
160
- uid: item.uid,
161
- url: item.url,
162
- uploadResponse: item.uploadResponse,
163
- fileSize: item.fileSize
164
- };
165
- }));
166
- const [previewVisible, setPreviewVisible] = useState(false);
167
- const [previewImage, setPreviewImage] = useState('');
168
- const [previewTitle, setPreviewTitle] = useState('');
169
-
170
- const handleCancel = () => setPreviewVisible(false);
171
-
172
- const handlePreview = async file => {
173
- if (!file.url && !file.preview) {
174
- file.preview = await getBase64(file.originFileObj);
175
- }
176
-
177
- setPreviewImage(file.url || file.preview)
178
- setPreviewVisible(true)
179
- setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf('/') + 1))
180
-
181
- }
182
-
183
- const uploadButton = (
184
- <div>
185
- <PlusOutlined />
186
- <div style={{ marginTop: 8 }}>
187
- {buttonContent}
188
- </div>
189
- </div>
190
- );
191
-
192
- let uploadProps = {
193
- name: 'file',
194
- action: apiUrl + `?uploadId=${uploadId}`,
195
- headers: headers,
196
- data: {
197
- uploadId: uploadId,
198
- ...apiUrlExtraParams
199
- },
200
- withCredentials: withCredentials,
201
- beforeUpload: (file) => {
202
- const sizeCheck = file.size / 1024 / 1024 < fileMaxSize;
203
- if (!sizeCheck) {
204
- messageApi.error(`${file.name}${locale2text.Upload[locale].sizeError[0]}${fileMaxSize}${locale2text.Upload[locale].sizeError[1]}`);
205
- }
206
-
207
- if (fileTypes) {
208
- if (fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) === -1) {
209
- messageApi.error(`${locale2text.Upload[locale].typeError[0]}${file.name}${locale2text.Upload[locale].typeError[1]}`);
210
- }
211
-
212
- return sizeCheck && fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) !== -1;
213
- }
214
-
215
- return sizeCheck;
216
- },
217
- onChange(info) {
218
-
219
- // 计算最近一次任务的子任务数量
220
- let lastTaskCount
221
- if (info.file.status === 'removed') {
222
- lastTaskCount = 0
223
- } else {
224
- lastTaskCount = info.fileList.length - listUploadTaskRecord.length;
225
- }
226
-
227
- // 单文件上传模式
228
- // 若当前事件为removed
229
- if (info.file.status === 'removed') {
230
-
231
- let _listUploadTaskRecord = info.fileList.map(
232
- (file) => {
233
- // 配置已完成上传文件下载链接
234
- let urlInfo = downloadUrlFromBackend ?
235
- (file.response ? { url: file.response.url } : {}) :
236
- (
237
- downloadUrl && (file.status === 'done' || file.status === 'success') ?
238
- {
239
- url: downloadUrl + `?taskId=${uploadId}&filename=${file.name}` + (
240
- Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
241
- )
242
- } :
243
- {}
244
- )
245
- // 配置已完成上传文件接口响应信息
246
- let responseInfo = file.response ? { uploadResponse: file.response } : {}
247
- return {
248
- fileName: file.name,
249
- fileSize: file.size,
250
- completeTimestamp: uploadedFile2CompleteTime.get(file.uid) || new Date().getTime(),
251
- taskStatus: (file.status === 'done' || file.status === 'success') ? 'success' : 'failed',
252
- taskId: uploadId,
253
- uid: file.uid,
254
- ...urlInfo,
255
- ...responseInfo
256
- }
257
- }
258
- )
259
-
260
- // AntdForm表单批量控制
261
- if (formId && (name || id) && enableBatchControl) {
262
- // 表单值更新
263
- updateItemValue(formId, name || id, _listUploadTaskRecord)
264
- }
265
- // 更新任务记录
266
- setProps({
267
- listUploadTaskRecord: _listUploadTaskRecord
268
- })
269
- } else if (info.file.status === 'done' || info.file.status === 'success' || info.file.status === 'error' || !info.file.status) {
270
- let _listUploadTaskRecord = info.fileList.map(
271
- (file) => {
272
- // 配置已完成上传文件下载链接
273
- let urlInfo = downloadUrlFromBackend ?
274
- (file.response ? { url: file.response.url } : {}) :
275
- (
276
- downloadUrl && (file.status === 'done' || file.status === 'success') ?
277
- {
278
- url: downloadUrl + `?taskId=${uploadId}&filename=${file.name}` + (
279
- Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
280
- )
281
- } :
282
- {}
283
- )
284
- // 配置已完成上传文件接口响应信息
285
- let responseInfo = file.response ? { uploadResponse: file.response } : {}
286
- return {
287
- fileName: file.name,
288
- fileSize: file.size,
289
- completeTimestamp: uploadedFile2CompleteTime.get(file.uid) || new Date().getTime(),
290
- taskStatus: (file.status === 'done' || file.status === 'success') ? 'success' : 'failed',
291
- taskId: uploadId,
292
- uid: file.uid,
293
- ...urlInfo,
294
- ...responseInfo
295
- }
296
- }
297
- )
298
-
299
- // AntdForm表单批量控制
300
- if (formId && (name || id) && enableBatchControl) {
301
- // 表单值更新
302
- updateItemValue(formId, name || id, _listUploadTaskRecord)
303
- }
304
- setProps({
305
- lastUploadTaskRecord: {
306
- fileName: info.file.name,
307
- fileSize: info.file.size,
308
- completeTimestamp: new Date().getTime(),
309
- taskStatus: (info.file.status === 'done' || info.file.status === 'success') ? 'success' : 'failed',
310
- taskId: uploadId,
311
- ...(
312
- downloadUrlFromBackend ?
313
- (info.file.response ? { url: info.file.response.url } : {}) :
314
- (
315
- downloadUrl && (info.file.status === 'done' || info.file.status === 'success') ?
316
- {
317
- url: downloadUrl + `?taskId=${uploadId}&filename=${info.file.name}` + (
318
- Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
319
- )
320
- } :
321
- {}
322
- )
323
- ),
324
- ...(
325
- info.file.response ? { uploadResponse: info.file.response } : {}
326
- )
327
- },
328
- listUploadTaskRecord: _listUploadTaskRecord
329
- })
330
- }
331
-
332
- if ((info.file.status === 'done' || info.file.status === 'success') && showSuccessMessage) {
333
- messageApi.success(`${info.file.name} ${locale2text.Upload[locale].uploadSuccess}`);
334
- } else if (info.file.status === 'error' && showErrorMessage) {
335
- messageApi.error(`${info.file.name} ${locale2text.Upload[locale].uploadFailed}`);
336
- }
337
-
338
- // 获取当前上传文件列表
339
- let _fileList = [...info.fileList];
340
-
341
- // 是否限制上传记录列表最大数量
342
- if (fileListMaxLength) {
343
- _fileList = _fileList.slice(-fileListMaxLength);
344
- }
345
-
346
- if (lastTaskCount !== 0) {
347
- _fileList = _fileList.slice(0, _fileList.length - lastTaskCount)
348
- .concat(
349
- _fileList.slice(-lastTaskCount).map(
350
- item => {
351
- if (item.status === 'error' || !item.status) {
352
-
353
- item.status = 'error'
354
- item.response = failedTooltipInfo ? failedTooltipInfo : '上传失败'
355
- }
356
- return item
357
- }
358
- )
359
- )
360
- }
361
-
362
- if (downloadUrl) {
363
- updateFileList(
364
- _fileList.map(
365
- item => {
366
- // 配置已完成上传文件接口响应信息
367
- let responseInfo = item.response ? { uploadResponse: item.response } : {}
368
- return {
369
- ...item,
370
- url: downloadUrl + `?taskId=${uploadId}&filename=${item.name}` + (
371
- Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
372
- ),
373
- ...responseInfo
374
- }
375
- }
376
- )
377
- )
378
- } else if (downloadUrlFromBackend) {
379
- updateFileList(
380
- _fileList.map(
381
- item => {
382
- if (item.response) {
383
- return {
384
- ...item,
385
- url: item.response.url,
386
- uploadResponse: item.response
387
- }
388
- }
389
- return {
390
- ...item
391
- }
392
- }
393
- )
394
- )
395
- } else {
396
- updateFileList(_fileList)
397
- }
398
- }
399
- };
400
-
401
- // 添加accept参数
402
- if (fileTypes && fileTypes.length != 0) {
403
-
404
- Object.assign(uploadProps, { accept: '.' + fileTypes.join(',.') })
405
- }
406
-
407
- if (editable) {
408
-
409
- return (
410
- <ConfigProvider locale={str2Locale.get(locale)}>
411
- <div
412
- // 提取具有data-*或aria-*通配格式的属性
413
- {...pickBy((_, k) => k.startsWith('data-') || k.startsWith('aria-'), others)}
414
- id={id}
415
- className={
416
- isString(className) ?
417
- className :
418
- (className ? useCss(className) : undefined)
419
- }
420
- style={{
421
- border: "1px solid transparent",
422
- transition: "border 0.3s",
423
- ...pictureUploadStatus2Style.get(status),
424
- ...style
425
- }}
426
- key={key}>
427
- {messageContextHolder}
428
- {modalContextHolder}
429
- <ImgCrop modalOk={locale2text.AntdPictureUpload[locale].imgCropModalOKText}
430
- modalCancel={locale2text.AntdPictureUpload[locale].imgCropModalCancelText}
431
- {...editConfig}>
432
- <Upload {...uploadProps}
433
- fileList={fileList}
434
- listType="picture-card"
435
- disabled={
436
- context && !isUndefined(context.componentDisabled) ?
437
- context.componentDisabled :
438
- disabled
439
- }
440
- progress={
441
- progressProps || showPercent ?
442
- {
443
- strokeColor: progressProps && progressProps.strokeColor,
444
- strokeWidth: (progressProps && progressProps.strokeWidth) || 2,
445
- format: (
446
- showPercent ? (
447
- (percent) => percent && `${(progressProps && progressProps.prefix) || ''}${parseFloat(percent.toFixed(1))}${(progressProps && progressProps.suffix) || '%'}`
448
- ) :
449
- undefined
450
- )
451
- } :
452
- undefined
453
- }
454
- showUploadList={{
455
- showRemoveIcon,
456
- showPreviewIcon
457
- }}
458
- pastable={pastable}
459
- onPreview={handlePreview}
460
- onRemove={
461
- confirmBeforeDelete ?
462
- () => {
463
- return new Promise((resolve, reject) => {
464
- modalApi.confirm({
465
- title: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteTitle,
466
- okText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteOkText,
467
- cancelText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteCancelText,
468
- onOk: () => {
469
- resolve(true);
470
- },
471
-
472
- });
473
- });
474
- } :
475
- undefined
476
- }
477
- data-dash-is-loading={useLoading()}>
478
- {uploadButton}
479
- </Upload>
480
- </ImgCrop>
481
- <Modal
482
- open={previewVisible}
483
- title={previewTitle}
484
- footer={null}
485
- onCancel={handleCancel}
486
- >
487
- <img alt="" style={{ width: '100%' }} src={previewImage} />
488
- </Modal>
489
- </div>
490
- </ConfigProvider>
491
- );
492
- }
493
-
494
- return (
495
- <ConfigProvider locale={str2Locale.get(locale)}>
496
- <div
497
- // 提取具有data-*或aria-*通配格式的属性
498
- {...pickBy((_, k) => k.startsWith('data-') || k.startsWith('aria-'), others)}
499
- id={id}
500
- className={
501
- isString(className) ?
502
- className :
503
- (className ? useCss(className) : undefined)
504
- }
505
- style={{
506
- border: "1px solid transparent",
507
- transition: "border 0.3s",
508
- ...pictureUploadStatus2Style.get(status),
509
- ...style
510
- }}
511
- key={key}>
512
- {messageContextHolder}
513
- {modalContextHolder}
514
- <Upload {...uploadProps}
515
- fileList={fileList}
516
- listType="picture-card"
517
- disabled={
518
- context && !isUndefined(context.componentDisabled) ?
519
- context.componentDisabled :
520
- disabled
521
- }
522
- progress={
523
- progressProps || showPercent ?
524
- {
525
- strokeColor: progressProps && progressProps.strokeColor,
526
- strokeWidth: (progressProps && progressProps.strokeWidth) || 2,
527
- format: (
528
- showPercent ? (
529
- (percent) => percent && `${(progressProps && progressProps.prefix) || ''}${parseFloat(percent.toFixed(1))}${(progressProps && progressProps.suffix) || '%'}`
530
- ) :
531
- undefined
532
- )
533
- } :
534
- undefined
535
- }
536
- showUploadList={{
537
- showRemoveIcon,
538
- showPreviewIcon
539
- }}
540
- pastable={pastable}
541
- onPreview={handlePreview}
542
- onRemove={
543
- confirmBeforeDelete ?
544
- () => {
545
- return new Promise((resolve, reject) => {
546
- modalApi.confirm({
547
- title: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteTitle,
548
- okText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteOkText,
549
- cancelText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteCancelText,
550
- onOk: () => {
551
- resolve(true);
552
- },
553
-
554
- });
555
- });
556
- } :
557
- undefined
558
- }
559
- data-dash-is-loading={useLoading()}>
560
- {uploadButton}
561
- </Upload>
562
- <Modal
563
- open={previewVisible}
564
- title={previewTitle}
565
- footer={null}
566
- onCancel={handleCancel}
567
- >
568
- <img alt="" style={{ width: '100%' }} src={previewImage} />
569
- </Modal>
570
- </div>
571
- </ConfigProvider>
572
- );
573
- }
574
-
575
- export default AntdPictureUpload;
576
-
577
- AntdPictureUpload.defaultProps = defaultProps;
1
+ // react核心
2
+ import React, { useState, useEffect, useContext } from 'react';
3
+ // antd核心
4
+ import { Upload, message, Modal, ConfigProvider } from 'antd';
5
+ import { PlusOutlined } from '@ant-design/icons';
6
+ import ImgCrop from 'antd-img-crop';
7
+ // 辅助库
8
+ import { str2Locale, locale2text } from '../../components/locales.react';
9
+ import { isUndefined, isString } from 'lodash';
10
+ import { v4 as uuidv4 } from 'uuid';
11
+ import { pickBy } from 'ramda';
12
+ import { useLoading } from '../../components/utils';
13
+ // 自定义hooks
14
+ import useCss from '../../hooks/useCss';
15
+ // 上下文
16
+ import PropsContext from '../../contexts/PropsContext';
17
+ import FormContext from '../../contexts/FormContext';
18
+ // 状态管理
19
+ import useFormStore from '../../store/formStore';
20
+ // 参数类型
21
+ import { propTypes, defaultProps } from '../../components/dataEntry/upload/AntdPictureUpload.react';
22
+
23
+ // 解析历史任务完成时间信息
24
+ const parseHistoryTaskCompleteTime = (e) => {
25
+ let uid2CompleteTime = new Map()
26
+ e.forEach((item) => {
27
+ uid2CompleteTime.set(item.uid, item.completeTimestamp)
28
+ })
29
+ return uid2CompleteTime
30
+ }
31
+
32
+ const getBase64 = (file) => {
33
+ return new Promise((resolve, reject) => {
34
+ const reader = new FileReader();
35
+ reader.readAsDataURL(file);
36
+ reader.onload = () => resolve(reader.result);
37
+ reader.onerror = error => reject(error);
38
+ });
39
+ }
40
+
41
+ const pictureUploadStatus2Style = new Map([
42
+ ['warning', {
43
+ border: "1px solid #faad14",
44
+ borderRadius: "2px",
45
+ padding: "6px 10px 0 10px",
46
+ transition: "border 0.3s"
47
+ }],
48
+ ['error', {
49
+ border: "1px solid #ff4d4f",
50
+ borderRadius: "2px",
51
+ padding: "6px 10px 0 10px",
52
+ transition: "border 0.3s"
53
+ }]
54
+ ])
55
+
56
+ /**
57
+ * 图片上传组件AntdPictureUpload
58
+ */
59
+ const AntdPictureUpload = (props) => {
60
+ let {
61
+ id,
62
+ className,
63
+ style,
64
+ key,
65
+ name,
66
+ enableBatchControl,
67
+ locale,
68
+ apiUrl,
69
+ apiUrlExtraParams,
70
+ headers,
71
+ withCredentials,
72
+ downloadUrl,
73
+ downloadUrlExtraParams,
74
+ downloadUrlFromBackend,
75
+ editable,
76
+ editConfig,
77
+ uploadId,
78
+ fileListMaxLength,
79
+ buttonContent,
80
+ fileTypes,
81
+ fileMaxSize,
82
+ failedTooltipInfo,
83
+ showRemoveIcon,
84
+ showPreviewIcon,
85
+ confirmBeforeDelete,
86
+ showPercent,
87
+ progressProps,
88
+ showSuccessMessage,
89
+ showErrorMessage,
90
+ pastable,
91
+ listUploadTaskRecord,
92
+ defaultFileList,
93
+ disabled,
94
+ status,
95
+ setProps,
96
+ ...others
97
+ } = props;
98
+
99
+ const [messageApi, messageContextHolder] = message.useMessage();
100
+ const [modalApi, modalContextHolder] = Modal.useModal();
101
+
102
+ const context = useContext(PropsContext)
103
+ const formId = useContext(FormContext)
104
+
105
+ const updateItemValue = useFormStore((state) => state.updateItemValue)
106
+ const deleteItemValue = useFormStore((state) => state.deleteItemValue)
107
+
108
+ locale = (context && context.locale) || locale
109
+ downloadUrlFromBackend = downloadUrl ? false : downloadUrlFromBackend
110
+
111
+ // 收集当前组件相关表单值
112
+ const currentFormValue = useFormStore(state => state.values?.[formId]?.[name || id])
113
+
114
+ // 针对上传类组件,特殊处理由表单值控制上传列表的清空
115
+ useEffect(() => {
116
+ // 若上文中存在有效表单id
117
+ if (formId && (name || id) && enableBatchControl) {
118
+ if (!currentFormValue || currentFormValue.length === 0) {
119
+ // 清空上传列表
120
+ updateFileList([])
121
+ setProps({
122
+ listUploadTaskRecord: [],
123
+ lastUploadTaskRecord: null
124
+ })
125
+ }
126
+ }
127
+ }, [currentFormValue])
128
+
129
+ // 处理组件卸载后,对应表单项值的清除
130
+ useEffect(() => {
131
+ return () => {
132
+ // 若上文中存在有效表单id
133
+ if (formId && (name || id) && enableBatchControl) {
134
+ // 表单值更新
135
+ deleteItemValue(formId, name || id)
136
+ }
137
+ }
138
+ }, [name, id])
139
+
140
+ listUploadTaskRecord = listUploadTaskRecord || []
141
+
142
+ // 更新已上传文件 -> 上传完成时间映射字典
143
+ const uploadedFile2CompleteTime = parseHistoryTaskCompleteTime(listUploadTaskRecord)
144
+
145
+ useEffect(() => {
146
+ // 初始化uploadId
147
+ if (!uploadId) {
148
+ if (defaultFileList && defaultFileList.length > 0) {
149
+ setProps({ uploadId: defaultFileList[0].taskId || uuidv4() })
150
+ } else {
151
+ setProps({ uploadId: uuidv4() })
152
+ }
153
+ }
154
+ }, [])
155
+
156
+ const [fileList, updateFileList] = useState(defaultFileList || listUploadTaskRecord.map((item) => {
157
+ return {
158
+ name: item.fileName,
159
+ status: item.taskStatus,
160
+ uid: item.uid,
161
+ url: item.url,
162
+ uploadResponse: item.uploadResponse,
163
+ fileSize: item.fileSize
164
+ };
165
+ }));
166
+ const [previewVisible, setPreviewVisible] = useState(false);
167
+ const [previewImage, setPreviewImage] = useState('');
168
+ const [previewTitle, setPreviewTitle] = useState('');
169
+
170
+ const handleCancel = () => setPreviewVisible(false);
171
+
172
+ const handlePreview = async file => {
173
+ if (!file.url && !file.preview) {
174
+ file.preview = await getBase64(file.originFileObj);
175
+ }
176
+
177
+ setPreviewImage(file.url || file.preview)
178
+ setPreviewVisible(true)
179
+ setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf('/') + 1))
180
+
181
+ }
182
+
183
+ const uploadButton = (
184
+ <div>
185
+ <PlusOutlined />
186
+ <div style={{ marginTop: 8 }}>
187
+ {buttonContent}
188
+ </div>
189
+ </div>
190
+ );
191
+
192
+ let uploadProps = {
193
+ name: 'file',
194
+ action: apiUrl + `?uploadId=${uploadId}`,
195
+ headers: headers,
196
+ data: {
197
+ uploadId: uploadId,
198
+ ...apiUrlExtraParams
199
+ },
200
+ withCredentials: withCredentials,
201
+ beforeUpload: (file) => {
202
+ const sizeCheck = file.size / 1024 / 1024 < fileMaxSize;
203
+ if (!sizeCheck) {
204
+ messageApi.error(`${file.name}${locale2text.Upload[locale].sizeError[0]}${fileMaxSize}${locale2text.Upload[locale].sizeError[1]}`);
205
+ }
206
+
207
+ if (fileTypes) {
208
+ if (fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) === -1) {
209
+ messageApi.error(`${locale2text.Upload[locale].typeError[0]}${file.name}${locale2text.Upload[locale].typeError[1]}`);
210
+ }
211
+
212
+ return sizeCheck && fileTypes.indexOf(file.name.split('.')[file.name.split('.').length - 1]) !== -1;
213
+ }
214
+
215
+ return sizeCheck;
216
+ },
217
+ onChange(info) {
218
+
219
+ // 计算最近一次任务的子任务数量
220
+ let lastTaskCount
221
+ if (info.file.status === 'removed') {
222
+ lastTaskCount = 0
223
+ } else {
224
+ lastTaskCount = info.fileList.length - listUploadTaskRecord.length;
225
+ }
226
+
227
+ // 单文件上传模式
228
+ // 若当前事件为removed
229
+ if (info.file.status === 'removed') {
230
+
231
+ let _listUploadTaskRecord = info.fileList.map(
232
+ (file) => {
233
+ // 配置已完成上传文件下载链接
234
+ let urlInfo = downloadUrlFromBackend ?
235
+ (file.response ? { url: file.response.url } : {}) :
236
+ (
237
+ downloadUrl && (file.status === 'done' || file.status === 'success') ?
238
+ {
239
+ url: downloadUrl + `?taskId=${uploadId}&filename=${file.name}` + (
240
+ Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
241
+ )
242
+ } :
243
+ {}
244
+ )
245
+ // 配置已完成上传文件接口响应信息
246
+ let responseInfo = file.response ? { uploadResponse: file.response } : {}
247
+ return {
248
+ fileName: file.name,
249
+ fileSize: file.size,
250
+ completeTimestamp: uploadedFile2CompleteTime.get(file.uid) || new Date().getTime(),
251
+ taskStatus: (file.status === 'done' || file.status === 'success') ? 'success' : 'failed',
252
+ taskId: uploadId,
253
+ uid: file.uid,
254
+ ...urlInfo,
255
+ ...responseInfo
256
+ }
257
+ }
258
+ )
259
+
260
+ // AntdForm表单批量控制
261
+ if (formId && (name || id) && enableBatchControl) {
262
+ // 表单值更新
263
+ updateItemValue(formId, name || id, _listUploadTaskRecord)
264
+ }
265
+ // 更新任务记录
266
+ setProps({
267
+ listUploadTaskRecord: _listUploadTaskRecord
268
+ })
269
+ } else if (info.file.status === 'done' || info.file.status === 'success' || info.file.status === 'error' || !info.file.status) {
270
+ let _listUploadTaskRecord = info.fileList.map(
271
+ (file) => {
272
+ // 配置已完成上传文件下载链接
273
+ let urlInfo = downloadUrlFromBackend ?
274
+ (file.response ? { url: file.response.url } : {}) :
275
+ (
276
+ downloadUrl && (file.status === 'done' || file.status === 'success') ?
277
+ {
278
+ url: downloadUrl + `?taskId=${uploadId}&filename=${file.name}` + (
279
+ Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
280
+ )
281
+ } :
282
+ {}
283
+ )
284
+ // 配置已完成上传文件接口响应信息
285
+ let responseInfo = file.response ? { uploadResponse: file.response } : {}
286
+ return {
287
+ fileName: file.name,
288
+ fileSize: file.size,
289
+ completeTimestamp: uploadedFile2CompleteTime.get(file.uid) || new Date().getTime(),
290
+ taskStatus: (file.status === 'done' || file.status === 'success') ? 'success' : 'failed',
291
+ taskId: uploadId,
292
+ uid: file.uid,
293
+ ...urlInfo,
294
+ ...responseInfo
295
+ }
296
+ }
297
+ )
298
+
299
+ // AntdForm表单批量控制
300
+ if (formId && (name || id) && enableBatchControl) {
301
+ // 表单值更新
302
+ updateItemValue(formId, name || id, _listUploadTaskRecord)
303
+ }
304
+ setProps({
305
+ lastUploadTaskRecord: {
306
+ fileName: info.file.name,
307
+ fileSize: info.file.size,
308
+ completeTimestamp: new Date().getTime(),
309
+ taskStatus: (info.file.status === 'done' || info.file.status === 'success') ? 'success' : 'failed',
310
+ taskId: uploadId,
311
+ ...(
312
+ downloadUrlFromBackend ?
313
+ (info.file.response ? { url: info.file.response.url } : {}) :
314
+ (
315
+ downloadUrl && (info.file.status === 'done' || info.file.status === 'success') ?
316
+ {
317
+ url: downloadUrl + `?taskId=${uploadId}&filename=${info.file.name}` + (
318
+ Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
319
+ )
320
+ } :
321
+ {}
322
+ )
323
+ ),
324
+ ...(
325
+ info.file.response ? { uploadResponse: info.file.response } : {}
326
+ )
327
+ },
328
+ listUploadTaskRecord: _listUploadTaskRecord
329
+ })
330
+ }
331
+
332
+ if ((info.file.status === 'done' || info.file.status === 'success') && showSuccessMessage) {
333
+ messageApi.success(`${info.file.name} ${locale2text.Upload[locale].uploadSuccess}`);
334
+ } else if (info.file.status === 'error' && showErrorMessage) {
335
+ messageApi.error(`${info.file.name} ${locale2text.Upload[locale].uploadFailed}`);
336
+ }
337
+
338
+ // 获取当前上传文件列表
339
+ let _fileList = [...info.fileList];
340
+
341
+ // 是否限制上传记录列表最大数量
342
+ if (fileListMaxLength) {
343
+ _fileList = _fileList.slice(-fileListMaxLength);
344
+ }
345
+
346
+ if (lastTaskCount !== 0) {
347
+ _fileList = _fileList.slice(0, _fileList.length - lastTaskCount)
348
+ .concat(
349
+ _fileList.slice(-lastTaskCount).map(
350
+ item => {
351
+ if (item.status === 'error' || !item.status) {
352
+
353
+ item.status = 'error'
354
+ item.response = failedTooltipInfo ? failedTooltipInfo : '上传失败'
355
+ }
356
+ return item
357
+ }
358
+ )
359
+ )
360
+ }
361
+
362
+ if (downloadUrl) {
363
+ updateFileList(
364
+ _fileList.map(
365
+ item => {
366
+ // 配置已完成上传文件接口响应信息
367
+ let responseInfo = item.response ? { uploadResponse: item.response } : {}
368
+ return {
369
+ ...item,
370
+ url: downloadUrl + `?taskId=${uploadId}&filename=${item.name}` + (
371
+ Object.keys(downloadUrlExtraParams).map(key => `&${key}=${downloadUrlExtraParams[key]}`).join('')
372
+ ),
373
+ ...responseInfo
374
+ }
375
+ }
376
+ )
377
+ )
378
+ } else if (downloadUrlFromBackend) {
379
+ updateFileList(
380
+ _fileList.map(
381
+ item => {
382
+ if (item.response) {
383
+ return {
384
+ ...item,
385
+ url: item.response.url,
386
+ uploadResponse: item.response
387
+ }
388
+ }
389
+ return {
390
+ ...item
391
+ }
392
+ }
393
+ )
394
+ )
395
+ } else {
396
+ updateFileList(_fileList)
397
+ }
398
+ }
399
+ };
400
+
401
+ // 添加accept参数
402
+ if (fileTypes && fileTypes.length != 0) {
403
+
404
+ Object.assign(uploadProps, { accept: '.' + fileTypes.join(',.') })
405
+ }
406
+
407
+ if (editable) {
408
+
409
+ return (
410
+ <ConfigProvider locale={str2Locale.get(locale)}>
411
+ <div
412
+ // 提取具有data-*或aria-*通配格式的属性
413
+ {...pickBy((_, k) => k.startsWith('data-') || k.startsWith('aria-'), others)}
414
+ id={id}
415
+ className={
416
+ isString(className) ?
417
+ className :
418
+ (className ? useCss(className) : undefined)
419
+ }
420
+ style={{
421
+ border: "1px solid transparent",
422
+ transition: "border 0.3s",
423
+ ...pictureUploadStatus2Style.get(status),
424
+ ...style
425
+ }}
426
+ key={key}>
427
+ {messageContextHolder}
428
+ {modalContextHolder}
429
+ <ImgCrop modalOk={locale2text.AntdPictureUpload[locale].imgCropModalOKText}
430
+ modalCancel={locale2text.AntdPictureUpload[locale].imgCropModalCancelText}
431
+ {...editConfig}>
432
+ <Upload {...uploadProps}
433
+ fileList={fileList}
434
+ listType="picture-card"
435
+ disabled={
436
+ context && !isUndefined(context.componentDisabled) ?
437
+ context.componentDisabled :
438
+ disabled
439
+ }
440
+ progress={
441
+ progressProps || showPercent ?
442
+ {
443
+ strokeColor: progressProps && progressProps.strokeColor,
444
+ strokeWidth: (progressProps && progressProps.strokeWidth) || 2,
445
+ format: (
446
+ showPercent ? (
447
+ (percent) => percent && `${(progressProps && progressProps.prefix) || ''}${parseFloat(percent.toFixed(1))}${(progressProps && progressProps.suffix) || '%'}`
448
+ ) :
449
+ undefined
450
+ )
451
+ } :
452
+ undefined
453
+ }
454
+ showUploadList={{
455
+ showRemoveIcon,
456
+ showPreviewIcon
457
+ }}
458
+ pastable={pastable}
459
+ onPreview={handlePreview}
460
+ onRemove={
461
+ confirmBeforeDelete ?
462
+ () => {
463
+ return new Promise((resolve, reject) => {
464
+ modalApi.confirm({
465
+ title: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteTitle,
466
+ okText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteOkText,
467
+ cancelText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteCancelText,
468
+ onOk: () => {
469
+ resolve(true);
470
+ },
471
+
472
+ });
473
+ });
474
+ } :
475
+ undefined
476
+ }
477
+ data-dash-is-loading={useLoading()}>
478
+ {uploadButton}
479
+ </Upload>
480
+ </ImgCrop>
481
+ <Modal
482
+ open={previewVisible}
483
+ title={previewTitle}
484
+ footer={null}
485
+ onCancel={handleCancel}
486
+ >
487
+ <img alt="" style={{ width: '100%' }} src={previewImage} />
488
+ </Modal>
489
+ </div>
490
+ </ConfigProvider>
491
+ );
492
+ }
493
+
494
+ return (
495
+ <ConfigProvider locale={str2Locale.get(locale)}>
496
+ <div
497
+ // 提取具有data-*或aria-*通配格式的属性
498
+ {...pickBy((_, k) => k.startsWith('data-') || k.startsWith('aria-'), others)}
499
+ id={id}
500
+ className={
501
+ isString(className) ?
502
+ className :
503
+ (className ? useCss(className) : undefined)
504
+ }
505
+ style={{
506
+ border: "1px solid transparent",
507
+ transition: "border 0.3s",
508
+ ...pictureUploadStatus2Style.get(status),
509
+ ...style
510
+ }}
511
+ key={key}>
512
+ {messageContextHolder}
513
+ {modalContextHolder}
514
+ <Upload {...uploadProps}
515
+ fileList={fileList}
516
+ listType="picture-card"
517
+ disabled={
518
+ context && !isUndefined(context.componentDisabled) ?
519
+ context.componentDisabled :
520
+ disabled
521
+ }
522
+ progress={
523
+ progressProps || showPercent ?
524
+ {
525
+ strokeColor: progressProps && progressProps.strokeColor,
526
+ strokeWidth: (progressProps && progressProps.strokeWidth) || 2,
527
+ format: (
528
+ showPercent ? (
529
+ (percent) => percent && `${(progressProps && progressProps.prefix) || ''}${parseFloat(percent.toFixed(1))}${(progressProps && progressProps.suffix) || '%'}`
530
+ ) :
531
+ undefined
532
+ )
533
+ } :
534
+ undefined
535
+ }
536
+ showUploadList={{
537
+ showRemoveIcon,
538
+ showPreviewIcon
539
+ }}
540
+ pastable={pastable}
541
+ onPreview={handlePreview}
542
+ onRemove={
543
+ confirmBeforeDelete ?
544
+ () => {
545
+ return new Promise((resolve, reject) => {
546
+ modalApi.confirm({
547
+ title: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteTitle,
548
+ okText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteOkText,
549
+ cancelText: locale2text.AntdPictureUpload[locale].confirmBeforeDeleteCancelText,
550
+ onOk: () => {
551
+ resolve(true);
552
+ },
553
+
554
+ });
555
+ });
556
+ } :
557
+ undefined
558
+ }
559
+ data-dash-is-loading={useLoading()}>
560
+ {uploadButton}
561
+ </Upload>
562
+ <Modal
563
+ open={previewVisible}
564
+ title={previewTitle}
565
+ footer={null}
566
+ onCancel={handleCancel}
567
+ >
568
+ <img alt="" style={{ width: '100%' }} src={previewImage} />
569
+ </Modal>
570
+ </div>
571
+ </ConfigProvider>
572
+ );
573
+ }
574
+
575
+ export default AntdPictureUpload;
576
+
577
+ AntdPictureUpload.defaultProps = defaultProps;
578
578
  AntdPictureUpload.propTypes = propTypes;