From 239cce3bf79ffed22b06c214fc918681ee4984a5 Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Sat, 17 Apr 2021 13:14:28 +0200 Subject: [PATCH] feat(overlays): expose "repositionOverlay()" on OverlayMixin --- .changeset/calm-paws-taste.md | 5 ++++ packages/overlays/src/OverlayController.js | 2 -- packages/overlays/src/OverlayMixin.js | 13 +++++++++- .../test-suites/OverlayMixin.suite.js | 25 ++++++++++++++++--- .../overlays/types/OverlayMixinTypes.d.ts | 19 ++++++++------ 5 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 .changeset/calm-paws-taste.md diff --git a/.changeset/calm-paws-taste.md b/.changeset/calm-paws-taste.md new file mode 100644 index 000000000..399274f36 --- /dev/null +++ b/.changeset/calm-paws-taste.md @@ -0,0 +1,5 @@ +--- +'@lion/overlays': minor +--- + +expose "repositionOverlay()" on OverlayMixin diff --git a/packages/overlays/src/OverlayController.js b/packages/overlays/src/OverlayController.js index bddab5239..c19f0e5e2 100644 --- a/packages/overlays/src/OverlayController.js +++ b/packages/overlays/src/OverlayController.js @@ -471,8 +471,6 @@ export class OverlayController extends EventTargetShim { /** @private */ this.__validateConfiguration(/** @type {OverlayConfig} */ (this.config)); - // TODO: remove this, so we only have the getters (no setters) - // Object.assign(this, this.config); /** @protected */ this._init({ cfgToAdd }); /** @private */ diff --git a/packages/overlays/src/OverlayMixin.js b/packages/overlays/src/OverlayMixin.js index cd97790f0..8eed5bf4f 100644 --- a/packages/overlays/src/OverlayMixin.js +++ b/packages/overlays/src/OverlayMixin.js @@ -79,7 +79,6 @@ export const OverlayMixinImplementation = superclass => // eslint-disable-next-line _defineOverlay({ contentNode, invokerNode, referenceNode, backdropNode, contentWrapperNode }) { const overlayConfig = this._defineOverlayConfig() || {}; - return new OverlayController({ contentNode, invokerNode, @@ -353,5 +352,17 @@ export const OverlayMixinImplementation = superclass => async close() { await /** @type {OverlayController} */ (this._overlayCtrl).hide(); } + + /** + * Sometimes it's needed to recompute Popper position of an overlay, for instance when we have + * an opened combobox and the surrounding context changes (the space consumed by the textbox + * increases vertically) + */ + repositionOverlay() { + const ctrl = /** @type {OverlayController} */ (this._overlayCtrl); + if (ctrl.placementMode === 'local' && ctrl._popper) { + ctrl._popper.update(); + } + } }; export const OverlayMixin = dedupeMixin(OverlayMixinImplementation); diff --git a/packages/overlays/test-suites/OverlayMixin.suite.js b/packages/overlays/test-suites/OverlayMixin.suite.js index 02c25c681..6da75cec7 100644 --- a/packages/overlays/test-suites/OverlayMixin.suite.js +++ b/packages/overlays/test-suites/OverlayMixin.suite.js @@ -1,7 +1,6 @@ import { expect, fixture, html, nextFrame, aTimeout } from '@open-wc/testing'; import sinon from 'sinon'; import { overlays } from '../src/overlays.js'; -// eslint-disable-next-line no-unused-vars import { OverlayController } from '../src/OverlayController.js'; /** @@ -171,7 +170,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) { expect(el.opened).to.be.true; }); - it('allows to call `preventDefault()` on "before-opened"/"before-closed" events', async () => { + it('allows to call "preventDefault()" on "before-opened"/"before-closed" events', async () => { function preventer(/** @type Event */ ev) { ev.preventDefault(); } @@ -215,7 +214,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) { }); // See https://github.com/ing-bank/lion/discussions/1095 - it('exposes open(), close() and toggle() methods', async () => { + it('exposes "open()", "close()" and "toggle()" methods', async () => { const el = /** @type {OverlayEl} */ (await fixture(html` <${tag}>
content
@@ -240,6 +239,25 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) { expect(el.opened).to.be.false; }); + it('exposes "repositionOverlay()" method', async () => { + const el = /** @type {OverlayEl} */ (await fixture(html` + <${tag} opened .config="${{ placementMode: 'local' }}"> +
content
+ + + `)); + await OverlayController.popperModule; + sinon.spy(el._overlayCtrl._popper, 'update'); + el.repositionOverlay(); + expect(el._overlayCtrl._popper.update).to.have.been.been.calledOnce; + + if (!el._overlayCtrl.isTooltip) { + el.config = { ...el.config, placementMode: 'global' }; + el.repositionOverlay(); + expect(el._overlayCtrl._popper.update).to.have.been.been.calledOnce; + } + }); + /** See: https://github.com/ing-bank/lion/issues/1075 */ it('stays open after config update', async () => { const el = /** @type {OverlayEl} */ (await fixture(html` @@ -250,6 +268,7 @@ export function runOverlayMixinSuite({ tagString, tag, suffix = '' }) { `)); el.open(); await el._overlayCtrl._showComplete; + el.config = { ...el.config, hidesOnOutsideClick: !el.config.hidesOnOutsideClick }; await nextFrame(); expect(el.opened).to.be.true; diff --git a/packages/overlays/types/OverlayMixinTypes.d.ts b/packages/overlays/types/OverlayMixinTypes.d.ts index d1c7e90f3..58ac0c2ff 100644 --- a/packages/overlays/types/OverlayMixinTypes.d.ts +++ b/packages/overlays/types/OverlayMixinTypes.d.ts @@ -17,14 +17,19 @@ export interface DefineOverlayConfig { } export declare class OverlayHost { - public opened: Boolean; + opened: Boolean; + get config(): OverlayConfig; + set config(value: OverlayConfig); - public get config(): OverlayConfig; - public set config(value: OverlayConfig); - - public open(): void; - public close(): void; - public toggle(): void; + open(): void; + close(): void; + toggle(): void; + /** + * Sometimes it's needed to recompute Popper position of an overlay, for instance when we have + * an opened combobox and the surrounding context changes (the space consumed by the textbox + * increases vertically) + */ + repositionOverlay(): void; protected _overlayCtrl: OverlayController;