@revolist/revogrid
Version:
Virtual reactive data grid spreadsheet component - RevoGrid.
205 lines (201 loc) • 7.01 kB
JavaScript
/*!
* Built by Revolist OU ❤️
*/
import { proxyCustomElement, HTMLElement, createEvent } from '@stencil/core/internal/client';
import { d as debounce } from './debounce.js';
import { b as getSourceItem } from './data.store.js';
import { k as DRAGG_TEXT } from './consts.js';
import './platform.js';
import { g as getItemByPosition } from './dimension.helpers.js';
class RowOrderService {
constructor(config) {
this.config = config;
this.currentCell = null;
this.previousRow = null;
}
/** Drag finished, calculate and apply changes */
endOrder(e, data) {
if (this.currentCell === null) {
return;
}
const newRow = this.getCell(e, data);
// if position changed
if (newRow.y !== this.currentCell.y) {
// rgRow dragged out table
if (newRow.y < 0) {
newRow.y = 0;
}
// rgRow dragged to the top
else if (newRow.y < this.currentCell.y) {
newRow.y++;
}
this.config.positionChanged(this.currentCell.y, newRow.y);
}
this.clear();
}
/** Drag started, reserve initial cell for farther use */
startOrder(e, data) {
this.currentCell = this.getCell(e, data);
return this.currentCell;
}
move(y, data) {
const rgRow = this.getRow(y, data);
// if rgRow same as previous or below range (-1 = 0) do nothing
if (this.previousRow === rgRow.itemIndex || rgRow.itemIndex < -1) {
return null;
}
this.previousRow = rgRow.itemIndex;
return rgRow;
}
/** Drag stopped, probably cursor outside of document area */
clear() {
this.currentCell = null;
this.previousRow = null;
}
/** Calculate cell based on x, y position */
getRow(y, { el, rows }) {
const { top } = el.getBoundingClientRect();
const topRelative = y - top;
const rgRow = getItemByPosition(rows, topRelative);
const absolutePosition = {
itemIndex: rgRow.itemIndex,
start: rgRow.start + top,
end: rgRow.end + top,
};
return absolutePosition;
}
/** Calculate cell based on x, y position */
getCell({ x, y }, { el, rows, cols }) {
const { top, left } = el.getBoundingClientRect();
const topRelative = y - top;
const leftRelative = x - left;
const rgRow = getItemByPosition(rows, topRelative);
const rgCol = getItemByPosition(cols, leftRelative);
return { x: rgCol.itemIndex, y: rgRow.itemIndex };
}
}
const OrderEditor = /*@__PURE__*/ proxyCustomElement(class OrderEditor extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.rowDragStart = createEvent(this, "rowdragstartinit", 7);
this.rowDragEnd = createEvent(this, "rowdragendinit", 7);
this.rowDrag = createEvent(this, "rowdragmoveinit", 7);
this.rowMouseMove = createEvent(this, "rowdragmousemove", 7);
this.rowDropped = createEvent(this, "rowdropinit", 7);
this.rowOrderChange = createEvent(this, "roworderchange", 7);
this.events = [];
this.rowMoveFunc = debounce((y) => {
const rgRow = this.rowOrderService.move(y, this.getData());
if (rgRow !== null) {
this.rowDrag.emit(Object.assign(Object.assign({}, rgRow), { rowType: this.rowType }));
}
}, 5);
this.parent = undefined;
this.dimensionRow = undefined;
this.dimensionCol = undefined;
this.dataStore = undefined;
this.rowType = undefined;
}
// #endregion
// #region Methods
async dragStart(e) {
e.originalEvent.preventDefault();
// extra check if previous ended
if (this.events.length) {
this.clearOrder();
}
const data = this.getData();
const cell = this.rowOrderService.startOrder(e.originalEvent, data);
const pos = this.rowOrderService.getRow(e.originalEvent.y, data);
const dragStartEvent = this.rowDragStart.emit({
cell,
text: DRAGG_TEXT,
pos,
event: e.originalEvent,
rowType: this.rowType,
model: getSourceItem(this.dataStore, pos.itemIndex),
});
if (dragStartEvent.defaultPrevented) {
return;
}
const moveMove = (e) => this.move(e);
const mouseUp = (e) => this.endOrder(e);
const mouseLeave = () => this.clearOrder();
this.events.push({
name: 'mousemove',
listener: moveMove,
}, {
name: 'mouseup',
listener: mouseUp,
}, {
name: 'mouseleave',
listener: mouseLeave,
});
document.addEventListener('mousemove', moveMove);
// Action finished inside of the document
document.addEventListener('mouseup', mouseUp);
document.addEventListener('mouseleave', mouseLeave);
}
async endOrder(e) {
this.rowOrderService.endOrder(e, this.getData());
this.clearOrder();
}
async clearOrder() {
this.rowOrderService.clear();
this.events.forEach(v => document.removeEventListener(v.name, v.listener));
this.events.length = 0;
this.rowDragEnd.emit({ rowType: this.rowType });
}
// #endregion
move({ x, y }) {
this.rowMouseMove.emit({ x, y, rowType: this.rowType });
this.rowMoveFunc(y);
}
connectedCallback() {
this.rowOrderService = new RowOrderService({
positionChanged: (from, to) => {
const dropEvent = this.rowDropped.emit({
from,
to,
rowType: this.rowType,
});
if (dropEvent.defaultPrevented) {
return;
}
this.rowOrderChange.emit(dropEvent.detail);
},
});
}
getData() {
return {
el: this.parent,
rows: this.dimensionRow.state,
cols: this.dimensionCol.state,
};
}
}, [0, "revogr-order-editor", {
"parent": [16],
"dimensionRow": [16],
"dimensionCol": [16],
"dataStore": [16],
"rowType": [1, "row-type"],
"dragStart": [64],
"endOrder": [64],
"clearOrder": [64]
}]);
function defineCustomElement() {
if (typeof customElements === "undefined") {
return;
}
const components = ["revogr-order-editor"];
components.forEach(tagName => { switch (tagName) {
case "revogr-order-editor":
if (!customElements.get(tagName)) {
customElements.define(tagName, OrderEditor);
}
break;
} });
}
export { OrderEditor as O, defineCustomElement as d };
//# sourceMappingURL=revogr-order-editor2.js.map