@king-design/intact 3.6.2-beta.1 → 3.7.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 (281) hide show
  1. package/components/.DS_Store +0 -0
  2. package/components/anchor/constants.ts +3 -0
  3. package/components/anchor/demos/basic.md +34 -0
  4. package/components/anchor/demos/container.md +76 -0
  5. package/components/anchor/demos/events.md +100 -0
  6. package/components/anchor/demos/horizontal.md +33 -0
  7. package/components/anchor/demos/nested.md +132 -0
  8. package/components/anchor/index.md +38 -0
  9. package/components/anchor/index.spec.ts +171 -0
  10. package/components/anchor/index.ts +159 -0
  11. package/components/anchor/index.vdt +24 -0
  12. package/components/anchor/link.ts +44 -0
  13. package/components/anchor/link.vdt +49 -0
  14. package/components/anchor/styles.ts +50 -0
  15. package/components/anchor/useScroll.ts +221 -0
  16. package/components/config/demos/basic.md +11 -3
  17. package/components/descriptions/.DS_Store +0 -0
  18. package/components/dialog/base.vdt +3 -1
  19. package/components/drawer/demos/resizable.md +67 -0
  20. package/components/drawer/index.md +1 -0
  21. package/components/drawer/index.spec.ts +43 -0
  22. package/components/drawer/index.ts +14 -0
  23. package/components/drawer/index.vdt +20 -3
  24. package/components/drawer/styles.ts +44 -0
  25. package/components/drawer/useDrawerResizable.ts +190 -0
  26. package/components/icon/demos/color.md +1 -1
  27. package/components/icon/demos/icons.md +18 -0
  28. package/components/menu/.DS_Store +0 -0
  29. package/components/menu/demos/.DS_Store +0 -0
  30. package/components/menu/demos/collapse.md +2 -2
  31. package/components/menu/demos/showCollapseArrow.md +3 -3
  32. package/components/menu/demos/size.md +4 -4
  33. package/components/menu/styles.ts +7 -3
  34. package/components/notification/demos/basic.md +27 -0
  35. package/components/notification/demos/close.md +52 -0
  36. package/components/notification/demos/duration.md +43 -0
  37. package/components/notification/demos/events.md +39 -0
  38. package/components/notification/demos/hideClose.md +30 -0
  39. package/components/notification/demos/icon.md +47 -0
  40. package/components/notification/demos/position.md +39 -0
  41. package/components/notification/demos/types.md +38 -0
  42. package/components/notification/index.md +62 -0
  43. package/components/notification/index.spec.ts +211 -0
  44. package/components/notification/index.ts +2 -0
  45. package/components/notification/notification.ts +185 -0
  46. package/components/notification/notification.vdt +62 -0
  47. package/components/notification/notifications.ts +46 -0
  48. package/components/notification/notifications.vdt +16 -0
  49. package/components/notification/styles.ts +179 -0
  50. package/components/select/styles.ts +2 -0
  51. package/components/table/.DS_Store +0 -0
  52. package/components/table/demos/hidden.md +8 -2
  53. package/components/table/demos/sort.md +4 -4
  54. package/components/table/styles.ts +6 -2
  55. package/components/tabs/useActiveBar.ts +3 -3
  56. package/components/tag/base.ts +4 -0
  57. package/components/tag/demos/border.md +1 -1
  58. package/components/tag/demos/color.md +40 -0
  59. package/components/tag/demos/draggable.md +1 -1
  60. package/components/tag/demos/tags.md +1 -1
  61. package/components/tag/index.md +1 -0
  62. package/components/tag/index.spec.ts +8 -0
  63. package/components/tag/index.vdt +6 -4
  64. package/components/tag/styles.ts +23 -0
  65. package/components/tag/useColor.ts +79 -0
  66. package/components/timepicker/index.spec.ts +16 -5
  67. package/components/timepicker/useDefaultValue.ts +16 -7
  68. package/components/timepicker/useStep.ts +3 -2
  69. package/components/tour/.DS_Store +0 -0
  70. package/components/transfer/demos/customFilter.md +1 -1
  71. package/components/transfer/demos/customList.md +1 -1
  72. package/components/transfer/demos/getData.md +1 -1
  73. package/components/transfer/demos/leftChecked.md +1 -1
  74. package/components/transfer/demos/pagination.md +63 -0
  75. package/components/transfer/demos/table.md +248 -0
  76. package/components/transfer/demos/tree.md +1 -1
  77. package/components/transfer/index.md +2 -0
  78. package/components/transfer/index.spec.ts +147 -0
  79. package/components/transfer/index.ts +7 -0
  80. package/components/transfer/index.vdt +30 -4
  81. package/components/transfer/styles.ts +11 -1
  82. package/components/transfer/useCheck.ts +5 -5
  83. package/components/transfer/usePagination.ts +92 -0
  84. package/components/virtualList/.DS_Store +0 -0
  85. package/components/virtualList/demos/.DS_Store +0 -0
  86. package/dist/fonts/iconfont.eot +0 -0
  87. package/dist/fonts/iconfont.svg +235 -0
  88. package/dist/fonts/iconfont.ttf +0 -0
  89. package/dist/fonts/iconfont.woff +0 -0
  90. package/dist/fonts/iconfont.woff2 +0 -0
  91. package/dist/fonts/ionicons.eot +0 -0
  92. package/dist/fonts/ionicons.svg +2230 -0
  93. package/dist/fonts/ionicons.ttf +0 -0
  94. package/dist/fonts/ionicons.woff +0 -0
  95. package/dist/fonts/ionicons.woff2 +0 -0
  96. package/dist/i18n/en-US.js +1411 -0
  97. package/dist/i18n/en-US.js.map +1 -0
  98. package/dist/i18n/en-US.min.js +1 -0
  99. package/dist/i18n/index.js +283 -0
  100. package/dist/i18n/index.js.map +1 -0
  101. package/dist/i18n/index.min.js +1 -0
  102. package/dist/kpc.js +50764 -0
  103. package/dist/kpc.js.map +1 -0
  104. package/dist/kpc.min.js +1 -0
  105. package/dist/kpc.react.js +58380 -0
  106. package/dist/kpc.react.js.map +1 -0
  107. package/dist/kpc.react.min.js +1 -0
  108. package/dist/kpc.tmp.js.map +1 -0
  109. package/dist/kpc.vue-legacy.js +58272 -0
  110. package/dist/kpc.vue-legacy.js.map +1 -0
  111. package/dist/kpc.vue-legacy.min.js +1 -0
  112. package/dist/kpc.vue.js +58128 -0
  113. package/dist/kpc.vue.js.map +1 -0
  114. package/dist/kpc.vue.min.js +1 -0
  115. package/es/components/anchor/constants.d.ts +2 -0
  116. package/es/components/anchor/constants.js +2 -0
  117. package/es/components/anchor/index.d.ts +41 -0
  118. package/es/components/anchor/index.js +141 -0
  119. package/es/components/anchor/index.spec.d.ts +1 -0
  120. package/es/components/anchor/index.spec.js +230 -0
  121. package/es/components/anchor/index.vdt.js +31 -0
  122. package/es/components/anchor/link.d.ts +16 -0
  123. package/es/components/anchor/link.js +52 -0
  124. package/es/components/anchor/link.vdt.js +49 -0
  125. package/es/components/anchor/styles.d.ts +5 -0
  126. package/es/components/anchor/styles.js +30 -0
  127. package/es/components/anchor/useScroll.d.ts +7 -0
  128. package/es/components/anchor/useScroll.js +218 -0
  129. package/es/components/dialog/base.vdt.js +1 -1
  130. package/es/components/drawer/index.d.ts +3 -0
  131. package/es/components/drawer/index.js +22 -3
  132. package/es/components/drawer/index.spec.js +83 -0
  133. package/es/components/drawer/index.vdt.js +23 -3
  134. package/es/components/drawer/styles.js +1 -1
  135. package/es/components/drawer/useDrawerResizable.d.ts +10 -0
  136. package/es/components/drawer/useDrawerResizable.js +162 -0
  137. package/es/components/menu/styles.d.ts +1 -0
  138. package/es/components/menu/styles.js +4 -1
  139. package/es/components/notification/index.d.ts +1 -0
  140. package/es/components/notification/index.js +1 -0
  141. package/es/components/notification/index.spec.d.ts +1 -0
  142. package/es/components/notification/index.spec.js +317 -0
  143. package/es/components/notification/notification.d.ts +39 -0
  144. package/es/components/notification/notification.js +183 -0
  145. package/es/components/notification/notification.vdt.js +56 -0
  146. package/es/components/notification/notifications.d.ts +16 -0
  147. package/es/components/notification/notifications.js +51 -0
  148. package/es/components/notification/notifications.vdt.js +24 -0
  149. package/es/components/notification/styles.d.ts +9 -0
  150. package/es/components/notification/styles.js +110 -0
  151. package/es/components/select/styles.js +1 -1
  152. package/es/components/table/styles.js +1 -1
  153. package/es/components/tabs/useActiveBar.js +7 -3
  154. package/es/components/tag/base.d.ts +2 -0
  155. package/es/components/tag/base.js +3 -0
  156. package/es/components/tag/index.spec.js +17 -0
  157. package/es/components/tag/index.vdt.js +12 -5
  158. package/es/components/tag/styles.d.ts +9 -0
  159. package/es/components/tag/styles.js +14 -1
  160. package/es/components/tag/useColor.d.ts +7 -0
  161. package/es/components/tag/useColor.js +71 -0
  162. package/es/components/timepicker/index.spec.js +70 -42
  163. package/es/components/timepicker/useDefaultValue.js +12 -7
  164. package/es/components/timepicker/useStep.js +4 -2
  165. package/es/components/transfer/index.d.ts +13 -0
  166. package/es/components/transfer/index.js +6 -2
  167. package/es/components/transfer/index.spec.js +197 -0
  168. package/es/components/transfer/index.vdt.js +28 -5
  169. package/es/components/transfer/styles.js +4 -1
  170. package/es/components/transfer/useCheck.js +2 -1
  171. package/es/components/transfer/usePagination.d.ts +12 -0
  172. package/es/components/transfer/usePagination.js +79 -0
  173. package/es/index.d.ts +4 -2
  174. package/es/index.js +4 -2
  175. package/es/site/data/components/anchor/demos/basic/index.d.ts +11 -0
  176. package/es/site/data/components/anchor/demos/basic/index.js +18 -0
  177. package/es/site/data/components/anchor/demos/basic/react.d.ts +11 -0
  178. package/es/site/data/components/anchor/demos/basic/react.js +46 -0
  179. package/es/site/data/components/anchor/demos/container/index.d.ts +12 -0
  180. package/es/site/data/components/anchor/demos/container/index.js +19 -0
  181. package/es/site/data/components/anchor/demos/container/react.d.ts +12 -0
  182. package/es/site/data/components/anchor/demos/container/react.js +52 -0
  183. package/es/site/data/components/anchor/demos/events/index.d.ts +17 -0
  184. package/es/site/data/components/anchor/demos/events/index.js +36 -0
  185. package/es/site/data/components/anchor/demos/events/react.d.ts +17 -0
  186. package/es/site/data/components/anchor/demos/events/react.js +88 -0
  187. package/es/site/data/components/anchor/demos/horizontal/index.d.ts +11 -0
  188. package/es/site/data/components/anchor/demos/horizontal/index.js +18 -0
  189. package/es/site/data/components/anchor/demos/horizontal/react.d.ts +11 -0
  190. package/es/site/data/components/anchor/demos/horizontal/react.js +46 -0
  191. package/es/site/data/components/anchor/demos/nested/index.d.ts +12 -0
  192. package/es/site/data/components/anchor/demos/nested/index.js +19 -0
  193. package/es/site/data/components/anchor/demos/nested/react.d.ts +12 -0
  194. package/es/site/data/components/anchor/demos/nested/react.js +100 -0
  195. package/es/site/data/components/anchor/index.d.ts +57 -0
  196. package/es/site/data/components/anchor/index.js +32 -0
  197. package/es/site/data/components/config/demos/basic/index.d.ts +1 -0
  198. package/es/site/data/components/config/demos/basic/index.js +8 -1
  199. package/es/site/data/components/config/demos/basic/react.d.ts +1 -0
  200. package/es/site/data/components/config/demos/basic/react.js +15 -3
  201. package/es/site/data/components/drawer/demos/resizable/index.d.ts +15 -0
  202. package/es/site/data/components/drawer/demos/resizable/index.js +26 -0
  203. package/es/site/data/components/drawer/demos/resizable/react.d.ts +15 -0
  204. package/es/site/data/components/drawer/demos/resizable/react.js +63 -0
  205. package/es/site/data/components/icon/demos/icons/index.js +1 -1
  206. package/es/site/data/components/menu/demos/collapse/index.d.ts +6 -1
  207. package/es/site/data/components/menu/demos/collapse/react.d.ts +6 -1
  208. package/es/site/data/components/menu/demos/showCollapseArrow/index.d.ts +8 -1
  209. package/es/site/data/components/menu/demos/showCollapseArrow/react.d.ts +8 -1
  210. package/es/site/data/components/menu/demos/size/index.d.ts +7 -2
  211. package/es/site/data/components/menu/demos/size/react.d.ts +7 -2
  212. package/es/site/data/components/notification/demos/basic/index.d.ts +6 -0
  213. package/es/site/data/components/notification/demos/basic/index.js +21 -0
  214. package/es/site/data/components/notification/demos/basic/react.d.ts +5 -0
  215. package/es/site/data/components/notification/demos/basic/react.js +24 -0
  216. package/es/site/data/components/notification/demos/close/index.d.ts +13 -0
  217. package/es/site/data/components/notification/demos/close/index.js +38 -0
  218. package/es/site/data/components/notification/demos/close/react.d.ts +13 -0
  219. package/es/site/data/components/notification/demos/close/react.js +52 -0
  220. package/es/site/data/components/notification/demos/duration/index.d.ts +7 -0
  221. package/es/site/data/components/notification/demos/duration/index.js +33 -0
  222. package/es/site/data/components/notification/demos/duration/react.d.ts +6 -0
  223. package/es/site/data/components/notification/demos/duration/react.js +38 -0
  224. package/es/site/data/components/notification/demos/events/index.d.ts +6 -0
  225. package/es/site/data/components/notification/demos/events/index.js +31 -0
  226. package/es/site/data/components/notification/demos/events/react.d.ts +5 -0
  227. package/es/site/data/components/notification/demos/events/react.js +34 -0
  228. package/es/site/data/components/notification/demos/hideClose/index.d.ts +6 -0
  229. package/es/site/data/components/notification/demos/hideClose/index.js +25 -0
  230. package/es/site/data/components/notification/demos/hideClose/react.d.ts +5 -0
  231. package/es/site/data/components/notification/demos/hideClose/react.js +28 -0
  232. package/es/site/data/components/notification/demos/icon/index.d.ts +7 -0
  233. package/es/site/data/components/notification/demos/icon/index.js +33 -0
  234. package/es/site/data/components/notification/demos/icon/react.d.ts +6 -0
  235. package/es/site/data/components/notification/demos/icon/react.js +42 -0
  236. package/es/site/data/components/notification/demos/position/index.d.ts +9 -0
  237. package/es/site/data/components/notification/demos/position/index.js +27 -0
  238. package/es/site/data/components/notification/demos/position/react.d.ts +8 -0
  239. package/es/site/data/components/notification/demos/position/react.js +40 -0
  240. package/es/site/data/components/notification/demos/types/index.d.ts +9 -0
  241. package/es/site/data/components/notification/demos/types/index.js +26 -0
  242. package/es/site/data/components/notification/demos/types/react.d.ts +8 -0
  243. package/es/site/data/components/notification/demos/types/react.js +39 -0
  244. package/es/site/data/components/notification/index.d.ts +57 -0
  245. package/es/site/data/components/notification/index.js +32 -0
  246. package/es/site/data/components/table/demos/hidden/react.js +21 -3
  247. package/es/site/data/components/tag/demos/color/index.d.ts +10 -0
  248. package/es/site/data/components/tag/demos/color/index.js +19 -0
  249. package/es/site/data/components/tag/demos/color/react.d.ts +10 -0
  250. package/es/site/data/components/tag/demos/color/react.js +34 -0
  251. package/es/site/data/components/transfer/demos/pagination/index.d.ts +19 -0
  252. package/es/site/data/components/transfer/demos/pagination/index.js +42 -0
  253. package/es/site/data/components/transfer/demos/pagination/react.d.ts +20 -0
  254. package/es/site/data/components/transfer/demos/pagination/react.js +65 -0
  255. package/es/site/data/components/transfer/demos/table/index.d.ts +33 -0
  256. package/es/site/data/components/transfer/demos/table/index.js +132 -0
  257. package/es/site/data/components/transfer/demos/table/react.d.ts +35 -0
  258. package/es/site/data/components/transfer/demos/table/react.js +246 -0
  259. package/es/site/src/router/index.js +4 -33
  260. package/es/styles/fonts/iconfont.eot +0 -0
  261. package/es/styles/fonts/iconfont.js +1 -1
  262. package/es/styles/fonts/iconfont.svg +38 -0
  263. package/es/styles/fonts/iconfont.ttf +0 -0
  264. package/es/styles/fonts/iconfont.woff +0 -0
  265. package/es/styles/fonts/iconfont.woff2 +0 -0
  266. package/es/styles/theme.d.ts +8 -0
  267. package/es/styles/theme.js +5 -1
  268. package/index.ts +4 -2
  269. package/package.json +2 -2
  270. package/styles/.DS_Store +0 -0
  271. package/styles/fonts/demo_index.html +443 -6
  272. package/styles/fonts/iconfont.css +82 -6
  273. package/styles/fonts/iconfont.eot +0 -0
  274. package/styles/fonts/iconfont.js +1 -1
  275. package/styles/fonts/iconfont.json +133 -0
  276. package/styles/fonts/iconfont.svg +38 -0
  277. package/styles/fonts/iconfont.ts +76 -0
  278. package/styles/fonts/iconfont.ttf +0 -0
  279. package/styles/fonts/iconfont.woff +0 -0
  280. package/styles/fonts/iconfont.woff2 +0 -0
  281. package/styles/theme.ts +4 -0
@@ -27,7 +27,7 @@ describe('Timepicker', () => {
27
27
 
28
28
  const dropdown = getElement('.k-time-content')!;
29
29
  const ok = dropdown.querySelector('.k-btn') as HTMLElement;
30
- expect(ok.classList.contains('k-disabled')).eql(true);
30
+ expect(ok.classList.contains('k-disabled')).eql(false);
31
31
  expect(dropdown.innerHTML).to.matchSnapshot();
32
32
 
33
33
  const next = dropdown.querySelector('.k-scroll-select-item:nth-child(11)') as HTMLElement;
@@ -41,7 +41,7 @@ describe('Timepicker', () => {
41
41
  expect(dropdown.innerHTML).to.matchSnapshot();
42
42
  ok.click();
43
43
  await wait(500);
44
- expect(instance.get('time')).to.eql('02:00:00');
44
+ expect(instance.get('time')).to.eql('03:34:56');
45
45
  expect(dropdown.style.display).to.eql('none');
46
46
  // set time
47
47
  instance.set('time', '03:03:03');
@@ -245,7 +245,18 @@ describe('Timepicker', () => {
245
245
  await wait();
246
246
  expect(dropdown.innerHTML).to.matchSnapshot();
247
247
  dropdown.querySelector<HTMLElement>('.k-btn')!.click();
248
- expect(instance.get('time')).to.eql(['00:30:00', '23:30:00']);
248
+ expect(instance.get('time')).to.eql(['00:30:00', '23:00:00']);
249
+ });
250
+
251
+ it('should not have 23:59:59 in step mode without max', async () => {
252
+ const [instance, element] = mount(StepRangeDemo);
253
+ const picker = element.querySelector('.k-select') as HTMLElement;
254
+ picker.click();
255
+ await wait();
256
+ const dropdown = getElement('.k-time-content')!;
257
+ const options = dropdown.querySelectorAll('k-scroll-select-item');
258
+ const texts = Array.from(options).map(el => (el as HTMLElement).innerText.trim());
259
+ expect(texts).to.not.include('23:59:59');
249
260
  });
250
261
 
251
262
  it('format', async () => {
@@ -261,7 +272,7 @@ describe('Timepicker', () => {
261
272
  await wait();
262
273
  content.querySelector<HTMLElement>('.k-btn')!.click();
263
274
  await wait();
264
- expect(instance.get('time1')).to.eql('02:00 am');
275
+ expect(instance.get('time1')).to.eql('03:34 am');
265
276
  expect(input1.innerHTML).to.matchSnapshot();
266
277
 
267
278
  input2.click();
@@ -302,7 +313,7 @@ describe('Timepicker', () => {
302
313
  private Timepicker = Timepicker;
303
314
  }
304
315
 
305
- const [instance, element] = mount(Demo);
316
+ const [instance, element] = mount(Demo as any);
306
317
  const [
307
318
  basicInput, multipleInput,
308
319
  rangeInput, formatInput
@@ -9,16 +9,25 @@ export function useDefaultValue() {
9
9
  const instance = useInstance() as PanelPicker;
10
10
 
11
11
  function get(): StateValueItem {
12
- const _value = instance.value.value.value;
13
- const lastValue = last(_value);
14
- const { range } = instance.get();
12
+ const { range, min, max } = instance.get();
13
+ const _value = instance.value?.value.value || [];
14
+ const options = instance.step?.options.value;
15
+
16
+ // 优先级:用户选择值 > step 选项首尾 > min/max 属性 > 全局默认值
17
+ const hasOptions = options && options.length;
18
+ const start = hasOptions
19
+ ? instance.formats.createDateByValueFormat(options![0].value)
20
+ : (min ? instance.formats.createDateByValueFormat(min) : NOW_START);
21
+
22
+ const end = hasOptions
23
+ ? instance.formats.createDateByValueFormat(options![options!.length - 1].value)
24
+ : (max ? instance.formats.createDateByValueFormat(max) : NOW_END);
15
25
 
16
26
  if (range) {
17
- // consider the second last value to maintain consistency
18
- const penulimate = getPenulimate(_value);
19
- return Object.assign([NOW_START, NOW_END], penulimate, lastValue);
27
+ return Object.assign([start, end], getPenulimate(_value), last(_value));
20
28
  }
21
- return lastValue || NOW_START;
29
+
30
+ return last(_value) || start;
22
31
  }
23
32
 
24
33
  return { get };
@@ -24,7 +24,7 @@ export function useStep(
24
24
  useReceive<StepComponent>(['step', 'min', 'max'], generateOptions);
25
25
 
26
26
  function generateOptions() {
27
- const {step} = instance.get();
27
+ const {step, max} = instance.get();
28
28
 
29
29
  if (step) {
30
30
  const data: Option[] = [];
@@ -43,7 +43,8 @@ export function useStep(
43
43
  if (value <= maxValue) {
44
44
  push(value);
45
45
  if (+value === +maxValue) break;
46
- } else if (data.length) {
46
+ } else if (data.length && max !== undefined) {
47
+ // unless max is undefined, it means the max is not set, so we don't need to add the maxValue to the last
47
48
  // it the last value is less than maxValue,
48
49
  // add the maxValue to the last
49
50
  push(maxValue);
Binary file
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 自定义搜索
3
- order: 1.1
3
+ order: 2
4
4
  ---
5
5
 
6
6
  我们可以通过`filter`扩展点自定义搜索内容,而且通过该扩展点的参数`type`,可以给左侧/右侧/两侧
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 完全自定义
3
- order: 3
3
+ order: 4
4
4
  ---
5
5
 
6
6
  本例展示如何利用`Transfer`自定义更复杂的应用场景,本例中我们通过`list`扩展点定义整个列表,并且根据扩展点参数
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 获取已选择的数据
3
- order: 7
3
+ order: 8
4
4
  ---
5
5
 
6
6
  通过`getData()`方法可以获取已选择的节点的数据。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 控制选择项
3
- order: 2
3
+ order: 3
4
4
  ---
5
5
 
6
6
  通过`leftCheckedKeys`属性,我们可以控制左侧已选项,`rightCheckedKeys`同理
@@ -0,0 +1,63 @@
1
+ ---
2
+ title: 分页
3
+ order: 5
4
+ ---
5
+
6
+ 数据量大时,给组件添加`pagination`属性即可开启分页功能,当改变页码或每页数量时会触发`page`事件。
7
+
8
+ ```vdt
9
+ import {Transfer} from 'kpc';
10
+
11
+ <div>
12
+ <Transfer v-model="value"
13
+ data={this.get('data')}
14
+ pagination
15
+ filterable
16
+ filter={this.customFilter}
17
+ ev-page={this.onChangePage}
18
+ ref="__test"
19
+ />
20
+ <p>{ `You selected: [${this.get('value').join(', ')}]` }</p>
21
+ </div>
22
+ ```
23
+
24
+ ```ts
25
+ import {range, bind} from 'kpc/components/utils';
26
+ import type {TransferDataItem} from 'kpc';
27
+
28
+ interface Props {
29
+ data: TransferDataItem[]
30
+ value?: number[]
31
+ }
32
+
33
+ const data: TransferDataItem[] = range(1, 100).map(item => {
34
+ return {
35
+ label: `主机名${item}`,
36
+ key: item
37
+ };
38
+ });
39
+
40
+ export default class extends Component<Props> {
41
+ static template = template;
42
+
43
+ static defaults() {
44
+ return {
45
+ data: data,
46
+ value: []
47
+ }
48
+ }
49
+
50
+ @bind
51
+ onChangePage(model: 'left' | 'right', data: { value: number, limit: number }) {
52
+ console.log(`${model} panel: page ${data.value}, limit ${data.limit}`);
53
+ }
54
+
55
+ @bind
56
+ customFilter(item: TransferDataItem, keywords: string) {
57
+ const label = item.label as string;
58
+ const matchKeywords = label.toLowerCase().includes(keywords.toLowerCase());
59
+ return matchKeywords;
60
+ }
61
+ }
62
+ ```
63
+
@@ -0,0 +1,248 @@
1
+ ---
2
+ title: 与表格控件结合
3
+ order: 7
4
+ ---
5
+
6
+ 与【完全自定义】示例一样,`Transfer`也可以与`Table`结合使用。当需要在表格中展示数据并支持分页和筛选时,可以在`b:list`插槽中使用带分页的`Table`组件,并且在`b:filter`扩展点自定义筛选输入框,实现筛选逻辑。
7
+
8
+ ```vdt
9
+ import {Transfer, Table, TableColumn, Input, Icon} from 'kpc';
10
+
11
+ <Transfer
12
+ filterable
13
+ enableAdd={this.enableAdd}
14
+ enableRemove={this.enableRemove}
15
+ ev-add={this.onAdd}
16
+ ev-remove={this.onRemove}
17
+ class="custom-table-transfer"
18
+ >
19
+ <b:header args="type">
20
+ <div v-if={type === 'left'}>
21
+ <span>可选数据</span>
22
+ <span>{ this.get('leftCheckedKeys').length + ' / ' + this.get('leftData').length }</span>
23
+ </div>
24
+ <div v-else>
25
+ <span>已选数据</span>
26
+ <span>{ this.get('rightCheckedKeys').length + ' / ' + this.get('rightData').length }</span>
27
+ </div>
28
+ </b:header>
29
+ <b:filter args="type">
30
+ <Input v-if={type === 'left'}
31
+ placeholder="搜索名称、IP或状态"
32
+ clearable
33
+ size="small"
34
+ value={this.get('leftKeywords')}
35
+ ev-$change:value={this.onLeftKeywordsChange}
36
+ >
37
+ <b:prefix>
38
+ <Icon class="k-icon-search" size="small" />
39
+ </b:prefix>
40
+ </Input>
41
+ <Input v-else
42
+ placeholder="搜索名称、IP或状态"
43
+ clearable
44
+ size="small"
45
+ value={this.get('rightKeywords')}
46
+ ev-$change:value={this.onRightKeywordsChange}
47
+ >
48
+ <b:prefix>
49
+ <Icon class="k-icon-search" size="small" />
50
+ </b:prefix>
51
+ </Input>
52
+ </b:filter>
53
+ <b:list args="type">
54
+ <Table v-if={type === 'left'}
55
+ data={this.get('leftFilteredData')}
56
+ rowKey={item => item.id}
57
+ checkedKeys={this.get('leftCheckedKeys')}
58
+ ev-$change:checkedKeys={this.onLeftCheckedKeysChange}
59
+ pagination={{limit: 5, showLimits: false, showTotal: false}}
60
+ ref="leftTable"
61
+ fixHeader
62
+ >
63
+ <TableColumn key="name" title="名称" />
64
+ <TableColumn key="ip" title="IP地址" />
65
+ <TableColumn key="status" title="状态" />
66
+ </Table>
67
+ <Table v-else
68
+ data={this.get('rightFilteredData')}
69
+ rowKey={item => item.id}
70
+ checkedKeys={this.get('rightCheckedKeys')}
71
+ ev-$change:checkedKeys={this.onRightCheckedKeysChange}
72
+ pagination={{limit: 5, showLimits: false, showTotal: false}}
73
+ ref="rightTable"
74
+ fixHeader
75
+ >
76
+ <TableColumn key="name" title="名称" />
77
+ <TableColumn key="ip" title="IP地址" />
78
+ <TableColumn key="status" title="状态" />
79
+ </Table>
80
+ </b:list>
81
+ </Transfer>
82
+ ```
83
+
84
+ ```styl
85
+ .custom-table-transfer
86
+ .k-transfer-panel
87
+ width 320px
88
+ .k-transfer-title
89
+ div
90
+ display flex
91
+ justify-content space-between
92
+ .k-input
93
+ margin 8px 16px
94
+ .k-table-wrapper
95
+ max-height 228px
96
+ table
97
+ thead
98
+ tr
99
+ th
100
+ background #fff
101
+ .k-table
102
+ .k-pagination
103
+ display flex
104
+ justify-content flex-end
105
+ align-items center
106
+ margin 8px 0
107
+ ```
108
+
109
+ ```ts
110
+ import {bind, Table, TableColumn} from 'kpc';
111
+ import {range} from 'kpc/components/utils';
112
+
113
+ interface Props {
114
+ allData: DataItem[]
115
+ leftData: DataItem[]
116
+ rightData: DataItem[]
117
+ leftCheckedKeys: number[]
118
+ rightCheckedKeys: number[]
119
+ leftKeywords: string
120
+ rightKeywords: string
121
+ leftFilteredData: DataItem[]
122
+ rightFilteredData: DataItem[]
123
+ }
124
+
125
+ type DataItem = {
126
+ id: number
127
+ name: string
128
+ ip: string
129
+ status: string
130
+ }
131
+
132
+ const rawData = range(1, 50).map(item => ({
133
+ id: item,
134
+ name: `服务器${item}`,
135
+ ip: `10.10.1.${item}`,
136
+ status: item % 3 === 0 ? '运行中' : item % 3 === 1 ? '已停止' : '维护中'
137
+ }));
138
+
139
+ export default class extends Component<Props> {
140
+ static template = template;
141
+
142
+ static defaults() {
143
+ return {
144
+ allData: rawData,
145
+ leftData: rawData,
146
+ rightData: [],
147
+ leftCheckedKeys: [],
148
+ rightCheckedKeys: [],
149
+ leftKeywords: '',
150
+ rightKeywords: '',
151
+ leftFilteredData: rawData,
152
+ rightFilteredData: [],
153
+ } as Props;
154
+ }
155
+
156
+ filterData(data: DataItem[], keywords: string): DataItem[] {
157
+ if (!keywords) return data;
158
+ const lowerKeywords = keywords.toLowerCase();
159
+ return data.filter((item: DataItem) =>
160
+ item.name.toLowerCase().includes(lowerKeywords) ||
161
+ item.ip.includes(keywords) ||
162
+ item.status.includes(keywords)
163
+ );
164
+ }
165
+
166
+ @bind
167
+ onLeftKeywordsChange(v: string | undefined) {
168
+ const keywords = v || '';
169
+ this.set('leftKeywords', keywords);
170
+ const data = this.filterData(this.get('leftData'), keywords);
171
+ this.set('leftFilteredData', data);
172
+ }
173
+
174
+ @bind
175
+ onRightKeywordsChange(v: string | undefined) {
176
+ const keywords = v || '';
177
+ this.set('rightKeywords', keywords);
178
+ const data = this.filterData(this.get('rightData'), keywords);
179
+ this.set('rightFilteredData', data);
180
+ }
181
+
182
+ @bind
183
+ onLeftCheckedKeysChange(keys: number[] | undefined) {
184
+ this.set('leftCheckedKeys', keys || []);
185
+ }
186
+
187
+ @bind
188
+ onRightCheckedKeysChange(keys: number[] | undefined) {
189
+ this.set('rightCheckedKeys', keys || []);
190
+ }
191
+
192
+ @bind
193
+ enableAdd() {
194
+ const keys = this.get('leftCheckedKeys');
195
+ return keys && keys.length > 0;
196
+ }
197
+
198
+ @bind
199
+ enableRemove() {
200
+ const keys = this.get('rightCheckedKeys');
201
+ return keys && keys.length > 0;
202
+ }
203
+
204
+ @bind
205
+ onAdd() {
206
+ const leftCheckedKeys = this.get('leftCheckedKeys');
207
+ const leftData = this.get('leftData');
208
+ const rightData = this.get('rightData');
209
+
210
+ const selectedItems = leftData.filter((item: DataItem) => leftCheckedKeys.includes(item.id));
211
+ const newLeftData = leftData.filter((item: DataItem) => !leftCheckedKeys.includes(item.id));
212
+ const newRightData = [...rightData, ...selectedItems];
213
+
214
+ this.set({
215
+ leftData: newLeftData,
216
+ rightData: newRightData,
217
+ leftCheckedKeys: [],
218
+ });
219
+
220
+ const leftFiltered = this.filterData(newLeftData, this.get('leftKeywords'));
221
+ const rightFiltered = this.filterData(newRightData, this.get('rightKeywords'));
222
+ this.set('leftFilteredData', leftFiltered);
223
+ this.set('rightFilteredData', rightFiltered);
224
+ }
225
+
226
+ @bind
227
+ onRemove() {
228
+ const rightCheckedKeys = this.get('rightCheckedKeys');
229
+ const allData = this.get('allData');
230
+ const rightData = this.get('rightData');
231
+
232
+ const newRightData = rightData.filter((item: DataItem) => !rightCheckedKeys.includes(item.id));
233
+ const rightDataIds = new Set(newRightData.map((item: DataItem) => item.id));
234
+ const newLeftData = allData.filter((item: DataItem) => !rightDataIds.has(item.id));
235
+
236
+ this.set({
237
+ leftData: newLeftData,
238
+ rightData: newRightData,
239
+ rightCheckedKeys: [],
240
+ });
241
+
242
+ const leftFiltered = this.filterData(newLeftData, this.get('leftKeywords'));
243
+ const rightFiltered = this.filterData(newRightData, this.get('rightKeywords'));
244
+ this.set('leftFilteredData', leftFiltered);
245
+ this.set('rightFilteredData', rightFiltered);
246
+ }
247
+ }
248
+ ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: 与树形控件结合
3
- order: 4
3
+ order: 6
4
4
  ---
5
5
 
6
6
  与【完全自定义】示例一样,`Transfer`也可以与`Tree`结合使用
@@ -24,6 +24,7 @@ sidebar: doc
24
24
  | rightTitle | 右边顶部展示的标题 | `string` &#124; `VNode` | `"已选择"` |
25
25
  | enableAdd | 指定右箭头按钮的可用状态 | `() => boolean` | `undefined` |
26
26
  | enableRemove | 指定左箭头按钮的可用状态 | `() => boolean` | `undefined` |
27
+ | pagination | 是否启用分页功能,传入`true`使用默认配置,传入对象可自定义分页配置,详见[Pagination组件](/components/pagination/) | `boolean` &#124; `PaginationProps` | `false` |
27
28
 
28
29
  ```ts
29
30
  export type TransferDataItem<
@@ -60,3 +61,4 @@ export type TransferDataItem<
60
61
  | --- | --- | --- |
61
62
  | add | 右箭头按钮点击事件 | - |
62
63
  | remove | 左箭头按钮点击事件 | - |
64
+ | page | 当内置翻页改变页码或每页数量时触发 | <code>(model: 'left' &#124; 'right', data: {value: number, limit: number}) => void</code> |
@@ -1,5 +1,6 @@
1
1
  import BasicDemo from '~/components/transfer/demos/basic';
2
2
  import LabelDemo from '~/components/transfer/demos/label';
3
+ import PaginationDemo from '~/components/transfer/demos/pagination';
3
4
  import {mount, unmount, dispatchEvent, wait} from '../../test/utils';
4
5
  import type {Transfer} from './';
5
6
 
@@ -128,4 +129,150 @@ describe('Transfer', () => {
128
129
  await wait(500);
129
130
  expect(element.innerHTML).to.matchSnapshot();
130
131
  });
132
+
133
+ it('pagination', async function() {
134
+ this.timeout(0);
135
+ const [instance, element] = mount(PaginationDemo as any);
136
+ await wait();
137
+ const transfer = instance.refs.__test as Transfer;
138
+
139
+ // 快照:初始状态(第1页)
140
+ expect(element.outerHTML).to.matchSnapshot();
141
+ // 测试1: 分页器存在
142
+ const pagination = element.querySelector('.k-transfer-pagination-wrapper .k-pagination');
143
+ expect(pagination).to.be.ok;
144
+ // 测试2: 第一页显示的数据(默认 limit=10,显示前10条)
145
+ const leftItems = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
146
+ expect(leftItems.length).to.eql(10);
147
+ // 验证显示的是前10条数据
148
+ const firstItem = leftItems[0].querySelector('.k-checkbox') as HTMLElement;
149
+ expect(firstItem.textContent).to.include('主机名1');
150
+ // 测试3: 点击下一页
151
+ const nextButton = element.querySelector('.k-transfer-pagination-wrapper .k-pagination .k-pagination-next') as HTMLElement;
152
+ if (nextButton && !nextButton.classList.contains('k-disabled')) {
153
+ nextButton.click();
154
+ await wait(500);
155
+ // 快照:第2页
156
+ expect(element.outerHTML).to.matchSnapshot();
157
+ // 验证显示的是第11-20条数据
158
+ const leftItemsPage2 = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
159
+ expect(leftItemsPage2.length).to.eql(10);
160
+ const firstItemPage2 = leftItemsPage2[0].querySelector('.k-checkbox') as HTMLElement;
161
+ expect(firstItemPage2.textContent).to.include('主机名11');
162
+ }
163
+ // 测试4: 设置关键词进行筛选,验证页码重置为1
164
+ // 先翻到第2页
165
+ const nextButton2 = element.querySelector('.k-transfer-pagination-wrapper .k-pagination .k-pagination-next') as HTMLElement;
166
+ if (nextButton2 && !nextButton2.classList.contains('k-disabled')) {
167
+ nextButton2.click();
168
+ await wait(500);
169
+ }
170
+ // 设置关键词,应该重置到第1页
171
+ transfer.set('leftKeywords', '1');
172
+ await wait(500);
173
+ // 快照:筛选后(第1页)
174
+ expect(element.outerHTML).to.matchSnapshot();
175
+ // 验证筛选后的数据(应该显示第1页的筛选结果)
176
+ const filteredItems = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
177
+ // 筛选包含'1'的数据,应该少于或等于10条
178
+ expect(filteredItems.length).to.be.at.most(10);
179
+ // 验证所有显示的数据都包含'1'
180
+ filteredItems.forEach((item) => {
181
+ const text = item.textContent || '';
182
+ expect(text).to.match(/主机名\d*1\d*/);
183
+ });
184
+ // 测试5: 清除筛选后恢复分页
185
+ transfer.set('leftKeywords', '');
186
+ await wait(500);
187
+ // 快照:清除筛选后(恢复第1页)
188
+ expect(element.outerHTML).to.matchSnapshot();
189
+ const restoredItems = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
190
+ expect(restoredItems.length).to.eql(10);
191
+ });
192
+
193
+ it('pagination with filter', async function() {
194
+ this.timeout(0);
195
+ const [instance, element] = mount(PaginationDemo as any);
196
+ await wait();
197
+ const transfer = instance.refs.__test as Transfer;
198
+
199
+ // 测试筛选后分页数据立即更新
200
+ transfer.set('leftKeywords', '2');
201
+ await wait(500);
202
+ // 快照:筛选后(第1页)
203
+ expect(element.outerHTML).to.matchSnapshot();
204
+ // 验证筛选后的数据立即显示
205
+ const filteredItems = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
206
+ // 所有显示的数据应该包含'2'
207
+ filteredItems.forEach((item) => {
208
+ const text = item.textContent || '';
209
+ expect(text).to.match(/主机名\d*2\d*/);
210
+ });
211
+
212
+ // 测试筛选后切换页面
213
+ const nextButton = element.querySelector('.k-transfer-pagination-wrapper .k-pagination .k-pagination-next') as HTMLElement;
214
+ if (nextButton && !nextButton.classList.contains('k-disabled')) {
215
+ nextButton.click();
216
+ await wait(500);
217
+ // 快照:筛选后第2页
218
+ expect(element.outerHTML).to.matchSnapshot();
219
+ // 验证第二页的数据也包含'2'
220
+ const page2Items = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
221
+ page2Items.forEach((item) => {
222
+ const text = item.textContent || '';
223
+ expect(text).to.match(/主机名\d*2\d*/);
224
+ });
225
+ }
226
+ // 清除筛选
227
+ transfer.set('leftKeywords', '');
228
+ await wait(500);
229
+ // 快照:清除筛选后(恢复第1页)
230
+ expect(element.outerHTML).to.matchSnapshot();
231
+ // 验证清除筛选后显示所有数据的第一页
232
+ const restoredItems = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
233
+ expect(restoredItems.length).to.eql(10);
234
+ });
235
+
236
+ it('pagination with checkbox selection', async function() {
237
+ this.timeout(0);
238
+ const [instance, element] = mount(PaginationDemo as any);
239
+ await wait();
240
+ const transfer = instance.refs.__test as Transfer;
241
+
242
+ // 测试1: 全选基于全部数据
243
+ const checkAll = element.querySelector('.k-transfer-title .k-checkbox') as HTMLElement;
244
+ checkAll.click();
245
+ await wait();
246
+ // 快照:全选后(第1页)
247
+ expect(element.outerHTML).to.matchSnapshot();
248
+ const leftCheckedKeys = transfer.get('leftCheckedKeys') as number[];
249
+ expect(leftCheckedKeys.length).to.eql(100);
250
+
251
+ // 测试2: 切换页面时保持选中状态
252
+ const nextButton = element.querySelector('.k-transfer-pagination-wrapper .k-pagination .k-pagination-next') as HTMLElement;
253
+ if (nextButton && !nextButton.classList.contains('k-disabled')) {
254
+ nextButton.click();
255
+ await wait(500);
256
+ // 快照:全选后切换到第2页(选中状态保持)
257
+ expect(element.outerHTML).to.matchSnapshot();
258
+ // 切换到第2页后,选中状态应该保持
259
+ const leftCheckedKeysAfterPageChange = transfer.get('leftCheckedKeys') as number[];
260
+ expect(leftCheckedKeysAfterPageChange.length).to.eql(100);
261
+
262
+ // 验证第2页的checkbox状态(应该都是选中的)
263
+ const page2Items = element.querySelectorAll('.k-transfer-panel:first-child .k-transfer-item');
264
+ page2Items.forEach((item) => {
265
+ const checkbox = item.querySelector('input[type="checkbox"]') as HTMLInputElement;
266
+ expect(checkbox.checked).to.be.true;
267
+ });
268
+ }
269
+
270
+ // 测试3: 取消全选
271
+ checkAll.click();
272
+ await wait();
273
+ // 快照:取消全选后
274
+ expect(element.outerHTML).to.matchSnapshot();
275
+ const leftCheckedKeysAfterUncheck = transfer.get('leftCheckedKeys') as number[];
276
+ expect(leftCheckedKeysAfterUncheck.length).to.eql(0);
277
+ });
131
278
  });