@light-sheet/react
Version:
FortuneSheet is a drop-in javascript spreadsheet library that provides rich features like Excel and Google Sheets
233 lines (226 loc) • 12.1 kB
JavaScript
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import React, { useRef, useEffect, useContext, useCallback, useImperativeHandle } from "react";
import { Canvas, updateContextWithCanvas, updateContextWithSheetData, handleGlobalWheel, initFreeze } from "@light-sheet/core";
import "./index.css";
import WorkbookContext from "../../context";
import SheetOverlay from "../SheetOverlay";
import { useUIapi } from "../../hooks/useUIapi";
var Sheet = function Sheet(_ref) {
var _context$config, _context$config2, _context$config3;
var sheet = _ref.sheet,
refLayout = _ref.refLayout;
var UIAPIS = useUIapi();
var data = sheet.data;
// const canvasRef = useRef<HTMLCanvasElement>(null);
var containerRef = useRef(null);
var placeholderRef = useRef(null);
var _useContext = useContext(WorkbookContext),
context = _useContext.context,
setContext = _useContext.setContext,
refs = _useContext.refs,
settings = _useContext.settings;
/**
* Update data on window resize
*/
useEffect(function () {
function resize() {
if (!data) return;
setContext(function (draftCtx) {
if (settings.devicePixelRatio === 0) {
draftCtx.devicePixelRatio = (typeof globalThis !== "undefined" ? globalThis : window).devicePixelRatio;
}
updateContextWithSheetData(draftCtx, data);
updateContextWithCanvas(draftCtx, refs.canvas.current, placeholderRef.current);
});
}
window.addEventListener("resize", resize);
return function () {
window.removeEventListener("resize", resize);
};
}, [data, refs.canvas, setContext, settings.devicePixelRatio]);
/**
* Recalculate row/col info when data changes
*/
useEffect(function () {
if (!data) return;
setContext(function (draftCtx) {
updateContextWithSheetData(draftCtx, data);
});
}, [(_context$config = context.config) === null || _context$config === void 0 ? void 0 : _context$config.rowlen, (_context$config2 = context.config) === null || _context$config2 === void 0 ? void 0 : _context$config2.columnlen, (_context$config3 = context.config) === null || _context$config3 === void 0 ? void 0 : _context$config3.rowhidden, context.config.colhidden, context.rightPanelVisible, data, context.zoomRatio, setContext]);
/**
* Init canvas
*/
useEffect(function () {
setContext(function (draftCtx) {
return updateContextWithCanvas(draftCtx, refs.canvas.current, placeholderRef.current);
});
}, [refs.canvas, setContext, context.rowHeaderWidth, context.columnHeaderHeight, context.devicePixelRatio]);
/**
* Recalculate freeze data when sheet changes or sheet.frozen changes
* should be defined before redraw
*/
useEffect(function () {
initFreeze(context, refs.globalCache, context.currentSheetId);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [refs.globalCache, sheet.frozen, context.currentSheetId, context.visibledatacolumn, context.visibledatarow]);
/**
* Redraw canvas When context changes
* All context changes will trigger this
*/
useEffect(function () {
var _refs$globalCache$fre, _freeze$horizontal, _freeze$vertical;
// update formula chains value first if not empty
if (context.groupValuesRefreshData.length > 0) {
// wait for it to be refreshed
return;
}
var tableCanvas = new Canvas(refs.canvas.current, context);
if (tableCanvas == null) return;
var freeze = (_refs$globalCache$fre = refs.globalCache.freezen) === null || _refs$globalCache$fre === void 0 ? void 0 : _refs$globalCache$fre[sheet.id];
if (freeze !== null && freeze !== void 0 && (_freeze$horizontal = freeze.horizontal) !== null && _freeze$horizontal !== void 0 && _freeze$horizontal.freezenhorizontaldata || freeze !== null && freeze !== void 0 && (_freeze$vertical = freeze.vertical) !== null && _freeze$vertical !== void 0 && _freeze$vertical.freezenverticaldata) {
var _freeze$horizontal2, _freeze$vertical2;
// with frozen
var horizontalData = freeze === null || freeze === void 0 || (_freeze$horizontal2 = freeze.horizontal) === null || _freeze$horizontal2 === void 0 ? void 0 : _freeze$horizontal2.freezenhorizontaldata;
var verticallData = freeze === null || freeze === void 0 || (_freeze$vertical2 = freeze.vertical) === null || _freeze$vertical2 === void 0 ? void 0 : _freeze$vertical2.freezenverticaldata;
if (horizontalData && verticallData) {
var _horizontalData = _slicedToArray(horizontalData, 3),
horizontalPx = _horizontalData[0],
horizontalScrollTop = _horizontalData[2];
var _verticallData = _slicedToArray(verticallData, 3),
verticalPx = _verticallData[0],
verticalScrollWidth = _verticallData[2];
// main
tableCanvas.drawMain({
scrollWidth: context.scrollLeft + verticalPx - verticalScrollWidth,
scrollHeight: context.scrollTop + horizontalPx - horizontalScrollTop,
offsetLeft: verticalPx - verticalScrollWidth + context.rowHeaderWidth,
offsetTop: horizontalPx - horizontalScrollTop + context.columnHeaderHeight,
clear: true
});
// right top
tableCanvas.drawMain({
scrollWidth: context.scrollLeft + verticalPx - verticalScrollWidth,
scrollHeight: horizontalScrollTop,
drawHeight: horizontalPx,
offsetLeft: verticalPx - verticalScrollWidth + context.rowHeaderWidth
});
// left down
tableCanvas.drawMain({
scrollWidth: verticalScrollWidth,
scrollHeight: context.scrollTop + horizontalPx - horizontalScrollTop,
drawWidth: verticalPx,
offsetTop: horizontalPx - horizontalScrollTop + context.columnHeaderHeight
});
// left top
tableCanvas.drawMain({
scrollWidth: verticalScrollWidth,
scrollHeight: horizontalScrollTop,
drawWidth: verticalPx,
drawHeight: horizontalPx
});
// headers
tableCanvas.drawColumnHeader(context.scrollLeft + verticalPx - verticalScrollWidth, undefined, verticalPx - verticalScrollWidth + context.rowHeaderWidth);
tableCanvas.drawColumnHeader(verticalScrollWidth, verticalPx);
tableCanvas.drawRowHeader(context.scrollTop + horizontalPx - horizontalScrollTop, undefined, horizontalPx - horizontalScrollTop + context.columnHeaderHeight);
tableCanvas.drawRowHeader(horizontalScrollTop, horizontalPx);
tableCanvas.drawFreezeLine({
horizontalTop: horizontalPx - horizontalScrollTop + context.columnHeaderHeight - 2,
verticalLeft: verticalPx - verticalScrollWidth + context.rowHeaderWidth - 2
});
} else if (horizontalData) {
var _horizontalData2 = _slicedToArray(horizontalData, 3),
_horizontalPx = _horizontalData2[0],
_horizontalScrollTop = _horizontalData2[2];
// main
tableCanvas.drawMain({
scrollWidth: context.scrollLeft,
scrollHeight: context.scrollTop + _horizontalPx - _horizontalScrollTop,
offsetTop: _horizontalPx - _horizontalScrollTop + context.columnHeaderHeight,
clear: true
});
// top
tableCanvas.drawMain({
scrollWidth: context.scrollLeft,
scrollHeight: _horizontalScrollTop,
drawHeight: _horizontalPx
});
// headers
tableCanvas.drawColumnHeader(context.scrollLeft);
tableCanvas.drawRowHeader(context.scrollTop + _horizontalPx - _horizontalScrollTop, undefined, _horizontalPx - _horizontalScrollTop + context.columnHeaderHeight);
tableCanvas.drawRowHeader(_horizontalScrollTop, _horizontalPx);
tableCanvas.drawFreezeLine({
horizontalTop: _horizontalPx - _horizontalScrollTop + context.columnHeaderHeight - 2
});
} else if (verticallData) {
var _verticallData2 = _slicedToArray(verticallData, 3),
_verticalPx = _verticallData2[0],
_verticalScrollWidth = _verticallData2[2];
// main
tableCanvas.drawMain({
scrollWidth: context.scrollLeft + _verticalPx - _verticalScrollWidth,
scrollHeight: context.scrollTop,
offsetLeft: _verticalPx - _verticalScrollWidth + context.rowHeaderWidth
});
// left
tableCanvas.drawMain({
scrollWidth: _verticalScrollWidth,
scrollHeight: context.scrollTop,
drawWidth: _verticalPx
});
// headers
tableCanvas.drawRowHeader(context.scrollTop);
tableCanvas.drawColumnHeader(context.scrollLeft + _verticalPx - _verticalScrollWidth, undefined, _verticalPx - _verticalScrollWidth + context.rowHeaderWidth);
tableCanvas.drawColumnHeader(_verticalScrollWidth, _verticalPx);
tableCanvas.drawFreezeLine({
verticalLeft: _verticalPx - _verticalScrollWidth + context.rowHeaderWidth - 2
});
}
} else {
// without frozen
tableCanvas.drawMain({
scrollWidth: context.scrollLeft,
scrollHeight: context.scrollTop,
clear: true
});
tableCanvas.drawColumnHeader(context.scrollLeft);
tableCanvas.drawRowHeader(context.scrollTop);
}
}, [context, refs.canvas, refs.globalCache.freezen, setContext, sheet.id]);
var onWheel = useCallback(function (e) {
setContext(function (draftCtx) {
handleGlobalWheel(draftCtx, e, refs.globalCache, refs.scrollbarX.current, refs.scrollbarY.current);
});
e.preventDefault();
}, [refs.globalCache, refs.scrollbarX, refs.scrollbarY, setContext]);
/**
* Bind wheel event.
* Note: cannot use onWheel directly on the container because it behaves strange
*/
useEffect(function () {
var container = containerRef.current;
container === null || container === void 0 || container.addEventListener("wheel", onWheel);
return function () {
container === null || container === void 0 || container.removeEventListener("wheel", onWheel);
};
}, [onWheel]);
// expose APIs
useImperativeHandle(refLayout, function () {
return UIAPIS;
}, [UIAPIS]);
return /*#__PURE__*/React.createElement("div", {
ref: containerRef,
className: "fortune-sheet-container"
}, /*#__PURE__*/React.createElement("div", {
ref: placeholderRef,
className: "fortune-sheet-canvas-placeholder"
}), /*#__PURE__*/React.createElement("canvas", {
className: "fortune-sheet-canvas",
ref: refs.canvas
}), /*#__PURE__*/React.createElement(SheetOverlay, null));
};
export default Sheet;