@pixerate/editor-react 0.17.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/canvas/index.cjs +880 -193
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +214 -3
- package/dist/canvas/index.d.ts +214 -3
- package/dist/canvas/index.js +699 -0
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-JR5ZBDR7.js → chunk-34HEZX7J.js} +206 -74
- package/dist/chunk-34HEZX7J.js.map +1 -0
- package/dist/index.cjs +1437 -1109
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +104 -5
- package/dist/index.d.ts +104 -5
- package/dist/index.js +350 -146
- package/dist/index.js.map +1 -1
- package/dist/spreadsheet/index.cjs +261 -135
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +39 -3
- package/dist/spreadsheet/index.d.ts +39 -3
- package/dist/spreadsheet/index.js +5 -3
- package/package.json +2 -2
- package/dist/chunk-JR5ZBDR7.js.map +0 -1
|
@@ -41,7 +41,8 @@ __export(spreadsheet_exports, {
|
|
|
41
41
|
SpreadsheetValidationDialog: () => SpreadsheetValidationDialog,
|
|
42
42
|
useFillHandle: () => useFillHandle,
|
|
43
43
|
useSpreadsheetClipboard: () => useSpreadsheetClipboard,
|
|
44
|
-
useSpreadsheetEditor: () => useSpreadsheetEditor
|
|
44
|
+
useSpreadsheetEditor: () => useSpreadsheetEditor,
|
|
45
|
+
useSpreadsheetViewport: () => useSpreadsheetViewport
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(spreadsheet_exports);
|
|
47
48
|
|
|
@@ -282,8 +283,8 @@ function useSpreadsheetEditor(options = {}) {
|
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
// src/spreadsheet/SpreadsheetEditor.tsx
|
|
285
|
-
var
|
|
286
|
-
var
|
|
286
|
+
var import_react10 = require("react");
|
|
287
|
+
var import_spreadsheet8 = require("@pixerate/editor/spreadsheet");
|
|
287
288
|
|
|
288
289
|
// src/spreadsheet/SpreadsheetContextMenu.tsx
|
|
289
290
|
var import_react2 = __toESM(require("react"), 1);
|
|
@@ -362,6 +363,7 @@ var SpreadsheetContextMenu = ({ items, x, y, onClose, onOpenPanel, ariaLabel = "
|
|
|
362
363
|
};
|
|
363
364
|
|
|
364
365
|
// src/spreadsheet/SpreadsheetGroupRow.tsx
|
|
366
|
+
var import_react3 = __toESM(require("react"), 1);
|
|
365
367
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
366
368
|
var formatSummary = (value) => value === null ? "\u2013" : String(value);
|
|
367
369
|
var SpreadsheetGroupRow = ({
|
|
@@ -369,9 +371,14 @@ var SpreadsheetGroupRow = ({
|
|
|
369
371
|
columns,
|
|
370
372
|
groupColId,
|
|
371
373
|
onToggle,
|
|
372
|
-
trailingCell
|
|
374
|
+
trailingCell,
|
|
375
|
+
labelColumns = columns,
|
|
376
|
+
leadingColumns,
|
|
377
|
+
leftSpace = 0,
|
|
378
|
+
rightSpace = 0
|
|
373
379
|
}) => {
|
|
374
|
-
const labelColId =
|
|
380
|
+
const labelColId = labelColumns.some((c) => c.column.id === groupColId) ? groupColId : labelColumns[0]?.column.id;
|
|
381
|
+
const spacer = (key) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { "aria-hidden": "true", "data-spacer": "", style: { padding: 0 } }, key);
|
|
375
382
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { className: "border-b border-border bg-muted/40 font-semibold", "data-group-key": group.key, style: { height: 28 }, children: [
|
|
376
383
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "w-12 min-w-[3rem] sticky left-0 z-10 bg-muted border-r border-border text-center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
377
384
|
"button",
|
|
@@ -387,24 +394,30 @@ var SpreadsheetGroupRow = ({
|
|
|
387
394
|
children: group.collapsed ? "\u25B8" : "\u25BE"
|
|
388
395
|
}
|
|
389
396
|
) }),
|
|
390
|
-
columns.map(({ column }) => {
|
|
397
|
+
columns.map(({ column }, i) => {
|
|
391
398
|
const summary = group.summaries[column.id];
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
399
|
+
const before = leadingColumns !== void 0 && i === leadingColumns && leftSpace > 0 ? spacer("space:left") : null;
|
|
400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react3.default.Fragment, { children: [
|
|
401
|
+
before,
|
|
402
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "border-r border-border px-2 py-1 truncate max-w-0 text-foreground", style: { maxWidth: 0, overflow: "hidden" }, children: column.id === labelColId ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "truncate", children: [
|
|
403
|
+
group.label,
|
|
404
|
+
" ",
|
|
405
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "font-normal text-muted-foreground", children: [
|
|
406
|
+
"(",
|
|
407
|
+
group.rowIndices.length,
|
|
408
|
+
")"
|
|
409
|
+
] })
|
|
410
|
+
] }) : summary !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "truncate", "data-summary": column.id, children: formatSummary(summary) }) : null })
|
|
411
|
+
] }, column.id);
|
|
401
412
|
}),
|
|
413
|
+
leadingColumns !== void 0 && leadingColumns >= columns.length && leftSpace > 0 && spacer("space:left"),
|
|
414
|
+
rightSpace > 0 && spacer("space:right"),
|
|
402
415
|
trailingCell && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "w-10 min-w-[2.5rem] bg-muted/10 border-r border-border" })
|
|
403
416
|
] });
|
|
404
417
|
};
|
|
405
418
|
|
|
406
419
|
// src/spreadsheet/useSpreadsheetTableInteractions.ts
|
|
407
|
-
var
|
|
420
|
+
var import_react4 = require("react");
|
|
408
421
|
var import_spreadsheet3 = require("@pixerate/editor/spreadsheet");
|
|
409
422
|
function gridHasFocus(grid) {
|
|
410
423
|
if (!grid || typeof document === "undefined") return false;
|
|
@@ -413,12 +426,12 @@ function gridHasFocus(grid) {
|
|
|
413
426
|
return !(active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement);
|
|
414
427
|
}
|
|
415
428
|
function useSpreadsheetClipboard(gridRef, state, readOnly) {
|
|
416
|
-
const stateRef = (0,
|
|
429
|
+
const stateRef = (0, import_react4.useRef)(state);
|
|
417
430
|
stateRef.current = state;
|
|
418
|
-
const readOnlyRef = (0,
|
|
431
|
+
const readOnlyRef = (0, import_react4.useRef)(readOnly);
|
|
419
432
|
readOnlyRef.current = readOnly;
|
|
420
|
-
const copiedRef = (0,
|
|
421
|
-
(0,
|
|
433
|
+
const copiedRef = (0, import_react4.useRef)(false);
|
|
434
|
+
(0, import_react4.useEffect)(() => {
|
|
422
435
|
if (typeof document === "undefined") return;
|
|
423
436
|
const handleCopy = (e) => {
|
|
424
437
|
const s = stateRef.current;
|
|
@@ -441,7 +454,7 @@ function useSpreadsheetClipboard(gridRef, state, readOnly) {
|
|
|
441
454
|
document.removeEventListener("paste", handlePaste);
|
|
442
455
|
};
|
|
443
456
|
}, [gridRef]);
|
|
444
|
-
const copyShortcutFallback = (0,
|
|
457
|
+
const copyShortcutFallback = (0, import_react4.useCallback)(() => {
|
|
445
458
|
copiedRef.current = false;
|
|
446
459
|
setTimeout(() => {
|
|
447
460
|
if (copiedRef.current) return;
|
|
@@ -453,13 +466,13 @@ function useSpreadsheetClipboard(gridRef, state, readOnly) {
|
|
|
453
466
|
return { copyShortcutFallback };
|
|
454
467
|
}
|
|
455
468
|
function useFillHandle(state) {
|
|
456
|
-
const [drag, setDrag] = (0,
|
|
457
|
-
const dragRef = (0,
|
|
469
|
+
const [drag, setDrag] = (0, import_react4.useState)(null);
|
|
470
|
+
const dragRef = (0, import_react4.useRef)(drag);
|
|
458
471
|
dragRef.current = drag;
|
|
459
|
-
const stateRef = (0,
|
|
472
|
+
const stateRef = (0, import_react4.useRef)(state);
|
|
460
473
|
stateRef.current = state;
|
|
461
474
|
const dragging = drag !== null;
|
|
462
|
-
(0,
|
|
475
|
+
(0, import_react4.useEffect)(() => {
|
|
463
476
|
if (!dragging) return;
|
|
464
477
|
const handleMouseUp = () => {
|
|
465
478
|
const current = dragRef.current;
|
|
@@ -469,13 +482,13 @@ function useFillHandle(state) {
|
|
|
469
482
|
window.addEventListener("mouseup", handleMouseUp);
|
|
470
483
|
return () => window.removeEventListener("mouseup", handleMouseUp);
|
|
471
484
|
}, [dragging]);
|
|
472
|
-
const startFill = (0,
|
|
485
|
+
const startFill = (0, import_react4.useCallback)((e) => {
|
|
473
486
|
e.preventDefault();
|
|
474
487
|
e.stopPropagation();
|
|
475
488
|
const range = stateRef.current.selectedRange;
|
|
476
489
|
if (range) setDrag({ source: (0, import_spreadsheet3.normalizeRange)(range), target: null });
|
|
477
490
|
}, []);
|
|
478
|
-
const extendFill = (0,
|
|
491
|
+
const extendFill = (0, import_react4.useCallback)((row, col) => {
|
|
479
492
|
const current = dragRef.current;
|
|
480
493
|
if (!current) return;
|
|
481
494
|
setDrag({ source: current.source, target: (0, import_spreadsheet3.computeFillTarget)(current.source, { row, col }) });
|
|
@@ -484,12 +497,12 @@ function useFillHandle(state) {
|
|
|
484
497
|
}
|
|
485
498
|
|
|
486
499
|
// src/spreadsheet/SpreadsheetValidationDialog.tsx
|
|
487
|
-
var
|
|
500
|
+
var import_react5 = require("react");
|
|
488
501
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
489
502
|
var SpreadsheetValidationDialog = ({ prompt, onResolve }) => {
|
|
490
503
|
const style = prompt.result.errorStyle ?? "stop";
|
|
491
|
-
const firstButton = (0,
|
|
492
|
-
(0,
|
|
504
|
+
const firstButton = (0, import_react5.useRef)(null);
|
|
505
|
+
(0, import_react5.useEffect)(() => {
|
|
493
506
|
firstButton.current?.focus();
|
|
494
507
|
}, [prompt]);
|
|
495
508
|
const buttons = style === "stop" ? [
|
|
@@ -555,7 +568,7 @@ var SpreadsheetValidationDialog = ({ prompt, onResolve }) => {
|
|
|
555
568
|
};
|
|
556
569
|
|
|
557
570
|
// src/spreadsheet/SpreadsheetRulePanels.tsx
|
|
558
|
-
var
|
|
571
|
+
var import_react6 = require("react");
|
|
559
572
|
var import_spreadsheet4 = require("@pixerate/editor/spreadsheet");
|
|
560
573
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
561
574
|
var inputClass = "w-full rounded border border-border bg-background px-1.5 py-0.5 text-xs text-foreground";
|
|
@@ -609,18 +622,18 @@ function RuleSwatch({ rule }) {
|
|
|
609
622
|
}
|
|
610
623
|
var SpreadsheetConditionalFormatPanel = ({ state, onClose }) => {
|
|
611
624
|
const rules = state.document.table?.conditionalFormats ?? [];
|
|
612
|
-
const [kind, setKind] = (0,
|
|
613
|
-
const [appliesTo, setAppliesTo] = (0,
|
|
614
|
-
const [value, setValue] = (0,
|
|
615
|
-
const [value2, setValue2] = (0,
|
|
616
|
-
const [text, setText] = (0,
|
|
617
|
-
const [formula, setFormula] = (0,
|
|
618
|
-
const [rank, setRank] = (0,
|
|
619
|
-
const [period, setPeriod] = (0,
|
|
620
|
-
const [iconSet, setIconSet] = (0,
|
|
621
|
-
const [color, setColor] = (0,
|
|
622
|
-
const [styleId, setStyleId] = (0,
|
|
623
|
-
const preset = (0,
|
|
625
|
+
const [kind, setKind] = (0, import_react6.useState)("greaterThan");
|
|
626
|
+
const [appliesTo, setAppliesTo] = (0, import_react6.useState)(() => selectionText(state.selectedRange));
|
|
627
|
+
const [value, setValue] = (0, import_react6.useState)("");
|
|
628
|
+
const [value2, setValue2] = (0, import_react6.useState)("");
|
|
629
|
+
const [text, setText] = (0, import_react6.useState)("");
|
|
630
|
+
const [formula, setFormula] = (0, import_react6.useState)("=");
|
|
631
|
+
const [rank, setRank] = (0, import_react6.useState)("10");
|
|
632
|
+
const [period, setPeriod] = (0, import_react6.useState)("today");
|
|
633
|
+
const [iconSet, setIconSet] = (0, import_react6.useState)("3TrafficLights1");
|
|
634
|
+
const [color, setColor] = (0, import_react6.useState)("#638ec6");
|
|
635
|
+
const [styleId, setStyleId] = (0, import_react6.useState)(import_spreadsheet4.CONDITIONAL_FORMAT_STYLE_PRESETS[0].id);
|
|
636
|
+
const preset = (0, import_react6.useMemo)(() => import_spreadsheet4.CONDITIONAL_FORMAT_PRESETS.find((p) => p.kind === kind), [kind]);
|
|
624
637
|
const ranges = (0, import_spreadsheet4.parseRuleRanges)(appliesTo);
|
|
625
638
|
const add = () => {
|
|
626
639
|
if (!ranges) return;
|
|
@@ -704,15 +717,15 @@ var SpreadsheetConditionalFormatPanel = ({ state, onClose }) => {
|
|
|
704
717
|
};
|
|
705
718
|
var SpreadsheetDataValidationPanel = ({ state, onClose }) => {
|
|
706
719
|
const rules = state.document.table?.dataValidations ?? [];
|
|
707
|
-
const [type, setType] = (0,
|
|
708
|
-
const [operator, setOperator] = (0,
|
|
709
|
-
const [formula1, setFormula1] = (0,
|
|
710
|
-
const [formula2, setFormula2] = (0,
|
|
711
|
-
const [errorStyle, setErrorStyle] = (0,
|
|
712
|
-
const [errorMessage, setErrorMessage] = (0,
|
|
713
|
-
const [inputMessage, setInputMessage] = (0,
|
|
714
|
-
const [ignoreBlank, setIgnoreBlank] = (0,
|
|
715
|
-
const [appliesTo, setAppliesTo] = (0,
|
|
720
|
+
const [type, setType] = (0, import_react6.useState)("list");
|
|
721
|
+
const [operator, setOperator] = (0, import_react6.useState)("between");
|
|
722
|
+
const [formula1, setFormula1] = (0, import_react6.useState)("");
|
|
723
|
+
const [formula2, setFormula2] = (0, import_react6.useState)("");
|
|
724
|
+
const [errorStyle, setErrorStyle] = (0, import_react6.useState)("stop");
|
|
725
|
+
const [errorMessage, setErrorMessage] = (0, import_react6.useState)("");
|
|
726
|
+
const [inputMessage, setInputMessage] = (0, import_react6.useState)("");
|
|
727
|
+
const [ignoreBlank, setIgnoreBlank] = (0, import_react6.useState)(true);
|
|
728
|
+
const [appliesTo, setAppliesTo] = (0, import_react6.useState)(() => selectionText(state.selectedRange));
|
|
716
729
|
const ranges = (0, import_spreadsheet4.parseRuleRanges)(appliesTo);
|
|
717
730
|
const usesOperator = type === "whole" || type === "decimal" || type === "date" || type === "time" || type === "textLength";
|
|
718
731
|
const needsTwo = usesOperator && (operator === "between" || operator === "notBetween");
|
|
@@ -785,35 +798,99 @@ var SpreadsheetDataValidationPanel = ({ state, onClose }) => {
|
|
|
785
798
|
] });
|
|
786
799
|
};
|
|
787
800
|
|
|
788
|
-
// src/spreadsheet/
|
|
789
|
-
var
|
|
801
|
+
// src/spreadsheet/useSpreadsheetViewport.ts
|
|
802
|
+
var import_react7 = require("react");
|
|
790
803
|
var import_spreadsheet5 = require("@pixerate/editor/spreadsheet");
|
|
804
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react7.useLayoutEffect : import_react7.useEffect;
|
|
805
|
+
function useSpreadsheetViewport(scrollRef, view, options = {}) {
|
|
806
|
+
const metrics = (0, import_react7.useMemo)(() => (0, import_spreadsheet5.measureSpreadsheetView)(view), [view]);
|
|
807
|
+
const virtual = (0, import_spreadsheet5.shouldVirtualizeSpreadsheet)(view, options.virtualize ?? "auto");
|
|
808
|
+
const [viewport, setViewport] = (0, import_react7.useState)({ scrollTop: 0, scrollLeft: 0, width: 0, height: 0 });
|
|
809
|
+
const windowOptions = (0, import_react7.useMemo)(
|
|
810
|
+
() => ({ merges: options.merges, overscanRows: options.overscanRows, overscanColumns: options.overscanColumns }),
|
|
811
|
+
[options.merges, options.overscanRows, options.overscanColumns]
|
|
812
|
+
);
|
|
813
|
+
const win = (0, import_react7.useMemo)(
|
|
814
|
+
() => virtual ? (0, import_spreadsheet5.getSpreadsheetViewWindow)(metrics, viewport, windowOptions) : (0, import_spreadsheet5.fullSpreadsheetViewWindow)(metrics),
|
|
815
|
+
[virtual, metrics, viewport, windowOptions]
|
|
816
|
+
);
|
|
817
|
+
const latest = (0, import_react7.useRef)({ metrics, viewport, virtual, windowOptions });
|
|
818
|
+
latest.current = { metrics, viewport, virtual, windowOptions };
|
|
819
|
+
const readViewport = (0, import_react7.useCallback)(() => {
|
|
820
|
+
const el = scrollRef.current;
|
|
821
|
+
if (!el) return null;
|
|
822
|
+
return { scrollTop: el.scrollTop, scrollLeft: el.scrollLeft, width: el.clientWidth, height: el.clientHeight };
|
|
823
|
+
}, [scrollRef]);
|
|
824
|
+
const updateViewport = (0, import_react7.useCallback)((next) => {
|
|
825
|
+
setViewport((prev) => {
|
|
826
|
+
const { metrics: m, virtual: v, windowOptions: o } = latest.current;
|
|
827
|
+
if (!v) return prev;
|
|
828
|
+
const same = prev.width === next.width && prev.height === next.height && (0, import_spreadsheet5.sameSpreadsheetViewWindow)((0, import_spreadsheet5.getSpreadsheetViewWindow)(m, prev, o), (0, import_spreadsheet5.getSpreadsheetViewWindow)(m, next, o));
|
|
829
|
+
return same ? prev : next;
|
|
830
|
+
});
|
|
831
|
+
}, []);
|
|
832
|
+
const onScroll = (0, import_react7.useCallback)(() => {
|
|
833
|
+
const next = readViewport();
|
|
834
|
+
if (next) updateViewport(next);
|
|
835
|
+
}, [readViewport, updateViewport]);
|
|
836
|
+
useIsomorphicLayoutEffect(() => {
|
|
837
|
+
if (!virtual) return;
|
|
838
|
+
onScroll();
|
|
839
|
+
const el = scrollRef.current;
|
|
840
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
841
|
+
const observer = new ResizeObserver(() => onScroll());
|
|
842
|
+
observer.observe(el);
|
|
843
|
+
return () => observer.disconnect();
|
|
844
|
+
}, [virtual, onScroll, scrollRef]);
|
|
845
|
+
const activeRow = options.activeCell?.row;
|
|
846
|
+
const activeCol = options.activeCell?.col;
|
|
847
|
+
useIsomorphicLayoutEffect(() => {
|
|
848
|
+
if (!virtual || activeRow === void 0 || activeCol === void 0) return;
|
|
849
|
+
const el = scrollRef.current;
|
|
850
|
+
const current = latest.current.viewport;
|
|
851
|
+
const measured = readViewport();
|
|
852
|
+
const base = measured ? { ...measured, scrollTop: Math.max(measured.scrollTop, 0), scrollLeft: Math.max(measured.scrollLeft, 0) } : current;
|
|
853
|
+
const target = (0, import_spreadsheet5.getSpreadsheetScrollToCell)(latest.current.metrics, base, { row: activeRow, col: activeCol });
|
|
854
|
+
if (!target) return;
|
|
855
|
+
const next = { ...base, ...target };
|
|
856
|
+
if (el) {
|
|
857
|
+
if (target.scrollTop !== void 0) el.scrollTop = target.scrollTop;
|
|
858
|
+
if (target.scrollLeft !== void 0) el.scrollLeft = target.scrollLeft;
|
|
859
|
+
}
|
|
860
|
+
updateViewport(next);
|
|
861
|
+
}, [virtual, activeRow, activeCol]);
|
|
862
|
+
return { metrics, window: win, onScroll };
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// src/spreadsheet/FormulaHints.tsx
|
|
866
|
+
var import_react8 = require("react");
|
|
867
|
+
var import_spreadsheet6 = require("@pixerate/editor/spreadsheet");
|
|
791
868
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
792
869
|
var FormulaHints = ({ inputRef, value, onAccept, limit = 8, names }) => {
|
|
793
|
-
const [caret, setCaret] = (0,
|
|
794
|
-
const [focused, setFocused] = (0,
|
|
795
|
-
const [selected, setSelected] = (0,
|
|
796
|
-
const [dismissed, setDismissed] = (0,
|
|
797
|
-
const [position, setPosition] = (0,
|
|
798
|
-
const pendingCaret = (0,
|
|
799
|
-
const hints = (0,
|
|
800
|
-
() => (0,
|
|
870
|
+
const [caret, setCaret] = (0, import_react8.useState)(null);
|
|
871
|
+
const [focused, setFocused] = (0, import_react8.useState)(false);
|
|
872
|
+
const [selected, setSelected] = (0, import_react8.useState)(0);
|
|
873
|
+
const [dismissed, setDismissed] = (0, import_react8.useState)(false);
|
|
874
|
+
const [position, setPosition] = (0, import_react8.useState)(null);
|
|
875
|
+
const pendingCaret = (0, import_react8.useRef)(null);
|
|
876
|
+
const hints = (0, import_react8.useMemo)(
|
|
877
|
+
() => (0, import_spreadsheet6.getFormulaHints)(value, caret ?? value.length, { limit, names }),
|
|
801
878
|
[value, caret, limit, names]
|
|
802
879
|
);
|
|
803
880
|
const suggestions = dismissed ? [] : hints.suggestions;
|
|
804
881
|
const selectedIndex = Math.max(0, Math.min(selected, suggestions.length - 1));
|
|
805
882
|
const visible = focused && value.trimStart().startsWith("=") && (suggestions.length > 0 || !!hints.activeCall);
|
|
806
|
-
const latest = (0,
|
|
883
|
+
const latest = (0, import_react8.useRef)({ suggestions, selected: selectedIndex, value, caret, onAccept });
|
|
807
884
|
latest.current = { suggestions, selected: selectedIndex, value, caret, onAccept };
|
|
808
885
|
const accept = (index) => {
|
|
809
886
|
const { suggestions: list, value: current, caret: at, onAccept: commit } = latest.current;
|
|
810
887
|
const suggestion = list[index];
|
|
811
888
|
if (!suggestion) return;
|
|
812
|
-
const next = (0,
|
|
889
|
+
const next = (0, import_spreadsheet6.applyFormulaSuggestion)(current, at ?? current.length, suggestion);
|
|
813
890
|
pendingCaret.current = next.caret;
|
|
814
891
|
commit(next.value);
|
|
815
892
|
};
|
|
816
|
-
(0,
|
|
893
|
+
(0, import_react8.useEffect)(() => {
|
|
817
894
|
const input = inputRef.current;
|
|
818
895
|
if (!input) return;
|
|
819
896
|
const syncCaret = () => setCaret(input.selectionStart ?? input.value.length);
|
|
@@ -863,7 +940,7 @@ var FormulaHints = ({ inputRef, value, onAccept, limit = 8, names }) => {
|
|
|
863
940
|
input.removeEventListener("keydown", onKeyDown);
|
|
864
941
|
};
|
|
865
942
|
}, [inputRef]);
|
|
866
|
-
(0,
|
|
943
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
867
944
|
const input = inputRef.current;
|
|
868
945
|
const at = pendingCaret.current;
|
|
869
946
|
if (!input || at === null || input.value !== value) return;
|
|
@@ -872,7 +949,7 @@ var FormulaHints = ({ inputRef, value, onAccept, limit = 8, names }) => {
|
|
|
872
949
|
setCaret(at);
|
|
873
950
|
setSelected(0);
|
|
874
951
|
}, [value, inputRef]);
|
|
875
|
-
(0,
|
|
952
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
876
953
|
const input = inputRef.current;
|
|
877
954
|
if (!visible || !input) return;
|
|
878
955
|
const rect = input.getBoundingClientRect();
|
|
@@ -936,16 +1013,16 @@ var FormulaHints = ({ inputRef, value, onAccept, limit = 8, names }) => {
|
|
|
936
1013
|
};
|
|
937
1014
|
|
|
938
1015
|
// src/spreadsheet/SheetTabs.tsx
|
|
939
|
-
var
|
|
940
|
-
var
|
|
1016
|
+
var import_react9 = require("react");
|
|
1017
|
+
var import_spreadsheet7 = require("@pixerate/editor/spreadsheet");
|
|
941
1018
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
942
1019
|
var SheetTabs = ({ state, readOnly = false, className = "" }) => {
|
|
943
1020
|
const { controller, sheets } = state;
|
|
944
|
-
const [renaming, setRenaming] = (0,
|
|
945
|
-
const [error, setError] = (0,
|
|
946
|
-
const [menu, setMenu] = (0,
|
|
947
|
-
const dragFrom = (0,
|
|
948
|
-
const [dropTarget, setDropTarget] = (0,
|
|
1021
|
+
const [renaming, setRenaming] = (0, import_react9.useState)(null);
|
|
1022
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
1023
|
+
const [menu, setMenu] = (0, import_react9.useState)(null);
|
|
1024
|
+
const dragFrom = (0, import_react9.useRef)(null);
|
|
1025
|
+
const [dropTarget, setDropTarget] = (0, import_react9.useState)(null);
|
|
949
1026
|
const commitRename = (cancelOnError) => {
|
|
950
1027
|
if (!renaming) return;
|
|
951
1028
|
const sheet = sheets.find((s) => s.id === renaming.id);
|
|
@@ -1016,7 +1093,7 @@ var SheetTabs = ({ state, readOnly = false, className = "" }) => {
|
|
|
1016
1093
|
onContextMenu: (e) => {
|
|
1017
1094
|
if (readOnly) return;
|
|
1018
1095
|
e.preventDefault();
|
|
1019
|
-
setMenu({ x: e.clientX, y: e.clientY, items: (0,
|
|
1096
|
+
setMenu({ x: e.clientX, y: e.clientY, items: (0, import_spreadsheet7.getSheetTabMenuItems)(controller, sheet.id, { onError: setError }) });
|
|
1020
1097
|
},
|
|
1021
1098
|
onDragStart: (e) => {
|
|
1022
1099
|
dragFrom.current = index;
|
|
@@ -1036,7 +1113,7 @@ var SheetTabs = ({ state, readOnly = false, className = "" }) => {
|
|
|
1036
1113
|
dragFrom.current = null;
|
|
1037
1114
|
setDropTarget(null);
|
|
1038
1115
|
if (from === null) return;
|
|
1039
|
-
state.moveSheet(sheets[from].id, (0,
|
|
1116
|
+
state.moveSheet(sheets[from].id, (0, import_spreadsheet7.sheetDropIndex)(from, index, dropAfter(e)));
|
|
1040
1117
|
},
|
|
1041
1118
|
onDragEnd: () => {
|
|
1042
1119
|
dragFrom.current = null;
|
|
@@ -1092,7 +1169,7 @@ function frozenCellStyle(viewRow, viewCol) {
|
|
|
1092
1169
|
background: "var(--background, #fff)"
|
|
1093
1170
|
};
|
|
1094
1171
|
}
|
|
1095
|
-
var coordKey = (cell) => cell ? `${(0,
|
|
1172
|
+
var coordKey = (cell) => cell ? `${(0, import_spreadsheet8.indexToColName)(cell.col)}${cell.row + 1}` : "";
|
|
1096
1173
|
function spillBorderStyle(range, row, col) {
|
|
1097
1174
|
const line = "1px solid color-mix(in srgb, var(--primary, #6366f1) 60%, transparent)";
|
|
1098
1175
|
return {
|
|
@@ -1107,8 +1184,8 @@ function spillBorderStyle(range, row, col) {
|
|
|
1107
1184
|
};
|
|
1108
1185
|
}
|
|
1109
1186
|
function CellText({ cell, conditional }) {
|
|
1110
|
-
const shown = (0,
|
|
1111
|
-
const color = conditional?.color ?? (shown.color ? (0,
|
|
1187
|
+
const shown = (0, import_spreadsheet8.formatCellForDisplay)(cell);
|
|
1188
|
+
const color = conditional?.color ?? (shown.color ? (0, import_spreadsheet8.numberFormatColorToCss)(shown.color) : void 0);
|
|
1112
1189
|
const decorated = !!conditional?.dataBar || !!conditional?.icon;
|
|
1113
1190
|
const text = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1114
1191
|
"span",
|
|
@@ -1126,9 +1203,9 @@ function CellText({ cell, conditional }) {
|
|
|
1126
1203
|
}
|
|
1127
1204
|
);
|
|
1128
1205
|
if (!conditional || !decorated) return text;
|
|
1129
|
-
const icon = conditional.icon ? (0,
|
|
1206
|
+
const icon = conditional.icon ? (0, import_spreadsheet8.getConditionalFormatIcon)(conditional.icon.set, conditional.icon.index) : null;
|
|
1130
1207
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1131
|
-
conditional.dataBar && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", className: "spreadsheet-data-bar", style: (0,
|
|
1208
|
+
conditional.dataBar && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", className: "spreadsheet-data-bar", style: (0, import_spreadsheet8.getDataBarCss)(conditional.dataBar) }),
|
|
1132
1209
|
icon ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex items-center gap-1 min-w-0", style: { position: "relative" }, children: [
|
|
1133
1210
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "spreadsheet-cf-icon shrink-0", role: "img", "aria-label": icon.label, "data-icon": conditional.icon.id, style: { color: icon.color }, children: icon.glyph }),
|
|
1134
1211
|
text
|
|
@@ -1142,65 +1219,94 @@ var SpreadsheetEditor = ({
|
|
|
1142
1219
|
onAddColumnClick,
|
|
1143
1220
|
onColumnHeaderClick,
|
|
1144
1221
|
onColumnResize,
|
|
1145
|
-
showSheetTabs = false
|
|
1222
|
+
showSheetTabs = false,
|
|
1223
|
+
virtualize = "auto"
|
|
1146
1224
|
}) => {
|
|
1147
1225
|
const defaultState = useSpreadsheetEditor();
|
|
1148
1226
|
const state = externalState || defaultState;
|
|
1149
|
-
const gridRef = (0,
|
|
1150
|
-
const
|
|
1151
|
-
const
|
|
1152
|
-
const
|
|
1153
|
-
const [
|
|
1154
|
-
const [
|
|
1155
|
-
const [
|
|
1227
|
+
const gridRef = (0, import_react10.useRef)(null);
|
|
1228
|
+
const scrollRef = (0, import_react10.useRef)(null);
|
|
1229
|
+
const formulaBarRef = (0, import_react10.useRef)(null);
|
|
1230
|
+
const cellInputRef = (0, import_react10.useRef)(null);
|
|
1231
|
+
const [resizingColId, setResizingColId] = (0, import_react10.useState)(null);
|
|
1232
|
+
const [hoveredColId, setHoveredColId] = (0, import_react10.useState)(null);
|
|
1233
|
+
const [resizeStartX, setResizeStartX] = (0, import_react10.useState)(0);
|
|
1234
|
+
const [resizeStartWidth, setResizeStartWidth] = (0, import_react10.useState)(0);
|
|
1156
1235
|
const view = state.viewModel;
|
|
1236
|
+
const { window: viewWindow, onScroll: handleGridScroll } = useSpreadsheetViewport(scrollRef, view, {
|
|
1237
|
+
virtualize,
|
|
1238
|
+
merges: state.document.table?.merges,
|
|
1239
|
+
activeCell: state.activeCell
|
|
1240
|
+
});
|
|
1241
|
+
const columnSlots = (0, import_react10.useMemo)(() => {
|
|
1242
|
+
const col = (viewCol) => ({ kind: "col", viewCol });
|
|
1243
|
+
if (!viewWindow.virtual) return view.columns.map(col);
|
|
1244
|
+
const slots = view.columns.slice(0, viewWindow.frozenColumns).map(col);
|
|
1245
|
+
if (viewWindow.leftSpace > 0) slots.push({ kind: "space", key: "space:left", width: viewWindow.leftSpace });
|
|
1246
|
+
for (let i = viewWindow.colStart; i < viewWindow.colEnd; i++) slots.push(col(view.columns[i]));
|
|
1247
|
+
if (viewWindow.rightSpace > 0) slots.push({ kind: "space", key: "space:right", width: viewWindow.rightSpace });
|
|
1248
|
+
return slots;
|
|
1249
|
+
}, [view, viewWindow]);
|
|
1250
|
+
const renderedColumns = (0, import_react10.useMemo)(
|
|
1251
|
+
() => columnSlots.flatMap((slot) => slot.kind === "col" ? [slot.viewCol] : []),
|
|
1252
|
+
[columnSlots]
|
|
1253
|
+
);
|
|
1254
|
+
const rowSlots = (0, import_react10.useMemo)(() => {
|
|
1255
|
+
const row = (viewRow) => ({ kind: "row", viewRow });
|
|
1256
|
+
if (!viewWindow.virtual) return view.rows.map(row);
|
|
1257
|
+
const slots = view.rows.slice(0, viewWindow.frozenRows).map(row);
|
|
1258
|
+
if (viewWindow.topSpace > 0) slots.push({ kind: "space", key: "space:top", height: viewWindow.topSpace });
|
|
1259
|
+
for (let i = viewWindow.rowStart; i < viewWindow.rowEnd; i++) slots.push(row(view.rows[i]));
|
|
1260
|
+
if (viewWindow.bottomSpace > 0) slots.push({ kind: "space", key: "space:bottom", height: viewWindow.bottomSpace });
|
|
1261
|
+
return slots;
|
|
1262
|
+
}, [view, viewWindow]);
|
|
1157
1263
|
const { copyShortcutFallback } = useSpreadsheetClipboard(gridRef, state, readOnly);
|
|
1158
1264
|
const { fillTarget, startFill, extendFill } = useFillHandle(state);
|
|
1159
|
-
const [menu, setMenu] = (0,
|
|
1160
|
-
const [panel, setPanel] = (0,
|
|
1161
|
-
const [listMenu, setListMenu] = (0,
|
|
1265
|
+
const [menu, setMenu] = (0, import_react10.useState)(null);
|
|
1266
|
+
const [panel, setPanel] = (0, import_react10.useState)(null);
|
|
1267
|
+
const [listMenu, setListMenu] = (0, import_react10.useState)(null);
|
|
1162
1268
|
const overlay = state.conditionalFormatOverlay;
|
|
1163
1269
|
const filter = state.document.table?.filter;
|
|
1164
|
-
const filteredColIds = (0,
|
|
1270
|
+
const filteredColIds = (0, import_react10.useMemo)(
|
|
1165
1271
|
() => new Set(filter?.enabled ? filter.rules.map((r) => r.colId) : []),
|
|
1166
1272
|
[filter]
|
|
1167
1273
|
);
|
|
1168
|
-
const handleCellContextMenu = (0,
|
|
1274
|
+
const handleCellContextMenu = (0, import_react10.useCallback)((rIdx, cIdx, e) => {
|
|
1169
1275
|
if (readOnly) return;
|
|
1170
1276
|
e.preventDefault();
|
|
1171
1277
|
if (state.editingCell) state.commitEditing();
|
|
1172
|
-
if (!state.selectedRange || !(0,
|
|
1278
|
+
if (!state.selectedRange || !(0, import_spreadsheet8.rangeContains)(state.selectedRange, rIdx, cIdx)) {
|
|
1173
1279
|
state.selectCell(rIdx, cIdx);
|
|
1174
1280
|
}
|
|
1175
|
-
setMenu({ x: e.clientX, y: e.clientY, items: (0,
|
|
1281
|
+
setMenu({ x: e.clientX, y: e.clientY, items: (0, import_spreadsheet8.getSpreadsheetMenuItems)(state.controller, { row: rIdx, col: cIdx }) });
|
|
1176
1282
|
}, [readOnly, state]);
|
|
1177
|
-
const nameSuggestions = (0,
|
|
1283
|
+
const nameSuggestions = (0, import_react10.useMemo)(
|
|
1178
1284
|
() => state.controller.getNameSuggestions(),
|
|
1179
1285
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1180
1286
|
[state.controller, state.document]
|
|
1181
1287
|
);
|
|
1182
|
-
const activeRawValue = (0,
|
|
1288
|
+
const activeRawValue = (0, import_react10.useMemo)(() => {
|
|
1183
1289
|
if (!state.activeCell) return "";
|
|
1184
1290
|
const row = state.document.rows[state.activeCell.row];
|
|
1185
1291
|
const col = state.document.columns[state.activeCell.col];
|
|
1186
1292
|
if (!row || !col) return "";
|
|
1187
1293
|
return state.getCell(row.id, col.id).raw;
|
|
1188
1294
|
}, [state.activeCell, state.document]);
|
|
1189
|
-
const activeSpill = (0,
|
|
1295
|
+
const activeSpill = (0, import_react10.useMemo)(
|
|
1190
1296
|
() => state.activeCell ? state.controller.getSpillAt(state.activeCell.row, state.activeCell.col) : null,
|
|
1191
1297
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1192
1298
|
[state.controller, state.activeCell, state.document]
|
|
1193
1299
|
);
|
|
1194
1300
|
const spillFormula = activeSpill && !activeRawValue && activeSpill.key !== coordKey(state.activeCell) ? activeSpill.formula : "";
|
|
1195
|
-
const coordLabel = (0,
|
|
1301
|
+
const coordLabel = (0, import_react10.useMemo)(() => {
|
|
1196
1302
|
if (!state.activeCell) return "--";
|
|
1197
|
-
const colName = (0,
|
|
1303
|
+
const colName = (0, import_spreadsheet8.indexToColName)(state.activeCell.col);
|
|
1198
1304
|
return `${colName}${state.activeCell.row + 1}`;
|
|
1199
1305
|
}, [state.activeCell]);
|
|
1200
|
-
const [formulaDraft, setFormulaDraft] = (0,
|
|
1306
|
+
const [formulaDraft, setFormulaDraft] = (0, import_react10.useState)(null);
|
|
1201
1307
|
const activeColumn = state.activeCell ? state.document.columns[state.activeCell.col] : void 0;
|
|
1202
1308
|
const formulaBarReadOnly = readOnly || !state.activeCell || !!activeColumn?.readOnly;
|
|
1203
|
-
(0,
|
|
1309
|
+
(0, import_react10.useEffect)(() => {
|
|
1204
1310
|
setFormulaDraft(null);
|
|
1205
1311
|
}, [state.activeCell?.row, state.activeCell?.col]);
|
|
1206
1312
|
const commitFormulaBar = () => {
|
|
@@ -1216,19 +1322,19 @@ var SpreadsheetEditor = ({
|
|
|
1216
1322
|
}
|
|
1217
1323
|
setFormulaDraft(null);
|
|
1218
1324
|
};
|
|
1219
|
-
const handleCellClick = (0,
|
|
1325
|
+
const handleCellClick = (0, import_react10.useCallback)((rIdx, cIdx, e) => {
|
|
1220
1326
|
if (state.editingCell && (state.editingCell.row !== rIdx || state.editingCell.col !== cIdx)) {
|
|
1221
1327
|
state.commitEditing();
|
|
1222
1328
|
}
|
|
1223
1329
|
state.selectCell(rIdx, cIdx, e.shiftKey);
|
|
1224
1330
|
}, [state]);
|
|
1225
|
-
const handleCellDblClick = (0,
|
|
1331
|
+
const handleCellDblClick = (0, import_react10.useCallback)((rIdx, cIdx) => {
|
|
1226
1332
|
if (readOnly) return;
|
|
1227
1333
|
const col = state.document.columns[cIdx];
|
|
1228
1334
|
if (col?.readOnly) return;
|
|
1229
1335
|
state.startEditing(rIdx, cIdx);
|
|
1230
1336
|
}, [readOnly, state]);
|
|
1231
|
-
const handleKeyDown = (0,
|
|
1337
|
+
const handleKeyDown = (0, import_react10.useCallback)((e) => {
|
|
1232
1338
|
if (state.editingCell) {
|
|
1233
1339
|
if (e.key === "Enter") {
|
|
1234
1340
|
e.preventDefault();
|
|
@@ -1300,12 +1406,12 @@ var SpreadsheetEditor = ({
|
|
|
1300
1406
|
}
|
|
1301
1407
|
}
|
|
1302
1408
|
}, [readOnly, state, copyShortcutFallback]);
|
|
1303
|
-
const activeListValues = (0,
|
|
1409
|
+
const activeListValues = (0, import_react10.useMemo)(
|
|
1304
1410
|
() => state.activeCell && !readOnly ? state.controller.getValidationListValues(state.activeCell.row, state.activeCell.col) : null,
|
|
1305
1411
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1306
1412
|
[state.controller, state.activeCell, state.document, readOnly]
|
|
1307
1413
|
);
|
|
1308
|
-
const activeRule = (0,
|
|
1414
|
+
const activeRule = (0, import_react10.useMemo)(
|
|
1309
1415
|
() => state.activeCell ? state.controller.getDataValidationAt(state.activeCell.row, state.activeCell.col) : void 0,
|
|
1310
1416
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1311
1417
|
[state.controller, state.activeCell, state.document]
|
|
@@ -1319,7 +1425,7 @@ var SpreadsheetEditor = ({
|
|
|
1319
1425
|
const rect = td?.getBoundingClientRect();
|
|
1320
1426
|
setListMenu({ x: rect ? rect.left : 0, y: rect ? rect.bottom : 0, row, col, values });
|
|
1321
1427
|
}
|
|
1322
|
-
(0,
|
|
1428
|
+
(0, import_react10.useEffect)(() => {
|
|
1323
1429
|
if (!listMenu) return;
|
|
1324
1430
|
const close = (e) => {
|
|
1325
1431
|
if (!e.target?.closest?.('[aria-label="Allowed values"], .spreadsheet-list-arrow')) setListMenu(null);
|
|
@@ -1342,11 +1448,11 @@ var SpreadsheetEditor = ({
|
|
|
1342
1448
|
else gridRef.current?.focus();
|
|
1343
1449
|
});
|
|
1344
1450
|
};
|
|
1345
|
-
const stateRef = (0,
|
|
1451
|
+
const stateRef = (0, import_react10.useRef)(state);
|
|
1346
1452
|
stateRef.current = state;
|
|
1347
|
-
const onColumnResizeRef = (0,
|
|
1453
|
+
const onColumnResizeRef = (0, import_react10.useRef)(onColumnResize);
|
|
1348
1454
|
onColumnResizeRef.current = onColumnResize;
|
|
1349
|
-
(0,
|
|
1455
|
+
(0, import_react10.useEffect)(() => {
|
|
1350
1456
|
if (!resizingColId) return;
|
|
1351
1457
|
if (typeof document !== "undefined") {
|
|
1352
1458
|
document.body.style.cursor = "col-resize";
|
|
@@ -1397,7 +1503,7 @@ var SpreadsheetEditor = ({
|
|
|
1397
1503
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
1398
1504
|
};
|
|
1399
1505
|
}, [resizingColId, resizeStartX, resizeStartWidth]);
|
|
1400
|
-
const measureElementContentWidth = (0,
|
|
1506
|
+
const measureElementContentWidth = (0, import_react10.useCallback)((el, container) => {
|
|
1401
1507
|
if (typeof document === "undefined") return 0;
|
|
1402
1508
|
let maxW = el.scrollWidth || 0;
|
|
1403
1509
|
const firstChild = el.firstElementChild;
|
|
@@ -1445,7 +1551,7 @@ var SpreadsheetEditor = ({
|
|
|
1445
1551
|
}
|
|
1446
1552
|
return maxW;
|
|
1447
1553
|
}, []);
|
|
1448
|
-
const autoFitColumn = (0,
|
|
1554
|
+
const autoFitColumn = (0, import_react10.useCallback)((colId, colIndex) => {
|
|
1449
1555
|
const col = state.document.columns.find((c) => c.id === colId);
|
|
1450
1556
|
if (!col) return;
|
|
1451
1557
|
let calculatedWidth = 0;
|
|
@@ -1481,12 +1587,12 @@ var SpreadsheetEditor = ({
|
|
|
1481
1587
|
onColumnResize(updatedCol.id, updatedCol.width || 130);
|
|
1482
1588
|
}
|
|
1483
1589
|
}, [state, measureElementContentWidth, onColumnResize]);
|
|
1484
|
-
const handleResizeDblClick = (0,
|
|
1590
|
+
const handleResizeDblClick = (0, import_react10.useCallback)((colId, colIndex, e) => {
|
|
1485
1591
|
e.preventDefault();
|
|
1486
1592
|
e.stopPropagation();
|
|
1487
1593
|
autoFitColumn(colId, colIndex);
|
|
1488
1594
|
}, [autoFitColumn]);
|
|
1489
|
-
const handleHeaderDblClick = (0,
|
|
1595
|
+
const handleHeaderDblClick = (0, import_react10.useCallback)((colId, colIndex, e) => {
|
|
1490
1596
|
const target = e.currentTarget;
|
|
1491
1597
|
if (target) {
|
|
1492
1598
|
const rect = target.getBoundingClientRect();
|
|
@@ -1571,10 +1677,19 @@ var SpreadsheetEditor = ({
|
|
|
1571
1677
|
inputMessage.inputTitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mr-1 font-semibold text-foreground", children: inputMessage.inputTitle }),
|
|
1572
1678
|
inputMessage.inputMessage
|
|
1573
1679
|
] }),
|
|
1574
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative flex-1 overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { className: "border-
|
|
1680
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: scrollRef, className: "relative flex-1 overflow-auto", onScroll: handleGridScroll, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("table", { className: "border-separate border-spacing-0 table-fixed w-max min-w-full [&>*>tr:not([data-spacer])>*]:border-b [&>*>tr>*]:border-border", children: [
|
|
1575
1681
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("tr", { className: "h-7 bg-muted sticky top-0 z-20 border-b border-border shadow-xs", children: [
|
|
1576
1682
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("th", { className: "w-12 min-w-[3rem] sticky left-0 z-30 bg-muted border-r border-border text-center text-[10px] text-muted-foreground font-medium", children: "#" }),
|
|
1577
|
-
|
|
1683
|
+
columnSlots.map((slot) => slot.kind === "space" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1684
|
+
"th",
|
|
1685
|
+
{
|
|
1686
|
+
"aria-hidden": "true",
|
|
1687
|
+
"data-spacer": "",
|
|
1688
|
+
className: "p-0",
|
|
1689
|
+
style: { width: slot.width, minWidth: slot.width, maxWidth: slot.width, padding: 0 }
|
|
1690
|
+
},
|
|
1691
|
+
slot.key
|
|
1692
|
+
) : (({ column: col, index: cIdx, frozen, stickyLeft }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1578
1693
|
"th",
|
|
1579
1694
|
{
|
|
1580
1695
|
"data-col": cIdx,
|
|
@@ -1633,7 +1748,7 @@ var SpreadsheetEditor = ({
|
|
|
1633
1748
|
]
|
|
1634
1749
|
},
|
|
1635
1750
|
col.id
|
|
1636
|
-
)),
|
|
1751
|
+
))(slot.viewCol)),
|
|
1637
1752
|
onAddColumnClick && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1638
1753
|
"th",
|
|
1639
1754
|
{
|
|
@@ -1644,13 +1759,21 @@ var SpreadsheetEditor = ({
|
|
|
1644
1759
|
}
|
|
1645
1760
|
)
|
|
1646
1761
|
] }) }),
|
|
1647
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children:
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tbody", { children: rowSlots.map((rowSlot) => {
|
|
1763
|
+
if (rowSlot.kind === "space") {
|
|
1764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("tr", { "aria-hidden": "true", "data-spacer": "", style: { height: rowSlot.height }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { colSpan: columnSlots.length + 2, style: { padding: 0, border: 0 } }) }, rowSlot.key);
|
|
1765
|
+
}
|
|
1766
|
+
const viewRow = rowSlot.viewRow;
|
|
1648
1767
|
if (viewRow.kind === "group") {
|
|
1649
1768
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1650
1769
|
SpreadsheetGroupRow,
|
|
1651
1770
|
{
|
|
1652
1771
|
group: viewRow.group,
|
|
1653
|
-
columns:
|
|
1772
|
+
columns: renderedColumns,
|
|
1773
|
+
labelColumns: view.columns,
|
|
1774
|
+
leadingColumns: viewWindow.virtual ? viewWindow.frozenColumns : void 0,
|
|
1775
|
+
leftSpace: viewWindow.leftSpace,
|
|
1776
|
+
rightSpace: viewWindow.rightSpace,
|
|
1654
1777
|
groupColId: state.document.table?.grouping?.colId ?? "",
|
|
1655
1778
|
onToggle: state.toggleGroupCollapsed,
|
|
1656
1779
|
trailingCell: !!onAddColumnClick
|
|
@@ -1659,7 +1782,7 @@ var SpreadsheetEditor = ({
|
|
|
1659
1782
|
);
|
|
1660
1783
|
}
|
|
1661
1784
|
const displayRowIndex = viewRow.index;
|
|
1662
|
-
const selection = state.selectedRange ? (0,
|
|
1785
|
+
const selection = state.selectedRange ? (0, import_spreadsheet8.normalizeRange)(state.selectedRange) : null;
|
|
1663
1786
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1664
1787
|
"tr",
|
|
1665
1788
|
{
|
|
@@ -1675,7 +1798,9 @@ var SpreadsheetEditor = ({
|
|
|
1675
1798
|
children: displayRowIndex + 1
|
|
1676
1799
|
}
|
|
1677
1800
|
),
|
|
1678
|
-
|
|
1801
|
+
columnSlots.map((slot) => {
|
|
1802
|
+
if (slot.kind === "space") return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("td", { "aria-hidden": "true", "data-spacer": "", style: { padding: 0 } }, slot.key);
|
|
1803
|
+
const viewCol = slot.viewCol;
|
|
1679
1804
|
const span = view.getCellSpan(displayRowIndex, viewCol.index);
|
|
1680
1805
|
if (!span) return null;
|
|
1681
1806
|
const rIdx = span.source.row;
|
|
@@ -1687,11 +1812,11 @@ var SpreadsheetEditor = ({
|
|
|
1687
1812
|
const active = isActiveCell(rIdx, cIdx);
|
|
1688
1813
|
const isEditing = state.editingCell?.row === rIdx && state.editingCell?.col === cIdx;
|
|
1689
1814
|
const conditional = overlay.get(rIdx, cIdx);
|
|
1690
|
-
const conditionalCss = (0,
|
|
1815
|
+
const conditionalCss = (0, import_spreadsheet8.getConditionalFormatCss)(conditional);
|
|
1691
1816
|
const circled = state.controller.isInvalidDataCircled(rIdx, cIdx);
|
|
1692
1817
|
const showListArrow = active && !isEditing && !!activeListValues;
|
|
1693
|
-
const inFillPreview = !!fillTarget && !selected && (0,
|
|
1694
|
-
const showFillHandle = !readOnly && !isEditing && !!selection && (span.merge ? (0,
|
|
1818
|
+
const inFillPreview = !!fillTarget && !selected && (0, import_spreadsheet8.rangeContains)(fillTarget, displayRowIndex, viewCol.index);
|
|
1819
|
+
const showFillHandle = !readOnly && !isEditing && !!selection && (span.merge ? (0, import_spreadsheet8.rangeContains)(span.merge, selection.endRow, selection.endCol) : selection.endRow === rIdx && selection.endCol === cIdx);
|
|
1695
1820
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1696
1821
|
"td",
|
|
1697
1822
|
{
|
|
@@ -1760,7 +1885,7 @@ var SpreadsheetEditor = ({
|
|
|
1760
1885
|
children: "\u25BE"
|
|
1761
1886
|
}
|
|
1762
1887
|
),
|
|
1763
|
-
activeSpill && (0,
|
|
1888
|
+
activeSpill && (0, import_spreadsheet8.rangeContains)(activeSpill.range, rIdx, cIdx) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": "true", className: "spreadsheet-spill-border", style: spillBorderStyle(activeSpill.range, rIdx, cIdx) }),
|
|
1764
1889
|
showFillHandle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1765
1890
|
"div",
|
|
1766
1891
|
{
|
|
@@ -1858,19 +1983,19 @@ var SpreadsheetEditor = ({
|
|
|
1858
1983
|
};
|
|
1859
1984
|
|
|
1860
1985
|
// src/spreadsheet/NameManager.tsx
|
|
1861
|
-
var
|
|
1862
|
-
var
|
|
1986
|
+
var import_react11 = require("react");
|
|
1987
|
+
var import_spreadsheet9 = require("@pixerate/editor/spreadsheet");
|
|
1863
1988
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1864
1989
|
var EMPTY_DRAFT = { original: null, name: "", refersTo: "=", scope: "", comment: "" };
|
|
1865
1990
|
var NameManager = ({ state, readOnly = false, onClose, className = "" }) => {
|
|
1866
1991
|
const { controller, sheets } = state;
|
|
1867
|
-
const rows = (0,
|
|
1868
|
-
() => (0,
|
|
1992
|
+
const rows = (0, import_react11.useMemo)(
|
|
1993
|
+
() => (0, import_spreadsheet9.getNameManagerRows)(controller),
|
|
1869
1994
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1870
1995
|
[controller, state.document, state.names]
|
|
1871
1996
|
);
|
|
1872
|
-
const [draft, setDraft] = (0,
|
|
1873
|
-
const [error, setError] = (0,
|
|
1997
|
+
const [draft, setDraft] = (0, import_react11.useState)(EMPTY_DRAFT);
|
|
1998
|
+
const [error, setError] = (0, import_react11.useState)(null);
|
|
1874
1999
|
const edit = (row) => {
|
|
1875
2000
|
setError(null);
|
|
1876
2001
|
setDraft({
|
|
@@ -1888,7 +2013,7 @@ var NameManager = ({ state, readOnly = false, onClose, className = "" }) => {
|
|
|
1888
2013
|
const invalid = controller.validateDefinedName(draft.name.trim());
|
|
1889
2014
|
if (invalid) throw new Error(invalid);
|
|
1890
2015
|
try {
|
|
1891
|
-
(0,
|
|
2016
|
+
(0, import_spreadsheet9.parseFormula)(draft.refersTo.trim().startsWith("=") ? draft.refersTo.trim() : `=${draft.refersTo.trim()}`);
|
|
1892
2017
|
} catch (err) {
|
|
1893
2018
|
throw new Error(`There's a problem with this formula: ${err?.message ?? draft.refersTo}`);
|
|
1894
2019
|
}
|
|
@@ -2024,6 +2149,7 @@ var NameManager = ({ state, readOnly = false, onClose, className = "" }) => {
|
|
|
2024
2149
|
SpreadsheetValidationDialog,
|
|
2025
2150
|
useFillHandle,
|
|
2026
2151
|
useSpreadsheetClipboard,
|
|
2027
|
-
useSpreadsheetEditor
|
|
2152
|
+
useSpreadsheetEditor,
|
|
2153
|
+
useSpreadsheetViewport
|
|
2028
2154
|
});
|
|
2029
2155
|
//# sourceMappingURL=index.cjs.map
|