import { css, LitElement, render } from '@lion/core'; import { html, storiesOf, withKnobs } from '@open-wc/demoing-storybook'; import { OverlayMixin, withBottomSheetConfig, withDropdownConfig, withModalDialogConfig, } from '../index.js'; function renderOffline(litHtmlTemplate) { const offlineRenderContainer = document.createElement('div'); render(litHtmlTemplate, offlineRenderContainer); return offlineRenderContainer.firstElementChild; } // Currently toggling while opened doesn't work (see OverlayController) /* let toggledPlacement = 'top'; const togglePlacement = popupController => { const placements = [ 'top-end', 'top', 'top-start', 'right-end', 'right', 'right-start', 'bottom-start', 'bottom', 'bottom-end', 'left-start', 'left', 'left-end', ]; toggledPlacement = placements[(placements.indexOf(toggledPlacement) + 1) % placements.length]; popupController.updateConfig({ togglePlacement }); }; */ const overlayDemoStyle = css` .demo-box { width: 200px; background-color: white; border-radius: 2px; border: 1px solid grey; padding: 8px; } .demo-box_placements { display: flex; flex-direction: column; width: 173px; margin: 0 auto; margin-top: 68px; } lion-demo-overlay { padding: 10px; } .close-button { color: black; font-size: 28px; line-height: 28px; } .demo-box__column { display: flex; flex-direction: column; } .demo-overlay { display: block; position: absolute; font-size: 16px; color: white; background-color: black; border-radius: 4px; padding: 8px; } .demo-overlay button { color: black; } .demo-popup { padding: 10px; border: 1px solid black; } `; customElements.define( 'lion-demo-overlay', class extends OverlayMixin(LitElement) { // eslint-disable-next-line class-methods-use-this _defineOverlayConfig() { return { placementMode: 'global', // have to set a default }; } _setupOpenCloseListeners() { super._setupOpenCloseListeners(); this.__toggle = () => { this.opened = !this.opened; }; this._overlayInvokerNode.addEventListener('click', this.__toggle); } _teardownOpenCloseListeners() { super._teardownOpenCloseListeners(); this._overlayInvokerNode.removeEventListener('click', this.__toggle); } render() { return html` `; } }, ); storiesOf('Overlay System | Overlay as a WC', module) .addDecorator(withKnobs) .add( 'Default', () => html`

Important note: For placementMode: 'global', your slot="content" gets moved to global overlay container. After initialization it is no longer a child of lion-demo-overlay

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

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

The demo below demonstrates this

Hello! You can close this notification here:
`, ) .add('Global placement configuration', () => { const overlay = placement => html`
Hello! You can close this notification here:
`; return html`
${overlay('center')} ${overlay('top-left')} ${overlay('top-right')} ${overlay('bottom-left')} ${overlay('bottom-right')}
`; }) .add( 'Nested overlays', () => html`
Hello! This is a notification.
Hello! You can close this notification here:
`, ) .add( 'Local placementMode', () => html`
Hello! You can close this notification here:
`, ) .add( 'Override the popper config', () => html`
The API is aligned with Popper.js, visit their documentation for more information: Popper.js Docs
United Kingdom
`, ) .add('Switch overlays configuration', () => { const overlay = renderOffline(html`
Hello! You can close this notification here:
`); return html`
${overlay}
`; }) .add( 'Responsive switching', () => html`

Open the overlay on a big screen and it will be a dialog

Close and open it again on a small screen (< 600px) and it will be a bottom sheet

{ if (window.innerWidth >= 600) { e.target.config = { ...withModalDialogConfig() }; } else { e.target.config = { ...withBottomSheetConfig() }; } }} >
Hello! You can close this notification here:
`, ) .add('On hover', () => { const popup = renderOffline(html` { popup.opened = true; }} @mouseleave=${() => { popup.opened = false; }} >UK
United Kingdom
`); return html`

In the beautiful ${popup} the weather is nice.

`; }) .add('On an input', () => { const popup = renderOffline(html`
United Kingdom
e.stopImmediatePropagation()} @focusout=${() => { popup.opened = false; }} @focusin=${() => { popup.opened = true; }} />
`); return html`
${popup}
`; }) .add('Sync application state', () => { const appState = { opened: true, }; const openedStateNode = renderOffline( html` ${appState.opened} `, ); function onOpenClosed(ev) { appState.opened = ev.target.opened; openedStateNode.innerText = appState.opened; } const popup = renderOffline(html`
Hello! You can close this notification here:
`); return html` appState.opened: ${openedStateNode}
${popup}
`; }) .add('Intercept open/close', () => { let shouldIntercept = true; let shouldInterceptButton; function toggleIntercept() { shouldIntercept = !shouldIntercept; shouldInterceptButton.textContent = shouldIntercept; } function intercept(ev) { if (shouldIntercept) { ev.preventDefault(); } } shouldInterceptButton = renderOffline( html` `, ); const popup = renderOffline(html`
Hello! You can close this notification here:
`); return html` toggle shouldIntercept:${shouldInterceptButton}
${popup}
`; }); /* .add('Toggle placement with knobs', () => { const overlay = (placementMode = 'global') => html`
Hello! You can close this notification here:
`; return html`

Local

${overlay('local')}

Global

${overlay()}
`; }) */