Skip to content

Commit b48f412

Browse files
authored
refactor!: update date-picker overlay to use native popover (#9762)
1 parent ff42c02 commit b48f412

File tree

13 files changed

+228
-532
lines changed

13 files changed

+228
-532
lines changed

packages/date-picker/src/styles/vaadin-date-picker-base-styles.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export const datePickerStyles = css`
1111
pointer-events: auto;
1212
}
1313
14+
:host([week-numbers]) {
15+
--_vaadin-date-picker-week-numbers-visible: 1;
16+
}
17+
1418
:host([dir='rtl']) [part='input-field'] {
1519
direction: ltr;
1620
}

packages/date-picker/src/styles/vaadin-date-picker-overlay-base-styles.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ export const datePickerOverlayStyles = css`
3636
width: 100%;
3737
}
3838
39-
:host([week-numbers]) {
40-
--_vaadin-date-picker-week-numbers-visible: 1;
41-
}
42-
4339
[part~='content'] {
4440
flex: auto;
4541
}

packages/date-picker/src/vaadin-date-picker-mixin.js

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ export const DatePickerMixin = (subclass) =>
295295

296296
this._boundOnClick = this._onClick.bind(this);
297297
this._boundOnScroll = this._onScroll.bind(this);
298-
this._boundOverlayRenderer = this._overlayRenderer.bind(this);
299298
}
300299

301300
/**
@@ -453,13 +452,17 @@ export const DatePickerMixin = (subclass) =>
453452

454453
this.addController(new VirtualKeyboardController(this));
455454

456-
const overlay = this.$.overlay;
457-
this._overlayElement = overlay;
455+
this._overlayElement = this.$.overlay;
456+
}
458457

459-
overlay.renderer = this._boundOverlayRenderer;
458+
/** @protected */
459+
updated(props) {
460+
super.updated(props);
460461

461-
this.addEventListener('mousedown', () => this.__bringToFront());
462-
this.addEventListener('touchstart', () => this.__bringToFront());
462+
if (props.has('showWeekNumbers') || props.has('__effectiveI18n')) {
463+
// Currently only supported for locales that start the week on Monday.
464+
this.toggleAttribute('week-numbers', this.showWeekNumbers && this.__effectiveI18n.firstDayOfWeek === 1);
465+
}
463466
}
464467

465468
/** @protected */
@@ -498,14 +501,15 @@ export const DatePickerMixin = (subclass) =>
498501
}
499502

500503
/** @private */
501-
_overlayRenderer(root) {
502-
if (root.firstChild) {
504+
__ensureContent() {
505+
if (this._overlayContent) {
503506
return;
504507
}
505508

506509
// Create and store document content element
507510
const content = document.createElement('vaadin-date-picker-overlay-content');
508-
root.appendChild(content);
511+
content.setAttribute('slot', 'overlay');
512+
this.appendChild(content);
509513

510514
this._overlayContent = content;
511515

@@ -712,13 +716,6 @@ export const DatePickerMixin = (subclass) =>
712716
this.close();
713717
}
714718

715-
/** @private */
716-
__bringToFront() {
717-
requestAnimationFrame(() => {
718-
this.$.overlay.bringToFront();
719-
});
720-
}
721-
722719
/** @private */
723720
// eslint-disable-next-line @typescript-eslint/max-params
724721
_isNoInput(inputElement, fullscreen, ios, effectiveI18n, opened, autoOpenDisabled) {
@@ -752,6 +749,10 @@ export const DatePickerMixin = (subclass) =>
752749

753750
/** @protected */
754751
_openedChanged(opened) {
752+
if (opened) {
753+
this.__ensureContent();
754+
}
755+
755756
if (this.inputElement) {
756757
this.inputElement.setAttribute('aria-expanded', opened);
757758
}
@@ -1031,6 +1032,11 @@ export const DatePickerMixin = (subclass) =>
10311032
* @private
10321033
*/
10331034
_onClick(event) {
1035+
// Ignore click events bubbling from the overlay
1036+
if (event.composedPath().includes(this._overlayContent)) {
1037+
return;
1038+
}
1039+
10341040
// Clear button click is handled in separate listener
10351041
// but bubbles to the host, so we need to ignore it.
10361042
if (!this._isClearButton(event)) {
@@ -1119,7 +1125,12 @@ export const DatePickerMixin = (subclass) =>
11191125
* @protected
11201126
* @override
11211127
*/
1122-
_onEnter(_event) {
1128+
_onEnter(event) {
1129+
// Ignore Enter keydown event bubbling from the overlay
1130+
if (event.composedPath().includes(this._overlayContent)) {
1131+
return;
1132+
}
1133+
11231134
if (this.opened) {
11241135
// Closing will implicitly select parsed or focused date
11251136
this.close();

packages/date-picker/src/vaadin-date-picker-overlay.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,33 @@ class DatePickerOverlay extends DatePickerOverlayMixin(
4545
</div>
4646
`;
4747
}
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+
}
59+
60+
/**
61+
* @protected
62+
* @override
63+
*/
64+
_attachOverlay() {
65+
this.showPopover();
66+
}
67+
68+
/**
69+
* @protected
70+
* @override
71+
*/
72+
_detachOverlay() {
73+
this.hidePopover();
74+
}
4875
}
4976

5077
defineCustomElement(DatePickerOverlay);

packages/date-picker/src/vaadin-date-picker.d.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,19 @@ export interface DatePickerEventMap extends HTMLElementEventMap, DatePickerCusto
8383
*
8484
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
8585
*
86-
* Part name | Description
87-
* ----------------------|--------------------
88-
* `toggle-button` | Toggle button
86+
* Part name | Description
87+
* -----------------|--------------------
88+
* `toggle-button` | Toggle button
89+
* `backdrop` | Backdrop of the overlay
90+
* `overlay` | The overlay container
91+
* `content` | The overlay content
8992
*
9093
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
9194
*
92-
* Attribute | Description | Part name
93-
* -----------|--------------------------------------------------|-----------
94-
* `opened` | Set when the date selector overlay is opened | :host
95+
* Attribute | Description
96+
* ---------------|----------------------------------------------
97+
* `opened` | Set when the date selector overlay is opened
98+
* `week-numbers` | Set when week numbers are shown in the calendar
9599
*
96100
* ### Internal components
97101
*

packages/date-picker/src/vaadin-date-picker.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,19 @@ import { DatePickerMixin } from './vaadin-date-picker-mixin.js';
4747
*
4848
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
4949
*
50-
* Part name | Description
51-
* ----------------------|--------------------
52-
* `toggle-button` | Toggle button
50+
* Part name | Description
51+
* -----------------|--------------------
52+
* `toggle-button` | Toggle button
53+
* `backdrop` | Backdrop of the overlay
54+
* `overlay` | The overlay container
55+
* `content` | The overlay content
5356
*
5457
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
5558
*
56-
* Attribute | Description | Part name
57-
* -----------|--------------------------------------------------|-----------
58-
* `opened` | Set when the date selector overlay is opened | :host
59+
* Attribute | Description
60+
* ---------------|----------------------------------------------
61+
* `opened` | Set when the date selector overlay is opened
62+
* `week-numbers` | Set when week numbers are shown in the calendar
5963
*
6064
* ### Internal components
6165
*
@@ -207,9 +211,9 @@ class DatePicker extends DatePickerMixin(
207211
208212
<vaadin-date-picker-overlay
209213
id="overlay"
214+
popover="manual"
210215
.owner="${this}"
211216
?fullscreen="${this._fullscreen}"
212-
?week-numbers="${this.showWeekNumbers}"
213217
theme="${ifDefined(this._theme)}"
214218
.opened="${this.opened}"
215219
@opened-changed="${this._onOpenedChanged}"
@@ -219,9 +223,12 @@ class DatePicker extends DatePickerMixin(
219223
@vaadin-overlay-closing="${this._onOverlayClosed}"
220224
restore-focus-on-close
221225
no-vertical-overlap
226+
exportparts="backdrop, overlay, content"
222227
.restoreFocusNode="${this.inputElement}"
223228
.positionTarget="${this._positionTarget}"
224-
></vaadin-date-picker-overlay>
229+
>
230+
<slot name="overlay"></slot>
231+
</vaadin-date-picker-overlay>
225232
226233
<slot name="tooltip"></slot>
227234
`;

0 commit comments

Comments
 (0)