From 49974bd2b86d7f02e8c19aa51a0a79779b897384 Mon Sep 17 00:00:00 2001 From: Thomas Allmer Date: Sat, 30 Nov 2019 14:59:00 +0100 Subject: [PATCH] fix: no longer use overlay templates --- packages/dialog/package.json | 2 - packages/dialog/src/LionDialog.js | 11 +- packages/dialog/stories/index.stories.js | 35 ++-- packages/dialog/test/lion-dialog.test.js | 73 ++------ .../src/LionCalendarOverlayFrame.js | 11 +- .../src/LionInputDatepicker.js | 18 +- packages/overlays/README.md | 7 +- packages/overlays/docs/OverlayController.md | 2 + packages/overlays/docs/migration.md | 141 --------------- packages/overlays/package.json | 3 +- packages/overlays/src/OverlayController.js | 24 ++- packages/overlays/src/OverlayMixin.js | 171 ++++++------------ packages/overlays/stories/index.stories.js | 123 ++++++------- .../stories/overlay-features.stories.js | 5 +- .../test-suites/OverlayMixin.suite.js | 57 ++++++ .../overlays/test/OverlayController.test.js | 27 +++ packages/overlays/test/OverlayMixin.test.js | 12 ++ packages/select-rich/src/LionSelectRich.js | 20 +- .../select-rich/test/lion-select-rich.test.js | 4 +- packages/tooltip/package.json | 2 - packages/tooltip/src/LionTooltip.js | 1 + packages/tooltip/stories/index.stories.js | 14 +- packages/tooltip/test/lion-tooltip.test.js | 36 ++-- yarn.lock | 2 +- 24 files changed, 334 insertions(+), 467 deletions(-) delete mode 100644 packages/overlays/docs/migration.md create mode 100644 packages/overlays/test-suites/OverlayMixin.suite.js create mode 100644 packages/overlays/test/OverlayMixin.test.js diff --git a/packages/dialog/package.json b/packages/dialog/package.json index f2fae9a63..b132cf84c 100644 --- a/packages/dialog/package.json +++ b/packages/dialog/package.json @@ -34,8 +34,6 @@ "@lion/overlays": "^0.6.4" }, "devDependencies": { - "@lion/button": "^0.3.43", - "@lion/icon": "^0.2.9", "@open-wc/demoing-storybook": "^0.2.0", "@open-wc/testing": "^2.3.4" } diff --git a/packages/dialog/src/LionDialog.js b/packages/dialog/src/LionDialog.js index fbe015e24..68e1b0666 100644 --- a/packages/dialog/src/LionDialog.js +++ b/packages/dialog/src/LionDialog.js @@ -15,21 +15,18 @@ export class LionDialog extends OverlayMixin(LitElement) { } _setupOpenCloseListeners() { - this.__close = () => { - this.opened = false; - }; this.__toggle = () => { this.opened = !this.opened; }; - if (this._overlayCtrl.invokerNode) { - this._overlayCtrl.invokerNode.addEventListener('click', this.__toggle); + if (this._overlayInvokerNode) { + this._overlayInvokerNode.addEventListener('click', this.__toggle); } } _teardownOpenCloseListeners() { - if (this._overlayCtrl.invokerNode) { - this._overlayCtrl.invokerNode.removeEventListener('click', this.__toggle); + if (this._overlayInvokerNode) { + this._overlayInvokerNode.removeEventListener('click', this.__toggle); } } diff --git a/packages/dialog/stories/index.stories.js b/packages/dialog/stories/index.stories.js index 29f7dbc0b..d880b5197 100644 --- a/packages/dialog/stories/index.stories.js +++ b/packages/dialog/stories/index.stories.js @@ -1,7 +1,5 @@ import { storiesOf, html, withKnobs, object } from '@open-wc/demoing-storybook'; import { css } from '@lion/core'; -import '@lion/icon/lion-icon.js'; -import '@lion/button/lion-button.js'; import '../lion-dialog.js'; const dialogDemoStyle = css` @@ -67,24 +65,25 @@ storiesOf('Overlays Specific WC | Dialog', module)

To close your dialog from some action performed inside the content slot, fire a - close event. + hide event.

For the dialog to close, it will need to bubble to the content slot (use - bubbles: true. Also composed: true if it needs to traverse shadow - boundaries) + bubbles: true. If absolutely needed composed: true can be used to + traverse shadow boundaries)

The demo below demonstrates this

- Dialog +
Hello! You can close this notification here: - e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
@@ -93,14 +92,15 @@ storiesOf('Overlays Specific WC | Dialog', module) .add('Custom configuration', () => { const dialog = placement => html` - Dialog ${placement} +
Hello! You can close this notification here: - e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
`; @@ -118,14 +118,15 @@ storiesOf('Overlays Specific WC | Dialog', module) .add('Toggle placement with knobs', () => { const dialog = html` - Dialog +
Hello! You can close this notification here: - e.target.dispatchEvent(new Event('dialog-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
`; diff --git a/packages/dialog/test/lion-dialog.test.js b/packages/dialog/test/lion-dialog.test.js index 155fef199..70932dcac 100644 --- a/packages/dialog/test/lion-dialog.test.js +++ b/packages/dialog/test/lion-dialog.test.js @@ -1,77 +1,34 @@ -import { expect, fixture, html } from '@open-wc/testing'; +import { expect, fixture, html, unsafeStatic } from '@open-wc/testing'; +import { runOverlayMixinSuite } from '@lion/overlays/test-suites/OverlayMixin.suite.js'; import '../lion-dialog.js'; -// Smoke tests dialog describe('lion-dialog', () => { - describe('Basic', () => { - it('should not be shown by default', async () => { - const el = await fixture(html` - -
Hey there
- Popup button -
- `); - expect(el._overlayCtrl.isShown).to.be.false; - }); + describe('Integration tests', () => { + const tagString = 'lion-dialog'; + const tag = unsafeStatic(tagString); + runOverlayMixinSuite({ + tagString, + tag, + suffix: ' for lion-dialog', + }); + }); + + describe('Basic', () => { it('should show content on invoker click', async () => { const el = await fixture(html`
Hey there
- Popup button +
`); const invoker = el.querySelector('[slot="invoker"]'); invoker.click(); - expect(el._overlayCtrl.isShown).to.be.true; - }); - - it('should hide content on close event', async () => { - const el = await fixture(html` - -
- Hey there - -
- Popup button -
- `); - const invoker = el.querySelector('[slot="invoker"]'); - invoker.click(); - - expect(el._overlayCtrl.isShown).to.be.true; - - const closeBtn = el._overlayCtrl.contentNode.querySelector('button'); - closeBtn.click(); - - expect(el._overlayCtrl.isShown).to.be.false; - }); - - it('should respond to initially and dynamically setting the config', async () => { - const el = await fixture(html` - -
Hey there
- Popup button -
- `); - await el._overlayCtrl.show(); - expect(el._overlayCtrl.trapsKeyboardFocus).to.be.false; - - el.config = { viewportConfig: { placement: 'left' } }; - expect(el._overlayCtrl.viewportConfig.placement).to.equal('left'); - expect( - el._overlayCtrl._contentNodeWrapper.classList.contains( - 'global-overlays__overlay-container--left', - ), - ); + expect(el.opened).to.be.true; }); }); }); diff --git a/packages/input-datepicker/src/LionCalendarOverlayFrame.js b/packages/input-datepicker/src/LionCalendarOverlayFrame.js index 3ec585e68..2978ef210 100644 --- a/packages/input-datepicker/src/LionCalendarOverlayFrame.js +++ b/packages/input-datepicker/src/LionCalendarOverlayFrame.js @@ -90,14 +90,9 @@ export class LionCalendarOverlayFrame extends LocalizeMixin(LitElement) { ]; } - constructor() { - super(); - this.__dispatchCloseEvent = this.__dispatchCloseEvent.bind(this); - } - - __dispatchCloseEvent() { + __dispatchHideEvent() { // Designed to work in conjunction with ModalDialogController - this.dispatchEvent(new CustomEvent('dialog-close'), { bubbles: true, composed: true }); + this.dispatchEvent(new CustomEvent('hide'), { bubbles: true }); } render() { @@ -109,7 +104,7 @@ export class LionCalendarOverlayFrame extends LocalizeMixin(LitElement) {
-
-
Hello, World!
- -
- -`; -``` - -Or using a more specific component like `lion-tooltip`, which toggles on-hover: - -```js -import '@lion/tooltip/lion-tooltip.js'; - -const template = html` - - -
-
Hello, World!
-
-
-`; -``` - -Or `lion-dialog` which uses modal dialog configuration defaults - -```js -import '@lion/dialog/lion-dialog.js'; - -const template = html` - - -
-
Hello, World!
- -
-
-`; -``` - -## Instantiating an overlay controller (discouraged) - -### Old - -```js -import { overlays, GlobalOverlayController } from '@lion/overlays'; - -const ctrl = overlays.add( - new GlobalOverlayController({ - contentTemplate: () => html` -
My content
- `, - }), -); - -const template = html` - - Open dialog - -`; -``` - -### New - -> Note: The OverlayController is render-system agnostic, you are responsible for passing a node (and rendering it prior). -> For lit-html, we will use a simple helper. Let us know if you think we should export this. - -```js -import { render } from '@lion/core'; - -function renderOffline(litHtmlTemplate) { - const offlineRenderContainer = document.createElement('div'); - render(litHtmlTemplate, offlineRenderContainer); - return offlineRenderContainer.firstElementChild; -} -``` - -This example shows how you can use our configuration generators. - -```js -import { OverlayController, withModalDialogConfig } from '@lion/overlays'; - -const ctrl = new OverlayController({ - ...withModalDialogConfig(), - contentTemplate: renderOffline(html` -
My content
- `), -}); - -const template = html` - - Open dialog - -`; -``` - -### New (local example) - -```js -import { OverlayController } from '@lion/overlays'; - -const ctrl = new OverlayController({ - ...withModalDialogConfig(), - placementMode: 'local', - hidesOnEsc: true, - hidesOnOutsideClick: true, - contentNode: renderOffline(html` -
United Kingdom
- `), - invokerNode: renderOffline(html` - - `), -}); - -const template = html` -
In the ${ctrl.invoker}${ctrl.content} the weather is nice.
-`; -``` diff --git a/packages/overlays/package.json b/packages/overlays/package.json index 2d3411218..79b8274a9 100644 --- a/packages/overlays/package.json +++ b/packages/overlays/package.json @@ -29,6 +29,7 @@ "stories", "test", "test-helpers", + "test-suites", "translations", "*.js" ], @@ -37,8 +38,6 @@ "popper.js": "^1.15.0" }, "devDependencies": { - "@lion/button": "^0.3.43", - "@lion/icon": "^0.2.9", "@open-wc/demoing-storybook": "^0.2.0", "@open-wc/testing": "^2.3.4", "@open-wc/testing-helpers": "^1.0.0", diff --git a/packages/overlays/src/OverlayController.js b/packages/overlays/src/OverlayController.js index 552b5ee21..1ba08b842 100644 --- a/packages/overlays/src/OverlayController.js +++ b/packages/overlays/src/OverlayController.js @@ -33,6 +33,7 @@ export class OverlayController { trapsKeyboardFocus: false, hidesOnEsc: false, hidesOnOutsideClick: false, + hidesOnHideEventInContentNode: true, isTooltip: false, handlesUserInteraction: false, handlesAccessibility: false, @@ -336,6 +337,9 @@ export class OverlayController { if (this.hidesOnOutsideClick) { this._handleHidesOnOutsideClick({ phase }); } + if (this.hidesOnHideEventInContentNode) { + this._handleHidesOnHideEventInContentNode({ phase }); + } if (this.handlesAccessibility) { this._handleAccessibility({ phase }); } @@ -483,10 +487,26 @@ export class OverlayController { if (phase === 'show') { this.__escKeyHandler = ev => ev.key === 'Escape' && this.hide(); this.contentNode.addEventListener('keyup', this.__escKeyHandler); - this.invokerNode.addEventListener('keyup', this.__escKeyHandler); + if (this.invokerNode) { + this.invokerNode.addEventListener('keyup', this.__escKeyHandler); + } } else if (phase === 'hide') { this.contentNode.removeEventListener('keyup', this.__escKeyHandler); - this.invokerNode.removeEventListener('keyup', this.__escKeyHandler); + if (this.invokerNode) { + this.invokerNode.removeEventListener('keyup', this.__escKeyHandler); + } + } + } + + _handleHidesOnHideEventInContentNode({ phase }) { + if (phase === 'show') { + this.__hideEventInContentNodeHandler = ev => { + ev.stopPropagation(); + this.hide(); + }; + this.contentNode.addEventListener('hide', this.__hideEventInContentNodeHandler); + } else if (phase === 'hide') { + this.contentNode.removeEventListener('keyup', this.__hideEventInContentNodeHandler); } } diff --git a/packages/overlays/src/OverlayMixin.js b/packages/overlays/src/OverlayMixin.js index 67a79c71d..a96cba7de 100644 --- a/packages/overlays/src/OverlayMixin.js +++ b/packages/overlays/src/OverlayMixin.js @@ -1,4 +1,4 @@ -import { render, dedupeMixin } from '@lion/core'; +import { dedupeMixin } from '@lion/core'; import { OverlayController } from './OverlayController.js'; /** @@ -16,54 +16,26 @@ export const OverlayMixin = dedupeMixin( type: Boolean, reflect: true, }, - config: { - type: Object, - }, - closeEventName: { - type: String, - }, }; } constructor() { super(); + this.opened = false; this.config = {}; - this.closeEventName = 'overlay-close'; - } - - get opened() { - return this._overlayCtrl.isShown; - } - - set opened(show) { - if (show) { - this.dispatchEvent(new Event('before-show')); - } - this._opened = show; // mainly captured for sync on connectedCallback - if (this._overlayCtrl) { - this.__syncOpened(); - } } get config() { - return this._config; + return this.__config; } set config(value) { if (this._overlayCtrl) { this._overlayCtrl.updateConfig(value); } - this._config = value; + this.__config = value; } - /** - * @overridable method `_overlayTemplate` - * Be aware that the overlay will be placed in a different shadow root. - * Therefore, style encapsulation should be provided by the contents of - * _overlayTemplate - * @return {TemplateResult} - */ - /** * @overridable method `_defineOverlay` * @desc returns an instance of a (dynamic) overlay controller @@ -88,7 +60,19 @@ export const OverlayMixin = dedupeMixin( */ // eslint-disable-next-line _defineOverlayConfig() { - return {}; + return { + placementMode: 'local', + }; + } + + updated(changedProperties) { + super.updated(changedProperties); + + if (changedProperties.has('opened')) { + if (this._overlayCtrl) { + this.__syncToOverlayController(); + } + } } /** @@ -106,44 +90,19 @@ export const OverlayMixin = dedupeMixin( // eslint-disable-next-line class-methods-use-this _teardownOpenCloseListeners() {} - connectedCallback() { - if (super.connectedCallback) { - super.connectedCallback(); - } - this._createOverlay(); - - // Default close event catcher on the contentNode which is useful if people want to close - // their overlay but the content is not in the global root node (nowhere near the overlay component) - this.__close = () => { - this.opened = false; - }; - this._overlayCtrl.contentNode.addEventListener(this.closeEventName, this.__close); - - this._setupOpenCloseListeners(); - this.__syncOpened(); - this.__syncPopper(); - } - - firstUpdated(c) { - super.firstUpdated(c); - this._createOutletForLocalOverlay(); - } - - updated(c) { - super.updated(c); - if (this.__managesOverlayViaTemplate) { - this._renderOverlayContent(); - } + firstUpdated(changedProperties) { + super.firstUpdated(changedProperties); + // we setup in firstUpdated so we can use nodes from light and shadowDom + this._setupOverlayCtrl(); } disconnectedCallback() { if (super.disconnectedCallback) { super.disconnectedCallback(); } - this.opened = false; - this._overlayCtrl.contentNode.removeEventListener(this.closeEventName, this.__close); - this._teardownOpenCloseListeners(); - this._overlayCtrl.teardown(); + if (this._overlayCtrl) { + this._teardownOverlayCtrl(); + } } get _overlayInvokerNode() { @@ -171,69 +130,51 @@ export const OverlayMixin = dedupeMixin( return contentNode || this._cachedOverlayContentNode; } - _renderOverlayContent() { - render(this._overlayTemplate(), this.__contentParent, { - scopeName: this.localName, - eventContext: this, + _setupOverlayCtrl() { + this._overlayCtrl = this._defineOverlay({ + contentNode: this._overlayContentNode, + invokerNode: this._overlayInvokerNode, }); + this.__syncToOverlayController(); + this.__setupSyncFromOverlayController(); + + this._setupOpenCloseListeners(); } - _createOverlay() { - let contentNode; - if (this.__managesOverlayViaTemplate) { - this.__contentParent = document.createElement('div'); - this._renderOverlayContent(); - contentNode = this.__contentParent.firstElementChild; - } else { - contentNode = this._overlayContentNode; - } - - // Why no template support for invokerNode? - // -> Because this node will always be managed by the Subclasser and should - // reside in the dom of the sub class. A reference to a rendered node suffices. - const invokerNode = this._overlayInvokerNode; - this._overlayCtrl = this._defineOverlay({ contentNode, invokerNode }); + _teardownOverlayCtrl() { + this._teardownOpenCloseListeners(); + this.__teardownSyncFromOverlayController(); + this._overlayCtrl.teardown(); } - // FIXME: We add an overlay slot to the wrapper, but the content node already has a slot="content" - // This is a big problem, because slots should be direct children of its host element. - // Putting the shadow outlet slot in between breaks that. https://github.com/ing-bank/lion/issues/382 - /** - * @desc Should be called by Subclasser for local overlay support in shadow roots - * Create an outlet slot in shadow dom that our local overlay can pass through - */ - _createOutletForLocalOverlay() { - const outlet = document.createElement('slot'); - outlet.name = '_overlay-shadow-outlet'; - this.shadowRoot.appendChild(outlet); - this._overlayCtrl._contentNodeWrapper.slot = '_overlay-shadow-outlet'; + __setupSyncFromOverlayController() { + this.__onOverlayCtrlShow = () => { + this.opened = true; + }; + this.__onOverlayCtrlHide = () => { + this.opened = false; + }; + this.__onBeforeShow = () => { + this.dispatchEvent(new Event('before-show')); + }; + + this._overlayCtrl.addEventListener('show', this.__onOverlayCtrlShow); + this._overlayCtrl.addEventListener('hide', this.__onOverlayCtrlHide); + this._overlayCtrl.addEventListener('before-show', this.__onBeforeShow); } - /** - * @desc Two options for a Subclasser: - * - 1: Define a template in `._overlayTemplate`. In this case the overlay content is - * predefined and thus belongs to the web component. Examples: datepicker. - * - 2: Define a getter `_overlayContentNode` that returns a node reference to a (content - * projected) node. Used when Application Developer is in charge of the content. Examples: - * popover, dialog, bottom sheet, dropdown, tooltip, select, combobox etc. - */ - get __managesOverlayViaTemplate() { - return Boolean(this._overlayTemplate); + __teardownSyncFromOverlayController() { + this._overlayCtrl.removeEventListener('show', this.__onOverlayCtrlShow); + this._overlayCtrl.removeEventListener('hide', this.__onOverlayCtrlHide); + this._overlayCtrl.removeEventListener('before-show', this.__onBeforeShow); } - __syncOpened() { - if (this._opened) { + __syncToOverlayController() { + if (this.opened) { this._overlayCtrl.show(); } else { this._overlayCtrl.hide(); } } - - __syncPopper() { - if (this._overlayCtrl) { - // TODO: Use updateConfig directly.. But maybe we can remove this entirely. - this._overlayCtrl.updatePopperConfig(this.config.popperConfig); - } - } }, ); diff --git a/packages/overlays/stories/index.stories.js b/packages/overlays/stories/index.stories.js index 4331b4b96..4b1e6100e 100644 --- a/packages/overlays/stories/index.stories.js +++ b/packages/overlays/stories/index.stories.js @@ -1,7 +1,5 @@ import { storiesOf, html, withKnobs } from '@open-wc/demoing-storybook'; import { css, render, LitElement } from '@lion/core'; -import '@lion/icon/lion-icon.js'; -import '@lion/button/lion-button.js'; import { withBottomSheetConfig, withDropdownConfig, @@ -70,7 +68,7 @@ const overlayDemoStyle = css` flex-direction: column; } - .overlay { + .demo-overlay { display: block; position: absolute; font-size: 16px; @@ -80,7 +78,7 @@ const overlayDemoStyle = css` padding: 8px; } - .overlay lion-button { + .demo-overlay button { color: black; } @@ -93,11 +91,6 @@ const overlayDemoStyle = css` customElements.define( 'lion-demo-overlay', class extends OverlayMixin(LitElement) { - constructor() { - super(); - this.closeEventName = 'demo-overlay-close'; - } - // eslint-disable-next-line class-methods-use-this _defineOverlayConfig() { return { @@ -107,24 +100,20 @@ customElements.define( _setupOpenCloseListeners() { this.__toggle = () => { - console.log('toggle!'); this.opened = !this.opened; }; - - console.log(this._overlayCtrl.invokerNode, this, this.__toggle); - this._overlayCtrl.invokerNode.addEventListener('click', this.__toggle); - this._overlayCtrl.invokerNode.addEventListener('click', () => console.log('ay')); + this._overlayInvokerNode.addEventListener('click', this.__toggle); } _teardownOpenCloseListeners() { - console.log('teardown for', this); - this._overlayCtrl.invokerNode.removeEventListener('click', this.__toggle); + this._overlayInvokerNode.removeEventListener('click', this.__toggle); } render() { return html` + `; } }, @@ -145,25 +134,25 @@ storiesOf('Overlay System | Overlay as a WC', module)

To close your overlay from some action performed inside the content slot, fire a - close event. + hide event.

For the overlay to close, it will need to bubble to the content slot (use - bubbles: true. Also composed: true if it needs to traverse shadow - boundaries) + bubbles: true. If absolutely needed composed: true can be used to + traverse shadow boundaries)

The demo below demonstrates this

- Overlay -
+ +
Hello! You can close this notification here: - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
@@ -174,15 +163,15 @@ storiesOf('Overlay System | Overlay as a WC', module) - Overlay ${placement} -
+ +
Hello! You can close this notification here: - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
`; @@ -204,27 +193,25 @@ storiesOf('Overlay System | Overlay as a WC', module) ${overlayDemoStyle} - Overlay -
+ +
Hello! This is a notification. - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >Close + - Open child -
+ +
Hello! You can close this notification here: - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
@@ -242,15 +229,15 @@ storiesOf('Overlay System | Overlay as a WC', module) - Overlay -
+ +
Hello! You can close this notification here: - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
@@ -307,15 +294,15 @@ storiesOf('Overlay System | Overlay as a WC', module) .add('Switch overlays configuration', () => { const overlay = renderOffline(html` - Overlay -
+ +
Hello! You can close this notification here: - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
`); @@ -376,15 +363,15 @@ storiesOf('Overlay System | Overlay as a WC', module) } }} > - Overlay -
+ +
Hello! You can close this notification here: - - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} > + ⨯ +
`, @@ -411,7 +398,7 @@ storiesOf('Overlay System | Overlay as a WC', module) }} >UK -
+
United Kingdom
@@ -475,13 +462,13 @@ storiesOf('Overlay System | Overlay as a WC', module) : { popperConfig: { placement: text('local config', 'top-start') } }), }} > - Overlay -
+ +
Hello! You can close this notification here: - e.target.dispatchEvent(new Event('demo-overlay-close', { bubbles: true }))} - >⨯ e.target.dispatchEvent(new Event('hide', { bubbles: true }))} + >⨯
diff --git a/packages/overlays/stories/overlay-features.stories.js b/packages/overlays/stories/overlay-features.stories.js index fd9a7d9f2..b6108c402 100644 --- a/packages/overlays/stories/overlay-features.stories.js +++ b/packages/overlays/stories/overlay-features.stories.js @@ -233,7 +233,7 @@ storiesOf('Overlay System | Behavior Features', module) ${this.options[(this.options.indexOf(this.placement) + 1) % this.options.length]} position - + `; } @@ -265,9 +265,6 @@ storiesOf('Overlay System | Behavior Features', module) element.addEventListener('toggle-placement', e => { overlayCtrl.updateConfig({ viewportConfig: { placement: e.detail } }); }); - element.addEventListener('close', () => { - overlayCtrl.hide(); - }); return html`
- Tooltip +
Hello there!
@@ -67,19 +65,19 @@ storiesOf('Overlays Specific WC|Tooltip', module)
- Top +
Its top placement
- Right +
Its right placement
- Bottom +
Its bottom placement
- Left +
Its left placement
@@ -119,7 +117,7 @@ storiesOf('Overlays Specific WC|Tooltip', module) }), }}" > - ${text('Invoker text', 'Hover me!')} +
${text('Content text', 'Hello, World!')}
diff --git a/packages/tooltip/test/lion-tooltip.test.js b/packages/tooltip/test/lion-tooltip.test.js index 45d64bddc..5d61bd42f 100644 --- a/packages/tooltip/test/lion-tooltip.test.js +++ b/packages/tooltip/test/lion-tooltip.test.js @@ -1,24 +1,26 @@ -import { expect, fixture, html } from '@open-wc/testing'; +import { expect, fixture, html, unsafeStatic } from '@open-wc/testing'; +import { runOverlayMixinSuite } from '@lion/overlays/test-suites/OverlayMixin.suite.js'; import '../lion-tooltip.js'; describe('lion-tooltip', () => { - describe('Basic', () => { - it('should not be shown by default', async () => { - const el = await fixture(html` - -
Hey there
- Tooltip button -
- `); - expect(el._overlayCtrl.isShown).to.equal(false); - }); + describe('Integration tests', () => { + const tagString = 'lion-tooltip'; + const tag = unsafeStatic(tagString); + runOverlayMixinSuite({ + tagString, + tag, + suffix: ' for lion-tooltip', + }); + }); + + describe('Basic', () => { it('should show content on mouseenter and hide on mouseleave', async () => { const el = await fixture(html`
Hey there
- Tooltip button +
`); const eventMouseEnter = new Event('mouseenter'); @@ -35,7 +37,7 @@ describe('lion-tooltip', () => { const el = await fixture(html`
Hey there
- Tooltip button +
`); const eventMouseEnter = new Event('mouseenter'); @@ -52,7 +54,7 @@ describe('lion-tooltip', () => { const el = await fixture(html`
Hey there
- Tooltip button +
`); const invoker = Array.from(el.children).find(child => child.slot === 'invoker'); @@ -70,7 +72,7 @@ describe('lion-tooltip', () => { const el = await fixture(html`
Hey there
- Tooltip button +
`); const invoker = Array.from(el.children).find(child => child.slot === 'invoker'); @@ -90,7 +92,7 @@ describe('lion-tooltip', () => {
This is Tooltip using overlay
- Tooltip button + `); const invoker = Array.from(el.children).find(child => child.slot === 'invoker'); @@ -106,7 +108,7 @@ describe('lion-tooltip', () => { const el = await fixture(html`
Hey there
- Tooltip button +
`); diff --git a/yarn.lock b/yarn.lock index 84580045d..7cfb81f99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2088,7 +2088,7 @@ wallaby-webpack "^3.0.0" webpack "^4.28.0" -"@open-wc/testing@^2.3.4", "@open-wc/testing@^2.3.9": +"@open-wc/testing@^2.3.4": version "2.3.9" resolved "https://registry.yarnpkg.com/@open-wc/testing/-/testing-2.3.9.tgz#048bb3122d989cf0df96611513aaec7738964e3d" integrity sha512-5pKtHNP/73y9VWAwXOdxf4uzKVAtCowSdy4B6It4iETq8RshkAtKJbJBj+iQSU81pG6jOgSNPlGYeU01/CXaxw==