@revolist/revogrid
Version:
Virtual reactive data grid spreadsheet component - RevoGrid.
110 lines (109 loc) • 3.87 kB
JavaScript
/*!
* Built by Revolist OU ❤️
*/
/**
* Storing pre-calculated
* Dimension information and sizes
*/
import reduce from "lodash/reduce";
import { createStore } from "@stencil/store";
import { setStore } from "../../utils";
import { calculateDimensionData } from "./dimension.helpers";
import { recalculateRealSizePlugin } from "./dimension.recalculate.plugin";
import { trimmedPlugin } from "./dimension.trim.plugin";
function initialBase() {
return {
indexes: [],
count: 0,
// hidden items
trimmed: null,
// virtual item index to size
sizes: {},
// order in indexes[] to coordinate
positionIndexToItem: {},
// initial element to coordinate ^
indexToItem: {},
positionIndexes: [],
};
}
function initialState() {
return Object.assign(Object.assign({}, initialBase()), {
// size which all items can take
realSize: 0,
// initial item size if it wasn't changed
originItemSize: 0
});
}
export class DimensionStore {
constructor(type) {
this.type = type;
this.store = createStore(initialState());
this.store.use(trimmedPlugin({
store: this.store,
setSizes: this.setDimensionSize.bind(this),
}));
this.store.use(recalculateRealSizePlugin({
store: this.store,
setStore: this.setStore.bind(this),
}));
}
getCurrentState() {
const state = initialState();
const keys = Object.keys(state);
return reduce(keys, (r, k) => {
const data = this.store.get(k);
r[k] = data;
return r;
}, state);
}
dispose() {
setStore(this.store, initialState());
}
setStore(data) {
setStore(this.store, data);
}
drop() {
setStore(this.store, initialBase());
}
/**
* Set custom dimension sizes and overwrite old
* Generates new indexes based on sizes
* @param sizes - sizes to set
*/
setDimensionSize(sizes = {}) {
const dimensionData = calculateDimensionData(this.store.get('originItemSize'), sizes);
setStore(this.store, Object.assign(Object.assign({}, dimensionData), { sizes }));
}
updateSizesPositionByIndexes(newItemsOrder, prevItemsOrder = []) {
// Move custom sizes to new order
const customSizes = Object.assign({}, this.store.get('sizes'));
if (!Object.keys(customSizes).length) {
return;
}
// Step 1: Create a map of original indices, but allow duplicates by storing arrays of indices
const originalIndices = {};
prevItemsOrder.forEach((physIndex, virtIndex) => {
if (!originalIndices[physIndex]) {
originalIndices[physIndex] = [];
}
originalIndices[physIndex].push(virtIndex); // Store all indices for each value
});
// Step 2: Create new sizes based on new item order
const newSizes = {};
newItemsOrder.forEach((physIndex, virtIndex) => {
const indices = originalIndices[physIndex]; // Get all original indices for this value
if (indices && indices.length > 0) {
const originalIndex = indices.shift(); // Get the first available original index
if (originalIndex !== undefined && originalIndex !== virtIndex && customSizes[originalIndex]) {
newSizes[virtIndex] = customSizes[originalIndex];
delete customSizes[originalIndex];
}
}
});
// Step 3: Set new sizes if there are changes
if (Object.keys(newSizes).length) {
this.setDimensionSize(Object.assign(Object.assign({}, customSizes), newSizes));
}
}
}
//# sourceMappingURL=dimension.store.js.map