@pixerate/editor-react 0.2.4 → 0.3.0

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.d.cts CHANGED
@@ -1,9 +1,11 @@
1
1
  import * as _tiptap_core from '@tiptap/core';
2
2
  import { Editor } from '@tiptap/core';
3
- import { Template, ColorGradient, RichTextPresetOptions } from '@pixerate/editor';
3
+ import * as _pixerate_editor from '@pixerate/editor';
4
+ import { Template, ColorGradient, RichTextPresetOptions, SpreadsheetControllerOptions, SpreadsheetDocument, CellCoordinate, CellRange, SpreadsheetController, SpreadsheetColumn, SpreadsheetRow, SpreadsheetDataSource, CellData } from '@pixerate/editor';
4
5
  export { ColorGradient, RichTextPresetOptions, Template, TemplateVersion, Token, TokenType } from '@pixerate/editor';
5
6
  import { UseEditorOptions, EditorContentProps as EditorContentProps$1 } from '@tiptap/react';
6
- import React from 'react';
7
+ import * as React from 'react';
8
+ import React__default from 'react';
7
9
  import { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu';
8
10
 
9
11
  interface UsePromptEditorProps {
@@ -61,18 +63,18 @@ declare function useEditor(options?: UseRichEditorProps): _tiptap_core.Editor |
61
63
  interface EditorContentProps extends EditorContentProps$1 {
62
64
  className?: string;
63
65
  }
64
- declare const EditorContent: React.FC<EditorContentProps>;
66
+ declare const EditorContent: React__default.FC<EditorContentProps>;
65
67
 
66
68
  interface BubbleMenuProps {
67
69
  editor: Editor | null;
68
70
  className?: string;
69
- children: React.ReactNode;
71
+ children: React__default.ReactNode;
70
72
  tippyOptions?: BubbleMenuPluginProps["tippyOptions"];
71
73
  shouldShow?: BubbleMenuPluginProps["shouldShow"];
72
74
  pluginKey?: BubbleMenuPluginProps["pluginKey"];
73
75
  updateDelay?: BubbleMenuPluginProps["updateDelay"];
74
76
  }
75
- declare const BubbleMenu: React.FC<BubbleMenuProps>;
77
+ declare const BubbleMenu: React__default.FC<BubbleMenuProps>;
76
78
 
77
79
  interface TemplateRendererProps {
78
80
  /** Raw prompt or text string to render */
@@ -90,6 +92,49 @@ interface TemplateRendererProps {
90
92
  /** Click callback for variable badges */
91
93
  onVariableClick?: (variableName: string) => void;
92
94
  }
93
- declare const TemplateRenderer: React.FC<TemplateRendererProps>;
95
+ declare const TemplateRenderer: React__default.FC<TemplateRendererProps>;
94
96
 
95
- export { BubbleMenu, type BubbleMenuProps, EditorContent, type EditorContentProps, TemplateRenderer, type TemplateRendererProps, type UsePromptEditorProps, type UseRichEditorProps, useEditor, usePromptEditor };
97
+ declare function useSpreadsheetEditor(options?: SpreadsheetControllerOptions): {
98
+ document: SpreadsheetDocument;
99
+ activeCell: CellCoordinate | null;
100
+ selectedRange: CellRange | null;
101
+ editingCell: CellCoordinate | null;
102
+ draftValue: string;
103
+ setDraftValue: React.Dispatch<React.SetStateAction<string>>;
104
+ controller: SpreadsheetController;
105
+ getCell: (rowId: string, colId: string) => _pixerate_editor.CellData;
106
+ setCellValue: (rowId: string, colId: string, raw: string) => void;
107
+ selectCell: (row: number, col: number, extendSelection?: boolean) => void;
108
+ selectRange: (range: CellRange) => void;
109
+ startEditing: (row?: number, col?: number, initialVal?: string) => void;
110
+ commitEditing: (val?: string) => void;
111
+ cancelEditing: () => void;
112
+ moveCursor: (dir: "up" | "down" | "left" | "right", extend?: boolean) => void;
113
+ insertColumn: (index: number, config?: Partial<SpreadsheetColumn>) => void;
114
+ deleteColumn: (colId: string) => void;
115
+ insertRow: (index: number, config?: Partial<SpreadsheetRow>) => void;
116
+ deleteRow: (rowId: string) => void;
117
+ setColumnWidth: (colId: string, width: number) => void;
118
+ registerDataSource: (ds: SpreadsheetDataSource) => void;
119
+ setPrimaryDataSource: (id: string | undefined) => void;
120
+ recalculateAll: () => void;
121
+ exportToTsv: () => string;
122
+ importFromTsv: (data: string) => void;
123
+ undo: () => void;
124
+ redo: () => void;
125
+ };
126
+
127
+ interface SpreadsheetEditorProps {
128
+ state?: ReturnType<typeof useSpreadsheetEditor>;
129
+ readOnly?: boolean;
130
+ customCellRenderer?: (props: {
131
+ row: SpreadsheetRow;
132
+ col: SpreadsheetColumn;
133
+ cell: CellData;
134
+ }) => React__default.ReactNode;
135
+ onAddColumnClick?: () => void;
136
+ onColumnHeaderClick?: (col: SpreadsheetColumn) => void;
137
+ }
138
+ declare const SpreadsheetEditor: React__default.FC<SpreadsheetEditorProps>;
139
+
140
+ export { BubbleMenu, type BubbleMenuProps, EditorContent, type EditorContentProps, SpreadsheetEditor, type SpreadsheetEditorProps, TemplateRenderer, type TemplateRendererProps, type UsePromptEditorProps, type UseRichEditorProps, useEditor, usePromptEditor, useSpreadsheetEditor };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import * as _tiptap_core from '@tiptap/core';
2
2
  import { Editor } from '@tiptap/core';
3
- import { Template, ColorGradient, RichTextPresetOptions } from '@pixerate/editor';
3
+ import * as _pixerate_editor from '@pixerate/editor';
4
+ import { Template, ColorGradient, RichTextPresetOptions, SpreadsheetControllerOptions, SpreadsheetDocument, CellCoordinate, CellRange, SpreadsheetController, SpreadsheetColumn, SpreadsheetRow, SpreadsheetDataSource, CellData } from '@pixerate/editor';
4
5
  export { ColorGradient, RichTextPresetOptions, Template, TemplateVersion, Token, TokenType } from '@pixerate/editor';
5
6
  import { UseEditorOptions, EditorContentProps as EditorContentProps$1 } from '@tiptap/react';
6
- import React from 'react';
7
+ import * as React from 'react';
8
+ import React__default from 'react';
7
9
  import { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu';
8
10
 
9
11
  interface UsePromptEditorProps {
@@ -61,18 +63,18 @@ declare function useEditor(options?: UseRichEditorProps): _tiptap_core.Editor |
61
63
  interface EditorContentProps extends EditorContentProps$1 {
62
64
  className?: string;
63
65
  }
64
- declare const EditorContent: React.FC<EditorContentProps>;
66
+ declare const EditorContent: React__default.FC<EditorContentProps>;
65
67
 
66
68
  interface BubbleMenuProps {
67
69
  editor: Editor | null;
68
70
  className?: string;
69
- children: React.ReactNode;
71
+ children: React__default.ReactNode;
70
72
  tippyOptions?: BubbleMenuPluginProps["tippyOptions"];
71
73
  shouldShow?: BubbleMenuPluginProps["shouldShow"];
72
74
  pluginKey?: BubbleMenuPluginProps["pluginKey"];
73
75
  updateDelay?: BubbleMenuPluginProps["updateDelay"];
74
76
  }
75
- declare const BubbleMenu: React.FC<BubbleMenuProps>;
77
+ declare const BubbleMenu: React__default.FC<BubbleMenuProps>;
76
78
 
77
79
  interface TemplateRendererProps {
78
80
  /** Raw prompt or text string to render */
@@ -90,6 +92,49 @@ interface TemplateRendererProps {
90
92
  /** Click callback for variable badges */
91
93
  onVariableClick?: (variableName: string) => void;
92
94
  }
93
- declare const TemplateRenderer: React.FC<TemplateRendererProps>;
95
+ declare const TemplateRenderer: React__default.FC<TemplateRendererProps>;
94
96
 
95
- export { BubbleMenu, type BubbleMenuProps, EditorContent, type EditorContentProps, TemplateRenderer, type TemplateRendererProps, type UsePromptEditorProps, type UseRichEditorProps, useEditor, usePromptEditor };
97
+ declare function useSpreadsheetEditor(options?: SpreadsheetControllerOptions): {
98
+ document: SpreadsheetDocument;
99
+ activeCell: CellCoordinate | null;
100
+ selectedRange: CellRange | null;
101
+ editingCell: CellCoordinate | null;
102
+ draftValue: string;
103
+ setDraftValue: React.Dispatch<React.SetStateAction<string>>;
104
+ controller: SpreadsheetController;
105
+ getCell: (rowId: string, colId: string) => _pixerate_editor.CellData;
106
+ setCellValue: (rowId: string, colId: string, raw: string) => void;
107
+ selectCell: (row: number, col: number, extendSelection?: boolean) => void;
108
+ selectRange: (range: CellRange) => void;
109
+ startEditing: (row?: number, col?: number, initialVal?: string) => void;
110
+ commitEditing: (val?: string) => void;
111
+ cancelEditing: () => void;
112
+ moveCursor: (dir: "up" | "down" | "left" | "right", extend?: boolean) => void;
113
+ insertColumn: (index: number, config?: Partial<SpreadsheetColumn>) => void;
114
+ deleteColumn: (colId: string) => void;
115
+ insertRow: (index: number, config?: Partial<SpreadsheetRow>) => void;
116
+ deleteRow: (rowId: string) => void;
117
+ setColumnWidth: (colId: string, width: number) => void;
118
+ registerDataSource: (ds: SpreadsheetDataSource) => void;
119
+ setPrimaryDataSource: (id: string | undefined) => void;
120
+ recalculateAll: () => void;
121
+ exportToTsv: () => string;
122
+ importFromTsv: (data: string) => void;
123
+ undo: () => void;
124
+ redo: () => void;
125
+ };
126
+
127
+ interface SpreadsheetEditorProps {
128
+ state?: ReturnType<typeof useSpreadsheetEditor>;
129
+ readOnly?: boolean;
130
+ customCellRenderer?: (props: {
131
+ row: SpreadsheetRow;
132
+ col: SpreadsheetColumn;
133
+ cell: CellData;
134
+ }) => React__default.ReactNode;
135
+ onAddColumnClick?: () => void;
136
+ onColumnHeaderClick?: (col: SpreadsheetColumn) => void;
137
+ }
138
+ declare const SpreadsheetEditor: React__default.FC<SpreadsheetEditorProps>;
139
+
140
+ export { BubbleMenu, type BubbleMenuProps, EditorContent, type EditorContentProps, SpreadsheetEditor, type SpreadsheetEditorProps, TemplateRenderer, type TemplateRendererProps, type UsePromptEditorProps, type UseRichEditorProps, useEditor, usePromptEditor, useSpreadsheetEditor };
package/dist/index.js CHANGED
@@ -361,11 +361,417 @@ var TemplateRenderer = ({
361
361
  return /* @__PURE__ */ jsx2("span", { children: token.value }, index);
362
362
  }) });
363
363
  };
364
+
365
+ // src/spreadsheet/useSpreadsheetEditor.ts
366
+ import { useState as useState2, useMemo as useMemo3, useCallback } from "react";
367
+ import {
368
+ SpreadsheetController
369
+ } from "@pixerate/editor";
370
+ function useSpreadsheetEditor(options = {}) {
371
+ const [doc, setDoc] = useState2(() => ({
372
+ id: options.document?.id || `sheet_${Date.now()}`,
373
+ name: options.document?.name || "Sheet 1",
374
+ columns: options.document?.columns || [],
375
+ rows: options.document?.rows || [],
376
+ cells: options.document?.cells || {},
377
+ createdAt: options.document?.createdAt || Date.now(),
378
+ updatedAt: options.document?.updatedAt || Date.now()
379
+ }));
380
+ const [activeCell, setActiveCell] = useState2(null);
381
+ const [selectedRange, setSelectedRange] = useState2(null);
382
+ const [editingCell, setEditingCell] = useState2(null);
383
+ const [draftValue, setDraftValue] = useState2("");
384
+ const controller = useMemo3(() => {
385
+ return new SpreadsheetController({
386
+ ...options,
387
+ onDocumentChange: (updated) => {
388
+ setDoc({ ...updated });
389
+ options.onDocumentChange?.(updated);
390
+ },
391
+ onSelectionChange: (active, range) => {
392
+ setActiveCell(active);
393
+ setSelectedRange(range);
394
+ options.onSelectionChange?.(active, range);
395
+ },
396
+ onCellCommit: (rowId, colId, raw, value) => {
397
+ options.onCellCommit?.(rowId, colId, raw, value);
398
+ }
399
+ });
400
+ }, []);
401
+ const setCellValue = useCallback((rowId, colId, raw) => {
402
+ controller.setCellValue(rowId, colId, raw);
403
+ setDoc({ ...controller.document });
404
+ }, [controller]);
405
+ const selectCell = useCallback((row, col, extendSelection = false) => {
406
+ controller.selectCell(row, col, extendSelection);
407
+ setActiveCell(controller.activeCell);
408
+ setSelectedRange(controller.selectedRange);
409
+ }, [controller]);
410
+ const selectRange = useCallback((range) => {
411
+ controller.selectRange(range);
412
+ setSelectedRange(controller.selectedRange);
413
+ }, [controller]);
414
+ const startEditing = useCallback((row, col, initialVal) => {
415
+ controller.startEditing(row, col, initialVal);
416
+ setActiveCell(controller.activeCell);
417
+ setEditingCell(controller.editingCell);
418
+ setDraftValue(controller.draftValue);
419
+ }, [controller]);
420
+ const commitEditing = useCallback((val) => {
421
+ controller.commitEditing(val);
422
+ setEditingCell(null);
423
+ setDraftValue("");
424
+ setDoc({ ...controller.document });
425
+ }, [controller]);
426
+ const cancelEditing = useCallback(() => {
427
+ controller.cancelEditing();
428
+ setEditingCell(null);
429
+ setDraftValue("");
430
+ }, [controller]);
431
+ const moveCursor = useCallback((dir, extend = false) => {
432
+ controller.moveCursor(dir, extend);
433
+ setActiveCell(controller.activeCell);
434
+ setSelectedRange(controller.selectedRange);
435
+ }, [controller]);
436
+ const insertColumn = useCallback((index, config) => {
437
+ controller.insertColumn(index, config);
438
+ setDoc({ ...controller.document });
439
+ }, [controller]);
440
+ const deleteColumn = useCallback((colId) => {
441
+ controller.deleteColumn(colId);
442
+ setDoc({ ...controller.document });
443
+ }, [controller]);
444
+ const insertRow = useCallback((index, config) => {
445
+ controller.insertRow(index, config);
446
+ setDoc({ ...controller.document });
447
+ }, [controller]);
448
+ const deleteRow = useCallback((rowId) => {
449
+ controller.deleteRow(rowId);
450
+ setDoc({ ...controller.document });
451
+ }, [controller]);
452
+ const setColumnWidth = useCallback((colId, width) => {
453
+ controller.setColumnWidth(colId, width);
454
+ setDoc({ ...controller.document });
455
+ }, [controller]);
456
+ const registerDataSource = useCallback((ds) => {
457
+ controller.registerDataSource(ds);
458
+ setDoc({ ...controller.document });
459
+ }, [controller]);
460
+ const setPrimaryDataSource = useCallback((id) => {
461
+ controller.setPrimaryDataSource(id);
462
+ setDoc({ ...controller.document });
463
+ }, [controller]);
464
+ const recalculateAll = useCallback(() => {
465
+ controller.recalculateAll();
466
+ setDoc({ ...controller.document });
467
+ }, [controller]);
468
+ const undo = useCallback(() => {
469
+ controller.undo();
470
+ setDoc({ ...controller.document });
471
+ }, [controller]);
472
+ const redo = useCallback(() => {
473
+ controller.redo();
474
+ setDoc({ ...controller.document });
475
+ }, [controller]);
476
+ return {
477
+ document: doc,
478
+ activeCell,
479
+ selectedRange,
480
+ editingCell,
481
+ draftValue,
482
+ setDraftValue,
483
+ controller,
484
+ getCell: (rowId, colId) => controller.getCell(rowId, colId),
485
+ setCellValue,
486
+ selectCell,
487
+ selectRange,
488
+ startEditing,
489
+ commitEditing,
490
+ cancelEditing,
491
+ moveCursor,
492
+ insertColumn,
493
+ deleteColumn,
494
+ insertRow,
495
+ deleteRow,
496
+ setColumnWidth,
497
+ registerDataSource,
498
+ setPrimaryDataSource,
499
+ recalculateAll,
500
+ exportToTsv: () => controller.exportToTsv(),
501
+ importFromTsv: (data) => {
502
+ controller.importFromTsv(data);
503
+ setDoc({ ...controller.document });
504
+ },
505
+ undo,
506
+ redo
507
+ };
508
+ }
509
+
510
+ // src/spreadsheet/SpreadsheetEditor.tsx
511
+ import { useState as useState3, useMemo as useMemo4, useEffect as useEffect3, useCallback as useCallback2 } from "react";
512
+ import {
513
+ indexToColName
514
+ } from "@pixerate/editor";
515
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
516
+ var SpreadsheetEditor = ({
517
+ state: externalState,
518
+ readOnly = false,
519
+ customCellRenderer,
520
+ onAddColumnClick,
521
+ onColumnHeaderClick
522
+ }) => {
523
+ const defaultState = useSpreadsheetEditor();
524
+ const state = externalState || defaultState;
525
+ const [resizingColId, setResizingColId] = useState3(null);
526
+ const [resizeStartX, setResizeStartX] = useState3(0);
527
+ const [resizeStartWidth, setResizeStartWidth] = useState3(0);
528
+ const activeRawValue = useMemo4(() => {
529
+ if (!state.activeCell) return "";
530
+ const row = state.document.rows[state.activeCell.row];
531
+ const col = state.document.columns[state.activeCell.col];
532
+ if (!row || !col) return "";
533
+ return state.getCell(row.id, col.id).raw;
534
+ }, [state.activeCell, state.document]);
535
+ const coordLabel = useMemo4(() => {
536
+ if (!state.activeCell) return "--";
537
+ const colName = indexToColName(state.activeCell.col);
538
+ return `${colName}${state.activeCell.row + 1}`;
539
+ }, [state.activeCell]);
540
+ const handleCellClick = useCallback2((rIdx, cIdx, e) => {
541
+ if (state.editingCell && (state.editingCell.row !== rIdx || state.editingCell.col !== cIdx)) {
542
+ state.commitEditing();
543
+ }
544
+ state.selectCell(rIdx, cIdx, e.shiftKey);
545
+ }, [state]);
546
+ const handleCellDblClick = useCallback2((rIdx, cIdx) => {
547
+ if (readOnly) return;
548
+ const col = state.document.columns[cIdx];
549
+ if (col?.readOnly) return;
550
+ state.startEditing(rIdx, cIdx);
551
+ }, [readOnly, state]);
552
+ const handleKeyDown = useCallback2((e) => {
553
+ if (state.editingCell) {
554
+ if (e.key === "Enter") {
555
+ e.preventDefault();
556
+ state.commitEditing();
557
+ state.moveCursor("down");
558
+ } else if (e.key === "Escape") {
559
+ e.preventDefault();
560
+ state.cancelEditing();
561
+ } else if (e.key === "Tab") {
562
+ e.preventDefault();
563
+ state.commitEditing();
564
+ state.moveCursor(e.shiftKey ? "left" : "right");
565
+ }
566
+ return;
567
+ }
568
+ if (!state.activeCell) return;
569
+ if (e.key === "ArrowUp") {
570
+ e.preventDefault();
571
+ state.moveCursor("up", e.shiftKey);
572
+ } else if (e.key === "ArrowDown") {
573
+ e.preventDefault();
574
+ state.moveCursor("down", e.shiftKey);
575
+ } else if (e.key === "ArrowLeft") {
576
+ e.preventDefault();
577
+ state.moveCursor("left", e.shiftKey);
578
+ } else if (e.key === "ArrowRight") {
579
+ e.preventDefault();
580
+ state.moveCursor("right", e.shiftKey);
581
+ } else if (e.key === "Tab") {
582
+ e.preventDefault();
583
+ state.moveCursor(e.shiftKey ? "left" : "right");
584
+ } else if (e.key === "Enter") {
585
+ e.preventDefault();
586
+ const col = state.document.columns[state.activeCell.col];
587
+ if (!readOnly && !col?.readOnly) {
588
+ state.startEditing();
589
+ }
590
+ } else if (e.key === "Backspace" || e.key === "Delete") {
591
+ if (readOnly) return;
592
+ const row = state.document.rows[state.activeCell.row];
593
+ const col = state.document.columns[state.activeCell.col];
594
+ if (row && col && !col.readOnly) {
595
+ e.preventDefault();
596
+ state.setCellValue(row.id, col.id, "");
597
+ }
598
+ } else if ((e.metaKey || e.ctrlKey) && e.key === "z") {
599
+ e.preventDefault();
600
+ if (e.shiftKey) {
601
+ state.redo();
602
+ } else {
603
+ state.undo();
604
+ }
605
+ } else if ((e.metaKey || e.ctrlKey) && e.key === "c") {
606
+ e.preventDefault();
607
+ const tsv = state.exportToTsv();
608
+ navigator.clipboard?.writeText(tsv);
609
+ } else if (!readOnly && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {
610
+ const col = state.document.columns[state.activeCell.col];
611
+ if (!col?.readOnly) {
612
+ state.startEditing(state.activeCell.row, state.activeCell.col, e.key);
613
+ }
614
+ }
615
+ }, [readOnly, state]);
616
+ useEffect3(() => {
617
+ if (!resizingColId) return;
618
+ const handleMouseMove = (e) => {
619
+ const delta = e.clientX - resizeStartX;
620
+ state.setColumnWidth(resizingColId, Math.max(60, resizeStartWidth + delta));
621
+ };
622
+ const handleMouseUp = () => {
623
+ setResizingColId(null);
624
+ };
625
+ window.addEventListener("mousemove", handleMouseMove);
626
+ window.addEventListener("mouseup", handleMouseUp);
627
+ return () => {
628
+ window.removeEventListener("mousemove", handleMouseMove);
629
+ window.removeEventListener("mouseup", handleMouseUp);
630
+ };
631
+ }, [resizingColId, resizeStartX, resizeStartWidth, state]);
632
+ const isCellSelected = (rIdx, cIdx) => {
633
+ if (!state.selectedRange) return false;
634
+ const minR = Math.min(state.selectedRange.startRow, state.selectedRange.endRow);
635
+ const maxR = Math.max(state.selectedRange.startRow, state.selectedRange.endRow);
636
+ const minC = Math.min(state.selectedRange.startCol, state.selectedRange.endCol);
637
+ const maxC = Math.max(state.selectedRange.startCol, state.selectedRange.endCol);
638
+ return rIdx >= minR && rIdx <= maxR && cIdx >= minC && cIdx <= maxC;
639
+ };
640
+ const isActiveCell = (rIdx, cIdx) => {
641
+ return state.activeCell?.row === rIdx && state.activeCell?.col === cIdx;
642
+ };
643
+ return /* @__PURE__ */ jsxs(
644
+ "div",
645
+ {
646
+ className: "flex flex-col h-full w-full overflow-hidden border border-border bg-background select-none outline-none text-foreground font-sans text-xs",
647
+ tabIndex: 0,
648
+ onKeyDown: handleKeyDown,
649
+ role: "grid",
650
+ "aria-label": "Spreadsheet",
651
+ children: [
652
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border bg-muted/20 px-3 py-1.5 text-xs font-mono", children: [
653
+ /* @__PURE__ */ jsx3("div", { className: "flex h-6 min-w-[3rem] items-center justify-center rounded border border-border bg-background px-1.5 font-semibold text-foreground", children: coordLabel }),
654
+ /* @__PURE__ */ jsx3("div", { className: "flex items-center text-muted-foreground select-none", children: /* @__PURE__ */ jsx3("span", { className: "italic font-serif font-bold text-sm text-primary", children: "fx" }) }),
655
+ /* @__PURE__ */ jsx3(
656
+ "input",
657
+ {
658
+ type: "text",
659
+ 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",
660
+ placeholder: "Enter a value or formula (e.g. =SUM(A1:A5))",
661
+ value: state.editingCell ? state.draftValue : activeRawValue,
662
+ onChange: (e) => {
663
+ if (state.activeCell) {
664
+ state.setDraftValue(e.target.value);
665
+ }
666
+ },
667
+ onKeyDown: (e) => {
668
+ if (e.key === "Enter") {
669
+ e.preventDefault();
670
+ if (state.activeCell) {
671
+ const row = state.document.rows[state.activeCell.row];
672
+ const col = state.document.columns[state.activeCell.col];
673
+ if (row && col) {
674
+ state.setCellValue(row.id, col.id, e.target.value);
675
+ }
676
+ }
677
+ } else if (e.key === "Escape") {
678
+ e.preventDefault();
679
+ state.cancelEditing();
680
+ }
681
+ }
682
+ }
683
+ )
684
+ ] }),
685
+ /* @__PURE__ */ jsx3("div", { className: "relative flex-1 overflow-auto", children: /* @__PURE__ */ jsxs("table", { className: "border-collapse table-fixed w-max min-w-full", children: [
686
+ /* @__PURE__ */ jsx3("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "h-7 bg-muted/60 sticky top-0 z-20 border-b border-border shadow-xs", children: [
687
+ /* @__PURE__ */ jsx3("th", { className: "w-12 min-w-[3rem] sticky left-0 z-30 bg-muted/90 border-r border-border text-center text-[10px] text-muted-foreground font-medium", children: "#" }),
688
+ state.document.columns.map((col, cIdx) => /* @__PURE__ */ jsxs(
689
+ "th",
690
+ {
691
+ className: "relative border-r border-border px-2 text-left font-medium text-muted-foreground hover:bg-muted/90 transition-colors group cursor-pointer",
692
+ style: { width: col.width || 130, minWidth: col.width || 130, maxWidth: col.width || 130 },
693
+ onClick: () => onColumnHeaderClick?.(col),
694
+ children: [
695
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-1 truncate", children: [
696
+ /* @__PURE__ */ jsx3("span", { className: "truncate font-semibold text-foreground text-xs", children: col.title }),
697
+ /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground/70 font-mono font-normal", children: [
698
+ "(",
699
+ col.key,
700
+ ")"
701
+ ] })
702
+ ] }),
703
+ /* @__PURE__ */ jsx3(
704
+ "div",
705
+ {
706
+ className: "absolute right-0 top-0 bottom-0 w-1.5 cursor-col-resize hover:bg-primary/50 group-hover:bg-primary/20 z-10",
707
+ onMouseDown: (e) => {
708
+ e.preventDefault();
709
+ e.stopPropagation();
710
+ setResizingColId(col.id);
711
+ setResizeStartX(e.clientX);
712
+ setResizeStartWidth(col.width || 130);
713
+ },
714
+ role: "separator",
715
+ "aria-orientation": "vertical"
716
+ }
717
+ )
718
+ ]
719
+ },
720
+ col.id
721
+ )),
722
+ onAddColumnClick && /* @__PURE__ */ jsx3(
723
+ "th",
724
+ {
725
+ className: "w-10 min-w-[2.5rem] px-1 text-center bg-muted/40 hover:bg-muted cursor-pointer transition-colors",
726
+ onClick: onAddColumnClick,
727
+ title: "Add Column",
728
+ children: /* @__PURE__ */ jsx3("span", { className: "text-xs font-bold text-muted-foreground", children: "+" })
729
+ }
730
+ )
731
+ ] }) }),
732
+ /* @__PURE__ */ jsx3("tbody", { children: state.document.rows.map((row, rIdx) => /* @__PURE__ */ jsxs("tr", { className: "border-b border-border hover:bg-muted/10 transition-colors", style: { height: row.height || 32 }, children: [
733
+ /* @__PURE__ */ jsx3("td", { className: "w-12 min-w-[3rem] sticky left-0 z-10 bg-muted/50 border-r border-border text-center text-[10px] text-muted-foreground font-mono select-none", children: rIdx + 1 }),
734
+ state.document.columns.map((col, cIdx) => {
735
+ const cell = state.getCell(row.id, col.id);
736
+ const selected = isCellSelected(rIdx, cIdx);
737
+ const active = isActiveCell(rIdx, cIdx);
738
+ const isEditing = state.editingCell?.row === rIdx && state.editingCell?.col === cIdx;
739
+ return /* @__PURE__ */ jsx3(
740
+ "td",
741
+ {
742
+ className: `relative border-r border-border px-2 py-1 truncate text-foreground transition-all ${selected ? "bg-primary/10" : ""} ${active ? "ring-2 ring-primary ring-inset z-10" : ""}`,
743
+ style: { width: col.width || 130, minWidth: col.width || 130, maxWidth: col.width || 130 },
744
+ onClick: (e) => handleCellClick(rIdx, cIdx, e),
745
+ onDoubleClick: () => handleCellDblClick(rIdx, cIdx),
746
+ children: isEditing ? /* @__PURE__ */ jsx3(
747
+ "input",
748
+ {
749
+ type: "text",
750
+ className: "absolute inset-0 w-full h-full px-2 py-1 bg-background text-foreground outline-none font-sans text-xs border-2 border-primary z-20",
751
+ value: state.draftValue,
752
+ onChange: (e) => state.setDraftValue(e.target.value),
753
+ onBlur: () => state.commitEditing(),
754
+ autoFocus: true
755
+ }
756
+ ) : customCellRenderer ? customCellRenderer({ row, col, cell }) : /* @__PURE__ */ jsx3("span", { className: `truncate block ${cell.error ? "text-destructive font-semibold" : ""}`, children: cell.error || (cell.value ?? "") })
757
+ },
758
+ col.id
759
+ );
760
+ }),
761
+ onAddColumnClick && /* @__PURE__ */ jsx3("td", { className: "w-10 min-w-[2.5rem] bg-muted/10 border-r border-border" })
762
+ ] }, row.id)) })
763
+ ] }) })
764
+ ]
765
+ }
766
+ );
767
+ };
364
768
  export {
365
769
  BubbleMenu,
366
770
  EditorContent,
771
+ SpreadsheetEditor,
367
772
  TemplateRenderer,
368
773
  useEditor2 as useEditor,
369
- usePromptEditor
774
+ usePromptEditor,
775
+ useSpreadsheetEditor
370
776
  };
371
777
  //# sourceMappingURL=index.js.map