@progress/kendo-react-spreadsheet
Version:
KendoReact Spreadsheet package
241 lines (240 loc) • 9.94 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as t from "react";
import l from "prop-types";
import { ToolbarSeparator as $, Toolbar as ee, ButtonGroup as te, Button as re } from "@progress/kendo-react-buttons";
import { TabStrip as ne, TabStripTab as oe } from "@progress/kendo-react-layout";
import { Dialog as ae, DialogActionsBar as le } from "@progress/kendo-react-dialogs";
import { FormulaInput as H } from "./FormulaInput.mjs";
import { NameBox as se } from "./NameBox.mjs";
import { SheetsBar as ce } from "./SheetsBar.mjs";
import { SpreadsheetWidget as ie } from "@progress/kendo-spreadsheet-common";
import { defaultTabs as L } from "./tools/defaultTools.mjs";
import { validatePackage as ue, getLicenseMessage as me, classNames as de, IconWrap as fe, WatermarkOverlay as pe } from "@progress/kendo-react-common";
import { packageMetadata as T } from "./package-metadata.mjs";
import { formulaFxIcon as ge } from "@progress/kendo-svg-icons";
import { useLocalization as z, useInternationalization as ke } from "@progress/kendo-react-intl";
import { saveAs as be } from "@progress/kendo-file-saver";
import { Workbook as he } from "@progress/kendo-ooxml";
import { keys as m, messages as g } from "./messages.mjs";
const B = [
"bold",
"italic",
"underline",
"fontFamily",
"fontSize",
"color",
"background",
"textAlign",
"verticalAlign",
"wrap",
"gridLines"
], O = {
Bold: (r) => r.bold,
Italic: (r) => r.italic,
Underline: (r) => r.underline,
FontFamily: (r) => r.fontFamily,
FontSize: (r) => r.fontSize,
IncreaseFontSize: (r) => r.fontSize,
DecreaseFontSize: (r) => r.fontSize,
TextColor: (r) => r.color,
BackgroundColor: (r) => r.background,
Alignment: (r) => ({ textAlign: r.textAlign, verticalAlign: r.verticalAlign }),
AlignHorizontally: (r) => r.textAlign,
AlignVertically: (r) => r.verticalAlign,
TextWrap: (r) => r.wrap,
GridLines: (r) => r.gridLines,
AddColumnLeft: (r) => r.selectedHeaders,
AddColumnRight: (r) => r.selectedHeaders,
AddRowBelow: (r) => r.selectedHeaders,
AddRowAbove: (r) => r.selectedHeaders,
DeleteColumn: (r) => r.selectedHeaders,
DeleteRow: (r) => r.selectedHeaders
}, J = ":not(.k-dropdownlist button):not(.k-combobox button):not(.k-upload-button):not(.k-colorpicker button):not(.k-split-button .k-split-button-arrow)", Se = [
"button" + J,
".k-button-group > button" + J,
".k-dropdownlist",
".k-combobox",
".k-colorpicker"
], W = t.forwardRef((r, K) => {
const M = !ue(T, { component: "Spreadsheet" }), P = me(T), { toolbar: b = L } = r, d = [];
typeof b == "boolean" ? d.push(...b ? L : []) : d.push(...b);
const [c, v] = t.useState(null), [D, G] = t.useState(d.findIndex((e) => e.selected) || 0), [Ee, U] = t.useState(!1), h = t.useRef(null), x = t.useRef(null), y = t.useRef(null), C = t.useRef(null), a = t.useRef(null), [S, V] = t.useState({}), k = t.useRef({});
k.current = S;
const s = t.useRef({});
s.current = r;
const E = z(), j = t.useCallback((e) => {
s.current.onSelect && s.current.onSelect.call(void 0, e);
}, []), _ = t.useCallback((e) => {
s.current.onChange && s.current.onChange.call(void 0, e);
}, []), q = t.useCallback((e) => {
s.current.onChangeFormat && s.current.onChangeFormat.call(void 0, e);
}, []), Q = t.useCallback((e) => {
s.current.onExcelImport && s.current.onExcelImport.call(void 0, e);
}, []), X = t.useCallback((e) => {
s.current.onExcelExport && s.current.onExcelExport.call(void 0, e);
}, []), w = t.useRef(null);
t.useImperativeHandle(
w,
() => ({
element: h.current,
get instance() {
return a.current;
},
props: r,
get view() {
return a.current.view;
},
get workbook() {
return a.current.workbook;
},
executeCommand(e) {
var n;
(n = a.current) == null || n.executeCommand(e);
},
fromJSON(e) {
var n;
return (n = a.current) == null ? void 0 : n.fromJSON(e);
},
toJSON() {
return a.current.toJSON();
},
saveJSON() {
return a.current.saveJSON();
},
fromFile(e) {
return a.current.fromFile(e);
},
saveAsExcel(e) {
var n;
(n = a.current) == null || n.saveAsExcel({
...a.current.options.excel,
saveAs: be,
Workbook: he,
...e
});
},
activeSheet(e) {
var n;
return (n = a.current) == null ? void 0 : n.activeSheet(e);
},
sheets() {
return a.current.sheets();
},
refresh() {
var e;
return (e = a.current) == null ? void 0 : e.refresh();
}
}),
[r]
), t.useImperativeHandle(K, () => w.current);
const Y = t.useCallback(() => a.current && a.current.view.nameEditor, []), N = t.useCallback((e) => {
const n = {};
B.forEach((o) => {
typeof e.range[o] == "function" ? n[o] = e.range[o]() : o === "gridLines" && (n[o] = e.range.sheet().showGridLines());
}), n.selectedHeaders = e.range.sheet().selectedHeaders(), (B.some((o) => n[o] !== k.current[o]) || n.selectedHeaders.allCols !== k.current.selectedHeaders.allCols || n.selectedHeaders.allRows !== k.current.selectedHeaders.allRows) && V(n);
}, []), Z = t.useCallback((e) => {
const n = e.name, o = m[n];
v({
title: e.title === "Error" ? E.toLanguageString(m.error, g[m.error]) : e.title,
message: o ? E.toLanguageString(o, g[o] || e.text) : e.text,
close: e.close
});
}, []), R = t.useCallback(() => {
v(null), c == null || c.close();
}, [c]), f = ke(), A = z();
t.useEffect(() => {
var p;
const e = {
...r.defaultProps,
sheets: window == null ? void 0 : window.structuredClone((p = r.defaultProps) == null ? void 0 : p.sheets),
messages: {
workbook: {
defaultSheetName: A.toLanguageString(
m.defaultSheetName,
g[m.defaultSheetName]
)
}
},
intl: {
localeInfo: () => f.localeInfo(),
localeCurrency: () => f.localeCurrency(),
parseDate: (i, u) => f.parseDate(i, u),
toString: (i, u) => f.toString(i, u),
format: (i, ...u) => f.format(i, ...u)
},
formulaBarInputRef: x,
formulaCellInputRef: y,
nameBoxRef: C
}, n = new ie(h.current, e);
a.current = n, n.bind("select", j), n.bind("change", _), n.bind("changeFormat", q), n.bind("excelImport", Q), n.bind("excelExport", X), n.view.bind("update", N), n.view.bind("message", Z);
const o = n.activeSheet();
return o && N({ range: o.range(o.activeCell()) }), U(!0), () => {
n.destroy();
};
}, []);
const I = t.useCallback(
(e, n) => {
const o = /* @__PURE__ */ t.createElement(
e,
{
spreadsheetRef: a,
value: O[e.displayName] ? O[e.displayName](S) : void 0,
key: n
}
);
return o.type === $ ? /* @__PURE__ */ t.createElement(e, { key: n }) : o;
},
[S]
);
let F = null;
return d.length && (F = /* @__PURE__ */ t.createElement(
ne,
{
selected: D,
animation: !1,
className: "k-floatwrap k-spreadsheet-tabstrip",
style: { minHeight: "auto" },
onSelect: (e) => G(e.selected)
},
d.map((e) => {
const n = e.textKey ? A.toLanguageString(e.textKey, g[e.textKey]) : e.text;
return /* @__PURE__ */ t.createElement(oe, { key: e.textKey || e.text, title: n }, /* @__PURE__ */ t.createElement(ee, { buttons: Se, className: "k-spreadsheet-toolbar" }, e.tools.map((o, p) => Array.isArray(o) ? /* @__PURE__ */ t.createElement(te, { key: p }, o.map((i, u) => I(i, u))) : I(o, p))));
})
)), /* @__PURE__ */ t.createElement(
"div",
{
ref: h,
style: r.style,
className: de("k-widget k-spreadsheet", r.className),
role: "application"
},
F,
/* @__PURE__ */ t.createElement("div", { className: "k-spreadsheet-action-bar" }, /* @__PURE__ */ t.createElement(se, { ref: C, nameEditor: Y }), /* @__PURE__ */ t.createElement("div", { className: "k-spreadsheet-formula-bar" }, /* @__PURE__ */ t.createElement(fe, { name: "formula-fx", icon: ge }), /* @__PURE__ */ t.createElement(H, { ref: x }))),
/* @__PURE__ */ t.createElement("div", { className: "k-spreadsheet-view" }, /* @__PURE__ */ t.createElement("div", { className: "k-spreadsheet-fixed-container" }), /* @__PURE__ */ t.createElement("div", { className: "k-spreadsheet-scroller" }, /* @__PURE__ */ t.createElement("div", { className: "k-spreadsheet-view-size" })), /* @__PURE__ */ t.createElement("div", { tabIndex: 0, className: "k-spreadsheet-clipboard", contentEditable: "true" }), /* @__PURE__ */ t.createElement(H, { ref: y, className: "k-spreadsheet-cell-editor" })),
/* @__PURE__ */ t.createElement(ce, { spreadsheetRef: a }),
c && /* @__PURE__ */ t.createElement(ae, { title: c.title, onClose: R }, /* @__PURE__ */ t.createElement("div", null, c.message), /* @__PURE__ */ t.createElement(le, { layout: "start" }, /* @__PURE__ */ t.createElement(re, { themeColor: "primary", onClick: R, autoFocus: !0 }, E.toLanguageString(m.ok, g[m.ok])))),
M && /* @__PURE__ */ t.createElement(pe, { message: P })
);
});
W.displayName = "KendoReactSpreadsheet";
W.propTypes = {
className: l.string,
defaultProps: l.any,
toolbar: l.oneOfType([l.bool, l.arrayOf(l.any)]),
style: l.object,
onSelect: l.func,
onChange: l.func,
onChangeFormat: l.func,
onExcelImport: l.func,
onExcelExport: l.func
};
export {
W as Spreadsheet,
O as toolsValueMap
};