@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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createContext, memo, useCallback, useContext, useEffect, useMemo, useState, useRef, useReducer } from 'react';
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: data ?? createEmptyWorkbook(),
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 { row, col } = parseAddress(editingCell);
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: confirmEdit
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 = rowHeight + s.row * rowHeight;
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 = rowHeight + row * rowHeight;
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
- onChange?.(state.workbook);
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
  ) });