UNPKG

react-konva-grid

Version:

Declarative React Canvas Grid primitive for Data table, Pivot table, Excel Worksheets

164 lines 6.83 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = require("react"); const helpers_1 = require("./../helpers"); const types_1 = require("../types"); /** * Copy paste hook * Usage * * useCopyPaste ({ * onPaste: (text) => { * } * }) */ const useCopyPaste = ({ selections = [], activeCell = null, getValue, gridRef, onPaste, onCut, }) => { const selectionRef = react_1.useRef({ selections, activeCell, getValue }); const cutSelections = react_1.useRef(null); /* Keep selections and activeCell upto date */ react_1.useEffect(() => { selectionRef.current = { selections, activeCell, getValue }; }); const currentSelections = () => { const sel = selectionRef.current.selections.length ? selectionRef.current.selections : helpers_1.selectionFromActiveCell(selectionRef.current.activeCell); return sel[sel.length - 1]; }; react_1.useEffect(() => { if (!gridRef.current) return; document.addEventListener("copy", (e) => { var _a; if (((_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.container) !== document.activeElement) return; handleCopy(e); }); document.addEventListener("paste", (e) => { var _a; if (((_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.container) !== document.activeElement) return; handlePaste(e); }); document.addEventListener("cut", (e) => { var _a; if (((_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.container) !== document.activeElement) return; cutSelections.current = currentSelections(); handleCopy(e); }); }, []); const handleCopy = react_1.useCallback((e) => { var _a, _b, _c, _d, _e; /* Only copy the last selection */ const { bounds } = currentSelections(); const { top, left, right, bottom } = bounds; const rows = []; for (let i = top; i <= bottom; i++) { const row = []; for (let j = left; j <= right; j++) { const value = (_a = selectionRef.current.getValue({ rowIndex: i, columnIndex: j })) !== null && _a !== void 0 ? _a : ""; row.push(value); } rows.push(row); } const [html, csv] = helpers_1.prepareClipboardData(rows); (_b = e.clipboardData) === null || _b === void 0 ? void 0 : _b.setData(types_1.MimeType.html, html); (_c = e.clipboardData) === null || _c === void 0 ? void 0 : _c.setData(types_1.MimeType.plain, csv); (_d = e.clipboardData) === null || _d === void 0 ? void 0 : _d.setData(types_1.MimeType.csv, csv); (_e = e.clipboardData) === null || _e === void 0 ? void 0 : _e.setData(types_1.MimeType.json, JSON.stringify(rows)); e.preventDefault(); }, [currentSelections]); const handlePaste = (e) => { var _a, _b; const items = (_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.items; if (!items) return; const mimeTypes = [types_1.MimeType.html, types_1.MimeType.csv, types_1.MimeType.plain]; let type; let value; for (type of mimeTypes) { value = (_b = e.clipboardData) === null || _b === void 0 ? void 0 : _b.getData(type); if (value) break; } if (!type || !value) { console.warn("No clipboard data to paste"); return; } const rows = []; if (/^text\/html/.test(type)) { const domparser = new DOMParser(); const doc = domparser.parseFromString(value, type); const supportedNodes = "table, p, h1, h2, h3, h4, h5, h6"; const nodes = doc.querySelectorAll(supportedNodes); for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; if (node.nodeName === "TABLE") { const tableRows = doc.querySelectorAll("tr"); for (const tableRow of tableRows) { const row = []; const cells = tableRow.querySelectorAll("td"); for (const cell of cells) { row.push(cell.textContent); } rows.push(row); } } else { // Single nodes rows.push([node.textContent]); } } } else { const values = value.split("\n"); for (const val of values) { const row = []; for (const cell of val.split(",")) { row.push(cell.replace(/^\"|\"$/gi, "")); } rows.push(row); } } onPaste && onPaste(rows, selectionRef.current.activeCell); /* Clear all values in cut */ if (cutSelections.current) { onCut && onCut(cutSelections.current); cutSelections.current = null; } }; /** * User is trying to copy from outisde the app */ const handleProgramaticCopy = react_1.useCallback(() => { gridRef.current.focus(); document.execCommand("copy"); }, []); /** * User is trying to paste from outisde the app */ const handleProgramaticPaste = react_1.useCallback(() => __awaiter(void 0, void 0, void 0, function* () { gridRef.current.focus(); const text = yield navigator.clipboard.readText(); const clipboardData = new DataTransfer(); clipboardData.setData(types_1.MimeType.plain, text); const event = new ClipboardEvent("paste", { clipboardData }); handlePaste(event); }), []); return { copy: handleProgramaticCopy, paste: handleProgramaticPaste, }; }; exports.default = useCopyPaste; //# sourceMappingURL=useCopyPaste.js.map