@ricsam/react-spreadsheets 0.0.14 → 0.0.15
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 +6 -1
- package/dist/cjs/lib.cjs +497 -310
- package/dist/cjs/lib.cjs.map +6 -5
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/lib.mjs +488 -301
- package/dist/mjs/lib.mjs.map +6 -5
- package/dist/mjs/package.json +1 -1
- package/dist/styles.css +201 -32
- package/dist/types/spreadsheet/spreadsheet.d.ts +3 -0
- package/dist/types/workbook/sheet-navigation.d.ts +15 -0
- package/package.json +2 -2
package/dist/cjs/lib.cjs
CHANGED
|
@@ -1893,6 +1893,7 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
1893
1893
|
"aria-describedby": ariaDescribedBy,
|
|
1894
1894
|
cellData: controlledCellData,
|
|
1895
1895
|
onCellDataChange,
|
|
1896
|
+
onCellDataPatch,
|
|
1896
1897
|
onCellDataChangeError,
|
|
1897
1898
|
rowCount,
|
|
1898
1899
|
columnCount,
|
|
@@ -2097,6 +2098,7 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
2097
2098
|
}, [overlayPlaceholder, containerDivRef, viewport, gridDims, placeholderPos]);
|
|
2098
2099
|
const effectsRefOb = {
|
|
2099
2100
|
onCellDataChange,
|
|
2101
|
+
onCellDataPatch,
|
|
2100
2102
|
onCellDataChangeError,
|
|
2101
2103
|
controlledCellData,
|
|
2102
2104
|
parseValue,
|
|
@@ -2343,13 +2345,13 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
2343
2345
|
return selectionManager.listenToUpdateData((updates) => {
|
|
2344
2346
|
const editingState = selectionManager.isEditing;
|
|
2345
2347
|
try {
|
|
2346
|
-
const { cellData, onCellDataChange } = effectsRef.current;
|
|
2347
|
-
const
|
|
2348
|
+
const { cellData, onCellDataChange, onCellDataPatch, controlledCellData } = effectsRef.current;
|
|
2349
|
+
const patch = new Map;
|
|
2348
2350
|
updates.forEach(({ value, rowIndex, colIndex }) => {
|
|
2349
2351
|
const key = `${indexToColumn(colIndex)}${rowIndex + 1}`;
|
|
2350
2352
|
const parseValue = effectsRef.current.parseValue;
|
|
2351
2353
|
if (value === "") {
|
|
2352
|
-
|
|
2354
|
+
patch.set(key, undefined);
|
|
2353
2355
|
} else {
|
|
2354
2356
|
let parsedValue = value;
|
|
2355
2357
|
if (parseValue && typeof value === "string") {
|
|
@@ -2369,10 +2371,23 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
2369
2371
|
});
|
|
2370
2372
|
}
|
|
2371
2373
|
}
|
|
2372
|
-
|
|
2374
|
+
patch.set(key, parsedValue);
|
|
2373
2375
|
}
|
|
2374
2376
|
});
|
|
2375
|
-
|
|
2377
|
+
if (onCellDataPatch) {
|
|
2378
|
+
onCellDataPatch(patch);
|
|
2379
|
+
if (controlledCellData !== undefined)
|
|
2380
|
+
return;
|
|
2381
|
+
}
|
|
2382
|
+
const newData = new Map(cellData);
|
|
2383
|
+
patch.forEach((value, key) => {
|
|
2384
|
+
if (value === undefined)
|
|
2385
|
+
newData.delete(key);
|
|
2386
|
+
else
|
|
2387
|
+
newData.set(key, value);
|
|
2388
|
+
});
|
|
2389
|
+
if (!onCellDataPatch)
|
|
2390
|
+
onCellDataChange?.(newData);
|
|
2376
2391
|
setInternalCellData(newData);
|
|
2377
2392
|
} catch (error) {
|
|
2378
2393
|
console.error("Failed to update spreadsheet cell data:", error);
|
|
@@ -3248,12 +3263,370 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
3248
3263
|
Spreadsheet.displayName = "Spreadsheet";
|
|
3249
3264
|
// src/workbook/workbook.tsx
|
|
3250
3265
|
var import_formula_engine2 = require("@ricsam/formula-engine");
|
|
3251
|
-
var
|
|
3266
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
3252
3267
|
|
|
3253
|
-
// src/
|
|
3268
|
+
// src/workbook/sheet-navigation.tsx
|
|
3254
3269
|
var import_react5 = require("react");
|
|
3270
|
+
var jsx_runtime4 = require("react/jsx-runtime");
|
|
3271
|
+
function SheetNavigation({
|
|
3272
|
+
sheets,
|
|
3273
|
+
activeSheet,
|
|
3274
|
+
workbookName,
|
|
3275
|
+
panelId,
|
|
3276
|
+
onSelect,
|
|
3277
|
+
onAdd,
|
|
3278
|
+
onRename,
|
|
3279
|
+
onDelete,
|
|
3280
|
+
children
|
|
3281
|
+
}) {
|
|
3282
|
+
const id = import_react5.useId();
|
|
3283
|
+
const root = import_react5.useRef(null);
|
|
3284
|
+
const menuButton = import_react5.useRef(null);
|
|
3285
|
+
const menu = import_react5.useRef(null);
|
|
3286
|
+
const input = import_react5.useRef(null);
|
|
3287
|
+
const [menuOpen, setMenuOpen] = import_react5.useState(false);
|
|
3288
|
+
const [renaming, setRenaming] = import_react5.useState(null);
|
|
3289
|
+
const [name, setName] = import_react5.useState("");
|
|
3290
|
+
const [error, setError] = import_react5.useState("");
|
|
3291
|
+
const [notice, setNotice] = import_react5.useState("");
|
|
3292
|
+
const selected = sheets.includes(activeSheet) ? activeSheet : sheets[0];
|
|
3293
|
+
const focusTab = (sheet = selected) => {
|
|
3294
|
+
const tabs = root.current?.querySelectorAll('[role="tab"]');
|
|
3295
|
+
tabs?.[sheets.indexOf(sheet ?? "")]?.focus();
|
|
3296
|
+
};
|
|
3297
|
+
import_react5.useEffect(() => {
|
|
3298
|
+
const tab = root.current?.querySelector('[aria-selected="true"]');
|
|
3299
|
+
const strip = tab?.parentElement;
|
|
3300
|
+
if (!tab || !strip)
|
|
3301
|
+
return;
|
|
3302
|
+
const bounds = strip.getBoundingClientRect();
|
|
3303
|
+
const target = tab.getBoundingClientRect();
|
|
3304
|
+
if (target.left < bounds.left)
|
|
3305
|
+
strip.scrollLeft -= bounds.left - target.left;
|
|
3306
|
+
else if (target.right > bounds.right)
|
|
3307
|
+
strip.scrollLeft += target.right - bounds.right;
|
|
3308
|
+
}, [activeSheet, sheets.join("\x00")]);
|
|
3309
|
+
import_react5.useEffect(() => {
|
|
3310
|
+
if (renaming) {
|
|
3311
|
+
input.current?.focus();
|
|
3312
|
+
input.current?.select();
|
|
3313
|
+
}
|
|
3314
|
+
}, [renaming]);
|
|
3315
|
+
import_react5.useEffect(() => {
|
|
3316
|
+
if (!menuOpen)
|
|
3317
|
+
return;
|
|
3318
|
+
menu.current?.querySelector("button")?.focus();
|
|
3319
|
+
const outside = (event) => {
|
|
3320
|
+
if (!root.current?.contains(event.target))
|
|
3321
|
+
setMenuOpen(false);
|
|
3322
|
+
};
|
|
3323
|
+
document.addEventListener("pointerdown", outside);
|
|
3324
|
+
return () => document.removeEventListener("pointerdown", outside);
|
|
3325
|
+
}, [menuOpen]);
|
|
3326
|
+
import_react5.useEffect(() => {
|
|
3327
|
+
setMenuOpen(false);
|
|
3328
|
+
setRenaming(null);
|
|
3329
|
+
setError("");
|
|
3330
|
+
}, [workbookName]);
|
|
3331
|
+
import_react5.useEffect(() => {
|
|
3332
|
+
if (renaming && !sheets.includes(renaming)) {
|
|
3333
|
+
setRenaming(null);
|
|
3334
|
+
setError("");
|
|
3335
|
+
}
|
|
3336
|
+
}, [renaming, sheets.join("\x00")]);
|
|
3337
|
+
const run = (action) => {
|
|
3338
|
+
try {
|
|
3339
|
+
action();
|
|
3340
|
+
setError("");
|
|
3341
|
+
return true;
|
|
3342
|
+
} catch (error) {
|
|
3343
|
+
setError(error instanceof Error ? error.message : "Unable to update this sheet. Please try again.");
|
|
3344
|
+
return false;
|
|
3345
|
+
}
|
|
3346
|
+
};
|
|
3347
|
+
const startRename = (sheet) => {
|
|
3348
|
+
setMenuOpen(false);
|
|
3349
|
+
setError("");
|
|
3350
|
+
setRenaming(sheet);
|
|
3351
|
+
setName(sheet);
|
|
3352
|
+
};
|
|
3353
|
+
const cancelRename = () => {
|
|
3354
|
+
setRenaming(null);
|
|
3355
|
+
setError("");
|
|
3356
|
+
focusTab();
|
|
3357
|
+
};
|
|
3358
|
+
const saveRename = (event) => {
|
|
3359
|
+
event.preventDefault();
|
|
3360
|
+
if (!renaming)
|
|
3361
|
+
return;
|
|
3362
|
+
const next = name.trim();
|
|
3363
|
+
if (!next) {
|
|
3364
|
+
setError("Enter a sheet name.");
|
|
3365
|
+
input.current?.focus();
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
if (sheets.some((sheet) => sheet !== renaming && sheet.toLocaleLowerCase() === next.toLocaleLowerCase())) {
|
|
3369
|
+
setError("A sheet with this name already exists. Choose a different name.");
|
|
3370
|
+
input.current?.focus();
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
if (run(() => {
|
|
3374
|
+
if (next !== renaming)
|
|
3375
|
+
onRename(renaming, next);
|
|
3376
|
+
})) {
|
|
3377
|
+
setRenaming(null);
|
|
3378
|
+
setNotice(`Sheet renamed to ${next}.`);
|
|
3379
|
+
menuButton.current?.focus();
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
return /* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
3383
|
+
ref: root,
|
|
3384
|
+
className: "rsp-sheet-navigation",
|
|
3385
|
+
onKeyDown: (event) => event.stopPropagation(),
|
|
3386
|
+
children: [
|
|
3387
|
+
/* @__PURE__ */ jsx_runtime4.jsx("span", {
|
|
3388
|
+
className: "rsp-sr-only",
|
|
3389
|
+
role: "status",
|
|
3390
|
+
children: notice
|
|
3391
|
+
}),
|
|
3392
|
+
renaming && /* @__PURE__ */ jsx_runtime4.jsxs("form", {
|
|
3393
|
+
className: "rsp-sheet-rename",
|
|
3394
|
+
onSubmit: saveRename,
|
|
3395
|
+
onKeyDown: (event) => {
|
|
3396
|
+
if (event.key === "Escape") {
|
|
3397
|
+
event.preventDefault();
|
|
3398
|
+
cancelRename();
|
|
3399
|
+
}
|
|
3400
|
+
},
|
|
3401
|
+
children: [
|
|
3402
|
+
/* @__PURE__ */ jsx_runtime4.jsx("label", {
|
|
3403
|
+
htmlFor: `${id}-name`,
|
|
3404
|
+
children: "Sheet name"
|
|
3405
|
+
}),
|
|
3406
|
+
/* @__PURE__ */ jsx_runtime4.jsx("input", {
|
|
3407
|
+
ref: input,
|
|
3408
|
+
id: `${id}-name`,
|
|
3409
|
+
className: "rsp-sheet-tab-input",
|
|
3410
|
+
value: name,
|
|
3411
|
+
onChange: (event) => {
|
|
3412
|
+
setName(event.target.value);
|
|
3413
|
+
setError("");
|
|
3414
|
+
},
|
|
3415
|
+
"aria-invalid": !!error,
|
|
3416
|
+
"aria-describedby": error ? `${id}-error` : undefined,
|
|
3417
|
+
"data-testid": `rename-sheet-input-${renaming}`
|
|
3418
|
+
}),
|
|
3419
|
+
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
3420
|
+
type: "submit",
|
|
3421
|
+
className: "rsp-sheet-action",
|
|
3422
|
+
children: "Save"
|
|
3423
|
+
}),
|
|
3424
|
+
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
3425
|
+
type: "button",
|
|
3426
|
+
className: "rsp-sheet-action",
|
|
3427
|
+
onClick: cancelRename,
|
|
3428
|
+
children: "Cancel"
|
|
3429
|
+
})
|
|
3430
|
+
]
|
|
3431
|
+
}),
|
|
3432
|
+
error && /* @__PURE__ */ jsx_runtime4.jsx("div", {
|
|
3433
|
+
id: `${id}-error`,
|
|
3434
|
+
className: "rsp-sheet-error",
|
|
3435
|
+
role: "alert",
|
|
3436
|
+
children: error
|
|
3437
|
+
}),
|
|
3438
|
+
/* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
3439
|
+
className: "rsp-sheet-tabs",
|
|
3440
|
+
children: [
|
|
3441
|
+
/* @__PURE__ */ jsx_runtime4.jsx("div", {
|
|
3442
|
+
className: "rsp-sheet-tabs-scroll",
|
|
3443
|
+
role: "tablist",
|
|
3444
|
+
"aria-label": `${workbookName} sheets`,
|
|
3445
|
+
children: sheets.map((sheet, index) => /* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
3446
|
+
type: "button",
|
|
3447
|
+
role: "tab",
|
|
3448
|
+
className: `rsp-sheet-tab${activeSheet === sheet ? " rsp-sheet-tab-active" : ""}`,
|
|
3449
|
+
"aria-controls": panelId,
|
|
3450
|
+
"aria-selected": activeSheet === sheet,
|
|
3451
|
+
tabIndex: sheet === selected ? 0 : -1,
|
|
3452
|
+
title: sheet,
|
|
3453
|
+
"data-testid": `sheet-tab-${sheet}`,
|
|
3454
|
+
onClick: () => {
|
|
3455
|
+
setMenuOpen(false);
|
|
3456
|
+
onSelect(sheet);
|
|
3457
|
+
},
|
|
3458
|
+
onDoubleClick: () => startRename(sheet),
|
|
3459
|
+
onKeyDown: (event) => {
|
|
3460
|
+
const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
|
|
3461
|
+
let next;
|
|
3462
|
+
if (event.key === "ArrowRight")
|
|
3463
|
+
next = (index + (rtl ? -1 : 1) + sheets.length) % sheets.length;
|
|
3464
|
+
if (event.key === "ArrowLeft")
|
|
3465
|
+
next = (index + (rtl ? 1 : -1) + sheets.length) % sheets.length;
|
|
3466
|
+
if (event.key === "Home")
|
|
3467
|
+
next = 0;
|
|
3468
|
+
if (event.key === "End")
|
|
3469
|
+
next = sheets.length - 1;
|
|
3470
|
+
if (next !== undefined) {
|
|
3471
|
+
event.preventDefault();
|
|
3472
|
+
onSelect(sheets[next]);
|
|
3473
|
+
focusTab(sheets[next]);
|
|
3474
|
+
}
|
|
3475
|
+
if (event.key === "F2") {
|
|
3476
|
+
event.preventDefault();
|
|
3477
|
+
startRename(sheet);
|
|
3478
|
+
}
|
|
3479
|
+
},
|
|
3480
|
+
children: /* @__PURE__ */ jsx_runtime4.jsx("span", {
|
|
3481
|
+
children: sheet
|
|
3482
|
+
})
|
|
3483
|
+
}, sheet))
|
|
3484
|
+
}),
|
|
3485
|
+
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
3486
|
+
type: "button",
|
|
3487
|
+
className: "rsp-add-sheet-button",
|
|
3488
|
+
title: "Add Sheet",
|
|
3489
|
+
"aria-label": "Add Sheet",
|
|
3490
|
+
"data-testid": `add-sheet-${workbookName}`,
|
|
3491
|
+
onClick: () => {
|
|
3492
|
+
setMenuOpen(false);
|
|
3493
|
+
run(onAdd);
|
|
3494
|
+
},
|
|
3495
|
+
children: /* @__PURE__ */ jsx_runtime4.jsx("svg", {
|
|
3496
|
+
"aria-hidden": "true",
|
|
3497
|
+
width: "16",
|
|
3498
|
+
height: "16",
|
|
3499
|
+
viewBox: "0 0 24 24",
|
|
3500
|
+
fill: "none",
|
|
3501
|
+
stroke: "currentColor",
|
|
3502
|
+
strokeWidth: "2",
|
|
3503
|
+
strokeLinecap: "round",
|
|
3504
|
+
children: /* @__PURE__ */ jsx_runtime4.jsx("path", {
|
|
3505
|
+
d: "M12 5v14M5 12h14"
|
|
3506
|
+
})
|
|
3507
|
+
})
|
|
3508
|
+
}),
|
|
3509
|
+
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
3510
|
+
ref: menuButton,
|
|
3511
|
+
type: "button",
|
|
3512
|
+
className: "rsp-icon-button rsp-sheet-menu-trigger",
|
|
3513
|
+
title: "Sheet actions",
|
|
3514
|
+
"aria-label": selected ? `Sheet actions for ${selected}` : "Sheet actions",
|
|
3515
|
+
disabled: !selected,
|
|
3516
|
+
"aria-haspopup": "menu",
|
|
3517
|
+
"aria-expanded": menuOpen,
|
|
3518
|
+
"aria-controls": menuOpen ? `${id}-menu` : undefined,
|
|
3519
|
+
onClick: () => setMenuOpen((open) => !open),
|
|
3520
|
+
onKeyDown: (event) => {
|
|
3521
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
3522
|
+
event.preventDefault();
|
|
3523
|
+
setMenuOpen(true);
|
|
3524
|
+
}
|
|
3525
|
+
},
|
|
3526
|
+
children: /* @__PURE__ */ jsx_runtime4.jsxs("svg", {
|
|
3527
|
+
"aria-hidden": "true",
|
|
3528
|
+
width: "16",
|
|
3529
|
+
height: "16",
|
|
3530
|
+
viewBox: "0 0 24 24",
|
|
3531
|
+
fill: "currentColor",
|
|
3532
|
+
children: [
|
|
3533
|
+
/* @__PURE__ */ jsx_runtime4.jsx("circle", {
|
|
3534
|
+
cx: "5",
|
|
3535
|
+
cy: "12",
|
|
3536
|
+
r: "2"
|
|
3537
|
+
}),
|
|
3538
|
+
/* @__PURE__ */ jsx_runtime4.jsx("circle", {
|
|
3539
|
+
cx: "12",
|
|
3540
|
+
cy: "12",
|
|
3541
|
+
r: "2"
|
|
3542
|
+
}),
|
|
3543
|
+
/* @__PURE__ */ jsx_runtime4.jsx("circle", {
|
|
3544
|
+
cx: "19",
|
|
3545
|
+
cy: "12",
|
|
3546
|
+
r: "2"
|
|
3547
|
+
})
|
|
3548
|
+
]
|
|
3549
|
+
})
|
|
3550
|
+
}),
|
|
3551
|
+
children
|
|
3552
|
+
]
|
|
3553
|
+
}),
|
|
3554
|
+
menuOpen && selected && /* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
3555
|
+
ref: menu,
|
|
3556
|
+
id: `${id}-menu`,
|
|
3557
|
+
role: "menu",
|
|
3558
|
+
"aria-label": `Actions for ${selected}`,
|
|
3559
|
+
className: "rsp-sheet-menu",
|
|
3560
|
+
onBlur: (event) => {
|
|
3561
|
+
if (!event.currentTarget.contains(event.relatedTarget) && event.relatedTarget !== menuButton.current)
|
|
3562
|
+
setMenuOpen(false);
|
|
3563
|
+
},
|
|
3564
|
+
onKeyDown: (event) => {
|
|
3565
|
+
const items = Array.from(menu.current?.querySelectorAll("button") ?? []);
|
|
3566
|
+
const index = items.indexOf(document.activeElement);
|
|
3567
|
+
if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
|
|
3568
|
+
event.preventDefault();
|
|
3569
|
+
const next = event.key === "Home" ? 0 : event.key === "End" ? items.length - 1 : (index + (event.key === "ArrowDown" ? 1 : -1) + items.length) % items.length;
|
|
3570
|
+
items[next]?.focus();
|
|
3571
|
+
}
|
|
3572
|
+
if (event.key === "Escape") {
|
|
3573
|
+
event.preventDefault();
|
|
3574
|
+
setMenuOpen(false);
|
|
3575
|
+
menuButton.current?.focus();
|
|
3576
|
+
}
|
|
3577
|
+
},
|
|
3578
|
+
children: [
|
|
3579
|
+
/* @__PURE__ */ jsx_runtime4.jsx("div", {
|
|
3580
|
+
className: "rsp-sheet-menu-name",
|
|
3581
|
+
title: selected,
|
|
3582
|
+
children: selected
|
|
3583
|
+
}),
|
|
3584
|
+
/* @__PURE__ */ jsx_runtime4.jsxs("button", {
|
|
3585
|
+
type: "button",
|
|
3586
|
+
role: "menuitem",
|
|
3587
|
+
onClick: () => startRename(selected),
|
|
3588
|
+
"data-testid": `rename-sheet-${selected}`,
|
|
3589
|
+
children: [
|
|
3590
|
+
"Rename sheet ",
|
|
3591
|
+
/* @__PURE__ */ jsx_runtime4.jsx("span", {
|
|
3592
|
+
"aria-hidden": "true",
|
|
3593
|
+
children: "F2"
|
|
3594
|
+
})
|
|
3595
|
+
]
|
|
3596
|
+
}),
|
|
3597
|
+
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
3598
|
+
type: "button",
|
|
3599
|
+
role: "menuitem",
|
|
3600
|
+
"aria-disabled": sheets.length <= 1,
|
|
3601
|
+
className: "rsp-sheet-delete",
|
|
3602
|
+
"data-testid": `delete-sheet-${selected}`,
|
|
3603
|
+
onClick: () => {
|
|
3604
|
+
if (sheets.length <= 1)
|
|
3605
|
+
return;
|
|
3606
|
+
if (window.confirm(`Delete sheet "${selected}" and its contents?`)) {
|
|
3607
|
+
if (run(() => onDelete(selected))) {
|
|
3608
|
+
setMenuOpen(false);
|
|
3609
|
+
setNotice(`Sheet ${selected} deleted.`);
|
|
3610
|
+
menuButton.current?.focus();
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
},
|
|
3614
|
+
children: "Delete sheet"
|
|
3615
|
+
}),
|
|
3616
|
+
sheets.length <= 1 && /* @__PURE__ */ jsx_runtime4.jsx("div", {
|
|
3617
|
+
className: "rsp-sheet-menu-hint",
|
|
3618
|
+
children: "Keep at least one sheet."
|
|
3619
|
+
})
|
|
3620
|
+
]
|
|
3621
|
+
})
|
|
3622
|
+
]
|
|
3623
|
+
});
|
|
3624
|
+
}
|
|
3625
|
+
|
|
3626
|
+
// src/utils/use-scheme-root.ts
|
|
3627
|
+
var import_react6 = require("react");
|
|
3255
3628
|
function useSchemeRoot() {
|
|
3256
|
-
const [element, setElement] =
|
|
3629
|
+
const [element, setElement] = import_react6.useState(null);
|
|
3257
3630
|
const scheme = useColorScheme(element);
|
|
3258
3631
|
return { ref: setElement, "data-rsp-scheme": scheme };
|
|
3259
3632
|
}
|
|
@@ -3634,7 +4007,7 @@ class WorkbookSelectionManager {
|
|
|
3634
4007
|
}
|
|
3635
4008
|
|
|
3636
4009
|
// src/workbook/workbook.tsx
|
|
3637
|
-
var
|
|
4010
|
+
var jsx_runtime5 = require("react/jsx-runtime");
|
|
3638
4011
|
var getWrapCellStyle = (style) => style?.wrapText ? {
|
|
3639
4012
|
whiteSpace: "pre-wrap",
|
|
3640
4013
|
overflowWrap: "anywhere",
|
|
@@ -3665,7 +4038,7 @@ var getBorderCellStyle = (style) => (() => {
|
|
|
3665
4038
|
...borderSides.left && { borderLeftColor: style.borderColor }
|
|
3666
4039
|
};
|
|
3667
4040
|
})();
|
|
3668
|
-
var
|
|
4041
|
+
var PlusIcon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime5.jsxs("svg", {
|
|
3669
4042
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3670
4043
|
width: "16",
|
|
3671
4044
|
height: "16",
|
|
@@ -3678,72 +4051,15 @@ var Edit2Icon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime4.j
|
|
|
3678
4051
|
className,
|
|
3679
4052
|
...props,
|
|
3680
4053
|
children: [
|
|
3681
|
-
/* @__PURE__ */
|
|
3682
|
-
d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"
|
|
3683
|
-
}),
|
|
3684
|
-
/* @__PURE__ */ jsx_runtime4.jsx("path", {
|
|
3685
|
-
d: "m15 5 4 4"
|
|
3686
|
-
})
|
|
3687
|
-
]
|
|
3688
|
-
});
|
|
3689
|
-
var Trash2Icon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime4.jsxs("svg", {
|
|
3690
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3691
|
-
width: "16",
|
|
3692
|
-
height: "16",
|
|
3693
|
-
viewBox: "0 0 24 24",
|
|
3694
|
-
fill: "none",
|
|
3695
|
-
stroke: "currentColor",
|
|
3696
|
-
strokeWidth: "2",
|
|
3697
|
-
strokeLinecap: "round",
|
|
3698
|
-
strokeLinejoin: "round",
|
|
3699
|
-
className,
|
|
3700
|
-
...props,
|
|
3701
|
-
children: [
|
|
3702
|
-
/* @__PURE__ */ jsx_runtime4.jsx("path", {
|
|
3703
|
-
d: "M3 6h18"
|
|
3704
|
-
}),
|
|
3705
|
-
/* @__PURE__ */ jsx_runtime4.jsx("path", {
|
|
3706
|
-
d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"
|
|
3707
|
-
}),
|
|
3708
|
-
/* @__PURE__ */ jsx_runtime4.jsx("path", {
|
|
3709
|
-
d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"
|
|
3710
|
-
}),
|
|
3711
|
-
/* @__PURE__ */ jsx_runtime4.jsx("line", {
|
|
3712
|
-
x1: "10",
|
|
3713
|
-
x2: "10",
|
|
3714
|
-
y1: "11",
|
|
3715
|
-
y2: "17"
|
|
3716
|
-
}),
|
|
3717
|
-
/* @__PURE__ */ jsx_runtime4.jsx("line", {
|
|
3718
|
-
x1: "14",
|
|
3719
|
-
x2: "14",
|
|
3720
|
-
y1: "11",
|
|
3721
|
-
y2: "17"
|
|
3722
|
-
})
|
|
3723
|
-
]
|
|
3724
|
-
});
|
|
3725
|
-
var PlusIcon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime4.jsxs("svg", {
|
|
3726
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3727
|
-
width: "16",
|
|
3728
|
-
height: "16",
|
|
3729
|
-
viewBox: "0 0 24 24",
|
|
3730
|
-
fill: "none",
|
|
3731
|
-
stroke: "currentColor",
|
|
3732
|
-
strokeWidth: "2",
|
|
3733
|
-
strokeLinecap: "round",
|
|
3734
|
-
strokeLinejoin: "round",
|
|
3735
|
-
className,
|
|
3736
|
-
...props,
|
|
3737
|
-
children: [
|
|
3738
|
-
/* @__PURE__ */ jsx_runtime4.jsx("path", {
|
|
4054
|
+
/* @__PURE__ */ jsx_runtime5.jsx("path", {
|
|
3739
4055
|
d: "M5 12h14"
|
|
3740
4056
|
}),
|
|
3741
|
-
/* @__PURE__ */
|
|
4057
|
+
/* @__PURE__ */ jsx_runtime5.jsx("path", {
|
|
3742
4058
|
d: "M12 5v14"
|
|
3743
4059
|
})
|
|
3744
4060
|
]
|
|
3745
4061
|
});
|
|
3746
|
-
var MinusIcon = ({ className = "", ...props }) => /* @__PURE__ */
|
|
4062
|
+
var MinusIcon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime5.jsx("svg", {
|
|
3747
4063
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3748
4064
|
width: "16",
|
|
3749
4065
|
height: "16",
|
|
@@ -3755,13 +4071,13 @@ var MinusIcon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime4.j
|
|
|
3755
4071
|
strokeLinejoin: "round",
|
|
3756
4072
|
className,
|
|
3757
4073
|
...props,
|
|
3758
|
-
children: /* @__PURE__ */
|
|
4074
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx("path", {
|
|
3759
4075
|
d: "M5 12h14"
|
|
3760
4076
|
})
|
|
3761
4077
|
});
|
|
3762
4078
|
function useEngine(engine) {
|
|
3763
|
-
const [state, setState] =
|
|
3764
|
-
|
|
4079
|
+
const [state, setState] = import_react7.useState(() => engine.getState());
|
|
4080
|
+
import_react7.default.useEffect(() => {
|
|
3765
4081
|
return engine.onUpdate(() => {
|
|
3766
4082
|
setState(engine.getState());
|
|
3767
4083
|
});
|
|
@@ -3867,11 +4183,11 @@ function FormulaSheet({
|
|
|
3867
4183
|
...rest
|
|
3868
4184
|
}) {
|
|
3869
4185
|
const schemeRoot = useSchemeRoot();
|
|
3870
|
-
const [selectedArea, setSelectedArea] =
|
|
3871
|
-
const clipboardManager =
|
|
4186
|
+
const [selectedArea, setSelectedArea] = import_react7.useState(null);
|
|
4187
|
+
const clipboardManager = import_react7.default.useMemo(() => controlledClipboardManager ?? new WorkbookClipboardManager(engine), [controlledClipboardManager, engine]);
|
|
3872
4188
|
const state = useEngine(engine);
|
|
3873
4189
|
const sheet = state.workbooks.get(workbookName)?.sheets.get(sheetName);
|
|
3874
|
-
const getEngineTableAt =
|
|
4190
|
+
const getEngineTableAt = import_react7.useCallback((cell) => {
|
|
3875
4191
|
const table = engine.isCellInTable({
|
|
3876
4192
|
workbookName,
|
|
3877
4193
|
sheetName,
|
|
@@ -3903,27 +4219,21 @@ function FormulaSheet({
|
|
|
3903
4219
|
} : {}
|
|
3904
4220
|
};
|
|
3905
4221
|
}, [engine, sheetName, workbookName]);
|
|
3906
|
-
const formulaNavigation =
|
|
4222
|
+
const formulaNavigation = import_react7.useMemo(() => ({
|
|
3907
4223
|
...selection?.navigation,
|
|
3908
4224
|
getTableAt: selection?.navigation?.getTableAt ?? getEngineTableAt
|
|
3909
4225
|
}), [getEngineTableAt, selection?.navigation]);
|
|
3910
|
-
const
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
if (typeof value === "string") {
|
|
4226
|
+
const onCellDataPatch = import_react7.useCallback((patch) => {
|
|
4227
|
+
engine.transact(() => {
|
|
4228
|
+
patch.forEach((value, key) => {
|
|
3914
4229
|
const { colIndex, rowIndex } = import_formula_engine2.parseCellReference(key);
|
|
3915
|
-
const
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
} else {
|
|
3919
|
-
data.set(key, coercedValue);
|
|
3920
|
-
}
|
|
3921
|
-
}
|
|
4230
|
+
const address = { workbookName, sheetName, colIndex, rowIndex };
|
|
4231
|
+
engine.setCellContent(address, typeof value === "string" ? coerceCellInput(value, engine.getCellDataType(address)) : value);
|
|
4232
|
+
});
|
|
3922
4233
|
});
|
|
3923
|
-
engine.setSheetContent({ sheetName, workbookName }, data);
|
|
3924
4234
|
}, [sheetName, engine, workbookName]);
|
|
3925
4235
|
const passedSelectionEffects = selection?.effects;
|
|
3926
|
-
const selectionManagerEffects =
|
|
4236
|
+
const selectionManagerEffects = import_react7.useCallback((spreadsheetSelectionManager) => {
|
|
3927
4237
|
const convertSmAreaToSpreadsheetRange = (area) => {
|
|
3928
4238
|
const rowEnd = area.end.row.type === "infinity" ? {
|
|
3929
4239
|
type: "infinity",
|
|
@@ -4047,7 +4357,7 @@ function FormulaSheet({
|
|
|
4047
4357
|
viewId,
|
|
4048
4358
|
workbookName
|
|
4049
4359
|
]);
|
|
4050
|
-
const renderCallbacks =
|
|
4360
|
+
const renderCallbacks = import_react7.useMemo(() => {
|
|
4051
4361
|
const metadata = engine.getWorkbookMetadata(workbookName);
|
|
4052
4362
|
const defaults = metadata?.defaultCellStyle;
|
|
4053
4363
|
const fontStyle = (style) => ({
|
|
@@ -4172,14 +4482,14 @@ function FormulaSheet({
|
|
|
4172
4482
|
Object.assign(conditionalStyleProps, fontStyle(conditionalStyle), getWrapContentStyle(conditionalStyle));
|
|
4173
4483
|
let defaultElement;
|
|
4174
4484
|
if (showFormulas) {
|
|
4175
|
-
defaultElement = /* @__PURE__ */
|
|
4485
|
+
defaultElement = /* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4176
4486
|
"data-conditional-background": conditionalStyle?.backgroundColor,
|
|
4177
4487
|
"data-conditional-text-color": conditionalStyle?.color,
|
|
4178
4488
|
style: conditionalStyleProps,
|
|
4179
4489
|
children: getCellDisplayText(value)
|
|
4180
4490
|
});
|
|
4181
4491
|
} else if (typeof value === "boolean") {
|
|
4182
|
-
defaultElement = /* @__PURE__ */
|
|
4492
|
+
defaultElement = /* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4183
4493
|
"data-conditional-background": conditionalStyle?.backgroundColor,
|
|
4184
4494
|
"data-conditional-text-color": conditionalStyle?.color,
|
|
4185
4495
|
"data-type": "boolean",
|
|
@@ -4192,7 +4502,7 @@ function FormulaSheet({
|
|
|
4192
4502
|
children: value ? "TRUE" : "FALSE"
|
|
4193
4503
|
});
|
|
4194
4504
|
} else if (typeof value === "number") {
|
|
4195
|
-
defaultElement = /* @__PURE__ */
|
|
4505
|
+
defaultElement = /* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4196
4506
|
"data-conditional-background": conditionalStyle?.backgroundColor,
|
|
4197
4507
|
"data-conditional-text-color": conditionalStyle?.color,
|
|
4198
4508
|
"data-type": "number",
|
|
@@ -4203,7 +4513,7 @@ function FormulaSheet({
|
|
|
4203
4513
|
})
|
|
4204
4514
|
});
|
|
4205
4515
|
} else {
|
|
4206
|
-
defaultElement = /* @__PURE__ */
|
|
4516
|
+
defaultElement = /* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4207
4517
|
"data-conditional-background": conditionalStyle?.backgroundColor,
|
|
4208
4518
|
"data-conditional-text-color": conditionalStyle?.color,
|
|
4209
4519
|
style: { ...conditionalStyleProps, width: "100%", textAlign: "left" },
|
|
@@ -4228,29 +4538,29 @@ function FormulaSheet({
|
|
|
4228
4538
|
customCellRenderer
|
|
4229
4539
|
]);
|
|
4230
4540
|
if (!sheet) {
|
|
4231
|
-
return /* @__PURE__ */
|
|
4541
|
+
return /* @__PURE__ */ jsx_runtime5.jsxs("div", {
|
|
4232
4542
|
className: "rsp-root rsp-workbook",
|
|
4233
4543
|
...schemeRoot,
|
|
4234
4544
|
children: [
|
|
4235
4545
|
toolbar,
|
|
4236
|
-
/* @__PURE__ */
|
|
4546
|
+
/* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4237
4547
|
style: { flex: 1 }
|
|
4238
4548
|
})
|
|
4239
4549
|
]
|
|
4240
4550
|
});
|
|
4241
4551
|
}
|
|
4242
|
-
return /* @__PURE__ */
|
|
4552
|
+
return /* @__PURE__ */ jsx_runtime5.jsxs("div", {
|
|
4243
4553
|
className: "rsp-root rsp-workbook",
|
|
4244
4554
|
...schemeRoot,
|
|
4245
4555
|
children: [
|
|
4246
4556
|
toolbar,
|
|
4247
|
-
/* @__PURE__ */
|
|
4557
|
+
/* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4248
4558
|
className: "rsp-workbook-body",
|
|
4249
|
-
children: /* @__PURE__ */
|
|
4559
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx(Spreadsheet, {
|
|
4250
4560
|
disableClipboard: true,
|
|
4251
4561
|
style: { height: "100%", width: "100%" },
|
|
4252
4562
|
cellData: sheet?.content,
|
|
4253
|
-
|
|
4563
|
+
onCellDataPatch,
|
|
4254
4564
|
onCellDataChangeError,
|
|
4255
4565
|
...rest,
|
|
4256
4566
|
components,
|
|
@@ -4298,18 +4608,16 @@ function FormulaWorkbook({
|
|
|
4298
4608
|
...rest
|
|
4299
4609
|
}) {
|
|
4300
4610
|
const schemeRoot = useSchemeRoot();
|
|
4301
|
-
|
|
4302
|
-
const
|
|
4303
|
-
const [
|
|
4304
|
-
const
|
|
4305
|
-
const renameCommittedRef = import_react6.useRef(false);
|
|
4306
|
-
const clipboardManager = import_react6.default.useMemo(() => controlledClipboardManager ?? new WorkbookClipboardManager(engine), [controlledClipboardManager, engine]);
|
|
4611
|
+
useEngine(engine);
|
|
4612
|
+
const panelId = import_react7.default.useId();
|
|
4613
|
+
const [spreadsheetZoom, setSpreadsheetZoom] = import_react7.useState(1);
|
|
4614
|
+
const clipboardManager = import_react7.default.useMemo(() => controlledClipboardManager ?? new WorkbookClipboardManager(engine), [controlledClipboardManager, engine]);
|
|
4307
4615
|
const sheetNames = engine.getOrderedSheetNames(workbookName);
|
|
4308
|
-
const [internalActiveSheet, setInternalActiveSheet] =
|
|
4616
|
+
const [internalActiveSheet, setInternalActiveSheet] = import_react7.useState(() => {
|
|
4309
4617
|
return sheetNames[0] || "";
|
|
4310
4618
|
});
|
|
4311
|
-
const isControlledRef =
|
|
4312
|
-
|
|
4619
|
+
const isControlledRef = import_react7.useRef(controlledActiveSheet !== undefined);
|
|
4620
|
+
import_react7.default.useEffect(() => {
|
|
4313
4621
|
const isCurrentlyControlled = controlledActiveSheet !== undefined;
|
|
4314
4622
|
if (isControlledRef.current !== isCurrentlyControlled) {
|
|
4315
4623
|
console.error(`FormulaWorkbook: Component changed from ${isControlledRef.current ? "controlled" : "uncontrolled"} to ${isCurrentlyControlled ? "controlled" : "uncontrolled"} mode. ` + `A component should not switch between controlled and uncontrolled modes. ` + `Decide between using activeSheet and onActiveSheetChange props (controlled) or neither (uncontrolled) for the lifetime of the component.`);
|
|
@@ -4317,100 +4625,61 @@ function FormulaWorkbook({
|
|
|
4317
4625
|
isControlledRef.current = isCurrentlyControlled;
|
|
4318
4626
|
}, [controlledActiveSheet]);
|
|
4319
4627
|
const activeSheet = controlledActiveSheet ?? internalActiveSheet;
|
|
4320
|
-
const handleActiveSheetChange =
|
|
4628
|
+
const handleActiveSheetChange = import_react7.useCallback((sheetName) => {
|
|
4321
4629
|
if (onActiveSheetChange) {
|
|
4322
4630
|
onActiveSheetChange(sheetName);
|
|
4323
|
-
} else {
|
|
4324
|
-
setInternalActiveSheet(sheetName);
|
|
4325
4631
|
}
|
|
4326
|
-
|
|
4632
|
+
if (controlledActiveSheet === undefined)
|
|
4633
|
+
setInternalActiveSheet(sheetName);
|
|
4634
|
+
}, [onActiveSheetChange, controlledActiveSheet]);
|
|
4327
4635
|
const activeSheetOverlayChildren = sheetOverlayChildren?.[activeSheet];
|
|
4328
4636
|
const activeSheetSelectedOverlayId = sheetSelectedOverlayIds?.[activeSheet];
|
|
4329
4637
|
const activeSheetColumnWidths = sheetLayouts?.[activeSheet]?.columnWidths;
|
|
4330
4638
|
const activeSheetRowHeights = sheetLayouts?.[activeSheet]?.rowHeights;
|
|
4331
|
-
const handleOverlaySelect =
|
|
4639
|
+
const handleOverlaySelect = import_react7.useCallback((overlayId) => {
|
|
4332
4640
|
onOverlaySelect?.(activeSheet, overlayId);
|
|
4333
4641
|
}, [onOverlaySelect, activeSheet]);
|
|
4334
|
-
const handleOverlayChildrenChange =
|
|
4642
|
+
const handleOverlayChildrenChange = import_react7.useCallback((children) => {
|
|
4335
4643
|
onOverlayChildrenChange?.(activeSheet, children);
|
|
4336
4644
|
}, [onOverlayChildrenChange, activeSheet]);
|
|
4337
|
-
const handleColumnWidthsChange =
|
|
4645
|
+
const handleColumnWidthsChange = import_react7.useCallback((columnWidths) => {
|
|
4338
4646
|
onSheetColumnWidthsChange?.(activeSheet, columnWidths);
|
|
4339
4647
|
}, [activeSheet, onSheetColumnWidthsChange]);
|
|
4340
|
-
const handleRowHeightsChange =
|
|
4648
|
+
const handleRowHeightsChange = import_react7.useCallback((rowHeights) => {
|
|
4341
4649
|
onSheetRowHeightsChange?.(activeSheet, rowHeights);
|
|
4342
4650
|
}, [activeSheet, onSheetRowHeightsChange]);
|
|
4343
4651
|
const addSheet = () => {
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
workbookName
|
|
4347
|
-
});
|
|
4348
|
-
handleActiveSheetChange(newSheet.name);
|
|
4349
|
-
} catch (error) {
|
|
4350
|
-
console.error("Failed to add sheet:", error);
|
|
4351
|
-
}
|
|
4352
|
-
};
|
|
4353
|
-
const startRenaming = (sheetName) => {
|
|
4354
|
-
renameCommittedRef.current = false;
|
|
4355
|
-
setRenamingSheet(sheetName);
|
|
4356
|
-
setNewSheetName(sheetName);
|
|
4357
|
-
};
|
|
4358
|
-
const cancelRenaming = () => {
|
|
4359
|
-
setRenamingSheet(null);
|
|
4360
|
-
setNewSheetName("");
|
|
4652
|
+
const newSheet = engine.createSheet({ workbookName });
|
|
4653
|
+
handleActiveSheetChange(newSheet.name);
|
|
4361
4654
|
};
|
|
4362
4655
|
const renameSheet = (oldName, newName) => {
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
}
|
|
4367
|
-
if (!newName.trim() || newName.trim() === oldName) {
|
|
4368
|
-
cancelRenaming();
|
|
4369
|
-
return;
|
|
4370
|
-
}
|
|
4371
|
-
try {
|
|
4372
|
-
renameCommittedRef.current = true;
|
|
4373
|
-
engine.renameSheet({
|
|
4374
|
-
workbookName,
|
|
4375
|
-
sheetName: oldName,
|
|
4376
|
-
newSheetName: newName.trim()
|
|
4377
|
-
});
|
|
4378
|
-
if (activeSheet === oldName) {
|
|
4379
|
-
handleActiveSheetChange(newName.trim());
|
|
4380
|
-
}
|
|
4381
|
-
cancelRenaming();
|
|
4382
|
-
} catch (error) {
|
|
4383
|
-
console.error("Failed to rename sheet:", error);
|
|
4384
|
-
cancelRenaming();
|
|
4385
|
-
}
|
|
4656
|
+
engine.renameSheet({ workbookName, sheetName: oldName, newSheetName: newName });
|
|
4657
|
+
if (activeSheet === oldName)
|
|
4658
|
+
handleActiveSheetChange(newName);
|
|
4386
4659
|
};
|
|
4387
4660
|
const deleteSheet = (sheetName) => {
|
|
4388
4661
|
if (sheetNames.length <= 1) {
|
|
4389
4662
|
console.error("Cannot delete the last sheet");
|
|
4390
4663
|
return;
|
|
4391
4664
|
}
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
handleActiveSheetChange(nextSheet);
|
|
4399
|
-
}
|
|
4665
|
+
engine.removeSheet({ workbookName, sheetName });
|
|
4666
|
+
if (activeSheet === sheetName) {
|
|
4667
|
+
const remainingSheets = sheetNames.filter((name) => name !== sheetName);
|
|
4668
|
+
const nextSheet = remainingSheets[Math.min(sheetNames.indexOf(sheetName), remainingSheets.length - 1)];
|
|
4669
|
+
if (nextSheet) {
|
|
4670
|
+
handleActiveSheetChange(nextSheet);
|
|
4400
4671
|
}
|
|
4401
|
-
} catch (error) {
|
|
4402
|
-
console.error("Failed to delete sheet:", error);
|
|
4403
4672
|
}
|
|
4404
4673
|
};
|
|
4405
|
-
return /* @__PURE__ */
|
|
4674
|
+
return /* @__PURE__ */ jsx_runtime5.jsxs("div", {
|
|
4406
4675
|
className: "rsp-root rsp-workbook",
|
|
4407
4676
|
...schemeRoot,
|
|
4408
4677
|
children: [
|
|
4409
4678
|
toolbar,
|
|
4410
|
-
/* @__PURE__ */
|
|
4679
|
+
/* @__PURE__ */ jsx_runtime5.jsxs("div", {
|
|
4411
4680
|
className: "rsp-workbook-header",
|
|
4412
4681
|
children: [
|
|
4413
|
-
/* @__PURE__ */
|
|
4682
|
+
/* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4414
4683
|
style: {
|
|
4415
4684
|
display: "flex",
|
|
4416
4685
|
alignItems: "center",
|
|
@@ -4419,13 +4688,13 @@ function FormulaWorkbook({
|
|
|
4419
4688
|
overflow: "hidden",
|
|
4420
4689
|
textOverflow: "ellipsis"
|
|
4421
4690
|
},
|
|
4422
|
-
children: /* @__PURE__ */
|
|
4691
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
4423
4692
|
className: "rsp-workbook-name",
|
|
4424
4693
|
"data-testid": `workbook-name-${workbookName}`,
|
|
4425
4694
|
children: workbookName
|
|
4426
4695
|
})
|
|
4427
4696
|
}),
|
|
4428
|
-
/* @__PURE__ */
|
|
4697
|
+
/* @__PURE__ */ jsx_runtime5.jsxs("span", {
|
|
4429
4698
|
className: "rsp-zoom-value",
|
|
4430
4699
|
"data-testid": `sheet-count-${workbookName}`,
|
|
4431
4700
|
children: [
|
|
@@ -4435,16 +4704,19 @@ function FormulaWorkbook({
|
|
|
4435
4704
|
})
|
|
4436
4705
|
]
|
|
4437
4706
|
}),
|
|
4438
|
-
/* @__PURE__ */
|
|
4439
|
-
|
|
4440
|
-
|
|
4707
|
+
/* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4708
|
+
id: panelId,
|
|
4709
|
+
role: "tabpanel",
|
|
4710
|
+
"aria-label": activeSheet || "Sheet",
|
|
4711
|
+
style: { flex: 1, minHeight: 0, overflow: "hidden" },
|
|
4712
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx("div", {
|
|
4441
4713
|
style: {
|
|
4442
4714
|
transform: spreadsheetZoom !== 1 ? `scale(${spreadsheetZoom})` : undefined,
|
|
4443
4715
|
transformOrigin: "0 0",
|
|
4444
4716
|
width: spreadsheetZoom !== 1 ? `${100 / spreadsheetZoom}%` : "100%",
|
|
4445
4717
|
height: spreadsheetZoom !== 1 ? `${100 / spreadsheetZoom}%` : "100%"
|
|
4446
4718
|
},
|
|
4447
|
-
children: /* @__PURE__ */
|
|
4719
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx(FormulaSheet, {
|
|
4448
4720
|
sheetName: activeSheet,
|
|
4449
4721
|
workbookName,
|
|
4450
4722
|
engine,
|
|
@@ -4468,138 +4740,53 @@ function FormulaWorkbook({
|
|
|
4468
4740
|
}, `${workbookName}-${activeSheet}`)
|
|
4469
4741
|
})
|
|
4470
4742
|
}),
|
|
4471
|
-
/* @__PURE__ */
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
renameSheet(sheetName, newSheetName);
|
|
4493
|
-
} else if (e.key === "Escape") {
|
|
4494
|
-
cancelRenaming();
|
|
4495
|
-
}
|
|
4496
|
-
},
|
|
4497
|
-
onBlur: () => {
|
|
4498
|
-
if (newSheetName.trim() && newSheetName.trim() !== sheetName) {
|
|
4499
|
-
renameSheet(sheetName, newSheetName);
|
|
4500
|
-
} else {
|
|
4501
|
-
cancelRenaming();
|
|
4502
|
-
}
|
|
4503
|
-
},
|
|
4504
|
-
autoFocus: true,
|
|
4505
|
-
"data-testid": `rename-sheet-input-${sheetName}`
|
|
4506
|
-
})
|
|
4507
|
-
}) : /* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
4508
|
-
className: cn("rsp-sheet-tab", {
|
|
4509
|
-
"rsp-sheet-tab-active": isActive
|
|
4510
|
-
}),
|
|
4511
|
-
onClick: () => handleActiveSheetChange(sheetName),
|
|
4512
|
-
onDoubleClick: () => startRenaming(sheetName),
|
|
4513
|
-
"data-testid": `sheet-tab-${sheetName}`,
|
|
4514
|
-
children: [
|
|
4515
|
-
/* @__PURE__ */ jsx_runtime4.jsx("span", {
|
|
4516
|
-
children: sheetName
|
|
4517
|
-
}),
|
|
4518
|
-
/* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
4519
|
-
className: "sheet-tab-actions",
|
|
4520
|
-
children: [
|
|
4521
|
-
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
4522
|
-
type: "button",
|
|
4523
|
-
className: "rsp-icon-button",
|
|
4524
|
-
onClick: (e) => {
|
|
4525
|
-
e.stopPropagation();
|
|
4526
|
-
startRenaming(sheetName);
|
|
4527
|
-
},
|
|
4528
|
-
title: "Rename Sheet",
|
|
4529
|
-
"data-testid": `rename-sheet-${sheetName}`,
|
|
4530
|
-
children: /* @__PURE__ */ jsx_runtime4.jsx(Edit2Icon, {
|
|
4531
|
-
style: { width: 12, height: 12 }
|
|
4532
|
-
})
|
|
4533
|
-
}),
|
|
4534
|
-
sheetNames.length > 1 && /* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
4535
|
-
type: "button",
|
|
4536
|
-
className: "rsp-icon-button rsp-icon-button-delete",
|
|
4537
|
-
onClick: (e) => {
|
|
4538
|
-
e.stopPropagation();
|
|
4539
|
-
if (confirm(`Are you sure you want to delete sheet "${sheetName}"?`)) {
|
|
4540
|
-
deleteSheet(sheetName);
|
|
4541
|
-
}
|
|
4542
|
-
},
|
|
4543
|
-
title: "Delete Sheet",
|
|
4544
|
-
"data-testid": `delete-sheet-${sheetName}`,
|
|
4545
|
-
children: /* @__PURE__ */ jsx_runtime4.jsx(Trash2Icon, {
|
|
4546
|
-
style: { width: 12, height: 12 }
|
|
4547
|
-
})
|
|
4548
|
-
})
|
|
4549
|
-
]
|
|
4550
|
-
})
|
|
4551
|
-
]
|
|
4552
|
-
})
|
|
4553
|
-
}, sheetName);
|
|
4554
|
-
})
|
|
4555
|
-
}),
|
|
4556
|
-
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
4557
|
-
type: "button",
|
|
4558
|
-
className: "rsp-add-sheet-button",
|
|
4559
|
-
onClick: addSheet,
|
|
4560
|
-
title: "Add Sheet",
|
|
4561
|
-
"data-testid": `add-sheet-${workbookName}`,
|
|
4562
|
-
children: /* @__PURE__ */ jsx_runtime4.jsx(PlusIcon, {
|
|
4563
|
-
style: { width: 12, height: 12 }
|
|
4564
|
-
})
|
|
4743
|
+
/* @__PURE__ */ jsx_runtime5.jsx(SheetNavigation, {
|
|
4744
|
+
sheets: sheetNames,
|
|
4745
|
+
activeSheet,
|
|
4746
|
+
workbookName,
|
|
4747
|
+
panelId,
|
|
4748
|
+
onSelect: handleActiveSheetChange,
|
|
4749
|
+
onAdd: addSheet,
|
|
4750
|
+
onRename: renameSheet,
|
|
4751
|
+
onDelete: deleteSheet,
|
|
4752
|
+
children: /* @__PURE__ */ jsx_runtime5.jsxs("div", {
|
|
4753
|
+
className: "rsp-zoom-controls",
|
|
4754
|
+
children: [
|
|
4755
|
+
/* @__PURE__ */ jsx_runtime5.jsx("button", {
|
|
4756
|
+
type: "button",
|
|
4757
|
+
className: "rsp-icon-button",
|
|
4758
|
+
onClick: () => setSpreadsheetZoom(Math.max(0.5, Math.round((spreadsheetZoom - 0.1) * 10) / 10)),
|
|
4759
|
+
disabled: spreadsheetZoom <= 0.5,
|
|
4760
|
+
title: "Zoom Out",
|
|
4761
|
+
style: { opacity: spreadsheetZoom <= 0.5 ? 0.5 : 1 },
|
|
4762
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx(MinusIcon, {
|
|
4763
|
+
style: { width: 12, height: 12 }
|
|
4565
4764
|
})
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
]
|
|
4588
|
-
}),
|
|
4589
|
-
/* @__PURE__ */ jsx_runtime4.jsx("button", {
|
|
4590
|
-
type: "button",
|
|
4591
|
-
className: "rsp-icon-button",
|
|
4592
|
-
onClick: () => setSpreadsheetZoom(Math.min(2, spreadsheetZoom + 0.1)),
|
|
4593
|
-
disabled: spreadsheetZoom >= 2,
|
|
4594
|
-
title: "Zoom In",
|
|
4595
|
-
style: { opacity: spreadsheetZoom >= 2 ? 0.5 : 1 },
|
|
4596
|
-
children: /* @__PURE__ */ jsx_runtime4.jsx(PlusIcon, {
|
|
4597
|
-
style: { width: 12, height: 12 }
|
|
4598
|
-
})
|
|
4765
|
+
}),
|
|
4766
|
+
/* @__PURE__ */ jsx_runtime5.jsxs("button", {
|
|
4767
|
+
type: "button",
|
|
4768
|
+
className: "rsp-zoom-value rsp-zoom-reset",
|
|
4769
|
+
"aria-label": `Zoom ${Math.round(spreadsheetZoom * 100)}%. Reset to 100%`,
|
|
4770
|
+
title: "Reset zoom to 100%",
|
|
4771
|
+
onClick: () => setSpreadsheetZoom(1),
|
|
4772
|
+
children: [
|
|
4773
|
+
Math.round(spreadsheetZoom * 100),
|
|
4774
|
+
"%"
|
|
4775
|
+
]
|
|
4776
|
+
}),
|
|
4777
|
+
/* @__PURE__ */ jsx_runtime5.jsx("button", {
|
|
4778
|
+
type: "button",
|
|
4779
|
+
className: "rsp-icon-button",
|
|
4780
|
+
onClick: () => setSpreadsheetZoom(Math.min(2, Math.round((spreadsheetZoom + 0.1) * 10) / 10)),
|
|
4781
|
+
disabled: spreadsheetZoom >= 2,
|
|
4782
|
+
title: "Zoom In",
|
|
4783
|
+
style: { opacity: spreadsheetZoom >= 2 ? 0.5 : 1 },
|
|
4784
|
+
children: /* @__PURE__ */ jsx_runtime5.jsx(PlusIcon, {
|
|
4785
|
+
style: { width: 12, height: 12 }
|
|
4599
4786
|
})
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4787
|
+
})
|
|
4788
|
+
]
|
|
4789
|
+
})
|
|
4603
4790
|
})
|
|
4604
4791
|
]
|
|
4605
4792
|
});
|
|
@@ -4611,9 +4798,9 @@ var DEFAULT_ZOOM = 1;
|
|
|
4611
4798
|
var MIN_ZOOM = 0.5;
|
|
4612
4799
|
var MAX_ZOOM = 3;
|
|
4613
4800
|
// src/utils/use-click-away.ts
|
|
4614
|
-
var
|
|
4801
|
+
var import_react8 = require("react");
|
|
4615
4802
|
var useClickAway = (ref, callback) => {
|
|
4616
|
-
|
|
4803
|
+
import_react8.useEffect(() => {
|
|
4617
4804
|
const handleClickAway = (event) => {
|
|
4618
4805
|
if (ref) {
|
|
4619
4806
|
const away = !ref.contains(event.target);
|
|
@@ -4627,4 +4814,4 @@ var useClickAway = (ref, callback) => {
|
|
|
4627
4814
|
}, [ref, callback]);
|
|
4628
4815
|
};
|
|
4629
4816
|
|
|
4630
|
-
//# debugId=
|
|
4817
|
+
//# debugId=0C8DF59ED93BC04F64756E2164756E21
|