@ricsam/react-spreadsheets 0.0.11 → 0.0.12
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 +26 -0
- package/dist/cjs/lib.cjs +103 -49
- package/dist/cjs/lib.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/lib.mjs +102 -46
- package/dist/mjs/lib.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/spreadsheet/spreadsheet.d.ts +4 -0
- package/package.json +2 -2
package/dist/cjs/package.json
CHANGED
package/dist/mjs/lib.mjs
CHANGED
|
@@ -8,6 +8,8 @@ import React2, {
|
|
|
8
8
|
useCallback as useCallback3,
|
|
9
9
|
useEffect as useEffect3,
|
|
10
10
|
useImperativeHandle,
|
|
11
|
+
useId,
|
|
12
|
+
useLayoutEffect,
|
|
11
13
|
useMemo,
|
|
12
14
|
useRef as useRef3,
|
|
13
15
|
useState as useState4
|
|
@@ -1472,6 +1474,7 @@ var CellComponent = React2.memo(({
|
|
|
1472
1474
|
value,
|
|
1473
1475
|
row,
|
|
1474
1476
|
col,
|
|
1477
|
+
domId,
|
|
1475
1478
|
selectionManager,
|
|
1476
1479
|
cellToPixelBase,
|
|
1477
1480
|
getColumnWidth,
|
|
@@ -1485,11 +1488,11 @@ var CellComponent = React2.memo(({
|
|
|
1485
1488
|
}) => {
|
|
1486
1489
|
const cellRef = useCallback3((el) => {
|
|
1487
1490
|
if (el) {
|
|
1488
|
-
const
|
|
1489
|
-
const
|
|
1491
|
+
const rowIndex = row - 1;
|
|
1492
|
+
const colIndex = columnToIndex(col);
|
|
1490
1493
|
return selectionManager.setupCellElement(el, {
|
|
1491
|
-
row:
|
|
1492
|
-
col:
|
|
1494
|
+
row: rowIndex,
|
|
1495
|
+
col: colIndex
|
|
1493
1496
|
});
|
|
1494
1497
|
}
|
|
1495
1498
|
}, [row, col, selectionManager]);
|
|
@@ -1517,16 +1520,22 @@ var CellComponent = React2.memo(({
|
|
|
1517
1520
|
});
|
|
1518
1521
|
const inputRef = useCallback3((el) => {
|
|
1519
1522
|
if (el) {
|
|
1520
|
-
const
|
|
1521
|
-
const
|
|
1523
|
+
const rowIndex = row - 1;
|
|
1524
|
+
const colIndex = columnToIndex(col);
|
|
1522
1525
|
return selectionManager.setupInputElement(el, {
|
|
1523
|
-
rowIndex
|
|
1524
|
-
colIndex
|
|
1526
|
+
rowIndex,
|
|
1527
|
+
colIndex
|
|
1525
1528
|
});
|
|
1526
1529
|
}
|
|
1527
1530
|
}, [row, col, selectionManager]);
|
|
1528
1531
|
return /* @__PURE__ */ jsxs2("div", {
|
|
1529
1532
|
ref: cellRef,
|
|
1533
|
+
id: domId,
|
|
1534
|
+
role: "gridcell",
|
|
1535
|
+
"aria-rowindex": row + 1,
|
|
1536
|
+
"aria-colindex": colIndex + 2,
|
|
1537
|
+
"aria-selected": isSelected,
|
|
1538
|
+
"data-cell-address": `${col}${row}`,
|
|
1530
1539
|
className: cn("rsp-cell", {
|
|
1531
1540
|
"rsp-cell-multiline": typeof value === "string" && value.includes(`
|
|
1532
1541
|
`),
|
|
@@ -1546,6 +1555,7 @@ var CellComponent = React2.memo(({
|
|
|
1546
1555
|
children: [
|
|
1547
1556
|
isBeingEdited ? /* @__PURE__ */ jsx3("textarea", {
|
|
1548
1557
|
className: "rsp-cell-editor",
|
|
1558
|
+
"aria-label": `Edit ${col}${row}`,
|
|
1549
1559
|
"data-testid": `spreadsheet-cell-input-${col}${row}`,
|
|
1550
1560
|
ref: inputRef,
|
|
1551
1561
|
defaultValue: inputValue?.toString() ?? "",
|
|
@@ -1624,6 +1634,10 @@ var HeaderComponent = React2.memo(({
|
|
|
1624
1634
|
const content = type === "col" ? reverseHeaders ? index + 1 : indexToColumn(index) : reverseHeaders ? rowToLetter(index + 1) : index + 1;
|
|
1625
1635
|
return /* @__PURE__ */ jsxs2("div", {
|
|
1626
1636
|
ref: headerRef,
|
|
1637
|
+
role: type === "col" ? "columnheader" : "rowheader",
|
|
1638
|
+
"aria-colindex": type === "col" ? index + 2 : 1,
|
|
1639
|
+
"aria-rowindex": type === "row" ? index + 2 : 1,
|
|
1640
|
+
"aria-selected": isSelected,
|
|
1627
1641
|
className: cn("rsp-header", `rsp-header-${type}`, {
|
|
1628
1642
|
"rsp-header-selected": isSelected
|
|
1629
1643
|
}),
|
|
@@ -1768,6 +1782,9 @@ var Spreadsheet = forwardRef(({
|
|
|
1768
1782
|
style,
|
|
1769
1783
|
className,
|
|
1770
1784
|
containerProps,
|
|
1785
|
+
"aria-label": ariaLabel = "Spreadsheet",
|
|
1786
|
+
"aria-labelledby": ariaLabelledBy,
|
|
1787
|
+
"aria-describedby": ariaDescribedBy,
|
|
1771
1788
|
cellData: controlledCellData,
|
|
1772
1789
|
onCellDataChange,
|
|
1773
1790
|
onCellDataChangeError,
|
|
@@ -1790,6 +1807,7 @@ var Spreadsheet = forwardRef(({
|
|
|
1790
1807
|
parentSelected = true,
|
|
1791
1808
|
disableClipboard = false
|
|
1792
1809
|
}, ref) => {
|
|
1810
|
+
const gridId = useId();
|
|
1793
1811
|
const [{ width, height }, containerRef] = useResizeObserver();
|
|
1794
1812
|
const [containerDivRef, setContainerDivRef] = useState4(null);
|
|
1795
1813
|
const colorScheme = useColorScheme(containerDivRef);
|
|
@@ -1983,15 +2001,15 @@ var Spreadsheet = forwardRef(({
|
|
|
1983
2001
|
};
|
|
1984
2002
|
const effectsRef = useRef3(effectsRefOb);
|
|
1985
2003
|
effectsRef.current = effectsRefOb;
|
|
1986
|
-
const setupCanvas = useCallback3((canvas,
|
|
2004
|
+
const setupCanvas = useCallback3((canvas, width, height) => {
|
|
1987
2005
|
const ctx = canvas.getContext("2d");
|
|
1988
2006
|
if (!ctx)
|
|
1989
2007
|
return null;
|
|
1990
2008
|
const devicePixelRatio = window.devicePixelRatio || 1;
|
|
1991
|
-
canvas.width =
|
|
1992
|
-
canvas.height =
|
|
1993
|
-
canvas.style.width =
|
|
1994
|
-
canvas.style.height =
|
|
2009
|
+
canvas.width = width * devicePixelRatio;
|
|
2010
|
+
canvas.height = height * devicePixelRatio;
|
|
2011
|
+
canvas.style.width = width + "px";
|
|
2012
|
+
canvas.style.height = height + "px";
|
|
1995
2013
|
ctx.scale(devicePixelRatio, devicePixelRatio);
|
|
1996
2014
|
return ctx;
|
|
1997
2015
|
}, []);
|
|
@@ -2219,36 +2237,36 @@ var Spreadsheet = forwardRef(({
|
|
|
2219
2237
|
return selectionManager.listenToUpdateData((updates) => {
|
|
2220
2238
|
const editingState = selectionManager.isEditing;
|
|
2221
2239
|
try {
|
|
2222
|
-
const { cellData
|
|
2223
|
-
const newData = new Map(
|
|
2240
|
+
const { cellData, onCellDataChange } = effectsRef.current;
|
|
2241
|
+
const newData = new Map(cellData);
|
|
2224
2242
|
updates.forEach(({ value, rowIndex, colIndex }) => {
|
|
2225
2243
|
const key = `${indexToColumn(colIndex)}${rowIndex + 1}`;
|
|
2226
|
-
const
|
|
2244
|
+
const parseValue = effectsRef.current.parseValue;
|
|
2227
2245
|
if (value === "") {
|
|
2228
2246
|
newData.delete(key);
|
|
2229
2247
|
} else {
|
|
2230
2248
|
let parsedValue = value;
|
|
2231
|
-
if (
|
|
2249
|
+
if (parseValue && typeof value === "string") {
|
|
2232
2250
|
const match = key.match(/^([A-Z]+)(\d+)$/);
|
|
2233
2251
|
const col = match?.[1];
|
|
2234
2252
|
const rowText = match?.[2];
|
|
2235
2253
|
if (col && rowText) {
|
|
2236
2254
|
const row = parseInt(rowText, 10);
|
|
2237
|
-
const
|
|
2238
|
-
const
|
|
2239
|
-
parsedValue =
|
|
2255
|
+
const colIndex = columnToIndex(col);
|
|
2256
|
+
const rowIndex = row - 1;
|
|
2257
|
+
parsedValue = parseValue(value, {
|
|
2240
2258
|
id: key,
|
|
2241
2259
|
row,
|
|
2242
2260
|
col,
|
|
2243
|
-
rowIndex
|
|
2244
|
-
colIndex
|
|
2261
|
+
rowIndex,
|
|
2262
|
+
colIndex
|
|
2245
2263
|
});
|
|
2246
2264
|
}
|
|
2247
2265
|
}
|
|
2248
2266
|
newData.set(key, parsedValue);
|
|
2249
2267
|
}
|
|
2250
2268
|
});
|
|
2251
|
-
|
|
2269
|
+
onCellDataChange?.(newData);
|
|
2252
2270
|
setInternalCellData(newData);
|
|
2253
2271
|
} catch (error) {
|
|
2254
2272
|
console.error("Failed to update spreadsheet cell data:", error);
|
|
@@ -2431,13 +2449,13 @@ var Spreadsheet = forwardRef(({
|
|
|
2431
2449
|
const handleColumnResizeDoubleClick = useCallback3((e, col) => {
|
|
2432
2450
|
e.preventDefault();
|
|
2433
2451
|
e.stopPropagation();
|
|
2434
|
-
const { viewport
|
|
2452
|
+
const { viewport, gridDims, height, cellData } = effectsRef.current;
|
|
2435
2453
|
let maxWidth = 50;
|
|
2436
|
-
const startRow = Math.max(0, Math.floor(
|
|
2437
|
-
const endRow = Math.ceil((
|
|
2454
|
+
const startRow = Math.max(0, Math.floor(viewport.scrollY / gridDims.cellHeight));
|
|
2455
|
+
const endRow = Math.ceil((viewport.scrollY + height) / gridDims.cellHeight) + 1;
|
|
2438
2456
|
for (let row = startRow;row <= endRow; row++) {
|
|
2439
2457
|
const cellKey = `${col}${getRowNumber(row)}`;
|
|
2440
|
-
const content =
|
|
2458
|
+
const content = cellData.get(cellKey) ?? "";
|
|
2441
2459
|
if (content) {
|
|
2442
2460
|
const estimatedWidth = String(content).length * 8 + 20;
|
|
2443
2461
|
maxWidth = Math.max(maxWidth, estimatedWidth);
|
|
@@ -2706,8 +2724,8 @@ var Spreadsheet = forwardRef(({
|
|
|
2706
2724
|
return editingCleanup;
|
|
2707
2725
|
}, [selectionManager]);
|
|
2708
2726
|
React2.useEffect(() => {
|
|
2709
|
-
return selectionManager.observeStateChange((state) => state.hasFocus, (
|
|
2710
|
-
if (
|
|
2727
|
+
return selectionManager.observeStateChange((state) => state.hasFocus, (hasFocus) => {
|
|
2728
|
+
if (hasFocus && selectedOverlayId) {
|
|
2711
2729
|
setSelectedOverlay(null);
|
|
2712
2730
|
}
|
|
2713
2731
|
});
|
|
@@ -2810,6 +2828,21 @@ var Spreadsheet = forwardRef(({
|
|
|
2810
2828
|
const visibleCells = React2.useMemo(() => getVisibleCells(), [getVisibleCells]);
|
|
2811
2829
|
const visibleColumnHeaders = React2.useMemo(() => getVisibleColumnHeaders(), [getVisibleColumnHeaders]);
|
|
2812
2830
|
const visibleRowHeaders = React2.useMemo(() => getVisibleRowHeaders(), [getVisibleRowHeaders]);
|
|
2831
|
+
const activeAddress = useSelectionManager(selectionManager, () => {
|
|
2832
|
+
const cell = selectionManager.getTopLeftCellInSelection();
|
|
2833
|
+
return cell ? `${indexToColumn(cell.col)}${cell.row + 1}` : undefined;
|
|
2834
|
+
});
|
|
2835
|
+
const activeCellId = visibleCells.some((cell) => `${cell.col}${cell.row}` === activeAddress) ? `${gridId}-cell-${activeAddress}` : undefined;
|
|
2836
|
+
const accessibilityManager = selectionManager;
|
|
2837
|
+
useLayoutEffect(() => {
|
|
2838
|
+
accessibilityManager.setInputCaptureAccessibility?.({
|
|
2839
|
+
label: `${ariaLabel} keyboard input`,
|
|
2840
|
+
controls: gridId,
|
|
2841
|
+
activeDescendant: activeCellId,
|
|
2842
|
+
describedBy: ariaDescribedBy
|
|
2843
|
+
});
|
|
2844
|
+
return () => accessibilityManager.setInputCaptureAccessibility?.({});
|
|
2845
|
+
}, [accessibilityManager, ariaLabel, ariaDescribedBy, gridId, activeCellId]);
|
|
2813
2846
|
const hasFocus = useSelectionManager(selectionManager, () => selectionManager.hasFocus);
|
|
2814
2847
|
const referenceSelection = useSelectionManager(selectionManager, () => selectionManager.referenceSelection);
|
|
2815
2848
|
const referenceSelectionRect = useMemo(() => {
|
|
@@ -2885,7 +2918,21 @@ var Spreadsheet = forwardRef(({
|
|
|
2885
2918
|
width,
|
|
2886
2919
|
height
|
|
2887
2920
|
},
|
|
2921
|
+
id: gridId,
|
|
2922
|
+
role: "grid",
|
|
2923
|
+
"aria-activedescendant": activeCellId,
|
|
2924
|
+
"aria-label": ariaLabel,
|
|
2925
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2926
|
+
"aria-describedby": ariaDescribedBy,
|
|
2927
|
+
"aria-rowcount": finiteRowCount === undefined ? -1 : finiteRowCount + 1,
|
|
2928
|
+
"aria-colcount": finiteColumnCount === undefined ? -1 : finiteColumnCount + 1,
|
|
2929
|
+
"aria-multiselectable": "true",
|
|
2888
2930
|
tabIndex: 0,
|
|
2931
|
+
onFocus: (event) => {
|
|
2932
|
+
if (event.target === event.currentTarget && !selectionManager.hasFocus) {
|
|
2933
|
+
selectionManager.focus();
|
|
2934
|
+
}
|
|
2935
|
+
},
|
|
2889
2936
|
children: [
|
|
2890
2937
|
/* @__PURE__ */ jsx3("span", {
|
|
2891
2938
|
ref: gridLineProbeRef,
|
|
@@ -2901,12 +2948,15 @@ var Spreadsheet = forwardRef(({
|
|
|
2901
2948
|
}),
|
|
2902
2949
|
/* @__PURE__ */ jsx3("canvas", {
|
|
2903
2950
|
ref: canvasRef,
|
|
2951
|
+
"aria-hidden": "true",
|
|
2904
2952
|
className: "rsp-canvas",
|
|
2905
2953
|
"data-testid": "spreadsheet-canvas",
|
|
2906
2954
|
style: { width, height }
|
|
2907
2955
|
}),
|
|
2908
2956
|
/* @__PURE__ */ jsx3("div", {
|
|
2909
2957
|
className: "rsp-column-headers",
|
|
2958
|
+
role: "row",
|
|
2959
|
+
"aria-rowindex": 1,
|
|
2910
2960
|
"data-testid": "spreadsheet-column-headers",
|
|
2911
2961
|
style: {
|
|
2912
2962
|
left: gridDims.headerWidth,
|
|
@@ -2949,16 +2999,21 @@ var Spreadsheet = forwardRef(({
|
|
|
2949
2999
|
transformOrigin: "0 0"
|
|
2950
3000
|
},
|
|
2951
3001
|
children: visibleRowHeaders.map(({ row, rowIndex }) => {
|
|
2952
|
-
return /* @__PURE__ */ jsx3(
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
3002
|
+
return /* @__PURE__ */ jsx3("div", {
|
|
3003
|
+
role: "row",
|
|
3004
|
+
"aria-rowindex": row + 1,
|
|
3005
|
+
"aria-owns": visibleCells.filter((cell) => cell.row === row).map((cell) => `${gridId}-cell-${cell.col}${cell.row}`).join(" ") || undefined,
|
|
3006
|
+
children: /* @__PURE__ */ jsx3(HeaderComponent, {
|
|
3007
|
+
index: rowIndex,
|
|
3008
|
+
type: "row",
|
|
3009
|
+
selectionManager,
|
|
3010
|
+
getColumnWidth,
|
|
3011
|
+
getRowHeight,
|
|
3012
|
+
handleColumnResizeStart,
|
|
3013
|
+
handleColumnResizeDoubleClick,
|
|
3014
|
+
handleRowResizeStart,
|
|
3015
|
+
handleRowResizeDoubleClick
|
|
3016
|
+
})
|
|
2962
3017
|
}, row);
|
|
2963
3018
|
})
|
|
2964
3019
|
})
|
|
@@ -2981,6 +3036,7 @@ var Spreadsheet = forwardRef(({
|
|
|
2981
3036
|
},
|
|
2982
3037
|
children: [
|
|
2983
3038
|
visibleCells.map((cell) => /* @__PURE__ */ jsx3(CellComponent, {
|
|
3039
|
+
domId: `${gridId}-cell-${cell.col}${cell.row}`,
|
|
2984
3040
|
value: cellData.get(`${cell.col}${cell.row}`) ?? "",
|
|
2985
3041
|
row: cell.row,
|
|
2986
3042
|
col: cell.col,
|
|
@@ -3815,11 +3871,11 @@ function FormulaSheet({
|
|
|
3815
3871
|
});
|
|
3816
3872
|
}
|
|
3817
3873
|
}),
|
|
3818
|
-
spreadsheetSelectionManager.observeStateChange((
|
|
3819
|
-
const currentSelection =
|
|
3874
|
+
spreadsheetSelectionManager.observeStateChange((state) => {
|
|
3875
|
+
const currentSelection = state.selections.length === 1 ? state.selections[0] : undefined;
|
|
3820
3876
|
return currentSelection;
|
|
3821
|
-
}, (
|
|
3822
|
-
setSelectedArea(
|
|
3877
|
+
}, (selection) => {
|
|
3878
|
+
setSelectedArea(selection ?? null);
|
|
3823
3879
|
})
|
|
3824
3880
|
];
|
|
3825
3881
|
const handleUndoRedoKeyDown = (event) => {
|
|
@@ -3935,7 +3991,7 @@ function FormulaSheet({
|
|
|
3935
3991
|
workbookName
|
|
3936
3992
|
});
|
|
3937
3993
|
if (!tableInfo) {
|
|
3938
|
-
const
|
|
3994
|
+
const style = conditionalStyle ? {
|
|
3939
3995
|
...conditionalStyle.backgroundColor && {
|
|
3940
3996
|
backgroundColor: conditionalStyle.backgroundColor
|
|
3941
3997
|
},
|
|
@@ -3957,7 +4013,7 @@ function FormulaSheet({
|
|
|
3957
4013
|
...getBorderCellStyle(conditionalStyle),
|
|
3958
4014
|
...getWrapCellStyle(conditionalStyle)
|
|
3959
4015
|
} : {};
|
|
3960
|
-
return customCellStyle ? customCellStyle(cell,
|
|
4016
|
+
return customCellStyle ? customCellStyle(cell, style) : style;
|
|
3961
4017
|
}
|
|
3962
4018
|
const isHeaderRow = cell.rowIndex === tableInfo.start.rowIndex;
|
|
3963
4019
|
const isFirstColumn = cell.colIndex === tableInfo.start.colIndex;
|
|
@@ -4507,4 +4563,4 @@ export {
|
|
|
4507
4563
|
useResizeObserver
|
|
4508
4564
|
};
|
|
4509
4565
|
|
|
4510
|
-
//# debugId=
|
|
4566
|
+
//# debugId=FA27216279C90A7964756E2164756E21
|