@limetech/lime-elements
Version:
112 lines (111 loc) • 3.78 kB
JavaScript
/**
* Contains a set of selected data objects with methods for adding and removing
* items to the selection by referring to them by their index/position.
* Maintains a memory of the last toggled item which can be used to select or
* deselect a range of items between the last toggled item and a given item.
*/
export class Selection {
/**
* Creates an instance of the Selection class.
* The provided function `getDataByIndex` is used to provide data for the
* selected items when selection is toggled by using the item index,
* which can be the row position in a table.
*
* @param getDataByIndex - A function that returns the data at the given index
*/
constructor(getDataByIndex) {
this.getDataByIndex = getDataByIndex;
this.toggleRange = (fromIndex, toIndex) => {
const select = !this.selectedItems.has(this.getDataByIndex(toIndex));
const lowerBound = Math.min(fromIndex, toIndex);
const upperBound = Math.max(fromIndex, toIndex);
const updatedIndexes = [];
const updatedItems = [];
for (let index = lowerBound; index <= upperBound; index++) {
const data = this.getDataByIndex(index);
if (!data) {
continue;
}
const isSelected = this.selectedItems.has(data);
if (isSelected === select) {
continue;
}
if (select) {
this.selectedItems.add(data);
}
else {
this.selectedItems.delete(data);
}
updatedIndexes.push(index);
updatedItems.push(data);
}
this.lastToggledIndex = toIndex;
return {
selected: select,
items: updatedItems,
indexes: updatedIndexes,
};
};
this.clear();
}
/**
* @returns The size of the selection
*/
get size() {
return this.selectedItems.size;
}
/**
* @returns The selected items
*/
get items() {
return [...this.selectedItems];
}
/**
* @param items - The selected items
*/
set items(items) {
this.selectedItems = new Set(items);
this.lastToggledIndex = -1;
}
/**
* Checks whether the given item exist in the selection
*
* @param data - The data to look up
* @returns `true` if the given data exist in the selection, otherwise `false`
*/
has(data) {
return this.selectedItems.has(data);
}
/**
* Toggles the item at the given index in the selection
*
* @param index - The index of the item to toggle
* @returns The changes made to the selection
*/
toggleSelection(index) {
return this.toggleRange(index, index);
}
/**
* Toggles the items from the last toggled index to the given index in the selection.
* The toggled items will be toggled as the item at the given index no matter
* their current state in the selection.
* Initially, when no last toggled index exist, this function behaves like
* `toggleSelection`.
*
* @param index - The index of the item to toggle
* @returns The changes made to the selection
*/
toggleSelectionFromLastIndex(index) {
if (this.lastToggledIndex < 0) {
return this.toggleSelection(index);
}
return this.toggleRange(this.lastToggledIndex, index);
}
/**
* Clears the current selection and resets last toggled index
*/
clear() {
this.selectedItems = new Set();
this.lastToggledIndex = -1;
}
}