Skip to content

Commit b4d90c2

Browse files
authored
refactor!: update combo-box overlay to use native popover (#9815)
1 parent 5c80d96 commit b4d90c2

16 files changed

+187
-242
lines changed

packages/combo-box/src/vaadin-combo-box-base-mixin.js

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,6 @@ export const ComboBoxBaseMixin = (superClass) =>
184184
this.clearElement.addEventListener('mousedown', this._boundOnClearButtonMouseDown);
185185
}
186186

187-
const bringToFrontListener = () => {
188-
requestAnimationFrame(() => {
189-
this._overlayElement.bringToFront();
190-
});
191-
};
192-
193-
this.addEventListener('mousedown', bringToFrontListener);
194-
this.addEventListener('touchstart', bringToFrontListener);
195-
196187
this.addController(new VirtualKeyboardController(this));
197188
}
198189

@@ -258,21 +249,14 @@ export const ComboBoxBaseMixin = (superClass) =>
258249

259250
/**
260251
* Render the scroller element to the overlay.
261-
* Override to provide custom logic (e.g. setting "slot").
262252
*
263-
* @protected
253+
* @private
264254
*/
265255
_renderScroller(scroller) {
266-
const overlay = this.$.overlay;
267-
268-
overlay.renderer = (root) => {
269-
if (!root.innerHTML) {
270-
root.appendChild(scroller);
271-
}
272-
};
273-
274-
// Ensure the scroller is rendered
275-
overlay.requestContentUpdate();
256+
scroller.setAttribute('slot', 'overlay');
257+
// Prevent focusing scroller on input Tab
258+
scroller.setAttribute('tabindex', '-1');
259+
this.appendChild(scroller);
276260
}
277261

278262
/**

packages/combo-box/src/vaadin-combo-box-item-mixin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export const ComboBoxItemMixin = (superClass) =>
9292

9393
/** @protected */
9494
_getHostDir() {
95-
return this._owner && this._owner.getAttribute('dir');
95+
return this._owner && this._owner.$.overlay.getAttribute('dir');
9696
}
9797

9898
/**

packages/combo-box/src/vaadin-combo-box-overlay-mixin.js

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,6 @@ export const ComboBoxOverlayMixin = (superClass) =>
2222
this.requiredVerticalSpace = 200;
2323
}
2424

25-
/** @protected */
26-
connectedCallback() {
27-
super.connectedCallback();
28-
29-
const hostDir = this._getHostDir();
30-
if (hostDir) {
31-
this.setAttribute('dir', hostDir);
32-
}
33-
}
34-
35-
/** @protected */
36-
_getHostDir() {
37-
return this.owner && this.owner.getAttribute('dir');
38-
}
39-
4025
/**
4126
* Override method inherited from `Overlay`
4227
* to not close on position target click.
@@ -66,16 +51,7 @@ export const ComboBoxOverlayMixin = (superClass) =>
6651

6752
/** @protected */
6853
_updateOverlayWidth() {
69-
const propPrefix = this.localName;
70-
this.style.setProperty(`--_${propPrefix}-default-width`, `${this.positionTarget.offsetWidth}px`);
71-
72-
const customWidth = getComputedStyle(this.owner).getPropertyValue(`--${propPrefix}-width`);
73-
74-
if (customWidth === '') {
75-
this.style.removeProperty(`--${propPrefix}-width`);
76-
} else {
77-
this.style.setProperty(`--${propPrefix}-width`, customWidth);
78-
}
54+
this.style.setProperty(`--_${this.localName}-default-width`, `${this.positionTarget.offsetWidth}px`);
7955
}
8056

8157
/** @private */

packages/combo-box/src/vaadin-combo-box-overlay.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,22 @@ export class ComboBoxOverlay extends ComboBoxOverlayMixin(
4545
</div>
4646
`;
4747
}
48+
49+
/**
50+
* @protected
51+
* @override
52+
*/
53+
_attachOverlay() {
54+
this.showPopover();
55+
}
56+
57+
/**
58+
* @protected
59+
* @override
60+
*/
61+
_detachOverlay() {
62+
this.hidePopover();
63+
}
4864
}
4965

5066
defineCustomElement(ComboBoxOverlay);

packages/combo-box/src/vaadin-combo-box.d.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,12 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
181181
*
182182
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
183183
*
184-
* Part name | Description
185-
* ----------------|----------------
186-
* `toggle-button` | The toggle button
184+
* Part name | Description
185+
* -----------------|------------------
186+
* `toggle-button` | The toggle button
187+
* `overlay` | The overlay container
188+
* `content` | The overlay content
189+
* `loader` | The loading indicator shown while loading items
187190
*
188191
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
189192
*
@@ -197,12 +200,7 @@ export interface ComboBoxEventMap<TItem> extends HTMLElementEventMap {
197200
* In addition to `<vaadin-combo-box>` itself, the following internal
198201
* components are themable:
199202
*
200-
* - `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
201203
* - `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
202-
* - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
203-
*
204-
* Note: the `theme` attribute value set on `<vaadin-combo-box>` is
205-
* propagated to the internal components listed above.
206204
*
207205
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
208206
*

packages/combo-box/src/vaadin-combo-box.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,12 @@ import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
112112
*
113113
* In addition to `<vaadin-text-field>` parts, the following parts are available for theming:
114114
*
115-
* Part name | Description
116-
* ----------------|----------------
117-
* `toggle-button` | The toggle button
115+
* Part name | Description
116+
* -----------------|------------------
117+
* `toggle-button` | The toggle button
118+
* `overlay` | The overlay container
119+
* `content` | The overlay content
120+
* `loader` | The loading indicator shown while loading items
118121
*
119122
* In addition to `<vaadin-text-field>` state attributes, the following state attributes are available for theming:
120123
*
@@ -128,12 +131,7 @@ import { ComboBoxMixin } from './vaadin-combo-box-mixin.js';
128131
* In addition to `<vaadin-combo-box>` itself, the following internal
129132
* components are themable:
130133
*
131-
* - `<vaadin-combo-box-overlay>` - has the same API as [`<vaadin-overlay>`](#/elements/vaadin-overlay).
132134
* - `<vaadin-combo-box-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).
133-
* - [`<vaadin-input-container>`](#/elements/vaadin-input-container) - an internal element wrapping the input.
134-
*
135-
* Note: the `theme` attribute value set on `<vaadin-combo-box>` is
136-
* propagated to the internal components listed above.
137135
*
138136
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
139137
*
@@ -221,13 +219,18 @@ class ComboBox extends ComboBoxDataProviderMixin(
221219
222220
<vaadin-combo-box-overlay
223221
id="overlay"
222+
popover="manual"
223+
exportparts="overlay, content, loader"
224224
.owner="${this}"
225+
.dir="${this.dir}"
225226
.opened="${this._overlayOpened}"
226227
?loading="${this.loading}"
227228
theme="${ifDefined(this._theme)}"
228229
.positionTarget="${this._positionTarget}"
229230
no-vertical-overlap
230-
></vaadin-combo-box-overlay>
231+
>
232+
<slot name="overlay"></slot>
233+
</vaadin-combo-box-overlay>
231234
232235
<slot name="tooltip"></slot>
233236
`;

packages/combo-box/test/basic.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ describe('pre-opened', () => {
264264
style="--vaadin-combo-box-overlay-max-height: 200px"
265265
></vaadin-combo-box>`);
266266
await nextRender();
267-
const scroller = comboBox.$.overlay.querySelector('vaadin-combo-box-scroller');
267+
const scroller = comboBox.querySelector('vaadin-combo-box-scroller');
268268
expect(scroller.style.maxHeight).to.equal('200px');
269269
});
270270
});

0 commit comments

Comments
 (0)