@furo/layout
Version:
Layout components for furo
210 lines (201 loc) • 6.58 kB
JavaScript
import { __decorate } from "tslib";
import { LitFBP } from '@furo/fbp/dist/LitFBP';
import { css, html, LitElement } from 'lit';
import { property } from "lit/decorators.js";
import { FuroBackdrop } from "./FuroBackdrop";
/**
* `furo-backdrop-display`
*
* This components receives and displays the backdrop requests from furo-backdrop components.
*
* The backdrop display can be placed anywhere in the dom. The higher the better.
*
* Tipp: place it below or inside the component which applies the style vars. Othewise the displayed components
* do not know these vars.
*
* ```html
* <!-- place the display in your main-stage -->
* <furo-backdrop-display></furo-backdrop-display>
* ```
*
* @cssprop {0px} [--furo-backdrop-color=#6d6d6d] - background color of backdrop
*
* @summary Display component for furo-backdrop
* @customElement
* @demo demo-furo-backdrop Basic usage
* @appliesMixin FBP
*/
export class FuroBackdropDisplay extends LitFBP(LitElement) {
constructor() {
super(...arguments);
/**
* Needed to start the animation.
* @private
*/
this.start = false;
/**
* Indicates that the backdrop is shown.
* @private
*/
this.show = false;
/**
* Timeout duration, to wait to notify the changes.
*
* Note: the animations in the css are set with 250ms.
*
* If you are interested to use at-opened to load some data, set this value lower. This gives you 250 ms extra time to load content, without feeling slow.
*
* If you are interested to use at-opened to show some ui stuff, set this value higher or equal 250.
*
* @type Number
*/
this.toDuration = 100;
}
/**
* flow is ready lifecycle method
* @private
*/
_FBPReady() {
super._FBPReady();
// listen on clicks on backdrop to close it
this.shadowRoot.getElementById('backdrop').addEventListener('click', () => {
this.close();
});
/**
* items which should be shown in the backdrop must be registered
* Otherwise we trigger a lot of connected and disconnected callbacks
*/
this.parentNode.addEventListener('register-backdrop', ((e) => {
this.contentSource = e.detail.handle;
this.contentSource.displayHandle = this.shadowRoot.getElementById('ctnt')
.appendChild(this.contentSource.children[0]);
}));
/**
* Listen to close requests
*/
this.parentNode.addEventListener('close-backdrop-requested', ((e) => {
this.contentSource = e.detail.handle;
this.close();
}));
/**
* Listen to show requests
*/
this.parentNode.addEventListener('show-backdrop-requested', ((e) => {
this.contentSource = e.detail.handle;
// set registered item to _active
this.contentSource.displayHandle?.classList.toggle('_active');
// start backdrop animation with a timeout of 1
this.start = true;
setTimeout(() => {
this.show = true;
setTimeout(() => {
// notify via furo-backdrop that it is opened
this.contentSource.dispatchEvent(new CustomEvent('opened', { composed: true, bubbles: true }));
}, this.toDuration);
}, 1);
}));
}
/**
* closes the backdrop.
* You can close the backdrop on the display element, this is useful when you want to close the backdrops on page
* changes.
*
* Usually the component which triggers the backdrop or is displayed closes it.
*/
close() {
// start animation => look at the css
this.show = false;
setTimeout(() => {
// end animation
this.start = false;
// deactivate the backdrop visibility
this.contentSource.displayHandle?.classList.toggle('_active');
// notify furo-backdrop that it is closed now
this.contentSource.dispatchEvent(new CustomEvent('closed', { composed: true, bubbles: true }));
}, this.toDuration);
}
/**
* Themable Styles
* @private
* @return {CSSResult}
*/
static get styles() {
// language=CSS
return (css `
:host {
position: absolute;
display: none;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
/* used to start the amimations */
:host([start]) {
display: block;
}
:host([start]) #backdrop {
opacity: 0;
}
:host([show]) #backdrop {
opacity: 0.6;
}
#backdrop {
width: 100%;
height: 100%;
transition: opacity 250ms;
opacity: 0;
background-color: var(--furo-backdrop-color, #6d6d6d);
}
/* center the content exactly in the middle */
:host .ctnt {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.3);
z-index: 11;
transition: all 250ms ease-out;
}
/* content area not visible at start time */
:host([start]) .ctnt {
visibility: hidden;
}
/* switch content area to visible */
:host([show]) .ctnt {
visibility: visible;
transform: translate(-50%, -50%) scale(1); /* center it exactly in the middle */
}
/* backdropped content by default not visible */
.ctnt > * {
display: none;
}
.ctnt > *._active {
display: block;
}
`);
}
/**
* @private
* @returns {TemplateResult}
* @private
*/
render() {
// language=HTML
return html `
<div id='backdrop'></div>
<div id='ctnt' class='ctnt'></div>
`;
}
}
__decorate([
property({ type: Boolean, reflect: true })
], FuroBackdropDisplay.prototype, "start", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], FuroBackdropDisplay.prototype, "show", void 0);
__decorate([
property({ type: Number, attribute: 'to-duration', })
], FuroBackdropDisplay.prototype, "toDuration", void 0);
window.customElements.define('furo-backdrop-display', FuroBackdropDisplay);
//# sourceMappingURL=FuroBackdropDisplay.js.map