@pixerate/editor-react 0.10.1 → 0.10.3
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/{chunk-UYT5EQU6.js → chunk-H7HCHLZU.js} +6 -3
- package/dist/chunk-H7HCHLZU.js.map +1 -0
- package/dist/image-editor/index.cjs +5 -2
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.js +1 -1
- package/dist/index.cjs +80 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +89 -64
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-UYT5EQU6.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -137,7 +137,8 @@ interface UseHistoryResult extends HistoryState {
|
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* React hook that subscribes to a HistoryManager instance.
|
|
140
|
-
* Accepts an existing HistoryManager or config options to create an instance
|
|
140
|
+
* Accepts an existing HistoryManager or config options to create an instance
|
|
141
|
+
* (options are read on first render only).
|
|
141
142
|
*/
|
|
142
143
|
declare function useHistory(managerOrOptions?: HistoryManager | HistoryManagerOptions): UseHistoryResult;
|
|
143
144
|
|
|
@@ -223,7 +224,7 @@ declare function useSpreadsheetEditor(options?: SpreadsheetControllerOptions): {
|
|
|
223
224
|
registerDataSource: (ds: SpreadsheetDataSource) => void;
|
|
224
225
|
setPrimaryDataSource: (id: string | undefined) => void;
|
|
225
226
|
recalculateAll: () => void;
|
|
226
|
-
exportToTsv: () => string;
|
|
227
|
+
exportToTsv: (range?: CellRange | null) => string;
|
|
227
228
|
importFromTsv: (data: string) => void;
|
|
228
229
|
undo: () => void;
|
|
229
230
|
redo: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -137,7 +137,8 @@ interface UseHistoryResult extends HistoryState {
|
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* React hook that subscribes to a HistoryManager instance.
|
|
140
|
-
* Accepts an existing HistoryManager or config options to create an instance
|
|
140
|
+
* Accepts an existing HistoryManager or config options to create an instance
|
|
141
|
+
* (options are read on first render only).
|
|
141
142
|
*/
|
|
142
143
|
declare function useHistory(managerOrOptions?: HistoryManager | HistoryManagerOptions): UseHistoryResult;
|
|
143
144
|
|
|
@@ -223,7 +224,7 @@ declare function useSpreadsheetEditor(options?: SpreadsheetControllerOptions): {
|
|
|
223
224
|
registerDataSource: (ds: SpreadsheetDataSource) => void;
|
|
224
225
|
setPrimaryDataSource: (id: string | undefined) => void;
|
|
225
226
|
recalculateAll: () => void;
|
|
226
|
-
exportToTsv: () => string;
|
|
227
|
+
exportToTsv: (range?: CellRange | null) => string;
|
|
227
228
|
importFromTsv: (data: string) => void;
|
|
228
229
|
undo: () => void;
|
|
229
230
|
redo: () => void;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ImageEditor,
|
|
3
3
|
useImageEditor
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-H7HCHLZU.js";
|
|
5
5
|
|
|
6
6
|
// src/hooks/usePromptEditor.ts
|
|
7
7
|
import { useMemo, useEffect, useRef } from "react";
|
|
@@ -373,18 +373,20 @@ function useDismissGuard({
|
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
// src/hooks/useHistory.ts
|
|
376
|
-
import { useSyncExternalStore,
|
|
376
|
+
import { useSyncExternalStore, useRef as useRef4, useCallback as useCallback3 } from "react";
|
|
377
377
|
import {
|
|
378
378
|
HistoryManager,
|
|
379
379
|
createHistoryManager
|
|
380
380
|
} from "@pixerate/editor";
|
|
381
381
|
function useHistory(managerOrOptions) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
382
|
+
const ownManagerRef = useRef4(null);
|
|
383
|
+
let manager;
|
|
384
|
+
if (managerOrOptions instanceof HistoryManager) {
|
|
385
|
+
manager = managerOrOptions;
|
|
386
|
+
} else {
|
|
387
|
+
ownManagerRef.current ??= createHistoryManager(managerOrOptions);
|
|
388
|
+
manager = ownManagerRef.current;
|
|
389
|
+
}
|
|
388
390
|
const state = useSyncExternalStore(
|
|
389
391
|
useCallback3(
|
|
390
392
|
(onStoreChange) => manager.subscribe(onStoreChange),
|
|
@@ -485,7 +487,7 @@ var EditorContent = ({
|
|
|
485
487
|
};
|
|
486
488
|
|
|
487
489
|
// src/components/BubbleMenu.tsx
|
|
488
|
-
import { useEffect as useEffect4, useRef as
|
|
490
|
+
import { useEffect as useEffect4, useRef as useRef5, useState as useState3 } from "react";
|
|
489
491
|
import { createPortal } from "react-dom";
|
|
490
492
|
import {
|
|
491
493
|
BubbleMenuPlugin
|
|
@@ -499,7 +501,7 @@ var BubbleMenu = ({
|
|
|
499
501
|
pluginKey = "bubbleMenu",
|
|
500
502
|
updateDelay
|
|
501
503
|
}) => {
|
|
502
|
-
const menuEl =
|
|
504
|
+
const menuEl = useRef5(null);
|
|
503
505
|
const [mounted, setMounted] = useState3(false);
|
|
504
506
|
if (!menuEl.current && typeof document !== "undefined") {
|
|
505
507
|
menuEl.current = document.createElement("div");
|
|
@@ -535,7 +537,7 @@ var BubbleMenu = ({
|
|
|
535
537
|
};
|
|
536
538
|
|
|
537
539
|
// src/components/TemplateRenderer.tsx
|
|
538
|
-
import { useMemo as
|
|
540
|
+
import { useMemo as useMemo2 } from "react";
|
|
539
541
|
import {
|
|
540
542
|
tokenizePrompt as tokenizePrompt2,
|
|
541
543
|
resolveTemplates
|
|
@@ -550,11 +552,11 @@ var TemplateRenderer = ({
|
|
|
550
552
|
onTemplateClick,
|
|
551
553
|
onVariableClick
|
|
552
554
|
}) => {
|
|
553
|
-
const displayText =
|
|
555
|
+
const displayText = useMemo2(() => {
|
|
554
556
|
if (!resolve || templates.length === 0) return content;
|
|
555
557
|
return resolveTemplates(content, templates);
|
|
556
558
|
}, [content, templates, resolve]);
|
|
557
|
-
const tokens =
|
|
559
|
+
const tokens = useMemo2(() => {
|
|
558
560
|
return tokenizePrompt2(displayText);
|
|
559
561
|
}, [displayText]);
|
|
560
562
|
return /* @__PURE__ */ jsx2("div", { className, children: tokens.map((token, index) => {
|
|
@@ -616,41 +618,37 @@ import {
|
|
|
616
618
|
} from "@pixerate/editor";
|
|
617
619
|
|
|
618
620
|
// src/spreadsheet/useSpreadsheetEditor.ts
|
|
619
|
-
import { useState as useState4,
|
|
621
|
+
import { useState as useState4, useRef as useRef6, useCallback as useCallback4 } from "react";
|
|
620
622
|
import {
|
|
621
623
|
SpreadsheetController
|
|
622
624
|
} from "@pixerate/editor";
|
|
623
625
|
function useSpreadsheetEditor(options = {}) {
|
|
624
|
-
const
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
cells: options.document?.cells || {},
|
|
630
|
-
createdAt: options.document?.createdAt || Date.now(),
|
|
631
|
-
updatedAt: options.document?.updatedAt || Date.now()
|
|
632
|
-
}));
|
|
633
|
-
const [activeCell, setActiveCell] = useState4(null);
|
|
634
|
-
const [selectedRange, setSelectedRange] = useState4(null);
|
|
635
|
-
const [editingCell, setEditingCell] = useState4(null);
|
|
636
|
-
const [draftValue, setDraftValue] = useState4("");
|
|
637
|
-
const controller = useMemo4(() => {
|
|
638
|
-
return new SpreadsheetController({
|
|
626
|
+
const optionsRef = useRef6(options);
|
|
627
|
+
optionsRef.current = options;
|
|
628
|
+
const settersRef = useRef6({});
|
|
629
|
+
const [controller] = useState4(
|
|
630
|
+
() => new SpreadsheetController({
|
|
639
631
|
...options,
|
|
640
632
|
onDocumentChange: (updated) => {
|
|
641
|
-
setDoc({ ...updated });
|
|
642
|
-
|
|
633
|
+
settersRef.current.setDoc?.({ ...updated });
|
|
634
|
+
optionsRef.current.onDocumentChange?.(updated);
|
|
643
635
|
},
|
|
644
636
|
onSelectionChange: (active, range) => {
|
|
645
|
-
setActiveCell(active);
|
|
646
|
-
setSelectedRange(range);
|
|
647
|
-
|
|
637
|
+
settersRef.current.setActiveCell?.(active);
|
|
638
|
+
settersRef.current.setSelectedRange?.(range);
|
|
639
|
+
optionsRef.current.onSelectionChange?.(active, range);
|
|
648
640
|
},
|
|
649
641
|
onCellCommit: (rowId, colId, raw, value) => {
|
|
650
|
-
|
|
642
|
+
optionsRef.current.onCellCommit?.(rowId, colId, raw, value);
|
|
651
643
|
}
|
|
652
|
-
})
|
|
653
|
-
|
|
644
|
+
})
|
|
645
|
+
);
|
|
646
|
+
const [doc, setDoc] = useState4(() => ({ ...controller.document }));
|
|
647
|
+
const [activeCell, setActiveCell] = useState4(controller.activeCell);
|
|
648
|
+
const [selectedRange, setSelectedRange] = useState4(controller.selectedRange);
|
|
649
|
+
const [editingCell, setEditingCell] = useState4(null);
|
|
650
|
+
const [draftValue, setDraftValue] = useState4("");
|
|
651
|
+
settersRef.current = { setDoc, setActiveCell, setSelectedRange };
|
|
654
652
|
const setCellValue = useCallback4((rowId, colId, raw) => {
|
|
655
653
|
controller.setCellValue(rowId, colId, raw);
|
|
656
654
|
setDoc({ ...controller.document });
|
|
@@ -768,7 +766,7 @@ function useSpreadsheetEditor(options = {}) {
|
|
|
768
766
|
registerDataSource,
|
|
769
767
|
setPrimaryDataSource,
|
|
770
768
|
recalculateAll,
|
|
771
|
-
exportToTsv: () => controller.exportToTsv(),
|
|
769
|
+
exportToTsv: (range) => controller.exportToTsv(range),
|
|
772
770
|
importFromTsv: (data) => {
|
|
773
771
|
controller.importFromTsv(data);
|
|
774
772
|
setDoc({ ...controller.document });
|
|
@@ -779,7 +777,7 @@ function useSpreadsheetEditor(options = {}) {
|
|
|
779
777
|
}
|
|
780
778
|
|
|
781
779
|
// src/spreadsheet/SpreadsheetEditor.tsx
|
|
782
|
-
import { useRef as
|
|
780
|
+
import { useRef as useRef7, useState as useState5, useMemo as useMemo3, useEffect as useEffect5, useCallback as useCallback5 } from "react";
|
|
783
781
|
import {
|
|
784
782
|
indexToColName
|
|
785
783
|
} from "@pixerate/editor";
|
|
@@ -794,23 +792,42 @@ var SpreadsheetEditor = ({
|
|
|
794
792
|
}) => {
|
|
795
793
|
const defaultState = useSpreadsheetEditor();
|
|
796
794
|
const state = externalState || defaultState;
|
|
797
|
-
const gridRef =
|
|
795
|
+
const gridRef = useRef7(null);
|
|
798
796
|
const [resizingColId, setResizingColId] = useState5(null);
|
|
799
797
|
const [hoveredColId, setHoveredColId] = useState5(null);
|
|
800
798
|
const [resizeStartX, setResizeStartX] = useState5(0);
|
|
801
799
|
const [resizeStartWidth, setResizeStartWidth] = useState5(0);
|
|
802
|
-
const activeRawValue =
|
|
800
|
+
const activeRawValue = useMemo3(() => {
|
|
803
801
|
if (!state.activeCell) return "";
|
|
804
802
|
const row = state.document.rows[state.activeCell.row];
|
|
805
803
|
const col = state.document.columns[state.activeCell.col];
|
|
806
804
|
if (!row || !col) return "";
|
|
807
805
|
return state.getCell(row.id, col.id).raw;
|
|
808
806
|
}, [state.activeCell, state.document]);
|
|
809
|
-
const coordLabel =
|
|
807
|
+
const coordLabel = useMemo3(() => {
|
|
810
808
|
if (!state.activeCell) return "--";
|
|
811
809
|
const colName = indexToColName(state.activeCell.col);
|
|
812
810
|
return `${colName}${state.activeCell.row + 1}`;
|
|
813
811
|
}, [state.activeCell]);
|
|
812
|
+
const [formulaDraft, setFormulaDraft] = useState5(null);
|
|
813
|
+
const activeColumn = state.activeCell ? state.document.columns[state.activeCell.col] : void 0;
|
|
814
|
+
const formulaBarReadOnly = readOnly || !state.activeCell || !!activeColumn?.readOnly;
|
|
815
|
+
useEffect5(() => {
|
|
816
|
+
setFormulaDraft(null);
|
|
817
|
+
}, [state.activeCell?.row, state.activeCell?.col]);
|
|
818
|
+
const commitFormulaBar = () => {
|
|
819
|
+
if (state.editingCell) {
|
|
820
|
+
state.commitEditing();
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
if (formulaDraft === null || !state.activeCell) return;
|
|
824
|
+
const row = state.document.rows[state.activeCell.row];
|
|
825
|
+
const col = state.document.columns[state.activeCell.col];
|
|
826
|
+
if (row && col && !formulaBarReadOnly && formulaDraft !== activeRawValue) {
|
|
827
|
+
state.setCellValue(row.id, col.id, formulaDraft);
|
|
828
|
+
}
|
|
829
|
+
setFormulaDraft(null);
|
|
830
|
+
};
|
|
814
831
|
const handleCellClick = useCallback5((rIdx, cIdx, e) => {
|
|
815
832
|
if (state.editingCell && (state.editingCell.row !== rIdx || state.editingCell.col !== cIdx)) {
|
|
816
833
|
state.commitEditing();
|
|
@@ -869,16 +886,19 @@ var SpreadsheetEditor = ({
|
|
|
869
886
|
e.preventDefault();
|
|
870
887
|
state.setCellValue(row.id, col.id, "");
|
|
871
888
|
}
|
|
872
|
-
} else if ((e.metaKey || e.ctrlKey) && e.key === "z") {
|
|
889
|
+
} else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "z") {
|
|
873
890
|
e.preventDefault();
|
|
874
891
|
if (e.shiftKey) {
|
|
875
892
|
state.redo();
|
|
876
893
|
} else {
|
|
877
894
|
state.undo();
|
|
878
895
|
}
|
|
879
|
-
} else if (
|
|
896
|
+
} else if (e.ctrlKey && !e.metaKey && e.key.toLowerCase() === "y") {
|
|
897
|
+
e.preventDefault();
|
|
898
|
+
state.redo();
|
|
899
|
+
} else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "c") {
|
|
880
900
|
e.preventDefault();
|
|
881
|
-
const tsv = state.exportToTsv();
|
|
901
|
+
const tsv = state.exportToTsv(state.selectedRange);
|
|
882
902
|
navigator.clipboard?.writeText(tsv);
|
|
883
903
|
} else if (!readOnly && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
|
|
884
904
|
const col = state.document.columns[state.activeCell.col];
|
|
@@ -887,6 +907,10 @@ var SpreadsheetEditor = ({
|
|
|
887
907
|
}
|
|
888
908
|
}
|
|
889
909
|
}, [readOnly, state]);
|
|
910
|
+
const stateRef = useRef7(state);
|
|
911
|
+
stateRef.current = state;
|
|
912
|
+
const onColumnResizeRef = useRef7(onColumnResize);
|
|
913
|
+
onColumnResizeRef.current = onColumnResize;
|
|
890
914
|
useEffect5(() => {
|
|
891
915
|
if (!resizingColId) return;
|
|
892
916
|
if (typeof document !== "undefined") {
|
|
@@ -905,7 +929,7 @@ var SpreadsheetEditor = ({
|
|
|
905
929
|
if (rafId === null) {
|
|
906
930
|
rafId = requestAnimationFrame(() => {
|
|
907
931
|
rafId = null;
|
|
908
|
-
|
|
932
|
+
stateRef.current.setColumnWidth(resizingColId, pendingWidth);
|
|
909
933
|
});
|
|
910
934
|
}
|
|
911
935
|
};
|
|
@@ -915,11 +939,8 @@ var SpreadsheetEditor = ({
|
|
|
915
939
|
rafId = null;
|
|
916
940
|
}
|
|
917
941
|
if (hasDragged) {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
if (col && onColumnResize) {
|
|
921
|
-
onColumnResize(col.id, col.width || pendingWidth);
|
|
922
|
-
}
|
|
942
|
+
stateRef.current.setColumnWidth(resizingColId, pendingWidth);
|
|
943
|
+
onColumnResizeRef.current?.(resizingColId, pendingWidth);
|
|
923
944
|
}
|
|
924
945
|
setResizingColId(null);
|
|
925
946
|
if (typeof document !== "undefined") {
|
|
@@ -940,7 +961,7 @@ var SpreadsheetEditor = ({
|
|
|
940
961
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
941
962
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
942
963
|
};
|
|
943
|
-
}, [resizingColId, resizeStartX, resizeStartWidth
|
|
964
|
+
}, [resizingColId, resizeStartX, resizeStartWidth]);
|
|
944
965
|
const measureElementContentWidth = useCallback5((el, container) => {
|
|
945
966
|
if (typeof document === "undefined") return 0;
|
|
946
967
|
let maxW = el.scrollWidth || 0;
|
|
@@ -1072,25 +1093,29 @@ var SpreadsheetEditor = ({
|
|
|
1072
1093
|
type: "text",
|
|
1073
1094
|
className: "flex-1 bg-transparent px-2 py-0.5 outline-none font-sans text-xs text-foreground placeholder:text-muted-foreground/60 focus:bg-background focus:ring-1 focus:ring-primary rounded",
|
|
1074
1095
|
placeholder: "Enter a value or formula (e.g. =SUM(A1:A5))",
|
|
1075
|
-
|
|
1096
|
+
"aria-label": "Formula bar",
|
|
1097
|
+
readOnly: formulaBarReadOnly,
|
|
1098
|
+
value: state.editingCell ? state.draftValue : formulaDraft ?? activeRawValue,
|
|
1099
|
+
onFocus: () => {
|
|
1100
|
+
if (!state.editingCell) setFormulaDraft(activeRawValue);
|
|
1101
|
+
},
|
|
1076
1102
|
onChange: (e) => {
|
|
1077
|
-
if (state.
|
|
1103
|
+
if (state.editingCell) {
|
|
1078
1104
|
state.setDraftValue(e.target.value);
|
|
1105
|
+
} else if (state.activeCell) {
|
|
1106
|
+
setFormulaDraft(e.target.value);
|
|
1079
1107
|
}
|
|
1080
1108
|
},
|
|
1109
|
+
onBlur: () => commitFormulaBar(),
|
|
1081
1110
|
onKeyDown: (e) => {
|
|
1111
|
+
e.stopPropagation();
|
|
1082
1112
|
if (e.key === "Enter") {
|
|
1083
1113
|
e.preventDefault();
|
|
1084
|
-
|
|
1085
|
-
const row = state.document.rows[state.activeCell.row];
|
|
1086
|
-
const col = state.document.columns[state.activeCell.col];
|
|
1087
|
-
if (row && col) {
|
|
1088
|
-
state.setCellValue(row.id, col.id, e.target.value);
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1114
|
+
commitFormulaBar();
|
|
1091
1115
|
} else if (e.key === "Escape") {
|
|
1092
1116
|
e.preventDefault();
|
|
1093
|
-
|
|
1117
|
+
setFormulaDraft(null);
|
|
1118
|
+
if (state.editingCell) state.cancelEditing();
|
|
1094
1119
|
}
|
|
1095
1120
|
}
|
|
1096
1121
|
}
|
|
@@ -1216,7 +1241,7 @@ var SpreadsheetEditor = ({
|
|
|
1216
1241
|
};
|
|
1217
1242
|
|
|
1218
1243
|
// src/slots.tsx
|
|
1219
|
-
import { createContext, useContext, useMemo as
|
|
1244
|
+
import { createContext, useContext, useMemo as useMemo4 } from "react";
|
|
1220
1245
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1221
1246
|
var defaultSlots = {
|
|
1222
1247
|
Button: (props) => /* @__PURE__ */ jsx4(
|
|
@@ -1240,7 +1265,7 @@ var defaultSlots = {
|
|
|
1240
1265
|
};
|
|
1241
1266
|
var EditorSlotsContext = createContext(defaultSlots);
|
|
1242
1267
|
function EditorSlotsProvider({ slots, children }) {
|
|
1243
|
-
const mergedSlots =
|
|
1268
|
+
const mergedSlots = useMemo4(() => ({ ...defaultSlots, ...slots }), [slots]);
|
|
1244
1269
|
return /* @__PURE__ */ jsx4(EditorSlotsContext.Provider, { value: mergedSlots, children });
|
|
1245
1270
|
}
|
|
1246
1271
|
function useEditorSlots() {
|