@vaadin/date-time-picker 23.0.0-alpha1 → 23.0.0-alpha5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/date-time-picker",
3
- "version": "23.0.0-alpha1",
3
+ "version": "23.0.0-alpha5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "main": "vaadin-date-time-picker.js",
20
20
  "module": "vaadin-date-time-picker.js",
21
+ "type": "module",
21
22
  "files": [
22
23
  "src",
23
24
  "theme",
@@ -33,19 +34,19 @@
33
34
  ],
34
35
  "dependencies": {
35
36
  "@polymer/polymer": "^3.0.0",
36
- "@vaadin/component-base": "23.0.0-alpha1",
37
- "@vaadin/custom-field": "23.0.0-alpha1",
38
- "@vaadin/date-picker": "23.0.0-alpha1",
39
- "@vaadin/field-base": "23.0.0-alpha1",
40
- "@vaadin/time-picker": "23.0.0-alpha1",
41
- "@vaadin/vaadin-lumo-styles": "23.0.0-alpha1",
42
- "@vaadin/vaadin-material-styles": "23.0.0-alpha1",
43
- "@vaadin/vaadin-themable-mixin": "23.0.0-alpha1"
37
+ "@vaadin/component-base": "23.0.0-alpha5",
38
+ "@vaadin/custom-field": "23.0.0-alpha5",
39
+ "@vaadin/date-picker": "23.0.0-alpha5",
40
+ "@vaadin/field-base": "23.0.0-alpha5",
41
+ "@vaadin/time-picker": "23.0.0-alpha5",
42
+ "@vaadin/vaadin-lumo-styles": "23.0.0-alpha5",
43
+ "@vaadin/vaadin-material-styles": "23.0.0-alpha5",
44
+ "@vaadin/vaadin-themable-mixin": "23.0.0-alpha5"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@esm-bundle/chai": "^4.3.4",
47
48
  "@vaadin/testing-helpers": "^0.3.2",
48
49
  "sinon": "^9.2.1"
49
50
  },
50
- "gitHead": "fbcb07328fdf88260e3b461088d207426b21c710"
51
+ "gitHead": "74f9294964eb8552d96578c14af6ad214f5257bc"
51
52
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 Vaadin Ltd.
3
+ * Copyright (c) 2019 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { DatePicker } from '@vaadin/date-picker/src/vaadin-date-picker.js';
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 Vaadin Ltd.
3
+ * Copyright (c) 2019 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { TimePicker } from '@vaadin/time-picker/src/vaadin-time-picker.js';
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 Vaadin Ltd.
3
+ * Copyright (c) 2019 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
7
7
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
8
+ import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
8
9
  import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
9
10
  import { DatePickerI18n } from '@vaadin/date-picker/src/vaadin-date-picker.js';
10
11
  import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
@@ -69,6 +70,8 @@ export interface DateTimePickerEventMap extends DateTimePickerCustomEventMap, HT
69
70
  * Attribute | Description | Part name
70
71
  * --------------------|-------------------------------------------|------------
71
72
  * `disabled` | Set when the element is disabled | :host
73
+ * `focused` | Set when the element is focused | :host
74
+ * `focus-ring` | Set when the element is keyboard focused | :host
72
75
  * `readonly` | Set when the element is readonly | :host
73
76
  * `invalid` | Set when the element is invalid | :host
74
77
  * `has-label` | Set when the element has a label | :host
@@ -93,7 +96,9 @@ export interface DateTimePickerEventMap extends DateTimePickerCustomEventMap, HT
93
96
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
94
97
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
95
98
  */
96
- declare class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(ElementMixin(HTMLElement))))) {
99
+ declare class DateTimePicker extends FieldMixin(
100
+ SlotMixin(DisabledMixin(FocusMixin(ThemableMixin(ElementMixin(HTMLElement)))))
101
+ ) {
97
102
  /**
98
103
  * The name of the control, which is submitted with the form data.
99
104
  */
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2021 Vaadin Ltd.
3
+ * Copyright (c) 2019 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import './vaadin-date-time-picker-date-picker.js';
7
7
  import './vaadin-date-time-picker-time-picker.js';
8
+ import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
8
9
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
9
10
  import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js';
10
11
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
12
+ import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
11
13
  import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
12
14
  import { dateEquals } from '@vaadin/date-picker/src/vaadin-date-picker-helper.js';
13
15
  import { FieldMixin } from '@vaadin/field-base/src/field-mixin.js';
@@ -25,14 +27,14 @@ registerStyles('vaadin-date-time-picker', inputFieldShared, { moduleId: 'vaadin-
25
27
  */
26
28
 
27
29
  // Find a property definition from the prototype chain of a Polymer element class
28
- const getPropertyFromPrototype = function (clazz, prop) {
30
+ function getPropertyFromPrototype(clazz, prop) {
29
31
  while (clazz) {
30
32
  if (clazz.properties && clazz.properties[prop]) {
31
33
  return clazz.properties[prop];
32
34
  }
33
- clazz = clazz.__proto__;
35
+ clazz = Object.getPrototypeOf(clazz);
34
36
  }
35
- };
37
+ }
36
38
 
37
39
  const datePickerClass = customElements.get('vaadin-date-time-picker-date-picker');
38
40
  const timePickerClass = customElements.get('vaadin-date-time-picker-time-picker');
@@ -70,6 +72,8 @@ const timePickerI18nProps = Object.keys(timePickerI18nDefaults);
70
72
  * Attribute | Description | Part name
71
73
  * --------------------|-------------------------------------------|------------
72
74
  * `disabled` | Set when the element is disabled | :host
75
+ * `focused` | Set when the element is focused | :host
76
+ * `focus-ring` | Set when the element is keyboard focused | :host
73
77
  * `readonly` | Set when the element is readonly | :host
74
78
  * `invalid` | Set when the element is invalid | :host
75
79
  * `has-label` | Set when the element has a label | :host
@@ -97,11 +101,14 @@ const timePickerI18nProps = Object.keys(timePickerI18nDefaults);
97
101
  * @extends HTMLElement
98
102
  * @mixes ElementMixin
99
103
  * @mixes ThemableMixin
104
+ * @mixes FocusMixin
100
105
  * @mixes DisabledMixin
101
106
  * @mixes SlotMixin
102
107
  * @mixes FieldMixin
103
108
  */
104
- class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(ElementMixin(PolymerElement))))) {
109
+ class DateTimePicker extends FieldMixin(
110
+ SlotMixin(DisabledMixin(FocusMixin(ThemableMixin(ElementMixin(PolymerElement)))))
111
+ ) {
105
112
  static get template() {
106
113
  return html`
107
114
  <style>
@@ -326,7 +333,25 @@ class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(El
326
333
  */
327
334
  i18n: {
328
335
  type: Object,
329
- value: () => Object.assign({}, datePickerI18nDefaults, timePickerI18nDefaults)
336
+ value: () => ({ ...datePickerI18nDefaults, ...timePickerI18nDefaults })
337
+ },
338
+
339
+ /**
340
+ * The current slotted date picker.
341
+ * @private
342
+ */
343
+ __datePicker: {
344
+ type: HTMLElement,
345
+ observer: '__datePickerChanged'
346
+ },
347
+
348
+ /**
349
+ * The current slotted time picker.
350
+ * @private
351
+ */
352
+ __timePicker: {
353
+ type: HTMLElement,
354
+ observer: '__timePickerChanged'
330
355
  }
331
356
  };
332
357
  }
@@ -378,6 +403,10 @@ class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(El
378
403
 
379
404
  this.__changeEventHandler = this.__changeEventHandler.bind(this);
380
405
  this.__valueChangedEventHandler = this.__valueChangedEventHandler.bind(this);
406
+
407
+ this._observer = new FlattenedNodesObserver(this, (info) => {
408
+ this.__onDomChange(info.addedNodes);
409
+ });
381
410
  }
382
411
 
383
412
  /** @protected */
@@ -390,11 +419,8 @@ class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(El
390
419
  }
391
420
  });
392
421
 
393
- this.__datePickerChanged();
394
- this.__timePickerChanged();
395
-
396
- this.$.dateSlot.addEventListener('slotchange', this.__datePickerChanged.bind(this));
397
- this.$.timeSlot.addEventListener('slotchange', this.__timePickerChanged.bind(this));
422
+ this.__datePicker = this._getDirectSlotChild('date-picker');
423
+ this.__timePicker = this._getDirectSlotChild('time-picker');
398
424
 
399
425
  if (this.autofocus && !this.disabled) {
400
426
  window.requestAnimationFrame(() => this.focus());
@@ -414,6 +440,28 @@ class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(El
414
440
  this.__datePicker.focus();
415
441
  }
416
442
 
443
+ /**
444
+ * Override method inherited from `FocusMixin` to not remove focused
445
+ * state when focus moves between pickers or to the overlay.
446
+ * @param {FocusEvent} event
447
+ * @return {boolean}
448
+ * @protected
449
+ * @override
450
+ */
451
+ _shouldRemoveFocus(event) {
452
+ const target = event.relatedTarget;
453
+
454
+ if (
455
+ this.__datePicker.contains(target) ||
456
+ this.__timePicker.contains(target) ||
457
+ target === this.__datePicker.$.overlay
458
+ ) {
459
+ return false;
460
+ }
461
+
462
+ return true;
463
+ }
464
+
417
465
  /** @private */
418
466
  __syncI18n(target, source, props) {
419
467
  props = props || Object.keys(source.i18n);
@@ -449,87 +497,98 @@ class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(El
449
497
  }
450
498
 
451
499
  /** @private */
452
- __datePickerChanged() {
453
- const datePicker = this._getDirectSlotChild('date-picker');
454
- if (this.__datePicker === datePicker || !datePicker) {
500
+ __onDomChange(addedNodes) {
501
+ addedNodes
502
+ .filter((node) => node.nodeType === Node.ELEMENT_NODE)
503
+ .forEach((node) => {
504
+ const slotAttributeValue = node.getAttribute('slot');
505
+
506
+ if (slotAttributeValue === 'date-picker') {
507
+ this.__datePicker = node;
508
+ } else if (slotAttributeValue === 'time-picker') {
509
+ this.__timePicker = node;
510
+ }
511
+ });
512
+ }
513
+
514
+ /** @private */
515
+ __datePickerChanged(newDatePicker, existingDatePicker) {
516
+ if (!newDatePicker) {
455
517
  return;
456
518
  }
457
- if (this.__datePicker) {
519
+ if (existingDatePicker) {
458
520
  // Remove an existing date picker
459
- this.__removeInputListeners(this.__datePicker);
460
- this.__datePicker.remove();
521
+ this.__removeInputListeners(existingDatePicker);
522
+ existingDatePicker.remove();
461
523
  }
462
524
 
463
- this.__addInputListeners(datePicker);
464
- this.__datePicker = datePicker;
525
+ this.__addInputListeners(newDatePicker);
465
526
 
466
- if (datePicker.__defaultPicker) {
527
+ if (newDatePicker.__defaultPicker) {
467
528
  // Synchronize properties to default date picker
468
- datePicker.placeholder = this.datePlaceholder;
469
- datePicker.invalid = this.invalid;
470
- datePicker.initialPosition = this.initialPosition;
471
- datePicker.showWeekNumbers = this.showWeekNumbers;
472
- this.__syncI18n(datePicker, this, datePickerI18nProps);
529
+ newDatePicker.placeholder = this.datePlaceholder;
530
+ newDatePicker.invalid = this.invalid;
531
+ newDatePicker.initialPosition = this.initialPosition;
532
+ newDatePicker.showWeekNumbers = this.showWeekNumbers;
533
+ this.__syncI18n(newDatePicker, this, datePickerI18nProps);
473
534
  } else {
474
535
  // Synchronize properties from slotted date picker
475
- this.datePlaceholder = datePicker.placeholder;
476
- this.initialPosition = datePicker.initialPosition;
477
- this.showWeekNumbers = datePicker.showWeekNumbers;
478
- this.__syncI18n(this, datePicker, datePickerI18nProps);
536
+ this.datePlaceholder = newDatePicker.placeholder;
537
+ this.initialPosition = newDatePicker.initialPosition;
538
+ this.showWeekNumbers = newDatePicker.showWeekNumbers;
539
+ this.__syncI18n(this, newDatePicker, datePickerI18nProps);
479
540
  }
480
541
 
481
542
  // min and max are always synchronized from date time picker (host) to inner fields because time picker
482
543
  // min and max need to be dynamically set depending on currently selected date instead of simple propagation
483
- datePicker.min = this.__formatDateISO(this.__minDateTime, this.__defaultDateMinMaxValue);
484
- datePicker.max = this.__formatDateISO(this.__maxDateTime, this.__defaultDateMinMaxValue);
485
- datePicker.required = this.required;
486
- datePicker.disabled = this.disabled;
487
- datePicker.readonly = this.readonly;
488
- datePicker.autoOpenDisabled = this.autoOpenDisabled;
544
+ newDatePicker.min = this.__formatDateISO(this.__minDateTime, this.__defaultDateMinMaxValue);
545
+ newDatePicker.max = this.__formatDateISO(this.__maxDateTime, this.__defaultDateMinMaxValue);
546
+ newDatePicker.required = this.required;
547
+ newDatePicker.disabled = this.disabled;
548
+ newDatePicker.readonly = this.readonly;
549
+ newDatePicker.autoOpenDisabled = this.autoOpenDisabled;
489
550
 
490
551
  // Disable default internal validation for the component
491
- datePicker.validate = () => {};
492
- datePicker._validateInput = () => {};
552
+ newDatePicker.validate = () => {};
553
+ newDatePicker._validateInput = () => {};
493
554
  }
494
555
 
495
556
  /** @private */
496
- __timePickerChanged() {
497
- const timePicker = this._getDirectSlotChild('time-picker');
498
- if (this.__timePicker === timePicker || !timePicker) {
557
+ __timePickerChanged(newTimePicker, existingTimePicker) {
558
+ if (!newTimePicker) {
499
559
  return;
500
560
  }
501
- if (this.__timePicker) {
561
+ if (existingTimePicker) {
502
562
  // Remove an existing time picker
503
- this.__removeInputListeners(this.__timePicker);
504
- this.__timePicker.remove();
563
+ this.__removeInputListeners(existingTimePicker);
564
+ existingTimePicker.remove();
505
565
  }
506
566
 
507
- this.__addInputListeners(timePicker);
508
- this.__timePicker = timePicker;
567
+ this.__addInputListeners(newTimePicker);
509
568
 
510
- if (timePicker.__defaultPicker) {
569
+ if (newTimePicker.__defaultPicker) {
511
570
  // Synchronize properties to default time picker
512
- timePicker.placeholder = this.timePlaceholder;
513
- timePicker.step = this.step;
514
- timePicker.invalid = this.invalid;
515
- this.__syncI18n(timePicker, this, timePickerI18nProps);
571
+ newTimePicker.placeholder = this.timePlaceholder;
572
+ newTimePicker.step = this.step;
573
+ newTimePicker.invalid = this.invalid;
574
+ this.__syncI18n(newTimePicker, this, timePickerI18nProps);
516
575
  } else {
517
576
  // Synchronize properties from slotted time picker
518
- this.timePlaceholder = timePicker.placeholder;
519
- this.step = timePicker.step;
520
- this.__syncI18n(this, timePicker, timePickerI18nProps);
577
+ this.timePlaceholder = newTimePicker.placeholder;
578
+ this.step = newTimePicker.step;
579
+ this.__syncI18n(this, newTimePicker, timePickerI18nProps);
521
580
  }
522
581
 
523
582
  // min and max are always synchronized from parent to slotted because time picker min and max
524
583
  // need to be dynamically set depending on currently selected date instead of simple propagation
525
584
  this.__updateTimePickerMinMax();
526
- timePicker.required = this.required;
527
- timePicker.disabled = this.disabled;
528
- timePicker.readonly = this.readonly;
529
- timePicker.autoOpenDisabled = this.autoOpenDisabled;
585
+ newTimePicker.required = this.required;
586
+ newTimePicker.disabled = this.disabled;
587
+ newTimePicker.readonly = this.readonly;
588
+ newTimePicker.autoOpenDisabled = this.autoOpenDisabled;
530
589
 
531
590
  // Disable default internal validation for the component
532
- timePicker.validate = () => {};
591
+ newTimePicker.validate = () => {};
533
592
  }
534
593
 
535
594
  /** @private */
@@ -561,12 +620,10 @@ class DateTimePicker extends FieldMixin(SlotMixin(DisabledMixin(ThemableMixin(El
561
620
 
562
621
  /** @private */
563
622
  __i18nChanged(changeRecord) {
564
- this.__datePickerChanged();
565
623
  if (this.__datePicker) {
566
624
  this.__datePicker.set(changeRecord.path, changeRecord.value);
567
625
  }
568
626
 
569
- this.__timePickerChanged();
570
627
  if (this.__timePicker) {
571
628
  this.__timePicker.set(changeRecord.path, changeRecord.value);
572
629
  }