@bendyline/squisq-editor-react 2.10.3 → 2.11.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.
@@ -1,5 +1,9 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode, RefObject } from 'react';
2
+ import { TableCellEdit, TableCellValue } from '@bendyline/squisq/table';
3
+ import { CalcEngineConfig, CalcEngine } from '@bendyline/squisq-calc';
4
+ import { IngestTable } from '@bendyline/squisq-grid-react';
5
+ import { XlsxWorkbookGrids } from '@bendyline/squisq-formats/xlsx';
6
+ import { ReactNode, RefObject, ReactElement } from 'react';
3
7
  import { Doc, MediaProvider, ViewportPreset, Theme } from '@bendyline/squisq/schemas';
4
8
  import { FenceRendererMap } from '@bendyline/squisq/fence';
5
9
  import { MarkdownDocument } from '@bendyline/squisq/markdown';
@@ -10,6 +14,141 @@ import { Editor } from '@tiptap/core';
10
14
  import { editor } from 'monaco-editor';
11
15
  import { CodeBlockCopyHandler } from '@bendyline/squisq-react';
12
16
 
17
+ /**
18
+ * Sidecar bytes → the grid's neutral `IngestTable`, via lazy formats
19
+ * imports (the `processTextFile`-docx precedent — formats stays out of the
20
+ * static graph).
21
+ *
22
+ * CSV/TSV additionally sniff and RETAIN the source conventions the save
23
+ * path must reproduce (delimiter, newline flavor, trailing newline, BOM)
24
+ * plus the original parsed `string[][]` — unedited cells re-serialize from
25
+ * the parse product, never from typed columns, so untouched values have no
26
+ * float-rendering drift. XLSX resolves the heading's `sheet`/`anchor`
27
+ * region (the summary card used to ignore those), keeps typed cell values,
28
+ * and carries the address map + per-cell formula/date locks the in-place
29
+ * patch save needs; parquet stays read-only.
30
+ */
31
+
32
+ interface CsvSourceMeta {
33
+ delimiter: string;
34
+ newline: '\r\n' | '\n';
35
+ trailingNewline: boolean;
36
+ bom: boolean;
37
+ /** The parsed source rows INCLUDING the header row — the save baseline. */
38
+ rows: string[][];
39
+ hasHeader: boolean;
40
+ }
41
+ interface XlsxSourceMeta {
42
+ /** Worksheet the region lives on. */
43
+ sheet: string;
44
+ /** 0-based grid row/col of the region's top-left cell (the header row, when there is one). */
45
+ anchorRow: number;
46
+ anchorCol: number;
47
+ hasHeader: boolean;
48
+ /**
49
+ * Body cells (`"row:col"`, body coordinates) locked WITHOUT a calculation
50
+ * engine: formula cells + date-styled cells. With an engine session,
51
+ * formula cells unlock and only `dateLocked` + `masterLocked` remain.
52
+ */
53
+ locked: ReadonlySet<string>;
54
+ /** Date-styled body cells — locked in every mode this milestone. */
55
+ dateLocked: ReadonlySet<string>;
56
+ /**
57
+ * Shared-formula MASTERS — locked even with an engine, because the
58
+ * in-place patcher refuses to replace them (their followers' `si` would
59
+ * dangle). Followers edit freely (they simply leave the group).
60
+ */
61
+ masterLocked: ReadonlySet<string>;
62
+ /** Body-cell formulas (no leading `=`), for display + engine seeding. */
63
+ formulas: ReadonlyMap<string, string>;
64
+ /** The full raw workbook — the calc engine seeds from ALL sheets, since
65
+ * region formulas routinely reference cells outside the region. */
66
+ grids: XlsxWorkbookGrids;
67
+ }
68
+ interface IngestedSidecar {
69
+ ingest: IngestTable;
70
+ /** Present only for CSV/TSV. */
71
+ csv?: CsvSourceMeta;
72
+ /** Present only for XLSX — the address map + per-cell locks the save needs. */
73
+ xlsx?: XlsxSourceMeta;
74
+ /** Present when editing is unavailable, with the user-facing reason. */
75
+ readOnlyReason?: string;
76
+ }
77
+ /** Tooltip shown on locked XLSX cells. */
78
+ declare const XLSX_LOCKED_REASON = "Formula and date cells become editable with the calculation engine (Phase 3)";
79
+ declare function ingestSidecarBytes(bytes: ArrayBuffer, ext: string, params: {
80
+ sheet?: string;
81
+ anchor?: string;
82
+ headerRow?: boolean;
83
+ }): Promise<IngestedSidecar>;
84
+
85
+ /**
86
+ * XLSX formula editing in the data card: an in-house calc-engine session
87
+ * behind the grid's `FormulaSupport` seam.
88
+ *
89
+ * The engine seeds from the ENTIRE workbook (`XlsxWorkbookGrids`) — region
90
+ * formulas routinely reference cells outside the region — with formula
91
+ * cells seeded as formulas and value cells as values (date cells converted
92
+ * back to serials, since the importer normalized them to ISO strings).
93
+ *
94
+ * Display discipline: the store keeps showing the file's CACHED values
95
+ * until an edit actually changes something. After each committed edit the
96
+ * session diffs the region's formula cells against its own previous engine
97
+ * values and returns only the CHANGES as `TableCellEdit`s — and a cell
98
+ * whose engine value is `#NAME?` (a function this tier doesn't implement)
99
+ * never overwrites its cached display.
100
+ *
101
+ * `@bendyline/squisq-calc` is a regular dependency reached only via
102
+ * dynamic `import()` (the grid-react pattern) — code-split, and a load
103
+ * failure just means formula cells stay locked.
104
+ */
105
+
106
+ /**
107
+ * Builds the engine a formula session runs on. The default is the in-house
108
+ * tier; a host may inject any `CalcEngine` backend (e.g. IronCalc via
109
+ * `@bendyline/squisq-calc/ironcalc`) — the session only speaks the
110
+ * contract. A factory failure falls back to the in-house tier.
111
+ */
112
+ type CalcEngineFactory = (config: CalcEngineConfig) => Promise<CalcEngine>;
113
+ interface FormulaSessionOptions {
114
+ engineFactory?: CalcEngineFactory;
115
+ }
116
+ interface FormulaEditRecord {
117
+ formula: string;
118
+ /** Engine result, when scalar — persisted as the cached `<v>`. */
119
+ cachedValue?: number | boolean | string;
120
+ }
121
+ interface XlsxFormulaSession {
122
+ getFormula(bodyRow: number, col: number): string | undefined;
123
+ /** Date cells + shared-formula masters stay locked; formulas edit. */
124
+ isCellLocked(bodyRow: number, col: number): boolean;
125
+ commitFormula(bodyRow: number, col: number, formula: string): Promise<{
126
+ ok: boolean;
127
+ error?: string;
128
+ updates?: TableCellEdit[];
129
+ }>;
130
+ /**
131
+ * Mirror a plain value edit into the engine and return the recalculated
132
+ * dependent updates (region formula cells whose values changed) — the
133
+ * live-recalc half of "edit Units, watch Revenue follow".
134
+ */
135
+ noteValueEdit(bodyRow: number, col: number, value: TableCellValue): Promise<TableCellEdit[]>;
136
+ readonly dirtyCount: number;
137
+ /** Unsaved formula edits, keyed `"row:col"` (body coordinates). */
138
+ formulaEdits(): ReadonlyMap<string, FormulaEditRecord>;
139
+ /** Revert to the loaded workbook; returns the display updates to re-apply. */
140
+ discard(): Promise<TableCellEdit[]>;
141
+ /** Forget the edits after a successful save (values stay current). */
142
+ markSaved(): void;
143
+ dispose(): void;
144
+ }
145
+ /**
146
+ * Create the engine session, or null when formula editing can't be offered
147
+ * (calc module unavailable, or the workbook blows the interactive budget —
148
+ * the standing NHS-stress-workbook rule: degrade, never hang).
149
+ */
150
+ declare function createXlsxFormulaSession(meta: XlsxSourceMeta, options?: FormulaSessionOptions): Promise<XlsxFormulaSession | null>;
151
+
13
152
  /**
14
153
  * Configuration a Scene host (diagram / drawing / layout widget) supplies
15
154
  * so the shared inline text editor knows how to read and write the text of
@@ -904,6 +1043,13 @@ interface EditorShellProps {
904
1043
  * (Slack, Discord). When omitted, the editor behaves normally.
905
1044
  */
906
1045
  submitOnEnter?: () => void;
1046
+ /**
1047
+ * Calc backend for the data card's XLSX formula sessions (default: the
1048
+ * in-house tier from `@bendyline/squisq-calc`). Hosts inject e.g.
1049
+ * IronCalc: `(config) => import('@bendyline/squisq-calc/ironcalc')
1050
+ * .then((m) => m.createIronCalcEngine({ ...config, wasmSource }))`.
1051
+ */
1052
+ calcEngineFactory?: CalcEngineFactory;
907
1053
  /**
908
1054
  * Host-supplied context dictionary rendered inside the Monaco (raw / code)
909
1055
  * surface: collapsible markdown sections injected above anchor lines, plus
@@ -1219,7 +1365,7 @@ interface EditorShellProps {
1219
1365
  * Complete markdown editor shell with toolbar, view switcher, and three
1220
1366
  * editing modes: Raw (Monaco), WYSIWYG (Tiptap), and Preview.
1221
1367
  */
1222
- declare function EditorShell({ initialMarkdown, initialView, hostMode, defaultViewportPreset, articleId, basePath, onChange, onLinkClick, showCodeCopyButton, onCopyCode, colorScheme, className, height, minHeight, maxHeight, mediaProvider, workspaceContainer, allowVersioning, versionBasename, versioningPrunePolicy, versioningAutoSaveIdleMs, onSaveVersion, showFilesToggle, showFilesWhenNotEmpty, showFormattingControls, showInsertControls, allowBinaryDownloads, toolbarSlotLeft, toolbarSlotAfterActions, toolbarSlotRight, statusBarSlotRight, showPlayTab, allowPresentationWindow, allowPresentationFullscreen, allowPrint, submitOnEnter, codeContext, fullWidth, uxFont, thinMargins, writeCanvasSettings, showStatusBar, imageDisplayMode, fileName, saveCoverImageOutput, saveDashboardImageOutput, language, findMode, onFindModeChange, mentionProvider, proofing, proofingDefaultEnabled, proofingSpellingEnabled, proofingGrammarEnabled, proofingIgnoreStore, documentLinkProvider, fenceRenderers, linkSchemes, allowRecording, allowNarrate, preserveSourceWrapping, placeholder, readOnly, imageSrc, imageAlt, imageMode, imageEditorContainer, onImageExport, inlinePreview, inlinePreviewWidth, outline, outlineWidth, blockTags, blockTagVisibility, themeInheritance, viewPreferences, onViewPreferencesChange, themeOverride, }: EditorShellProps): react_jsx_runtime.JSX.Element;
1368
+ declare function EditorShell({ initialMarkdown, initialView, hostMode, defaultViewportPreset, articleId, basePath, onChange, onLinkClick, showCodeCopyButton, onCopyCode, colorScheme, className, height, minHeight, maxHeight, mediaProvider, workspaceContainer, allowVersioning, versionBasename, versioningPrunePolicy, versioningAutoSaveIdleMs, onSaveVersion, showFilesToggle, showFilesWhenNotEmpty, showFormattingControls, showInsertControls, allowBinaryDownloads, toolbarSlotLeft, toolbarSlotAfterActions, toolbarSlotRight, statusBarSlotRight, showPlayTab, allowPresentationWindow, allowPresentationFullscreen, allowPrint, submitOnEnter, calcEngineFactory, codeContext, fullWidth, uxFont, thinMargins, writeCanvasSettings, showStatusBar, imageDisplayMode, fileName, saveCoverImageOutput, saveDashboardImageOutput, language, findMode, onFindModeChange, mentionProvider, proofing, proofingDefaultEnabled, proofingSpellingEnabled, proofingGrammarEnabled, proofingIgnoreStore, documentLinkProvider, fenceRenderers, linkSchemes, allowRecording, allowNarrate, preserveSourceWrapping, placeholder, readOnly, imageSrc, imageAlt, imageMode, imageEditorContainer, onImageExport, inlinePreview, inlinePreviewWidth, outline, outlineWidth, blockTags, blockTagVisibility, themeInheritance, viewPreferences, onViewPreferencesChange, themeOverride, }: EditorShellProps): react_jsx_runtime.JSX.Element;
1223
1369
 
1224
1370
  /**
1225
1371
  * Shared editor context menu.
@@ -1267,7 +1413,7 @@ interface EditorContextMenuProviderProps {
1267
1413
  * Context-menu owner used by EditorShell. Exported for hosts that compose the
1268
1414
  * lower-level RawEditor/WysiwygEditor primitives into their own shell.
1269
1415
  */
1270
- declare function EditorContextMenuProvider({ rootRef, readOnly, children, }: EditorContextMenuProviderProps): JSX.Element;
1416
+ declare function EditorContextMenuProvider({ rootRef, readOnly, children, }: EditorContextMenuProviderProps): ReactElement;
1271
1417
 
1272
1418
  /**
1273
1419
  * RawEditor
@@ -1325,12 +1471,24 @@ interface WysiwygEditorProps {
1325
1471
  readOnly?: boolean;
1326
1472
  /** Host-controlled base text size and line spacing for the Write canvas. */
1327
1473
  writeCanvasSettings?: WriteCanvasSettings;
1474
+ /**
1475
+ * Open the shell's Files panel — the data card's "Show in Files" button.
1476
+ * Receives the sidecar path so hosts with a focusable file list can jump
1477
+ * to it. Omitted (e.g. no media provider host) hides the affordance.
1478
+ */
1479
+ onOpenFilesPanel?: (relativePath?: string) => void;
1480
+ /**
1481
+ * Calc backend for the data card's formula sessions. Default: the
1482
+ * in-house tier. A host may inject another `CalcEngine` implementation
1483
+ * (e.g. IronCalc via `@bendyline/squisq-calc/ironcalc`).
1484
+ */
1485
+ calcEngineFactory?: CalcEngineFactory;
1328
1486
  }
1329
1487
  /**
1330
1488
  * Rich WYSIWYG markdown editor built on Tiptap (ProseMirror).
1331
1489
  * Binds to the shared EditorContext for source synchronization.
1332
1490
  */
1333
- declare function WysiwygEditor({ placeholder, className, submitOnEnter, readOnly, writeCanvasSettings, }: WysiwygEditorProps): react_jsx_runtime.JSX.Element;
1491
+ declare function WysiwygEditor({ placeholder, className, submitOnEnter, readOnly, writeCanvasSettings, onOpenFilesPanel, calcEngineFactory, }: WysiwygEditorProps): react_jsx_runtime.JSX.Element;
1334
1492
 
1335
1493
  interface PreviewPanelProps {
1336
1494
  /** Base path for resolving media URLs in DocPlayer */
@@ -1357,4 +1515,4 @@ interface PreviewPanelProps {
1357
1515
  */
1358
1516
  declare function PreviewPanel({ basePath, className, workspaceContainer, onLinkClick, showCodeCopyButton, onCopyCode, }: PreviewPanelProps): react_jsx_runtime.JSX.Element;
1359
1517
 
1360
- export { type BlockTagVisibility as B, type CodeContext as C, type DashboardImageSaveOutput as D, type EditorHostMode as E, type ImageDisplayMode as I, type LayoutMode as L, type MentionCandidate as M, PreviewPanel as P, RawEditor as R, type SceneTextChannel as S, type ThemeInheritance as T, type ViewPreferences as V, type WriteCanvasSettings as W, type CodeContextSection as a, type CoverImageSaveOutput as b, type DocumentLinkCandidate as c, type DocumentLinkProvider as d, type EditorActions as e, type EditorColorScheme as f, type EditorContextMenuContext as g, type EditorContextMenuItem as h, type EditorContextMenuItemVisibility as i, EditorContextMenuProvider as j, type EditorContextMenuProviderProps as k, type EditorContextValue as l, type EditorMode as m, EditorProvider as n, type EditorProviderProps as o, EditorShell as p, type EditorShellProps as q, type EditorState as r, type EditorView as s, type MentionProvider as t, type PreviewPanelProps as u, type RawEditorProps as v, WysiwygEditor as w, type WysiwygEditorProps as x, useEditorContext as y, useEditorContextMenuItems as z };
1518
+ export { WysiwygEditor as A, type BlockTagVisibility as B, type CodeContext as C, type DashboardImageSaveOutput as D, type EditorHostMode as E, type FormulaEditRecord as F, type WysiwygEditorProps as G, XLSX_LOCKED_REASON as H, type ImageDisplayMode as I, type XlsxFormulaSession as J, createXlsxFormulaSession as K, type LayoutMode as L, type MentionCandidate as M, ingestSidecarBytes as N, useEditorContext as O, PreviewPanel as P, useEditorContextMenuItems as Q, RawEditor as R, type SceneTextChannel as S, type ThemeInheritance as T, type ViewPreferences as V, type WriteCanvasSettings as W, type XlsxSourceMeta as X, type CalcEngineFactory as a, type CsvSourceMeta as b, type CodeContextSection as c, type CoverImageSaveOutput as d, type DocumentLinkCandidate as e, type DocumentLinkProvider as f, type EditorActions as g, type EditorColorScheme as h, type EditorContextMenuContext as i, type EditorContextMenuItem as j, type EditorContextMenuItemVisibility as k, EditorContextMenuProvider as l, type EditorContextMenuProviderProps as m, type EditorContextValue as n, type EditorMode as o, EditorProvider as p, type EditorProviderProps as q, EditorShell as r, type EditorShellProps as s, type EditorState as t, type EditorView as u, type FormulaSessionOptions as v, type IngestedSidecar as w, type MentionProvider as x, type PreviewPanelProps as y, type RawEditorProps as z };