@vaadin/date-picker 25.0.0-alpha2 → 25.0.0-alpha21

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 (40) hide show
  1. package/package.json +13 -14
  2. package/src/styles/vaadin-date-picker-base-styles.d.ts +8 -0
  3. package/src/{vaadin-date-picker-styles.js → styles/vaadin-date-picker-base-styles.js} +9 -0
  4. package/src/styles/vaadin-date-picker-overlay-base-styles.js +48 -0
  5. package/src/styles/vaadin-date-picker-overlay-content-base-styles.js +108 -0
  6. package/src/styles/vaadin-date-picker-year-base-styles.js +27 -0
  7. package/src/styles/vaadin-month-calendar-base-styles.js +143 -0
  8. package/src/vaadin-date-picker-helper.d.ts +5 -0
  9. package/src/vaadin-date-picker-helper.js +1 -1
  10. package/src/vaadin-date-picker-mixin.d.ts +1 -3
  11. package/src/vaadin-date-picker-mixin.js +45 -23
  12. package/src/vaadin-date-picker-month-scroller.js +2 -6
  13. package/src/vaadin-date-picker-overlay-content-mixin.js +5 -132
  14. package/src/vaadin-date-picker-overlay-content.js +19 -17
  15. package/src/vaadin-date-picker-overlay.js +17 -3
  16. package/src/vaadin-date-picker-year-scroller.js +3 -4
  17. package/src/vaadin-date-picker-year.js +32 -10
  18. package/src/vaadin-date-picker.d.ts +33 -24
  19. package/src/vaadin-date-picker.js +45 -28
  20. package/src/vaadin-infinite-scroller.js +1 -19
  21. package/src/vaadin-month-calendar.js +3 -2
  22. package/vaadin-date-picker.js +1 -1
  23. package/web-types.json +3 -25
  24. package/web-types.lit.json +3 -10
  25. package/src/vaadin-date-picker-overlay-content-styles.js +0 -68
  26. package/src/vaadin-date-picker-overlay-styles.js +0 -23
  27. package/src/vaadin-date-picker-year-mixin.js +0 -35
  28. package/src/vaadin-month-calendar-styles.js +0 -64
  29. package/theme/lumo/vaadin-date-picker-overlay-content-styles.d.ts +0 -7
  30. package/theme/lumo/vaadin-date-picker-overlay-content-styles.js +0 -164
  31. package/theme/lumo/vaadin-date-picker-overlay-styles.d.ts +0 -2
  32. package/theme/lumo/vaadin-date-picker-overlay-styles.js +0 -55
  33. package/theme/lumo/vaadin-date-picker-styles.d.ts +0 -2
  34. package/theme/lumo/vaadin-date-picker-styles.js +0 -30
  35. package/theme/lumo/vaadin-date-picker-year-styles.d.ts +0 -1
  36. package/theme/lumo/vaadin-date-picker-year-styles.js +0 -32
  37. package/theme/lumo/vaadin-date-picker.d.ts +0 -5
  38. package/theme/lumo/vaadin-date-picker.js +0 -5
  39. package/theme/lumo/vaadin-month-calendar-styles.d.ts +0 -5
  40. package/theme/lumo/vaadin-month-calendar-styles.js +0 -158
@@ -5,16 +5,10 @@
5
5
  */
6
6
  import { timeOut } from '@vaadin/component-base/src/async.js';
7
7
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
8
- import { addListener, setTouchAction } from '@vaadin/component-base/src/gestures.js';
8
+ import { addListener } from '@vaadin/component-base/src/gestures.js';
9
9
  import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
10
10
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
11
- import {
12
- dateAfterXMonths,
13
- dateAllowed,
14
- dateEquals,
15
- extractDateParts,
16
- getClosestDate,
17
- } from './vaadin-date-picker-helper.js';
11
+ import { dateAfterXMonths, dateAllowed, dateEquals, getClosestDate } from './vaadin-date-picker-helper.js';
18
12
 
19
13
  /**
20
14
  * @polymerMixin
@@ -75,14 +69,6 @@ export const DatePickerOverlayContentMixin = (superClass) =>
75
69
  value: '(min-width: 375px)',
76
70
  },
77
71
 
78
- _translateX: {
79
- observer: '_translateXChanged',
80
- },
81
-
82
- _yearScrollerWidth: {
83
- value: 50,
84
- },
85
-
86
72
  i18n: {
87
73
  type: Object,
88
74
  },
@@ -178,20 +164,6 @@ export const DatePickerOverlayContentMixin = (superClass) =>
178
164
  return this.calendars.map((calendar) => calendar.focusableDateElement).find(Boolean);
179
165
  }
180
166
 
181
- /** @protected */
182
- _addListeners() {
183
- setTouchAction(this.$.scrollers, 'pan-y');
184
-
185
- addListener(this.$.scrollers, 'track', this._track.bind(this));
186
- addListener(this.shadowRoot.querySelector('[part="clear-button"]'), 'tap', this._clear.bind(this));
187
- addListener(this.shadowRoot.querySelector('[part="toggle-button"]'), 'tap', this._cancel.bind(this));
188
- addListener(
189
- this.shadowRoot.querySelector('[part="years-toggle-button"]'),
190
- 'tap',
191
- this._toggleYearScroller.bind(this),
192
- );
193
- }
194
-
195
167
  /** @protected */
196
168
  _initControllers() {
197
169
  this.addController(
@@ -206,7 +178,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
206
178
  initializer: (btn) => {
207
179
  btn.setAttribute('theme', 'tertiary');
208
180
  btn.addEventListener('keydown', (e) => this.__onTodayButtonKeyDown(e));
209
- addListener(btn, 'tap', this._onTodayTap.bind(this));
181
+ btn.addEventListener('click', this._onTodayTap.bind(this));
210
182
  this._todayButton = btn;
211
183
  },
212
184
  }),
@@ -218,7 +190,7 @@ export const DatePickerOverlayContentMixin = (superClass) =>
218
190
  initializer: (btn) => {
219
191
  btn.setAttribute('theme', 'tertiary');
220
192
  btn.addEventListener('keydown', (e) => this.__onCancelButtonKeyDown(e));
221
- addListener(btn, 'tap', this._cancel.bind(this));
193
+ btn.addEventListener('click', this._cancel.bind(this));
222
194
  this._cancelButton = btn;
223
195
  },
224
196
  }),
@@ -230,7 +202,6 @@ export const DatePickerOverlayContentMixin = (superClass) =>
230
202
 
231
203
  reset() {
232
204
  this._closeYearScroller();
233
- this._toggleAnimateClass(true);
234
205
  }
235
206
 
236
207
  /**
@@ -527,14 +498,6 @@ export const DatePickerOverlayContentMixin = (superClass) =>
527
498
  });
528
499
  }
529
500
 
530
- /** @protected */
531
- _formatDisplayed(date, i18n, label) {
532
- if (date && i18n && typeof i18n.formatDate === 'function') {
533
- return i18n.formatDate(extractDateParts(date));
534
- }
535
- return label;
536
- }
537
-
538
501
  /** @private */
539
502
  _onTodayTap() {
540
503
  const today = this._getTodayMidnight();
@@ -647,99 +610,14 @@ export const DatePickerOverlayContentMixin = (superClass) =>
647
610
  window.requestAnimationFrame(smoothScroll);
648
611
  }
649
612
 
650
- /** @private */
651
- _limit(value, range) {
652
- return Math.min(range.max, Math.max(range.min, value));
653
- }
654
-
655
- /** @private */
656
- _handleTrack(e) {
657
- // Check if horizontal movement threshold (dx) not exceeded or
658
- // scrolling fast vertically (ddy).
659
- if (Math.abs(e.detail.dx) < 10 || Math.abs(e.detail.ddy) > 10) {
660
- return;
661
- }
662
-
663
- // If we're flinging quickly -> start animating already.
664
- if (Math.abs(e.detail.ddx) > this._yearScrollerWidth / 3) {
665
- this._toggleAnimateClass(true);
666
- }
667
-
668
- const newTranslateX = this._translateX + e.detail.ddx;
669
- this._translateX = this._limit(newTranslateX, {
670
- min: 0,
671
- max: this._yearScrollerWidth,
672
- });
673
- }
674
-
675
- /** @private */
676
- _track(e) {
677
- if (this._desktopMode) {
678
- // No need to track for swipe gestures on desktop.
679
- return;
680
- }
681
-
682
- switch (e.detail.state) {
683
- case 'start':
684
- this._toggleAnimateClass(false);
685
- break;
686
- case 'track':
687
- this._handleTrack(e);
688
- break;
689
- case 'end':
690
- this._toggleAnimateClass(true);
691
- if (this._translateX >= this._yearScrollerWidth / 2) {
692
- this._closeYearScroller();
693
- } else {
694
- this._openYearScroller();
695
- }
696
- break;
697
- default:
698
- break;
699
- }
700
- }
701
-
702
- /** @private */
703
- _toggleAnimateClass(enable) {
704
- if (enable) {
705
- this.classList.add('animate');
706
- } else {
707
- this.classList.remove('animate');
708
- }
709
- }
710
-
711
613
  /** @private */
712
614
  _toggleYearScroller() {
713
- if (this._isYearScrollerVisible()) {
714
- this._closeYearScroller();
715
- } else {
716
- this._openYearScroller();
717
- }
718
- }
719
-
720
- /** @private */
721
- _openYearScroller() {
722
- this._translateX = 0;
723
- this.setAttribute('years-visible', '');
615
+ this.toggleAttribute('years-visible');
724
616
  }
725
617
 
726
618
  /** @private */
727
619
  _closeYearScroller() {
728
620
  this.removeAttribute('years-visible');
729
- this._translateX = this._yearScrollerWidth;
730
- }
731
-
732
- /** @private */
733
- _isYearScrollerVisible() {
734
- return this._translateX < this._yearScrollerWidth / 2;
735
- }
736
-
737
- /** @private */
738
- _translateXChanged(x) {
739
- if (!this._desktopMode) {
740
- this._monthScroller.style.transform = `translateX(${x - this._yearScrollerWidth}px)`;
741
- this._yearScroller.style.transform = `translateX(${x}px)`;
742
- }
743
621
  }
744
622
 
745
623
  /** @private */
@@ -769,11 +647,6 @@ export const DatePickerOverlayContentMixin = (superClass) =>
769
647
  this._close();
770
648
  }
771
649
 
772
- /** @protected */
773
- _preventDefault(e) {
774
- e.preventDefault();
775
- }
776
-
777
650
  /** @private */
778
651
  __toggleDate(date) {
779
652
  if (dateEquals(date, this.selectedDate)) {
@@ -12,9 +12,10 @@ import { html, LitElement } from 'lit';
12
12
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
13
13
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
14
14
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
15
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
15
16
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
17
+ import { overlayContentStyles } from './styles/vaadin-date-picker-overlay-content-base-styles.js';
16
18
  import { DatePickerOverlayContentMixin } from './vaadin-date-picker-overlay-content-mixin.js';
17
- import { overlayContentStyles } from './vaadin-date-picker-overlay-content-styles.js';
18
19
 
19
20
  /**
20
21
  * @customElement
@@ -22,7 +23,7 @@ import { overlayContentStyles } from './vaadin-date-picker-overlay-content-style
22
23
  * @private
23
24
  */
24
25
  class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
25
- ThemableMixin(DirMixin(PolylitMixin(LitElement))),
26
+ ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement)))),
26
27
  ) {
27
28
  static get is() {
28
29
  return 'vaadin-date-picker-overlay-content';
@@ -32,26 +33,28 @@ class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
32
33
  return overlayContentStyles;
33
34
  }
34
35
 
36
+ static get lumoInjector() {
37
+ return {
38
+ includeBaseStyles: true,
39
+ };
40
+ }
41
+
35
42
  /** @protected */
36
43
  render() {
37
44
  return html`
38
- <div part="overlay-header" @touchend="${this._preventDefault}" aria-hidden="true">
39
- <div part="label">${this._formatDisplayed(this.selectedDate, this.i18n, this.label)}</div>
40
- <div part="clear-button" ?hidden="${!this.selectedDate}"></div>
41
- <div part="toggle-button"></div>
45
+ <slot name="months"></slot>
46
+ <slot name="years"></slot>
42
47
 
43
- <div part="years-toggle-button" ?hidden="${this._desktopMode}" aria-hidden="true">
48
+ <div role="toolbar" part="toolbar">
49
+ <slot name="today-button"></slot>
50
+ <div
51
+ part="years-toggle-button"
52
+ ?hidden="${this._desktopMode}"
53
+ aria-hidden="true"
54
+ @click="${this._toggleYearScroller}"
55
+ >
44
56
  ${this._yearAfterXMonths(this._visibleMonthIndex)}
45
57
  </div>
46
- </div>
47
-
48
- <div id="scrollers">
49
- <slot name="months"></slot>
50
- <slot name="years"></slot>
51
- </div>
52
-
53
- <div @touchend="${this._preventDefault}" role="toolbar" part="toolbar">
54
- <slot name="today-button"></slot>
55
58
  <slot name="cancel-button"></slot>
56
59
  </div>
57
60
  `;
@@ -63,7 +66,6 @@ class DatePickerOverlayContent extends DatePickerOverlayContentMixin(
63
66
 
64
67
  this.setAttribute('role', 'dialog');
65
68
 
66
- this._addListeners();
67
69
  this._initControllers();
68
70
  }
69
71
  }
@@ -7,10 +7,11 @@ import { html, LitElement } from 'lit';
7
7
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
8
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
9
9
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
- import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
10
+ import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-base-styles.js';
11
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
11
12
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
+ import { datePickerOverlayStyles } from './styles/vaadin-date-picker-overlay-base-styles.js';
12
14
  import { DatePickerOverlayMixin } from './vaadin-date-picker-overlay-mixin.js';
13
- import { datePickerOverlayStyles } from './vaadin-date-picker-overlay-styles.js';
14
15
 
15
16
  /**
16
17
  * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
@@ -22,7 +23,9 @@ import { datePickerOverlayStyles } from './vaadin-date-picker-overlay-styles.js'
22
23
  * @mixes ThemableMixin
23
24
  * @private
24
25
  */
25
- class DatePickerOverlay extends DatePickerOverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement)))) {
26
+ class DatePickerOverlay extends DatePickerOverlayMixin(
27
+ DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement)))),
28
+ ) {
26
29
  static get is() {
27
30
  return 'vaadin-date-picker-overlay';
28
31
  }
@@ -42,6 +45,17 @@ class DatePickerOverlay extends DatePickerOverlayMixin(DirMixin(ThemableMixin(Po
42
45
  </div>
43
46
  `;
44
47
  }
48
+
49
+ /**
50
+ * Override method from `OverlayFocusMixin` to specify content root
51
+ * used to detect whether focus should be restored on overlay close.
52
+ *
53
+ * @protected
54
+ * @override
55
+ */
56
+ get _contentRoot() {
57
+ return this.owner._overlayContent;
58
+ }
45
59
  }
46
60
 
47
61
  defineCustomElement(DatePickerOverlay);
@@ -13,10 +13,9 @@ stylesTemplate.innerHTML = `
13
13
  --vaadin-infinite-scroller-item-height: 80px;
14
14
  width: 50px;
15
15
  display: block;
16
- height: 100%;
17
- position: absolute;
18
- right: 0;
19
- transform: translateX(100%);
16
+ position: relative;
17
+ grid-area: years;
18
+ height: auto;
20
19
  -webkit-tap-highlight-color: transparent;
21
20
  -webkit-user-select: none;
22
21
  user-select: none;
@@ -3,11 +3,12 @@
3
3
  * Copyright (c) 2016 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { css, html, LitElement } from 'lit';
6
+ import { html, LitElement } from 'lit';
7
7
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
8
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
9
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
9
10
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10
- import { DatePickerYearMixin } from './vaadin-date-picker-year-mixin.js';
11
+ import { datePickerYearStyles } from './styles/vaadin-date-picker-year-base-styles.js';
11
12
 
12
13
  /**
13
14
  * An element used internally by `<vaadin-date-picker>`. Not intended to be used separately.
@@ -15,21 +16,29 @@ import { DatePickerYearMixin } from './vaadin-date-picker-year-mixin.js';
15
16
  * @customElement
16
17
  * @extends HTMLElement
17
18
  * @mixes ThemableMixin
18
- * @mixes DatePickerYearMixin
19
19
  * @private
20
20
  */
21
- export class DatePickerYear extends ThemableMixin(DatePickerYearMixin(PolylitMixin(LitElement))) {
21
+ export class DatePickerYear extends ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))) {
22
22
  static get is() {
23
23
  return 'vaadin-date-picker-year';
24
24
  }
25
25
 
26
26
  static get styles() {
27
- return css`
28
- :host {
29
- display: block;
30
- height: 100%;
31
- }
32
- `;
27
+ return datePickerYearStyles;
28
+ }
29
+
30
+ static get properties() {
31
+ return {
32
+ year: {
33
+ type: String,
34
+ sync: true,
35
+ },
36
+
37
+ selectedDate: {
38
+ type: Object,
39
+ sync: true,
40
+ },
41
+ };
33
42
  }
34
43
 
35
44
  /** @protected */
@@ -39,6 +48,19 @@ export class DatePickerYear extends ThemableMixin(DatePickerYearMixin(PolylitMix
39
48
  <div part="year-separator" aria-hidden="true"></div>
40
49
  `;
41
50
  }
51
+
52
+ /** @protected */
53
+ updated(props) {
54
+ super.updated(props);
55
+
56
+ if (props.has('year')) {
57
+ this.toggleAttribute('current', this.year === new Date().getFullYear());
58
+ }
59
+
60
+ if (props.has('year') || props.has('selectedDate')) {
61
+ this.toggleAttribute('selected', this.selectedDate && this.selectedDate.getFullYear() === this.year);
62
+ }
63
+ }
42
64
  }
43
65
 
44
66
  defineCustomElement(DatePickerYear);
@@ -78,44 +78,56 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
78
78
  * -------------------------------|----------------------------|---------
79
79
  * `--vaadin-field-default-width` | Default width of the field | `12em`
80
80
  *
81
- * `<vaadin-date-picker>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
82
- * See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
83
- *
84
- * In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
85
- *
86
- * Part name | Description
87
- * ----------------------|--------------------
88
- * `toggle-button` | Toggle button
89
- *
90
- * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
91
- *
92
- * Attribute | Description | Part name
93
- * -----------|--------------------------------------------------|-----------
94
- * `opened` | Set when the date selector overlay is opened | :host
81
+ * The following shadow DOM parts are available for styling:
82
+ *
83
+ * Part name | Description
84
+ * ---------------------|----------------
85
+ * `label` | The label element
86
+ * `input-field` | The element that wraps prefix, value and buttons
87
+ * `field-button` | Set on both clear and toggle buttons
88
+ * `clear-button` | The clear button
89
+ * `error-message` | The error message element
90
+ * `helper-text` | The helper text element wrapper
91
+ * `required-indicator` | The `required` state indicator element
92
+ * `toggle-button` | The toggle button
93
+ * `backdrop` | Backdrop of the overlay
94
+ * `overlay` | The overlay container
95
+ * `content` | The overlay content
96
+ *
97
+ * The following state attributes are available for styling:
98
+ *
99
+ * Attribute | Description
100
+ * ---------------------|---------------------------------
101
+ * `disabled` | Set when the element is disabled
102
+ * `has-value` | Set when the element has a value
103
+ * `has-label` | Set when the element has a label
104
+ * `has-helper` | Set when the element has helper text or slot
105
+ * `has-error-message` | Set when the element has an error message
106
+ * `has-tooltip` | Set when the element has a slotted tooltip
107
+ * `invalid` | Set when the element is invalid
108
+ * `focused` | Set when the element is focused
109
+ * `focus-ring` | Set when the element is keyboard focused
110
+ * `readonly` | Set when the element is readonly
111
+ * `opened` | Set when the overlay is opened
112
+ * `week-numbers` | Set when week numbers are shown in the calendar
95
113
  *
96
114
  * ### Internal components
97
115
  *
98
116
  * In addition to `<vaadin-date-picker>` itself, the following internal
99
117
  * components are themable:
100
118
  *
101
- * - `<vaadin-date-picker-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
102
119
  * - `<vaadin-date-picker-overlay-content>`
103
120
  * - `<vaadin-date-picker-month-scroller>`
104
121
  * - `<vaadin-date-picker-year-scroller>`
105
122
  * - `<vaadin-date-picker-year>`
106
123
  * - `<vaadin-month-calendar>`
107
- * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
108
124
  *
109
125
  * In order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:
110
126
  *
111
127
  * Part name | Description
112
128
  * ----------------------|--------------------
113
- * `overlay-header` | Fullscreen mode header
114
- * `label` | Fullscreen mode value/label
115
- * `clear-button` | Fullscreen mode clear button
116
- * `toggle-button` | Fullscreen mode toggle button
117
129
  * `years-toggle-button` | Fullscreen mode years scroller toggle
118
- * `toolbar` | Footer bar with slotted buttons
130
+ * `toolbar` | Toolbar with slotted buttons
119
131
  *
120
132
  * The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
121
133
  *
@@ -149,9 +161,6 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
149
161
  * `year-number` | Year number
150
162
  * `year-separator` | Year separator
151
163
  *
152
- * Note: the `theme` attribute value set on `<vaadin-date-picker>` is
153
- * propagated to the internal components listed above.
154
- *
155
164
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
156
165
  *
157
166
  * ### Change events
@@ -16,9 +16,10 @@ import { InputControlMixin } from '@vaadin/field-base/src/input-control-mixin.js
16
16
  import { InputController } from '@vaadin/field-base/src/input-controller.js';
17
17
  import { LabelledInputController } from '@vaadin/field-base/src/labelled-input-controller.js';
18
18
  import { inputFieldShared } from '@vaadin/field-base/src/styles/input-field-shared-styles.js';
19
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
19
20
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
21
+ import { datePickerStyles } from './styles/vaadin-date-picker-base-styles.js';
20
22
  import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
21
- import { datePickerStyles } from './vaadin-date-picker-styles.js';
22
23
 
23
24
  /**
24
25
  * `<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.
@@ -41,44 +42,56 @@ import { datePickerStyles } from './vaadin-date-picker-styles.js';
41
42
  * -------------------------------|----------------------------|---------
42
43
  * `--vaadin-field-default-width` | Default width of the field | `12em`
43
44
  *
44
- * `<vaadin-date-picker>` provides the same set of shadow DOM parts and state attributes as `<vaadin-text-field>`.
45
- * See [`<vaadin-text-field>`](#/elements/vaadin-text-field) for the styling documentation.
45
+ * The following shadow DOM parts are available for styling:
46
46
  *
47
- * In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
47
+ * Part name | Description
48
+ * ---------------------|----------------
49
+ * `label` | The label element
50
+ * `input-field` | The element that wraps prefix, value and buttons
51
+ * `field-button` | Set on both clear and toggle buttons
52
+ * `clear-button` | The clear button
53
+ * `error-message` | The error message element
54
+ * `helper-text` | The helper text element wrapper
55
+ * `required-indicator` | The `required` state indicator element
56
+ * `toggle-button` | The toggle button
57
+ * `backdrop` | Backdrop of the overlay
58
+ * `overlay` | The overlay container
59
+ * `content` | The overlay content
48
60
  *
49
- * Part name | Description
50
- * ----------------------|--------------------
51
- * `toggle-button` | Toggle button
61
+ * The following state attributes are available for styling:
52
62
  *
53
- * In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
54
- *
55
- * Attribute | Description | Part name
56
- * -----------|--------------------------------------------------|-----------
57
- * `opened` | Set when the date selector overlay is opened | :host
63
+ * Attribute | Description
64
+ * ---------------------|---------------------------------
65
+ * `disabled` | Set when the element is disabled
66
+ * `has-value` | Set when the element has a value
67
+ * `has-label` | Set when the element has a label
68
+ * `has-helper` | Set when the element has helper text or slot
69
+ * `has-error-message` | Set when the element has an error message
70
+ * `has-tooltip` | Set when the element has a slotted tooltip
71
+ * `invalid` | Set when the element is invalid
72
+ * `focused` | Set when the element is focused
73
+ * `focus-ring` | Set when the element is keyboard focused
74
+ * `readonly` | Set when the element is readonly
75
+ * `opened` | Set when the overlay is opened
76
+ * `week-numbers` | Set when week numbers are shown in the calendar
58
77
  *
59
78
  * ### Internal components
60
79
  *
61
80
  * In addition to `<vaadin-date-picker>` itself, the following internal
62
81
  * components are themable:
63
82
  *
64
- * - `<vaadin-date-picker-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
65
83
  * - `<vaadin-date-picker-overlay-content>`
66
84
  * - `<vaadin-date-picker-month-scroller>`
67
85
  * - `<vaadin-date-picker-year-scroller>`
68
86
  * - `<vaadin-date-picker-year>`
69
87
  * - `<vaadin-month-calendar>`
70
- * - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
71
88
  *
72
89
  * In order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:
73
90
  *
74
91
  * Part name | Description
75
92
  * ----------------------|--------------------
76
- * `overlay-header` | Fullscreen mode header
77
- * `label` | Fullscreen mode value/label
78
- * `clear-button` | Fullscreen mode clear button
79
- * `toggle-button` | Fullscreen mode toggle button
80
93
  * `years-toggle-button` | Fullscreen mode years scroller toggle
81
- * `toolbar` | Footer bar with slotted buttons
94
+ * `toolbar` | Toolbar with slotted buttons
82
95
  *
83
96
  * The following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:
84
97
  *
@@ -112,9 +125,6 @@ import { datePickerStyles } from './vaadin-date-picker-styles.js';
112
125
  * `year-number` | Year number
113
126
  * `year-separator` | Year separator
114
127
  *
115
- * Note: the `theme` attribute value set on `<vaadin-date-picker>` is
116
- * propagated to the internal components listed above.
117
- *
118
128
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
119
129
  *
120
130
  * ### Change events
@@ -147,7 +157,9 @@ import { datePickerStyles } from './vaadin-date-picker-styles.js';
147
157
  * @mixes InputControlMixin
148
158
  * @mixes DatePickerMixin
149
159
  */
150
- class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(ElementMixin(PolylitMixin(LitElement))))) {
160
+ class DatePicker extends DatePickerMixin(
161
+ InputControlMixin(ThemableMixin(ElementMixin(PolylitMixin(LumoInjectionMixin(LitElement))))),
162
+ ) {
151
163
  static get is() {
152
164
  return 'vaadin-date-picker';
153
165
  }
@@ -193,8 +205,8 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
193
205
  >
194
206
  <slot name="prefix" slot="prefix"></slot>
195
207
  <slot name="input"></slot>
196
- <div id="clearButton" part="clear-button" slot="suffix" aria-hidden="true"></div>
197
- <div part="toggle-button" slot="suffix" aria-hidden="true" @click="${this._toggle}"></div>
208
+ <div id="clearButton" part="field-button clear-button" slot="suffix" aria-hidden="true"></div>
209
+ <div part="field-button toggle-button" slot="suffix" aria-hidden="true" @click="${this._toggle}"></div>
198
210
  </vaadin-input-container>
199
211
 
200
212
  <div part="helper-text">
@@ -208,6 +220,7 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
208
220
 
209
221
  <vaadin-date-picker-overlay
210
222
  id="overlay"
223
+ .owner="${this}"
211
224
  ?fullscreen="${this._fullscreen}"
212
225
  theme="${ifDefined(this._theme)}"
213
226
  .opened="${this.opened}"
@@ -218,9 +231,12 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
218
231
  @vaadin-overlay-closing="${this._onOverlayClosed}"
219
232
  restore-focus-on-close
220
233
  no-vertical-overlap
234
+ exportparts="backdrop, overlay, content"
221
235
  .restoreFocusNode="${this.inputElement}"
222
236
  .positionTarget="${this._positionTarget}"
223
- ></vaadin-date-picker-overlay>
237
+ >
238
+ <slot name="overlay"></slot>
239
+ </vaadin-date-picker-overlay>
224
240
 
225
241
  <slot name="tooltip"></slot>
226
242
  `;
@@ -257,7 +273,7 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
257
273
 
258
274
  this._positionTarget = this.shadowRoot.querySelector('[part="input-field"]');
259
275
 
260
- const toggleButton = this.shadowRoot.querySelector('[part="toggle-button"]');
276
+ const toggleButton = this.shadowRoot.querySelector('[part="field-button toggle-button"]');
261
277
  toggleButton.addEventListener('mousedown', (e) => e.preventDefault());
262
278
  }
263
279
 
@@ -269,7 +285,8 @@ class DatePicker extends DatePickerMixin(InputControlMixin(ThemableMixin(Element
269
285
  /** @private */
270
286
  _onVaadinOverlayClose(e) {
271
287
  // Prevent closing the overlay on label element click
272
- if (e.detail.sourceEvent && e.detail.sourceEvent.composedPath().includes(this)) {
288
+ const event = e.detail.sourceEvent;
289
+ if (event && event.composedPath().includes(this) && !event.composedPath().includes(this._overlayElement)) {
273
290
  e.preventDefault();
274
291
  }
275
292
  }