ui-lit
Version:
UI Elements on LIT
359 lines (358 loc) • 13.5 kB
JavaScript
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
= "${() => this._hover("sort", true)}"
= "${() => this._hover("sort", false)}"
= "${() => this._pointer("sort", true)}"
= "${() => 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
= "${this._onFilterToggle}"
= "${() => this._hover("filter", true)}"
= "${() => this._hover("filter", false)}"
= "${() => this._pointer("filter", true)}"
= "${() => 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
= "${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
= "${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
= "${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 };