@yoka-ui/ui 1.0.10-test → 1.1.0

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 (385) hide show
  1. package/@Docs-yoka/exports.generated.md +68 -62
  2. package/README.md +40 -189
  3. package/dist/es/assets/image/skills.zip +0 -0
  4. package/dist/es/business/AiChat/index.d.ts +3 -3
  5. package/dist/es/business/AiChat/index.js +331 -119
  6. package/dist/es/business/AiChat/index.js.map +3 -3
  7. package/dist/es/business/AiChat/intentRecognizer.js.map +1 -1
  8. package/dist/es/business/AiChat/navigationManager.js +6 -6
  9. package/dist/es/business/AiChat/navigationManager.js.map +2 -2
  10. package/dist/es/business/AiChat/sse.d.ts +15 -0
  11. package/dist/es/business/AiChat/sse.js +118 -7
  12. package/dist/es/business/AiChat/sse.js.map +2 -2
  13. package/dist/es/business/AiChat/type.d.ts +22 -23
  14. package/dist/es/business/AiChat/useAiChat.js +105 -75
  15. package/dist/es/business/AiChat/useAiChat.js.map +3 -3
  16. package/dist/es/business/AiChat/useTaskWorkflow.d.ts +1 -2
  17. package/dist/es/business/AiChat/useTaskWorkflow.js +2 -36
  18. package/dist/es/business/AiChat/useTaskWorkflow.js.map +2 -2
  19. package/dist/es/business/DrawerPageInfo/index.js.map +1 -1
  20. package/dist/es/business/Editor/index.d.ts +1 -1
  21. package/dist/es/business/Editor/index.js.map +2 -2
  22. package/dist/es/business/Empty/index.js +1 -1
  23. package/dist/es/business/Empty/index.js.map +1 -1
  24. package/dist/es/business/ModCommonFilter/components/PopoverContent/Category.js +2 -2
  25. package/dist/es/business/ModCommonFilter/components/PopoverContent/Category.js.map +2 -2
  26. package/dist/es/business/ModCommonFilter/components/PopoverContent/Content.js +3 -3
  27. package/dist/es/business/ModCommonFilter/components/PopoverContent/Content.js.map +2 -2
  28. package/dist/es/business/ModCommonFilter/components/PopoverContent/Selected.js +2 -2
  29. package/dist/es/business/ModCommonFilter/components/PopoverContent/Selected.js.map +2 -2
  30. package/dist/es/business/ModCommonFilter/index.d.ts +1 -1
  31. package/dist/es/business/ModCommonFilter/index.js.map +2 -2
  32. package/dist/es/business/YkCharts/Area.d.ts +18 -0
  33. package/dist/es/business/YkCharts/Area.js +336 -0
  34. package/dist/es/business/YkCharts/Area.js.map +7 -0
  35. package/dist/es/business/YkCharts/Bar.d.ts +21 -0
  36. package/dist/es/business/YkCharts/Bar.js +316 -0
  37. package/dist/es/business/YkCharts/Bar.js.map +7 -0
  38. package/dist/es/business/YkCharts/BarProperty.d.ts +21 -0
  39. package/dist/es/business/YkCharts/BarProperty.js +357 -0
  40. package/dist/es/business/YkCharts/BarProperty.js.map +7 -0
  41. package/dist/es/business/YkCharts/BarTotal.d.ts +21 -0
  42. package/dist/es/business/YkCharts/BarTotal.js +292 -0
  43. package/dist/es/business/YkCharts/BarTotal.js.map +7 -0
  44. package/dist/es/business/YkCharts/Line.d.ts +21 -0
  45. package/dist/es/business/YkCharts/Line.js +342 -0
  46. package/dist/es/business/YkCharts/Line.js.map +7 -0
  47. package/dist/es/business/YkCharts/Pie.d.ts +19 -0
  48. package/dist/es/business/YkCharts/Pie.js +107 -0
  49. package/dist/es/business/YkCharts/Pie.js.map +7 -0
  50. package/dist/es/business/YkCharts/PieProperty.d.ts +18 -0
  51. package/dist/es/business/YkCharts/PieProperty.js +180 -0
  52. package/dist/es/business/YkCharts/PieProperty.js.map +7 -0
  53. package/dist/es/business/YkCharts/Pies.d.ts +26 -0
  54. package/dist/es/business/YkCharts/Pies.js +352 -0
  55. package/dist/es/business/YkCharts/Pies.js.map +7 -0
  56. package/dist/es/business/YkCharts/constants.d.ts +1 -0
  57. package/dist/es/business/YkCharts/constants.js +47 -0
  58. package/dist/es/business/YkCharts/constants.js.map +7 -0
  59. package/dist/es/business/YkCharts/hooks.d.ts +4 -0
  60. package/dist/es/business/YkCharts/hooks.js +37 -0
  61. package/dist/es/business/YkCharts/hooks.js.map +7 -0
  62. package/dist/es/business/YkCharts/index.d.ts +9 -0
  63. package/dist/es/business/YkCharts/index.js +20 -0
  64. package/dist/es/business/YkCharts/index.js.map +7 -0
  65. package/dist/es/business/YkCharts/index.module.less +164 -0
  66. package/dist/es/business/YkCharts/tooltip.less +92 -0
  67. package/dist/es/business/YkCharts/transformData.js +16 -0
  68. package/dist/es/business/YkCharts/transformData.js.map +7 -0
  69. package/dist/es/business/YkCharts/typing.d.ts +74 -0
  70. package/dist/es/business/YkCharts/typing.js +1 -0
  71. package/dist/es/business/YkCharts/typing.js.map +7 -0
  72. package/dist/es/business/YkCharts/utils.d.ts +4 -0
  73. package/dist/es/business/YkCharts/utils.js +109 -0
  74. package/dist/es/business/YkCharts/utils.js.map +7 -0
  75. package/dist/es/business/YkCharts/variables.less +13 -0
  76. package/dist/es/business/YkLoginModule/SmsLoginForm.d.ts +25 -0
  77. package/dist/es/business/YkLoginModule/SmsLoginForm.js +178 -0
  78. package/dist/es/business/YkLoginModule/SmsLoginForm.js.map +7 -0
  79. package/dist/es/business/YkLoginModule/index.d.ts +48 -0
  80. package/dist/es/business/YkLoginModule/index.js +198 -0
  81. package/dist/es/business/YkLoginModule/index.js.map +7 -0
  82. package/dist/es/business/YkLoginModule/styles.module.less +169 -0
  83. package/dist/es/business/YkPorjectSelect/index.d.ts +1 -1
  84. package/dist/es/business/YkPorjectSelect/index.js +2 -2
  85. package/dist/es/business/YkPorjectSelect/index.js.map +2 -2
  86. package/dist/es/business/YkSqlEdit/code-mirror-custom.module.less +154 -0
  87. package/dist/es/business/YkSqlEdit/index.d.ts +20 -0
  88. package/dist/es/business/YkSqlEdit/index.js +180 -0
  89. package/dist/es/business/YkSqlEdit/index.js.map +7 -0
  90. package/dist/es/business/YkSqlEdit/sql-language.d.ts +11 -0
  91. package/dist/es/business/YkSqlEdit/sql-language.js +1460 -0
  92. package/dist/es/business/YkSqlEdit/sql-language.js.map +7 -0
  93. package/dist/es/components/DebounceInput/index.js.map +2 -2
  94. package/dist/es/components/MultipleSelect/index.d.ts +14 -0
  95. package/dist/es/components/MultipleSelect/index.js +1 -1
  96. package/dist/es/components/MultipleSelect/index.js.map +2 -2
  97. package/dist/es/components/RefreshButton/index.js.map +2 -2
  98. package/dist/es/components/SearchWithHistory/index.js +1 -1
  99. package/dist/es/components/SearchWithHistory/index.js.map +2 -2
  100. package/dist/es/components/TextWithToolTip/index.d.ts +1 -1
  101. package/dist/es/components/TextWithToolTip/index.js.map +2 -2
  102. package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.d.ts +1 -24
  103. package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.js +2 -2
  104. package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.js.map +2 -2
  105. package/dist/es/components/TreeTransfer/index.d.ts +1 -24
  106. package/dist/es/components/TreeTransfer/index.js +8 -8
  107. package/dist/es/components/TreeTransfer/index.js.map +2 -2
  108. package/dist/es/components/TreeTransfer/utils/index.d.ts +1 -1
  109. package/dist/es/components/TreeTransfer/utils/index.js.map +2 -2
  110. package/dist/es/components/YKMarkdown/index.d.ts +11 -0
  111. package/dist/es/components/YKMarkdown/index.js +236 -0
  112. package/dist/es/components/YKMarkdown/index.js.map +7 -0
  113. package/dist/es/components/YKMarkdown/index.module.less +83 -0
  114. package/dist/es/components/YkDateRangePicker/YkDateRangePicker.mdx +194 -0
  115. package/dist/es/components/YkDateRangePicker/index.d.ts +9 -1
  116. package/dist/es/components/YkDateRangePicker/index.js +127 -61
  117. package/dist/es/components/YkDateRangePicker/index.js.map +2 -2
  118. package/dist/es/components/YkDateRangePicker/index.module.less +33 -9
  119. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.d.ts +1 -1
  120. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js +3 -2
  121. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js.map +2 -2
  122. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.d.ts +1 -1
  123. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js +23 -3
  124. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js.map +2 -2
  125. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.d.ts +1 -1
  126. package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.js.map +2 -2
  127. package/dist/es/components/YkRangeDateWithVS/index.d.ts +2 -2
  128. package/dist/es/components/YkRangeDateWithVS/index.js.map +2 -2
  129. package/dist/es/components/YkRangeDateWithVS/index.module.less +22 -4
  130. package/dist/es/components/YkRangeTimeWithRecent/index.d.ts +1 -1
  131. package/dist/es/components/YkRangeTimeWithRecent/index.js.map +2 -2
  132. package/dist/es/creative/ArcCheckbox/index.d.ts +12 -0
  133. package/dist/es/creative/ArcCheckbox/index.js +49 -0
  134. package/dist/es/creative/ArcCheckbox/index.js.map +7 -0
  135. package/dist/es/creative/ArcCheckbox/index.module.less +102 -0
  136. package/dist/es/creative/ButtonRadioWithInfo/index.js.map +1 -1
  137. package/dist/es/creative/ButtonWithProgress/index.d.ts +1 -1
  138. package/dist/es/creative/ButtonWithProgress/index.js.map +2 -2
  139. package/dist/es/creative/GlassSegmentedRadio/index.d.ts +24 -0
  140. package/dist/es/creative/GlassSegmentedRadio/index.js +75 -0
  141. package/dist/es/creative/GlassSegmentedRadio/index.js.map +7 -0
  142. package/dist/es/creative/GlassSegmentedRadio/index.module.less +241 -0
  143. package/dist/es/creative/SkillsWriter/index.d.ts +3 -0
  144. package/dist/es/creative/SkillsWriter/index.js +191 -0
  145. package/dist/es/creative/SkillsWriter/index.js.map +7 -0
  146. package/dist/es/creative/SkillsWriter/index.module.less +21 -0
  147. package/dist/es/index.d.ts +32 -24
  148. package/dist/es/index.js +90 -80
  149. package/dist/es/index.js.map +2 -2
  150. package/dist/es/index.less +44 -0
  151. package/dist/es/layout/FlexGrid/index.d.ts +1 -1
  152. package/dist/es/layout/FlexGrid/index.js.map +2 -2
  153. package/dist/es/layout/YkContainer/index.js.map +1 -1
  154. package/dist/es/layout/YkDrawer/index.d.ts +1 -1
  155. package/dist/es/layout/YkDrawer/index.js.map +2 -2
  156. package/dist/es/ui/LabelSelect/demo.js +1 -1
  157. package/dist/es/ui/LabelSelect/demo.js.map +2 -2
  158. package/dist/es/ui/LabelSelect/index.d.ts +1 -1
  159. package/dist/es/ui/LabelSelect/index.js +1 -1
  160. package/dist/es/ui/LabelSelect/index.js.map +2 -2
  161. package/dist/es/ui/LogicOperator/index.d.ts +1 -1
  162. package/dist/es/ui/LogicOperator/index.js.map +2 -2
  163. package/dist/es/ui/YkButton/index.d.ts +1 -1
  164. package/dist/es/ui/YkButton/index.js.map +2 -2
  165. package/dist/es/ui/YkCard/index.d.ts +1 -1
  166. package/dist/es/ui/YkCard/index.js +1 -1
  167. package/dist/es/ui/YkCard/index.js.map +2 -2
  168. package/dist/es/ui/YkCheckbox/index.d.ts +1 -1
  169. package/dist/es/ui/YkCheckbox/index.js.map +2 -2
  170. package/dist/es/ui/YkDescriptions/index.d.ts +1 -1
  171. package/dist/es/ui/YkDescriptions/index.js.map +2 -2
  172. package/dist/es/ui/YkPagination/index.d.ts +1 -1
  173. package/dist/es/ui/YkPagination/index.js.map +2 -2
  174. package/dist/es/ui/YkRadio/index.d.ts +1 -1
  175. package/dist/es/ui/YkRadio/index.js.map +2 -2
  176. package/dist/es/ui/YkSegmented/index.d.ts +1 -1
  177. package/dist/es/ui/YkSegmented/index.js.map +2 -2
  178. package/dist/es/ui/YkSelect/index.d.ts +1 -1
  179. package/dist/es/ui/YkSelect/index.js.map +2 -2
  180. package/dist/es/ui/YkSpin/index.d.ts +1 -1
  181. package/dist/es/ui/YkSpin/index.js.map +2 -2
  182. package/dist/es/ui/YkStatistic/index.d.ts +1 -1
  183. package/dist/es/ui/YkStatistic/index.js.map +2 -2
  184. package/dist/es/ui/YkSwitch/index.d.ts +1 -1
  185. package/dist/es/ui/YkSwitch/index.js.map +2 -2
  186. package/dist/es/ui/YkTabs/index.d.ts +1 -1
  187. package/dist/es/ui/YkTabs/index.js.map +2 -2
  188. package/dist/es/ui/YkTooltip/index.d.ts +1 -1
  189. package/dist/es/ui/YkTooltip/index.js.map +2 -2
  190. package/dist/es/utils/styleUtils.js.map +2 -2
  191. package/dist/es/utils/ykStorybookDoc.d.ts +15 -0
  192. package/dist/es/utils/ykStorybookDoc.js +24 -2
  193. package/dist/es/utils/ykStorybookDoc.js.map +2 -2
  194. package/dist/lib/assets/image/skills.zip +0 -0
  195. package/dist/lib/business/AiChat/index.d.ts +3 -3
  196. package/dist/lib/business/AiChat/index.js +320 -111
  197. package/dist/lib/business/AiChat/index.js.map +3 -3
  198. package/dist/lib/business/AiChat/intentRecognizer.js.map +1 -1
  199. package/dist/lib/business/AiChat/navigationManager.js +6 -6
  200. package/dist/lib/business/AiChat/navigationManager.js.map +2 -2
  201. package/dist/lib/business/AiChat/sse.d.ts +15 -0
  202. package/dist/lib/business/AiChat/sse.js +117 -7
  203. package/dist/lib/business/AiChat/sse.js.map +2 -2
  204. package/dist/lib/business/AiChat/type.d.ts +22 -23
  205. package/dist/lib/business/AiChat/type.js.map +1 -1
  206. package/dist/lib/business/AiChat/useAiChat.js +104 -74
  207. package/dist/lib/business/AiChat/useAiChat.js.map +3 -3
  208. package/dist/lib/business/AiChat/useTaskWorkflow.d.ts +1 -2
  209. package/dist/lib/business/AiChat/useTaskWorkflow.js +0 -34
  210. package/dist/lib/business/AiChat/useTaskWorkflow.js.map +2 -2
  211. package/dist/lib/business/DrawerPageInfo/index.js.map +1 -1
  212. package/dist/lib/business/Editor/index.d.ts +1 -1
  213. package/dist/lib/business/Editor/index.js.map +2 -2
  214. package/dist/lib/business/Empty/index.js +1 -1
  215. package/dist/lib/business/Empty/index.js.map +1 -1
  216. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Category.js +3 -3
  217. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Category.js.map +2 -2
  218. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Content.js +4 -4
  219. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Content.js.map +2 -2
  220. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Selected.js +3 -3
  221. package/dist/lib/business/ModCommonFilter/components/PopoverContent/Selected.js.map +2 -2
  222. package/dist/lib/business/ModCommonFilter/index.d.ts +1 -1
  223. package/dist/lib/business/ModCommonFilter/index.js.map +2 -2
  224. package/dist/lib/business/YkCharts/Area.d.ts +18 -0
  225. package/dist/lib/business/YkCharts/Area.js +346 -0
  226. package/dist/lib/business/YkCharts/Area.js.map +7 -0
  227. package/dist/lib/business/YkCharts/Bar.d.ts +21 -0
  228. package/dist/lib/business/YkCharts/Bar.js +323 -0
  229. package/dist/lib/business/YkCharts/Bar.js.map +7 -0
  230. package/dist/lib/business/YkCharts/BarProperty.d.ts +21 -0
  231. package/dist/lib/business/YkCharts/BarProperty.js +370 -0
  232. package/dist/lib/business/YkCharts/BarProperty.js.map +7 -0
  233. package/dist/lib/business/YkCharts/BarTotal.d.ts +21 -0
  234. package/dist/lib/business/YkCharts/BarTotal.js +298 -0
  235. package/dist/lib/business/YkCharts/BarTotal.js.map +7 -0
  236. package/dist/lib/business/YkCharts/Line.d.ts +21 -0
  237. package/dist/lib/business/YkCharts/Line.js +349 -0
  238. package/dist/lib/business/YkCharts/Line.js.map +7 -0
  239. package/dist/lib/business/YkCharts/Pie.d.ts +19 -0
  240. package/dist/lib/business/YkCharts/Pie.js +117 -0
  241. package/dist/lib/business/YkCharts/Pie.js.map +7 -0
  242. package/dist/lib/business/YkCharts/PieProperty.d.ts +18 -0
  243. package/dist/lib/business/YkCharts/PieProperty.js +193 -0
  244. package/dist/lib/business/YkCharts/PieProperty.js.map +7 -0
  245. package/dist/lib/business/YkCharts/Pies.d.ts +26 -0
  246. package/dist/lib/business/YkCharts/Pies.js +341 -0
  247. package/dist/lib/business/YkCharts/Pies.js.map +7 -0
  248. package/dist/lib/business/YkCharts/constants.d.ts +1 -0
  249. package/dist/lib/business/YkCharts/constants.js +71 -0
  250. package/dist/lib/business/YkCharts/constants.js.map +7 -0
  251. package/dist/lib/business/YkCharts/hooks.d.ts +4 -0
  252. package/dist/lib/business/YkCharts/hooks.js +62 -0
  253. package/dist/lib/business/YkCharts/hooks.js.map +7 -0
  254. package/dist/lib/business/YkCharts/index.d.ts +9 -0
  255. package/dist/lib/business/YkCharts/index.js +61 -0
  256. package/dist/lib/business/YkCharts/index.js.map +7 -0
  257. package/dist/lib/business/YkCharts/index.module.less +164 -0
  258. package/dist/lib/business/YkCharts/tooltip.less +92 -0
  259. package/dist/lib/business/YkCharts/transformData.js +40 -0
  260. package/dist/lib/business/YkCharts/transformData.js.map +7 -0
  261. package/dist/lib/business/YkCharts/typing.d.ts +74 -0
  262. package/dist/lib/business/YkCharts/typing.js +18 -0
  263. package/dist/lib/business/YkCharts/typing.js.map +7 -0
  264. package/dist/lib/business/YkCharts/utils.d.ts +4 -0
  265. package/dist/lib/business/YkCharts/utils.js +143 -0
  266. package/dist/lib/business/YkCharts/utils.js.map +7 -0
  267. package/dist/lib/business/YkCharts/variables.less +13 -0
  268. package/dist/lib/business/YkLoginModule/SmsLoginForm.d.ts +25 -0
  269. package/dist/lib/business/YkLoginModule/SmsLoginForm.js +171 -0
  270. package/dist/lib/business/YkLoginModule/SmsLoginForm.js.map +7 -0
  271. package/dist/lib/business/YkLoginModule/index.d.ts +48 -0
  272. package/dist/lib/business/YkLoginModule/index.js +206 -0
  273. package/dist/lib/business/YkLoginModule/index.js.map +7 -0
  274. package/dist/lib/business/YkLoginModule/styles.module.less +169 -0
  275. package/dist/lib/business/YkPorjectSelect/index.d.ts +1 -1
  276. package/dist/lib/business/YkPorjectSelect/index.js +3 -3
  277. package/dist/lib/business/YkPorjectSelect/index.js.map +2 -2
  278. package/dist/lib/business/YkSqlEdit/code-mirror-custom.module.less +154 -0
  279. package/dist/lib/business/YkSqlEdit/index.d.ts +20 -0
  280. package/dist/lib/business/YkSqlEdit/index.js +202 -0
  281. package/dist/lib/business/YkSqlEdit/index.js.map +7 -0
  282. package/dist/lib/business/YkSqlEdit/sql-language.d.ts +11 -0
  283. package/dist/lib/business/YkSqlEdit/sql-language.js +1493 -0
  284. package/dist/lib/business/YkSqlEdit/sql-language.js.map +7 -0
  285. package/dist/lib/components/DebounceInput/index.js.map +2 -2
  286. package/dist/lib/components/MultipleSelect/index.d.ts +14 -0
  287. package/dist/lib/components/MultipleSelect/index.js +1 -1
  288. package/dist/lib/components/MultipleSelect/index.js.map +2 -2
  289. package/dist/lib/components/RefreshButton/index.js.map +2 -2
  290. package/dist/lib/components/SearchWithHistory/index.js +1 -1
  291. package/dist/lib/components/SearchWithHistory/index.js.map +2 -2
  292. package/dist/lib/components/TextWithToolTip/index.d.ts +1 -1
  293. package/dist/lib/components/TextWithToolTip/index.js.map +2 -2
  294. package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.d.ts +1 -24
  295. package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.js +2 -2
  296. package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.js.map +2 -2
  297. package/dist/lib/components/TreeTransfer/index.d.ts +1 -24
  298. package/dist/lib/components/TreeTransfer/index.js +3 -3
  299. package/dist/lib/components/TreeTransfer/index.js.map +2 -2
  300. package/dist/lib/components/TreeTransfer/utils/index.d.ts +1 -1
  301. package/dist/lib/components/TreeTransfer/utils/index.js.map +2 -2
  302. package/dist/lib/components/YKMarkdown/index.d.ts +11 -0
  303. package/dist/lib/components/YKMarkdown/index.js +188 -0
  304. package/dist/lib/components/YKMarkdown/index.js.map +7 -0
  305. package/dist/lib/components/YKMarkdown/index.module.less +83 -0
  306. package/dist/lib/components/YkDateRangePicker/YkDateRangePicker.mdx +194 -0
  307. package/dist/lib/components/YkDateRangePicker/index.d.ts +9 -1
  308. package/dist/lib/components/YkDateRangePicker/index.js +127 -61
  309. package/dist/lib/components/YkDateRangePicker/index.js.map +2 -2
  310. package/dist/lib/components/YkDateRangePicker/index.module.less +33 -9
  311. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.d.ts +1 -1
  312. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js +3 -2
  313. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js.map +2 -2
  314. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.d.ts +1 -1
  315. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js +22 -2
  316. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js.map +2 -2
  317. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.d.ts +1 -1
  318. package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.js.map +2 -2
  319. package/dist/lib/components/YkRangeDateWithVS/index.d.ts +2 -2
  320. package/dist/lib/components/YkRangeDateWithVS/index.js.map +2 -2
  321. package/dist/lib/components/YkRangeDateWithVS/index.module.less +22 -4
  322. package/dist/lib/components/YkRangeTimeWithRecent/index.d.ts +1 -1
  323. package/dist/lib/components/YkRangeTimeWithRecent/index.js.map +2 -2
  324. package/dist/lib/creative/ArcCheckbox/index.d.ts +12 -0
  325. package/dist/lib/creative/ArcCheckbox/index.js +50 -0
  326. package/dist/lib/creative/ArcCheckbox/index.js.map +7 -0
  327. package/dist/lib/creative/ArcCheckbox/index.module.less +102 -0
  328. package/dist/lib/creative/ButtonRadioWithInfo/index.js.map +1 -1
  329. package/dist/lib/creative/ButtonWithProgress/index.d.ts +1 -1
  330. package/dist/lib/creative/ButtonWithProgress/index.js.map +2 -2
  331. package/dist/lib/creative/GlassSegmentedRadio/index.d.ts +24 -0
  332. package/dist/lib/creative/GlassSegmentedRadio/index.js +78 -0
  333. package/dist/lib/creative/GlassSegmentedRadio/index.js.map +7 -0
  334. package/dist/lib/creative/GlassSegmentedRadio/index.module.less +241 -0
  335. package/dist/lib/creative/SkillsWriter/index.d.ts +3 -0
  336. package/dist/lib/creative/SkillsWriter/index.js +200 -0
  337. package/dist/lib/creative/SkillsWriter/index.js.map +7 -0
  338. package/dist/lib/creative/SkillsWriter/index.module.less +21 -0
  339. package/dist/lib/index.d.ts +32 -24
  340. package/dist/lib/index.js +39 -24
  341. package/dist/lib/index.js.map +2 -2
  342. package/dist/lib/index.less +44 -0
  343. package/dist/lib/layout/FlexGrid/index.d.ts +1 -1
  344. package/dist/lib/layout/FlexGrid/index.js.map +2 -2
  345. package/dist/lib/layout/YkContainer/index.js.map +1 -1
  346. package/dist/lib/layout/YkDrawer/index.d.ts +1 -1
  347. package/dist/lib/layout/YkDrawer/index.js.map +2 -2
  348. package/dist/lib/ui/LabelSelect/demo.js +1 -1
  349. package/dist/lib/ui/LabelSelect/demo.js.map +2 -2
  350. package/dist/lib/ui/LabelSelect/index.d.ts +1 -1
  351. package/dist/lib/ui/LabelSelect/index.js +1 -1
  352. package/dist/lib/ui/LabelSelect/index.js.map +2 -2
  353. package/dist/lib/ui/LogicOperator/index.d.ts +1 -1
  354. package/dist/lib/ui/LogicOperator/index.js.map +2 -2
  355. package/dist/lib/ui/YkButton/index.d.ts +1 -1
  356. package/dist/lib/ui/YkButton/index.js.map +2 -2
  357. package/dist/lib/ui/YkCard/index.d.ts +1 -1
  358. package/dist/lib/ui/YkCard/index.js.map +2 -2
  359. package/dist/lib/ui/YkCheckbox/index.d.ts +1 -1
  360. package/dist/lib/ui/YkCheckbox/index.js.map +2 -2
  361. package/dist/lib/ui/YkDescriptions/index.d.ts +1 -1
  362. package/dist/lib/ui/YkDescriptions/index.js.map +2 -2
  363. package/dist/lib/ui/YkPagination/index.d.ts +1 -1
  364. package/dist/lib/ui/YkPagination/index.js.map +2 -2
  365. package/dist/lib/ui/YkRadio/index.d.ts +1 -1
  366. package/dist/lib/ui/YkRadio/index.js.map +2 -2
  367. package/dist/lib/ui/YkSegmented/index.d.ts +1 -1
  368. package/dist/lib/ui/YkSegmented/index.js.map +2 -2
  369. package/dist/lib/ui/YkSelect/index.d.ts +1 -1
  370. package/dist/lib/ui/YkSelect/index.js.map +2 -2
  371. package/dist/lib/ui/YkSpin/index.d.ts +1 -1
  372. package/dist/lib/ui/YkSpin/index.js.map +2 -2
  373. package/dist/lib/ui/YkStatistic/index.d.ts +1 -1
  374. package/dist/lib/ui/YkStatistic/index.js.map +2 -2
  375. package/dist/lib/ui/YkSwitch/index.d.ts +1 -1
  376. package/dist/lib/ui/YkSwitch/index.js.map +2 -2
  377. package/dist/lib/ui/YkTabs/index.d.ts +1 -1
  378. package/dist/lib/ui/YkTabs/index.js.map +2 -2
  379. package/dist/lib/ui/YkTooltip/index.d.ts +1 -1
  380. package/dist/lib/ui/YkTooltip/index.js.map +2 -2
  381. package/dist/lib/utils/styleUtils.js.map +2 -2
  382. package/dist/lib/utils/ykStorybookDoc.d.ts +15 -0
  383. package/dist/lib/utils/ykStorybookDoc.js +23 -1
  384. package/dist/lib/utils/ykStorybookDoc.js.map +2 -2
  385. package/package.json +152 -144
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/TreeTransfer/index.tsx"],
4
- "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransfer\n *\n * 树形表格穿梭框组件。支持:\n * - 树形结构展示,父子联动选择(checkStrictly: false)\n * - 前端分页 + 防抖搜索\n * - 左右穿梭操作(含多级树正确迁移)\n * - 自定义列配置和渲染\n * - 完整的 TypeScript 泛型支持\n *\n * @template T - 行数据的自定义业务类型\n *\n * @example\n * ```tsx\n * <TreeTransfer\n * leftDataSource={leftData}\n * rightDataSource={rightData}\n * leftTitle=\"待分配\"\n * rightTitle=\"已分配\"\n * onChange={({ leftData, rightData }) => { ... }}\n * />\n * ```\n */\n\nimport React, { useState, useMemo, useCallback, useEffect, useRef } from 'react';\nimport { Spin, Button, Space } from 'antd';\nimport { RightOutlined, LeftOutlined } from '@ant-design/icons';\nimport { TreeTransferProps, DEFAULT_PAGE_SIZE } from './types';\nimport {\n sliceDataByPage,\n filterData,\n getAllDescendantKeys,\n removeNodesFromTree,\n addNodesToTree,\n countParentNodes,\n extractTopLevelSelectedNodes,\n} from './utils';\nimport TreeTransferPanel from './components/TreeTransferPanel';\nimport './index.less';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useDebounce\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 防抖 Hook\n *\n * 修复说明:\n * 原实现将 `callback` 放入 `useCallback` 的 deps,导致每次渲染(callback 为\n * 新引用)都重新创建防抖函数,使 timeout 重置,防抖完全失效。\n * 修复方案:将最新 callback 存入 ref,useCallback 仅依赖 delay,保证\n * 防抖函数引用稳定,timeout 不被意外清除。\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number): T {\n // 存储最新 callback,避免 stale closure\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n return useCallback(\n (...args: Parameters<T>) => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);\n },\n [delay], // callback 通过 ref 读取,不需要放入 deps\n ) as T;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransfer\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 面板选择/分页状态(不含 dataSource,数据源来自 props + memo 计算)\n */\ninterface PanelState {\n selectedRowKeys: React.Key[];\n searchValue: string;\n currentPage: number;\n totalCount: number;\n}\n\nfunction TreeTransfer<T>({\n leftDataSource,\n rightDataSource,\n loading = false,\n leftTitle = '待分配项',\n rightTitle = '已分配项',\n pageSize = DEFAULT_PAGE_SIZE,\n columns,\n customRender,\n searchFields,\n searchPlaceholder,\n onChange,\n}: TreeTransferProps<T>) {\n // ── 面板状态(选择、搜索、分页) ─────────────────────────────────────────────\n // 注意:dataSource 不存储在 state 中;显示数据通过 memo 从 props 实时计算,\n // 避免 state 与 props 不同步的问题。\n const [leftPanel, setLeftPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n const [rightPanel, setRightPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n // ── 过滤后的完整数据(先 filter,再由 slice 分页) ──────────────────────────\n // 合并 filter + count,避免对同一搜索词调用两次 filterData(原来的问题)。\n\n const filteredLeft = useMemo(\n () => filterData<T>(leftDataSource, leftPanel.searchValue, searchFields),\n [leftDataSource, leftPanel.searchValue, searchFields],\n );\n\n const filteredRight = useMemo(\n () => filterData<T>(rightDataSource, rightPanel.searchValue, searchFields),\n [rightDataSource, rightPanel.searchValue, searchFields],\n );\n\n /** 当前页展示数据(供左侧面板渲染) */\n const filteredLeftData = useMemo(\n () => sliceDataByPage<T>(filteredLeft, leftPanel.currentPage, pageSize),\n [filteredLeft, leftPanel.currentPage, pageSize],\n );\n\n /** 当前页展示数据(供右侧面板渲染) */\n const filteredRightData = useMemo(\n () => sliceDataByPage<T>(filteredRight, rightPanel.currentPage, pageSize),\n [filteredRight, rightPanel.currentPage, pageSize],\n );\n\n /** 搜索后的顶层节点数(用于分页器 total) */\n const filteredLeftTotalCount = useMemo(() => countParentNodes(filteredLeft), [filteredLeft]);\n const filteredRightTotalCount = useMemo(() => countParentNodes(filteredRight), [filteredRight]);\n\n // ── 数据源变化时更新 totalCount,同时重置到第 1 页 ──────────────────────────\n useEffect(() => {\n setLeftPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(leftDataSource),\n }));\n }, [leftDataSource]);\n\n useEffect(() => {\n setRightPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(rightDataSource),\n }));\n }, [rightDataSource]);\n\n // ── 防抖搜索 ─────────────────────────────────────────────────────────────────\n\n const handleLeftSearchChange = useDebounce((value: string) => {\n setLeftPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n const handleRightSearchChange = useDebounce((value: string) => {\n setRightPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n // ── 分页 ─────────────────────────────────────────────────────────────────────\n\n const handleLeftPageChange = useCallback((page: number) => {\n setLeftPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n const handleRightPageChange = useCallback((page: number) => {\n setRightPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n // ── 穿梭操作 ─────────────────────────────────────────────────────────────────\n\n /**\n * 右移:将左侧选中项移到右侧\n *\n * 修复说明:\n * 原实现通过 `dataSource.filter(item => item.key === key)` 只查根节点,\n * 导致仅选中子节点时 nodesToAdd 为空,数据静默丢失。\n * 修复:使用 `extractTopLevelSelectedNodes` 递归提取选中的顶层节点(含 children)。\n */\n const handleMoveRight = useCallback(() => {\n if (leftPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(leftPanel.selectedRowKeys.map(String));\n // 提取选中的顶层节点(子节点随父一起携带)\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, leftDataSource);\n // 删除所有相关 key(含后代)\n const keysToRemove = new Set(getAllDescendantKeys(leftPanel.selectedRowKeys, leftDataSource));\n const newLeftData = removeNodesFromTree(leftDataSource, keysToRemove);\n const newRightData = addNodesToTree(rightDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [leftPanel.selectedRowKeys, leftDataSource, rightDataSource, onChange]);\n\n /**\n * 左移:将右侧选中项移到左侧\n */\n const handleMoveLeft = useCallback(() => {\n if (rightPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(rightPanel.selectedRowKeys.map(String));\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, rightDataSource);\n const keysToRemove = new Set(getAllDescendantKeys(rightPanel.selectedRowKeys, rightDataSource));\n const newRightData = removeNodesFromTree(rightDataSource, keysToRemove);\n const newLeftData = addNodesToTree(leftDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [rightPanel.selectedRowKeys, rightDataSource, leftDataSource, onChange]);\n\n // ── 渲染 ─────────────────────────────────────────────────────────────────────\n\n return (\n <div className='tree-transfer-wrapper'>\n <Spin spinning={loading}>\n <div className='tree-transfer-content'>\n {/* 左侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredLeftData}\n selectedRowKeys={leftPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setLeftPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={leftPanel.searchValue}\n setSearchValue={handleLeftSearchChange}\n totalCount={leftPanel.searchValue ? filteredLeftTotalCount : leftPanel.totalCount}\n title={leftTitle}\n showPagination={true}\n currentPage={leftPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleLeftPageChange}\n columns={columns}\n customRender={customRender}\n searchPlaceholder={searchPlaceholder}\n />\n\n {/* 中间操作按钮 */}\n <div className='tree-transfer-operations'>\n <Space direction='vertical' size={8}>\n <Button\n className='tree-transfer-operation-btn'\n type={leftPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<RightOutlined />}\n onClick={handleMoveRight}\n disabled={leftPanel.selectedRowKeys.length === 0}\n />\n <Button\n className='tree-transfer-operation-btn'\n type={rightPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<LeftOutlined />}\n onClick={handleMoveLeft}\n disabled={rightPanel.selectedRowKeys.length === 0}\n />\n </Space>\n </div>\n\n {/* 右侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredRightData}\n selectedRowKeys={rightPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setRightPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={rightPanel.searchValue}\n setSearchValue={handleRightSearchChange}\n totalCount={rightPanel.searchValue ? filteredRightTotalCount : rightPanel.totalCount}\n title={rightTitle}\n showPagination={true}\n currentPage={rightPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleRightPageChange}\n columns={columns}\n customRender={customRender}\n />\n </div>\n </Spin>\n </div>\n );\n}\n\nexport default TreeTransfer;\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CA,mBAAyE;AACzE,kBAAoC;AACpC,mBAA4C;AAC5C,mBAAqD;AACrD,mBAQO;AACP,+BAA8B;AAC9B,mBAAO;AAgBP,SAAS,YAA+C,UAAa,OAAkB;AAErF,QAAM,kBAAc,qBAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,QAAM,iBAAa,qBAAuB;AAE1C,aAAO;AAAA,IACL,IAAI,SAAwB;AAC1B,mBAAa,WAAW,OAAO;AAC/B,iBAAW,UAAU,WAAW,MAAM,YAAY,QAAQ,GAAG,IAAI,GAAG,KAAK;AAAA,IAC3E;AAAA,IACA,CAAC,KAAK;AAAA;AAAA,EACR;AACF;AAgBA,SAAS,aAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AAIvB,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAqB;AAAA,IACrD,iBAAiB,CAAC;AAAA,IAClB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY;AAAA,EACd,CAAC;AAED,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAqB;AAAA,IACvD,iBAAiB,CAAC;AAAA,IAClB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,YAAY;AAAA,EACd,CAAC;AAKD,QAAM,mBAAe;AAAA,IACnB,UAAM,yBAAc,gBAAgB,UAAU,aAAa,YAAY;AAAA,IACvE,CAAC,gBAAgB,UAAU,aAAa,YAAY;AAAA,EACtD;AAEA,QAAM,oBAAgB;AAAA,IACpB,UAAM,yBAAc,iBAAiB,WAAW,aAAa,YAAY;AAAA,IACzE,CAAC,iBAAiB,WAAW,aAAa,YAAY;AAAA,EACxD;AAGA,QAAM,uBAAmB;AAAA,IACvB,UAAM,8BAAmB,cAAc,UAAU,aAAa,QAAQ;AAAA,IACtE,CAAC,cAAc,UAAU,aAAa,QAAQ;AAAA,EAChD;AAGA,QAAM,wBAAoB;AAAA,IACxB,UAAM,8BAAmB,eAAe,WAAW,aAAa,QAAQ;AAAA,IACxE,CAAC,eAAe,WAAW,aAAa,QAAQ;AAAA,EAClD;AAGA,QAAM,6BAAyB,sBAAQ,UAAM,+BAAiB,YAAY,GAAG,CAAC,YAAY,CAAC;AAC3F,QAAM,8BAA0B,sBAAQ,UAAM,+BAAiB,aAAa,GAAG,CAAC,aAAa,CAAC;AAG9F,8BAAU,MAAM;AACd,iBAAa,CAAC,UAAU;AAAA,MACtB,GAAG;AAAA,MACH,aAAa;AAAA,MACb,gBAAY,+BAAiB,cAAc;AAAA,IAC7C,EAAE;AAAA,EACJ,GAAG,CAAC,cAAc,CAAC;AAEnB,8BAAU,MAAM;AACd,kBAAc,CAAC,UAAU;AAAA,MACvB,GAAG;AAAA,MACH,aAAa;AAAA,MACb,gBAAY,+BAAiB,eAAe;AAAA,IAC9C,EAAE;AAAA,EACJ,GAAG,CAAC,eAAe,CAAC;AAIpB,QAAM,yBAAyB,YAAY,CAAC,UAAkB;AAC5D,iBAAa,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,OAAO,aAAa,EAAE,EAAE;AAAA,EAC1E,GAAG,GAAG;AAEN,QAAM,0BAA0B,YAAY,CAAC,UAAkB;AAC7D,kBAAc,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,OAAO,aAAa,EAAE,EAAE;AAAA,EAC3E,GAAG,GAAG;AAIN,QAAM,2BAAuB,0BAAY,CAAC,SAAiB;AACzD,iBAAa,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,KAAK,EAAE;AAAA,EACzD,GAAG,CAAC,CAAC;AAEL,QAAM,4BAAwB,0BAAY,CAAC,SAAiB;AAC1D,kBAAc,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,KAAK,EAAE;AAAA,EAC1D,GAAG,CAAC,CAAC;AAYL,QAAM,sBAAkB,0BAAY,MAAM;AACxC,QAAI,UAAU,gBAAgB,WAAW;AAAG;AAE5C,UAAM,cAAc,IAAI,IAAI,UAAU,gBAAgB,IAAI,MAAM,CAAC;AAEjE,UAAM,iBAAa,2CAAgC,aAAa,cAAc;AAE9E,UAAM,eAAe,IAAI,QAAI,mCAAqB,UAAU,iBAAiB,cAAc,CAAC;AAC5F,UAAM,kBAAc,kCAAoB,gBAAgB,YAAY;AACpE,UAAM,mBAAe,6BAAe,iBAAiB,MAAM,UAAU;AAErE,iBAAa,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,GAAG,iBAAiB,CAAC,EAAE,EAAE;AACzE,kBAAc,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,GAAG,iBAAiB,CAAC,EAAE,EAAE;AAE1E,yCAAW;AAAA,MACT,cAAc,CAAC;AAAA,MACf,eAAe,CAAC;AAAA,MAChB,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,UAAU,iBAAiB,gBAAgB,iBAAiB,QAAQ,CAAC;AAKzE,QAAM,qBAAiB,0BAAY,MAAM;AACvC,QAAI,WAAW,gBAAgB,WAAW;AAAG;AAE7C,UAAM,cAAc,IAAI,IAAI,WAAW,gBAAgB,IAAI,MAAM,CAAC;AAClE,UAAM,iBAAa,2CAAgC,aAAa,eAAe;AAC/E,UAAM,eAAe,IAAI,QAAI,mCAAqB,WAAW,iBAAiB,eAAe,CAAC;AAC9F,UAAM,mBAAe,kCAAoB,iBAAiB,YAAY;AACtE,UAAM,kBAAc,6BAAe,gBAAgB,MAAM,UAAU;AAEnE,iBAAa,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,GAAG,iBAAiB,CAAC,EAAE,EAAE;AACzE,kBAAc,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,GAAG,iBAAiB,CAAC,EAAE,EAAE;AAE1E,yCAAW;AAAA,MACT,cAAc,CAAC;AAAA,MACf,eAAe,CAAC;AAAA,MAChB,UAAU;AAAA,MACV,WAAW;AAAA,IACb;AAAA,EACF,GAAG,CAAC,WAAW,iBAAiB,iBAAiB,gBAAgB,QAAQ,CAAC;AAI1E,SACE,6BAAAA,QAAA,cAAC,SAAI,WAAU,2BACb,6BAAAA,QAAA,cAAC,oBAAK,UAAU,WACd,6BAAAA,QAAA,cAAC,SAAI,WAAU,2BAEb,6BAAAA,QAAA;AAAA,IAAC,yBAAAC;AAAA,IAAA;AAAA,MACC,YAAY;AAAA,MACZ,iBAAiB,UAAU;AAAA,MAC3B,aAAa,CAAC,GAAG,SAAS,aAAa,CAAC,UAAU,EAAE,GAAG,MAAM,iBAAiB,KAAK,EAAE;AAAA,MACrF,aAAa,UAAU;AAAA,MACvB,gBAAgB;AAAA,MAChB,YAAY,UAAU,cAAc,yBAAyB,UAAU;AAAA,MACvE,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,aAAa,UAAU;AAAA,MACvB;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF,GAGA,6BAAAD,QAAA,cAAC,SAAI,WAAU,8BACb,6BAAAA,QAAA,cAAC,qBAAM,WAAU,YAAW,MAAM,KAChC,6BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAM,UAAU,gBAAgB,SAAS,IAAI,YAAY;AAAA,MACzD,MAAM,6BAAAA,QAAA,cAAC,gCAAc;AAAA,MACrB,SAAS;AAAA,MACT,UAAU,UAAU,gBAAgB,WAAW;AAAA;AAAA,EACjD,GACA,6BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAM,WAAW,gBAAgB,SAAS,IAAI,YAAY;AAAA,MAC1D,MAAM,6BAAAA,QAAA,cAAC,+BAAa;AAAA,MACpB,SAAS;AAAA,MACT,UAAU,WAAW,gBAAgB,WAAW;AAAA;AAAA,EAClD,CACF,CACF,GAGA,6BAAAA,QAAA;AAAA,IAAC,yBAAAC;AAAA,IAAA;AAAA,MACC,YAAY;AAAA,MACZ,iBAAiB,WAAW;AAAA,MAC5B,aAAa,CAAC,GAAG,SAAS,cAAc,CAAC,UAAU,EAAE,GAAG,MAAM,iBAAiB,KAAK,EAAE;AAAA,MACtF,aAAa,WAAW;AAAA,MACxB,gBAAgB;AAAA,MAChB,YAAY,WAAW,cAAc,0BAA0B,WAAW;AAAA,MAC1E,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,aAAa,WAAW;AAAA,MACxB;AAAA,MACA,cAAc;AAAA,MACd;AAAA,MACA;AAAA;AAAA,EACF,CACF,CACF,CACF;AAEJ;AAEA,IAAO,uBAAQ;",
4
+ "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransfer\n *\n * 树形表格穿梭框组件。支持:\n * - 树形结构展示,父子联动选择(checkStrictly: false)\n * - 前端分页 + 防抖搜索\n * - 左右穿梭操作(含多级树正确迁移)\n * - 自定义列配置和渲染\n * - 完整的 TypeScript 泛型支持\n *\n * @template T - 行数据的自定义业务类型\n *\n * @example\n * ```tsx\n * <TreeTransfer\n * leftDataSource={leftData}\n * rightDataSource={rightData}\n * leftTitle=\"待分配\"\n * rightTitle=\"已分配\"\n * onChange={({ leftData, rightData }) => { ... }}\n * />\n * ```\n */\n\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\nimport { Button, Space, Spin } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport TreeTransferPanel from './components/TreeTransferPanel';\nimport { DEFAULT_PAGE_SIZE, type TreeTransferProps } from './types';\nimport {\n addNodesToTree,\n countParentNodes,\n extractTopLevelSelectedNodes,\n filterData,\n getAllDescendantKeys,\n removeNodesFromTree,\n sliceDataByPage,\n} from './utils';\nimport './index.less';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useDebounce\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 防抖 Hook\n *\n * 修复说明:\n * 原实现将 `callback` 放入 `useCallback` 的 deps,导致每次渲染(callback 为\n * 新引用)都重新创建防抖函数,使 timeout 重置,防抖完全失效。\n * 修复方案:将最新 callback 存入 ref,useCallback 仅依赖 delay,保证\n * 防抖函数引用稳定,timeout 不被意外清除。\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number): T {\n // 存储最新 callback,避免 stale closure\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n return useCallback(\n (...args: Parameters<T>) => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);\n },\n [delay], // callback 通过 ref 读取,不需要放入 deps\n ) as T;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransfer\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 面板选择/分页状态(不含 dataSource,数据源来自 props + memo 计算)\n */\ninterface PanelState {\n selectedRowKeys: React.Key[];\n searchValue: string;\n currentPage: number;\n totalCount: number;\n}\n\nfunction TreeTransfer<T>({\n leftDataSource,\n rightDataSource,\n loading = false,\n leftTitle = '待分配项',\n rightTitle = '已分配项',\n pageSize = DEFAULT_PAGE_SIZE,\n columns,\n customRender,\n searchFields,\n searchPlaceholder,\n onChange,\n}: TreeTransferProps<T>) {\n // ── 面板状态(选择、搜索、分页) ─────────────────────────────────────────────\n // 注意:dataSource 不存储在 state 中;显示数据通过 memo 从 props 实时计算,\n // 避免 state 与 props 不同步的问题。\n const [leftPanel, setLeftPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n const [rightPanel, setRightPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n // ── 过滤后的完整数据(先 filter,再由 slice 分页) ──────────────────────────\n // 合并 filter + count,避免对同一搜索词调用两次 filterData(原来的问题)。\n\n const filteredLeft = useMemo(\n () => filterData<T>(leftDataSource, leftPanel.searchValue, searchFields),\n [leftDataSource, leftPanel.searchValue, searchFields],\n );\n\n const filteredRight = useMemo(\n () => filterData<T>(rightDataSource, rightPanel.searchValue, searchFields),\n [rightDataSource, rightPanel.searchValue, searchFields],\n );\n\n /** 当前页展示数据(供左侧面板渲染) */\n const filteredLeftData = useMemo(\n () => sliceDataByPage<T>(filteredLeft, leftPanel.currentPage, pageSize),\n [filteredLeft, leftPanel.currentPage, pageSize],\n );\n\n /** 当前页展示数据(供右侧面板渲染) */\n const filteredRightData = useMemo(\n () => sliceDataByPage<T>(filteredRight, rightPanel.currentPage, pageSize),\n [filteredRight, rightPanel.currentPage, pageSize],\n );\n\n /** 搜索后的顶层节点数(用于分页器 total) */\n const filteredLeftTotalCount = useMemo(() => countParentNodes(filteredLeft), [filteredLeft]);\n const filteredRightTotalCount = useMemo(() => countParentNodes(filteredRight), [filteredRight]);\n\n // ── 数据源变化时更新 totalCount,同时重置到第 1 页 ──────────────────────────\n useEffect(() => {\n setLeftPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(leftDataSource),\n }));\n }, [leftDataSource]);\n\n useEffect(() => {\n setRightPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(rightDataSource),\n }));\n }, [rightDataSource]);\n\n // ── 防抖搜索 ─────────────────────────────────────────────────────────────────\n\n const handleLeftSearchChange = useDebounce((value: string) => {\n setLeftPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n const handleRightSearchChange = useDebounce((value: string) => {\n setRightPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n // ── 分页 ─────────────────────────────────────────────────────────────────────\n\n const handleLeftPageChange = useCallback((page: number) => {\n setLeftPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n const handleRightPageChange = useCallback((page: number) => {\n setRightPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n // ── 穿梭操作 ─────────────────────────────────────────────────────────────────\n\n /**\n * 右移:将左侧选中项移到右侧\n *\n * 修复说明:\n * 原实现通过 `dataSource.filter(item => item.key === key)` 只查根节点,\n * 导致仅选中子节点时 nodesToAdd 为空,数据静默丢失。\n * 修复:使用 `extractTopLevelSelectedNodes` 递归提取选中的顶层节点(含 children)。\n */\n const handleMoveRight = useCallback(() => {\n if (leftPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(leftPanel.selectedRowKeys.map(String));\n // 提取选中的顶层节点(子节点随父一起携带)\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, leftDataSource);\n // 删除所有相关 key(含后代)\n const keysToRemove = new Set(getAllDescendantKeys(leftPanel.selectedRowKeys, leftDataSource));\n const newLeftData = removeNodesFromTree(leftDataSource, keysToRemove);\n const newRightData = addNodesToTree(rightDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [leftPanel.selectedRowKeys, leftDataSource, rightDataSource, onChange]);\n\n /**\n * 左移:将右侧选中项移到左侧\n */\n const handleMoveLeft = useCallback(() => {\n if (rightPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(rightPanel.selectedRowKeys.map(String));\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, rightDataSource);\n const keysToRemove = new Set(getAllDescendantKeys(rightPanel.selectedRowKeys, rightDataSource));\n const newRightData = removeNodesFromTree(rightDataSource, keysToRemove);\n const newLeftData = addNodesToTree(leftDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [rightPanel.selectedRowKeys, rightDataSource, leftDataSource, onChange]);\n\n // ── 渲染 ─────────────────────────────────────────────────────────────────────\n\n return (\n <div className='tree-transfer-wrapper'>\n <Spin spinning={loading}>\n <div className='tree-transfer-content'>\n {/* 左侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredLeftData}\n selectedRowKeys={leftPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setLeftPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={leftPanel.searchValue}\n setSearchValue={handleLeftSearchChange}\n totalCount={leftPanel.searchValue ? filteredLeftTotalCount : leftPanel.totalCount}\n title={leftTitle}\n showPagination={true}\n currentPage={leftPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleLeftPageChange}\n columns={columns}\n customRender={customRender}\n searchPlaceholder={searchPlaceholder}\n />\n\n {/* 中间操作按钮 */}\n <div className='tree-transfer-operations'>\n <Space direction='vertical' size={8}>\n <Button\n className='tree-transfer-operation-btn'\n type={leftPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<RightOutlined />}\n onClick={handleMoveRight}\n disabled={leftPanel.selectedRowKeys.length === 0}\n />\n <Button\n className='tree-transfer-operation-btn'\n type={rightPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<LeftOutlined />}\n onClick={handleMoveLeft}\n disabled={rightPanel.selectedRowKeys.length === 0}\n />\n </Space>\n </div>\n\n {/* 右侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredRightData}\n selectedRowKeys={rightPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setRightPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={rightPanel.searchValue}\n setSearchValue={handleRightSearchChange}\n totalCount={rightPanel.searchValue ? filteredRightTotalCount : rightPanel.totalCount}\n title={rightTitle}\n showPagination={true}\n currentPage={rightPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleRightPageChange}\n columns={columns}\n customRender={customRender}\n />\n </div>\n </Spin>\n </div>\n );\n}\n\nexport default TreeTransfer;\n"],
5
+ "mappings": "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",
6
6
  "names": ["React", "TreeTransferPanel"]
7
7
  }
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import { TreeTransferRow } from '../types';
2
+ import { type TreeTransferRow } from '../types';
3
3
  /**
4
4
  * 从平铺的数据构建树形结构
5
5
  *
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/components/TreeTransfer/utils/index.ts"],
4
- "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport { TreeTransferRow, DEFAULT_PAGE_SIZE } from '../types';\n\n/**\n * 从平铺的数据构建树形结构\n *\n * @param data - 平铺的数据数组\n * @param options - 配置选项\n * @returns 树形结构数据\n *\n * @example\n * ```tsx\n * const flatData = [\n * { id: '1', parentId: null, name: '应用1' },\n * { id: '1-1', parentId: '1', name: '权限1' },\n * ];\n *\n * const treeData = buildTreeData(flatData, {\n * keyField: 'id',\n * parentField: 'parentId',\n * });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function buildTreeData<T extends Record<string, any>>(\n data: T[],\n options: {\n /** 唯一键字段名,默认 'id' */\n keyField?: string;\n /** 父键字段名,默认 'parentId' */\n parentField?: string;\n /** 判断是否为父节点的函数,默认:无父键则为父节点 */\n isParent?: (item: T) => boolean;\n } = {},\n): TreeTransferRow<T>[] {\n const { keyField = 'id', parentField = 'parentId', isParent = (item) => !item[parentField] } = options;\n\n const map = new Map<string | number, TreeTransferRow<T>>();\n const roots: TreeTransferRow<T>[] = [];\n\n // 第一次遍历:建立 key → node 映射\n data.forEach((item) => {\n const key = item[keyField];\n map.set(key, { key, data: item, isParent: isParent(item), children: [] });\n });\n\n // 第二次遍历:挂载父子关系\n data.forEach((item) => {\n const key = item[keyField];\n const parentId = item[parentField];\n const node = map.get(key)!;\n\n if (parentId && map.has(parentId)) {\n map.get(parentId)!.children!.push(node);\n } else {\n roots.push(node);\n }\n });\n\n return roots;\n}\n\n/**\n * 将树形结构平铺为一维数组(深度优先)\n *\n * @example\n * ```tsx\n * const flat = flattenTreeData([{ key: '1', children: [{ key: '1-1' }] }]);\n * // → [{ key: '1' }, { key: '1-1' }]\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function flattenTreeData<T = any>(treeData: TreeTransferRow<T>[]): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n function traverse(nodes: TreeTransferRow<T>[]) {\n nodes.forEach((node) => {\n result.push(node);\n if (node.children?.length) traverse(node.children);\n });\n }\n\n traverse(treeData);\n return result;\n}\n\n/**\n * 根据页码切片数据(前端分页)\n *\n * @param data - 数据数组\n * @param page - 页码(从 1 开始)\n * @param pageSize - 每页条数\n * @returns 当前页数据\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function sliceDataByPage<T = any>(\n data: TreeTransferRow<T>[],\n page: number,\n pageSize: number = DEFAULT_PAGE_SIZE,\n): TreeTransferRow<T>[] {\n const start = (page - 1) * pageSize;\n return data.slice(start, start + pageSize);\n}\n\n/**\n * 过滤数据(支持模糊搜索,递归保留有匹配子节点的父节点)\n *\n * @param data - 数据数组\n * @param searchValue - 搜索关键词(空字符串返回全量数据)\n * @param fields - 搜索字段列表,支持字段名或自定义取值函数,默认 ['id', 'name']\n * @returns 过滤后的数据\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function filterData<T = any>(\n data: TreeTransferRow<T>[],\n searchValue: string,\n fields: (string | ((item: T) => string))[] = ['id', 'name'],\n): TreeTransferRow<T>[] {\n if (!searchValue.trim()) return data;\n\n const lowerSearch = searchValue.toLowerCase();\n\n return data.filter((item) => {\n // 当前节点任意字段匹配即保留\n const selfMatch = fields.some((field) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const value = typeof field === 'function' ? field(item.data) : (item.data as any)[field];\n return String(value ?? '')\n .toLowerCase()\n .includes(lowerSearch);\n });\n\n if (selfMatch) return true;\n\n // 子节点有匹配项则保留父节点(子节点也递归过滤)\n if (item.children?.length) {\n return filterData(item.children, searchValue, fields).length > 0;\n }\n\n return false;\n });\n}\n\n/**\n * 获取选中节点及其所有后代节点的 key 集合(用于批量移除)\n *\n * 修复说明:原实现对 3+ 层树只展开 2 层。现改为对每个选中节点\n * 递归收集完整后代链,支持任意深度的树结构。\n *\n * @param selectedKeys - 选中的 keys\n * @param dataSource - 完整数据源\n * @returns 所有相关 key(字符串形式,含选中节点本身)\n *\n * @example\n * ```tsx\n * // 选中 'app1'(含 2 级子节点)\n * getAllDescendantKeys(['app1'], dataSource);\n * // → ['app1', 'app1-perm1', 'app1-perm1-sub1', 'app1-perm2', ...]\n * ```\n */\nexport function getAllDescendantKeys(selectedKeys: React.Key[], dataSource: TreeTransferRow[]): string[] {\n const keySet = new Set(selectedKeys.map(String));\n const allKeys: string[] = [];\n\n /** 递归收集节点本身及所有后代的 key */\n function collectWithDescendants(node: TreeTransferRow): void {\n allKeys.push(String(node.key));\n node.children?.forEach(collectWithDescendants);\n }\n\n function traverse(nodes: TreeTransferRow[]): void {\n nodes.forEach((node) => {\n if (keySet.has(String(node.key))) {\n // 选中节点:收集自身及全部后代\n collectWithDescendants(node);\n } else {\n // 未选中:继续向下搜索\n if (node.children?.length) traverse(node.children);\n }\n });\n }\n\n traverse(dataSource);\n return allKeys;\n}\n\n/**\n * 计算数据总节点数(包含所有后代)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function countTotalNodes<T = any>(data: TreeTransferRow<T>[]): number {\n let count = 0;\n function traverse(nodes: TreeTransferRow<T>[]) {\n nodes.forEach((node) => {\n count += 1;\n if (node.children?.length) traverse(node.children);\n });\n }\n traverse(data);\n return count;\n}\n\n/**\n * 计算顶层节点数(用于分页总数,不含嵌套子节点)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function countParentNodes<T = any>(data: TreeTransferRow<T>[]): number {\n return data.length;\n}\n\n/**\n * 查找节点及其所有后代节点(按 key 定位)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function findNodeWithDescendants<T = any>(\n key: string | number,\n dataSource: TreeTransferRow<T>[],\n): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n function traverse(nodes: TreeTransferRow<T>[]): boolean {\n for (const node of nodes) {\n if (node.key === key) {\n result.push(node);\n node.children?.forEach((child) => {\n result.push(child);\n if (child.children) traverse(child.children);\n });\n return true;\n }\n if (node.children && traverse(node.children)) return true;\n }\n return false;\n }\n\n traverse(dataSource);\n return result;\n}\n\n/**\n * 从树形数据中移除指定 key 的节点(不可变,返回新数组)\n *\n * @param dataSource - 数据源\n * @param keysToRemove - 要移除的节点 key 集合\n * @returns 过滤后的新数据源\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function removeNodesFromTree<T = any>(\n dataSource: TreeTransferRow<T>[],\n keysToRemove: Set<string | number>,\n): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n for (const node of dataSource) {\n if (keysToRemove.has(node.key)) continue;\n\n if (node.children?.length) {\n result.push({ ...node, children: removeNodesFromTree(node.children, keysToRemove) });\n } else {\n result.push(node);\n }\n }\n\n return result;\n}\n\n/**\n * 向树形数据添加节点\n *\n * @param dataSource - 数据源\n * @param parentKey - 父节点 key;传 null 表示添加到根\n * @param nodes - 要添加的节点列表\n * @returns 新的数据源\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addNodesToTree<T = any>(\n dataSource: TreeTransferRow<T>[],\n parentKey: string | number | null,\n nodes: TreeTransferRow<T>[],\n): TreeTransferRow<T>[] {\n if (parentKey === null) {\n return [...dataSource, ...nodes];\n }\n\n return dataSource.map((node) => {\n if (node.key === parentKey) {\n return { ...node, children: [...(node.children ?? []), ...nodes] };\n }\n if (node.children) {\n return { ...node, children: addNodesToTree(node.children, parentKey, nodes) };\n }\n return node;\n });\n}\n\n/**\n * 从树形数据中提取\"顶层选中节点\"(用于穿梭框移动操作)\n *\n * 行为:遍历树,遇到选中节点时直接收集(含其 children),不再向下递归。\n * 这样可以避免父节点和其已选中的子节点被分别添加两次。\n *\n * 适用场景:AntD Table 的 checkStrictly:false 级联选择中,\n * 选中父节点会自动勾选子节点。move 时只需携带父节点(含 children)。\n * 若仅选了某个子节点,则该子节点会被作为顶层节点添加到目标列表。\n *\n * @param selectedKeys - 选中的 key 集合(字符串)\n * @param dataSource - 数据源(支持嵌套树)\n * @returns 最小集合的顶层选中节点列表\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractTopLevelSelectedNodes<T = any>(\n selectedKeys: Set<string>,\n dataSource: TreeTransferRow<T>[],\n): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n function traverse(nodes: TreeTransferRow<T>[]): void {\n nodes.forEach((node) => {\n if (selectedKeys.has(String(node.key))) {\n // 选中节点:整体移动(children 随之迁移)\n result.push(node);\n } else if (node.children?.length) {\n // 父节点未选中:继续向下搜寻子节点选中项\n traverse(node.children);\n }\n });\n }\n\n traverse(dataSource);\n return result;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\nimport { DEFAULT_PAGE_SIZE, type TreeTransferRow } from '../types';\n\n/**\n * 从平铺的数据构建树形结构\n *\n * @param data - 平铺的数据数组\n * @param options - 配置选项\n * @returns 树形结构数据\n *\n * @example\n * ```tsx\n * const flatData = [\n * { id: '1', parentId: null, name: '应用1' },\n * { id: '1-1', parentId: '1', name: '权限1' },\n * ];\n *\n * const treeData = buildTreeData(flatData, {\n * keyField: 'id',\n * parentField: 'parentId',\n * });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function buildTreeData<T extends Record<string, any>>(\n data: T[],\n options: {\n /** 唯一键字段名,默认 'id' */\n keyField?: string;\n /** 父键字段名,默认 'parentId' */\n parentField?: string;\n /** 判断是否为父节点的函数,默认:无父键则为父节点 */\n isParent?: (item: T) => boolean;\n } = {},\n): TreeTransferRow<T>[] {\n const { keyField = 'id', parentField = 'parentId', isParent = (item) => !item[parentField] } = options;\n\n const map = new Map<string | number, TreeTransferRow<T>>();\n const roots: TreeTransferRow<T>[] = [];\n\n // 第一次遍历:建立 key → node 映射\n data.forEach((item) => {\n const key = item[keyField];\n map.set(key, { key, data: item, isParent: isParent(item), children: [] });\n });\n\n // 第二次遍历:挂载父子关系\n data.forEach((item) => {\n const key = item[keyField];\n const parentId = item[parentField];\n const node = map.get(key)!;\n\n if (parentId && map.has(parentId)) {\n map.get(parentId)!.children!.push(node);\n } else {\n roots.push(node);\n }\n });\n\n return roots;\n}\n\n/**\n * 将树形结构平铺为一维数组(深度优先)\n *\n * @example\n * ```tsx\n * const flat = flattenTreeData([{ key: '1', children: [{ key: '1-1' }] }]);\n * // → [{ key: '1' }, { key: '1-1' }]\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function flattenTreeData<T = any>(treeData: TreeTransferRow<T>[]): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n function traverse(nodes: TreeTransferRow<T>[]) {\n nodes.forEach((node) => {\n result.push(node);\n if (node.children?.length) traverse(node.children);\n });\n }\n\n traverse(treeData);\n return result;\n}\n\n/**\n * 根据页码切片数据(前端分页)\n *\n * @param data - 数据数组\n * @param page - 页码(从 1 开始)\n * @param pageSize - 每页条数\n * @returns 当前页数据\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function sliceDataByPage<T = any>(\n data: TreeTransferRow<T>[],\n page: number,\n pageSize: number = DEFAULT_PAGE_SIZE,\n): TreeTransferRow<T>[] {\n const start = (page - 1) * pageSize;\n return data.slice(start, start + pageSize);\n}\n\n/**\n * 过滤数据(支持模糊搜索,递归保留有匹配子节点的父节点)\n *\n * @param data - 数据数组\n * @param searchValue - 搜索关键词(空字符串返回全量数据)\n * @param fields - 搜索字段列表,支持字段名或自定义取值函数,默认 ['id', 'name']\n * @returns 过滤后的数据\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function filterData<T = any>(\n data: TreeTransferRow<T>[],\n searchValue: string,\n fields: (string | ((item: T) => string))[] = ['id', 'name'],\n): TreeTransferRow<T>[] {\n if (!searchValue.trim()) return data;\n\n const lowerSearch = searchValue.toLowerCase();\n\n return data.filter((item) => {\n // 当前节点任意字段匹配即保留\n const selfMatch = fields.some((field) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const value = typeof field === 'function' ? field(item.data) : (item.data as any)[field];\n return String(value ?? '')\n .toLowerCase()\n .includes(lowerSearch);\n });\n\n if (selfMatch) return true;\n\n // 子节点有匹配项则保留父节点(子节点也递归过滤)\n if (item.children?.length) {\n return filterData(item.children, searchValue, fields).length > 0;\n }\n\n return false;\n });\n}\n\n/**\n * 获取选中节点及其所有后代节点的 key 集合(用于批量移除)\n *\n * 修复说明:原实现对 3+ 层树只展开 2 层。现改为对每个选中节点\n * 递归收集完整后代链,支持任意深度的树结构。\n *\n * @param selectedKeys - 选中的 keys\n * @param dataSource - 完整数据源\n * @returns 所有相关 key(字符串形式,含选中节点本身)\n *\n * @example\n * ```tsx\n * // 选中 'app1'(含 2 级子节点)\n * getAllDescendantKeys(['app1'], dataSource);\n * // → ['app1', 'app1-perm1', 'app1-perm1-sub1', 'app1-perm2', ...]\n * ```\n */\nexport function getAllDescendantKeys(selectedKeys: React.Key[], dataSource: TreeTransferRow[]): string[] {\n const keySet = new Set(selectedKeys.map(String));\n const allKeys: string[] = [];\n\n /** 递归收集节点本身及所有后代的 key */\n function collectWithDescendants(node: TreeTransferRow): void {\n allKeys.push(String(node.key));\n node.children?.forEach(collectWithDescendants);\n }\n\n function traverse(nodes: TreeTransferRow[]): void {\n nodes.forEach((node) => {\n if (keySet.has(String(node.key))) {\n // 选中节点:收集自身及全部后代\n collectWithDescendants(node);\n } else {\n // 未选中:继续向下搜索\n if (node.children?.length) traverse(node.children);\n }\n });\n }\n\n traverse(dataSource);\n return allKeys;\n}\n\n/**\n * 计算数据总节点数(包含所有后代)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function countTotalNodes<T = any>(data: TreeTransferRow<T>[]): number {\n let count = 0;\n function traverse(nodes: TreeTransferRow<T>[]) {\n nodes.forEach((node) => {\n count += 1;\n if (node.children?.length) traverse(node.children);\n });\n }\n traverse(data);\n return count;\n}\n\n/**\n * 计算顶层节点数(用于分页总数,不含嵌套子节点)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function countParentNodes<T = any>(data: TreeTransferRow<T>[]): number {\n return data.length;\n}\n\n/**\n * 查找节点及其所有后代节点(按 key 定位)\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function findNodeWithDescendants<T = any>(\n key: string | number,\n dataSource: TreeTransferRow<T>[],\n): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n function traverse(nodes: TreeTransferRow<T>[]): boolean {\n for (const node of nodes) {\n if (node.key === key) {\n result.push(node);\n node.children?.forEach((child) => {\n result.push(child);\n if (child.children) traverse(child.children);\n });\n return true;\n }\n if (node.children && traverse(node.children)) return true;\n }\n return false;\n }\n\n traverse(dataSource);\n return result;\n}\n\n/**\n * 从树形数据中移除指定 key 的节点(不可变,返回新数组)\n *\n * @param dataSource - 数据源\n * @param keysToRemove - 要移除的节点 key 集合\n * @returns 过滤后的新数据源\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function removeNodesFromTree<T = any>(\n dataSource: TreeTransferRow<T>[],\n keysToRemove: Set<string | number>,\n): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n for (const node of dataSource) {\n if (keysToRemove.has(node.key)) continue;\n\n if (node.children?.length) {\n result.push({ ...node, children: removeNodesFromTree(node.children, keysToRemove) });\n } else {\n result.push(node);\n }\n }\n\n return result;\n}\n\n/**\n * 向树形数据添加节点\n *\n * @param dataSource - 数据源\n * @param parentKey - 父节点 key;传 null 表示添加到根\n * @param nodes - 要添加的节点列表\n * @returns 新的数据源\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addNodesToTree<T = any>(\n dataSource: TreeTransferRow<T>[],\n parentKey: string | number | null,\n nodes: TreeTransferRow<T>[],\n): TreeTransferRow<T>[] {\n if (parentKey === null) {\n return [...dataSource, ...nodes];\n }\n\n return dataSource.map((node) => {\n if (node.key === parentKey) {\n return { ...node, children: [...(node.children ?? []), ...nodes] };\n }\n if (node.children) {\n return { ...node, children: addNodesToTree(node.children, parentKey, nodes) };\n }\n return node;\n });\n}\n\n/**\n * 从树形数据中提取\"顶层选中节点\"(用于穿梭框移动操作)\n *\n * 行为:遍历树,遇到选中节点时直接收集(含其 children),不再向下递归。\n * 这样可以避免父节点和其已选中的子节点被分别添加两次。\n *\n * 适用场景:AntD Table 的 checkStrictly:false 级联选择中,\n * 选中父节点会自动勾选子节点。move 时只需携带父节点(含 children)。\n * 若仅选了某个子节点,则该子节点会被作为顶层节点添加到目标列表。\n *\n * @param selectedKeys - 选中的 key 集合(字符串)\n * @param dataSource - 数据源(支持嵌套树)\n * @returns 最小集合的顶层选中节点列表\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function extractTopLevelSelectedNodes<T = any>(\n selectedKeys: Set<string>,\n dataSource: TreeTransferRow<T>[],\n): TreeTransferRow<T>[] {\n const result: TreeTransferRow<T>[] = [];\n\n function traverse(nodes: TreeTransferRow<T>[]): void {\n nodes.forEach((node) => {\n if (selectedKeys.has(String(node.key))) {\n // 选中节点:整体移动(children 随之迁移)\n result.push(node);\n } else if (node.children?.length) {\n // 父节点未选中:继续向下搜寻子节点选中项\n traverse(node.children);\n }\n });\n }\n\n traverse(dataSource);\n return result;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Markdown 渲染器组件
3
+ */
4
+ import React from 'react';
5
+ export interface YKMarkdownProps {
6
+ markdown: string;
7
+ showToc?: boolean;
8
+ language?: string;
9
+ }
10
+ declare const YKMarkdown: React.FC<YKMarkdownProps>;
11
+ export default YKMarkdown;
@@ -0,0 +1,188 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/components/YKMarkdown/index.tsx
30
+ var YKMarkdown_exports = {};
31
+ __export(YKMarkdown_exports, {
32
+ default: () => YKMarkdown_default
33
+ });
34
+ module.exports = __toCommonJS(YKMarkdown_exports);
35
+ var import_react_markdown_preview = __toESM(require("@uiw/react-markdown-preview"));
36
+ var import_react = __toESM(require("react"));
37
+ var import_index_module = __toESM(require("./index.module.less"));
38
+ var YKMarkdown = ({ markdown, showToc = false }) => {
39
+ const contentRef = (0, import_react.useRef)(null);
40
+ const [headings, setHeadings] = (0, import_react.useState)([]);
41
+ (0, import_react.useEffect)(() => {
42
+ if (!showToc) {
43
+ setHeadings([]);
44
+ return;
45
+ }
46
+ if (!contentRef.current)
47
+ return;
48
+ const headingElements = contentRef.current.querySelectorAll("h1, h2, h3, h4, h5, h6");
49
+ const headingList = Array.from(headingElements).map((el) => ({
50
+ id: el.id,
51
+ text: el.textContent || "",
52
+ level: parseInt(el.tagName.charAt(1), 10)
53
+ }));
54
+ setHeadings(headingList);
55
+ }, [markdown, showToc]);
56
+ const handleScrollTo = (0, import_react.useCallback)((id) => {
57
+ const element = document.getElementById(id);
58
+ if (element) {
59
+ element.scrollIntoView({ behavior: "smooth", block: "start" });
60
+ }
61
+ }, []);
62
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: import_index_module.default.container }, showToc && headings.length > 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: import_index_module.default.toc }, /* @__PURE__ */ import_react.default.createElement("h3", null, "目录"), /* @__PURE__ */ import_react.default.createElement("ul", { style: { paddingLeft: "16px", fontSize: "12px", color: "#666" } }, headings.map((heading) => /* @__PURE__ */ import_react.default.createElement(
63
+ "li",
64
+ {
65
+ key: heading.id,
66
+ style: {
67
+ marginLeft: `${(heading.level - 1) * 12}px`,
68
+ listStyle: "none",
69
+ marginBottom: "8px"
70
+ }
71
+ },
72
+ /* @__PURE__ */ import_react.default.createElement(
73
+ "a",
74
+ {
75
+ href: `#${heading.id}`,
76
+ onClick: (e) => {
77
+ e.preventDefault();
78
+ handleScrollTo(heading.id);
79
+ },
80
+ style: { color: "#000", textDecoration: "none" }
81
+ },
82
+ heading.text
83
+ )
84
+ )))), /* @__PURE__ */ import_react.default.createElement("div", { ref: contentRef, className: import_index_module.default.content }, /* @__PURE__ */ import_react.default.createElement(
85
+ import_react_markdown_preview.default,
86
+ {
87
+ source: markdown,
88
+ components: { code: Code, pre: Pre },
89
+ style: { padding: 16 }
90
+ }
91
+ )), showToc && headings.length > 0 && /* @__PURE__ */ import_react.default.createElement("div", { className: import_index_module.default.spacer }));
92
+ };
93
+ var MermaidCode = ({ code, className }) => {
94
+ const demoid = (0, import_react.useMemo)(() => `dome${parseInt(String(Math.random() * 1e15), 10).toString(36)}`, []);
95
+ const [container, setContainer] = (0, import_react.useState)(null);
96
+ const [mermaidInstance, setMermaidInstance] = (0, import_react.useState)(null);
97
+ const isMermaid = className && /^language-mermaid/.test(className.toLocaleLowerCase());
98
+ (0, import_react.useEffect)(() => {
99
+ if (isMermaid && !mermaidInstance) {
100
+ import("mermaid").then((mod) => {
101
+ setMermaidInstance(mod.default || mod);
102
+ });
103
+ }
104
+ }, [isMermaid, mermaidInstance]);
105
+ const reRender = (0, import_react.useCallback)(async () => {
106
+ if (container && isMermaid && mermaidInstance) {
107
+ try {
108
+ const str = await mermaidInstance.render(demoid, code);
109
+ container.innerHTML = str.svg;
110
+ } catch (error) {
111
+ container.innerHTML = String(error);
112
+ }
113
+ }
114
+ }, [container, isMermaid, code, demoid, mermaidInstance]);
115
+ (0, import_react.useEffect)(() => {
116
+ reRender();
117
+ }, [reRender]);
118
+ const refElement = (0, import_react.useCallback)((node) => {
119
+ if (node !== null) {
120
+ setContainer(node);
121
+ }
122
+ }, []);
123
+ if (isMermaid) {
124
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("code", { id: demoid, style: { display: "none" } }), /* @__PURE__ */ import_react.default.createElement("code", { ref: refElement, "data-name": "mermaid" }));
125
+ }
126
+ return /* @__PURE__ */ import_react.default.createElement("code", null, code);
127
+ };
128
+ var getCodeString = (children) => {
129
+ let result = "";
130
+ const traverse = (nodes) => {
131
+ for (const node of nodes) {
132
+ if (typeof node === "object" && node !== null && "type" in node) {
133
+ const n = node;
134
+ if (n.type === "text" && n.value) {
135
+ result += n.value;
136
+ } else if (n.children) {
137
+ traverse(n.children);
138
+ }
139
+ }
140
+ }
141
+ };
142
+ traverse(children);
143
+ return result;
144
+ };
145
+ var Code = ({ inline, children, className, node, ...props }) => {
146
+ if (inline) {
147
+ return /* @__PURE__ */ import_react.default.createElement("code", { ...props }, children);
148
+ }
149
+ const code = (node == null ? void 0 : node.children) ? getCodeString(node.children) : Array.isArray(children) ? String(children[0] || "") : String(children || "");
150
+ return /* @__PURE__ */ import_react.default.createElement(MermaidCode, { code, className });
151
+ };
152
+ var Pre = ({ children, node, ...props }) => {
153
+ let codeStr = "";
154
+ let mermaidCode = "";
155
+ let mermaidClassName = "";
156
+ import_react.default.Children.forEach(children, (child) => {
157
+ var _a, _b;
158
+ if (import_react.default.isValidElement(child)) {
159
+ const childProps = child.props;
160
+ if (childProps == null ? void 0 : childProps.node) {
161
+ codeStr = getCodeString(childProps.node.children);
162
+ }
163
+ if ((_b = (_a = childProps == null ? void 0 : childProps.className) == null ? void 0 : _a.includes) == null ? void 0 : _b.call(_a, "language-mermaid")) {
164
+ mermaidCode = codeStr;
165
+ mermaidClassName = childProps.className || "";
166
+ }
167
+ }
168
+ });
169
+ if (!codeStr && (node == null ? void 0 : node.children)) {
170
+ codeStr = getCodeString(node.children);
171
+ }
172
+ const renderContent = (child) => {
173
+ var _a, _b, _c, _d;
174
+ if (import_react.default.isValidElement(child)) {
175
+ const childElement = child;
176
+ if ((_c = (_b = (_a = childElement.props) == null ? void 0 : _a.className) == null ? void 0 : _b.includes) == null ? void 0 : _c.call(_b, "language-mermaid")) {
177
+ return /* @__PURE__ */ import_react.default.createElement(MermaidCode, { code: mermaidCode, className: mermaidClassName });
178
+ }
179
+ return import_react.default.cloneElement(childElement, {
180
+ children: import_react.default.Children.map((_d = childElement.props) == null ? void 0 : _d.children, renderContent)
181
+ });
182
+ }
183
+ return child;
184
+ };
185
+ return /* @__PURE__ */ import_react.default.createElement("div", { className: import_index_module.default.codeBlock }, /* @__PURE__ */ import_react.default.createElement("pre", { ...props }, import_react.default.Children.map(children, renderContent)));
186
+ };
187
+ var YKMarkdown_default = YKMarkdown;
188
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/components/YKMarkdown/index.tsx"],
4
+ "sourcesContent": ["/**\n * Markdown 渲染器组件\n */\n\nimport MarkdownPreview from '@uiw/react-markdown-preview';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport styles from './index.module.less';\n\ninterface HeadingItem {\n id: string;\n text: string;\n level: number;\n}\n\nexport interface YKMarkdownProps {\n markdown: string;\n showToc?: boolean;\n language?: string;\n}\n\nconst YKMarkdown: React.FC<YKMarkdownProps> = ({ markdown, showToc = false }) => {\n const contentRef = useRef<HTMLDivElement>(null);\n const [headings, setHeadings] = useState<HeadingItem[]>([]);\n\n useEffect(() => {\n if (!showToc) {\n setHeadings([]);\n return;\n }\n if (!contentRef.current) return;\n\n const headingElements = contentRef.current.querySelectorAll('h1, h2, h3, h4, h5, h6');\n const headingList: HeadingItem[] = Array.from(headingElements).map((el: HTMLElement) => ({\n id: el.id,\n text: el.textContent || '',\n level: parseInt(el.tagName.charAt(1), 10),\n }));\n\n setHeadings(headingList);\n }, [markdown, showToc]);\n\n const handleScrollTo = useCallback((id: string) => {\n const element = document.getElementById(id);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n }, []);\n\n return (\n <div className={styles.container}>\n {showToc && headings.length > 0 && (\n <div className={styles.toc}>\n <h3>目录</h3>\n <ul style={{ paddingLeft: '16px', fontSize: '12px', color: '#666' }}>\n {headings.map((heading) => (\n <li\n key={heading.id}\n style={{\n marginLeft: `${(heading.level - 1) * 12}px`,\n listStyle: 'none',\n marginBottom: '8px',\n }}\n >\n <a\n href={`#${heading.id}`}\n onClick={(e) => {\n e.preventDefault();\n handleScrollTo(heading.id);\n }}\n style={{ color: '#000', textDecoration: 'none' }}\n >\n {heading.text}\n </a>\n </li>\n ))}\n </ul>\n </div>\n )}\n\n <div ref={contentRef} className={styles.content}>\n <MarkdownPreview\n source={markdown}\n components={{ code: Code as React.ComponentType, pre: Pre as React.ComponentType }}\n style={{ padding: 16 }}\n />\n </div>\n\n {showToc && headings.length > 0 && <div className={styles.spacer} />}\n </div>\n );\n};\n\ninterface MermaidInstance {\n render: (id: string, code: string) => Promise<{ svg: string }>;\n}\n\nconst MermaidCode: React.FC<{ code: string; className?: string }> = ({ code, className }) => {\n const demoid = useMemo(() => `dome${parseInt(String(Math.random() * 1e15), 10).toString(36)}`, []);\n const [container, setContainer] = useState<HTMLElement | null>(null);\n const [mermaidInstance, setMermaidInstance] = useState<MermaidInstance | null>(null);\n const isMermaid = className && /^language-mermaid/.test(className.toLocaleLowerCase());\n\n useEffect(() => {\n if (isMermaid && !mermaidInstance) {\n import('mermaid').then((mod) => {\n // @ts-expect-error mermaid module type\n setMermaidInstance(mod.default || mod);\n });\n }\n }, [isMermaid, mermaidInstance]);\n\n const reRender = useCallback(async () => {\n if (container && isMermaid && mermaidInstance) {\n try {\n const str = await mermaidInstance.render(demoid, code);\n container.innerHTML = str.svg;\n } catch (error) {\n container.innerHTML = String(error);\n }\n }\n }, [container, isMermaid, code, demoid, mermaidInstance]);\n\n useEffect(() => {\n reRender();\n }, [reRender]);\n\n const refElement = useCallback((node: HTMLElement | null) => {\n if (node !== null) {\n setContainer(node);\n }\n }, []);\n\n if (isMermaid) {\n return (\n <>\n <code id={demoid} style={{ display: 'none' }} />\n <code ref={refElement} data-name='mermaid' />\n </>\n );\n }\n return <code>{code}</code>;\n};\n\ninterface CodeProps {\n inline?: boolean;\n children?: React.ReactNode;\n className?: string;\n node?: { children?: unknown[] };\n [key: string]: unknown;\n}\n\nconst getCodeString = (children: unknown[]): string => {\n let result = '';\n const traverse = (nodes: unknown[]) => {\n for (const node of nodes) {\n if (typeof node === 'object' && node !== null && 'type' in node) {\n const n = node as { type: string; children?: unknown[]; value?: string };\n if (n.type === 'text' && n.value) {\n result += n.value;\n } else if (n.children) {\n traverse(n.children);\n }\n }\n }\n };\n traverse(children);\n return result;\n};\n\nconst Code: React.FC<CodeProps> = ({ inline, children, className, node, ...props }) => {\n if (inline) {\n return <code {...props}>{children}</code>;\n }\n const code = node?.children\n ? getCodeString(node.children as unknown[])\n : Array.isArray(children)\n ? String(children[0] || '')\n : String(children || '');\n return <MermaidCode code={code} className={className} />;\n};\n\ninterface PreProps {\n children?: React.ReactNode;\n node?: { children?: unknown[] };\n [key: string]: unknown;\n}\n\nconst Pre: React.FC<PreProps> = ({ children, node, ...props }) => {\n let codeStr = '';\n let mermaidCode = '';\n let mermaidClassName = '';\n React.Children.forEach(children, (child) => {\n if (React.isValidElement(child)) {\n const childProps = child.props as CodeProps;\n if (childProps?.node) {\n codeStr = getCodeString(childProps.node.children as unknown[]);\n }\n if (childProps?.className?.includes?.('language-mermaid')) {\n mermaidCode = codeStr;\n mermaidClassName = childProps.className || '';\n }\n }\n });\n if (!codeStr && node?.children) {\n codeStr = getCodeString(node.children as unknown[]);\n }\n\n const renderContent = (child: React.ReactNode): React.ReactNode => {\n if (React.isValidElement(child)) {\n const childElement = child as React.ReactElement<{ children?: React.ReactNode; className?: string }>;\n if (childElement.props?.className?.includes?.('language-mermaid')) {\n return <MermaidCode code={mermaidCode} className={mermaidClassName} />;\n }\n return React.cloneElement(childElement, {\n children: React.Children.map(childElement.props?.children, renderContent),\n });\n }\n return child;\n };\n\n return (\n <div className={styles.codeBlock}>\n <pre {...props}>{React.Children.map(children, renderContent)}</pre>\n </div>\n );\n};\n\nexport default YKMarkdown;\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "styles", "MarkdownPreview"]
7
+ }
@@ -0,0 +1,83 @@
1
+ .container {
2
+ display: flex;
3
+ gap: 24px;
4
+ position: relative;
5
+ }
6
+
7
+ .toc {
8
+ width: 220px;
9
+ flex-shrink: 0;
10
+ position: sticky;
11
+ top: 80px;
12
+ max-height: calc(100vh - 96px);
13
+ overflow-y: auto;
14
+ z-index: 10;
15
+ background-color: #fff;
16
+ }
17
+
18
+ .content {
19
+ flex: 1;
20
+ min-width: 0;
21
+ }
22
+
23
+ .codeBlock {
24
+ position: relative;
25
+
26
+ .copyBtn {
27
+ position: absolute;
28
+ top: 8px;
29
+ right: 8px;
30
+ padding: 4px 8px;
31
+ background: rgba(255, 255, 255, 0.1);
32
+ border: 1px solid rgba(255, 255, 255, 0.2);
33
+ border-radius: 4px;
34
+ cursor: pointer;
35
+ color: #999;
36
+ font-size: 12px;
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ transition: all 0.2s;
41
+ z-index: 10;
42
+ opacity: 0;
43
+
44
+ &:hover {
45
+ background: rgba(255, 255, 255, 0.2);
46
+ color: #fff;
47
+ }
48
+
49
+ &.success {
50
+ color: #52c41a;
51
+ border-color: #52c41a;
52
+ opacity: 1;
53
+ }
54
+ }
55
+ }
56
+
57
+ .codeBlock:hover .copyBtn {
58
+ opacity: 1;
59
+ }
60
+
61
+ .spacer {
62
+ width: 220px;
63
+ flex-shrink: 0;
64
+ }
65
+
66
+ @media (max-width: 1024px) {
67
+ .container {
68
+ flex-direction: column;
69
+ gap: 16px;
70
+ }
71
+
72
+ .toc {
73
+ width: 100%;
74
+ position: static;
75
+ max-height: none;
76
+ border-bottom: 1px solid #eee;
77
+ padding-bottom: 16px;
78
+ }
79
+
80
+ .spacer {
81
+ display: none;
82
+ }
83
+ }