@3mo/data-grid
Version:
A data grid web component
127 lines (120 loc) • 4.02 kB
JavaScript
import { __decorate } from "tslib";
import { Component, component, property, html, css, state, eventListener, style } from '@a11d/lit';
import { DirectionsByLanguage } from '@3mo/localization';
let DataGridHeaderSeparator = class DataGridHeaderSeparator extends Component {
constructor() {
super(...arguments);
this.isResizing = false;
this.pointerInlineStart = 0;
this.minimum = 30;
this.handlePointerDown = (e) => {
this.isResizing = true;
this.initialWidth = this.column.widthInPixels;
this.updatePointerPosition(e);
};
this.handleDoubleClick = () => {
this.isResizing = false;
this.column.width = 'max-content';
this.dataGrid.setColumns(this.dataGrid.columns);
};
}
static get styles() {
return css `
:host {
position: absolute;
inset-inline-end: -3px;
height: 100%;
width: 6px;
user-select: none;
}
:host([disabled]) {
pointer-events: none;
}
:host([data-last]) {
inset-inline-end: 0px !important;
}
:host(:hover) {
cursor: col-resize;
}
.separator {
margin-inline: auto;
width: 1px;
height: 100%;
cursor: col-resize;
background-color: var(--mo-color-transparent-gray-3);
transition: 0.1s;
}
:host(:hover) .separator {
width: 100%;
background-color: var(--mo-color-accent);
}
.resizer {
position: fixed;
pointer-events: none;
top: 0;
height: 100%;
background: var(--mo-color-gray);
width: 2px;
}
`;
}
get template() {
return html `
<div class='separator' =${this.handlePointerDown} =${this.handleDoubleClick}></div>
${!this.isResizing ? html.nothing : html `<div class='resizer' ${style({ insetInlineStart: `${this.pointerInlineStart}px` })}></div>`}
`;
}
handlePointerUp() {
if (!this.isResizing) {
return;
}
this.isResizing = false;
this.initialWidth = undefined;
if (this.targetWidth) {
this.column.width = `${this.targetWidth}px`;
}
this.dataGrid.setColumns(this.dataGrid.columns);
}
handlePointerMove(e) {
if (this.isResizing === false || this.initialWidth === undefined) {
return;
}
e.preventDefault();
this.updatePointerPosition(e);
const isRtl = DirectionsByLanguage.get() === 'rtl';
const { left: offsetLeft, right: offsetRight } = this.getBoundingClientRect();
const offsetInlineStart = !isRtl ? offsetLeft : offsetRight;
this.targetWidth = this.initialWidth + this.pointerInlineStart - offsetInlineStart;
if (this.targetWidth < this.minimum) {
this.targetWidth = this.minimum;
}
}
updatePointerPosition(e) {
const isRtl = DirectionsByLanguage.get() === 'rtl';
const clientX = 'touches' in e ? e.touches[0].clientX : e.clientX;
this.pointerInlineStart = !isRtl ? clientX : window.innerWidth - clientX;
}
};
__decorate([
property({ type: Object })
], DataGridHeaderSeparator.prototype, "dataGrid", void 0);
__decorate([
property({ type: Object })
], DataGridHeaderSeparator.prototype, "column", void 0);
__decorate([
state()
], DataGridHeaderSeparator.prototype, "isResizing", void 0);
__decorate([
state()
], DataGridHeaderSeparator.prototype, "pointerInlineStart", void 0);
__decorate([
eventListener({ target: window, type: 'pointerup' })
], DataGridHeaderSeparator.prototype, "handlePointerUp", null);
__decorate([
eventListener({ target: window, type: 'pointermove', options: { passive: false } }),
eventListener({ target: window, type: 'touchmove', options: { passive: false } })
], DataGridHeaderSeparator.prototype, "handlePointerMove", null);
DataGridHeaderSeparator = __decorate([
component('mo-data-grid-header-separator')
], DataGridHeaderSeparator);
export { DataGridHeaderSeparator };