@robot-admin/naive-ui-components 0.6.19 → 0.6.21

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 (274) hide show
  1. package/CHANGELOG.md +48 -48
  2. package/README.md +277 -277
  3. package/dist/C_ActionBar-jZPsiXtT.css.map +1 -0
  4. package/dist/C_ActionBar-nnfbZCea.css.map +1 -0
  5. package/dist/C_ActionBar.css +47 -47
  6. package/dist/C_ActionBar.js.map +1 -1
  7. package/dist/C_ActionBar2.js +1 -1
  8. package/dist/C_ActionBar2.js.map +1 -1
  9. package/dist/{C_AntV-BY8jqqmi.css.map → C_AntV-A3NXx_sF.css.map} +1 -1
  10. package/dist/{C_AntV-BbkHc-_a.css.map → C_AntV-D2Zp2qQF.css.map} +1 -1
  11. package/dist/C_AntV.css +78 -78
  12. package/dist/C_AntV.js.map +1 -1
  13. package/dist/C_AntV2.js +2 -2
  14. package/dist/C_AntV2.js.map +1 -1
  15. package/dist/{C_AudioPlayer-DKRIGhi7.css.map → C_AudioPlayer-CXl4yP_m.css.map} +1 -1
  16. package/dist/{C_AudioPlayer-DlB6eNsa.css.map → C_AudioPlayer-CcBtt71m.css.map} +1 -1
  17. package/dist/C_AudioPlayer.css +47 -47
  18. package/dist/C_AudioPlayer.js.map +1 -1
  19. package/dist/C_AudioPlayer2.js +1 -1
  20. package/dist/C_AudioPlayer2.js.map +1 -1
  21. package/dist/{C_AvatarGroup-D02zci-i.css.map → C_AvatarGroup-CtPhfH9h.css.map} +1 -1
  22. package/dist/{C_AvatarGroup-DatHaUlY.css.map → C_AvatarGroup-M1dNPH3E.css.map} +1 -1
  23. package/dist/C_AvatarGroup.css +21 -21
  24. package/dist/C_AvatarGroup.js.map +1 -1
  25. package/dist/C_AvatarGroup2.js +1 -1
  26. package/dist/C_AvatarGroup2.js.map +1 -1
  27. package/dist/{C_Barcode-DYDRDe2O.css.map → C_Barcode-DjTmDkbQ.css.map} +1 -1
  28. package/dist/{C_Barcode-muJdc_O4.css.map → C_Barcode-Do1Ozsmh.css.map} +1 -1
  29. package/dist/C_Barcode.css +7 -7
  30. package/dist/C_Barcode.js.map +1 -1
  31. package/dist/C_Barcode2.js +1 -1
  32. package/dist/C_Barcode2.js.map +1 -1
  33. package/dist/C_Breadcrumb.js.map +1 -1
  34. package/dist/C_Breadcrumb2.js.map +1 -1
  35. package/dist/{C_Captcha-9_hk6VmY.css.map → C_Captcha-CZmAETly.css.map} +1 -1
  36. package/dist/{C_Captcha-MtASlJ0f.css.map → C_Captcha-Ccq3DMrR.css.map} +1 -1
  37. package/dist/C_Captcha.css +19 -19
  38. package/dist/C_Captcha.js.map +1 -1
  39. package/dist/C_Captcha2.js +1 -1
  40. package/dist/C_Captcha2.js.map +1 -1
  41. package/dist/{C_Chat-CcjZdAwu.css.map → C_Chat-CcdWgVE8.css.map} +1 -1
  42. package/dist/{C_Chat-Diq7tyWU.css.map → C_Chat-Cx0woEEe.css.map} +1 -1
  43. package/dist/C_Chat.css +65 -65
  44. package/dist/C_Chat.js.map +1 -1
  45. package/dist/C_Chat2.js +1 -1
  46. package/dist/C_Chat2.js.map +1 -1
  47. package/dist/{C_City-Bam08Qv3.css.map → C_City-Cv5BESaN.css.map} +1 -1
  48. package/dist/{C_City-Bb3W-KaN.css.map → C_City-DNKv4MpH.css.map} +1 -1
  49. package/dist/C_City.css +29 -29
  50. package/dist/C_City.js.map +1 -1
  51. package/dist/C_City2.js +1 -1
  52. package/dist/C_City2.js.map +1 -1
  53. package/dist/C_Code-DPZlNSxL.css.map +1 -0
  54. package/dist/C_Code-avZjAnHD.css.map +1 -0
  55. package/dist/C_Code.css +3 -3
  56. package/dist/C_Code.js.map +1 -1
  57. package/dist/C_Code2.js +1 -1
  58. package/dist/C_Code2.js.map +1 -1
  59. package/dist/{C_CollapsePanel-BCmTFuDz.css.map → C_CollapsePanel-B18ryXwh.css.map} +1 -1
  60. package/dist/{C_CollapsePanel-Bxnh4Zy-.css.map → C_CollapsePanel-BiGoiHgh.css.map} +1 -1
  61. package/dist/C_CollapsePanel.css +35 -35
  62. package/dist/C_CollapsePanel.js.map +1 -1
  63. package/dist/C_CollapsePanel2.js +1 -1
  64. package/dist/C_CollapsePanel2.js.map +1 -1
  65. package/dist/{C_ContextMenu-B3Cgz_wJ.css.map → C_ContextMenu-CCsCeI39.css.map} +1 -1
  66. package/dist/{C_ContextMenu-u1LixF3_.css.map → C_ContextMenu-DOTBeltf.css.map} +1 -1
  67. package/dist/C_ContextMenu.css +17 -17
  68. package/dist/C_ContextMenu.js.map +1 -1
  69. package/dist/C_ContextMenu2.js +1 -1
  70. package/dist/C_ContextMenu2.js.map +1 -1
  71. package/dist/{C_Cron-Civir5-I.css.map → C_Cron-C0-8b5af.css.map} +1 -1
  72. package/dist/{C_Cron-iw3qpMsy.css.map → C_Cron-DqHQ92LN.css.map} +1 -1
  73. package/dist/C_Cron.css +37 -37
  74. package/dist/C_Cron.js.map +1 -1
  75. package/dist/C_Cron2.js +1 -1
  76. package/dist/C_Cron2.js.map +1 -1
  77. package/dist/C_Date.js.map +1 -1
  78. package/dist/C_Date2.js.map +1 -1
  79. package/dist/{C_Draggable-BCjIvIwT.css.map → C_Draggable-Bq6o0qXn.css.map} +1 -1
  80. package/dist/{C_Draggable-DwkSlCOS.css.map → C_Draggable-r6nhx3yM.css.map} +1 -1
  81. package/dist/C_Draggable.css +46 -46
  82. package/dist/C_Draggable.js.map +1 -1
  83. package/dist/C_Draggable2.js +1 -1
  84. package/dist/C_Draggable2.js.map +1 -1
  85. package/dist/{C_FilePreview-BhcbiXsV.css.map → C_FilePreview-BVarVvnD.css.map} +1 -1
  86. package/dist/{C_FilePreview-DJudcIbW.css.map → C_FilePreview-DHGlV4OR.css.map} +1 -1
  87. package/dist/C_FilePreview.css +91 -91
  88. package/dist/C_FilePreview.js.map +1 -1
  89. package/dist/C_FilePreview2.js +1 -1
  90. package/dist/C_FilePreview2.js.map +1 -1
  91. package/dist/{C_Form-BtcAPIRi.css.map → C_Form-BciQUPpS.css.map} +1 -1
  92. package/dist/{C_Form-D_gwQ7hC.css.map → C_Form-CKHvXL3O.css.map} +1 -1
  93. package/dist/C_Form.css +222 -222
  94. package/dist/C_Form.d.cts +2 -2
  95. package/dist/C_Form.d.ts +2 -2
  96. package/dist/C_Form.js.map +1 -1
  97. package/dist/C_Form2.js +1 -1
  98. package/dist/C_Form2.js.map +1 -1
  99. package/dist/{C_FormSearch-Bi4XYjjk.css.map → C_FormSearch-Bmd2CmG6.css.map} +1 -1
  100. package/dist/{C_FormSearch-DUGOoX0u.css.map → C_FormSearch-DBNtnjaL.css.map} +1 -1
  101. package/dist/C_FormSearch.css +45 -45
  102. package/dist/C_FormSearch.js.map +1 -1
  103. package/dist/C_FormSearch2.js +1 -1
  104. package/dist/C_FormSearch2.js.map +1 -1
  105. package/dist/{C_FormulaEditor-CJk3SSUJ.css.map → C_FormulaEditor-3WG2vtQl.css.map} +1 -1
  106. package/dist/{C_FormulaEditor-Cy7mjfVO.css.map → C_FormulaEditor-Cm0CokN5.css.map} +1 -1
  107. package/dist/C_FormulaEditor.css +78 -78
  108. package/dist/C_FormulaEditor.js.map +1 -1
  109. package/dist/C_FormulaEditor2.js +1 -1
  110. package/dist/C_FormulaEditor2.js.map +1 -1
  111. package/dist/C_FullCalendar-1U4VlG7X.css.map +1 -0
  112. package/dist/C_FullCalendar-DLUdCtqf.css.map +1 -0
  113. package/dist/C_FullCalendar.css +3 -3
  114. package/dist/C_FullCalendar.js.map +1 -1
  115. package/dist/C_FullCalendar2.js +1 -1
  116. package/dist/C_FullCalendar2.js.map +1 -1
  117. package/dist/C_Icon.js.map +1 -1
  118. package/dist/C_Icon2.js.map +1 -1
  119. package/dist/{C_ImageCropper-BqZpkZfU.css.map → C_ImageCropper-D3L2-J_J.css.map} +1 -1
  120. package/dist/{C_ImageCropper-CylwGuzS.css.map → C_ImageCropper-DrmUlaLi.css.map} +1 -1
  121. package/dist/C_ImageCropper.css +10 -10
  122. package/dist/C_ImageCropper.js.map +1 -1
  123. package/dist/C_ImageCropper2.js +1 -1
  124. package/dist/C_ImageCropper2.js.map +1 -1
  125. package/dist/C_Language.js.map +1 -1
  126. package/dist/C_Language2.js.map +1 -1
  127. package/dist/{C_Login-BkdnkBKX.css.map → C_Login-Cst_W1XC.css.map} +1 -1
  128. package/dist/{C_Login-VkMM6OJ2.css.map → C_Login-DWZ_6K1x.css.map} +1 -1
  129. package/dist/C_Login.css +72 -72
  130. package/dist/C_Login.js.map +1 -1
  131. package/dist/C_Login2.js +1 -1
  132. package/dist/C_Login2.js.map +1 -1
  133. package/dist/{C_Map-DNnBcY70.css.map → C_Map-BCJmDnJT.css.map} +1 -1
  134. package/dist/{C_Map-LEXIx6zM.css.map → C_Map-WUMXSAfy.css.map} +1 -1
  135. package/dist/C_Map.css +4 -4
  136. package/dist/C_Map.js.map +1 -1
  137. package/dist/C_Map2.js +1 -1
  138. package/dist/C_Map2.js.map +1 -1
  139. package/dist/{C_Markdown-Kujzx1qG.css.map → C_Markdown-7iBnLDtL.css.map} +1 -1
  140. package/dist/{C_Markdown-YCAmBbNF.css.map → C_Markdown-BbTvdFCl.css.map} +1 -1
  141. package/dist/C_Markdown.css +33 -33
  142. package/dist/C_Markdown.js.map +1 -1
  143. package/dist/C_Markdown2.js +1 -1
  144. package/dist/C_Markdown2.js.map +1 -1
  145. package/dist/{C_QRCode-CFNTda_1.css.map → C_QRCode-DMxSyogU.css.map} +1 -1
  146. package/dist/{C_QRCode-CmWr9lK-.css.map → C_QRCode-G7fiAkm4.css.map} +1 -1
  147. package/dist/C_QRCode.css +9 -9
  148. package/dist/C_QRCode.js.map +1 -1
  149. package/dist/C_QRCode2.js +1 -1
  150. package/dist/C_QRCode2.js.map +1 -1
  151. package/dist/{C_Signature-PN4GOLRX.css.map → C_Signature-B5fFz6RD.css.map} +1 -1
  152. package/dist/{C_Signature-fWQqGIZ-.css.map → C_Signature-es-ZNPzr.css.map} +1 -1
  153. package/dist/C_Signature.css +14 -14
  154. package/dist/C_Signature.js.map +1 -1
  155. package/dist/C_Signature2.js +1 -1
  156. package/dist/C_Signature2.js.map +1 -1
  157. package/dist/{C_SplitPane-BOwr1C7K.css.map → C_SplitPane-Br2eK8IG.css.map} +1 -1
  158. package/dist/{C_SplitPane-N-a_D-7F.css.map → C_SplitPane-DuyzUhKB.css.map} +1 -1
  159. package/dist/C_SplitPane.css +31 -31
  160. package/dist/C_SplitPane.js.map +1 -1
  161. package/dist/C_SplitPane2.js +1 -1
  162. package/dist/C_SplitPane2.js.map +1 -1
  163. package/dist/C_Steps-BHYNJI1l.css.map +1 -0
  164. package/dist/C_Steps-DY7vl-4I.css.map +1 -0
  165. package/dist/C_Steps.css +38 -38
  166. package/dist/C_Steps.js.map +1 -1
  167. package/dist/C_Steps2.js +1 -1
  168. package/dist/C_Steps2.js.map +1 -1
  169. package/dist/{C_Table-BV1wUw6f.css.map → C_Table-vZlcgH6x.css.map} +1 -1
  170. package/dist/{C_Table-LlJ-JEdm.css.map → C_Table-wzAO43l0.css.map} +1 -1
  171. package/dist/C_Table.css +93 -93
  172. package/dist/C_Table.js.map +1 -1
  173. package/dist/C_Table2.js +1 -1
  174. package/dist/C_Table2.js.map +1 -1
  175. package/dist/{C_TagsView-DX3LecK1.css.map → C_TagsView-BsutyC3U.css.map} +1 -1
  176. package/dist/{C_TagsView-DqOTa8bL.css.map → C_TagsView-Crm7yWg9.css.map} +1 -1
  177. package/dist/C_TagsView.css +36 -36
  178. package/dist/C_TagsView.js.map +1 -1
  179. package/dist/C_TagsView2.js +1 -1
  180. package/dist/C_TagsView2.js.map +1 -1
  181. package/dist/C_Time-Bd_e1YDN.css.map +1 -0
  182. package/dist/C_Time-CKb_fwdm.css.map +1 -0
  183. package/dist/C_Time.css +5 -5
  184. package/dist/C_Time.js.map +1 -1
  185. package/dist/C_Time2.js +1 -1
  186. package/dist/C_Time2.js.map +1 -1
  187. package/dist/{C_Timeline-BIvw3f41.css.map → C_Timeline-CGTFTMX0.css.map} +1 -1
  188. package/dist/{C_Timeline-VsDfCv4Q.css.map → C_Timeline-DxKyvKer.css.map} +1 -1
  189. package/dist/C_Timeline.css +42 -42
  190. package/dist/C_Timeline.js.map +1 -1
  191. package/dist/C_Timeline2.js +1 -1
  192. package/dist/C_Timeline2.js.map +1 -1
  193. package/dist/{C_Transfer-BOB6OBqS.css.map → C_Transfer-CCEqnC-v.css.map} +1 -1
  194. package/dist/{C_Transfer-Dpq7ezWC.css.map → C_Transfer-CStPm4NP.css.map} +1 -1
  195. package/dist/C_Transfer.css +31 -31
  196. package/dist/C_Transfer.js.map +1 -1
  197. package/dist/C_Transfer2.js +1 -1
  198. package/dist/C_Transfer2.js.map +1 -1
  199. package/dist/{C_Tree-D98nX9qT.css.map → C_Tree-B-Le4hjQ.css.map} +1 -1
  200. package/dist/{C_Tree-ulfm7b-P.css.map → C_Tree-DnGc_MPb.css.map} +1 -1
  201. package/dist/C_Tree.css +33 -33
  202. package/dist/C_Tree.js.map +1 -1
  203. package/dist/C_Tree2.js +1 -1
  204. package/dist/C_Tree2.js.map +1 -1
  205. package/dist/{C_VideoPlayer-4J96tKfK.css.map → C_VideoPlayer-Cdgv4Zq0.css.map} +1 -1
  206. package/dist/{C_VideoPlayer-D35seHkm.css.map → C_VideoPlayer-rm0MODUv.css.map} +1 -1
  207. package/dist/C_VideoPlayer.css +13 -13
  208. package/dist/C_VideoPlayer.js.map +1 -1
  209. package/dist/C_VideoPlayer2.js +1 -1
  210. package/dist/C_VideoPlayer2.js.map +1 -1
  211. package/dist/{C_VtableGantt-C2lxFmWg.css.map → C_VtableGantt-BpY-Rng3.css.map} +1 -1
  212. package/dist/{C_VtableGantt-Dwnkw_WL.css.map → C_VtableGantt-DB87-jdS.css.map} +1 -1
  213. package/dist/C_VtableGantt.css +15 -15
  214. package/dist/C_VtableGantt.js.map +1 -1
  215. package/dist/C_VtableGantt2.js +1 -1
  216. package/dist/C_VtableGantt2.js.map +1 -1
  217. package/dist/{C_WorkFlow-2hJfvvTK.css.map → C_WorkFlow-7F6op6qN.css.map} +1 -1
  218. package/dist/{C_WorkFlow-DHoNjl8-.css.map → C_WorkFlow-Cy3HWA6A.css.map} +1 -1
  219. package/dist/C_WorkFlow.css +108 -108
  220. package/dist/C_WorkFlow.js.map +1 -1
  221. package/dist/C_WorkFlow2.js +1 -1
  222. package/dist/C_WorkFlow2.js.map +1 -1
  223. package/dist/constants.d.ts +2 -2
  224. package/dist/constants2.d.ts +1 -1
  225. package/dist/constants3.d.ts +2 -2
  226. package/dist/constants4.d.ts +3 -3
  227. package/dist/data.d.ts +1 -1
  228. package/dist/index.cjs.map +1 -1
  229. package/dist/index.d.cts +2 -2
  230. package/dist/index.d.ts +2 -2
  231. package/dist/index.js.map +1 -1
  232. package/dist/index10.vue.d.ts +3 -3
  233. package/dist/index11.vue.d.ts +5 -5
  234. package/dist/index13.vue.d.ts +1 -1
  235. package/dist/index15.vue.d.ts +2 -2
  236. package/dist/index18.vue.d.ts +3 -3
  237. package/dist/index2.vue.d.ts +5 -5
  238. package/dist/index20.vue.d.ts +2 -2
  239. package/dist/index24.vue.d.ts +2 -2
  240. package/dist/index26.vue.d.ts +2 -2
  241. package/dist/index3.vue.d.ts +1 -1
  242. package/dist/index4.vue.d.ts +5 -5
  243. package/dist/index6.vue.d.ts +2 -2
  244. package/dist/index8.vue.d.ts +2 -2
  245. package/dist/menuAdapter.js.map +1 -1
  246. package/dist/resolver.cjs.map +1 -1
  247. package/dist/resolver.js.map +1 -1
  248. package/dist/style.css +1512 -1512
  249. package/dist/useCalendarEvents.d.ts +1 -1
  250. package/dist/useCollapsePanel.d.ts +3 -1
  251. package/dist/useCropperCore.d.ts +5 -5
  252. package/dist/useDraggableLayout.d.ts +3 -3
  253. package/dist/useDynamicFormState.d.ts +7 -7
  254. package/dist/useEdgeInteraction.d.ts +1 -1
  255. package/dist/useFullscreen.d.ts +2 -2
  256. package/dist/useInfiniteScroll.d.ts +3 -3
  257. package/dist/useModalEdit.d.ts +3 -3
  258. package/dist/useQRCode.d.ts +3 -3
  259. package/dist/useSignatureHistory.d.ts +1 -1
  260. package/dist/useSplitResize.d.ts +2 -2
  261. package/dist/useTimeSelection.d.ts +2 -2
  262. package/dist/useTreeOperations.d.ts +3 -3
  263. package/dist/useWorkflowValidation.d.ts +2 -2
  264. package/package.json +1 -1
  265. package/dist/C_ActionBar-DYG0Yf3A.css.map +0 -1
  266. package/dist/C_ActionBar-MAjRhqcI.css.map +0 -1
  267. package/dist/C_Code-BFi5xxnM.css.map +0 -1
  268. package/dist/C_Code-CZ7yfnri.css.map +0 -1
  269. package/dist/C_FullCalendar-BQA0OjGB.css.map +0 -1
  270. package/dist/C_FullCalendar-ChJUosAi.css.map +0 -1
  271. package/dist/C_Steps-Bk1krgiR.css.map +0 -1
  272. package/dist/C_Steps-Dn2CMpy1.css.map +0 -1
  273. package/dist/C_Time-BzyQVvTS.css.map +0 -1
  274. package/dist/C_Time-DmpKLQHc.css.map +0 -1
@@ -7,7 +7,7 @@
7
7
  * --tf-accent : 操作按钮主色
8
8
  * --tf-height : 面板高度
9
9
  */
10
- .c-transfer[data-v-6de1c97f] {
10
+ .c-transfer[data-v-a627032d] {
11
11
  --tf-border: var(--border-color);
12
12
  --tf-header-bg: color-mix(in srgb, var(--primary-color) 6%, var(--card-color));
13
13
  --tf-item-hover: color-mix(in srgb, var(--primary-color) 8%, var(--card-color));
@@ -26,7 +26,7 @@
26
26
  /* ======================== Sizes ======================== */
27
27
  /* ======================== Group divider ======================== */
28
28
  }
29
- .c-transfer__panel[data-v-6de1c97f] {
29
+ .c-transfer__panel[data-v-a627032d] {
30
30
  flex: 1;
31
31
  display: flex;
32
32
  flex-direction: column;
@@ -37,10 +37,10 @@
37
37
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
38
38
  transition: box-shadow 0.2s;
39
39
  }
40
- .c-transfer__panel[data-v-6de1c97f]:hover {
40
+ .c-transfer__panel[data-v-a627032d]:hover {
41
41
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.07);
42
42
  }
43
- .c-transfer__header[data-v-6de1c97f] {
43
+ .c-transfer__header[data-v-a627032d] {
44
44
  display: flex;
45
45
  align-items: center;
46
46
  justify-content: space-between;
@@ -51,27 +51,27 @@
51
51
  font-size: 13px;
52
52
  color: var(--text-color-1);
53
53
  }
54
- .c-transfer__count[data-v-6de1c97f] {
54
+ .c-transfer__count[data-v-a627032d] {
55
55
  font-weight: 400;
56
56
  font-size: 12px;
57
57
  color: var(--text-color-3);
58
58
  }
59
- .c-transfer__filter[data-v-6de1c97f] {
59
+ .c-transfer__filter[data-v-a627032d] {
60
60
  padding: 8px 10px;
61
61
  border-bottom: 1px solid var(--tf-border);
62
62
  }
63
- .c-transfer__filter .n-input[data-v-6de1c97f] {
63
+ .c-transfer__filter .n-input[data-v-a627032d] {
64
64
  --n-border: 1px solid var(--tf-border);
65
65
  --n-border-focus: 1px solid var(--tf-accent);
66
66
  }
67
- .c-transfer__list[data-v-6de1c97f] {
67
+ .c-transfer__list[data-v-a627032d] {
68
68
  flex: 1;
69
69
  overflow-y: auto;
70
70
  padding: 4px 0;
71
71
  min-height: 0;
72
72
  max-height: var(--tf-height);
73
73
  }
74
- .c-transfer__item[data-v-6de1c97f] {
74
+ .c-transfer__item[data-v-a627032d] {
75
75
  display: flex;
76
76
  align-items: center;
77
77
  gap: 8px;
@@ -81,37 +81,37 @@
81
81
  font-size: 13px;
82
82
  color: var(--text-color-1);
83
83
  }
84
- .c-transfer__item[data-v-6de1c97f]:hover {
84
+ .c-transfer__item[data-v-a627032d]:hover {
85
85
  background: var(--tf-item-hover);
86
86
  }
87
- .c-transfer__item.is-disabled[data-v-6de1c97f] {
87
+ .c-transfer__item.is-disabled[data-v-a627032d] {
88
88
  opacity: 0.45;
89
89
  cursor: not-allowed;
90
90
  }
91
- .c-transfer__item.is-disabled[data-v-6de1c97f]:hover {
91
+ .c-transfer__item.is-disabled[data-v-a627032d]:hover {
92
92
  background: transparent;
93
93
  }
94
- .c-transfer__item.is-checked[data-v-6de1c97f] {
94
+ .c-transfer__item.is-checked[data-v-a627032d] {
95
95
  color: var(--tf-accent);
96
96
  font-weight: 500;
97
97
  }
98
- .c-transfer__item-icon[data-v-6de1c97f] {
98
+ .c-transfer__item-icon[data-v-a627032d] {
99
99
  font-size: 16px;
100
100
  flex-shrink: 0;
101
101
  color: var(--text-color-3);
102
102
  }
103
- .c-transfer__item-label[data-v-6de1c97f] {
103
+ .c-transfer__item-label[data-v-a627032d] {
104
104
  flex: 1;
105
105
  overflow: hidden;
106
106
  text-overflow: ellipsis;
107
107
  white-space: nowrap;
108
108
  }
109
- .c-transfer__item-desc[data-v-6de1c97f] {
109
+ .c-transfer__item-desc[data-v-a627032d] {
110
110
  font-size: 11px;
111
111
  color: var(--text-color-3);
112
112
  margin-top: 2px;
113
113
  }
114
- .c-transfer__empty[data-v-6de1c97f] {
114
+ .c-transfer__empty[data-v-a627032d] {
115
115
  display: flex;
116
116
  align-items: center;
117
117
  justify-content: center;
@@ -120,13 +120,13 @@
120
120
  font-size: 13px;
121
121
  padding: 32px 0;
122
122
  }
123
- .c-transfer__actions[data-v-6de1c97f] {
123
+ .c-transfer__actions[data-v-a627032d] {
124
124
  display: flex;
125
125
  flex-direction: column;
126
126
  justify-content: center;
127
127
  gap: 10px;
128
128
  }
129
- .c-transfer__btn[data-v-6de1c97f] {
129
+ .c-transfer__btn[data-v-a627032d] {
130
130
  display: inline-flex;
131
131
  align-items: center;
132
132
  justify-content: center;
@@ -140,48 +140,48 @@
140
140
  cursor: pointer;
141
141
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
142
142
  }
143
- .c-transfer__btn[data-v-6de1c97f]:hover:not(.is-disabled) {
143
+ .c-transfer__btn[data-v-a627032d]:hover:not(.is-disabled) {
144
144
  background: var(--tf-accent);
145
145
  color: #fff;
146
146
  box-shadow: 0 2px 8px color-mix(in srgb, var(--tf-accent) 30%, transparent);
147
147
  }
148
- .c-transfer__btn.is-disabled[data-v-6de1c97f] {
148
+ .c-transfer__btn.is-disabled[data-v-a627032d] {
149
149
  opacity: 0.35;
150
150
  cursor: not-allowed;
151
151
  }
152
- .c-transfer.is-small[data-v-6de1c97f] {
152
+ .c-transfer.is-small[data-v-a627032d] {
153
153
  --tf-height: 280px;
154
154
  }
155
- .c-transfer.is-small .c-transfer__header[data-v-6de1c97f] {
155
+ .c-transfer.is-small .c-transfer__header[data-v-a627032d] {
156
156
  padding: 8px 12px;
157
157
  font-size: 12px;
158
158
  }
159
- .c-transfer.is-small .c-transfer__item[data-v-6de1c97f] {
159
+ .c-transfer.is-small .c-transfer__item[data-v-a627032d] {
160
160
  padding: 5px 12px;
161
161
  font-size: 12px;
162
162
  }
163
- .c-transfer.is-small .c-transfer__btn[data-v-6de1c97f] {
163
+ .c-transfer.is-small .c-transfer__btn[data-v-a627032d] {
164
164
  width: 30px;
165
165
  height: 30px;
166
166
  font-size: 15px;
167
167
  }
168
- .c-transfer.is-large[data-v-6de1c97f] {
168
+ .c-transfer.is-large[data-v-a627032d] {
169
169
  --tf-height: 480px;
170
170
  }
171
- .c-transfer.is-large .c-transfer__header[data-v-6de1c97f] {
171
+ .c-transfer.is-large .c-transfer__header[data-v-a627032d] {
172
172
  padding: 12px 16px;
173
173
  font-size: 14px;
174
174
  }
175
- .c-transfer.is-large .c-transfer__item[data-v-6de1c97f] {
175
+ .c-transfer.is-large .c-transfer__item[data-v-a627032d] {
176
176
  padding: 9px 16px;
177
177
  font-size: 14px;
178
178
  }
179
- .c-transfer.is-large .c-transfer__btn[data-v-6de1c97f] {
179
+ .c-transfer.is-large .c-transfer__btn[data-v-a627032d] {
180
180
  width: 42px;
181
181
  height: 42px;
182
182
  font-size: 20px;
183
183
  }
184
- .c-transfer__group[data-v-6de1c97f] {
184
+ .c-transfer__group[data-v-a627032d] {
185
185
  padding: 6px 14px 4px;
186
186
  font-size: 11px;
187
187
  font-weight: 600;
@@ -190,4 +190,4 @@
190
190
  letter-spacing: 0.04em;
191
191
  }
192
192
 
193
- /*# sourceMappingURL=C_Transfer-BOB6OBqS.css.map*/
193
+ /*# sourceMappingURL=C_Transfer-CCEqnC-v.css.map*/
@@ -1 +1 @@
1
- {"version":3,"file":"C_Transfer.js","names":[],"sources":["../src/components/C_Transfer/types.ts","../src/components/C_Transfer/index.vue","../src/components/C_Transfer/index.vue","../src/components/C_Transfer/index.vue"],"sourcesContent":["/**\n * @Description: 穿梭框组件类型定义\n */\n\n/** 穿梭框数据项 */\nexport interface TransferItem {\n /** 唯一标识 */\n key: string | number\n /** 显示标签 */\n label: string\n /** 是否禁用 */\n disabled?: boolean\n /** 分组名称 */\n group?: string\n /** 描述信息(用于详细模式) */\n description?: string\n /** 图标(Iconify) */\n icon?: string\n /** 额外数据 */\n extra?: Record<string, unknown>\n}\n\n/** 组件 Props */\nexport interface TransferProps {\n /** 数据源 */\n data: TransferItem[]\n /** 右侧已选 key 列表 (v-model) */\n modelValue: Array<string | number>\n /** 左右栏标题 */\n titles?: [string, string]\n /** 是否可搜索 */\n filterable?: boolean\n /** 搜索占位符 */\n filterPlaceholder?: string\n /** 自定义筛选函数 */\n filterMethod?: (query: string, item: TransferItem) => boolean\n /** 是否显示全选复选框 */\n showSelectAll?: boolean\n /** 左侧空状态描述 */\n sourceEmptyText?: string\n /** 右侧空状态描述 */\n targetEmptyText?: string\n /** 尺寸 */\n size?: 'small' | 'medium' | 'large'\n}\n\n/** 默认 Props */\nexport const DEFAULT_TRANSFER_PROPS: Partial<TransferProps> = {\n titles: ['可选列表', '已选列表'],\n filterable: false,\n filterPlaceholder: '搜索...',\n showSelectAll: true,\n sourceEmptyText: '暂无数据',\n targetEmptyText: '未选择任何项',\n size: 'medium',\n}\n","/* unplugin-vue-components disabled */<!--\n * @Description: 穿梭框组件\n-->\n<template>\n <div\n class=\"c-transfer\"\n :class=\"[`is-${mergedProps.size}`]\"\n >\n <!-- ================ Source Panel ================ -->\n <div class=\"c-transfer__panel\">\n <div class=\"c-transfer__header\">\n <NCheckbox\n v-if=\"mergedProps.showSelectAll\"\n :checked=\"isSourceAllChecked\"\n :indeterminate=\"isSourceIndeterminate\"\n @update:checked=\"toggleSourceAll\"\n >\n {{ mergedProps.titles?.[0] }}\n </NCheckbox>\n <span\n v-else\n class=\"c-transfer__title\"\n >\n {{ mergedProps.titles?.[0] }}\n </span>\n <span class=\"c-transfer__count\"\n >{{ sourceChecked.size }} / {{ sourceList.length }}</span\n >\n </div>\n\n <div\n v-if=\"mergedProps.filterable\"\n class=\"c-transfer__filter\"\n >\n <NInput\n v-model:value=\"sourceQuery\"\n clearable\n size=\"small\"\n :placeholder=\"mergedProps.filterPlaceholder\"\n >\n <template #prefix>\n <C_Icon name=\"mdi:magnify\" />\n </template>\n </NInput>\n </div>\n\n <div\n v-if=\"filteredSourceList.length\"\n class=\"c-transfer__list\"\n >\n <template\n v-for=\"item in filteredSourceList\"\n :key=\"item.key\"\n >\n <div\n class=\"c-transfer__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-checked': sourceChecked.has(item.key),\n }\"\n @click=\"!item.disabled && toggleSourceCheck(item.key)\"\n >\n <NCheckbox\n :checked=\"sourceChecked.has(item.key)\"\n :disabled=\"item.disabled\"\n size=\"small\"\n @update:checked=\"toggleSourceCheck(item.key)\"\n @click.stop\n />\n <C_Icon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n class=\"c-transfer__item-icon\"\n />\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\n </div>\n </template>\n </div>\n <div\n v-else\n class=\"c-transfer__empty\"\n >\n {{ mergedProps.sourceEmptyText }}\n </div>\n </div>\n\n <!-- ================ Actions ================ -->\n <div class=\"c-transfer__actions\">\n <button\n class=\"c-transfer__btn\"\n :class=\"{ 'is-disabled': sourceChecked.size === 0 }\"\n :disabled=\"sourceChecked.size === 0\"\n @click=\"moveToTarget\"\n >\n <C_Icon name=\"mdi:chevron-right\" />\n </button>\n <button\n class=\"c-transfer__btn\"\n :class=\"{ 'is-disabled': targetChecked.size === 0 }\"\n :disabled=\"targetChecked.size === 0\"\n @click=\"moveToSource\"\n >\n <C_Icon name=\"mdi:chevron-left\" />\n </button>\n </div>\n\n <!-- ================ Target Panel ================ -->\n <div class=\"c-transfer__panel\">\n <div class=\"c-transfer__header\">\n <NCheckbox\n v-if=\"mergedProps.showSelectAll\"\n :checked=\"isTargetAllChecked\"\n :indeterminate=\"isTargetIndeterminate\"\n @update:checked=\"toggleTargetAll\"\n >\n {{ mergedProps.titles?.[1] }}\n </NCheckbox>\n <span\n v-else\n class=\"c-transfer__title\"\n >\n {{ mergedProps.titles?.[1] }}\n </span>\n <span class=\"c-transfer__count\"\n >{{ targetChecked.size }} / {{ targetList.length }}</span\n >\n </div>\n\n <div\n v-if=\"mergedProps.filterable\"\n class=\"c-transfer__filter\"\n >\n <NInput\n v-model:value=\"targetQuery\"\n clearable\n size=\"small\"\n :placeholder=\"mergedProps.filterPlaceholder\"\n >\n <template #prefix>\n <C_Icon name=\"mdi:magnify\" />\n </template>\n </NInput>\n </div>\n\n <div\n v-if=\"filteredTargetList.length\"\n class=\"c-transfer__list\"\n >\n <template\n v-for=\"item in filteredTargetList\"\n :key=\"item.key\"\n >\n <div\n class=\"c-transfer__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-checked': targetChecked.has(item.key),\n }\"\n @click=\"!item.disabled && toggleTargetCheck(item.key)\"\n >\n <NCheckbox\n :checked=\"targetChecked.has(item.key)\"\n :disabled=\"item.disabled\"\n size=\"small\"\n @update:checked=\"toggleTargetCheck(item.key)\"\n @click.stop\n />\n <C_Icon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n class=\"c-transfer__item-icon\"\n />\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\n </div>\n </template>\n </div>\n <div\n v-else\n class=\"c-transfer__empty\"\n >\n {{ mergedProps.targetEmptyText }}\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed, reactive, ref } from 'vue'\n import C_Icon from '../C_Icon/index.vue'\n import {\n DEFAULT_TRANSFER_PROPS,\n type TransferItem,\n type TransferProps,\n } from './types'\n\n const props = withDefaults(\n defineProps<{\n data: TransferProps['data']\n modelValue: TransferProps['modelValue']\n titles?: TransferProps['titles']\n filterable?: boolean\n filterPlaceholder?: string\n filterMethod?: TransferProps['filterMethod']\n showSelectAll?: boolean\n sourceEmptyText?: string\n targetEmptyText?: string\n size?: TransferProps['size']\n }>(),\n {\n titles: () => DEFAULT_TRANSFER_PROPS.titles as [string, string],\n filterable: DEFAULT_TRANSFER_PROPS.filterable,\n filterPlaceholder: DEFAULT_TRANSFER_PROPS.filterPlaceholder,\n showSelectAll: DEFAULT_TRANSFER_PROPS.showSelectAll,\n sourceEmptyText: DEFAULT_TRANSFER_PROPS.sourceEmptyText,\n targetEmptyText: DEFAULT_TRANSFER_PROPS.targetEmptyText,\n size: DEFAULT_TRANSFER_PROPS.size,\n }\n )\n\n const emit = defineEmits<{\n 'update:modelValue': [value: Array<string | number>]\n change: [\n targetKeys: Array<string | number>,\n direction: 'left' | 'right',\n moveKeys: Array<string | number>,\n ]\n }>()\n\n const mergedProps = computed(() => ({ ...DEFAULT_TRANSFER_PROPS, ...props }))\n\n // ==================== 数据列表 ====================\n\n const dataMap = computed(() => {\n const m = new Map<string | number, TransferItem>()\n for (const item of props.data) m.set(item.key, item)\n return m\n })\n\n const targetKeySet = computed(() => new Set(props.modelValue))\n\n const sourceList = computed(() =>\n props.data.filter(d => !targetKeySet.value.has(d.key))\n )\n\n const targetList = computed(() => {\n const result: TransferItem[] = []\n for (const key of props.modelValue) {\n const item = dataMap.value.get(key)\n if (item) result.push(item)\n }\n return result\n })\n\n // ==================== 搜索 ====================\n\n const sourceQuery = ref('')\n const targetQuery = ref('')\n\n /** 默认过滤方法 */\n function defaultFilter(query: string, item: TransferItem): boolean {\n return item.label.toLowerCase().includes(query.toLowerCase())\n }\n\n const filterFn = computed(() => props.filterMethod ?? defaultFilter)\n\n const filteredSourceList = computed(() => {\n const q = sourceQuery.value.trim()\n return q\n ? sourceList.value.filter(item => filterFn.value(q, item))\n : sourceList.value\n })\n\n const filteredTargetList = computed(() => {\n const q = targetQuery.value.trim()\n return q\n ? targetList.value.filter(item => filterFn.value(q, item))\n : targetList.value\n })\n\n // ==================== 选中态 ====================\n\n const sourceChecked = reactive(new Set<string | number>())\n const targetChecked = reactive(new Set<string | number>())\n\n /** 切换源列表项选中状态 */\n function toggleSourceCheck(key: string | number) {\n if (sourceChecked.has(key)) sourceChecked.delete(key)\n else sourceChecked.add(key)\n }\n\n /** 切换目标列表项选中状态 */\n function toggleTargetCheck(key: string | number) {\n if (targetChecked.has(key)) targetChecked.delete(key)\n else targetChecked.add(key)\n }\n\n const isSourceAllChecked = computed(\n () =>\n filteredSourceList.value.length > 0 &&\n filteredSourceList.value.every(\n i => i.disabled || sourceChecked.has(i.key)\n )\n )\n const isSourceIndeterminate = computed(\n () =>\n !isSourceAllChecked.value &&\n filteredSourceList.value.some(i => sourceChecked.has(i.key))\n )\n const isTargetAllChecked = computed(\n () =>\n filteredTargetList.value.length > 0 &&\n filteredTargetList.value.every(\n i => i.disabled || targetChecked.has(i.key)\n )\n )\n const isTargetIndeterminate = computed(\n () =>\n !isTargetAllChecked.value &&\n filteredTargetList.value.some(i => targetChecked.has(i.key))\n )\n\n /** 切换源列表全选状态 */\n function toggleSourceAll(checked: boolean) {\n for (const item of filteredSourceList.value) {\n if (item.disabled) continue\n if (checked) sourceChecked.add(item.key)\n else sourceChecked.delete(item.key)\n }\n }\n\n /** 切换目标列表全选状态 */\n function toggleTargetAll(checked: boolean) {\n for (const item of filteredTargetList.value) {\n if (item.disabled) continue\n if (checked) targetChecked.add(item.key)\n else targetChecked.delete(item.key)\n }\n }\n\n // ==================== 穿梭操作 ====================\n\n /** 将选中项移至目标列表 */\n function moveToTarget() {\n const keys = [...sourceChecked]\n const newVal = [...props.modelValue, ...keys]\n emit('update:modelValue', newVal)\n emit('change', newVal, 'right', keys)\n sourceChecked.clear()\n }\n\n /** 将选中项移回源列表 */\n function moveToSource() {\n const keys = [...targetChecked]\n const removeSet = new Set(keys)\n const newVal = props.modelValue.filter(k => !removeSet.has(k))\n emit('update:modelValue', newVal)\n emit('change', newVal, 'left', keys)\n targetChecked.clear()\n }\n</script>\n\n<style scoped lang=\"scss\">\n @use './index.scss';\n</style>\n","/* unplugin-vue-components disabled */<!--\n * @Description: 穿梭框组件\n-->\n<template>\n <div\n class=\"c-transfer\"\n :class=\"[`is-${mergedProps.size}`]\"\n >\n <!-- ================ Source Panel ================ -->\n <div class=\"c-transfer__panel\">\n <div class=\"c-transfer__header\">\n <NCheckbox\n v-if=\"mergedProps.showSelectAll\"\n :checked=\"isSourceAllChecked\"\n :indeterminate=\"isSourceIndeterminate\"\n @update:checked=\"toggleSourceAll\"\n >\n {{ mergedProps.titles?.[0] }}\n </NCheckbox>\n <span\n v-else\n class=\"c-transfer__title\"\n >\n {{ mergedProps.titles?.[0] }}\n </span>\n <span class=\"c-transfer__count\"\n >{{ sourceChecked.size }} / {{ sourceList.length }}</span\n >\n </div>\n\n <div\n v-if=\"mergedProps.filterable\"\n class=\"c-transfer__filter\"\n >\n <NInput\n v-model:value=\"sourceQuery\"\n clearable\n size=\"small\"\n :placeholder=\"mergedProps.filterPlaceholder\"\n >\n <template #prefix>\n <C_Icon name=\"mdi:magnify\" />\n </template>\n </NInput>\n </div>\n\n <div\n v-if=\"filteredSourceList.length\"\n class=\"c-transfer__list\"\n >\n <template\n v-for=\"item in filteredSourceList\"\n :key=\"item.key\"\n >\n <div\n class=\"c-transfer__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-checked': sourceChecked.has(item.key),\n }\"\n @click=\"!item.disabled && toggleSourceCheck(item.key)\"\n >\n <NCheckbox\n :checked=\"sourceChecked.has(item.key)\"\n :disabled=\"item.disabled\"\n size=\"small\"\n @update:checked=\"toggleSourceCheck(item.key)\"\n @click.stop\n />\n <C_Icon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n class=\"c-transfer__item-icon\"\n />\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\n </div>\n </template>\n </div>\n <div\n v-else\n class=\"c-transfer__empty\"\n >\n {{ mergedProps.sourceEmptyText }}\n </div>\n </div>\n\n <!-- ================ Actions ================ -->\n <div class=\"c-transfer__actions\">\n <button\n class=\"c-transfer__btn\"\n :class=\"{ 'is-disabled': sourceChecked.size === 0 }\"\n :disabled=\"sourceChecked.size === 0\"\n @click=\"moveToTarget\"\n >\n <C_Icon name=\"mdi:chevron-right\" />\n </button>\n <button\n class=\"c-transfer__btn\"\n :class=\"{ 'is-disabled': targetChecked.size === 0 }\"\n :disabled=\"targetChecked.size === 0\"\n @click=\"moveToSource\"\n >\n <C_Icon name=\"mdi:chevron-left\" />\n </button>\n </div>\n\n <!-- ================ Target Panel ================ -->\n <div class=\"c-transfer__panel\">\n <div class=\"c-transfer__header\">\n <NCheckbox\n v-if=\"mergedProps.showSelectAll\"\n :checked=\"isTargetAllChecked\"\n :indeterminate=\"isTargetIndeterminate\"\n @update:checked=\"toggleTargetAll\"\n >\n {{ mergedProps.titles?.[1] }}\n </NCheckbox>\n <span\n v-else\n class=\"c-transfer__title\"\n >\n {{ mergedProps.titles?.[1] }}\n </span>\n <span class=\"c-transfer__count\"\n >{{ targetChecked.size }} / {{ targetList.length }}</span\n >\n </div>\n\n <div\n v-if=\"mergedProps.filterable\"\n class=\"c-transfer__filter\"\n >\n <NInput\n v-model:value=\"targetQuery\"\n clearable\n size=\"small\"\n :placeholder=\"mergedProps.filterPlaceholder\"\n >\n <template #prefix>\n <C_Icon name=\"mdi:magnify\" />\n </template>\n </NInput>\n </div>\n\n <div\n v-if=\"filteredTargetList.length\"\n class=\"c-transfer__list\"\n >\n <template\n v-for=\"item in filteredTargetList\"\n :key=\"item.key\"\n >\n <div\n class=\"c-transfer__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-checked': targetChecked.has(item.key),\n }\"\n @click=\"!item.disabled && toggleTargetCheck(item.key)\"\n >\n <NCheckbox\n :checked=\"targetChecked.has(item.key)\"\n :disabled=\"item.disabled\"\n size=\"small\"\n @update:checked=\"toggleTargetCheck(item.key)\"\n @click.stop\n />\n <C_Icon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n class=\"c-transfer__item-icon\"\n />\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\n </div>\n </template>\n </div>\n <div\n v-else\n class=\"c-transfer__empty\"\n >\n {{ mergedProps.targetEmptyText }}\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed, reactive, ref } from 'vue'\n import C_Icon from '../C_Icon/index.vue'\n import {\n DEFAULT_TRANSFER_PROPS,\n type TransferItem,\n type TransferProps,\n } from './types'\n\n const props = withDefaults(\n defineProps<{\n data: TransferProps['data']\n modelValue: TransferProps['modelValue']\n titles?: TransferProps['titles']\n filterable?: boolean\n filterPlaceholder?: string\n filterMethod?: TransferProps['filterMethod']\n showSelectAll?: boolean\n sourceEmptyText?: string\n targetEmptyText?: string\n size?: TransferProps['size']\n }>(),\n {\n titles: () => DEFAULT_TRANSFER_PROPS.titles as [string, string],\n filterable: DEFAULT_TRANSFER_PROPS.filterable,\n filterPlaceholder: DEFAULT_TRANSFER_PROPS.filterPlaceholder,\n showSelectAll: DEFAULT_TRANSFER_PROPS.showSelectAll,\n sourceEmptyText: DEFAULT_TRANSFER_PROPS.sourceEmptyText,\n targetEmptyText: DEFAULT_TRANSFER_PROPS.targetEmptyText,\n size: DEFAULT_TRANSFER_PROPS.size,\n }\n )\n\n const emit = defineEmits<{\n 'update:modelValue': [value: Array<string | number>]\n change: [\n targetKeys: Array<string | number>,\n direction: 'left' | 'right',\n moveKeys: Array<string | number>,\n ]\n }>()\n\n const mergedProps = computed(() => ({ ...DEFAULT_TRANSFER_PROPS, ...props }))\n\n // ==================== 数据列表 ====================\n\n const dataMap = computed(() => {\n const m = new Map<string | number, TransferItem>()\n for (const item of props.data) m.set(item.key, item)\n return m\n })\n\n const targetKeySet = computed(() => new Set(props.modelValue))\n\n const sourceList = computed(() =>\n props.data.filter(d => !targetKeySet.value.has(d.key))\n )\n\n const targetList = computed(() => {\n const result: TransferItem[] = []\n for (const key of props.modelValue) {\n const item = dataMap.value.get(key)\n if (item) result.push(item)\n }\n return result\n })\n\n // ==================== 搜索 ====================\n\n const sourceQuery = ref('')\n const targetQuery = ref('')\n\n /** 默认过滤方法 */\n function defaultFilter(query: string, item: TransferItem): boolean {\n return item.label.toLowerCase().includes(query.toLowerCase())\n }\n\n const filterFn = computed(() => props.filterMethod ?? defaultFilter)\n\n const filteredSourceList = computed(() => {\n const q = sourceQuery.value.trim()\n return q\n ? sourceList.value.filter(item => filterFn.value(q, item))\n : sourceList.value\n })\n\n const filteredTargetList = computed(() => {\n const q = targetQuery.value.trim()\n return q\n ? targetList.value.filter(item => filterFn.value(q, item))\n : targetList.value\n })\n\n // ==================== 选中态 ====================\n\n const sourceChecked = reactive(new Set<string | number>())\n const targetChecked = reactive(new Set<string | number>())\n\n /** 切换源列表项选中状态 */\n function toggleSourceCheck(key: string | number) {\n if (sourceChecked.has(key)) sourceChecked.delete(key)\n else sourceChecked.add(key)\n }\n\n /** 切换目标列表项选中状态 */\n function toggleTargetCheck(key: string | number) {\n if (targetChecked.has(key)) targetChecked.delete(key)\n else targetChecked.add(key)\n }\n\n const isSourceAllChecked = computed(\n () =>\n filteredSourceList.value.length > 0 &&\n filteredSourceList.value.every(\n i => i.disabled || sourceChecked.has(i.key)\n )\n )\n const isSourceIndeterminate = computed(\n () =>\n !isSourceAllChecked.value &&\n filteredSourceList.value.some(i => sourceChecked.has(i.key))\n )\n const isTargetAllChecked = computed(\n () =>\n filteredTargetList.value.length > 0 &&\n filteredTargetList.value.every(\n i => i.disabled || targetChecked.has(i.key)\n )\n )\n const isTargetIndeterminate = computed(\n () =>\n !isTargetAllChecked.value &&\n filteredTargetList.value.some(i => targetChecked.has(i.key))\n )\n\n /** 切换源列表全选状态 */\n function toggleSourceAll(checked: boolean) {\n for (const item of filteredSourceList.value) {\n if (item.disabled) continue\n if (checked) sourceChecked.add(item.key)\n else sourceChecked.delete(item.key)\n }\n }\n\n /** 切换目标列表全选状态 */\n function toggleTargetAll(checked: boolean) {\n for (const item of filteredTargetList.value) {\n if (item.disabled) continue\n if (checked) targetChecked.add(item.key)\n else targetChecked.delete(item.key)\n }\n }\n\n // ==================== 穿梭操作 ====================\n\n /** 将选中项移至目标列表 */\n function moveToTarget() {\n const keys = [...sourceChecked]\n const newVal = [...props.modelValue, ...keys]\n emit('update:modelValue', newVal)\n emit('change', newVal, 'right', keys)\n sourceChecked.clear()\n }\n\n /** 将选中项移回源列表 */\n function moveToSource() {\n const keys = [...targetChecked]\n const removeSet = new Set(keys)\n const newVal = props.modelValue.filter(k => !removeSet.has(k))\n emit('update:modelValue', newVal)\n emit('change', newVal, 'left', keys)\n targetChecked.clear()\n }\n</script>\n\n<style scoped lang=\"scss\">\n @use './index.scss';\n</style>\n","<!--\n * @Description: 穿梭框组件\n-->\n<template>\n <div\n class=\"c-transfer\"\n :class=\"[`is-${mergedProps.size}`]\"\n >\n <!-- ================ Source Panel ================ -->\n <div class=\"c-transfer__panel\">\n <div class=\"c-transfer__header\">\n <NCheckbox\n v-if=\"mergedProps.showSelectAll\"\n :checked=\"isSourceAllChecked\"\n :indeterminate=\"isSourceIndeterminate\"\n @update:checked=\"toggleSourceAll\"\n >\n {{ mergedProps.titles?.[0] }}\n </NCheckbox>\n <span\n v-else\n class=\"c-transfer__title\"\n >\n {{ mergedProps.titles?.[0] }}\n </span>\n <span class=\"c-transfer__count\"\n >{{ sourceChecked.size }} / {{ sourceList.length }}</span\n >\n </div>\n\n <div\n v-if=\"mergedProps.filterable\"\n class=\"c-transfer__filter\"\n >\n <NInput\n v-model:value=\"sourceQuery\"\n clearable\n size=\"small\"\n :placeholder=\"mergedProps.filterPlaceholder\"\n >\n <template #prefix>\n <C_Icon name=\"mdi:magnify\" />\n </template>\n </NInput>\n </div>\n\n <div\n v-if=\"filteredSourceList.length\"\n class=\"c-transfer__list\"\n >\n <template\n v-for=\"item in filteredSourceList\"\n :key=\"item.key\"\n >\n <div\n class=\"c-transfer__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-checked': sourceChecked.has(item.key),\n }\"\n @click=\"!item.disabled && toggleSourceCheck(item.key)\"\n >\n <NCheckbox\n :checked=\"sourceChecked.has(item.key)\"\n :disabled=\"item.disabled\"\n size=\"small\"\n @update:checked=\"toggleSourceCheck(item.key)\"\n @click.stop\n />\n <C_Icon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n class=\"c-transfer__item-icon\"\n />\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\n </div>\n </template>\n </div>\n <div\n v-else\n class=\"c-transfer__empty\"\n >\n {{ mergedProps.sourceEmptyText }}\n </div>\n </div>\n\n <!-- ================ Actions ================ -->\n <div class=\"c-transfer__actions\">\n <button\n class=\"c-transfer__btn\"\n :class=\"{ 'is-disabled': sourceChecked.size === 0 }\"\n :disabled=\"sourceChecked.size === 0\"\n @click=\"moveToTarget\"\n >\n <C_Icon name=\"mdi:chevron-right\" />\n </button>\n <button\n class=\"c-transfer__btn\"\n :class=\"{ 'is-disabled': targetChecked.size === 0 }\"\n :disabled=\"targetChecked.size === 0\"\n @click=\"moveToSource\"\n >\n <C_Icon name=\"mdi:chevron-left\" />\n </button>\n </div>\n\n <!-- ================ Target Panel ================ -->\n <div class=\"c-transfer__panel\">\n <div class=\"c-transfer__header\">\n <NCheckbox\n v-if=\"mergedProps.showSelectAll\"\n :checked=\"isTargetAllChecked\"\n :indeterminate=\"isTargetIndeterminate\"\n @update:checked=\"toggleTargetAll\"\n >\n {{ mergedProps.titles?.[1] }}\n </NCheckbox>\n <span\n v-else\n class=\"c-transfer__title\"\n >\n {{ mergedProps.titles?.[1] }}\n </span>\n <span class=\"c-transfer__count\"\n >{{ targetChecked.size }} / {{ targetList.length }}</span\n >\n </div>\n\n <div\n v-if=\"mergedProps.filterable\"\n class=\"c-transfer__filter\"\n >\n <NInput\n v-model:value=\"targetQuery\"\n clearable\n size=\"small\"\n :placeholder=\"mergedProps.filterPlaceholder\"\n >\n <template #prefix>\n <C_Icon name=\"mdi:magnify\" />\n </template>\n </NInput>\n </div>\n\n <div\n v-if=\"filteredTargetList.length\"\n class=\"c-transfer__list\"\n >\n <template\n v-for=\"item in filteredTargetList\"\n :key=\"item.key\"\n >\n <div\n class=\"c-transfer__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-checked': targetChecked.has(item.key),\n }\"\n @click=\"!item.disabled && toggleTargetCheck(item.key)\"\n >\n <NCheckbox\n :checked=\"targetChecked.has(item.key)\"\n :disabled=\"item.disabled\"\n size=\"small\"\n @update:checked=\"toggleTargetCheck(item.key)\"\n @click.stop\n />\n <C_Icon\n v-if=\"item.icon\"\n :name=\"item.icon\"\n class=\"c-transfer__item-icon\"\n />\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\n </div>\n </template>\n </div>\n <div\n v-else\n class=\"c-transfer__empty\"\n >\n {{ mergedProps.targetEmptyText }}\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n import { computed, reactive, ref } from 'vue'\n import C_Icon from '../C_Icon/index.vue'\n import {\n DEFAULT_TRANSFER_PROPS,\n type TransferItem,\n type TransferProps,\n } from './types'\n\n const props = withDefaults(\n defineProps<{\n data: TransferProps['data']\n modelValue: TransferProps['modelValue']\n titles?: TransferProps['titles']\n filterable?: boolean\n filterPlaceholder?: string\n filterMethod?: TransferProps['filterMethod']\n showSelectAll?: boolean\n sourceEmptyText?: string\n targetEmptyText?: string\n size?: TransferProps['size']\n }>(),\n {\n titles: () => DEFAULT_TRANSFER_PROPS.titles as [string, string],\n filterable: DEFAULT_TRANSFER_PROPS.filterable,\n filterPlaceholder: DEFAULT_TRANSFER_PROPS.filterPlaceholder,\n showSelectAll: DEFAULT_TRANSFER_PROPS.showSelectAll,\n sourceEmptyText: DEFAULT_TRANSFER_PROPS.sourceEmptyText,\n targetEmptyText: DEFAULT_TRANSFER_PROPS.targetEmptyText,\n size: DEFAULT_TRANSFER_PROPS.size,\n }\n )\n\n const emit = defineEmits<{\n 'update:modelValue': [value: Array<string | number>]\n change: [\n targetKeys: Array<string | number>,\n direction: 'left' | 'right',\n moveKeys: Array<string | number>,\n ]\n }>()\n\n const mergedProps = computed(() => ({ ...DEFAULT_TRANSFER_PROPS, ...props }))\n\n // ==================== 数据列表 ====================\n\n const dataMap = computed(() => {\n const m = new Map<string | number, TransferItem>()\n for (const item of props.data) m.set(item.key, item)\n return m\n })\n\n const targetKeySet = computed(() => new Set(props.modelValue))\n\n const sourceList = computed(() =>\n props.data.filter(d => !targetKeySet.value.has(d.key))\n )\n\n const targetList = computed(() => {\n const result: TransferItem[] = []\n for (const key of props.modelValue) {\n const item = dataMap.value.get(key)\n if (item) result.push(item)\n }\n return result\n })\n\n // ==================== 搜索 ====================\n\n const sourceQuery = ref('')\n const targetQuery = ref('')\n\n /** 默认过滤方法 */\n function defaultFilter(query: string, item: TransferItem): boolean {\n return item.label.toLowerCase().includes(query.toLowerCase())\n }\n\n const filterFn = computed(() => props.filterMethod ?? defaultFilter)\n\n const filteredSourceList = computed(() => {\n const q = sourceQuery.value.trim()\n return q\n ? sourceList.value.filter(item => filterFn.value(q, item))\n : sourceList.value\n })\n\n const filteredTargetList = computed(() => {\n const q = targetQuery.value.trim()\n return q\n ? targetList.value.filter(item => filterFn.value(q, item))\n : targetList.value\n })\n\n // ==================== 选中态 ====================\n\n const sourceChecked = reactive(new Set<string | number>())\n const targetChecked = reactive(new Set<string | number>())\n\n /** 切换源列表项选中状态 */\n function toggleSourceCheck(key: string | number) {\n if (sourceChecked.has(key)) sourceChecked.delete(key)\n else sourceChecked.add(key)\n }\n\n /** 切换目标列表项选中状态 */\n function toggleTargetCheck(key: string | number) {\n if (targetChecked.has(key)) targetChecked.delete(key)\n else targetChecked.add(key)\n }\n\n const isSourceAllChecked = computed(\n () =>\n filteredSourceList.value.length > 0 &&\n filteredSourceList.value.every(\n i => i.disabled || sourceChecked.has(i.key)\n )\n )\n const isSourceIndeterminate = computed(\n () =>\n !isSourceAllChecked.value &&\n filteredSourceList.value.some(i => sourceChecked.has(i.key))\n )\n const isTargetAllChecked = computed(\n () =>\n filteredTargetList.value.length > 0 &&\n filteredTargetList.value.every(\n i => i.disabled || targetChecked.has(i.key)\n )\n )\n const isTargetIndeterminate = computed(\n () =>\n !isTargetAllChecked.value &&\n filteredTargetList.value.some(i => targetChecked.has(i.key))\n )\n\n /** 切换源列表全选状态 */\n function toggleSourceAll(checked: boolean) {\n for (const item of filteredSourceList.value) {\n if (item.disabled) continue\n if (checked) sourceChecked.add(item.key)\n else sourceChecked.delete(item.key)\n }\n }\n\n /** 切换目标列表全选状态 */\n function toggleTargetAll(checked: boolean) {\n for (const item of filteredTargetList.value) {\n if (item.disabled) continue\n if (checked) targetChecked.add(item.key)\n else targetChecked.delete(item.key)\n }\n }\n\n // ==================== 穿梭操作 ====================\n\n /** 将选中项移至目标列表 */\n function moveToTarget() {\n const keys = [...sourceChecked]\n const newVal = [...props.modelValue, ...keys]\n emit('update:modelValue', newVal)\n emit('change', newVal, 'right', keys)\n sourceChecked.clear()\n }\n\n /** 将选中项移回源列表 */\n function moveToSource() {\n const keys = [...targetChecked]\n const removeSet = new Set(keys)\n const newVal = props.modelValue.filter(k => !removeSet.has(k))\n emit('update:modelValue', newVal)\n emit('change', newVal, 'left', keys)\n targetChecked.clear()\n }\n</script>\n\n<style scoped lang=\"scss\">\n @use './index.scss';\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"C_Transfer.js","names":[],"sources":["../src/components/C_Transfer/types.ts","../src/components/C_Transfer/index.vue","../src/components/C_Transfer/index.vue","../src/components/C_Transfer/index.vue"],"sourcesContent":["/**\r\n * @Description: 穿梭框组件类型定义\r\n */\r\n\r\n/** 穿梭框数据项 */\r\nexport interface TransferItem {\r\n /** 唯一标识 */\r\n key: string | number\r\n /** 显示标签 */\r\n label: string\r\n /** 是否禁用 */\r\n disabled?: boolean\r\n /** 分组名称 */\r\n group?: string\r\n /** 描述信息(用于详细模式) */\r\n description?: string\r\n /** 图标(Iconify) */\r\n icon?: string\r\n /** 额外数据 */\r\n extra?: Record<string, unknown>\r\n}\r\n\r\n/** 组件 Props */\r\nexport interface TransferProps {\r\n /** 数据源 */\r\n data: TransferItem[]\r\n /** 右侧已选 key 列表 (v-model) */\r\n modelValue: Array<string | number>\r\n /** 左右栏标题 */\r\n titles?: [string, string]\r\n /** 是否可搜索 */\r\n filterable?: boolean\r\n /** 搜索占位符 */\r\n filterPlaceholder?: string\r\n /** 自定义筛选函数 */\r\n filterMethod?: (query: string, item: TransferItem) => boolean\r\n /** 是否显示全选复选框 */\r\n showSelectAll?: boolean\r\n /** 左侧空状态描述 */\r\n sourceEmptyText?: string\r\n /** 右侧空状态描述 */\r\n targetEmptyText?: string\r\n /** 尺寸 */\r\n size?: 'small' | 'medium' | 'large'\r\n}\r\n\r\n/** 默认 Props */\r\nexport const DEFAULT_TRANSFER_PROPS: Partial<TransferProps> = {\r\n titles: ['可选列表', '已选列表'],\r\n filterable: false,\r\n filterPlaceholder: '搜索...',\r\n showSelectAll: true,\r\n sourceEmptyText: '暂无数据',\r\n targetEmptyText: '未选择任何项',\r\n size: 'medium',\r\n}\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Description: 穿梭框组件\r\n-->\r\n<template>\r\n <div\r\n class=\"c-transfer\"\r\n :class=\"[`is-${mergedProps.size}`]\"\r\n >\r\n <!-- ================ Source Panel ================ -->\r\n <div class=\"c-transfer__panel\">\r\n <div class=\"c-transfer__header\">\r\n <NCheckbox\r\n v-if=\"mergedProps.showSelectAll\"\r\n :checked=\"isSourceAllChecked\"\r\n :indeterminate=\"isSourceIndeterminate\"\r\n @update:checked=\"toggleSourceAll\"\r\n >\r\n {{ mergedProps.titles?.[0] }}\r\n </NCheckbox>\r\n <span\r\n v-else\r\n class=\"c-transfer__title\"\r\n >\r\n {{ mergedProps.titles?.[0] }}\r\n </span>\r\n <span class=\"c-transfer__count\"\r\n >{{ sourceChecked.size }} / {{ sourceList.length }}</span\r\n >\r\n </div>\r\n\r\n <div\r\n v-if=\"mergedProps.filterable\"\r\n class=\"c-transfer__filter\"\r\n >\r\n <NInput\r\n v-model:value=\"sourceQuery\"\r\n clearable\r\n size=\"small\"\r\n :placeholder=\"mergedProps.filterPlaceholder\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n </div>\r\n\r\n <div\r\n v-if=\"filteredSourceList.length\"\r\n class=\"c-transfer__list\"\r\n >\r\n <template\r\n v-for=\"item in filteredSourceList\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n class=\"c-transfer__item\"\r\n :class=\"{\r\n 'is-disabled': item.disabled,\r\n 'is-checked': sourceChecked.has(item.key),\r\n }\"\r\n @click=\"!item.disabled && toggleSourceCheck(item.key)\"\r\n >\r\n <NCheckbox\r\n :checked=\"sourceChecked.has(item.key)\"\r\n :disabled=\"item.disabled\"\r\n size=\"small\"\r\n @update:checked=\"toggleSourceCheck(item.key)\"\r\n @click.stop\r\n />\r\n <C_Icon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n class=\"c-transfer__item-icon\"\r\n />\r\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\r\n </div>\r\n </template>\r\n </div>\r\n <div\r\n v-else\r\n class=\"c-transfer__empty\"\r\n >\r\n {{ mergedProps.sourceEmptyText }}\r\n </div>\r\n </div>\r\n\r\n <!-- ================ Actions ================ -->\r\n <div class=\"c-transfer__actions\">\r\n <button\r\n class=\"c-transfer__btn\"\r\n :class=\"{ 'is-disabled': sourceChecked.size === 0 }\"\r\n :disabled=\"sourceChecked.size === 0\"\r\n @click=\"moveToTarget\"\r\n >\r\n <C_Icon name=\"mdi:chevron-right\" />\r\n </button>\r\n <button\r\n class=\"c-transfer__btn\"\r\n :class=\"{ 'is-disabled': targetChecked.size === 0 }\"\r\n :disabled=\"targetChecked.size === 0\"\r\n @click=\"moveToSource\"\r\n >\r\n <C_Icon name=\"mdi:chevron-left\" />\r\n </button>\r\n </div>\r\n\r\n <!-- ================ Target Panel ================ -->\r\n <div class=\"c-transfer__panel\">\r\n <div class=\"c-transfer__header\">\r\n <NCheckbox\r\n v-if=\"mergedProps.showSelectAll\"\r\n :checked=\"isTargetAllChecked\"\r\n :indeterminate=\"isTargetIndeterminate\"\r\n @update:checked=\"toggleTargetAll\"\r\n >\r\n {{ mergedProps.titles?.[1] }}\r\n </NCheckbox>\r\n <span\r\n v-else\r\n class=\"c-transfer__title\"\r\n >\r\n {{ mergedProps.titles?.[1] }}\r\n </span>\r\n <span class=\"c-transfer__count\"\r\n >{{ targetChecked.size }} / {{ targetList.length }}</span\r\n >\r\n </div>\r\n\r\n <div\r\n v-if=\"mergedProps.filterable\"\r\n class=\"c-transfer__filter\"\r\n >\r\n <NInput\r\n v-model:value=\"targetQuery\"\r\n clearable\r\n size=\"small\"\r\n :placeholder=\"mergedProps.filterPlaceholder\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n </div>\r\n\r\n <div\r\n v-if=\"filteredTargetList.length\"\r\n class=\"c-transfer__list\"\r\n >\r\n <template\r\n v-for=\"item in filteredTargetList\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n class=\"c-transfer__item\"\r\n :class=\"{\r\n 'is-disabled': item.disabled,\r\n 'is-checked': targetChecked.has(item.key),\r\n }\"\r\n @click=\"!item.disabled && toggleTargetCheck(item.key)\"\r\n >\r\n <NCheckbox\r\n :checked=\"targetChecked.has(item.key)\"\r\n :disabled=\"item.disabled\"\r\n size=\"small\"\r\n @update:checked=\"toggleTargetCheck(item.key)\"\r\n @click.stop\r\n />\r\n <C_Icon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n class=\"c-transfer__item-icon\"\r\n />\r\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\r\n </div>\r\n </template>\r\n </div>\r\n <div\r\n v-else\r\n class=\"c-transfer__empty\"\r\n >\r\n {{ mergedProps.targetEmptyText }}\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed, reactive, ref } from 'vue'\r\n import C_Icon from '../C_Icon/index.vue'\r\n import {\r\n DEFAULT_TRANSFER_PROPS,\r\n type TransferItem,\r\n type TransferProps,\r\n } from './types'\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n data: TransferProps['data']\r\n modelValue: TransferProps['modelValue']\r\n titles?: TransferProps['titles']\r\n filterable?: boolean\r\n filterPlaceholder?: string\r\n filterMethod?: TransferProps['filterMethod']\r\n showSelectAll?: boolean\r\n sourceEmptyText?: string\r\n targetEmptyText?: string\r\n size?: TransferProps['size']\r\n }>(),\r\n {\r\n titles: () => DEFAULT_TRANSFER_PROPS.titles as [string, string],\r\n filterable: DEFAULT_TRANSFER_PROPS.filterable,\r\n filterPlaceholder: DEFAULT_TRANSFER_PROPS.filterPlaceholder,\r\n showSelectAll: DEFAULT_TRANSFER_PROPS.showSelectAll,\r\n sourceEmptyText: DEFAULT_TRANSFER_PROPS.sourceEmptyText,\r\n targetEmptyText: DEFAULT_TRANSFER_PROPS.targetEmptyText,\r\n size: DEFAULT_TRANSFER_PROPS.size,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n 'update:modelValue': [value: Array<string | number>]\r\n change: [\r\n targetKeys: Array<string | number>,\r\n direction: 'left' | 'right',\r\n moveKeys: Array<string | number>,\r\n ]\r\n }>()\r\n\r\n const mergedProps = computed(() => ({ ...DEFAULT_TRANSFER_PROPS, ...props }))\r\n\r\n // ==================== 数据列表 ====================\r\n\r\n const dataMap = computed(() => {\r\n const m = new Map<string | number, TransferItem>()\r\n for (const item of props.data) m.set(item.key, item)\r\n return m\r\n })\r\n\r\n const targetKeySet = computed(() => new Set(props.modelValue))\r\n\r\n const sourceList = computed(() =>\r\n props.data.filter(d => !targetKeySet.value.has(d.key))\r\n )\r\n\r\n const targetList = computed(() => {\r\n const result: TransferItem[] = []\r\n for (const key of props.modelValue) {\r\n const item = dataMap.value.get(key)\r\n if (item) result.push(item)\r\n }\r\n return result\r\n })\r\n\r\n // ==================== 搜索 ====================\r\n\r\n const sourceQuery = ref('')\r\n const targetQuery = ref('')\r\n\r\n /** 默认过滤方法 */\r\n function defaultFilter(query: string, item: TransferItem): boolean {\r\n return item.label.toLowerCase().includes(query.toLowerCase())\r\n }\r\n\r\n const filterFn = computed(() => props.filterMethod ?? defaultFilter)\r\n\r\n const filteredSourceList = computed(() => {\r\n const q = sourceQuery.value.trim()\r\n return q\r\n ? sourceList.value.filter(item => filterFn.value(q, item))\r\n : sourceList.value\r\n })\r\n\r\n const filteredTargetList = computed(() => {\r\n const q = targetQuery.value.trim()\r\n return q\r\n ? targetList.value.filter(item => filterFn.value(q, item))\r\n : targetList.value\r\n })\r\n\r\n // ==================== 选中态 ====================\r\n\r\n const sourceChecked = reactive(new Set<string | number>())\r\n const targetChecked = reactive(new Set<string | number>())\r\n\r\n /** 切换源列表项选中状态 */\r\n function toggleSourceCheck(key: string | number) {\r\n if (sourceChecked.has(key)) sourceChecked.delete(key)\r\n else sourceChecked.add(key)\r\n }\r\n\r\n /** 切换目标列表项选中状态 */\r\n function toggleTargetCheck(key: string | number) {\r\n if (targetChecked.has(key)) targetChecked.delete(key)\r\n else targetChecked.add(key)\r\n }\r\n\r\n const isSourceAllChecked = computed(\r\n () =>\r\n filteredSourceList.value.length > 0 &&\r\n filteredSourceList.value.every(\r\n i => i.disabled || sourceChecked.has(i.key)\r\n )\r\n )\r\n const isSourceIndeterminate = computed(\r\n () =>\r\n !isSourceAllChecked.value &&\r\n filteredSourceList.value.some(i => sourceChecked.has(i.key))\r\n )\r\n const isTargetAllChecked = computed(\r\n () =>\r\n filteredTargetList.value.length > 0 &&\r\n filteredTargetList.value.every(\r\n i => i.disabled || targetChecked.has(i.key)\r\n )\r\n )\r\n const isTargetIndeterminate = computed(\r\n () =>\r\n !isTargetAllChecked.value &&\r\n filteredTargetList.value.some(i => targetChecked.has(i.key))\r\n )\r\n\r\n /** 切换源列表全选状态 */\r\n function toggleSourceAll(checked: boolean) {\r\n for (const item of filteredSourceList.value) {\r\n if (item.disabled) continue\r\n if (checked) sourceChecked.add(item.key)\r\n else sourceChecked.delete(item.key)\r\n }\r\n }\r\n\r\n /** 切换目标列表全选状态 */\r\n function toggleTargetAll(checked: boolean) {\r\n for (const item of filteredTargetList.value) {\r\n if (item.disabled) continue\r\n if (checked) targetChecked.add(item.key)\r\n else targetChecked.delete(item.key)\r\n }\r\n }\r\n\r\n // ==================== 穿梭操作 ====================\r\n\r\n /** 将选中项移至目标列表 */\r\n function moveToTarget() {\r\n const keys = [...sourceChecked]\r\n const newVal = [...props.modelValue, ...keys]\r\n emit('update:modelValue', newVal)\r\n emit('change', newVal, 'right', keys)\r\n sourceChecked.clear()\r\n }\r\n\r\n /** 将选中项移回源列表 */\r\n function moveToSource() {\r\n const keys = [...targetChecked]\r\n const removeSet = new Set(keys)\r\n const newVal = props.modelValue.filter(k => !removeSet.has(k))\r\n emit('update:modelValue', newVal)\r\n emit('change', newVal, 'left', keys)\r\n targetChecked.clear()\r\n }\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n @use './index.scss';\r\n</style>\r\n","/* unplugin-vue-components disabled */<!--\r\n * @Description: 穿梭框组件\r\n-->\r\n<template>\r\n <div\r\n class=\"c-transfer\"\r\n :class=\"[`is-${mergedProps.size}`]\"\r\n >\r\n <!-- ================ Source Panel ================ -->\r\n <div class=\"c-transfer__panel\">\r\n <div class=\"c-transfer__header\">\r\n <NCheckbox\r\n v-if=\"mergedProps.showSelectAll\"\r\n :checked=\"isSourceAllChecked\"\r\n :indeterminate=\"isSourceIndeterminate\"\r\n @update:checked=\"toggleSourceAll\"\r\n >\r\n {{ mergedProps.titles?.[0] }}\r\n </NCheckbox>\r\n <span\r\n v-else\r\n class=\"c-transfer__title\"\r\n >\r\n {{ mergedProps.titles?.[0] }}\r\n </span>\r\n <span class=\"c-transfer__count\"\r\n >{{ sourceChecked.size }} / {{ sourceList.length }}</span\r\n >\r\n </div>\r\n\r\n <div\r\n v-if=\"mergedProps.filterable\"\r\n class=\"c-transfer__filter\"\r\n >\r\n <NInput\r\n v-model:value=\"sourceQuery\"\r\n clearable\r\n size=\"small\"\r\n :placeholder=\"mergedProps.filterPlaceholder\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n </div>\r\n\r\n <div\r\n v-if=\"filteredSourceList.length\"\r\n class=\"c-transfer__list\"\r\n >\r\n <template\r\n v-for=\"item in filteredSourceList\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n class=\"c-transfer__item\"\r\n :class=\"{\r\n 'is-disabled': item.disabled,\r\n 'is-checked': sourceChecked.has(item.key),\r\n }\"\r\n @click=\"!item.disabled && toggleSourceCheck(item.key)\"\r\n >\r\n <NCheckbox\r\n :checked=\"sourceChecked.has(item.key)\"\r\n :disabled=\"item.disabled\"\r\n size=\"small\"\r\n @update:checked=\"toggleSourceCheck(item.key)\"\r\n @click.stop\r\n />\r\n <C_Icon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n class=\"c-transfer__item-icon\"\r\n />\r\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\r\n </div>\r\n </template>\r\n </div>\r\n <div\r\n v-else\r\n class=\"c-transfer__empty\"\r\n >\r\n {{ mergedProps.sourceEmptyText }}\r\n </div>\r\n </div>\r\n\r\n <!-- ================ Actions ================ -->\r\n <div class=\"c-transfer__actions\">\r\n <button\r\n class=\"c-transfer__btn\"\r\n :class=\"{ 'is-disabled': sourceChecked.size === 0 }\"\r\n :disabled=\"sourceChecked.size === 0\"\r\n @click=\"moveToTarget\"\r\n >\r\n <C_Icon name=\"mdi:chevron-right\" />\r\n </button>\r\n <button\r\n class=\"c-transfer__btn\"\r\n :class=\"{ 'is-disabled': targetChecked.size === 0 }\"\r\n :disabled=\"targetChecked.size === 0\"\r\n @click=\"moveToSource\"\r\n >\r\n <C_Icon name=\"mdi:chevron-left\" />\r\n </button>\r\n </div>\r\n\r\n <!-- ================ Target Panel ================ -->\r\n <div class=\"c-transfer__panel\">\r\n <div class=\"c-transfer__header\">\r\n <NCheckbox\r\n v-if=\"mergedProps.showSelectAll\"\r\n :checked=\"isTargetAllChecked\"\r\n :indeterminate=\"isTargetIndeterminate\"\r\n @update:checked=\"toggleTargetAll\"\r\n >\r\n {{ mergedProps.titles?.[1] }}\r\n </NCheckbox>\r\n <span\r\n v-else\r\n class=\"c-transfer__title\"\r\n >\r\n {{ mergedProps.titles?.[1] }}\r\n </span>\r\n <span class=\"c-transfer__count\"\r\n >{{ targetChecked.size }} / {{ targetList.length }}</span\r\n >\r\n </div>\r\n\r\n <div\r\n v-if=\"mergedProps.filterable\"\r\n class=\"c-transfer__filter\"\r\n >\r\n <NInput\r\n v-model:value=\"targetQuery\"\r\n clearable\r\n size=\"small\"\r\n :placeholder=\"mergedProps.filterPlaceholder\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n </div>\r\n\r\n <div\r\n v-if=\"filteredTargetList.length\"\r\n class=\"c-transfer__list\"\r\n >\r\n <template\r\n v-for=\"item in filteredTargetList\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n class=\"c-transfer__item\"\r\n :class=\"{\r\n 'is-disabled': item.disabled,\r\n 'is-checked': targetChecked.has(item.key),\r\n }\"\r\n @click=\"!item.disabled && toggleTargetCheck(item.key)\"\r\n >\r\n <NCheckbox\r\n :checked=\"targetChecked.has(item.key)\"\r\n :disabled=\"item.disabled\"\r\n size=\"small\"\r\n @update:checked=\"toggleTargetCheck(item.key)\"\r\n @click.stop\r\n />\r\n <C_Icon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n class=\"c-transfer__item-icon\"\r\n />\r\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\r\n </div>\r\n </template>\r\n </div>\r\n <div\r\n v-else\r\n class=\"c-transfer__empty\"\r\n >\r\n {{ mergedProps.targetEmptyText }}\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed, reactive, ref } from 'vue'\r\n import C_Icon from '../C_Icon/index.vue'\r\n import {\r\n DEFAULT_TRANSFER_PROPS,\r\n type TransferItem,\r\n type TransferProps,\r\n } from './types'\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n data: TransferProps['data']\r\n modelValue: TransferProps['modelValue']\r\n titles?: TransferProps['titles']\r\n filterable?: boolean\r\n filterPlaceholder?: string\r\n filterMethod?: TransferProps['filterMethod']\r\n showSelectAll?: boolean\r\n sourceEmptyText?: string\r\n targetEmptyText?: string\r\n size?: TransferProps['size']\r\n }>(),\r\n {\r\n titles: () => DEFAULT_TRANSFER_PROPS.titles as [string, string],\r\n filterable: DEFAULT_TRANSFER_PROPS.filterable,\r\n filterPlaceholder: DEFAULT_TRANSFER_PROPS.filterPlaceholder,\r\n showSelectAll: DEFAULT_TRANSFER_PROPS.showSelectAll,\r\n sourceEmptyText: DEFAULT_TRANSFER_PROPS.sourceEmptyText,\r\n targetEmptyText: DEFAULT_TRANSFER_PROPS.targetEmptyText,\r\n size: DEFAULT_TRANSFER_PROPS.size,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n 'update:modelValue': [value: Array<string | number>]\r\n change: [\r\n targetKeys: Array<string | number>,\r\n direction: 'left' | 'right',\r\n moveKeys: Array<string | number>,\r\n ]\r\n }>()\r\n\r\n const mergedProps = computed(() => ({ ...DEFAULT_TRANSFER_PROPS, ...props }))\r\n\r\n // ==================== 数据列表 ====================\r\n\r\n const dataMap = computed(() => {\r\n const m = new Map<string | number, TransferItem>()\r\n for (const item of props.data) m.set(item.key, item)\r\n return m\r\n })\r\n\r\n const targetKeySet = computed(() => new Set(props.modelValue))\r\n\r\n const sourceList = computed(() =>\r\n props.data.filter(d => !targetKeySet.value.has(d.key))\r\n )\r\n\r\n const targetList = computed(() => {\r\n const result: TransferItem[] = []\r\n for (const key of props.modelValue) {\r\n const item = dataMap.value.get(key)\r\n if (item) result.push(item)\r\n }\r\n return result\r\n })\r\n\r\n // ==================== 搜索 ====================\r\n\r\n const sourceQuery = ref('')\r\n const targetQuery = ref('')\r\n\r\n /** 默认过滤方法 */\r\n function defaultFilter(query: string, item: TransferItem): boolean {\r\n return item.label.toLowerCase().includes(query.toLowerCase())\r\n }\r\n\r\n const filterFn = computed(() => props.filterMethod ?? defaultFilter)\r\n\r\n const filteredSourceList = computed(() => {\r\n const q = sourceQuery.value.trim()\r\n return q\r\n ? sourceList.value.filter(item => filterFn.value(q, item))\r\n : sourceList.value\r\n })\r\n\r\n const filteredTargetList = computed(() => {\r\n const q = targetQuery.value.trim()\r\n return q\r\n ? targetList.value.filter(item => filterFn.value(q, item))\r\n : targetList.value\r\n })\r\n\r\n // ==================== 选中态 ====================\r\n\r\n const sourceChecked = reactive(new Set<string | number>())\r\n const targetChecked = reactive(new Set<string | number>())\r\n\r\n /** 切换源列表项选中状态 */\r\n function toggleSourceCheck(key: string | number) {\r\n if (sourceChecked.has(key)) sourceChecked.delete(key)\r\n else sourceChecked.add(key)\r\n }\r\n\r\n /** 切换目标列表项选中状态 */\r\n function toggleTargetCheck(key: string | number) {\r\n if (targetChecked.has(key)) targetChecked.delete(key)\r\n else targetChecked.add(key)\r\n }\r\n\r\n const isSourceAllChecked = computed(\r\n () =>\r\n filteredSourceList.value.length > 0 &&\r\n filteredSourceList.value.every(\r\n i => i.disabled || sourceChecked.has(i.key)\r\n )\r\n )\r\n const isSourceIndeterminate = computed(\r\n () =>\r\n !isSourceAllChecked.value &&\r\n filteredSourceList.value.some(i => sourceChecked.has(i.key))\r\n )\r\n const isTargetAllChecked = computed(\r\n () =>\r\n filteredTargetList.value.length > 0 &&\r\n filteredTargetList.value.every(\r\n i => i.disabled || targetChecked.has(i.key)\r\n )\r\n )\r\n const isTargetIndeterminate = computed(\r\n () =>\r\n !isTargetAllChecked.value &&\r\n filteredTargetList.value.some(i => targetChecked.has(i.key))\r\n )\r\n\r\n /** 切换源列表全选状态 */\r\n function toggleSourceAll(checked: boolean) {\r\n for (const item of filteredSourceList.value) {\r\n if (item.disabled) continue\r\n if (checked) sourceChecked.add(item.key)\r\n else sourceChecked.delete(item.key)\r\n }\r\n }\r\n\r\n /** 切换目标列表全选状态 */\r\n function toggleTargetAll(checked: boolean) {\r\n for (const item of filteredTargetList.value) {\r\n if (item.disabled) continue\r\n if (checked) targetChecked.add(item.key)\r\n else targetChecked.delete(item.key)\r\n }\r\n }\r\n\r\n // ==================== 穿梭操作 ====================\r\n\r\n /** 将选中项移至目标列表 */\r\n function moveToTarget() {\r\n const keys = [...sourceChecked]\r\n const newVal = [...props.modelValue, ...keys]\r\n emit('update:modelValue', newVal)\r\n emit('change', newVal, 'right', keys)\r\n sourceChecked.clear()\r\n }\r\n\r\n /** 将选中项移回源列表 */\r\n function moveToSource() {\r\n const keys = [...targetChecked]\r\n const removeSet = new Set(keys)\r\n const newVal = props.modelValue.filter(k => !removeSet.has(k))\r\n emit('update:modelValue', newVal)\r\n emit('change', newVal, 'left', keys)\r\n targetChecked.clear()\r\n }\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n @use './index.scss';\r\n</style>\r\n","<!--\r\n * @Description: 穿梭框组件\r\n-->\r\n<template>\r\n <div\r\n class=\"c-transfer\"\r\n :class=\"[`is-${mergedProps.size}`]\"\r\n >\r\n <!-- ================ Source Panel ================ -->\r\n <div class=\"c-transfer__panel\">\r\n <div class=\"c-transfer__header\">\r\n <NCheckbox\r\n v-if=\"mergedProps.showSelectAll\"\r\n :checked=\"isSourceAllChecked\"\r\n :indeterminate=\"isSourceIndeterminate\"\r\n @update:checked=\"toggleSourceAll\"\r\n >\r\n {{ mergedProps.titles?.[0] }}\r\n </NCheckbox>\r\n <span\r\n v-else\r\n class=\"c-transfer__title\"\r\n >\r\n {{ mergedProps.titles?.[0] }}\r\n </span>\r\n <span class=\"c-transfer__count\"\r\n >{{ sourceChecked.size }} / {{ sourceList.length }}</span\r\n >\r\n </div>\r\n\r\n <div\r\n v-if=\"mergedProps.filterable\"\r\n class=\"c-transfer__filter\"\r\n >\r\n <NInput\r\n v-model:value=\"sourceQuery\"\r\n clearable\r\n size=\"small\"\r\n :placeholder=\"mergedProps.filterPlaceholder\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n </div>\r\n\r\n <div\r\n v-if=\"filteredSourceList.length\"\r\n class=\"c-transfer__list\"\r\n >\r\n <template\r\n v-for=\"item in filteredSourceList\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n class=\"c-transfer__item\"\r\n :class=\"{\r\n 'is-disabled': item.disabled,\r\n 'is-checked': sourceChecked.has(item.key),\r\n }\"\r\n @click=\"!item.disabled && toggleSourceCheck(item.key)\"\r\n >\r\n <NCheckbox\r\n :checked=\"sourceChecked.has(item.key)\"\r\n :disabled=\"item.disabled\"\r\n size=\"small\"\r\n @update:checked=\"toggleSourceCheck(item.key)\"\r\n @click.stop\r\n />\r\n <C_Icon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n class=\"c-transfer__item-icon\"\r\n />\r\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\r\n </div>\r\n </template>\r\n </div>\r\n <div\r\n v-else\r\n class=\"c-transfer__empty\"\r\n >\r\n {{ mergedProps.sourceEmptyText }}\r\n </div>\r\n </div>\r\n\r\n <!-- ================ Actions ================ -->\r\n <div class=\"c-transfer__actions\">\r\n <button\r\n class=\"c-transfer__btn\"\r\n :class=\"{ 'is-disabled': sourceChecked.size === 0 }\"\r\n :disabled=\"sourceChecked.size === 0\"\r\n @click=\"moveToTarget\"\r\n >\r\n <C_Icon name=\"mdi:chevron-right\" />\r\n </button>\r\n <button\r\n class=\"c-transfer__btn\"\r\n :class=\"{ 'is-disabled': targetChecked.size === 0 }\"\r\n :disabled=\"targetChecked.size === 0\"\r\n @click=\"moveToSource\"\r\n >\r\n <C_Icon name=\"mdi:chevron-left\" />\r\n </button>\r\n </div>\r\n\r\n <!-- ================ Target Panel ================ -->\r\n <div class=\"c-transfer__panel\">\r\n <div class=\"c-transfer__header\">\r\n <NCheckbox\r\n v-if=\"mergedProps.showSelectAll\"\r\n :checked=\"isTargetAllChecked\"\r\n :indeterminate=\"isTargetIndeterminate\"\r\n @update:checked=\"toggleTargetAll\"\r\n >\r\n {{ mergedProps.titles?.[1] }}\r\n </NCheckbox>\r\n <span\r\n v-else\r\n class=\"c-transfer__title\"\r\n >\r\n {{ mergedProps.titles?.[1] }}\r\n </span>\r\n <span class=\"c-transfer__count\"\r\n >{{ targetChecked.size }} / {{ targetList.length }}</span\r\n >\r\n </div>\r\n\r\n <div\r\n v-if=\"mergedProps.filterable\"\r\n class=\"c-transfer__filter\"\r\n >\r\n <NInput\r\n v-model:value=\"targetQuery\"\r\n clearable\r\n size=\"small\"\r\n :placeholder=\"mergedProps.filterPlaceholder\"\r\n >\r\n <template #prefix>\r\n <C_Icon name=\"mdi:magnify\" />\r\n </template>\r\n </NInput>\r\n </div>\r\n\r\n <div\r\n v-if=\"filteredTargetList.length\"\r\n class=\"c-transfer__list\"\r\n >\r\n <template\r\n v-for=\"item in filteredTargetList\"\r\n :key=\"item.key\"\r\n >\r\n <div\r\n class=\"c-transfer__item\"\r\n :class=\"{\r\n 'is-disabled': item.disabled,\r\n 'is-checked': targetChecked.has(item.key),\r\n }\"\r\n @click=\"!item.disabled && toggleTargetCheck(item.key)\"\r\n >\r\n <NCheckbox\r\n :checked=\"targetChecked.has(item.key)\"\r\n :disabled=\"item.disabled\"\r\n size=\"small\"\r\n @update:checked=\"toggleTargetCheck(item.key)\"\r\n @click.stop\r\n />\r\n <C_Icon\r\n v-if=\"item.icon\"\r\n :name=\"item.icon\"\r\n class=\"c-transfer__item-icon\"\r\n />\r\n <span class=\"c-transfer__item-label\">{{ item.label }}</span>\r\n </div>\r\n </template>\r\n </div>\r\n <div\r\n v-else\r\n class=\"c-transfer__empty\"\r\n >\r\n {{ mergedProps.targetEmptyText }}\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { computed, reactive, ref } from 'vue'\r\n import C_Icon from '../C_Icon/index.vue'\r\n import {\r\n DEFAULT_TRANSFER_PROPS,\r\n type TransferItem,\r\n type TransferProps,\r\n } from './types'\r\n\r\n const props = withDefaults(\r\n defineProps<{\r\n data: TransferProps['data']\r\n modelValue: TransferProps['modelValue']\r\n titles?: TransferProps['titles']\r\n filterable?: boolean\r\n filterPlaceholder?: string\r\n filterMethod?: TransferProps['filterMethod']\r\n showSelectAll?: boolean\r\n sourceEmptyText?: string\r\n targetEmptyText?: string\r\n size?: TransferProps['size']\r\n }>(),\r\n {\r\n titles: () => DEFAULT_TRANSFER_PROPS.titles as [string, string],\r\n filterable: DEFAULT_TRANSFER_PROPS.filterable,\r\n filterPlaceholder: DEFAULT_TRANSFER_PROPS.filterPlaceholder,\r\n showSelectAll: DEFAULT_TRANSFER_PROPS.showSelectAll,\r\n sourceEmptyText: DEFAULT_TRANSFER_PROPS.sourceEmptyText,\r\n targetEmptyText: DEFAULT_TRANSFER_PROPS.targetEmptyText,\r\n size: DEFAULT_TRANSFER_PROPS.size,\r\n }\r\n )\r\n\r\n const emit = defineEmits<{\r\n 'update:modelValue': [value: Array<string | number>]\r\n change: [\r\n targetKeys: Array<string | number>,\r\n direction: 'left' | 'right',\r\n moveKeys: Array<string | number>,\r\n ]\r\n }>()\r\n\r\n const mergedProps = computed(() => ({ ...DEFAULT_TRANSFER_PROPS, ...props }))\r\n\r\n // ==================== 数据列表 ====================\r\n\r\n const dataMap = computed(() => {\r\n const m = new Map<string | number, TransferItem>()\r\n for (const item of props.data) m.set(item.key, item)\r\n return m\r\n })\r\n\r\n const targetKeySet = computed(() => new Set(props.modelValue))\r\n\r\n const sourceList = computed(() =>\r\n props.data.filter(d => !targetKeySet.value.has(d.key))\r\n )\r\n\r\n const targetList = computed(() => {\r\n const result: TransferItem[] = []\r\n for (const key of props.modelValue) {\r\n const item = dataMap.value.get(key)\r\n if (item) result.push(item)\r\n }\r\n return result\r\n })\r\n\r\n // ==================== 搜索 ====================\r\n\r\n const sourceQuery = ref('')\r\n const targetQuery = ref('')\r\n\r\n /** 默认过滤方法 */\r\n function defaultFilter(query: string, item: TransferItem): boolean {\r\n return item.label.toLowerCase().includes(query.toLowerCase())\r\n }\r\n\r\n const filterFn = computed(() => props.filterMethod ?? defaultFilter)\r\n\r\n const filteredSourceList = computed(() => {\r\n const q = sourceQuery.value.trim()\r\n return q\r\n ? sourceList.value.filter(item => filterFn.value(q, item))\r\n : sourceList.value\r\n })\r\n\r\n const filteredTargetList = computed(() => {\r\n const q = targetQuery.value.trim()\r\n return q\r\n ? targetList.value.filter(item => filterFn.value(q, item))\r\n : targetList.value\r\n })\r\n\r\n // ==================== 选中态 ====================\r\n\r\n const sourceChecked = reactive(new Set<string | number>())\r\n const targetChecked = reactive(new Set<string | number>())\r\n\r\n /** 切换源列表项选中状态 */\r\n function toggleSourceCheck(key: string | number) {\r\n if (sourceChecked.has(key)) sourceChecked.delete(key)\r\n else sourceChecked.add(key)\r\n }\r\n\r\n /** 切换目标列表项选中状态 */\r\n function toggleTargetCheck(key: string | number) {\r\n if (targetChecked.has(key)) targetChecked.delete(key)\r\n else targetChecked.add(key)\r\n }\r\n\r\n const isSourceAllChecked = computed(\r\n () =>\r\n filteredSourceList.value.length > 0 &&\r\n filteredSourceList.value.every(\r\n i => i.disabled || sourceChecked.has(i.key)\r\n )\r\n )\r\n const isSourceIndeterminate = computed(\r\n () =>\r\n !isSourceAllChecked.value &&\r\n filteredSourceList.value.some(i => sourceChecked.has(i.key))\r\n )\r\n const isTargetAllChecked = computed(\r\n () =>\r\n filteredTargetList.value.length > 0 &&\r\n filteredTargetList.value.every(\r\n i => i.disabled || targetChecked.has(i.key)\r\n )\r\n )\r\n const isTargetIndeterminate = computed(\r\n () =>\r\n !isTargetAllChecked.value &&\r\n filteredTargetList.value.some(i => targetChecked.has(i.key))\r\n )\r\n\r\n /** 切换源列表全选状态 */\r\n function toggleSourceAll(checked: boolean) {\r\n for (const item of filteredSourceList.value) {\r\n if (item.disabled) continue\r\n if (checked) sourceChecked.add(item.key)\r\n else sourceChecked.delete(item.key)\r\n }\r\n }\r\n\r\n /** 切换目标列表全选状态 */\r\n function toggleTargetAll(checked: boolean) {\r\n for (const item of filteredTargetList.value) {\r\n if (item.disabled) continue\r\n if (checked) targetChecked.add(item.key)\r\n else targetChecked.delete(item.key)\r\n }\r\n }\r\n\r\n // ==================== 穿梭操作 ====================\r\n\r\n /** 将选中项移至目标列表 */\r\n function moveToTarget() {\r\n const keys = [...sourceChecked]\r\n const newVal = [...props.modelValue, ...keys]\r\n emit('update:modelValue', newVal)\r\n emit('change', newVal, 'right', keys)\r\n sourceChecked.clear()\r\n }\r\n\r\n /** 将选中项移回源列表 */\r\n function moveToSource() {\r\n const keys = [...targetChecked]\r\n const removeSet = new Set(keys)\r\n const newVal = props.modelValue.filter(k => !removeSet.has(k))\r\n emit('update:modelValue', newVal)\r\n emit('change', newVal, 'left', keys)\r\n targetChecked.clear()\r\n }\r\n</script>\r\n\r\n<style scoped lang=\"scss\">\r\n @use './index.scss';\r\n</style>\r\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./C_Icon2.js";import{t}from"./export-helper.js";import{NCheckbox as n,NInput as r}from"naive-ui";import{Fragment as i,computed as a,createBlock as o,createCommentVNode as s,createElementBlock as c,createElementVNode as l,createTextVNode as u,createVNode as d,defineComponent as f,normalizeClass as p,openBlock as m,reactive as h,ref as g,renderList as _,toDisplayString as v,withCtx as y,withModifiers as b}from"vue";const x={titles:[`可选列表`,`已选列表`],filterable:!1,filterPlaceholder:`搜索...`,showSelectAll:!0,sourceEmptyText:`暂无数据`,targetEmptyText:`未选择任何项`,size:`medium`},S={class:`c-transfer__panel`},ee={class:`c-transfer__header`},te={key:1,class:`c-transfer__title`},ne={class:`c-transfer__count`},re={key:0,class:`c-transfer__filter`},ie={key:1,class:`c-transfer__list`},ae=[`onClick`],C={class:`c-transfer__item-label`},w={key:2,class:`c-transfer__empty`},T={class:`c-transfer__actions`},E=[`disabled`],D=[`disabled`],O={class:`c-transfer__panel`},k={class:`c-transfer__header`},oe={key:1,class:`c-transfer__title`},se={class:`c-transfer__count`},ce={key:0,class:`c-transfer__filter`},A={key:1,class:`c-transfer__list`},j=[`onClick`],M={class:`c-transfer__item-label`},N={key:2,class:`c-transfer__empty`};var P=t(f({__name:`index`,props:{data:{},modelValue:{},titles:{default:()=>x.titles},filterable:{type:Boolean,default:x.filterable},filterPlaceholder:{default:x.filterPlaceholder},filterMethod:{},showSelectAll:{type:Boolean,default:x.showSelectAll},sourceEmptyText:{default:x.sourceEmptyText},targetEmptyText:{default:x.targetEmptyText},size:{default:x.size}},emits:[`update:modelValue`,`change`],setup(t,{emit:f}){let P=t,F=f,I=a(()=>({...x,...P})),L=a(()=>{let e=new Map;for(let t of P.data)e.set(t.key,t);return e}),R=a(()=>new Set(P.modelValue)),z=a(()=>P.data.filter(e=>!R.value.has(e.key))),B=a(()=>{let e=[];for(let t of P.modelValue){let n=L.value.get(t);n&&e.push(n)}return e}),V=g(``),H=g(``);function U(e,t){return t.label.toLowerCase().includes(e.toLowerCase())}let W=a(()=>P.filterMethod??U),G=a(()=>{let e=V.value.trim();return e?z.value.filter(t=>W.value(e,t)):z.value}),K=a(()=>{let e=H.value.trim();return e?B.value.filter(t=>W.value(e,t)):B.value}),q=h(new Set),J=h(new Set);function Y(e){q.has(e)?q.delete(e):q.add(e)}function X(e){J.has(e)?J.delete(e):J.add(e)}let Z=a(()=>G.value.length>0&&G.value.every(e=>e.disabled||q.has(e.key))),le=a(()=>!Z.value&&G.value.some(e=>q.has(e.key))),Q=a(()=>K.value.length>0&&K.value.every(e=>e.disabled||J.has(e.key))),$=a(()=>!Q.value&&K.value.some(e=>J.has(e.key)));function ue(e){for(let t of G.value)t.disabled||(e?q.add(t.key):q.delete(t.key))}function de(e){for(let t of K.value)t.disabled||(e?J.add(t.key):J.delete(t.key))}function fe(){let e=[...q],t=[...P.modelValue,...e];F(`update:modelValue`,t),F(`change`,t,`right`,e),q.clear()}function pe(){let e=[...J],t=new Set(e),n=P.modelValue.filter(e=>!t.has(e));F(`update:modelValue`,n),F(`change`,n,`left`,e),J.clear()}return(t,a)=>{let f=n,h=r;return m(),c(`div`,{class:p([`c-transfer`,[`is-${I.value.size}`]])},[s(` ================ Source Panel ================ `),l(`div`,S,[l(`div`,ee,[I.value.showSelectAll?(m(),o(f,{key:0,checked:Z.value,indeterminate:le.value,"onUpdate:checked":ue},{default:y(()=>[u(v(I.value.titles?.[0]),1)]),_:1},8,[`checked`,`indeterminate`])):(m(),c(`span`,te,v(I.value.titles?.[0]),1)),l(`span`,ne,v(q.size)+` / `+v(z.value.length),1)]),I.value.filterable?(m(),c(`div`,re,[d(h,{value:V.value,"onUpdate:value":a[0]||=e=>V.value=e,clearable:``,size:`small`,placeholder:I.value.filterPlaceholder},{prefix:y(()=>[d(e,{name:`mdi:magnify`})]),_:1},8,[`value`,`placeholder`])])):s(`v-if`,!0),G.value.length?(m(),c(`div`,ie,[(m(!0),c(i,null,_(G.value,t=>(m(),c(`div`,{key:t.key,class:p([`c-transfer__item`,{"is-disabled":t.disabled,"is-checked":q.has(t.key)}]),onClick:e=>!t.disabled&&Y(t.key)},[d(f,{checked:q.has(t.key),disabled:t.disabled,size:`small`,"onUpdate:checked":e=>Y(t.key),onClick:a[1]||=b(()=>{},[`stop`])},null,8,[`checked`,`disabled`,`onUpdate:checked`]),t.icon?(m(),o(e,{key:0,name:t.icon,class:`c-transfer__item-icon`},null,8,[`name`])):s(`v-if`,!0),l(`span`,C,v(t.label),1)],10,ae))),128))])):(m(),c(`div`,w,v(I.value.sourceEmptyText),1))]),s(` ================ Actions ================ `),l(`div`,T,[l(`button`,{class:p([`c-transfer__btn`,{"is-disabled":q.size===0}]),disabled:q.size===0,onClick:fe},[d(e,{name:`mdi:chevron-right`})],10,E),l(`button`,{class:p([`c-transfer__btn`,{"is-disabled":J.size===0}]),disabled:J.size===0,onClick:pe},[d(e,{name:`mdi:chevron-left`})],10,D)]),s(` ================ Target Panel ================ `),l(`div`,O,[l(`div`,k,[I.value.showSelectAll?(m(),o(f,{key:0,checked:Q.value,indeterminate:$.value,"onUpdate:checked":de},{default:y(()=>[u(v(I.value.titles?.[1]),1)]),_:1},8,[`checked`,`indeterminate`])):(m(),c(`span`,oe,v(I.value.titles?.[1]),1)),l(`span`,se,v(J.size)+` / `+v(B.value.length),1)]),I.value.filterable?(m(),c(`div`,ce,[d(h,{value:H.value,"onUpdate:value":a[2]||=e=>H.value=e,clearable:``,size:`small`,placeholder:I.value.filterPlaceholder},{prefix:y(()=>[d(e,{name:`mdi:magnify`})]),_:1},8,[`value`,`placeholder`])])):s(`v-if`,!0),K.value.length?(m(),c(`div`,A,[(m(!0),c(i,null,_(K.value,t=>(m(),c(`div`,{key:t.key,class:p([`c-transfer__item`,{"is-disabled":t.disabled,"is-checked":J.has(t.key)}]),onClick:e=>!t.disabled&&X(t.key)},[d(f,{checked:J.has(t.key),disabled:t.disabled,size:`small`,"onUpdate:checked":e=>X(t.key),onClick:a[3]||=b(()=>{},[`stop`])},null,8,[`checked`,`disabled`,`onUpdate:checked`]),t.icon?(m(),o(e,{key:0,name:t.icon,class:`c-transfer__item-icon`},null,8,[`name`])):s(`v-if`,!0),l(`span`,M,v(t.label),1)],10,j))),128))])):(m(),c(`div`,N,v(I.value.targetEmptyText),1))])],2)}}}),[[`__scopeId`,`data-v-6de1c97f`]]);export{x as n,P as t};
1
+ import{t as e}from"./C_Icon2.js";import{t}from"./export-helper.js";import{NCheckbox as n,NInput as r}from"naive-ui";import{Fragment as i,computed as a,createBlock as o,createCommentVNode as s,createElementBlock as c,createElementVNode as l,createTextVNode as u,createVNode as d,defineComponent as f,normalizeClass as p,openBlock as m,reactive as h,ref as g,renderList as _,toDisplayString as v,withCtx as y,withModifiers as b}from"vue";const x={titles:[`可选列表`,`已选列表`],filterable:!1,filterPlaceholder:`搜索...`,showSelectAll:!0,sourceEmptyText:`暂无数据`,targetEmptyText:`未选择任何项`,size:`medium`},S={class:`c-transfer__panel`},ee={class:`c-transfer__header`},te={key:1,class:`c-transfer__title`},ne={class:`c-transfer__count`},re={key:0,class:`c-transfer__filter`},ie={key:1,class:`c-transfer__list`},ae=[`onClick`],C={class:`c-transfer__item-label`},w={key:2,class:`c-transfer__empty`},T={class:`c-transfer__actions`},E=[`disabled`],D=[`disabled`],O={class:`c-transfer__panel`},k={class:`c-transfer__header`},oe={key:1,class:`c-transfer__title`},se={class:`c-transfer__count`},ce={key:0,class:`c-transfer__filter`},A={key:1,class:`c-transfer__list`},j=[`onClick`],M={class:`c-transfer__item-label`},N={key:2,class:`c-transfer__empty`};var P=t(f({__name:`index`,props:{data:{},modelValue:{},titles:{default:()=>x.titles},filterable:{type:Boolean,default:x.filterable},filterPlaceholder:{default:x.filterPlaceholder},filterMethod:{},showSelectAll:{type:Boolean,default:x.showSelectAll},sourceEmptyText:{default:x.sourceEmptyText},targetEmptyText:{default:x.targetEmptyText},size:{default:x.size}},emits:[`update:modelValue`,`change`],setup(t,{emit:f}){let P=t,F=f,I=a(()=>({...x,...P})),L=a(()=>{let e=new Map;for(let t of P.data)e.set(t.key,t);return e}),R=a(()=>new Set(P.modelValue)),z=a(()=>P.data.filter(e=>!R.value.has(e.key))),B=a(()=>{let e=[];for(let t of P.modelValue){let n=L.value.get(t);n&&e.push(n)}return e}),V=g(``),H=g(``);function U(e,t){return t.label.toLowerCase().includes(e.toLowerCase())}let W=a(()=>P.filterMethod??U),G=a(()=>{let e=V.value.trim();return e?z.value.filter(t=>W.value(e,t)):z.value}),K=a(()=>{let e=H.value.trim();return e?B.value.filter(t=>W.value(e,t)):B.value}),q=h(new Set),J=h(new Set);function Y(e){q.has(e)?q.delete(e):q.add(e)}function X(e){J.has(e)?J.delete(e):J.add(e)}let Z=a(()=>G.value.length>0&&G.value.every(e=>e.disabled||q.has(e.key))),le=a(()=>!Z.value&&G.value.some(e=>q.has(e.key))),Q=a(()=>K.value.length>0&&K.value.every(e=>e.disabled||J.has(e.key))),$=a(()=>!Q.value&&K.value.some(e=>J.has(e.key)));function ue(e){for(let t of G.value)t.disabled||(e?q.add(t.key):q.delete(t.key))}function de(e){for(let t of K.value)t.disabled||(e?J.add(t.key):J.delete(t.key))}function fe(){let e=[...q],t=[...P.modelValue,...e];F(`update:modelValue`,t),F(`change`,t,`right`,e),q.clear()}function pe(){let e=[...J],t=new Set(e),n=P.modelValue.filter(e=>!t.has(e));F(`update:modelValue`,n),F(`change`,n,`left`,e),J.clear()}return(t,a)=>{let f=n,h=r;return m(),c(`div`,{class:p([`c-transfer`,[`is-${I.value.size}`]])},[s(` ================ Source Panel ================ `),l(`div`,S,[l(`div`,ee,[I.value.showSelectAll?(m(),o(f,{key:0,checked:Z.value,indeterminate:le.value,"onUpdate:checked":ue},{default:y(()=>[u(v(I.value.titles?.[0]),1)]),_:1},8,[`checked`,`indeterminate`])):(m(),c(`span`,te,v(I.value.titles?.[0]),1)),l(`span`,ne,v(q.size)+` / `+v(z.value.length),1)]),I.value.filterable?(m(),c(`div`,re,[d(h,{value:V.value,"onUpdate:value":a[0]||=e=>V.value=e,clearable:``,size:`small`,placeholder:I.value.filterPlaceholder},{prefix:y(()=>[d(e,{name:`mdi:magnify`})]),_:1},8,[`value`,`placeholder`])])):s(`v-if`,!0),G.value.length?(m(),c(`div`,ie,[(m(!0),c(i,null,_(G.value,t=>(m(),c(`div`,{key:t.key,class:p([`c-transfer__item`,{"is-disabled":t.disabled,"is-checked":q.has(t.key)}]),onClick:e=>!t.disabled&&Y(t.key)},[d(f,{checked:q.has(t.key),disabled:t.disabled,size:`small`,"onUpdate:checked":e=>Y(t.key),onClick:a[1]||=b(()=>{},[`stop`])},null,8,[`checked`,`disabled`,`onUpdate:checked`]),t.icon?(m(),o(e,{key:0,name:t.icon,class:`c-transfer__item-icon`},null,8,[`name`])):s(`v-if`,!0),l(`span`,C,v(t.label),1)],10,ae))),128))])):(m(),c(`div`,w,v(I.value.sourceEmptyText),1))]),s(` ================ Actions ================ `),l(`div`,T,[l(`button`,{class:p([`c-transfer__btn`,{"is-disabled":q.size===0}]),disabled:q.size===0,onClick:fe},[d(e,{name:`mdi:chevron-right`})],10,E),l(`button`,{class:p([`c-transfer__btn`,{"is-disabled":J.size===0}]),disabled:J.size===0,onClick:pe},[d(e,{name:`mdi:chevron-left`})],10,D)]),s(` ================ Target Panel ================ `),l(`div`,O,[l(`div`,k,[I.value.showSelectAll?(m(),o(f,{key:0,checked:Q.value,indeterminate:$.value,"onUpdate:checked":de},{default:y(()=>[u(v(I.value.titles?.[1]),1)]),_:1},8,[`checked`,`indeterminate`])):(m(),c(`span`,oe,v(I.value.titles?.[1]),1)),l(`span`,se,v(J.size)+` / `+v(B.value.length),1)]),I.value.filterable?(m(),c(`div`,ce,[d(h,{value:H.value,"onUpdate:value":a[2]||=e=>H.value=e,clearable:``,size:`small`,placeholder:I.value.filterPlaceholder},{prefix:y(()=>[d(e,{name:`mdi:magnify`})]),_:1},8,[`value`,`placeholder`])])):s(`v-if`,!0),K.value.length?(m(),c(`div`,A,[(m(!0),c(i,null,_(K.value,t=>(m(),c(`div`,{key:t.key,class:p([`c-transfer__item`,{"is-disabled":t.disabled,"is-checked":J.has(t.key)}]),onClick:e=>!t.disabled&&X(t.key)},[d(f,{checked:J.has(t.key),disabled:t.disabled,size:`small`,"onUpdate:checked":e=>X(t.key),onClick:a[3]||=b(()=>{},[`stop`])},null,8,[`checked`,`disabled`,`onUpdate:checked`]),t.icon?(m(),o(e,{key:0,name:t.icon,class:`c-transfer__item-icon`},null,8,[`name`])):s(`v-if`,!0),l(`span`,M,v(t.label),1)],10,j))),128))])):(m(),c(`div`,N,v(I.value.targetEmptyText),1))])],2)}}}),[[`__scopeId`,`data-v-a627032d`]]);export{x as n,P as t};
2
2
  //# sourceMappingURL=C_Transfer2.js.map