vxe-pc-ui 4.15.2 → 4.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/all.esm.js +774 -211
  2. package/es/backtop/src/backtop.js +2 -1
  3. package/es/button/src/button.js +3 -2
  4. package/es/calendar/src/calendar.js +2 -1
  5. package/es/cascader/src/cascader.js +2 -1
  6. package/es/checkbox/src/group.js +5 -1
  7. package/es/date-panel/src/util.js +27 -16
  8. package/es/date-picker/src/date-picker.js +572 -74
  9. package/es/date-range-picker/src/date-range-picker.js +3 -2
  10. package/es/drawer/src/drawer.js +2 -0
  11. package/es/form/render/index.js +3 -2
  12. package/es/form/src/form.js +6 -5
  13. package/es/form/src/itemInfo.js +6 -5
  14. package/es/input/src/input.js +2 -1
  15. package/es/menu/src/menu.js +2 -1
  16. package/es/modal/src/modal.js +5 -2
  17. package/es/pager/src/pager.js +4 -3
  18. package/es/radio/src/group.js +5 -1
  19. package/es/select/src/select.js +25 -20
  20. package/es/splitter/src/splitter.js +7 -6
  21. package/es/table-select/src/table-select.js +21 -16
  22. package/es/tabs/src/tabs.js +4 -3
  23. package/es/textarea/src/textarea.js +2 -1
  24. package/es/tree/src/tree.js +3 -2
  25. package/es/tree-select/src/tree-select.js +2 -1
  26. package/es/ui/index.js +1 -1
  27. package/es/ui/src/log.js +7 -1
  28. package/es/upload/src/upload.js +12 -3
  29. package/lib/backtop/src/backtop.js +5 -2
  30. package/lib/backtop/src/backtop.min.js +1 -1
  31. package/lib/button/src/button.js +4 -1
  32. package/lib/button/src/button.min.js +1 -1
  33. package/lib/calendar/src/calendar.js +4 -1
  34. package/lib/calendar/src/calendar.min.js +1 -1
  35. package/lib/cascader/src/cascader.js +4 -1
  36. package/lib/cascader/src/cascader.min.js +1 -1
  37. package/lib/checkbox/src/group.js +5 -1
  38. package/lib/checkbox/src/group.min.js +1 -1
  39. package/lib/date-panel/src/util.js +37 -19
  40. package/lib/date-panel/src/util.min.js +1 -1
  41. package/lib/date-picker/src/date-picker.js +620 -77
  42. package/lib/date-picker/src/date-picker.min.js +1 -1
  43. package/lib/date-range-picker/src/date-range-picker.js +4 -1
  44. package/lib/date-range-picker/src/date-range-picker.min.js +1 -1
  45. package/lib/drawer/src/drawer.js +2 -0
  46. package/lib/drawer/src/drawer.min.js +1 -1
  47. package/lib/form/render/index.js +4 -1
  48. package/lib/form/render/index.min.js +1 -1
  49. package/lib/form/src/form.js +8 -4
  50. package/lib/form/src/form.min.js +1 -1
  51. package/lib/form/src/itemInfo.js +7 -4
  52. package/lib/form/src/itemInfo.min.js +1 -1
  53. package/lib/index.umd.js +847 -177
  54. package/lib/index.umd.min.js +1 -1
  55. package/lib/input/src/input.js +6 -3
  56. package/lib/input/src/input.min.js +1 -1
  57. package/lib/menu/src/menu.js +4 -1
  58. package/lib/menu/src/menu.min.js +1 -1
  59. package/lib/modal/src/modal.js +8 -2
  60. package/lib/modal/src/modal.min.js +1 -1
  61. package/lib/pager/src/pager.js +6 -2
  62. package/lib/pager/src/pager.min.js +1 -1
  63. package/lib/radio/src/group.js +5 -1
  64. package/lib/radio/src/group.min.js +1 -1
  65. package/lib/select/src/select.js +27 -20
  66. package/lib/select/src/select.min.js +1 -1
  67. package/lib/splitter/src/splitter.js +12 -8
  68. package/lib/splitter/src/splitter.min.js +1 -1
  69. package/lib/table-select/src/table-select.js +22 -15
  70. package/lib/table-select/src/table-select.min.js +1 -1
  71. package/lib/tabs/src/tabs.js +7 -3
  72. package/lib/tabs/src/tabs.min.js +1 -1
  73. package/lib/textarea/src/textarea.js +4 -1
  74. package/lib/textarea/src/textarea.min.js +1 -1
  75. package/lib/tree/src/tree.js +7 -4
  76. package/lib/tree/src/tree.min.js +1 -1
  77. package/lib/tree-select/src/tree-select.js +7 -3
  78. package/lib/tree-select/src/tree-select.min.js +1 -1
  79. package/lib/ui/index.js +1 -1
  80. package/lib/ui/index.min.js +1 -1
  81. package/lib/ui/src/log.js +8 -1
  82. package/lib/ui/src/log.min.js +1 -1
  83. package/lib/upload/src/upload.js +20 -3
  84. package/lib/upload/src/upload.min.js +1 -1
  85. package/package.json +1 -1
  86. package/packages/backtop/src/backtop.ts +3 -1
  87. package/packages/button/src/button.ts +4 -2
  88. package/packages/calendar/src/calendar.ts +3 -1
  89. package/packages/cascader/src/cascader.ts +3 -1
  90. package/packages/checkbox/src/group.ts +6 -2
  91. package/packages/date-panel/src/util.ts +28 -16
  92. package/packages/date-picker/src/date-picker.ts +583 -75
  93. package/packages/date-range-picker/src/date-range-picker.ts +4 -2
  94. package/packages/drawer/src/drawer.ts +2 -0
  95. package/packages/form/render/index.ts +4 -2
  96. package/packages/form/src/form.ts +7 -5
  97. package/packages/form/src/itemInfo.ts +7 -5
  98. package/packages/input/src/input.ts +3 -1
  99. package/packages/menu/src/menu.ts +3 -1
  100. package/packages/modal/src/modal.ts +6 -2
  101. package/packages/pager/src/pager.ts +5 -3
  102. package/packages/radio/src/group.ts +6 -2
  103. package/packages/select/src/select.ts +29 -22
  104. package/packages/splitter/src/splitter.ts +8 -6
  105. package/packages/table-select/src/table-select.ts +24 -17
  106. package/packages/tabs/src/tabs.ts +5 -3
  107. package/packages/textarea/src/textarea.ts +3 -1
  108. package/packages/tree/src/tree.ts +4 -2
  109. package/packages/tree-select/src/tree-select.ts +3 -1
  110. package/packages/ui/src/log.ts +7 -0
  111. package/packages/upload/src/upload.ts +14 -3
  112. package/types/components/date-picker.d.ts +14 -6
  113. package/types/components/drawer.d.ts +2 -0
  114. package/types/components/modal.d.ts +2 -0
  115. package/types/components/upload.d.ts +28 -1
  116. /package/es/icon/{iconfont.1781753592499.ttf → iconfont.1781852740683.ttf} +0 -0
  117. /package/es/icon/{iconfont.1781753592499.woff → iconfont.1781852740683.woff} +0 -0
  118. /package/es/icon/{iconfont.1781753592499.woff2 → iconfont.1781852740683.woff2} +0 -0
  119. /package/es/{iconfont.1781753592499.ttf → iconfont.1781852740683.ttf} +0 -0
  120. /package/es/{iconfont.1781753592499.woff → iconfont.1781852740683.woff} +0 -0
  121. /package/es/{iconfont.1781753592499.woff2 → iconfont.1781852740683.woff2} +0 -0
  122. /package/lib/icon/style/{iconfont.1781753592499.ttf → iconfont.1781852740683.ttf} +0 -0
  123. /package/lib/icon/style/{iconfont.1781753592499.woff → iconfont.1781852740683.woff} +0 -0
  124. /package/lib/icon/style/{iconfont.1781753592499.woff2 → iconfont.1781852740683.woff2} +0 -0
  125. /package/lib/{iconfont.1781753592499.ttf → iconfont.1781852740683.ttf} +0 -0
  126. /package/lib/{iconfont.1781753592499.woff → iconfont.1781852740683.woff} +0 -0
  127. /package/lib/{iconfont.1781753592499.woff2 → iconfont.1781852740683.woff2} +0 -0
@@ -3,13 +3,40 @@ import { defineVxeComponent } from '../../ui/src/comp';
3
3
  import XEUtils from 'xe-utils';
4
4
  import { getConfig, getIcon, getI18n, commands, createEvent, globalEvents, GLOBAL_EVENT_KEYS, useSize, renderEmptyElement } from '../../ui';
5
5
  import { getFuncText, getLastZIndex, nextZIndex, isEnableConf } from '../../ui/src/utils';
6
- import { updatePanelPlacement, getEventTargetNode } from '../../ui/src/dom';
6
+ import { updatePanelPlacement, getEventTargetNode, hasControlKey } from '../../ui/src/dom';
7
7
  import { getSlotVNs } from '../../ui/src/vn';
8
- import { parseDateObj, parseDateValue, getDateByCode, handleValueFormat, handleInputFormat, hasDateValueType, hasTimestampValueType } from '../../date-panel/src/util';
9
- import { errLog } from '../../ui/src/log';
8
+ import { parseDateObj, parseDateValue, getDateByCode, handleValueFormat, hasDateValueType, hasTimestampValueType, isAllSameChar, getChunkDefaultNum } from '../../date-panel/src/util';
9
+ import { createComponentLog } from '../../ui/src/log';
10
10
  import VxeDatePanelComponent from '../../date-panel/src/date-panel';
11
11
  import VxeButtonComponent from '../../button/src/button';
12
12
  import VxeButtonGroupComponent from '../../button/src/button-group';
13
+ const { warnLog, errLog } = createComponentLog('date-picker');
14
+ const maskedTypes = ['year', 'month', 'date', 'datetime', 'time'];
15
+ const inputMaskedKeys = ['y', 'M', 'd', 'H', 'm', 'n', 's'];
16
+ const parseInputKayMaps = {};
17
+ inputMaskedKeys.forEach(key => {
18
+ parseInputKayMaps[key] = true;
19
+ });
20
+ function createReactData() {
21
+ return {
22
+ initialized: false,
23
+ panelIndex: 0,
24
+ visiblePanel: false,
25
+ isAniVisible: false,
26
+ panelStyle: {},
27
+ panelPlacement: '',
28
+ isActivated: false,
29
+ inputValue: '',
30
+ labelFlag: 0
31
+ };
32
+ }
33
+ function createInternalData() {
34
+ return {
35
+ // hpTimeout: undefined,
36
+ inputLabel: '',
37
+ laseFocusMasked: 0
38
+ };
39
+ }
13
40
  export default defineVxeComponent({
14
41
  name: 'VxeDatePicker',
15
42
  props: {
@@ -72,7 +99,6 @@ export default defineVxeComponent({
72
99
  labelFormat: String,
73
100
  valueFormat: String,
74
101
  timeFormat: String,
75
- inputFormat: String,
76
102
  editable: {
77
103
  type: Boolean,
78
104
  default: true
@@ -102,7 +128,7 @@ export default defineVxeComponent({
102
128
  type: Boolean,
103
129
  default: () => getConfig().datePicker.autoClose
104
130
  },
105
- controlConfig: Object,
131
+ maskedConfig: Object,
106
132
  prefixIcon: String,
107
133
  suffixIcon: String,
108
134
  placement: String,
@@ -143,21 +169,8 @@ export default defineVxeComponent({
143
169
  const formItemInfo = inject('xeFormItemInfo', null);
144
170
  const xID = XEUtils.uniqueId();
145
171
  const { computeSize } = useSize(props);
146
- const reactData = reactive({
147
- initialized: false,
148
- panelIndex: 0,
149
- visiblePanel: false,
150
- isAniVisible: false,
151
- panelStyle: {},
152
- panelPlacement: '',
153
- isActivated: false,
154
- inputValue: '',
155
- inputLabel: ''
156
- });
157
- const internalData = {
158
- // hpTimeout: undefined,
159
- parseInputKayMaps: {}
160
- };
172
+ const reactData = reactive(createReactData());
173
+ const internalData = createInternalData();
161
174
  const refElem = ref();
162
175
  const refInputTarget = ref();
163
176
  const refInputPanel = ref();
@@ -223,6 +236,44 @@ export default defineVxeComponent({
223
236
  const computeIsClearable = computed(() => {
224
237
  return props.clearable;
225
238
  });
239
+ const computeIsDatePanelType = computed(() => {
240
+ const isDateTimeType = computeIsDateTimeType.value;
241
+ return isDateTimeType || ['date', 'week', 'month', 'quarter', 'year'].indexOf(props.type) > -1;
242
+ });
243
+ const computeDateListValue = computed(() => {
244
+ const { modelValue, type, multiple } = props;
245
+ const isDatePanelType = computeIsDatePanelType.value;
246
+ const dateValueFormat = computeDateValueFormat.value;
247
+ if (multiple && modelValue && isDatePanelType) {
248
+ return XEUtils.toValueString(modelValue).split(',').map(item => {
249
+ const date = parseDateValue(item, type, {
250
+ valueFormat: dateValueFormat
251
+ });
252
+ if (XEUtils.isValidDate(date)) {
253
+ return date;
254
+ }
255
+ return date;
256
+ });
257
+ }
258
+ return [];
259
+ });
260
+ const computeLimitMaxCount = computed(() => {
261
+ return props.multiple ? XEUtils.toNumber(props.limitCount) : 0;
262
+ });
263
+ const computeDateMultipleValue = computed(() => {
264
+ const dateListValue = computeDateListValue.value;
265
+ const dateValueFormat = computeDateValueFormat.value;
266
+ return dateListValue.map(date => XEUtils.toDateString(date, dateValueFormat));
267
+ });
268
+ const computeOverCount = computed(() => {
269
+ const { multiple } = props;
270
+ const limitMaxCount = computeLimitMaxCount.value;
271
+ const dateMultipleValue = computeDateMultipleValue.value;
272
+ if (multiple && limitMaxCount) {
273
+ return dateMultipleValue.length >= limitMaxCount;
274
+ }
275
+ return false;
276
+ });
226
277
  const computeInputReadonly = computed(() => {
227
278
  const { type, editable, multiple } = props;
228
279
  const formReadonly = computeFormReadonly.value;
@@ -272,9 +323,9 @@ export default defineVxeComponent({
272
323
  const { type, valueFormat } = props;
273
324
  return handleValueFormat(type, valueFormat);
274
325
  });
275
- const computeDateInputFormat = computed(() => {
276
- const { type, inputFormat } = props;
277
- return handleInputFormat(type, inputFormat);
326
+ const computeDateMaskedFormat = computed(() => {
327
+ const dateLabelFormat = computeDateLabelFormat.value;
328
+ return dateLabelFormat;
278
329
  });
279
330
  const computeFirstDayOfWeek = computed(() => {
280
331
  const { startDay } = props;
@@ -296,8 +347,13 @@ export default defineVxeComponent({
296
347
  return dateObj.label;
297
348
  }).join(', ');
298
349
  });
299
- const computeControlOpts = computed(() => {
300
- return Object.assign({}, getConfig().datePicker.controlConfig, props.controlConfig);
350
+ const computeMaskedOpts = computed(() => {
351
+ return Object.assign({}, getConfig().datePicker.maskedConfig, props.maskedConfig);
352
+ });
353
+ const computeMaskChar = computed(() => {
354
+ const maskedOpts = computeMaskedOpts.value;
355
+ const { maskPlaceholder } = maskedOpts;
356
+ return (maskPlaceholder ? ('' + maskPlaceholder)[0] : '') || '*';
301
357
  });
302
358
  const updateModelValue = () => {
303
359
  const { modelValue } = props;
@@ -312,6 +368,12 @@ export default defineVxeComponent({
312
368
  }
313
369
  reactData.inputValue = val;
314
370
  };
371
+ const handleInputLabel = (text, isUpdate) => {
372
+ internalData.inputLabel = text;
373
+ if (isUpdate) {
374
+ reactData.labelFlag++;
375
+ }
376
+ };
315
377
  const triggerEvent = (evnt) => {
316
378
  const { inputValue } = reactData;
317
379
  dispatchEvent(evnt.type, { value: inputValue }, evnt);
@@ -357,7 +419,7 @@ export default defineVxeComponent({
357
419
  const inputEvent = (evnt) => {
358
420
  const inputElem = evnt.target;
359
421
  const value = inputElem.value;
360
- reactData.inputLabel = value;
422
+ handleInputLabel(value, true);
361
423
  dispatchEvent('input', { value }, evnt);
362
424
  };
363
425
  const changeEvent = (evnt) => {
@@ -366,18 +428,6 @@ export default defineVxeComponent({
366
428
  triggerEvent(evnt);
367
429
  }
368
430
  };
369
- const focusEvent = (evnt) => {
370
- const popupOpts = computePopupOpts.value;
371
- const { trigger } = popupOpts;
372
- reactData.isActivated = true;
373
- if (!trigger || trigger === 'default') {
374
- datePickerOpenEvent(evnt);
375
- }
376
- else if (trigger === 'icon') {
377
- hidePanel();
378
- }
379
- triggerEvent(evnt);
380
- };
381
431
  const clickPrefixEvent = (evnt) => {
382
432
  const isDisabled = computeIsDisabled.value;
383
433
  if (!isDisabled) {
@@ -394,6 +444,107 @@ export default defineVxeComponent({
394
444
  }, 350);
395
445
  });
396
446
  };
447
+ const dateChange = (date, isReload) => {
448
+ const { modelValue, multiple } = props;
449
+ const isDateTimeType = computeIsDateTimeType.value;
450
+ const dateValueFormat = computeDateValueFormat.value;
451
+ const firstDayOfWeek = computeFirstDayOfWeek.value;
452
+ if (props.type === 'week') {
453
+ const sWeek = XEUtils.toNumber(props.selectDay);
454
+ date = XEUtils.getWhatWeek(date, 0, sWeek, firstDayOfWeek);
455
+ }
456
+ const inpVal = XEUtils.toDateString(date, dateValueFormat, { firstDay: firstDayOfWeek });
457
+ if (multiple) {
458
+ const overCount = computeOverCount.value;
459
+ // 如果为多选
460
+ if (isDateTimeType) {
461
+ // 如果是datetime特殊类型
462
+ const dateListValue = isReload ? [] : [...computeDateListValue.value];
463
+ const datetimeRest = [];
464
+ const eqIndex = XEUtils.findIndexOf(dateListValue, val => XEUtils.isDateSame(date, val, 'yyyyMMdd'));
465
+ if (eqIndex === -1) {
466
+ if (overCount) {
467
+ // 如果超出最大多选数量
468
+ return;
469
+ }
470
+ dateListValue.push(date);
471
+ }
472
+ else {
473
+ dateListValue.splice(eqIndex, 1);
474
+ }
475
+ dateListValue.forEach(item => {
476
+ if (item) {
477
+ datetimeRest.push(item);
478
+ }
479
+ });
480
+ handleChange(datetimeRest.map(date => XEUtils.toDateString(date, dateValueFormat)).join(','), { type: 'update' });
481
+ }
482
+ else {
483
+ const dateMultipleValue = isReload ? [] : computeDateMultipleValue.value;
484
+ // 如果是日期类型
485
+ if (dateMultipleValue.some(val => XEUtils.isEqual(val, inpVal))) {
486
+ handleChange(dateMultipleValue.filter(val => !XEUtils.isEqual(val, inpVal)).join(','), { type: 'update' });
487
+ }
488
+ else {
489
+ if (overCount) {
490
+ // 如果超出最大多选数量
491
+ return;
492
+ }
493
+ handleChange(dateMultipleValue.concat([inpVal]).join(','), { type: 'update' });
494
+ }
495
+ }
496
+ }
497
+ else {
498
+ // 如果为单选
499
+ if (!XEUtils.isEqual(modelValue, inpVal)) {
500
+ handleChange(inpVal, { type: 'update' });
501
+ }
502
+ }
503
+ };
504
+ const dateRevert = () => {
505
+ const panelLabel = computePanelLabel.value;
506
+ handleInputLabel(panelLabel, true);
507
+ };
508
+ const afterCheckValue = (inpVal) => {
509
+ const { type } = props;
510
+ const { inputLabel } = internalData;
511
+ const dateLabelFormat = computeDateLabelFormat.value;
512
+ if (!inpVal) {
513
+ handleChange('', { type: 'check' });
514
+ return;
515
+ }
516
+ let inpDateVal = parseDateValue(inpVal, type, {
517
+ valueFormat: dateLabelFormat
518
+ });
519
+ if (!XEUtils.isValidDate(inpDateVal)) {
520
+ dateRevert();
521
+ return;
522
+ }
523
+ if (type === 'time') {
524
+ inpDateVal = XEUtils.toDateString(inpDateVal, dateLabelFormat);
525
+ if (inputLabel !== inpDateVal) {
526
+ handleChange(inpDateVal, { type: 'check' });
527
+ }
528
+ handleInputLabel(inpDateVal, true);
529
+ return;
530
+ }
531
+ let isChange = false;
532
+ const firstDayOfWeek = computeFirstDayOfWeek.value;
533
+ if (type === 'datetime') {
534
+ const dateValue = reactData.inputValue;
535
+ if (inpVal !== XEUtils.toDateString(dateValue, dateLabelFormat) || inpVal !== XEUtils.toDateString(inpDateVal, dateLabelFormat)) {
536
+ isChange = true;
537
+ }
538
+ }
539
+ else {
540
+ isChange = true;
541
+ }
542
+ const label = XEUtils.toDateString(inpDateVal, dateLabelFormat, { firstDay: firstDayOfWeek });
543
+ handleInputLabel(label, true);
544
+ if (isChange) {
545
+ dateChange(inpDateVal);
546
+ }
547
+ };
397
548
  const clearValueEvent = (evnt, value) => {
398
549
  const isDatePickerType = computeIsDatePickerType.value;
399
550
  if (isDatePickerType) {
@@ -409,29 +560,296 @@ export default defineVxeComponent({
409
560
  dispatchEvent('suffix-click', { value: inputValue }, evnt);
410
561
  }
411
562
  };
412
- const handleArrowInputDate = (evnt, isUpArrow) => {
563
+ const handleArrowInputDate = (evnt, isUpArrow, isDwArrow, isLtArrow, isRtArrow) => {
564
+ const { type, multiple } = props;
565
+ if (multiple) {
566
+ return;
567
+ }
568
+ const targetElem = refInputTarget.value;
569
+ if (!targetElem) {
570
+ return;
571
+ }
572
+ const inpValue = targetElem.value;
573
+ if (!inpValue) {
574
+ return;
575
+ }
576
+ const dateMaskedFormat = computeDateMaskedFormat.value;
577
+ const dateLabelFormat = computeDateLabelFormat.value;
578
+ const firstDayOfWeek = computeFirstDayOfWeek.value;
579
+ const maskChar = computeMaskChar.value;
580
+ const selectionStart = targetElem.selectionStart || 0;
581
+ let selectKey = dateMaskedFormat[selectionStart];
582
+ if (!parseInputKayMaps[selectKey]) {
583
+ selectKey = dateMaskedFormat[selectionStart - 1];
584
+ }
585
+ const skRest = dateMaskedFormat.match(new RegExp(selectKey + '+'));
586
+ if (!skRest) {
587
+ return;
588
+ }
589
+ if (isUpArrow || isDwArrow) {
590
+ const chunkFormat = skRest[0] || '';
591
+ const chunkStartIndex = skRest.index || 0;
592
+ const chunkEndIndex = chunkStartIndex + chunkFormat.length;
593
+ const chunkValue = inpValue.slice(chunkStartIndex, chunkEndIndex);
594
+ if (parseInputKayMaps[selectKey]) {
595
+ const chunkNum = (isAllSameChar(chunkValue, maskChar) ? getChunkDefaultNum(selectKey) : XEUtils.toNumber(chunkValue)) + (isUpArrow ? 1 : -1);
596
+ const restValue = inpValue.slice(0, chunkStartIndex) + XEUtils.padStart(chunkNum, chunkFormat.length, '0') + inpValue.slice(chunkEndIndex);
597
+ evnt.preventDefault();
598
+ if (restValue.indexOf(maskChar) === -1) {
599
+ // 解析日期
600
+ const inpDateVal = parseDateValue(restValue, type, {
601
+ valueFormat: dateLabelFormat
602
+ });
603
+ if (XEUtils.isValidDate(inpDateVal)) {
604
+ const label = XEUtils.toDateString(inpDateVal, dateLabelFormat, { firstDay: firstDayOfWeek });
605
+ targetElem.value = label;
606
+ handleInputLabel(label, false);
607
+ }
608
+ }
609
+ else {
610
+ targetElem.value = restValue;
611
+ handleInputLabel(restValue, false);
612
+ }
613
+ }
614
+ targetElem.setSelectionRange(chunkStartIndex, chunkEndIndex);
615
+ }
616
+ else if (isLtArrow || isRtArrow) {
617
+ const currKeyIndex = inputMaskedKeys.indexOf(selectKey);
618
+ if (currKeyIndex > -1) {
619
+ const allMaskedKeys = XEUtils.map(dateMaskedFormat.match(new RegExp(`(${inputMaskedKeys.join('|')})+`, 'g')) || [], fullKey => fullKey[0]);
620
+ const currIndex = XEUtils.findIndexOf(allMaskedKeys, key => selectKey === key[0]);
621
+ const targetFormatKey = isLtArrow ? (allMaskedKeys[currIndex - 1] || allMaskedKeys[0]) : (allMaskedKeys[currIndex + 1] || allMaskedKeys[allMaskedKeys.length - 1]);
622
+ const targetKey = targetFormatKey ? targetFormatKey[0] : '';
623
+ const sktRest = dateMaskedFormat.match(new RegExp(targetKey + '+'));
624
+ if (sktRest) {
625
+ evnt.preventDefault();
626
+ const mtStartIndex = sktRest.index || 0;
627
+ const mtEndIndex = mtStartIndex + sktRest[0].length;
628
+ targetElem.setSelectionRange(mtStartIndex, mtEndIndex);
629
+ }
630
+ }
631
+ }
632
+ internalData.isTriggerMasked = true;
633
+ };
634
+ const handleMaskedInputDate = (evnt) => {
413
635
  const { multiple } = props;
414
636
  if (multiple) {
415
637
  return;
416
638
  }
417
- const { inputValue } = reactData;
418
- if (!inputValue) {
639
+ const targetElem = refInputTarget.value;
640
+ if (!targetElem) {
641
+ return;
642
+ }
643
+ const isControlKey = hasControlKey(evnt);
644
+ if (isControlKey) {
645
+ return;
646
+ }
647
+ evnt.preventDefault();
648
+ const eKey = evnt.key;
649
+ const isDeleleKey = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.DELETE);
650
+ const isBackspaceKey = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.BACKSPACE);
651
+ const isNumKey = eKey >= '0' && eKey <= '9';
652
+ const numKey = isNumKey ? evnt.key : '';
653
+ if (!(isDeleleKey || isBackspaceKey || isNumKey)) {
654
+ return;
655
+ }
656
+ const { isTriggerMasked } = internalData;
657
+ const dateMaskedFormat = computeDateMaskedFormat.value;
658
+ const maskChar = computeMaskChar.value;
659
+ let inpValue = targetElem.value || dateMaskedFormat;
660
+ const selectionStart = targetElem.selectionStart || 0;
661
+ const selectionEnd = targetElem.selectionEnd || 0;
662
+ let selectKey = dateMaskedFormat[selectionStart];
663
+ if (!parseInputKayMaps[selectKey]) {
664
+ selectKey = dateMaskedFormat[selectionStart - 1];
665
+ }
666
+ const skRest = dateMaskedFormat.match(new RegExp(selectKey + '+'));
667
+ if (!skRest) {
668
+ return;
669
+ }
670
+ const allMaskedKeys = XEUtils.map(dateMaskedFormat.match(new RegExp(`(${inputMaskedKeys.join('|')})+`, 'g')) || [], fullKey => fullKey[0]);
671
+ const chunkFormat = skRest[0] || '';
672
+ const chunkStartIndex = skRest.index || 0;
673
+ const chunkEndIndex = chunkStartIndex + chunkFormat.length;
674
+ const currKeyIndex = allMaskedKeys.indexOf(selectKey);
675
+ // 全选 | 如果无效字符
676
+ const isAllSelected = !selectionStart && selectionEnd === inpValue.length;
677
+ const isNotMasked = inpValue && inpValue.length !== dateMaskedFormat.length;
678
+ if (isAllSelected || isNotMasked) {
679
+ inpValue = dateMaskedFormat;
680
+ }
681
+ let chunkValue = isDeleleKey ? '' : inpValue.slice(chunkStartIndex, chunkEndIndex);
682
+ const chunkNums = (chunkValue.match(/\d/g) || []);
683
+ const chunkNumList = isTriggerMasked && !isBackspaceKey ? [] : chunkNums.slice(0);
684
+ if (isNumKey) {
685
+ chunkNumList.push(numKey);
686
+ }
687
+ else if (isBackspaceKey) {
688
+ chunkNumList.pop();
689
+ }
690
+ chunkValue = chunkNumList.join('').padEnd(chunkFormat.length, maskChar);
691
+ let restValue = inpValue.slice(0, chunkStartIndex) + chunkValue + inpValue.slice(chunkEndIndex);
692
+ restValue = restValue.replace(new RegExp(`(${inputMaskedKeys.join('|')})`, 'g'), maskChar);
693
+ targetElem.value = restValue;
694
+ handleInputLabel(restValue, false);
695
+ // 如果是全选/删除
696
+ if (isAllSelected) {
697
+ if (isBackspaceKey || isDeleleKey) {
698
+ const firstMaskedKeys = allMaskedKeys[0];
699
+ const firstSkRest = dateMaskedFormat.match(new RegExp(`${firstMaskedKeys}+`));
700
+ if (firstSkRest) {
701
+ const firstChunkFormat = firstSkRest[0];
702
+ targetElem.setSelectionRange(0, firstChunkFormat.length);
703
+ internalData.isTriggerMasked = true;
704
+ return;
705
+ }
706
+ }
707
+ }
708
+ else {
709
+ if (isBackspaceKey && !chunkNums.length) {
710
+ // 回退到上一个数字块
711
+ for (let i = currKeyIndex - 1; i >= 0; i--) {
712
+ const prveChunkKey = allMaskedKeys[i];
713
+ const prveSkRest = dateMaskedFormat.match(new RegExp(`${prveChunkKey}+`));
714
+ if (prveSkRest) {
715
+ const prveChunkFormat = prveSkRest[0];
716
+ const prveChunkStartIndex = prveSkRest.index || 0;
717
+ const prveChunkEndIndex = prveChunkStartIndex + prveChunkFormat.length;
718
+ let prveChunkValue = restValue.slice(prveChunkStartIndex, prveChunkEndIndex);
719
+ const prveChunkNums = (prveChunkValue.match(/\d/g) || []);
720
+ if (prveChunkNums.length) {
721
+ prveChunkNums.pop();
722
+ prveChunkValue = prveChunkNums.join('').padEnd(prveChunkFormat.length, maskChar);
723
+ restValue = restValue.slice(0, prveChunkStartIndex) + prveChunkValue + restValue.slice(prveChunkEndIndex);
724
+ targetElem.value = restValue;
725
+ handleInputLabel(restValue, false);
726
+ targetElem.setSelectionRange(prveChunkStartIndex, prveChunkEndIndex);
727
+ return;
728
+ }
729
+ }
730
+ }
731
+ const firstMaskedKeys = allMaskedKeys[0];
732
+ const firstSkRest = dateMaskedFormat.match(new RegExp(`${firstMaskedKeys}+`));
733
+ if (firstSkRest) {
734
+ const firstChunkFormat = firstSkRest[0];
735
+ restValue = dateMaskedFormat.replace(new RegExp(`(${inputMaskedKeys.join('|')})`, 'g'), maskChar);
736
+ targetElem.value = restValue;
737
+ handleInputLabel(restValue, false);
738
+ targetElem.setSelectionRange(0, firstChunkFormat.length);
739
+ internalData.isTriggerMasked = true;
740
+ return;
741
+ }
742
+ return;
743
+ }
744
+ }
745
+ let maskStartIndex = skRest.index || 0;
746
+ let maskEndIndex = maskStartIndex + skRest[0].length;
747
+ // 如果输入完成,跳转下一个
748
+ if (chunkNumList.length >= chunkValue.length) {
749
+ const nextKeys = allMaskedKeys.slice(currKeyIndex + 1);
750
+ if (currKeyIndex > -1) {
751
+ const nextRest = nextKeys.length ? dateMaskedFormat.match(new RegExp(`(${nextKeys.join('|')})+`)) : null;
752
+ // 如果当前数字块已输入,则跳转下一个数字块
753
+ if (nextRest) {
754
+ maskStartIndex = nextRest.index || 0;
755
+ maskEndIndex = maskStartIndex + nextRest[0].length;
756
+ targetElem.setSelectionRange(maskStartIndex, maskEndIndex);
757
+ }
758
+ else {
759
+ targetElem.setSelectionRange(maskStartIndex, maskEndIndex);
760
+ }
761
+ }
762
+ internalData.isTriggerMasked = true;
763
+ return;
764
+ }
765
+ targetElem.setSelectionRange(maskStartIndex, maskEndIndex);
766
+ internalData.isTriggerMasked = false;
767
+ };
768
+ const handleMaskedSelectedDate = (evnt, isFocus) => {
769
+ const { type, multiple, modelValue } = props;
770
+ if (multiple) {
771
+ return;
772
+ }
773
+ if (!maskedTypes.includes(type)) {
419
774
  return;
420
775
  }
421
776
  const targetElem = refInputTarget.value;
422
777
  if (!targetElem) {
423
778
  return;
424
779
  }
425
- const { parseInputKayMaps } = internalData;
426
- const inputFormat = computeDateInputFormat.value;
780
+ const { laseFocusMasked } = internalData;
781
+ if (laseFocusMasked && Date.now() - laseFocusMasked < 100) {
782
+ return;
783
+ }
784
+ const dateMaskedFormat = computeDateMaskedFormat.value;
785
+ const maskChar = computeMaskChar.value;
427
786
  const selectionStart = targetElem.selectionStart || 0;
428
- let selectKey = inputFormat[selectionStart];
787
+ const selectionEnd = targetElem.selectionEnd || 0;
788
+ const inpValue = targetElem.value;
789
+ const allMaskedKeys = XEUtils.map(dateMaskedFormat.match(new RegExp(`(${inputMaskedKeys.join('|')})+`, 'g')) || [], fullKey => fullKey[0]);
790
+ // 如果为空
791
+ if (!inpValue) {
792
+ let restValue = dateMaskedFormat.replace(new RegExp(`(${inputMaskedKeys.join('|')})`, 'g'), maskChar);
793
+ // 还原值
794
+ if (isFocus && modelValue) {
795
+ const chunkNums = (('' + XEUtils.toNumber(modelValue)).match(/\d/g) || []);
796
+ let useNumIndex = 0;
797
+ restValue = dateMaskedFormat.replace(new RegExp(`(${inputMaskedKeys.join('|')})`, 'g'), (txt) => chunkNums[useNumIndex++] || txt);
798
+ }
799
+ const firstMaskedKeys = allMaskedKeys[0];
800
+ const firstSkRest = dateMaskedFormat.match(new RegExp(`${firstMaskedKeys}+`));
801
+ if (firstSkRest) {
802
+ evnt.preventDefault();
803
+ const firstChunkFormat = firstSkRest[0];
804
+ targetElem.value = restValue;
805
+ handleInputLabel(restValue, false);
806
+ targetElem.setSelectionRange(0, firstChunkFormat.length);
807
+ internalData.laseFocusMasked = Date.now();
808
+ return;
809
+ }
810
+ }
811
+ // 全选 | 如果无效字符
812
+ const isAllSelected = !selectionStart && selectionEnd === inpValue.length;
813
+ const isNotMasked = inpValue && inpValue.length !== dateMaskedFormat.length;
814
+ if (isAllSelected || isNotMasked) {
815
+ let restValue = '';
816
+ // 还原值
817
+ if (isNotMasked && inpValue) {
818
+ const chunkNums = inpValue.match(/\d/g) || [];
819
+ let useNumIndex = 0;
820
+ restValue = dateMaskedFormat.replace(new RegExp(`(${inputMaskedKeys.join('|')})`, 'g'), () => chunkNums[useNumIndex++] || maskChar);
821
+ }
822
+ else {
823
+ dateMaskedFormat.replace(new RegExp(`(${inputMaskedKeys.join('|')})`, 'g'), maskChar);
824
+ }
825
+ const firstMaskedKeys = allMaskedKeys[0];
826
+ const firstSkRest = dateMaskedFormat.match(new RegExp(`${firstMaskedKeys}+`));
827
+ if (firstSkRest) {
828
+ evnt.preventDefault();
829
+ const firstChunkFormat = firstSkRest[0];
830
+ targetElem.value = restValue;
831
+ handleInputLabel(restValue, false);
832
+ targetElem.setSelectionRange(0, firstChunkFormat.length);
833
+ internalData.laseFocusMasked = Date.now();
834
+ return;
835
+ }
836
+ }
837
+ // 是否选择数字块
838
+ let selectKey = dateMaskedFormat[selectionStart];
429
839
  if (!parseInputKayMaps[selectKey]) {
430
- selectKey = inputFormat[selectionStart - 1];
840
+ selectKey = dateMaskedFormat[selectionStart - 1];
431
841
  }
432
- const inputPaesrFn = parseInputKayMaps[selectKey];
433
- if (inputPaesrFn) {
434
- inputPaesrFn(evnt, targetElem, isUpArrow);
842
+ if (selectKey) {
843
+ evnt.preventDefault();
844
+ const skRest = dateMaskedFormat.match(new RegExp(selectKey + '+'));
845
+ if (skRest) {
846
+ const chunkFormat = skRest[0] || '';
847
+ const chunkStartIndex = skRest.index || 0;
848
+ const chunkEndIndex = chunkStartIndex + chunkFormat.length;
849
+ targetElem.setSelectionRange(chunkStartIndex, chunkEndIndex);
850
+ internalData.isTriggerMasked = true;
851
+ internalData.laseFocusMasked = Date.now();
852
+ }
435
853
  }
436
854
  };
437
855
  const blurEvent = (evnt) => {
@@ -443,10 +861,14 @@ export default defineVxeComponent({
443
861
  handleChange(value, evnt);
444
862
  }
445
863
  if (!reactData.visiblePanel) {
864
+ const { inputLabel } = internalData;
446
865
  reactData.isActivated = false;
447
866
  // 未打开面板时才校验
448
867
  if ($datePanel) {
449
- $datePanel.checkValue(reactData.inputLabel);
868
+ $datePanel.checkValue(inputLabel);
869
+ }
870
+ else {
871
+ afterCheckValue(inputLabel);
450
872
  }
451
873
  }
452
874
  dispatchEvent('blur', { value }, evnt);
@@ -455,13 +877,80 @@ export default defineVxeComponent({
455
877
  $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, value);
456
878
  }
457
879
  };
880
+ const focusEvent = (evnt) => {
881
+ const { multiple, editable, maskedConfig } = props;
882
+ const maskedOpts = computeMaskedOpts.value;
883
+ const popupOpts = computePopupOpts.value;
884
+ const { trigger } = popupOpts;
885
+ reactData.isActivated = true;
886
+ if (!trigger || trigger === 'default') {
887
+ datePickerOpenEvent(evnt);
888
+ setTimeout(() => {
889
+ if (editable && !multiple && (isEnableConf(maskedConfig) || maskedOpts.enabled)) {
890
+ handleMaskedSelectedDate(evnt, true);
891
+ }
892
+ }, 15);
893
+ }
894
+ else if (trigger === 'icon') {
895
+ hidePanel();
896
+ setTimeout(() => {
897
+ if (editable && !multiple && (isEnableConf(maskedConfig) || maskedOpts.enabled)) {
898
+ handleMaskedSelectedDate(evnt, true);
899
+ }
900
+ }, 15);
901
+ }
902
+ else {
903
+ if (editable && !multiple && (isEnableConf(maskedConfig) || maskedOpts.enabled)) {
904
+ handleMaskedSelectedDate(evnt, true);
905
+ }
906
+ }
907
+ triggerEvent(evnt);
908
+ };
909
+ const clickEvent = (evnt) => {
910
+ const { editable, maskedConfig } = props;
911
+ const maskedOpts = computeMaskedOpts.value;
912
+ if (editable && (isEnableConf(maskedConfig) || maskedOpts.enabled)) {
913
+ handleMaskedSelectedDate(evnt);
914
+ }
915
+ triggerEvent(evnt);
916
+ };
458
917
  const keydownEvent = (evnt) => {
459
- const { controlConfig } = props;
460
- const controlOpts = computeControlOpts.value;
918
+ const { type, editable, maskedConfig } = props;
919
+ const { visiblePanel } = reactData;
920
+ const maskedOpts = computeMaskedOpts.value;
461
921
  const isUpArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_UP);
462
922
  const isDwArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_DOWN);
463
- if ((isUpArrow || isDwArrow) && controlOpts.isArrow && (controlConfig || controlOpts.enabled)) {
464
- handleArrowInputDate(evnt, isUpArrow);
923
+ const isLtArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_LEFT);
924
+ const isRtArrow = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ARROW_RIGHT);
925
+ const isEnter = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ENTER);
926
+ if (editable) {
927
+ if (isEnter) {
928
+ const $datePanel = refDatePanel.value;
929
+ const { inputLabel } = internalData;
930
+ const targetElem = refInputTarget.value;
931
+ if (visiblePanel) {
932
+ hidePanel();
933
+ }
934
+ if ($datePanel) {
935
+ $datePanel.checkValue(inputLabel);
936
+ }
937
+ else {
938
+ afterCheckValue(inputLabel);
939
+ }
940
+ if (targetElem) {
941
+ targetElem.blur();
942
+ }
943
+ }
944
+ else if (maskedTypes.includes(type)) {
945
+ if (isEnableConf(maskedConfig) || maskedOpts.enabled) {
946
+ if (maskedOpts.isArrow && (isUpArrow || isDwArrow || isLtArrow || isRtArrow)) {
947
+ handleArrowInputDate(evnt, isUpArrow, isDwArrow, isLtArrow, isRtArrow);
948
+ }
949
+ else if (maskedOpts.isMasked) {
950
+ handleMaskedInputDate(evnt);
951
+ }
952
+ }
953
+ }
465
954
  }
466
955
  triggerEvent(evnt);
467
956
  };
@@ -490,7 +979,7 @@ export default defineVxeComponent({
490
979
  dispatchEvent('confirm', params, params.$event);
491
980
  };
492
981
  const panelRevertEvent = (params) => {
493
- reactData.inputLabel = params.label;
982
+ handleInputLabel(params.label, true);
494
983
  };
495
984
  // 全局事件
496
985
  const handleGlobalMousedownEvent = (evnt) => {
@@ -500,25 +989,34 @@ export default defineVxeComponent({
500
989
  const panelWrapperElem = refPanelWrapper.value;
501
990
  const isDisabled = computeIsDisabled.value;
502
991
  if (!isDisabled && isActivated) {
503
- reactData.isActivated = getEventTargetNode(evnt, el).flag || getEventTargetNode(evnt, panelWrapperElem).flag;
504
- if (!reactData.isActivated) {
992
+ const currActivated = getEventTargetNode(evnt, el).flag || getEventTargetNode(evnt, panelWrapperElem).flag;
993
+ if (currActivated !== isActivated) {
994
+ reactData.isActivated = currActivated;
995
+ }
996
+ if (!currActivated) {
505
997
  if (visiblePanel) {
506
998
  hidePanel();
999
+ const { inputLabel } = internalData;
507
1000
  if ($datePanel) {
508
- $datePanel.checkValue(reactData.inputLabel);
1001
+ $datePanel.checkValue(inputLabel);
1002
+ }
1003
+ else {
1004
+ afterCheckValue(inputLabel);
509
1005
  }
510
1006
  }
511
1007
  }
512
1008
  }
513
1009
  };
514
1010
  const handleGlobalKeydownEvent = (evnt) => {
515
- const { visiblePanel } = reactData;
1011
+ const { isActivated, visiblePanel } = reactData;
516
1012
  const isDisabled = computeIsDisabled.value;
517
1013
  if (!isDisabled) {
518
1014
  const isTab = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.TAB);
519
1015
  const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE);
520
1016
  if (isTab) {
521
- reactData.isActivated = false;
1017
+ if (isActivated) {
1018
+ reactData.isActivated = false;
1019
+ }
522
1020
  }
523
1021
  if (visiblePanel) {
524
1022
  if (isEsc || isTab) {
@@ -553,7 +1051,7 @@ export default defineVxeComponent({
553
1051
  }
554
1052
  if (visiblePanel || isActivated) {
555
1053
  if ($datePanel) {
556
- $datePanel.checkValue(reactData.inputLabel);
1054
+ $datePanel.checkValue(internalData.inputLabel);
557
1055
  }
558
1056
  const targetElem = refInputTarget.value;
559
1057
  if (targetElem) {
@@ -645,9 +1143,6 @@ export default defineVxeComponent({
645
1143
  }
646
1144
  }
647
1145
  };
648
- const clickEvent = (evnt) => {
649
- triggerEvent(evnt);
650
- };
651
1146
  const handleShortcutEvent = ({ option, $event }) => {
652
1147
  const { type } = props;
653
1148
  const { inputValue } = reactData;
@@ -686,7 +1181,7 @@ export default defineVxeComponent({
686
1181
  break;
687
1182
  }
688
1183
  default:
689
- errLog('vxe.error.notCommands', [`[date-picker] ${code}`]);
1184
+ errLog('vxe.error.notCommands', [code]);
690
1185
  break;
691
1186
  }
692
1187
  }
@@ -971,7 +1466,8 @@ export default defineVxeComponent({
971
1466
  };
972
1467
  const renderVN = () => {
973
1468
  const { className, type, name, autoComplete } = props;
974
- const { inputValue, inputLabel, visiblePanel, isActivated } = reactData;
1469
+ const { inputValue, visiblePanel, isActivated, labelFlag } = reactData;
1470
+ const { inputLabel } = internalData;
975
1471
  const vSize = computeSize.value;
976
1472
  const isDisabled = computeIsDisabled.value;
977
1473
  const formReadonly = computeFormReadonly.value;
@@ -1007,7 +1503,7 @@ export default defineVxeComponent({
1007
1503
  h('input', {
1008
1504
  ref: refInputTarget,
1009
1505
  class: 'vxe-date-picker--inner',
1010
- value: inputLabel,
1506
+ value: labelFlag ? inputLabel : '',
1011
1507
  name,
1012
1508
  type: 'text',
1013
1509
  placeholder: inpPlaceholder,
@@ -1029,7 +1525,7 @@ export default defineVxeComponent({
1029
1525
  ]);
1030
1526
  };
1031
1527
  watch(computePanelLabel, (val) => {
1032
- reactData.inputLabel = val;
1528
+ handleInputLabel(val, true);
1033
1529
  });
1034
1530
  watch(() => props.modelValue, () => {
1035
1531
  updateModelValue();
@@ -1042,13 +1538,15 @@ export default defineVxeComponent({
1042
1538
  globalEvents.on($xeDatePicker, 'resize', handleGlobalResizeEvent);
1043
1539
  });
1044
1540
  onMounted(() => {
1045
- const { parseInputKayMaps } = internalData;
1046
- const inputKeys = ['y', 'M', 'd', 'H', 'm', 'n'];
1047
- inputKeys.forEach(key => {
1048
- parseInputKayMaps[key] = (evnt) => {
1049
- evnt.preventDefault();
1050
- };
1051
- });
1541
+ const { type, multiple, maskedConfig } = props;
1542
+ if (isEnableConf(maskedConfig)) {
1543
+ if (multiple) {
1544
+ errLog('vxe.error.notSupportProp', ['multiple', 'control-config.enabled=true', 'control-config.enabled=false']);
1545
+ }
1546
+ if (!maskedTypes.includes(type)) {
1547
+ warnLog('vxe.error.notSupportProp', ['control-config.enabled=true', `type=${type}`, `type=${maskedTypes.join('|')}`]);
1548
+ }
1549
+ }
1052
1550
  });
1053
1551
  onUnmounted(() => {
1054
1552
  globalEvents.off($xeDatePicker, 'mousewheel');