UNPKG

@3mo/data-grid

Version:
106 lines (105 loc) 4.62 kB
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); } } }