@vaadin/date-picker 23.2.0-alpha2 → 23.2.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-picker",
3
- "version": "23.2.0-alpha2",
3
+ "version": "23.2.0-alpha5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -23,7 +23,9 @@
23
23
  "src",
24
24
  "theme",
25
25
  "vaadin-*.d.ts",
26
- "vaadin-*.js"
26
+ "vaadin-*.js",
27
+ "web-types.json",
28
+ "web-types.lit.json"
27
29
  ],
28
30
  "keywords": [
29
31
  "Vaadin",
@@ -34,19 +36,23 @@
34
36
  "dependencies": {
35
37
  "@open-wc/dedupe-mixin": "^1.3.0",
36
38
  "@polymer/polymer": "^3.2.0",
37
- "@vaadin/button": "23.2.0-alpha2",
38
- "@vaadin/component-base": "23.2.0-alpha2",
39
- "@vaadin/field-base": "23.2.0-alpha2",
40
- "@vaadin/input-container": "23.2.0-alpha2",
41
- "@vaadin/vaadin-lumo-styles": "23.2.0-alpha2",
42
- "@vaadin/vaadin-material-styles": "23.2.0-alpha2",
43
- "@vaadin/vaadin-overlay": "23.2.0-alpha2",
44
- "@vaadin/vaadin-themable-mixin": "23.2.0-alpha2"
39
+ "@vaadin/button": "23.2.0-alpha5",
40
+ "@vaadin/component-base": "23.2.0-alpha5",
41
+ "@vaadin/field-base": "23.2.0-alpha5",
42
+ "@vaadin/input-container": "23.2.0-alpha5",
43
+ "@vaadin/vaadin-lumo-styles": "23.2.0-alpha5",
44
+ "@vaadin/vaadin-material-styles": "23.2.0-alpha5",
45
+ "@vaadin/vaadin-overlay": "23.2.0-alpha5",
46
+ "@vaadin/vaadin-themable-mixin": "23.2.0-alpha5"
45
47
  },
46
48
  "devDependencies": {
47
49
  "@esm-bundle/chai": "^4.3.4",
48
50
  "@vaadin/testing-helpers": "^0.3.2",
49
51
  "sinon": "^13.0.2"
50
52
  },
51
- "gitHead": "c9b8113d0fa9a602f8b9cb915c1826355af2e8df"
53
+ "web-types": [
54
+ "web-types.json",
55
+ "web-types.lit.json"
56
+ ],
57
+ "gitHead": "c6247fd741d61096d75a71feda4a1faf88b6f0ce"
52
58
  }
@@ -3,6 +3,7 @@
3
3
  * Copyright (c) 2016 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js';
6
7
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
7
8
  import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
8
9
  export { DatePickerDate, DatePickerI18n } from './vaadin-date-picker-mixin.js';
@@ -29,12 +30,19 @@ export type DatePickerLightInvalidChangedEvent = CustomEvent<{ value: boolean }>
29
30
  */
30
31
  export type DatePickerLightValueChangedEvent = CustomEvent<{ value: string }>;
31
32
 
33
+ /**
34
+ * Fired whenever the field is validated.
35
+ */
36
+ export type DatePickerLightValidatedEvent = CustomEvent<{ valid: boolean }>;
37
+
32
38
  export interface DatePickerLightCustomEventMap {
33
39
  'opened-changed': DatePickerLightOpenedChangedEvent;
34
40
 
35
41
  'invalid-changed': DatePickerLightInvalidChangedEvent;
36
42
 
37
43
  'value-changed': DatePickerLightValueChangedEvent;
44
+
45
+ validated: DatePickerLightValidatedEvent;
38
46
  }
39
47
 
40
48
  export interface DatePickerLightEventMap extends HTMLElementEventMap, DatePickerLightCustomEventMap {
@@ -79,8 +87,9 @@ export interface DatePickerLightEventMap extends HTMLElementEventMap, DatePicker
79
87
  * @fires {Event} change - Fired when the user commits a value change.
80
88
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
81
89
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
90
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
82
91
  */
83
- declare class DatePickerLight extends ThemableMixin(DatePickerMixin(HTMLElement)) {
92
+ declare class DatePickerLight extends ThemableMixin(DatePickerMixin(ValidateMixin(HTMLElement))) {
84
93
  /**
85
94
  * Name of the two-way data-bindable property representing the
86
95
  * value of the custom input field.
@@ -90,13 +99,13 @@ declare class DatePickerLight extends ThemableMixin(DatePickerMixin(HTMLElement)
90
99
  addEventListener<K extends keyof DatePickerLightEventMap>(
91
100
  type: K,
92
101
  listener: (this: DatePickerLight, ev: DatePickerLightEventMap[K]) => void,
93
- options?: boolean | AddEventListenerOptions,
102
+ options?: AddEventListenerOptions | boolean,
94
103
  ): void;
95
104
 
96
105
  removeEventListener<K extends keyof DatePickerLightEventMap>(
97
106
  type: K,
98
107
  listener: (this: DatePickerLight, ev: DatePickerLightEventMap[K]) => void,
99
- options?: boolean | EventListenerOptions,
108
+ options?: EventListenerOptions | boolean,
100
109
  ): void;
101
110
  }
102
111
 
@@ -7,6 +7,7 @@ import './vaadin-date-picker-overlay.js';
7
7
  import './vaadin-date-picker-overlay-content.js';
8
8
  import { dashToCamelCase } from '@polymer/polymer/lib/utils/case-map.js';
9
9
  import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
10
+ import { ValidateMixin } from '@vaadin/field-base/src/validate-mixin.js';
10
11
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
11
12
  import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
12
13
 
@@ -48,12 +49,13 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
48
49
  * @fires {Event} change - Fired when the user commits a value change.
49
50
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
50
51
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
52
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
51
53
  *
52
54
  * @extends HTMLElement
53
55
  * @mixes ThemableMixin
54
56
  * @mixes DatePickerMixin
55
57
  */
56
- class DatePickerLight extends ThemableMixin(DatePickerMixin(PolymerElement)) {
58
+ class DatePickerLight extends ThemableMixin(DatePickerMixin(ValidateMixin(PolymerElement))) {
57
59
  static get template() {
58
60
  return html`
59
61
  <style>
@@ -3,12 +3,12 @@
3
3
  * Copyright (c) 2016 - 2022 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { Constructor } from '@open-wc/dedupe-mixin';
7
- import { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
8
- import { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
9
- import { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
10
- import { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
11
- import { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
6
+ import type { Constructor } from '@open-wc/dedupe-mixin';
7
+ import type { DisabledMixinClass } from '@vaadin/component-base/src/disabled-mixin.js';
8
+ import type { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js';
9
+ import type { KeyboardMixinClass } from '@vaadin/component-base/src/keyboard-mixin.js';
10
+ import type { DelegateFocusMixinClass } from '@vaadin/field-base/src/delegate-focus-mixin.js';
11
+ import type { InputMixinClass } from '@vaadin/field-base/src/input-mixin.js';
12
12
 
13
13
  export interface DatePickerDate {
14
14
  day: number;
@@ -33,13 +33,13 @@ export interface DatePickerI18n {
33
33
 
34
34
  export declare function DatePickerMixin<T extends Constructor<HTMLElement>>(
35
35
  base: T,
36
- ): T &
37
- Constructor<DatePickerMixinClass> &
36
+ ): Constructor<DatePickerMixinClass> &
38
37
  Constructor<DelegateFocusMixinClass> &
39
38
  Constructor<DisabledMixinClass> &
40
39
  Constructor<FocusMixinClass> &
41
40
  Constructor<InputMixinClass> &
42
- Constructor<KeyboardMixinClass>;
41
+ Constructor<KeyboardMixinClass> &
42
+ T;
43
43
 
44
44
  export declare class DatePickerMixinClass {
45
45
  /**
@@ -188,13 +188,6 @@ export declare class DatePickerMixinClass {
188
188
  */
189
189
  close(): void;
190
190
 
191
- /**
192
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
193
- *
194
- * @returns True if the value is valid and sets the `invalid` flag appropriately
195
- */
196
- validate(): boolean;
197
-
198
191
  /**
199
192
  * Returns true if the current input value satisfies all constraints (if any)
200
193
  *
@@ -46,7 +46,6 @@ export const DatePickerMixin = (subclass) =>
46
46
  */
47
47
  value: {
48
48
  type: String,
49
- observer: '_valueChanged',
50
49
  notify: true,
51
50
  value: '',
52
51
  },
@@ -264,7 +263,6 @@ export const DatePickerMixin = (subclass) =>
264
263
  */
265
264
  min: {
266
265
  type: String,
267
- observer: '_minChanged',
268
266
  },
269
267
 
270
268
  /**
@@ -278,28 +276,28 @@ export const DatePickerMixin = (subclass) =>
278
276
  */
279
277
  max: {
280
278
  type: String,
281
- observer: '_maxChanged',
282
279
  },
283
280
 
284
281
  /**
285
282
  * The earliest date that can be selected. All earlier dates will be disabled.
286
- * @type {Date | string}
283
+ * @type {Date | undefined}
287
284
  * @protected
288
285
  */
289
286
  _minDate: {
290
287
  type: Date,
291
- // Null does not work here because minimizer passes undefined to overlay (#351)
292
- value: '',
288
+ observer: '__minDateChanged',
289
+ computed: '__computeMinOrMaxDate(min)',
293
290
  },
294
291
 
295
292
  /**
296
293
  * The latest date that can be selected. All later dates will be disabled.
297
- * @type {Date | string}
294
+ * @type {Date | undefined}
298
295
  * @protected
299
296
  */
300
297
  _maxDate: {
301
298
  type: Date,
302
- value: '',
299
+ observer: '__maxDateChanged',
300
+ computed: '__computeMinOrMaxDate(max)',
303
301
  },
304
302
 
305
303
  /** @private */
@@ -475,7 +473,9 @@ export const DatePickerMixin = (subclass) =>
475
473
  this.$.overlay.removeAttribute('disable-upgrade');
476
474
  this._overlayInitialized = true;
477
475
 
478
- this.$.overlay.addEventListener('opened-changed', (e) => (this.opened = e.detail.value));
476
+ this.$.overlay.addEventListener('opened-changed', (e) => {
477
+ this.opened = e.detail.value;
478
+ });
479
479
 
480
480
  this.$.overlay.addEventListener('vaadin-overlay-escape-press', () => {
481
481
  this._focusedDate = this._selectedDate;
@@ -510,15 +510,6 @@ export const DatePickerMixin = (subclass) =>
510
510
  this.addEventListener('touchstart', () => this.__bringToFront());
511
511
  }
512
512
 
513
- /**
514
- * Returns true if `value` is valid, and sets the `invalid` flag appropriately.
515
- *
516
- * @return {boolean} True if the value is valid and sets the `invalid` flag appropriately
517
- */
518
- validate() {
519
- return !(this.invalid = !this.checkValidity());
520
- }
521
-
522
513
  /**
523
514
  * Returns true if the current input value satisfies all constraints (if any)
524
515
  *
@@ -529,7 +520,7 @@ export const DatePickerMixin = (subclass) =>
529
520
  checkValidity() {
530
521
  const inputValid =
531
522
  !this._inputValue ||
532
- (this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
523
+ (!!this._selectedDate && this._inputValue === this._getFormattedDate(this.i18n.formatDate, this._selectedDate));
533
524
  const minMaxValid = !this._selectedDate || dateAllowed(this._selectedDate, this._minDate, this._maxDate);
534
525
 
535
526
  let inputValidity = true;
@@ -696,41 +687,56 @@ export const DatePickerMixin = (subclass) =>
696
687
  }
697
688
  }
698
689
 
699
- /** @private */
700
- _handleDateChange(property, value, oldValue) {
701
- if (!value) {
702
- this[property] = '';
703
- return;
704
- }
690
+ /**
691
+ * Override the value observer from `InputMixin` to implement custom
692
+ * handling of the `value` property. The date-picker doesn't forward
693
+ * the value directly to the input like the default implementation of `InputMixin`.
694
+ * Instead, it parses the value into a date, puts it in `_selectedDate` which
695
+ * is then displayed in the input with respect to the specified date format.
696
+ *
697
+ * @param {string | undefined} value
698
+ * @param {string | undefined} oldValue
699
+ * @protected
700
+ * @override
701
+ */
702
+ _valueChanged(value, oldValue) {
703
+ const newDate = this._parseDate(value);
705
704
 
706
- const date = this._parseDate(value);
707
- if (!date) {
705
+ if (value && !newDate) {
706
+ // The new value cannot be parsed, revert the old value.
708
707
  this.value = oldValue;
709
708
  return;
710
709
  }
711
- if (!dateEquals(this[property], date)) {
712
- this[property] = date;
713
- if (this.value) {
714
- this.validate();
710
+
711
+ if (value) {
712
+ if (!dateEquals(this._selectedDate, newDate)) {
713
+ // Update the date instance only if the date has actually changed.
714
+ this._selectedDate = newDate;
715
+
716
+ if (oldValue !== undefined) {
717
+ // Validate only if `value` changes after initialization.
718
+ this.validate();
719
+ }
715
720
  }
721
+ } else {
722
+ this._selectedDate = null;
716
723
  }
717
- }
718
-
719
- /** @private */
720
- _valueChanged(value, oldValue) {
721
- this._handleDateChange('_selectedDate', value, oldValue);
722
724
 
723
725
  this._toggleHasValue(!!value);
724
726
  }
725
727
 
726
728
  /** @private */
727
- _minChanged(value, oldValue) {
728
- this._handleDateChange('_minDate', value, oldValue);
729
+ __minDateChanged() {
730
+ if (this.value) {
731
+ this.validate();
732
+ }
729
733
  }
730
734
 
731
735
  /** @private */
732
- _maxChanged(value, oldValue) {
733
- this._handleDateChange('_maxDate', value, oldValue);
736
+ __maxDateChanged() {
737
+ if (this.value) {
738
+ this.validate();
739
+ }
734
740
  }
735
741
 
736
742
  /** @protected */
@@ -819,9 +825,9 @@ export const DatePickerMixin = (subclass) =>
819
825
  window.removeEventListener('scroll', this._boundOnScroll, true);
820
826
 
821
827
  if (this._touchPrevented) {
822
- this._touchPrevented.forEach(
823
- (prevented) => (prevented.element.style.webkitOverflowScrolling = prevented.oldInlineValue),
824
- );
828
+ this._touchPrevented.forEach((prevented) => {
829
+ prevented.element.style.webkitOverflowScrolling = prevented.oldInlineValue;
830
+ });
825
831
  this._touchPrevented = [];
826
832
  }
827
833
 
@@ -1100,6 +1106,11 @@ export const DatePickerMixin = (subclass) =>
1100
1106
  return this.$.overlay.content.querySelector('#overlay-content');
1101
1107
  }
1102
1108
 
1109
+ /** @private */
1110
+ __computeMinOrMaxDate(dateString) {
1111
+ return this._parseDate(dateString);
1112
+ }
1113
+
1103
1114
  /**
1104
1115
  * Fired when the user commits a value change.
1105
1116
  *
@@ -451,7 +451,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
451
451
 
452
452
  _onYearScrollTouchStart() {
453
453
  this._notTapping = false;
454
- setTimeout(() => (this._notTapping = true), 300);
454
+ setTimeout(() => {
455
+ this._notTapping = true;
456
+ }, 300);
455
457
 
456
458
  this._repositionMonthScroller();
457
459
  }
@@ -462,7 +464,9 @@ class DatePickerOverlayContent extends ControllerMixin(ThemableMixin(DirMixin(Po
462
464
 
463
465
  _doIgnoreTaps() {
464
466
  this._ignoreTaps = true;
465
- this._debouncer = Debouncer.debounce(this._debouncer, timeOut.after(300), () => (this._ignoreTaps = false));
467
+ this._debouncer = Debouncer.debounce(this._debouncer, timeOut.after(300), () => {
468
+ this._ignoreTaps = false;
469
+ });
466
470
  }
467
471
 
468
472
  _formatDisplayed(date, formatDate, label) {
@@ -31,12 +31,19 @@ export type DatePickerInvalidChangedEvent = CustomEvent<{ value: boolean }>;
31
31
  */
32
32
  export type DatePickerValueChangedEvent = CustomEvent<{ value: string }>;
33
33
 
34
+ /**
35
+ * Fired whenever the field is validated.
36
+ */
37
+ export type DatePickerValidatedEvent = CustomEvent<{ valid: boolean }>;
38
+
34
39
  export interface DatePickerCustomEventMap {
35
40
  'opened-changed': DatePickerOpenedChangedEvent;
36
41
 
37
42
  'invalid-changed': DatePickerInvalidChangedEvent;
38
43
 
39
44
  'value-changed': DatePickerValueChangedEvent;
45
+
46
+ validated: DatePickerValidatedEvent;
40
47
  }
41
48
 
42
49
  export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCustomEventMap {
@@ -133,18 +140,19 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
133
140
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
134
141
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
135
142
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
143
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
136
144
  */
137
145
  declare class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(ElementMixin(HTMLElement)))) {
138
146
  addEventListener<K extends keyof DatePickerEventMap>(
139
147
  type: K,
140
148
  listener: (this: DatePicker, ev: DatePickerEventMap[K]) => void,
141
- options?: boolean | AddEventListenerOptions,
149
+ options?: AddEventListenerOptions | boolean,
142
150
  ): void;
143
151
 
144
152
  removeEventListener<K extends keyof DatePickerEventMap>(
145
153
  type: K,
146
154
  listener: (this: DatePicker, ev: DatePickerEventMap[K]) => void,
147
- options?: boolean | EventListenerOptions,
155
+ options?: EventListenerOptions | boolean,
148
156
  ): void;
149
157
  }
150
158
 
@@ -108,6 +108,7 @@ registerStyles('vaadin-date-picker', [inputFieldShared, datePickerStyles], { mod
108
108
  * @fires {CustomEvent} invalid-changed - Fired when the `invalid` property changes.
109
109
  * @fires {CustomEvent} opened-changed - Fired when the `opened` property changes.
110
110
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
111
+ * @fires {CustomEvent} validated - Fired whenever the field is validated.
111
112
  *
112
113
  * @extends HTMLElement
113
114
  * @mixes ElementMixin
@@ -155,7 +155,7 @@ class InfiniteScroller extends PolymerElement {
155
155
  // Once the first set of items start fading in, stamp the rest
156
156
  this._buffers.forEach((buffer) => {
157
157
  [].forEach.call(buffer.children, (insertionPoint) => this._ensureStampedInstance(insertionPoint._itemWrapper));
158
- }, this);
158
+ });
159
159
 
160
160
  if (!this._buffers[0].translateY) {
161
161
  this._reset();
@@ -318,7 +318,7 @@ class InfiniteScroller extends PolymerElement {
318
318
  }
319
319
  }, 1); // Wait for first reset
320
320
  }
321
- }, this);
321
+ });
322
322
 
323
323
  setTimeout(() => {
324
324
  afterNextRender(this, this._finishInit.bind(this));
@@ -356,7 +356,7 @@ class InfiniteScroller extends PolymerElement {
356
356
  });
357
357
  buffer.updated = true;
358
358
  }
359
- }, this);
359
+ });
360
360
  }
361
361
 
362
362
  _isVisible(element, container) {
@@ -250,7 +250,9 @@ class MonthCalendar extends FocusMixin(ThemableMixin(PolymerElement)) {
250
250
 
251
251
  _onMonthGridTouchStart() {
252
252
  this._notTapping = false;
253
- setTimeout(() => (this._notTapping = true), 300);
253
+ setTimeout(() => {
254
+ this._notTapping = true;
255
+ }, 300);
254
256
  }
255
257
 
256
258
  _dateAdd(date, delta) {
@@ -151,9 +151,9 @@ registerStyles(
151
151
  { moduleId: 'lumo-month-calendar' },
152
152
  );
153
153
 
154
- const $_documentContainer = document.createElement('template');
154
+ const template = document.createElement('template');
155
155
 
156
- $_documentContainer.innerHTML = `
156
+ template.innerHTML = `
157
157
  <style>
158
158
  @keyframes vaadin-date-picker-month-calendar-focus-date {
159
159
  50% {
@@ -163,4 +163,4 @@ $_documentContainer.innerHTML = `
163
163
  </style>
164
164
  `;
165
165
 
166
- document.head.appendChild($_documentContainer.content);
166
+ document.head.appendChild(template.content);