UNPKG

ui-lit

Version:

UI Elements on LIT

359 lines (358 loc) 13.5 kB
import { __decorate } from "tslib"; import { selectCSSVarNames } from './../select/styles'; import { ifDefined } from 'lit/directives/if-defined'; import { classMap } from 'lit/directives/class-map'; import { LitElement, html, css, nothing } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { noselect } from '../styles/noselect'; import '../textfield'; import '../number'; import '../divider'; import '../button'; import '../select'; import { isClickInElement, getHost } from 'kailib'; import { tableHeaderStyles, filterWidth } from './styles'; let dialogOpened = false; let LitTableHeader = class LitTableHeader extends LitElement { constructor() { super(...arguments); this.align = 'left'; this.sort = ''; this.sortDirection = 'ascend'; this._filterVisible = false; this._host = null; this._sortHover = false; this._filterHover = false; this._pointer = (type, state) => { if (type === "sort" && !this._sortHover) { this._sortHover = state; } if (type === "filter" && !this._filterHover) { this._filterHover = state; } }; this._hover = (type, state) => { if (type === "sort") { this._sortHover = state; } if (type === "filter") { this._filterHover = state; } }; this._showFilter = () => { this.filterVisible = true; dialogOpened = true; document.addEventListener('click', this._documentClick); }; this._hideFilter = () => { this.filterVisible = false; dialogOpened = false; document.removeEventListener('click', this._documentClick); }; this._documentClick = (e) => { if (!isClickInElement(e, this)) { this._onFilterToggle(e); } }; } connectedCallback() { super.connectedCallback(); this.sortDirection = this.directions[0] || 'ascend'; this._host = getHost(this); } willUpdate(_changedProperties) { var _a; if (this.filterVisible && ((_a = this._host) === null || _a === void 0 ? void 0 : _a.rect)) { const width = this.clientWidth; const avalableLeft = this.offsetLeft + width; const avalableRight = this._host.rect.width - this.offsetLeft; const overflowLeft = filterWidth - avalableLeft > 0; const overflowRight = filterWidth - avalableRight > 0; if (!overflowRight) { this.style.setProperty("--left-offset", "1px"); this.style.setProperty("--right-offset", "initial"); } else if (!overflowLeft) { this.style.setProperty("--left-offset", "initial"); this.style.setProperty("--right-offset", "1px"); } else if (avalableRight > avalableLeft) { this.style.setProperty("--left-offset", `-${this.offsetLeft - 5}px`); this.style.setProperty("--right-offset", "initial"); } else { this.style.setProperty("--left-offset", `initial`); this.style.setProperty("--right-offset", `-${avalableRight - width - 5}px`); } } } get filterVisible() { return this._filterVisible; } set filterVisible(value) { const oldValue = this._filterVisible; this._filterVisible = value; this.requestUpdate('filterVisible', oldValue); } get isSort() { var _a; return this.sort === ((_a = this.item) === null || _a === void 0 ? void 0 : _a.key); } get directions() { var _a; return ((_a = this.item) === null || _a === void 0 ? void 0 : _a.sortDirections) || ['ascend', 'descend']; } get filtersData() { var _a; return this.filters || ((_a = this.item) === null || _a === void 0 ? void 0 : _a.filters); } _getNewDirection() { const directions = this.directions; const index = directions.indexOf(this.sortDirection); if (index === -1 || !this.isSort) { return directions[0]; } if (directions.length - 1 < index) { return ''; } return directions[index + 1]; } /** Templates */ _sortTemplate() { var _a; if ((_a = this.item) === null || _a === void 0 ? void 0 : _a.sorter) { return html `<div @mouseover = "${() => this._hover("sort", true)}" @mouseout = "${() => this._hover("sort", false)}" @pointerdown = "${() => this._pointer("sort", true)}" @pointerup = "${() => this._pointer("sort", false)}" ?hover = "${this._sortHover}" class = "sort-icons"> ${this.directions.slice().sort().map(it => { if (it === 'ascend') { return html `<lit-icon icon = "dropup"></lit-icon>`; } else { return html `<lit-icon icon = "dropdown"></lit-icon>`; } })} </div>`; } } _filterIconTemplate() { if (!this.filtersData) return nothing; const map = { "filters-checked": this.filtersData.filter(it => it.checked).length }; return html `<lit-icon @click = "${this._onFilterToggle}" @mouseover = "${() => this._hover("filter", true)}" @mouseout = "${() => this._hover("filter", false)}" @pointerdown = "${() => this._pointer("filter", true)}" @pointerup = "${() => this._pointer("filter", false)}" ?hover = "${this._filterHover}" class = "${classMap(map)}" icon = "filter"></lit-icon>`; } updated(_changedProperties) { } _filterItemTemplate(item, i) { var _a; console.log(item.value); let type = item.type; const value = Array.isArray(item.value) ? item.value[0] : item.value; if (item.type === 'number') { type = 'text'; } if (type === 'checkbox' || !item.type) { return html ` <lit-label> ${item.text} </lit-label> <lit-checkbox .checked = "${item.checked || false}" name = "${i}"></lit-checkbox>`; } else if (type === 'number') { return html ` <lit-label> ${item.text} </lit-label> <lit-numberfield name = "${i.toString()}" value = "${item.value}" placeholder = "${ifDefined(item.placeholder)}"></lit-numberfield>`; } else if (type === 'text' || type === 'date') { /// text return html ` <lit-label> ${item.text} </lit-label> <lit-textfield type = "${type}" name = "${i.toString()}" value = "${value}" placeholder = "${ifDefined(item.placeholder)}"></lit-textfield>`; } else if (type === 'select') { return html ` <lit-label> ${item.text} </lit-label> <lit-select name = "${i.toString()}" searchable multiple listboxPosition = "top" placeholder = "${ifDefined(item.placeholder)}"> ${(_a = item.items) === null || _a === void 0 ? void 0 : _a.map(it => html `<lit-option .selected = "${Array.isArray(item.value) ? item.value.includes(it) : item.value === it}" value = "${it}">${it}</lit-option>`)} </lit-select>`; } return nothing; } _filterTemplate() { if (!this.filterVisible) return nothing; return html `<lit-form @submit = "${this._onSubmitFilter}" class = "filter-template"> <div class = "rows"> ${this.filtersData.map((it, i) => html `<div class = "row"> ${it.title && html `<div style = "grid-column: 1/3;">${it.title}</div>`} ${this._filterItemTemplate(it, i)} ${it.divider && html `<lit-divider style = "grid-column: 1/3;"></lit-divider>`} </div>`)} </div> <footer> <lit-button @click = "${this._onReset}" type = "button" size = "small">Reset</lit-button> <lit-button type = "submit" primary size = "small">OK</lit-button> </footer> </lit-form>`; } render() { var _a, _b; const map = { "wrapper": true, "noselect": true, "sorted": this.isSort, "sorter": !!((_a = this.item) === null || _a === void 0 ? void 0 : _a.sorter) }; return html `<div @click = "${this._onChangeSort}" class = "${classMap(map)}"> <div>${(_b = this.item) === null || _b === void 0 ? void 0 : _b.title}</div>${this._sortTemplate()}${this._filterIconTemplate()} </div> ${this._filterTemplate()}`; } _onFilterToggle(e) { //e.stopPropagation(); // Скрывать если открыт фильтр, предотвращать клик на смену сортировки // if (!this.filterVisible) { this._showFilter(); } else { this._hideFilter(); } } _onChangeSort() { var _a; if (dialogOpened) return; if (!((_a = this.item) === null || _a === void 0 ? void 0 : _a.sorter)) return; const direction = this._getNewDirection(); this.dispatchEvent(new CustomEvent("changeSort", { detail: { sort: direction ? this.item.key : '', direction }, bubbles: true })); } _onSubmitFilter(e) { var _a; this._hideFilter(); const data = e.detail.data; const filters = this.filtersData.map((it, i) => { if (!it.type || it.type === 'checkbox') { return { ...it, checked: data[i] }; } if (it.type === 'select') { return { ...it, value: data[i], checked: Boolean(data[i].length) }; } return { ...it, value: data[i], checked: !!data[i] }; }); console.log(filters); this.dispatchEvent(new CustomEvent("changeFilter", { detail: { key: (_a = this.item) === null || _a === void 0 ? void 0 : _a.key, filters }, bubbles: true, composed: true, })); } _onReset() { var _a; this._hideFilter(); this.dispatchEvent(new CustomEvent("resetFilter", { detail: (_a = this.item) === null || _a === void 0 ? void 0 : _a.key, bubbles: true, composed: true, })); } }; LitTableHeader.styles = [ css ` ${selectCSSVarNames.listboxHeight}: var(--max-select-height); `, tableHeaderStyles, noselect ]; __decorate([ property({ type: String, reflect: true }) ], LitTableHeader.prototype, "align", void 0); __decorate([ property({ type: Object }) ], LitTableHeader.prototype, "item", void 0); __decorate([ property({ type: Array }) ], LitTableHeader.prototype, "filters", void 0); __decorate([ property({ type: String }) ], LitTableHeader.prototype, "sort", void 0); __decorate([ property({ type: String, reflect: true }) ], LitTableHeader.prototype, "sortDirection", void 0); __decorate([ state() ], LitTableHeader.prototype, "_sortHover", void 0); __decorate([ state() ], LitTableHeader.prototype, "_filterHover", void 0); LitTableHeader = __decorate([ customElement('lit-table-header') ], LitTableHeader); export { LitTableHeader };