@3mo/data-grid
Version:
A data grid web component
102 lines (101 loc) • 3.82 kB
JavaScript
import { html, style } from '@a11d/lit';
import { equals } from '@a11d/equals';
export class DataGridColumn {
hide() {
this.hidden = true;
this.dataGrid.requestUpdate();
}
toggleSticky(sticky) {
this.sticky = this.sticky === sticky ? undefined : sticky;
this.dataGrid.requestUpdate();
}
get sortDataSelector() { return this._sortDataSelector || this.dataSelector; }
set sortDataSelector(value) { this._sortDataSelector = value; }
toggleSort(strategy) {
if (!this.sortable) {
return;
}
if (!!strategy && this.sortingDefinition?.strategy === strategy) {
strategy = null;
}
if (strategy === null) {
this.dataGrid.sortingController.reset();
}
else {
this.dataGrid.sortingController.toggle(this.sortDataSelector, strategy);
}
this.dataGrid.requestUpdate();
}
constructor(column) {
this.width = 'max-content';
this.alignment = 'start';
this.hidden = false;
this.sortable = true;
this.editable = false;
this._intersecting = false;
Object.assign(this, column);
}
[equals](other) {
return !!this.dataSelector || !!other.dataSelector
? this.dataSelector === other.dataSelector
: this.heading === other.heading && this.description === other.description;
}
with(other) {
return new DataGridColumn({ ...this, ...other });
}
get widthInPixels() { return this._widthInPixels || 0; }
set widthInPixels(value) {
this._widthInPixels = value;
this.dataGrid?.requestUpdate();
}
get intersecting() { return this._intersecting; }
set intersecting(value) {
this._intersecting = value;
this.dataGrid?.requestUpdate();
}
get sortingDefinition() {
return this.dataGrid
?.getSorting()
.find(s => s.selector === this.sortDataSelector);
}
get sumTemplate() {
if (!this.dataGrid || this.sumHeading === undefined || this.getSumTemplate === undefined) {
return;
}
const sumsData = this.dataGrid.selectedData.length ? this.dataGrid.selectedData : this.dataGrid.renderDataRecords.map(r => r.data);
const sum = sumsData
.map(data => parseFloat(KeyPath.get(data, this.dataSelector)))
.filter(n => isNaN(n) === false)
.reduce(((a, b) => a + b), 0)
|| 0;
return html `
<mo-data-grid-footer-sum heading=${this.sumHeading || ''} ${style({ color: this.dataGrid.selectedData.length > 0 ? 'var(--mo-color-accent)' : 'currentColor' })}>
${this.getSumTemplate(sum)}
</mo-data-grid-footer-sum>
`;
}
get stickyColumnInsetInline() {
const dataGrid = this.dataGrid;
if (!dataGrid) {
return '';
}
const columnIndex = dataGrid.visibleColumns.indexOf(this);
const calculate = (type) => dataGrid.visibleColumns
.filter((c, i) => c.sticky === type && (type === 'start' ? i < columnIndex : i > columnIndex))
.map(c => c.widthInPixels)
.filter(x => x !== undefined)
.reduce((a, b) => a + b, 0);
const start = `${dataGrid.columnsController.selectionColumnWidthInPixels + dataGrid.columnsController.detailsColumnWidthInPixels + calculate('start')}px`;
const end = `${calculate('end') + dataGrid.columnsController.actionsColumnWidthInPixels}px`;
switch (this.sticky) {
case 'start':
return `${start} auto`;
case 'end':
return `auto ${end}`;
case 'both':
return `${start} ${end}`;
default:
return '';
}
}
}