@king-design/intact 3.5.1 → 3.6.0-beta.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 (227) hide show
  1. package/components/breadcrumb/demos/separator.md +4 -4
  2. package/components/breadcrumb/index.vdt +1 -1
  3. package/components/breadcrumb/styles.ts +3 -2
  4. package/components/button/index.md +1 -0
  5. package/components/datepicker/basepicker.ts +60 -13
  6. package/components/datepicker/calendar.ts +5 -1
  7. package/components/datepicker/calendar.vdt +20 -6
  8. package/components/datepicker/dayjs.ts +22 -2
  9. package/components/datepicker/demos/multiple.md +0 -5
  10. package/components/datepicker/demos/nowrap.md +35 -0
  11. package/components/datepicker/demos/yearMonth.md +8 -2
  12. package/components/datepicker/helpers.ts +5 -5
  13. package/components/datepicker/index.md +3 -2
  14. package/components/datepicker/index.spec.ts +107 -90
  15. package/components/datepicker/index.ts +23 -5
  16. package/components/datepicker/index.vdt +34 -35
  17. package/components/datepicker/styles.ts +102 -3
  18. package/components/datepicker/useDisabled.ts +3 -3
  19. package/components/datepicker/useFormats.ts +2 -0
  20. package/components/datepicker/useMergeRange.ts +54 -0
  21. package/components/datepicker/usePosition.ts +169 -0
  22. package/components/datepicker/useQuarters.ts +47 -0
  23. package/components/datepicker/useShowDate.ts +42 -11
  24. package/components/datepicker/useValue.ts +35 -4
  25. package/components/datepicker/useWeeks.ts +58 -0
  26. package/components/dialog/useFixBody.ts +7 -64
  27. package/components/ellipsis/styles.ts +4 -0
  28. package/components/form/styles.ts +1 -0
  29. package/components/scrollSelect/index.spec.ts +3 -3
  30. package/components/scrollSelect/useMouseEvents.ts +23 -10
  31. package/components/select/base.vdt +2 -1
  32. package/components/select/demos/creatable.md +13 -0
  33. package/components/select/index.md +1 -0
  34. package/components/select/index.spec.ts +180 -0
  35. package/components/select/option.ts +9 -1
  36. package/components/select/select.ts +2 -0
  37. package/components/select/useFilterable.ts +1 -1
  38. package/components/select/useInput.ts +4 -2
  39. package/components/select/useSearchable.ts +2 -2
  40. package/components/table/table.vdt +3 -3
  41. package/components/timepicker/demos/step.md +1 -1
  42. package/components/timepicker/panelPicker.vdt +5 -1
  43. package/components/timepicker/styles.ts +0 -1
  44. package/components/tour/demos/basic.md +73 -0
  45. package/components/tour/demos/beforeChange.md +109 -0
  46. package/components/tour/demos/closable.md +70 -0
  47. package/components/tour/demos/custom.md +98 -0
  48. package/components/tour/demos/customText.md +94 -0
  49. package/components/tour/demos/declarative.md +72 -0
  50. package/components/tour/demos/events.md +101 -0
  51. package/components/tour/demos/maskClosable.md +76 -0
  52. package/components/tour/demos/notarget.md +59 -0
  53. package/components/tour/index.md +48 -0
  54. package/components/tour/index.spec.ts +259 -0
  55. package/components/tour/index.ts +2 -0
  56. package/components/tour/step.ts +55 -0
  57. package/components/tour/step.vdt +75 -0
  58. package/components/tour/styles.ts +283 -0
  59. package/components/tour/tour.ts +107 -0
  60. package/components/tour/tour.vdt +83 -0
  61. package/components/tour/useArrow.ts +46 -0
  62. package/components/tour/useFixBody.ts +22 -0
  63. package/components/tour/useHighlight.ts +36 -0
  64. package/components/tour/useMaskClosable.ts +26 -0
  65. package/components/tour/useNavigation.ts +46 -0
  66. package/components/tour/usePosition.ts +91 -0
  67. package/components/tour/useSteps.ts +80 -0
  68. package/components/tree/useChecked.ts +6 -4
  69. package/components/treeSelect/index.spec.ts +13 -1
  70. package/components/virtualList/useVirtualRows.ts +1 -1
  71. package/es/components/breadcrumb/index.vdt.js +2 -1
  72. package/es/components/breadcrumb/styles.js +5 -3
  73. package/es/components/datepicker/basepicker.d.ts +4 -2
  74. package/es/components/datepicker/basepicker.js +46 -13
  75. package/es/components/datepicker/calendar.d.ts +34 -6
  76. package/es/components/datepicker/calendar.js +4 -0
  77. package/es/components/datepicker/calendar.vdt.js +21 -5
  78. package/es/components/datepicker/dayjs.d.ts +13 -2
  79. package/es/components/datepicker/dayjs.js +6 -0
  80. package/es/components/datepicker/helpers.d.ts +5 -5
  81. package/es/components/datepicker/index.d.ts +17 -2
  82. package/es/components/datepicker/index.js +23 -5
  83. package/es/components/datepicker/index.spec.js +356 -355
  84. package/es/components/datepicker/index.vdt.js +25 -29
  85. package/es/components/datepicker/styles.d.ts +17 -0
  86. package/es/components/datepicker/styles.js +29 -2
  87. package/es/components/datepicker/useDisabled.d.ts +2 -2
  88. package/es/components/datepicker/useDisabled.js +1 -1
  89. package/es/components/datepicker/useFormats.js +3 -1
  90. package/es/components/datepicker/useMergeRange.d.ts +5 -0
  91. package/es/components/datepicker/useMergeRange.js +50 -0
  92. package/es/components/datepicker/usePosition.d.ts +10 -0
  93. package/es/components/datepicker/usePosition.js +166 -0
  94. package/es/components/datepicker/useQuarters.d.ts +15 -0
  95. package/es/components/datepicker/useQuarters.js +36 -0
  96. package/es/components/datepicker/useShowDate.d.ts +1 -1
  97. package/es/components/datepicker/useShowDate.js +42 -9
  98. package/es/components/datepicker/useStatus.d.ts +1 -1
  99. package/es/components/datepicker/useValue.d.ts +1 -0
  100. package/es/components/datepicker/useValue.js +26 -2
  101. package/es/components/datepicker/useWeeks.d.ts +19 -0
  102. package/es/components/datepicker/useWeeks.js +48 -0
  103. package/es/components/dialog/useFixBody.js +6 -58
  104. package/es/components/ellipsis/styles.js +1 -1
  105. package/es/components/form/styles.js +1 -1
  106. package/es/components/scrollSelect/index.spec.js +4 -6
  107. package/es/components/scrollSelect/useMouseEvents.js +21 -9
  108. package/es/components/select/base.vdt.js +4 -2
  109. package/es/components/select/index.spec.js +269 -42
  110. package/es/components/select/option.d.ts +1 -0
  111. package/es/components/select/option.js +9 -2
  112. package/es/components/select/select.d.ts +1 -0
  113. package/es/components/select/select.js +2 -1
  114. package/es/components/select/useFilterable.js +2 -1
  115. package/es/components/select/useInput.js +5 -2
  116. package/es/components/select/useSearchable.js +1 -0
  117. package/es/components/table/table.vdt.js +4 -2
  118. package/es/components/timepicker/panelPicker.d.ts +2 -1
  119. package/es/components/timepicker/panelPicker.vdt.js +12 -4
  120. package/es/components/timepicker/selectPicker.d.ts +1 -1
  121. package/es/components/timepicker/styles.js +1 -1
  122. package/es/components/timepicker/useDisabled.d.ts +1 -1
  123. package/es/components/timepicker/useValue.d.ts +1 -0
  124. package/es/components/tour/index.d.ts +2 -0
  125. package/es/components/tour/index.js +2 -0
  126. package/es/components/tour/index.spec.d.ts +1 -0
  127. package/es/components/tour/index.spec.js +356 -0
  128. package/es/components/tour/step.d.ts +23 -0
  129. package/es/components/tour/step.js +46 -0
  130. package/es/components/tour/step.vdt.js +74 -0
  131. package/es/components/tour/styles.d.ts +7 -0
  132. package/es/components/tour/styles.js +84 -0
  133. package/es/components/tour/tour.d.ts +73 -0
  134. package/es/components/tour/tour.js +70 -0
  135. package/es/components/tour/tour.vdt.js +66 -0
  136. package/es/components/tour/useArrow.d.ts +4 -0
  137. package/es/components/tour/useArrow.js +40 -0
  138. package/es/components/tour/useFixBody.d.ts +4 -0
  139. package/es/components/tour/useFixBody.js +17 -0
  140. package/es/components/tour/useHighlight.d.ts +4 -0
  141. package/es/components/tour/useHighlight.js +31 -0
  142. package/es/components/tour/useMaskClosable.d.ts +1 -0
  143. package/es/components/tour/useMaskClosable.js +25 -0
  144. package/es/components/tour/useNavigation.d.ts +5 -0
  145. package/es/components/tour/useNavigation.js +103 -0
  146. package/es/components/tour/usePosition.d.ts +6 -0
  147. package/es/components/tour/usePosition.js +93 -0
  148. package/es/components/tour/useSteps.d.ts +6 -0
  149. package/es/components/tour/useSteps.js +68 -0
  150. package/es/components/tree/useChecked.js +6 -4
  151. package/es/components/treeSelect/index.spec.js +20 -5
  152. package/es/components/virtualList/useVirtualRows.js +1 -1
  153. package/es/hooks/useDocumentClick.js +3 -3
  154. package/es/hooks/useFixBody.d.ts +11 -0
  155. package/es/hooks/useFixBody.js +72 -0
  156. package/es/index.d.ts +3 -2
  157. package/es/index.js +3 -2
  158. package/es/site/data/components/breadcrumb/demos/separator/react.js +7 -5
  159. package/es/site/data/components/datepicker/demos/multiple/index.d.ts +0 -1
  160. package/es/site/data/components/datepicker/demos/multiple/index.js +1 -2
  161. package/es/site/data/components/datepicker/demos/multiple/react.d.ts +0 -1
  162. package/es/site/data/components/datepicker/demos/multiple/react.js +2 -13
  163. package/es/site/data/components/datepicker/demos/nowrap/index.d.ts +10 -0
  164. package/es/site/data/components/datepicker/demos/nowrap/index.js +19 -0
  165. package/es/site/data/components/datepicker/demos/nowrap/react.d.ts +10 -0
  166. package/es/site/data/components/datepicker/demos/nowrap/react.js +49 -0
  167. package/es/site/data/components/datepicker/demos/yearMonth/index.d.ts +2 -0
  168. package/es/site/data/components/datepicker/demos/yearMonth/index.js +3 -1
  169. package/es/site/data/components/datepicker/demos/yearMonth/react.d.ts +2 -0
  170. package/es/site/data/components/datepicker/demos/yearMonth/react.js +21 -1
  171. package/es/site/data/components/select/demos/creatable/index.d.ts +1 -0
  172. package/es/site/data/components/select/demos/creatable/index.js +2 -1
  173. package/es/site/data/components/select/demos/creatable/react.d.ts +1 -0
  174. package/es/site/data/components/select/demos/creatable/react.js +31 -2
  175. package/es/site/data/components/select/demos/searchable/index.js +1 -1
  176. package/es/site/data/components/select/demos/searchable/react.js +1 -1
  177. package/es/site/data/components/tour/demos/basic/index.d.ts +17 -0
  178. package/es/site/data/components/tour/demos/basic/index.js +46 -0
  179. package/es/site/data/components/tour/demos/basic/react.d.ts +16 -0
  180. package/es/site/data/components/tour/demos/basic/react.js +82 -0
  181. package/es/site/data/components/tour/demos/beforeChange/index.d.ts +20 -0
  182. package/es/site/data/components/tour/demos/beforeChange/index.js +69 -0
  183. package/es/site/data/components/tour/demos/beforeChange/react.d.ts +19 -0
  184. package/es/site/data/components/tour/demos/beforeChange/react.js +129 -0
  185. package/es/site/data/components/tour/demos/closable/index.d.ts +18 -0
  186. package/es/site/data/components/tour/demos/closable/index.js +42 -0
  187. package/es/site/data/components/tour/demos/closable/react.d.ts +17 -0
  188. package/es/site/data/components/tour/demos/closable/react.js +85 -0
  189. package/es/site/data/components/tour/demos/custom/index.d.ts +11 -0
  190. package/es/site/data/components/tour/demos/custom/index.js +35 -0
  191. package/es/site/data/components/tour/demos/custom/react.d.ts +11 -0
  192. package/es/site/data/components/tour/demos/custom/react.js +108 -0
  193. package/es/site/data/components/tour/demos/customButtons/index.d.ts +33 -0
  194. package/es/site/data/components/tour/demos/customButtons/index.js +55 -0
  195. package/es/site/data/components/tour/demos/customButtons/react.d.ts +33 -0
  196. package/es/site/data/components/tour/demos/customButtons/react.js +99 -0
  197. package/es/site/data/components/tour/demos/customText/index.d.ts +20 -0
  198. package/es/site/data/components/tour/demos/customText/index.js +54 -0
  199. package/es/site/data/components/tour/demos/customText/react.d.ts +19 -0
  200. package/es/site/data/components/tour/demos/customText/react.js +95 -0
  201. package/es/site/data/components/tour/demos/declarative/index.d.ts +11 -0
  202. package/es/site/data/components/tour/demos/declarative/index.js +36 -0
  203. package/es/site/data/components/tour/demos/declarative/react.d.ts +10 -0
  204. package/es/site/data/components/tour/demos/declarative/react.js +80 -0
  205. package/es/site/data/components/tour/demos/events/index.d.ts +18 -0
  206. package/es/site/data/components/tour/demos/events/index.js +58 -0
  207. package/es/site/data/components/tour/demos/events/react.d.ts +18 -0
  208. package/es/site/data/components/tour/demos/events/react.js +101 -0
  209. package/es/site/data/components/tour/demos/maskClosable/index.d.ts +18 -0
  210. package/es/site/data/components/tour/demos/maskClosable/index.js +47 -0
  211. package/es/site/data/components/tour/demos/maskClosable/react.d.ts +17 -0
  212. package/es/site/data/components/tour/demos/maskClosable/react.js +95 -0
  213. package/es/site/data/components/tour/demos/notarget/index.d.ts +11 -0
  214. package/es/site/data/components/tour/demos/notarget/index.js +35 -0
  215. package/es/site/data/components/tour/demos/notarget/react.d.ts +10 -0
  216. package/es/site/data/components/tour/demos/notarget/react.js +61 -0
  217. package/es/site/data/components/tour/index.d.ts +57 -0
  218. package/es/site/data/components/tour/index.js +32 -0
  219. package/es/site/src/pages/resource/index.js +1 -1
  220. package/es/styles/fonts/iconfont.js +2 -1
  221. package/es/styles/global.js +2 -1
  222. package/hooks/useDocumentClick.ts +3 -3
  223. package/hooks/useFixBody.ts +87 -0
  224. package/index.ts +3 -2
  225. package/package.json +1 -1
  226. package/styles/fonts/iconfont.ts +2 -1
  227. package/styles/global.ts +2 -1
@@ -79,6 +79,40 @@ describe('Datepicker', () => {
79
79
  expect(+_year).eql(year);
80
80
  expect(+_month - 1).eql(month);
81
81
  });
82
+
83
+ it('week', async () => {
84
+ const [instance, element] = mount(YearMonthDemo);
85
+ const inputs = element.querySelectorAll<HTMLElement>('.k-input');
86
+ const WeekInput = inputs[2];
87
+
88
+ WeekInput.click();
89
+ await wait();
90
+
91
+ const content = getElement('.k-datepicker-content')!;
92
+ const weekItem = content.querySelector('.week-row:nth-child(1) .k-week-number') as HTMLElement;
93
+ weekItem.click();
94
+
95
+ expect(instance.get<string>('week')).to.match(/^\d{4}-\d+周$/)
96
+
97
+ });
98
+
99
+ it('quarter', async () => {
100
+ const [instance, element] = mount(YearMonthDemo);
101
+ const inputs = element.querySelectorAll<HTMLElement>('.k-input');
102
+ const QuarterInput = inputs[3];
103
+
104
+ QuarterInput.click();
105
+ await wait();
106
+ const content = getElement('.k-datepicker-content')!;
107
+
108
+ // 选择第一个季度
109
+ const quarterItem = content.querySelector('.k-calendar-item:nth-child(1)') as HTMLElement;
110
+ quarterItem.click();
111
+
112
+ // 验证输入框的值是否包含Q1
113
+ expect(instance.get<string>('quarter')).to.include('Q1')
114
+ });
115
+
82
116
  });
83
117
 
84
118
  describe('Panel', async () => {
@@ -137,7 +171,7 @@ describe('Datepicker', () => {
137
171
  select.click();
138
172
  await wait();
139
173
  const content = getElement('.k-datepicker-content')!;
140
- const [panel1, panel2] = content.querySelectorAll<HTMLElement>('.k-datepicker-calendar-wrapper');
174
+ const [panel1, panel2] = content.querySelectorAll<HTMLElement>('.k-datepicker-calendar-time-wrapper');
141
175
  const [nextMonth, nextYear] = panel1.querySelectorAll<HTMLElement>('.k-next');
142
176
  const [monthValues1, monthValues2]= content.querySelectorAll<HTMLElement>('.k-month-values');
143
177
 
@@ -183,7 +217,7 @@ describe('Datepicker', () => {
183
217
  select.click();
184
218
  await wait();
185
219
  const content = getElement('.k-datepicker-content')!;
186
- const [panel1, panel2] = content.querySelectorAll<HTMLElement>('.k-datepicker-calendar-wrapper');
220
+ const [panel1, panel2] = content.querySelectorAll<HTMLElement>('.k-datepicker-calendar-time-wrapper');
187
221
  const [next] = panel1.querySelectorAll<HTMLElement>('.k-next');
188
222
  const [prev] = panel2.querySelectorAll<HTMLElement>('.k-prev');
189
223
  const [label1, label2]= content.querySelectorAll<HTMLElement>('.k-month-values');
@@ -209,7 +243,7 @@ describe('Datepicker', () => {
209
243
  select.click();
210
244
  await wait();
211
245
  const content = getElement('.k-datepicker-content')!;
212
- const [panel1, panel2] = content.querySelectorAll<HTMLElement>('.k-datepicker-calendar-wrapper');
246
+ const [panel1, panel2] = content.querySelectorAll<HTMLElement>('.k-datepicker-calendar-time-wrapper');
213
247
  const [next] = panel1.querySelectorAll<HTMLElement>('.k-next');
214
248
  const [prev] = panel2.querySelectorAll<HTMLElement>('.k-prev');
215
249
  const [label1, label2]= content.querySelectorAll<HTMLElement>('.k-month-values');
@@ -305,14 +339,14 @@ describe('Datepicker', () => {
305
339
  const content = getElement('.k-datepicker-content')!;
306
340
  dispatchEvent(content.querySelector('.k-calendar-item:nth-child(18)')!, 'click');
307
341
  await wait();
308
- dispatchEvent(content.querySelector('.k-btn')!, 'click');
342
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
309
343
  await wait();
310
344
  expect(instance.get('datetime')).have.lengthOf(1);
311
345
 
312
346
  // select the same datetime
313
347
  dispatchEvent(content.querySelector('.k-calendar-item:nth-child(18)')!, 'click');
314
348
  await wait();
315
- dispatchEvent(content.querySelector('.k-btn')!, 'click');
349
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
316
350
  await wait();
317
351
  expect(instance.get('datetime')).have.lengthOf(1);
318
352
 
@@ -321,7 +355,7 @@ describe('Datepicker', () => {
321
355
  await wait();
322
356
  dispatchEvent(content.querySelector('.k-scroll-select-item')!, 'click');
323
357
  await wait();
324
- dispatchEvent(content.querySelector('.k-btn')!, 'click');
358
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
325
359
  await wait();
326
360
  expect(instance.get('datetime')).have.lengthOf(2);
327
361
 
@@ -330,7 +364,7 @@ describe('Datepicker', () => {
330
364
  await wait();
331
365
  instance.set('datetime', []);
332
366
  await wait();
333
- dispatchEvent(content.querySelector('.k-btn')!, 'click');
367
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
334
368
  await wait();
335
369
  expect(instance.get('datetime')).have.lengthOf(1);
336
370
  });
@@ -384,7 +418,9 @@ describe('Datepicker', () => {
384
418
  dispatchEvent(select, 'click');
385
419
  await wait();
386
420
  const content = getElement('.k-datepicker-content')!;
387
- const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-wrapper');
421
+ const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-time-wrapper');
422
+
423
+
388
424
  const first = calendar1.querySelectorAll('.k-calendar-item')[17] as HTMLElement;
389
425
  const second = calendar2.querySelectorAll('.k-calendar-item')[17] as HTMLElement;
390
426
  first.click();
@@ -410,55 +446,6 @@ describe('Datepicker', () => {
410
446
  expect(instance.get('dateRange')).have.lengthOf(1);
411
447
  });
412
448
 
413
- it('datetime range', async () => {
414
- const [instance, element] = mount(MultipleDemo);
415
-
416
- const [, , , , , select] = element.querySelectorAll<HTMLElement>('.k-datepicker');
417
- dispatchEvent(select, 'click');
418
- await wait();
419
- const content = getElement('.k-datepicker-content')!;
420
- const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-wrapper');
421
- calendar1.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
422
- calendar2.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
423
- await wait();
424
- content.querySelector<HTMLElement>('.k-btn')!.click();
425
- await wait();
426
- expect(instance.get('datetimeRange')).have.lengthOf(1);
427
-
428
- calendar1.querySelectorAll<HTMLElement>('.k-calendar-item')[18].click();
429
- calendar2.querySelectorAll<HTMLElement>('.k-calendar-item')[18].click();
430
- await wait();
431
- content.querySelector<HTMLElement>('.k-btn')!.click();
432
- await wait();
433
- expect(instance.get('datetimeRange')).have.lengthOf(2);
434
-
435
- // selecting the same date time will do nothing
436
- calendar1.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
437
- calendar2.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
438
- await wait();
439
- content.querySelector<HTMLElement>('.k-btn')!.click();
440
- await wait();
441
- expect(instance.get('datetimeRange')).have.lengthOf(2);
442
-
443
- instance.set('datetimeRange', []);
444
- await wait();
445
- calendar1.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
446
- calendar2.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
447
- await wait();
448
- content.querySelector<HTMLElement>('.k-btn')!.click();
449
- await wait();
450
- expect(instance.get('datetimeRange')).have.lengthOf(1);
451
-
452
- // select the first value in end panel
453
- calendar2.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
454
- calendar2.querySelectorAll<HTMLElement>('.k-calendar-item')[17].click();
455
- await wait();
456
- content.querySelector<HTMLElement>('.k-btn')!.click();
457
- await wait();
458
- const values = instance.get('datetimeRange')!;
459
- expect(values).have.lengthOf(2);
460
- expect(values[1][1].includes('23:59:59')).to.be.true;
461
- });
462
449
  });
463
450
 
464
451
  describe('Range', () => {
@@ -515,7 +502,7 @@ describe('Datepicker', () => {
515
502
  select.click();
516
503
  await wait();
517
504
  first.click();
518
- let second = content.querySelector('.k-datepicker-calendar-wrapper:nth-child(2) .k-calendar-item:nth-child(19)') as HTMLElement;
505
+ let second = content.querySelector('.k-datepicker-calendar-time-wrapper:nth-child(2) .k-calendar-item:nth-child(19)') as HTMLElement;
519
506
  second.click();
520
507
  await wait();
521
508
  expect(instance.get('date')).have.lengthOf(2);
@@ -523,28 +510,42 @@ describe('Datepicker', () => {
523
510
  });
524
511
 
525
512
  it('datetime', async () => {
526
- const [instance, element] = mount(RangeDemo);
513
+ const [instance, element] = mount(MultipleDemo);
527
514
 
528
- const [, datetime] = element.querySelectorAll<HTMLElement>('.k-datepicker');
529
- datetime.click();
515
+ const [, select] = element.querySelectorAll<HTMLElement>('.k-datepicker');
516
+ dispatchEvent(select, 'click');
530
517
  await wait();
531
518
  const content = getElement('.k-datepicker-content')!;
532
- const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-wrapper');
533
- const first = calendar1.querySelectorAll('.k-calendar-item')[17] as HTMLElement;
534
- const second = calendar2.querySelectorAll('.k-calendar-item')[17] as HTMLElement;
535
- first.click();
536
- // should stay at date panel
519
+ dispatchEvent(content.querySelector('.k-calendar-item:nth-child(18)')!, 'click');
537
520
  await wait();
538
- expect(calendar1.querySelector('.k-days')).be.exist;
539
- second.click();
521
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
540
522
  await wait();
541
- dispatchEvent(calendar1.querySelector<HTMLElement>('.k-scroll-select-wrapper .k-active')!.nextElementSibling!, 'click');
542
- dispatchEvent(calendar2.querySelector<HTMLElement>('.k-scroll-select-wrapper .k-active')!.previousElementSibling!, 'click');
543
- (content.querySelector('.k-datepicker-footer .k-btn') as HTMLElement).click();
523
+ expect(instance.get('datetime')).have.lengthOf(1);
524
+
525
+ // select the same datetime
526
+ dispatchEvent(content.querySelector('.k-calendar-item:nth-child(18)')!, 'click');
527
+ await wait();
528
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
529
+ await wait();
530
+ expect(instance.get('datetime')).have.lengthOf(1);
531
+
532
+ // select different time with the same date
533
+ dispatchEvent(content.querySelector('.k-calendar-item:nth-child(18)')!, 'click');
534
+ await wait();
535
+ dispatchEvent(content.querySelector('.k-scroll-select-item')!, 'click');
536
+ await wait();
537
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
538
+ await wait();
539
+ expect(instance.get('datetime')).have.lengthOf(2);
540
+
541
+ // change to time panel, and remove the selections, then click confirm ok
542
+ dispatchEvent(content.querySelector('.k-calendar-item:nth-child(18)')!, 'click');
543
+ await wait();
544
+ instance.set('datetime', []);
544
545
  await wait();
545
- const value2 = instance.get('time')!;
546
- expect(value2).have.lengthOf(2);
547
- expect(value2.map(item => item.split(' ')[1])).eql(['01:00:00', '22:59:59']);
546
+ dispatchEvent(content.querySelector('.k-datepicker-footer .k-btn')!, 'click');
547
+ await wait();
548
+ expect(instance.get('datetime')).have.lengthOf(1);
548
549
  });
549
550
 
550
551
  it('year', async () => {
@@ -554,7 +555,7 @@ describe('Datepicker', () => {
554
555
  select.click();
555
556
  await wait();
556
557
  const content = getElement('.k-datepicker-content')!;
557
- const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-wrapper');
558
+ const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-time-wrapper');
558
559
  const first = calendar1.querySelector('.k-calendar-item:nth-child(2)') as HTMLElement;
559
560
  const second = calendar2.querySelector('.k-calendar-item:nth-child(2)') as HTMLElement;
560
561
  first.click();
@@ -571,7 +572,7 @@ describe('Datepicker', () => {
571
572
  select.click();
572
573
  await wait();
573
574
  const content = getElement('.k-datepicker-content')!;
574
- const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-wrapper');
575
+ const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-time-wrapper');
575
576
  const first = calendar1.querySelector('.k-calendar-item:nth-child(1)') as HTMLElement;
576
577
  const second = calendar2.querySelector('.k-calendar-item:nth-child(1)') as HTMLElement;
577
578
  first.click();
@@ -672,23 +673,39 @@ describe('Datepicker', () => {
672
673
  element.click();
673
674
  await wait();
674
675
  const content = getElement('.k-datepicker-content')!;
675
- const [calendar1, calendar2] = content.querySelectorAll('.k-datepicker-calendar-wrapper');
676
- const first = calendar1.querySelectorAll('.k-calendar-item')[17] as HTMLElement;
677
- const second = calendar2.querySelectorAll('.k-calendar-item')[17] as HTMLElement;
678
- first.click();
676
+ const calendar = content.querySelector<HTMLElement>('.k-datepicker-calendar-time-wrapper');
677
+ const first = calendar!.querySelector('.k-datepicker-calendar') as HTMLElement;
678
+ const second = calendar!.querySelector('.k-datepicker-time-wrapper') as HTMLElement;
679
+ const firstDateItem = first.querySelector('.k-calendar-item') as HTMLElement;
680
+ firstDateItem.click();
679
681
  expect(fn.callCount).to.eql(1);
680
682
  expect(fn.lastCall.args[0]).have.lengthOf(1);
681
- second.click();
683
+ const activeTimeItem = second.querySelector('.k-scroll-select-wrapper .k-active') as HTMLElement;
684
+ const nextTimeItem = activeTimeItem.nextElementSibling as HTMLElement;
685
+ nextTimeItem.click();
682
686
  expect(fn.callCount).to.eql(2);
683
- expect(fn.lastCall.args[0]).have.lengthOf(2);
687
+ expect(fn.lastCall.args[0]).have.lengthOf(1);
688
+ const confirmBtn = content.querySelector('.k-datepicker-footer .k-btn') as HTMLElement;
689
+ confirmBtn.click();
684
690
  await wait();
685
- dispatchEvent(calendar1.querySelector<HTMLElement>('.k-scroll-select-wrapper .k-active')!.nextElementSibling!, 'click');
691
+
692
+ const endCalendar = content.querySelector<HTMLElement>('.k-datepicker-calendar-time-wrapper');
693
+ const endFirst = endCalendar!.querySelector('.k-datepicker-calendar') as HTMLElement;
694
+ const endSecond = endCalendar!.querySelector('.k-datepicker-time-wrapper') as HTMLElement;
695
+
696
+ const endDateItem = endFirst.querySelector('.k-calendar-item') as HTMLElement;
697
+ endDateItem.click();
686
698
  expect(fn.callCount).to.eql(3);
687
- expect(fn.lastCall.args[0]).have.lengthOf(2);
688
- dispatchEvent(calendar2.querySelector<HTMLElement>('.k-scroll-select-wrapper .k-active')!.previousElementSibling!, 'click');
699
+ expect(fn.lastCall.args[0]).have.lengthOf(1);
700
+
701
+ const endActiveTimeItem = endSecond.querySelector('.k-scroll-select-wrapper .k-active') as HTMLElement;
702
+ const endNextTimeItem = endActiveTimeItem.nextElementSibling as HTMLElement;
703
+ endNextTimeItem.click();
689
704
  expect(fn.callCount).to.eql(4);
690
- expect(fn.lastCall.args[0]).have.lengthOf(2);
691
- (content.querySelector('.k-datepicker-footer .k-btn') as HTMLElement).click();
705
+ expect(fn.lastCall.args[0]).have.lengthOf(1);
706
+
707
+ const finalConfirmBtn = content.querySelector('.k-datepicker-footer .k-btn') as HTMLElement;
708
+ finalConfirmBtn.click();
692
709
  await wait();
693
710
  expect(fn.callCount).to.eql(4);
694
711
  });
@@ -736,7 +753,7 @@ describe('Datepicker', () => {
736
753
  content = getElement('.k-datepicker-content')!;
737
754
  content.querySelector<HTMLElement>('.k-today')!.click();
738
755
  await wait();
739
- content.querySelector<HTMLElement>('.k-btn')!.click();
756
+ content.querySelector<HTMLElement>('.k-datepicker-footer .k-btn')!.click();
740
757
  await wait();
741
758
  expect(instance.get('date3')).to.eql(dayjs().format('YYYY-MM-DD') + 'T00:00:00.000Z');
742
759
  expect(input3.value).to.eql(dayjs().format('YYYY-MM-DD') + ' 00:00:00');
@@ -782,7 +799,7 @@ describe('Datepicker', () => {
782
799
  const content = getElement('.k-datepicker-content')!;
783
800
  content.querySelector<HTMLElement>('.k-today')!.click();
784
801
  await wait();
785
- content.querySelector<HTMLElement>('.k-btn')!.click();
802
+ content.querySelector<HTMLElement>('.k-datepicker-footer .k-btn')!.click();
786
803
  await wait();
787
804
  expect(instance.get('toTime')).to.eql(`${date} ${time}`);
788
805
  });
@@ -853,7 +870,7 @@ describe('Datepicker', () => {
853
870
  await myTest('2020-03-03~2020-03-04', ['2020-03-03', '2020-03-04']);
854
871
  expect(
855
872
  getElement('.k-datepicker-content')!
856
- .querySelector<HTMLElement>('.k-datepicker-calendar-wrapper:nth-child(1)')!
873
+ .querySelector<HTMLElement>('.k-datepicker-calendar-time-wrapper:nth-child(1)')!
857
874
  .innerHTML
858
875
  ).to.matchSnapshot();
859
876
  // clear value
@@ -14,6 +14,9 @@ import {usePanel} from './usePanel';
14
14
  import {useFocusDate} from './useFocusDate';
15
15
  import {useKeyboards} from './useKeyboards';
16
16
  import {Shortcut} from './shortcuts';
17
+ import {usePosition} from './usePosition';
18
+ import {useMergeRange} from './useMergeRange';
19
+
17
20
  import {
18
21
  BasePicker,
19
22
  BasePickerProps,
@@ -30,8 +33,9 @@ export interface DatepickerProps<
30
33
  M extends boolean = boolean,
31
34
  R extends boolean = boolean,
32
35
  > extends BasePickerProps<V extends string ? V : V | string, M, R> {
33
- type?: 'date' | 'datetime' | 'year' | 'month'
34
- shortcuts?: Shortcut[]
36
+ type?: 'date' | 'datetime' | 'year' | 'month' | 'week' | 'quarter'
37
+ shortcuts?: Shortcut[],
38
+ isMerge?: boolean
35
39
  }
36
40
 
37
41
  export interface DatepickerEvents extends BasePickerEvents { }
@@ -43,13 +47,15 @@ export interface DatepickerBlocks<
43
47
 
44
48
  const typeDefs: Required<TypeDefs<DatepickerProps>> = {
45
49
  ...BasePicker.typeDefs,
46
- type: ['date', 'datetime', 'year', 'month'],
50
+ type: ['date', 'datetime', 'year', 'month', 'week', 'quarter'],
47
51
  shortcuts: Array,
52
+ isMerge: Boolean
48
53
  };
49
54
 
50
55
  const defaults = (): Partial<DatepickerProps> => ({
51
56
  ...BasePicker.defaults(),
52
57
  type: 'date',
58
+ isMerge: false
53
59
  });
54
60
 
55
61
  export class Datepicker<
@@ -66,16 +72,18 @@ export class Datepicker<
66
72
  public panel = usePanel();
67
73
  public focusDate = useFocusDate();
68
74
  public value = useValue(this.formats, this.disabled, this.panel);
69
-
75
+ public activePosition = usePosition();
76
+ public mergeRange = useMergeRange(this.formats);
77
+
70
78
  init() {
71
79
  super.init();
72
80
  provide(DATEPICKER, this);
73
81
  useKeyboards(this.panel.startRef, this.focusDate.focusDate);
82
+ this.activePosition.setupEventListeners();
74
83
  }
75
84
 
76
85
  protected getPlaceholder() {
77
86
  const {placeholder, type, range} = this.get();
78
-
79
87
  if (!isNullOrUndefined(placeholder)) return placeholder;
80
88
 
81
89
  switch (type) {
@@ -85,12 +93,22 @@ export class Datepicker<
85
93
  return _$('请选择年份');
86
94
  case 'month':
87
95
  return _$('请选择月份');
96
+ case 'week':
97
+ return _$('请选择周');
98
+ case 'quarter':
99
+ return _$('请选择季度');
88
100
  default:
89
101
  return range ? _$('开始日期 ~ 结束日期') : _$('请选择日期');
90
102
  }
91
103
  }
92
104
 
93
105
  protected getLabel() {
106
+ const {multiple} = this.get();
107
+ if(multiple) {
108
+ const results = this.value.format();
109
+ const dayjsValue = this.value.getDayjsValue();
110
+ return this.mergeRange.formatMultipleValues(dayjsValue, results as string[]);
111
+ }
94
112
  return this.value.format();
95
113
  }
96
114
 
@@ -5,7 +5,7 @@ import {DatepickerTime} from './time';
5
5
  import {Icon} from '../icon';
6
6
  import {Button} from '../button';
7
7
  import {_$} from '../../i18n';
8
- import {makePanelStyles} from './styles';
8
+ import {makePanelStyles, makeDatePickRangeStyles} from './styles';
9
9
  import {PanelTypes, PanelFlags} from './usePanel';
10
10
  import {isFunction} from 'intact-shared';
11
11
  import {Tabs, Tab} from '../tabs';
@@ -19,61 +19,60 @@ const {
19
19
  onChangeDateForRange,
20
20
  getTimeValue,
21
21
  } = this.value;
22
+ const { position, charLength, startTextLength, handleInputClick } = this.activePosition
22
23
  const { k } = this.config;
24
+ const showPanel = range && position.value === 'end';
25
+ const positionDisplay = !multiple && range && (type === 'datetime' || type === 'date');
26
+ // 判断是否显示双面板
27
+ const showDualPanels = range && (type === 'date' || type === 'month' || type === 'year')
28
+
23
29
  const classNameObj = {
24
30
  [`${k}-datepicker-content`]: true,
25
31
  [className]: className,
26
32
  [makePanelStyles(k)]: true,
27
33
  };
28
-
34
+ const classDatePickerObj = {
35
+ [`${k}-datepicker`]: true,
36
+ [makeDatePickRangeStyles(k, position.value, positionDisplay, charLength.value, startTextLength.value)]: true,
37
+ }
29
38
  const {isDisabledTime, isDisabledConfirm} = this.disabled;
30
39
  const {startPanel, endPanel, getPanel, startRef, endRef} = this.panel;
31
40
  const generatePanel = (flag) => {
32
41
  const panel = getPanel(flag);
33
42
  const timeValue = getTimeValue(flag);
43
+ let dateString = '0000-00-00';
44
+ let timeString = '00:00:00';
45
+
46
+ if (type === 'datetime' && timeValue) {
47
+ const valueString = this.formats.getShowString(timeValue).split(/\s+/);
48
+ dateString = valueString[0];
49
+ timeString = valueString[1];
50
+ }
51
+
34
52
  return (
35
- <div class={`${k}-datepicker-calendar-wrapper`}>
36
- {(() => {
37
- if (type === 'datetime') {
38
- let dateString = '0000-00-00';
39
- let timeString = '00:00:00';
40
- if (timeValue) {
41
- const valueString = this.formats.getShowString(timeValue).split(/\s+/);
42
- dateString = valueString[0];
43
- timeString = valueString[1];
44
- }
45
- return (
46
- <Tabs type="card"
47
- value={panel.value}
48
- ev-$change:value={panel.set}
49
- >
50
- <Tab value={PanelTypes.Date}>{dateString}</Tab>
51
- <Tab value={PanelTypes.Time} disabled={!timeValue} >{timeString}</Tab>
52
- </Tabs>
53
- );
54
- }
55
- })()}
53
+ <div class={`${k}-datepicker-calendar-time-wrapper`}>
56
54
  <DatepickerCalendar
57
- v-if={panel.value === PanelTypes.Date}
58
55
  value={value}
59
56
  ev-change={onChangeDate}
60
57
  type={type === 'datetime' ? 'date' : type}
61
58
  flag={flag}
62
59
  ref={flag === PanelFlags.Start ? startRef : endRef}
63
60
  />
64
- <DatepickerTime
65
- v-else
66
- value={timeValue}
67
- ev-$change:value={v => onChangeTime(v, flag)}
68
- format={this.formats.getValueFormat()}
69
- flag={flag}
70
- isDisabledTime={isDisabledTime}
71
- />
61
+ <div class={`${k}-datepicker-time-wrapper`} v-if={type === 'datetime'}>
62
+ <div class={`${k}-datepicker-time-time`}>{timeString}</div>
63
+ <DatepickerTime
64
+ value={timeValue}
65
+ ev-$change:value={v => onChangeTime(v, flag)}
66
+ format={this.formats.getValueFormat()}
67
+ flag={flag}
68
+ isDisabledTime={isDisabledTime}
69
+ />
70
+ </div>
72
71
  </div>
73
72
  );
74
73
  };
75
74
 
76
- <t:super class={`${k}-datepicker`}>
75
+ <t:super class={classDatePickerObj} onClick={handleInputClick}>
77
76
  <b:base-menu>
78
77
  <DropdownMenu class={classNameObj}>
79
78
  <div class={`${k}-datepicker-shortcuts`} v-if={shortcuts && shortcuts.length}>
@@ -87,8 +86,8 @@ const generatePanel = (flag) => {
87
86
  </div>
88
87
  <div class={`${k}-datepicker-wrapper`}>
89
88
  <div class={`${k}-datepicker-calendars`}>
90
- {generatePanel(PanelFlags.Start)}
91
- {range ? generatePanel(PanelFlags.End) : null}
89
+ { showDualPanels ? generatePanel(PanelFlags.Start) : (showPanel ? null : generatePanel(PanelFlags.Start))}
90
+ { showDualPanels ? generatePanel(PanelFlags.End) : (showPanel ? generatePanel(PanelFlags.End) : null)}
92
91
  </div>
93
92
  <div v-if={type === 'datetime'} class={`${k}-datepicker-footer`}>
94
93
  <Button type="primary" size="small"
@@ -11,7 +11,9 @@ const defaults = {
11
11
 
12
12
  item: {
13
13
  gutter: `7px`,
14
+ yearGutter: '36px',
14
15
  height: `24px`,
16
+ rangeGutter: `17px`,
15
17
  get hoverBgColor() { return theme.color.bg },
16
18
  get exceedColor() { return theme.color.disabled },
17
19
  get todayBorder() { return `1px solid ${theme.color.border}` },
@@ -49,6 +51,19 @@ const defaults = {
49
51
  padding: `8px 16px`,
50
52
  },
51
53
 
54
+ week: {
55
+ height: `20px`,
56
+ width: `40px`,
57
+ margin: `0 0 0 10px`,
58
+ padding: `0 2px`,
59
+ currentWeek: '#eee'
60
+ },
61
+
62
+ calendarTime: {
63
+ height: `44px`,
64
+ fontSize: `14px`,
65
+ },
66
+
52
67
  shortcuts: {
53
68
  width: '100px',
54
69
  padding: '12px 0',
@@ -57,7 +72,7 @@ const defaults = {
57
72
  height: '32px',
58
73
  padding: '0 16px',
59
74
  }
60
- }
75
+ },
61
76
  };
62
77
 
63
78
  let datepicker: typeof defaults;
@@ -103,12 +118,26 @@ export const makePanelStyles = cache(function makePanelStyles(k: string) {
103
118
  width: 50%;
104
119
  }
105
120
  }
121
+
122
+ }
123
+ .${k}-datepicker-calendar-time-wrapper {
124
+ display: flex;
125
+ .${k}-datepicker-time-time {
126
+ height: ${datepicker.calendarTime.height};
127
+ line-height: ${datepicker.calendarTime.height};
128
+ text-align: center;
129
+ font-size: ${datepicker.calendarTime.fontSize};
130
+ }
131
+ .${k}-datepicker-time-wrapper {
132
+ overflow: hidden;
133
+ height: 320px;
134
+ }
106
135
  }
107
136
  .${k}-datepicker-footer {
108
137
  border-top: ${datepicker.border};
109
138
  padding: ${datepicker.footer.padding};
110
139
  text-align: right;
111
- }
140
+ }
112
141
  `
113
142
  });
114
143
 
@@ -207,8 +236,56 @@ export const makeCalendarStyles = cache(function makeCalendarStyles(k: string) {
207
236
  grid-template-columns: repeat(7, 1fr);
208
237
  }
209
238
  .${k}-years {
239
+ .${k}-calendar-item {
240
+ height: 20px;
241
+ width: 40px;
242
+
243
+ &.${k}-in-range:after {
244
+ width: calc(100% + 14px);
245
+ left: calc(-${datepicker.item.yearGutter} / 2);
246
+ padding: 0 calc(${datepicker.item.yearGutter} / 2);
247
+ }
248
+ }
210
249
  display: grid;
211
- grid-template-columns: repeat(4, 1fr);
250
+ justify-items: center;
251
+ grid-template-columns: repeat(3, 1fr);
252
+ gap: 0;
253
+ }
254
+ .${k}-weeks {
255
+ display: grid;
256
+ .week-row {
257
+ display: flex;
258
+ align-items: center;
259
+ width: ${datepicker.week.width};
260
+ margin: ${datepicker.week.margin};
261
+
262
+ .${k}-week-number {
263
+ padding: ${datepicker.week.padding};
264
+ cursor: pointer;
265
+ }
266
+ }
267
+ .${k}-calendar-item {
268
+ height: ${datepicker.week.height};
269
+ &.${k}-today:not(:last-child) .${k}-value {
270
+ background: ${datepicker.week.currentWeek};
271
+ border: 0;
272
+ &:after {
273
+ content: '';
274
+ display: block;
275
+ position: absolute;
276
+ box-sizing: content-box;
277
+ background: ${datepicker.week.currentWeek};
278
+ width: 100%;
279
+ height: 100%;
280
+ left: 0;
281
+ padding: 0 ${datepicker.item.rangeGutter};
282
+ z-index: -1;
283
+ }
284
+ }
285
+ &.${k}-today:last-child .${k}-value {
286
+ border: 0;
287
+ }
288
+ }
212
289
  }
213
290
  `
214
291
  });
@@ -225,3 +302,25 @@ export const makeTimeStyles = cache(function makeTimeStyles(k: string) {
225
302
  }
226
303
  `;
227
304
  });
305
+
306
+ export const makeDatePickRangeStyles = cache(function makeTimeStyles(k: string, activePositionValue: string, display: boolean, charLength: number = 10, startTextLength: number = 10) {
307
+ const displayType = display ? 'block' : 'none';
308
+ const charWidthPx = 8;
309
+ const highlightWidthPx = charLength * charWidthPx;
310
+
311
+ // 计算结束文本的起始位置 - 紧接着开始文本
312
+ const endTextStartPos = startTextLength * charWidthPx;
313
+
314
+ return css`
315
+ &:hover:before, &:focus:before{
316
+ content: '';
317
+ display: ${displayType};
318
+ width: ${highlightWidthPx}px;
319
+ height: 1px;
320
+ position: absolute;
321
+ background-color: ${datepicker.item.active.bgColor};
322
+ left: ${activePositionValue === 'start' ? '0' : endTextStartPos + 'px'};
323
+ bottom: 0;
324
+ }
325
+ `;
326
+ });