@3mo/data-grid
Version:
A data grid web component
106 lines (105 loc) • 4.62 kB
JavaScript
import { KeyboardController } from '@3mo/keyboard-controller';
export var DataGridSelectability;
(function (DataGridSelectability) {
DataGridSelectability["Single"] = "single";
DataGridSelectability["Multiple"] = "multiple";
})(DataGridSelectability || (DataGridSelectability = {}));
export var DataGridSelectionBehaviorOnDataChange;
(function (DataGridSelectionBehaviorOnDataChange) {
/** Resets the selection of all data */
DataGridSelectionBehaviorOnDataChange["Reset"] = "reset";
/** Tries to find the previously selected data to maintain the selection */
DataGridSelectionBehaviorOnDataChange["Maintain"] = "maintain";
/** Prevents the selection from changing */
DataGridSelectionBehaviorOnDataChange["Prevent"] = "prevent";
})(DataGridSelectionBehaviorOnDataChange || (DataGridSelectionBehaviorOnDataChange = {}));
export class DataGridSelectionController {
constructor(host) {
this.host = host;
}
get selectability() {
if (this.host.hasContextMenu === true && this.host.selectability === undefined) {
this.host.selectability = DataGridSelectability.Single;
}
return this.host.selectability;
}
get hasSelection() {
return !!this.selectability;
}
get data() { return this.host.dataRecords.map(d => d.data); }
get selectableData() { return this.data.filter(d => this.isSelectable(d)); }
get selectedData() { return this.host.selectedData; }
set selectedData(data) { this.host.selectedData = data; }
get previouslySelectedData() {
const hasId = this.selectedData.every(d => typeof d === 'object' && d !== null && 'id' in d);
if (hasId) {
const selectedIds = this.selectedData.map((d) => d.id);
return this.data.filter((d) => selectedIds.includes(d.id));
}
else {
const selectedDataJson = this.selectedData.map(d => JSON.stringify(d));
return this.data.filter(d => selectedDataJson.includes(JSON.stringify(d)));
}
}
isSelectable(data) {
return this.host.isDataSelectable?.(data) ?? true;
}
isSelected(data) {
return this.selectedData.includes(data);
}
handleDataChange(behavior) {
switch (behavior) {
case DataGridSelectionBehaviorOnDataChange.Reset:
this.deselectAll();
break;
case DataGridSelectionBehaviorOnDataChange.Maintain:
this.selectPreviouslySelectedData();
break;
}
}
selectPreviouslySelectedData() {
this.select(this.previouslySelectedData);
}
setSelection(data, selected, preservePreviousSelections = false) {
if (!this.hasSelection || !this.isSelectable(data)) {
return;
}
const dataToSelect = [...new Set((() => {
switch (true) {
case this.selectability === DataGridSelectability.Multiple && KeyboardController.shift && !!this.lastActiveSelection:
const lastActiveSelection = this.lastActiveSelection;
const indexes = [
this.selectableData.findIndex(data => lastActiveSelection.data === data),
this.selectableData.findIndex(d => d === data)
].sort((a, b) => a - b);
const range = this.selectableData.slice(indexes[0], indexes[1] + 1);
return lastActiveSelection.selected
? [...this.selectedData, ...range]
: this.selectedData.filter(d => range.includes(d) === false);
case preservePreviousSelections && selected && this.selectability === DataGridSelectability.Multiple:
return [...this.selectedData, data];
case selected:
return [data];
default:
return this.selectedData.filter(d => d !== data);
}
})())];
this.lastActiveSelection = { data, selected };
this.select(dataToSelect);
}
selectAll() {
if (this.selectability === DataGridSelectability.Multiple) {
this.select([...this.data]);
}
}
deselectAll() {
this.select([]);
}
select(data) {
if (this.hasSelection) {
const selectableData = data.filter(d => this.isSelectable(d));
this.selectedData = selectableData;
this.host.selectionChange?.dispatch(selectableData);
}
}
}