@ricsam/react-spreadsheets 0.0.2 → 0.0.4
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 +39 -6
- package/dist/cjs/lib.cjs +163 -42
- package/dist/cjs/lib.cjs.map +7 -5
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/lib.mjs +148 -27
- package/dist/mjs/lib.mjs.map +7 -5
- package/dist/mjs/package.json +1 -1
- package/dist/styles.css +290 -71
- package/dist/types/lib.d.ts +1 -0
- package/dist/types/utils/contrast-text.d.ts +36 -0
- package/dist/types/utils/use-scheme-root.d.ts +16 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -88,11 +88,11 @@ top of `FormulaSheet`.
|
|
|
88
88
|
|
|
89
89
|
## Theming
|
|
90
90
|
|
|
91
|
-
All colors, fonts and sizes are CSS custom properties declared on
|
|
92
|
-
|
|
91
|
+
All colors, fonts and sizes are CSS custom properties declared on `:root`, so
|
|
92
|
+
you can override them from **any** ancestor of the grid:
|
|
93
93
|
|
|
94
94
|
```css
|
|
95
|
-
.
|
|
95
|
+
.my-panel {
|
|
96
96
|
--rsp-accent: #7c3aed;
|
|
97
97
|
--rsp-bg: #ffffff;
|
|
98
98
|
--rsp-header-bg: #f4f4f5;
|
|
@@ -100,9 +100,42 @@ Override them anywhere in your cascade:
|
|
|
100
100
|
}
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
-
Light and dark
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
### Light and dark
|
|
104
|
+
|
|
105
|
+
By default the grid follows the user's OS preference.
|
|
106
|
+
|
|
107
|
+
The grid deliberately does **not** declare `color-scheme` on `.rsp-root`, so a
|
|
108
|
+
pin you set on an ancestor is respected. Pin a subtree with plain CSS:
|
|
109
|
+
|
|
110
|
+
```css
|
|
111
|
+
.workbook-stage { color-scheme: light; } /* always light */
|
|
112
|
+
.workbook-stage { color-scheme: dark; } /* always dark */
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
or with the bundled helper classes:
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<FormulaWorkbook className="rsp-theme-dark" ... />
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Canvas gridlines and every DOM surface follow the same resolved scheme. The
|
|
122
|
+
component resolves the inherited `color-scheme` and reflects it on the grid root
|
|
123
|
+
as `data-rsp-scheme`, which drives the `--rsp-light` / `--rsp-dark` token
|
|
124
|
+
switches.
|
|
125
|
+
|
|
126
|
+
> **Note** — the stylesheet intentionally avoids `light-dark()`. Bundlers that
|
|
127
|
+
> target browsers without native support (Vite's Lightning CSS, for example)
|
|
128
|
+
> lower it to switch variables that only exist next to a `color-scheme`
|
|
129
|
+
> declaration, which makes shared-root tokens compute to an invalid value — in
|
|
130
|
+
> production builds only. An equivalent space-toggle is used instead.
|
|
131
|
+
|
|
132
|
+
### Cell fills stay readable
|
|
133
|
+
|
|
134
|
+
A `backgroundColor` coming from your document model is usually a single literal
|
|
135
|
+
color with no dark-mode variant. To stop light fills from pairing with the dark
|
|
136
|
+
theme's near-white text, the grid derives a readable ink for any cell that sets
|
|
137
|
+
a background but no explicit `color`. Set `color` yourself to opt out, and use
|
|
138
|
+
`getContrastingTextColor` if you want the same behaviour elsewhere.
|
|
106
139
|
|
|
107
140
|
Per-cell styling is done in JS:
|
|
108
141
|
|
package/dist/cjs/lib.cjs
CHANGED
|
@@ -92,6 +92,7 @@ __export(exports_lib, {
|
|
|
92
92
|
getCellReference: () => getCellReference,
|
|
93
93
|
getCellSnapAnchorFromRect: () => getCellSnapAnchorFromRect,
|
|
94
94
|
getColumnEdgePosition: () => getColumnEdgePosition,
|
|
95
|
+
getContrastingTextColor: () => getContrastingTextColor,
|
|
95
96
|
getNearestColumnEdgeIndex: () => getNearestColumnEdgeIndex,
|
|
96
97
|
getNearestRowEdgeIndex: () => getNearestRowEdgeIndex,
|
|
97
98
|
getRectFromCellSnapAnchor: () => getRectFromCellSnapAnchor,
|
|
@@ -105,7 +106,9 @@ __export(exports_lib, {
|
|
|
105
106
|
normalizeCellSnapAnchor: () => normalizeCellSnapAnchor,
|
|
106
107
|
onCellEditError: () => onCellEditError,
|
|
107
108
|
parseCellReference: () => parseCellReference,
|
|
109
|
+
parseCssColor: () => parseCssColor,
|
|
108
110
|
queueCellEditError: () => queueCellEditError,
|
|
111
|
+
relativeLuminance: () => relativeLuminance,
|
|
109
112
|
resizeCellSnapAnchorToNearestEdges: () => resizeCellSnapAnchorToNearestEdges,
|
|
110
113
|
rowToLetter: () => rowToLetter,
|
|
111
114
|
useClickAway: () => useClickAway,
|
|
@@ -174,6 +177,85 @@ function useColorScheme(element) {
|
|
|
174
177
|
return scheme;
|
|
175
178
|
}
|
|
176
179
|
|
|
180
|
+
// src/utils/contrast-text.ts
|
|
181
|
+
var DARK_INK = "#101828";
|
|
182
|
+
var LIGHT_INK = "#ffffff";
|
|
183
|
+
var NAMED_COLORS = {
|
|
184
|
+
white: [255, 255, 255],
|
|
185
|
+
black: [0, 0, 0],
|
|
186
|
+
red: [255, 0, 0],
|
|
187
|
+
green: [0, 128, 0],
|
|
188
|
+
blue: [0, 0, 255],
|
|
189
|
+
yellow: [255, 255, 0],
|
|
190
|
+
orange: [255, 165, 0],
|
|
191
|
+
purple: [128, 0, 128],
|
|
192
|
+
gray: [128, 128, 128],
|
|
193
|
+
grey: [128, 128, 128],
|
|
194
|
+
silver: [192, 192, 192]
|
|
195
|
+
};
|
|
196
|
+
var clamp255 = (value) => Math.min(255, Math.max(0, value));
|
|
197
|
+
function parseCssColor(input) {
|
|
198
|
+
const value = input.trim().toLowerCase();
|
|
199
|
+
if (!value || value === "transparent" || value === "currentcolor" || value === "inherit") {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (value.includes("var(") || value.includes("color-mix(") || value.includes("gradient")) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const named = NAMED_COLORS[value];
|
|
206
|
+
if (named) {
|
|
207
|
+
return { r: named[0], g: named[1], b: named[2], a: 1 };
|
|
208
|
+
}
|
|
209
|
+
if (value.startsWith("#")) {
|
|
210
|
+
const hex = value.slice(1);
|
|
211
|
+
const expand = (part) => parseInt(part + part, 16);
|
|
212
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
213
|
+
const r = expand(hex[0]);
|
|
214
|
+
const g = expand(hex[1]);
|
|
215
|
+
const b = expand(hex[2]);
|
|
216
|
+
const a = hex.length === 4 ? expand(hex[3]) / 255 : 1;
|
|
217
|
+
return Number.isNaN(r + g + b) ? undefined : { r, g, b, a };
|
|
218
|
+
}
|
|
219
|
+
if (hex.length === 6 || hex.length === 8) {
|
|
220
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
221
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
222
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
223
|
+
const a = hex.length === 8 ? parseInt(hex.slice(6, 8), 16) / 255 : 1;
|
|
224
|
+
return Number.isNaN(r + g + b) ? undefined : { r, g, b, a };
|
|
225
|
+
}
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const rgbMatch = value.match(/^rgba?\(([^)]+)\)$/);
|
|
229
|
+
if (rgbMatch) {
|
|
230
|
+
const parts = rgbMatch[1].split(/[\s,/]+/).filter(Boolean);
|
|
231
|
+
if (parts.length < 3)
|
|
232
|
+
return;
|
|
233
|
+
const toChannel = (part) => part.endsWith("%") ? parseFloat(part) / 100 * 255 : parseFloat(part);
|
|
234
|
+
const r = toChannel(parts[0]);
|
|
235
|
+
const g = toChannel(parts[1]);
|
|
236
|
+
const b = toChannel(parts[2]);
|
|
237
|
+
const alphaPart = parts[3];
|
|
238
|
+
const a = alphaPart === undefined ? 1 : alphaPart.endsWith("%") ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart);
|
|
239
|
+
if ([r, g, b, a].some((channel) => Number.isNaN(channel)))
|
|
240
|
+
return;
|
|
241
|
+
return { r: clamp255(r), g: clamp255(g), b: clamp255(b), a };
|
|
242
|
+
}
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
function relativeLuminance({ r, g, b }) {
|
|
246
|
+
const channel = (value) => {
|
|
247
|
+
const srgb = value / 255;
|
|
248
|
+
return srgb <= 0.03928 ? srgb / 12.92 : Math.pow((srgb + 0.055) / 1.055, 2.4);
|
|
249
|
+
};
|
|
250
|
+
return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
|
|
251
|
+
}
|
|
252
|
+
function getContrastingTextColor(background) {
|
|
253
|
+
const color = parseCssColor(background);
|
|
254
|
+
if (!color || color.a < 0.5)
|
|
255
|
+
return;
|
|
256
|
+
return relativeLuminance(color) > 0.45 ? DARK_INK : LIGHT_INK;
|
|
257
|
+
}
|
|
258
|
+
|
|
177
259
|
// src/utils/cn.ts
|
|
178
260
|
function cn(...values) {
|
|
179
261
|
const out = [];
|
|
@@ -1352,16 +1434,27 @@ var resizeCellSnapAnchorToNearestEdges = (anchor, rect, handle, columnWidths, ro
|
|
|
1352
1434
|
|
|
1353
1435
|
// src/spreadsheet/spreadsheet.tsx
|
|
1354
1436
|
var jsx_runtime3 = require("react/jsx-runtime");
|
|
1355
|
-
var resolveGridLineColor = (
|
|
1356
|
-
const fallback = colorScheme === "dark" ? "#
|
|
1357
|
-
if (!
|
|
1437
|
+
var resolveGridLineColor = (probe, colorScheme) => {
|
|
1438
|
+
const fallback = colorScheme === "dark" ? "#232c3d" : "#e8ebf1";
|
|
1439
|
+
if (!probe || typeof getComputedStyle !== "function") {
|
|
1358
1440
|
return fallback;
|
|
1359
1441
|
}
|
|
1360
|
-
const
|
|
1361
|
-
if (!
|
|
1442
|
+
const resolved = getComputedStyle(probe).color?.trim();
|
|
1443
|
+
if (!resolved || resolved.includes("light-dark(") || resolved === "rgba(0, 0, 0, 0)") {
|
|
1362
1444
|
return fallback;
|
|
1363
1445
|
}
|
|
1364
|
-
return
|
|
1446
|
+
return resolved;
|
|
1447
|
+
};
|
|
1448
|
+
var withReadableTextColor = (style) => {
|
|
1449
|
+
if (!style?.backgroundColor || style.color)
|
|
1450
|
+
return style;
|
|
1451
|
+
const background = style.backgroundColor;
|
|
1452
|
+
if (typeof background !== "string")
|
|
1453
|
+
return style;
|
|
1454
|
+
const color = getContrastingTextColor(background);
|
|
1455
|
+
if (!color)
|
|
1456
|
+
return style;
|
|
1457
|
+
return { ...style, color };
|
|
1365
1458
|
};
|
|
1366
1459
|
var hasBorderStyle = (style) => Boolean(style?.borderColor || style?.borderTopColor || style?.borderRightColor || style?.borderBottomColor || style?.borderLeftColor);
|
|
1367
1460
|
var CellComponent = import_react4.default.memo(({
|
|
@@ -1404,7 +1497,7 @@ var CellComponent = import_react4.default.memo(({
|
|
|
1404
1497
|
isSelected,
|
|
1405
1498
|
isBeingEdited: isBeingEdited || false
|
|
1406
1499
|
};
|
|
1407
|
-
const customStyle = customCellStyle?.(cellStyleCallbackData);
|
|
1500
|
+
const customStyle = withReadableTextColor(customCellStyle?.(cellStyleCallbackData));
|
|
1408
1501
|
const canHaveFillHandle = import_selection_manager.useSelectionManager(selectionManager, () => {
|
|
1409
1502
|
return selectionManager.canCellHaveFillHandle({
|
|
1410
1503
|
row: rowIndex,
|
|
@@ -1436,7 +1529,8 @@ var CellComponent = import_react4.default.memo(({
|
|
|
1436
1529
|
top: y,
|
|
1437
1530
|
width: getColumnWidth(col) - 1,
|
|
1438
1531
|
height: getRowHeight(row) - 1,
|
|
1439
|
-
...customStyle
|
|
1532
|
+
...customStyle,
|
|
1533
|
+
...isBeingEdited ? { backgroundColor: undefined, color: undefined } : null
|
|
1440
1534
|
},
|
|
1441
1535
|
children: [
|
|
1442
1536
|
isBeingEdited ? /* @__PURE__ */ jsx_runtime3.jsx("textarea", {
|
|
@@ -1686,6 +1780,7 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
1686
1780
|
const [{ width, height }, containerRef] = useResizeObserver();
|
|
1687
1781
|
const [containerDivRef, setContainerDivRef] = import_react4.useState(null);
|
|
1688
1782
|
const colorScheme = useColorScheme(containerDivRef);
|
|
1783
|
+
const gridLineProbeRef = import_react4.useRef(null);
|
|
1689
1784
|
const selectionManager = import_selection_manager.useInitializeSelectionManager({
|
|
1690
1785
|
getNumCols: () => ({ type: "infinity" }),
|
|
1691
1786
|
getNumRows: () => ({ type: "infinity" }),
|
|
@@ -1879,7 +1974,7 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
1879
1974
|
if (!ctx)
|
|
1880
1975
|
return;
|
|
1881
1976
|
ctx.clearRect(0, 0, width, height);
|
|
1882
|
-
ctx.strokeStyle = resolveGridLineColor(
|
|
1977
|
+
ctx.strokeStyle = resolveGridLineColor(gridLineProbeRef.current, colorScheme);
|
|
1883
1978
|
ctx.lineWidth = 1;
|
|
1884
1979
|
let x = gridDims.headerWidth;
|
|
1885
1980
|
let colIndex = 0;
|
|
@@ -2627,6 +2722,7 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
2627
2722
|
}), [selectionManager]);
|
|
2628
2723
|
return /* @__PURE__ */ jsx_runtime3.jsx("div", {
|
|
2629
2724
|
className: cn("rsp-root", className),
|
|
2725
|
+
"data-rsp-scheme": colorScheme,
|
|
2630
2726
|
style: { position: "relative", ...style },
|
|
2631
2727
|
...containerProps,
|
|
2632
2728
|
children: /* @__PURE__ */ jsx_runtime3.jsx("div", {
|
|
@@ -2642,6 +2738,18 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
2642
2738
|
},
|
|
2643
2739
|
tabIndex: 0,
|
|
2644
2740
|
children: [
|
|
2741
|
+
/* @__PURE__ */ jsx_runtime3.jsx("span", {
|
|
2742
|
+
ref: gridLineProbeRef,
|
|
2743
|
+
"aria-hidden": "true",
|
|
2744
|
+
style: {
|
|
2745
|
+
position: "absolute",
|
|
2746
|
+
width: 0,
|
|
2747
|
+
height: 0,
|
|
2748
|
+
visibility: "hidden",
|
|
2749
|
+
pointerEvents: "none",
|
|
2750
|
+
color: "var(--rsp-gridline)"
|
|
2751
|
+
}
|
|
2752
|
+
}),
|
|
2645
2753
|
/* @__PURE__ */ jsx_runtime3.jsx("canvas", {
|
|
2646
2754
|
ref: canvasRef,
|
|
2647
2755
|
className: "rsp-canvas",
|
|
@@ -2818,7 +2926,15 @@ var Spreadsheet = import_react4.forwardRef(({
|
|
|
2818
2926
|
Spreadsheet.displayName = "Spreadsheet";
|
|
2819
2927
|
// src/workbook/workbook.tsx
|
|
2820
2928
|
var import_formula_engine2 = require("@ricsam/formula-engine");
|
|
2821
|
-
var
|
|
2929
|
+
var import_react6 = __toESM(require("react"));
|
|
2930
|
+
|
|
2931
|
+
// src/utils/use-scheme-root.ts
|
|
2932
|
+
var import_react5 = require("react");
|
|
2933
|
+
function useSchemeRoot() {
|
|
2934
|
+
const [element, setElement] = import_react5.useState(null);
|
|
2935
|
+
const scheme = useColorScheme(element);
|
|
2936
|
+
return { ref: setElement, "data-rsp-scheme": scheme };
|
|
2937
|
+
}
|
|
2822
2938
|
|
|
2823
2939
|
// src/workbook/border-sides.ts
|
|
2824
2940
|
function normalizeBorderSides(sides, defaultAllWhenUnset = false) {
|
|
@@ -3224,8 +3340,8 @@ var MinusIcon = ({ className = "", ...props }) => /* @__PURE__ */ jsx_runtime4.j
|
|
|
3224
3340
|
})
|
|
3225
3341
|
});
|
|
3226
3342
|
function useEngine(engine) {
|
|
3227
|
-
const [state, setState] =
|
|
3228
|
-
|
|
3343
|
+
const [state, setState] = import_react6.useState(() => engine.getState());
|
|
3344
|
+
import_react6.default.useEffect(() => {
|
|
3229
3345
|
return engine.onUpdate(() => {
|
|
3230
3346
|
setState(engine.getState());
|
|
3231
3347
|
});
|
|
@@ -3329,11 +3445,12 @@ function FormulaSheet({
|
|
|
3329
3445
|
showFormulas = false,
|
|
3330
3446
|
...rest
|
|
3331
3447
|
}) {
|
|
3332
|
-
const
|
|
3333
|
-
const
|
|
3448
|
+
const schemeRoot = useSchemeRoot();
|
|
3449
|
+
const [selectedArea, setSelectedArea] = import_react6.useState(null);
|
|
3450
|
+
const clipboardManager = import_react6.default.useMemo(() => controlledClipboardManager ?? new WorkbookClipboardManager(engine), [controlledClipboardManager, engine]);
|
|
3334
3451
|
const state = useEngine(engine);
|
|
3335
3452
|
const sheet = state.workbooks.get(workbookName)?.sheets.get(sheetName);
|
|
3336
|
-
const onCellDataChange =
|
|
3453
|
+
const onCellDataChange = import_react6.useCallback((updatedSpreadsheet) => {
|
|
3337
3454
|
const data = new Map(updatedSpreadsheet);
|
|
3338
3455
|
data.forEach((value, key) => {
|
|
3339
3456
|
if (typeof value === "string") {
|
|
@@ -3349,7 +3466,7 @@ function FormulaSheet({
|
|
|
3349
3466
|
engine.setSheetContent({ sheetName, workbookName }, data);
|
|
3350
3467
|
}, [sheetName, engine, workbookName]);
|
|
3351
3468
|
const passedSelectionEffects = selection?.effects;
|
|
3352
|
-
const selectionManagerEffects =
|
|
3469
|
+
const selectionManagerEffects = import_react6.useCallback((spreadsheetSelectionManager) => {
|
|
3353
3470
|
const convertSmAreaToSpreadsheetRange = (area) => {
|
|
3354
3471
|
const rowEnd = area.end.row.type === "infinity" ? {
|
|
3355
3472
|
type: "infinity",
|
|
@@ -3474,6 +3591,7 @@ function FormulaSheet({
|
|
|
3474
3591
|
if (!sheet) {
|
|
3475
3592
|
return /* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
3476
3593
|
className: "rsp-root rsp-workbook",
|
|
3594
|
+
...schemeRoot,
|
|
3477
3595
|
children: [
|
|
3478
3596
|
toolbar,
|
|
3479
3597
|
/* @__PURE__ */ jsx_runtime4.jsx("div", {
|
|
@@ -3484,6 +3602,7 @@ function FormulaSheet({
|
|
|
3484
3602
|
}
|
|
3485
3603
|
return /* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
3486
3604
|
className: "rsp-root rsp-workbook",
|
|
3605
|
+
...schemeRoot,
|
|
3487
3606
|
children: [
|
|
3488
3607
|
toolbar,
|
|
3489
3608
|
/* @__PURE__ */ jsx_runtime4.jsx("div", {
|
|
@@ -3554,32 +3673,32 @@ function FormulaSheet({
|
|
|
3554
3673
|
const isLastColumn = cell.colIndex === tableInfo.start.colIndex + tableInfo.headers.size - 1;
|
|
3555
3674
|
const isLastRow = tableInfo.endRow.type === "number" ? cell.rowIndex === tableInfo.endRow.value : false;
|
|
3556
3675
|
const style = {
|
|
3557
|
-
border: "1px solid var(--table-border-light)"
|
|
3676
|
+
border: "1px solid var(--rsp-table-border-light)"
|
|
3558
3677
|
};
|
|
3559
3678
|
if (isHeaderRow) {
|
|
3560
|
-
style.backgroundColor = "var(--table-header-bg)";
|
|
3561
|
-
style.color = "var(--table-header-color)";
|
|
3679
|
+
style.backgroundColor = "var(--rsp-table-header-bg)";
|
|
3680
|
+
style.color = "var(--rsp-table-header-color)";
|
|
3562
3681
|
style.fontWeight = "bold";
|
|
3563
|
-
style.borderBottom = "2px solid var(--table-header-border)";
|
|
3682
|
+
style.borderBottom = "2px solid var(--rsp-table-header-border)";
|
|
3564
3683
|
} else {
|
|
3565
3684
|
const dataRowIndex = cell.rowIndex - tableInfo.start.rowIndex - 1;
|
|
3566
3685
|
if (dataRowIndex % 2 === 0) {
|
|
3567
|
-
style.backgroundColor = "var(--table-even-row-bg)";
|
|
3686
|
+
style.backgroundColor = "var(--rsp-table-even-row-bg)";
|
|
3568
3687
|
} else {
|
|
3569
|
-
style.backgroundColor = "var(--table-odd-row-bg)";
|
|
3688
|
+
style.backgroundColor = "var(--rsp-table-odd-row-bg)";
|
|
3570
3689
|
}
|
|
3571
3690
|
}
|
|
3572
3691
|
if (isFirstColumn) {
|
|
3573
|
-
style.borderLeft = "2px solid var(--table-border-color)";
|
|
3692
|
+
style.borderLeft = "2px solid var(--rsp-table-border-color)";
|
|
3574
3693
|
}
|
|
3575
3694
|
if (isLastColumn) {
|
|
3576
|
-
style.borderRight = "2px solid var(--table-border-color)";
|
|
3695
|
+
style.borderRight = "2px solid var(--rsp-table-border-color)";
|
|
3577
3696
|
}
|
|
3578
3697
|
if (isHeaderRow) {
|
|
3579
|
-
style.borderTop = "2px solid var(--table-border-color)";
|
|
3698
|
+
style.borderTop = "2px solid var(--rsp-table-border-color)";
|
|
3580
3699
|
}
|
|
3581
3700
|
if (isLastRow) {
|
|
3582
|
-
style.borderBottom = "2px solid var(--table-border-color)";
|
|
3701
|
+
style.borderBottom = "2px solid var(--rsp-table-border-color)";
|
|
3583
3702
|
}
|
|
3584
3703
|
if (conditionalStyle?.backgroundColor) {
|
|
3585
3704
|
style.backgroundColor = conditionalStyle.backgroundColor;
|
|
@@ -3715,18 +3834,19 @@ function FormulaWorkbook({
|
|
|
3715
3834
|
showFormulas = false,
|
|
3716
3835
|
...rest
|
|
3717
3836
|
}) {
|
|
3837
|
+
const schemeRoot = useSchemeRoot();
|
|
3718
3838
|
const state = useEngine(engine);
|
|
3719
|
-
const [renamingSheet, setRenamingSheet] =
|
|
3720
|
-
const [newSheetName, setNewSheetName] =
|
|
3721
|
-
const [spreadsheetZoom, setSpreadsheetZoom] =
|
|
3722
|
-
const renameCommittedRef =
|
|
3723
|
-
const clipboardManager =
|
|
3839
|
+
const [renamingSheet, setRenamingSheet] = import_react6.useState(null);
|
|
3840
|
+
const [newSheetName, setNewSheetName] = import_react6.useState("");
|
|
3841
|
+
const [spreadsheetZoom, setSpreadsheetZoom] = import_react6.useState(1);
|
|
3842
|
+
const renameCommittedRef = import_react6.useRef(false);
|
|
3843
|
+
const clipboardManager = import_react6.default.useMemo(() => controlledClipboardManager ?? new WorkbookClipboardManager(engine), [controlledClipboardManager, engine]);
|
|
3724
3844
|
const sheetNames = engine.getOrderedSheetNames(workbookName);
|
|
3725
|
-
const [internalActiveSheet, setInternalActiveSheet] =
|
|
3845
|
+
const [internalActiveSheet, setInternalActiveSheet] = import_react6.useState(() => {
|
|
3726
3846
|
return sheetNames[0] || "";
|
|
3727
3847
|
});
|
|
3728
|
-
const isControlledRef =
|
|
3729
|
-
|
|
3848
|
+
const isControlledRef = import_react6.useRef(controlledActiveSheet !== undefined);
|
|
3849
|
+
import_react6.default.useEffect(() => {
|
|
3730
3850
|
const isCurrentlyControlled = controlledActiveSheet !== undefined;
|
|
3731
3851
|
if (isControlledRef.current !== isCurrentlyControlled) {
|
|
3732
3852
|
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.`);
|
|
@@ -3734,7 +3854,7 @@ function FormulaWorkbook({
|
|
|
3734
3854
|
isControlledRef.current = isCurrentlyControlled;
|
|
3735
3855
|
}, [controlledActiveSheet]);
|
|
3736
3856
|
const activeSheet = controlledActiveSheet ?? internalActiveSheet;
|
|
3737
|
-
const handleActiveSheetChange =
|
|
3857
|
+
const handleActiveSheetChange = import_react6.useCallback((sheetName) => {
|
|
3738
3858
|
if (onActiveSheetChange) {
|
|
3739
3859
|
onActiveSheetChange(sheetName);
|
|
3740
3860
|
} else {
|
|
@@ -3745,16 +3865,16 @@ function FormulaWorkbook({
|
|
|
3745
3865
|
const activeSheetSelectedOverlayId = sheetSelectedOverlayIds?.[activeSheet];
|
|
3746
3866
|
const activeSheetColumnWidths = sheetLayouts?.[activeSheet]?.columnWidths;
|
|
3747
3867
|
const activeSheetRowHeights = sheetLayouts?.[activeSheet]?.rowHeights;
|
|
3748
|
-
const handleOverlaySelect =
|
|
3868
|
+
const handleOverlaySelect = import_react6.useCallback((overlayId) => {
|
|
3749
3869
|
onOverlaySelect?.(activeSheet, overlayId);
|
|
3750
3870
|
}, [onOverlaySelect, activeSheet]);
|
|
3751
|
-
const handleOverlayChildrenChange =
|
|
3871
|
+
const handleOverlayChildrenChange = import_react6.useCallback((children) => {
|
|
3752
3872
|
onOverlayChildrenChange?.(activeSheet, children);
|
|
3753
3873
|
}, [onOverlayChildrenChange, activeSheet]);
|
|
3754
|
-
const handleColumnWidthsChange =
|
|
3874
|
+
const handleColumnWidthsChange = import_react6.useCallback((columnWidths) => {
|
|
3755
3875
|
onSheetColumnWidthsChange?.(activeSheet, columnWidths);
|
|
3756
3876
|
}, [activeSheet, onSheetColumnWidthsChange]);
|
|
3757
|
-
const handleRowHeightsChange =
|
|
3877
|
+
const handleRowHeightsChange = import_react6.useCallback((rowHeights) => {
|
|
3758
3878
|
onSheetRowHeightsChange?.(activeSheet, rowHeights);
|
|
3759
3879
|
}, [activeSheet, onSheetRowHeightsChange]);
|
|
3760
3880
|
const addSheet = () => {
|
|
@@ -3821,6 +3941,7 @@ function FormulaWorkbook({
|
|
|
3821
3941
|
};
|
|
3822
3942
|
return /* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
3823
3943
|
className: "rsp-root rsp-workbook",
|
|
3944
|
+
...schemeRoot,
|
|
3824
3945
|
children: [
|
|
3825
3946
|
toolbar,
|
|
3826
3947
|
/* @__PURE__ */ jsx_runtime4.jsxs("div", {
|
|
@@ -4026,9 +4147,9 @@ var DEFAULT_ZOOM = 1;
|
|
|
4026
4147
|
var MIN_ZOOM = 0.5;
|
|
4027
4148
|
var MAX_ZOOM = 3;
|
|
4028
4149
|
// src/utils/use-click-away.ts
|
|
4029
|
-
var
|
|
4150
|
+
var import_react7 = require("react");
|
|
4030
4151
|
var useClickAway = (ref, callback) => {
|
|
4031
|
-
|
|
4152
|
+
import_react7.useEffect(() => {
|
|
4032
4153
|
const handleClickAway = (event) => {
|
|
4033
4154
|
if (ref) {
|
|
4034
4155
|
const away = !ref.contains(event.target);
|
|
@@ -4042,4 +4163,4 @@ var useClickAway = (ref, callback) => {
|
|
|
4042
4163
|
}, [ref, callback]);
|
|
4043
4164
|
};
|
|
4044
4165
|
|
|
4045
|
-
//# debugId=
|
|
4166
|
+
//# debugId=A383A8C557A8A55164756E2164756E21
|