isu-element
Version:
Polymer components for building web apps.
317 lines (282 loc) • 7.61 kB
JavaScript
import {mixinBehaviors} from "@polymer/polymer/lib/legacy/class";
import {BaseBehavior} from "./behaviors/base-behavior";
import {html, PolymerElement} from "@polymer/polymer";
import '@polymer/iron-collapse';
import './behaviors/isu-elements-shared-styles';
import './isu-button';
/**
*
* `isu-button-group`
*
* Example:
* ```html
* <isu-button-group label="测试">
* <div bind-item="1">测试1</div>
* <div bind-item="2">测试2</div>
* <div bind-item="3">测试3</div>
* </isu-button-group>
*
*
* <isu-button-group items="[[ items ]]" label="测试" attr-for-label="label"></isu-button-group>
*
* items = [
* {label: "测试1", value: "1"},
* {label: "测试2", value: "2"},
* {label: "测试3", value: "3"}
* ]
*
* ```
*
* ## Styling
*
* The following custom properties and mixins are available for styling:
*
* |Custom property | Description | Default|
* |----------------|-------------|----------|
* |`--isu-button-group-button` | Mixin applied to the group button | {}
* |`--isu-button-group-dropdown` | Mixin applied to the group dropdown | {}
*
* @customElement
* @polymer
* @demo demo/isu-button-group/index.html
*/
class IsuButtonGroup extends mixinBehaviors([BaseBehavior], PolymerElement) {
static get template() {
return html`
<style include="isu-elements-shared-styles">
:host {
display: inline-block;
min-width: 70px;
outline: none;
font-family: var(--isu-ui-font-family), sans-serif;
font-size: var(--isu-ui-font-size);
}
/*.box {*/
/*!*position: relative;*!*/
/*!*width: 100%;*!*/
/*!*height: 100%;*!*/
/*}*/
.trigger {
width: 100%;
height: 100%;
display: flex;
border-radius: var(--isu-ui-border-radius);
@apply --isu-button-group-button;
}
.trigger:hover {
}
.trigger__label {
flex: 1;
}
:host([divided]) .trigger__label::after {
width: 2px;
border-right: 1px solid lightgray;
content: '|';
color: transparent;
float: right;
}
/*下拉列表*/
:host .dropdown-menu {
position: fixed;
background: #fff;
color: var(--isu-ui-color_skyblue);
flex-flow: column nowrap;
box-sizing: border-box;
z-index: 999;
/*width: 100%;*/
/*margin-top: 2px;*/
font-size: 1em;
text-align: center;
background-clip: padding-box;
--iron-collapse-transition-duration: 200ms;
overflow: auto;
@apply --isu-button-group-dropdown;
}
.dropdown-menu::-webkit-scrollbar {
display: none;
}
.container {
border-radius: var(--isu-ui-border-radius);
border: 1px solid var(--isu-ui-color_skyblue);
}
.item, ::slotted(*) {
display: block;
cursor: pointer;
margin: 0px;
line-height: 20px;
white-space: nowrap;
font-size: 0.9em;
text-align: center;
outline: none;
}
/*hover*/
.item:hover, ::slotted(*:hover) {
color: #fff;
background: var(--isu-ui-bg);
}
.trigger__icon {
transition: transform .2s ease-in-out
}
:host([opened]) .trigger__icon {
transform: rotate(180deg);
transition: transform .2s ease-in-out
}
:host([size=small]) {
width: 90px;
height: 30px;
}
:host([size=medium]) {
width: 120px;
height: 35px;
}
:host([size=large]) {
width: 150px;
height: 40px;
}
:host([disabled]) {
cursor: not-allowed;
color: #fff;
}
.item([disabled]) {
background: #aeaeae ;
cursor: not-allowed;
color: #fff;
}
</style>
<isu-button class="trigger" on-mouseover="toggle" on-mouseout="close" disabled="[[disabled]]">
<div class="trigger__label">[[ label ]]</div>
<iron-icon class="trigger__icon" icon="icons:expand-more"></iron-icon>
</isu-button>
<iron-collapse id="collapse" on-mouseover="toggle" on-mouseout="close" disabled="[[disabled]]" class="dropdown-menu" opened="[[ opened ]]" on-click="_onButtonDropdownClick">
<div class="container">
<template is="dom-repeat" items="[[ items ]]" filter="_hasPermission">
<paper-button class="item" bind-item="[[ item ]]" disabled="[[item.disabled]]">[[ getValueByKey(item, attrForLabel, 'Unknown') ]]</paper-button>
</template>
<slot id="itemSlot"></slot>
</div>
</iron-collapse>
`;
}
static get properties() {
return {
/**
* Size of the action group button.options:small/medium/large.Default option:medium
* */
size: {
type: String,
value: 'medium',
reflectToAttribute: true
},
/**
* Label of the action group.
*/
label: {
type: String
},
/**
* Return true if the action group is expanded.
* @type {boolean}
* @default false
*/
opened: {
type: Boolean,
value: false,
reflectToAttribute: true
},
/**
* The dropdown items.
* @type Array
*/
items: {
type: Array
},
/**
* Attribute name for label.
* @type {string}
* @default 'label'
*/
attrForLabel: {
type: String,
value: "label"
},
/**
* The Function called when user click on every item on dropdownlist.
*/
onItemClick: {
type: Object
},
disabled: {
type: Boolean,
value: false
},
/**
* The items will hide when user clicks one item
* */
hideOnClick: {
type: Boolean,
value: false
}
};
}
static get is() {
return "isu-button-group";
}
connectedCallback() {
super.connectedCallback();
window.addEventListener('scroll', e => {
this.close();
});
}
/**
* Expand the group.
*/
open() {
this.opened = true;
}
/**
* Collpase the group.
*/
close() {
this.opened = false;
}
/**
* Toggle the group.
*/
toggle(e) {
if (!this.disabled) {
const {top, left} = this.getElemPos(this);
const collapseHeight = (this.items || []).length * 30 + 2;
const totalHeight = top + collapseHeight;
let _top;
if(totalHeight > document.documentElement.clientHeight) {
_top = top - collapseHeight - 4;
} else {
_top = top + this.clientHeight;
}
this.$.collapse.style.top = _top + 'px';
this.$.collapse.style.left = left + 'px';
this.$.collapse.style.width = this.clientWidth + 'px';
this.opened = !this.opened;
}
}
getElemPos(obj) {
const {x, y} = obj.getBoundingClientRect();
return {top: y + 2, left: x};
}
_onButtonDropdownClick(e) {
const target = e.target,
bindItem = e.target.bindItem || e.target.getAttribute('bind-item');
if (this.hideOnClick) {
this.opened = false;
}
this.dispatchEvent(new CustomEvent('item-click', {detail: {target, bindItem}}));
}
/**
* 是否有权限
* */
_hasPermission(item) {
const permission = 'permission' in item
return !permission || (permission && item['permission'])
}
}
window.customElements.define(IsuButtonGroup.is, IsuButtonGroup);