@particle-academy/fancy-sheets 0.1.0 → 0.1.2
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 +392 -0
- package/dist/index.cjs +34 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +35 -13
- package/dist/index.js.map +1 -1
- package/dist/styles.css.map +1 -1
- package/package.json +56 -56
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, memo, useCallback, useContext, useEffect, useMemo, useState,
|
|
1
|
+
import { createContext, memo, useCallback, useContext, useRef, useEffect, useMemo, useState, useReducer } from 'react';
|
|
2
2
|
import { cn } from '@particle-academy/react-fancy';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -576,9 +576,16 @@ function getRecalculationOrder(graph) {
|
|
|
576
576
|
}
|
|
577
577
|
|
|
578
578
|
// src/hooks/use-spreadsheet-store.ts
|
|
579
|
+
function recalculateWorkbook(workbook) {
|
|
580
|
+
return {
|
|
581
|
+
...workbook,
|
|
582
|
+
sheets: workbook.sheets.map(recalculateSheet)
|
|
583
|
+
};
|
|
584
|
+
}
|
|
579
585
|
function createInitialState(data) {
|
|
586
|
+
const workbook = data ?? createEmptyWorkbook();
|
|
580
587
|
return {
|
|
581
|
-
workbook:
|
|
588
|
+
workbook: recalculateWorkbook(workbook),
|
|
582
589
|
selection: { activeCell: "A1", ranges: [{ start: "A1", end: "A1" }] },
|
|
583
590
|
editingCell: null,
|
|
584
591
|
editValue: "",
|
|
@@ -1016,18 +1023,22 @@ function CellEditor() {
|
|
|
1016
1023
|
confirmEdit,
|
|
1017
1024
|
cancelEdit,
|
|
1018
1025
|
getColumnWidth,
|
|
1019
|
-
rowHeight
|
|
1020
|
-
activeSheet
|
|
1026
|
+
rowHeight
|
|
1021
1027
|
} = useSpreadsheet();
|
|
1022
1028
|
const inputRef = useRef(null);
|
|
1029
|
+
const mountedAt = useRef(0);
|
|
1023
1030
|
useEffect(() => {
|
|
1024
1031
|
if (editingCell && inputRef.current) {
|
|
1032
|
+
mountedAt.current = Date.now();
|
|
1025
1033
|
inputRef.current.focus();
|
|
1026
|
-
inputRef.current.select();
|
|
1027
1034
|
}
|
|
1028
1035
|
}, [editingCell]);
|
|
1036
|
+
const handleBlur = useCallback(() => {
|
|
1037
|
+
if (Date.now() - mountedAt.current < 100) return;
|
|
1038
|
+
confirmEdit();
|
|
1039
|
+
}, [confirmEdit]);
|
|
1029
1040
|
if (!editingCell) return null;
|
|
1030
|
-
const {
|
|
1041
|
+
const { col } = parseAddress(editingCell);
|
|
1031
1042
|
const width = getColumnWidth(col);
|
|
1032
1043
|
const handleKeyDown = (e) => {
|
|
1033
1044
|
if (e.key === "Enter") {
|
|
@@ -1051,7 +1062,7 @@ function CellEditor() {
|
|
|
1051
1062
|
value: editValue,
|
|
1052
1063
|
onChange: (e) => updateEdit(e.target.value),
|
|
1053
1064
|
onKeyDown: handleKeyDown,
|
|
1054
|
-
onBlur:
|
|
1065
|
+
onBlur: handleBlur
|
|
1055
1066
|
}
|
|
1056
1067
|
);
|
|
1057
1068
|
}
|
|
@@ -1067,7 +1078,7 @@ function SelectionOverlay() {
|
|
|
1067
1078
|
for (let c = 0; c < s.col; c++) left += getColumnWidth(c);
|
|
1068
1079
|
let width = 0;
|
|
1069
1080
|
for (let c = s.col; c <= e.col; c++) width += getColumnWidth(c);
|
|
1070
|
-
const top =
|
|
1081
|
+
const top = s.row * rowHeight;
|
|
1071
1082
|
const height = (e.row - s.row + 1) * rowHeight;
|
|
1072
1083
|
return { left, top, width, height, isPrimary: i === 0 };
|
|
1073
1084
|
});
|
|
@@ -1223,7 +1234,7 @@ function SpreadsheetGrid({ className }) {
|
|
|
1223
1234
|
const { row, col } = parseAddress(editingCell);
|
|
1224
1235
|
let left = 48;
|
|
1225
1236
|
for (let c = 0; c < col; c++) left += getColumnWidth(c);
|
|
1226
|
-
const top =
|
|
1237
|
+
const top = row * rowHeight;
|
|
1227
1238
|
return { left, top };
|
|
1228
1239
|
})() : null;
|
|
1229
1240
|
return /* @__PURE__ */ jsxs(
|
|
@@ -1231,7 +1242,7 @@ function SpreadsheetGrid({ className }) {
|
|
|
1231
1242
|
{
|
|
1232
1243
|
ref: containerRef,
|
|
1233
1244
|
"data-fancy-sheets-grid": "",
|
|
1234
|
-
className: cn("relative flex-1 overflow-auto bg-white focus:outline-none dark:bg-zinc-900", className),
|
|
1245
|
+
className: cn("relative min-h-0 flex-1 overflow-auto bg-white focus:outline-none dark:bg-zinc-900", className),
|
|
1235
1246
|
tabIndex: 0,
|
|
1236
1247
|
onKeyDown: handleKeyDown,
|
|
1237
1248
|
children: [
|
|
@@ -1462,13 +1473,24 @@ function SpreadsheetRoot({
|
|
|
1462
1473
|
readOnly = false
|
|
1463
1474
|
}) {
|
|
1464
1475
|
const { state, actions } = useSpreadsheetStore(data ?? defaultData);
|
|
1476
|
+
const onChangeRef = useRef(onChange);
|
|
1477
|
+
const isExternalSync = useRef(false);
|
|
1478
|
+
const prevDataRef = useRef(data);
|
|
1479
|
+
onChangeRef.current = onChange;
|
|
1465
1480
|
useEffect(() => {
|
|
1466
|
-
if (data && data !== state.workbook) {
|
|
1481
|
+
if (data && data !== prevDataRef.current && data !== state.workbook) {
|
|
1482
|
+
isExternalSync.current = true;
|
|
1467
1483
|
actions.setWorkbook(data);
|
|
1484
|
+
prevDataRef.current = data;
|
|
1468
1485
|
}
|
|
1469
1486
|
}, [data]);
|
|
1470
1487
|
useEffect(() => {
|
|
1471
|
-
|
|
1488
|
+
if (isExternalSync.current) {
|
|
1489
|
+
isExternalSync.current = false;
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
prevDataRef.current = state.workbook;
|
|
1493
|
+
onChangeRef.current?.(state.workbook);
|
|
1472
1494
|
}, [state.workbook]);
|
|
1473
1495
|
const activeSheet = useMemo(
|
|
1474
1496
|
() => state.workbook.sheets.find((s) => s.id === state.workbook.activeSheetId),
|
|
@@ -1519,7 +1541,7 @@ function SpreadsheetRoot({
|
|
|
1519
1541
|
"div",
|
|
1520
1542
|
{
|
|
1521
1543
|
"data-fancy-sheets": "",
|
|
1522
|
-
className: cn("flex flex-col overflow-hidden", className),
|
|
1544
|
+
className: cn("flex h-full flex-col overflow-hidden", className),
|
|
1523
1545
|
children
|
|
1524
1546
|
}
|
|
1525
1547
|
) });
|