isu-element
Version:
Polymer components for building web apps.
277 lines (245 loc) • 6.42 kB
JavaScript
import {html, PolymerElement} from "@polymer/polymer";
import {mixinBehaviors} from "@polymer/polymer/lib/legacy/class";
import '@polymer/paper-dialog';
import '@polymer/neon-animation/animations/scale-up-animation.js';
import '@polymer/neon-animation/animations/fade-out-animation.js';
import '@polymer/iron-icon';
import '@polymer/iron-icons';
import {BaseBehavior} from "./behaviors/base-behavior";
import './behaviors/isu-elements-shared-styles.js';
/**
* `isu-dialog`
*
* Example:
* ```html
* <isu-dialog id="dialog">
* Put your Content here inside an element which with [slot=container]
* </isu-dialog>
* <button id="btn" onclick="javascript:dialog.open();">Click to open the Dialog</button>
* ```
* ## Styling
*
* The following custom properties and mixins are available for styling:
*
* |Custom property | Description | Default|
* |----------------|-------------|----------|
* |`--isu-dialog-width` | Mixin applied to the width of dialog | 85%
* |`--isu-dialog-height` | Mixin applied to the height of dialog | 90%
* |`--isu-dialog-title` | Mixin applied to the style of dialog title | {}
* @customElement
* @polymer
* @demo demo/isu-dialog/index.html
*/
class IsuDialog extends mixinBehaviors([BaseBehavior], PolymerElement) {
static get template() {
return html`
<style include="isu-elements-shared-styles">
:host {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: none;
align-items: center;
justify-content: center;
z-index: 99;
}
#dialog {
position: relative;
display: flex;
flex-flow: column nowrap;
align-content: stretch;
width: var(--isu-dialog-width, 85%);
height: var(--isu-dialog-height, 90%);
border-radius: 6px;
font-family: var(--isu-ui-font-family), sans-serif;
font-size: var(--isu-ui-font-size);
}
.scrollable-container {
flex: 1;
overflow-x: hidden;
overflow-y: auto;
margin: 0;
padding: 12px;
@apply --isu-dialog-content;
}
.close-dialog {
position: absolute;
top: -14px;
right: -14px;
cursor: pointer;
z-index: 10;
color: #797979;
}
.close-dialog:hover {
color: var(--isu-ui-red);
}
.title {
font-size: 26px;
font-weight: bold;
margin: 20px 0 10px;
text-align: left;
padding: 0 16px;
@apply --isu-dialog-title;
}
:host([modal]) .backdrop {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
z-index: 1;
}
</style>
<paper-dialog id="dialog"
entry-animation="scale-up-animation"
exit-animation="fade-out-animation"
no-cancel-on-esc-key="[[noCancelOnEscKey]]"
opened="{{opened}}"
no-cancel-on-outside-click="[[noCancelOnOutsideClick]]" on-opened-changed="openedChanged">
<div class="close-dialog" on-tap="close">
<iron-icon icon="icons:close"></iron-icon>
</div>
<template is="dom-if" if="[[ toBoolean(title) ]]">
<div class="title">[[title]]</div>
</template>
<div class="scrollable-container">
<slot></slot>
</div>
</paper-dialog>
<div class="backdrop"></div>
`;
}
static get properties() {
return {
/**
* Title of the dialog
*/
title: {
type: String
},
/**
* Set to True to stop auto dismiss.
* @type {boolean}
* @default false
*/
stopAutoDismiss: {
type: Boolean,
value: false
},
/**
* @type {boolean}
* @default false
*/
modal: {
type: Boolean,
value: false,
reflectToAttribute: true,
observer: 'modalChanged'
},
/**
* @type {boolean}
* @default false
*/
noCancelOnOutsideClick: {
type: Boolean,
value: false,
reflectToAttribute: true
},
noCancelOnEscKey: {
type: Boolean,
value: false
},
opened: {
type: Boolean,
reflectToAttribute: true
},
/**
* 距顶端的距离
* */
top: {
type: Number
},
/**
* 距左边的距离
* */
left: {
type: Number
},
/**
* 是否在 Dialog 出现时将 body 滚动锁定
* */
lockScroll: {
type: Boolean,
value: false
}
};
}
static get observers() {
return ['_positionChanged(top, left)']
}
static get is() {
return "isu-dialog";
}
_positionChanged(top, left) {
if (top) this.$.dialog.style.top = `${top}px`
if (left) this.$.dialog.style.left = `${left}px`
}
connectedCallback() {
super.connectedCallback();
/**
* @listens iron-overlay-closed
*/
this.addEventListener('iron-overlay-closed', e => {
// ignore 'iron-overlay-closed' event fired by other element
if (e.path[0] != this.$.dialog) return;
e.stopPropagation();
/**
* @event isu-dialog-closed
* Fired when the dialog closed.
*/
this.dispatchEvent(new CustomEvent('isu-dialog-closed'), {
composed: true,
bubbles: true
});
if (!this.stopAutoDismiss) {
setTimeout(() => {
this.parentElement && this.parentElement.removeChild(this);
}, 100);
}
});
/**
* @listens isu-dialog-dismiss
*/
this.addEventListener('isu-dialog-dismiss', this.close);
}
/**
* Open the dialog.
*/
open() {
this.style.display = 'flex';
this.$.dialog.open();
if (this.lockScroll ) document.body.style['overflow-y'] = 'hidden'
}
/**
* Close the dialog.
*/
close() {
this.style.display = 'none';
this.$.dialog.close();
if (this.lockScroll) document.body.style['overflow-y'] = 'auto'
}
openedChanged({detail: {value}}) {
if (!value) this.close();
}
modalChanged(modal) {
if(modal) {
this.noCancelOnOutsideClick = true;
this.noCancelOnEscKey = true;
}
}
}
window.customElements.define(IsuDialog.is, IsuDialog);