@sheetxl/grid-react 0.7.21 → 0.7.23-beta.1
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 +502 -2
- package/browser/cjs/index.cjs +3 -12
- package/browser/esm/index.mjs +5797 -1867
- package/licenses/dependencies.txt +143 -41
- package/node/esm/index.mjs +4951 -1861
- package/package.json +7 -6
- package/types/index.d.ts +2 -1497
- package/types/src/cell/CellLayer.d.ts +70 -0
- package/types/src/cell/CellLayer.d.ts.map +1 -0
- package/types/src/cell/CellRenderer.d.ts +42 -0
- package/types/src/cell/CellRenderer.d.ts.map +1 -0
- package/types/src/cell/DefaultCellRenderer.d.ts +6 -0
- package/types/src/cell/DefaultCellRenderer.d.ts.map +1 -0
- package/types/src/cell/GridlineLayer.d.ts +38 -0
- package/types/src/cell/GridlineLayer.d.ts.map +1 -0
- package/types/src/cell/Types.d.ts +12 -0
- package/types/src/cell/Types.d.ts.map +1 -0
- package/types/src/cell/_CellModel.d.ts +82 -0
- package/types/src/cell/_CellModel.d.ts.map +1 -0
- package/types/src/cell/index.d.ts +6 -0
- package/types/src/cell/index.d.ts.map +1 -0
- package/types/src/editor/DefaultEditable.d.ts +121 -0
- package/types/src/editor/DefaultEditable.d.ts.map +1 -0
- package/types/src/editor/EditSession.d.ts +182 -0
- package/types/src/editor/EditSession.d.ts.map +1 -0
- package/types/src/editor/EditState.d.ts +61 -0
- package/types/src/editor/EditState.d.ts.map +1 -0
- package/types/src/editor/EditorDiv.d.ts +65 -0
- package/types/src/editor/EditorDiv.d.ts.map +1 -0
- package/types/src/editor/EditorInput.d.ts +88 -0
- package/types/src/editor/EditorInput.d.ts.map +1 -0
- package/types/src/editor/EditorLayer.d.ts +69 -0
- package/types/src/editor/EditorLayer.d.ts.map +1 -0
- package/types/src/editor/EditorPlacement.d.ts +38 -0
- package/types/src/editor/EditorPlacement.d.ts.map +1 -0
- package/types/src/editor/index.d.ts +10 -0
- package/types/src/editor/index.d.ts.map +1 -0
- package/types/src/editor/useEditorKeymap.d.ts +74 -0
- package/types/src/editor/useEditorKeymap.d.ts.map +1 -0
- package/types/src/grid/Grid.d.ts +16 -0
- package/types/src/grid/Grid.d.ts.map +1 -0
- package/types/src/grid/IGrid.d.ts +93 -0
- package/types/src/grid/IGrid.d.ts.map +1 -0
- package/types/src/grid/index.d.ts +3 -0
- package/types/src/grid/index.d.ts.map +1 -0
- package/types/src/header/HeaderDividerAnchor.d.ts +120 -0
- package/types/src/header/HeaderDividerAnchor.d.ts.map +1 -0
- package/types/src/header/index.d.ts +3 -0
- package/types/src/header/index.d.ts.map +1 -0
- package/types/src/header/useHeaderSelectionPointer.d.ts +122 -0
- package/types/src/header/useHeaderSelectionPointer.d.ts.map +1 -0
- package/types/src/index.d.ts +13 -0
- package/types/src/index.d.ts.map +1 -0
- package/types/src/layer/HoverTipLayer.d.ts +74 -0
- package/types/src/layer/HoverTipLayer.d.ts.map +1 -0
- package/types/src/layer/Layer.d.ts +92 -0
- package/types/src/layer/Layer.d.ts.map +1 -0
- package/types/src/layer/LayerTypes.d.ts +47 -0
- package/types/src/layer/LayerTypes.d.ts.map +1 -0
- package/types/src/layer/RangePrompt.d.ts +42 -0
- package/types/src/layer/RangePrompt.d.ts.map +1 -0
- package/types/src/layer/Stage.d.ts +147 -0
- package/types/src/layer/Stage.d.ts.map +1 -0
- package/types/src/layer/StickyAnchor.d.ts +83 -0
- package/types/src/layer/StickyAnchor.d.ts.map +1 -0
- package/types/src/layer/StickyFloat.d.ts +65 -0
- package/types/src/layer/StickyFloat.d.ts.map +1 -0
- package/types/src/layer/VirtualDiv.d.ts +59 -0
- package/types/src/layer/VirtualDiv.d.ts.map +1 -0
- package/types/src/layer/_Utils.d.ts +37 -0
- package/types/src/layer/_Utils.d.ts.map +1 -0
- package/types/src/layer/index.d.ts +11 -0
- package/types/src/layer/index.d.ts.map +1 -0
- package/types/src/layer/useGridAnchor.d.ts +157 -0
- package/types/src/layer/useGridAnchor.d.ts.map +1 -0
- package/types/src/layer/useHoverIntent.d.ts +49 -0
- package/types/src/layer/useHoverIntent.d.ts.map +1 -0
- package/types/src/layer/useLayerResponder.d.ts +29 -0
- package/types/src/layer/useLayerResponder.d.ts.map +1 -0
- package/types/src/layer/usePlacement.d.ts +18 -0
- package/types/src/layer/usePlacement.d.ts.map +1 -0
- package/types/src/layer/useRangeHover.d.ts +35 -0
- package/types/src/layer/useRangeHover.d.ts.map +1 -0
- package/types/src/list/CheckboxList.d.ts +63 -0
- package/types/src/list/CheckboxList.d.ts.map +1 -0
- package/types/src/list/List.d.ts +55 -0
- package/types/src/list/List.d.ts.map +1 -0
- package/types/src/list/index.d.ts +3 -0
- package/types/src/list/index.d.ts.map +1 -0
- package/types/src/metrics/Types.d.ts +23 -0
- package/types/src/metrics/Types.d.ts.map +1 -0
- package/types/src/metrics/index.d.ts +3 -0
- package/types/src/metrics/index.d.ts.map +1 -0
- package/types/src/metrics/useGridMetrics.d.ts +67 -0
- package/types/src/metrics/useGridMetrics.d.ts.map +1 -0
- package/types/src/range/DragHandle.d.ts +129 -0
- package/types/src/range/DragHandle.d.ts.map +1 -0
- package/types/src/range/Draggable.d.ts +86 -0
- package/types/src/range/Draggable.d.ts.map +1 -0
- package/types/src/range/FillHandle.d.ts +54 -0
- package/types/src/range/FillHandle.d.ts.map +1 -0
- package/types/src/range/RangeRect.d.ts +36 -0
- package/types/src/range/RangeRect.d.ts.map +1 -0
- package/types/src/range/RangeResizer.d.ts +68 -0
- package/types/src/range/RangeResizer.d.ts.map +1 -0
- package/types/src/range/RangeStyle.d.ts +8 -0
- package/types/src/range/RangeStyle.d.ts.map +1 -0
- package/types/src/range/index.d.ts +13 -0
- package/types/src/range/index.d.ts.map +1 -0
- package/types/src/selection/DefaultSelection.d.ts +59 -0
- package/types/src/selection/DefaultSelection.d.ts.map +1 -0
- package/types/src/selection/ICellAnchor.d.ts +21 -0
- package/types/src/selection/ICellAnchor.d.ts.map +1 -0
- package/types/src/selection/ISelection.d.ts +65 -0
- package/types/src/selection/ISelection.d.ts.map +1 -0
- package/types/src/selection/RangesPickerLayer.d.ts +128 -0
- package/types/src/selection/RangesPickerLayer.d.ts.map +1 -0
- package/types/src/selection/SelectionLayer.d.ts +179 -0
- package/types/src/selection/SelectionLayer.d.ts.map +1 -0
- package/types/src/selection/SelectionStyle.d.ts +28 -0
- package/types/src/selection/SelectionStyle.d.ts.map +1 -0
- package/types/src/selection/SelectionTouchGrips.d.ts +29 -0
- package/types/src/selection/SelectionTouchGrips.d.ts.map +1 -0
- package/types/src/selection/SelectionUtils.d.ts +2 -0
- package/types/src/selection/SelectionUtils.d.ts.map +1 -0
- package/types/src/selection/Types.d.ts +67 -0
- package/types/src/selection/Types.d.ts.map +1 -0
- package/types/src/selection/_SelectionNavigation.d.ts +6 -0
- package/types/src/selection/_SelectionNavigation.d.ts.map +1 -0
- package/types/src/selection/_SelectionUtils.d.ts +7 -0
- package/types/src/selection/_SelectionUtils.d.ts.map +1 -0
- package/types/src/selection/index.d.ts +12 -0
- package/types/src/selection/index.d.ts.map +1 -0
- package/types/src/selection/useDragCells.d.ts +218 -0
- package/types/src/selection/useDragCells.d.ts.map +1 -0
- package/types/src/selection/useSelectionPointer.d.ts +70 -0
- package/types/src/selection/useSelectionPointer.d.ts.map +1 -0
- package/types/src/surface/GridPane.d.ts +85 -0
- package/types/src/surface/GridPane.d.ts.map +1 -0
- package/types/src/surface/GridPaneProvider.d.ts +37 -0
- package/types/src/surface/GridPaneProvider.d.ts.map +1 -0
- package/types/src/surface/GridSurface.d.ts +11 -0
- package/types/src/surface/GridSurface.d.ts.map +1 -0
- package/types/src/surface/IGridPane.d.ts +288 -0
- package/types/src/surface/IGridPane.d.ts.map +1 -0
- package/types/src/surface/IGridSurface.d.ts +141 -0
- package/types/src/surface/IGridSurface.d.ts.map +1 -0
- package/types/src/surface/SurfaceStateProvider.d.ts +50 -0
- package/types/src/surface/SurfaceStateProvider.d.ts.map +1 -0
- package/types/src/surface/_GridUtils.d.ts +37 -0
- package/types/src/surface/_GridUtils.d.ts.map +1 -0
- package/types/src/surface/index.d.ts +7 -0
- package/types/src/surface/index.d.ts.map +1 -0
- package/types/src/surface/useGridPane.d.ts +31 -0
- package/types/src/surface/useGridPane.d.ts.map +1 -0
- package/types/src/surface/useSurfaceState.d.ts +22 -0
- package/types/src/surface/useSurfaceState.d.ts.map +1 -0
- package/types/src/svg/LineSVG.d.ts +13 -0
- package/types/src/svg/LineSVG.d.ts.map +1 -0
- package/types/src/svg/RectangleSVG.d.ts +114 -0
- package/types/src/svg/RectangleSVG.d.ts.map +1 -0
- package/types/src/svg/ShapeBounds.d.ts +15 -0
- package/types/src/svg/ShapeBounds.d.ts.map +1 -0
- package/types/src/svg/Types.d.ts +37 -0
- package/types/src/svg/Types.d.ts.map +1 -0
- package/types/src/svg/index.d.ts +9 -0
- package/types/src/svg/index.d.ts.map +1 -0
- package/types/src/theme/GridTheme.d.ts +56 -0
- package/types/src/theme/GridTheme.d.ts.map +1 -0
- package/types/src/theme/index.d.ts +2 -0
- package/types/src/theme/index.d.ts.map +1 -0
- package/node/assets/style.css +0 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CellCoords } from '@sheetxl/utils';
|
|
2
|
+
/**
|
|
3
|
+
* The editor's two modes (renamed from `EditMode` to avoid colliding with the global edit-mode bus
|
|
4
|
+
* `EditMode` in `@sheetxl/utils`):
|
|
5
|
+
*
|
|
6
|
+
* - `enter` — started by typing (or Backspace). Typing replaces; arrow keys commit + let the
|
|
7
|
+
* selection navigate.
|
|
8
|
+
* - `edit` — started by F2 / double-click / clicking in. Arrow keys move the caret.
|
|
9
|
+
*/
|
|
10
|
+
export type EditorMode = 'enter' | 'edit';
|
|
11
|
+
/**
|
|
12
|
+
* Intent flags passed through a commit (the editor's commit "signal") — from the keymap, up through
|
|
13
|
+
* {@link EditorInputProps.onCommit}, to {@link IEditable.commit} and on to the model's write, where
|
|
14
|
+
* the app interprets them. Kept grid-generic: a "broadcast" commit means *apply to the whole
|
|
15
|
+
* selection, not just the active cell* — an interaction concept, not a spreadsheet one.
|
|
16
|
+
*/
|
|
17
|
+
export interface EditCommitArgs {
|
|
18
|
+
/**
|
|
19
|
+
* Broadcast the value to **every cell in the current selection** rather than only the active cell —
|
|
20
|
+
* Excel's `Ctrl+Enter`. The active cell does not move (the leave-key does not navigate/traverse).
|
|
21
|
+
*/
|
|
22
|
+
broadcast?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A text selection range within the editor input. Mirrors the `HTMLTextAreaElement` selection API.
|
|
26
|
+
*/
|
|
27
|
+
export interface EditorTextSelection {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
direction?: 'forward' | 'backward' | 'none';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The immutable snapshot inside an {@link EditSession} — the value React renders from. Its existence
|
|
34
|
+
* (a non-`null` session state) means an edit is active.
|
|
35
|
+
*
|
|
36
|
+
* @typeParam C - The clean value type. @typeParam D - The dirty (working) value type.
|
|
37
|
+
*/
|
|
38
|
+
export interface EditState<C, D = string> {
|
|
39
|
+
/** The current {@link EditorMode}. */
|
|
40
|
+
mode: EditorMode;
|
|
41
|
+
/** The cell being edited. */
|
|
42
|
+
coords: CellCoords;
|
|
43
|
+
/**
|
|
44
|
+
* The clean value, captured from the model when the edit began. The input projects it to the
|
|
45
|
+
* displayed text when {@link dirty} is unset, and a cell-aware input reads styling/rendering info
|
|
46
|
+
* from it that the dirty text does not carry.
|
|
47
|
+
*/
|
|
48
|
+
clean: C;
|
|
49
|
+
/**
|
|
50
|
+
* The working (dirty) value. `undefined` ⇒ show the {@link clean} value. The first keystroke is
|
|
51
|
+
* seeded here **by value** — why no keystroke is lost (no synthetic replay).
|
|
52
|
+
*/
|
|
53
|
+
dirty: D | undefined;
|
|
54
|
+
/** Selection to apply the next time the input focuses (consumed once per {@link token}). */
|
|
55
|
+
initialSelection?: EditorTextSelection | null;
|
|
56
|
+
/** Whether the input should grab focus when the edit begins. */
|
|
57
|
+
autoFocus: boolean;
|
|
58
|
+
/** Bumped on each (re)start; editors watch it to re-focus on a fresh open. */
|
|
59
|
+
token: number;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=EditState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditState.d.ts","sourceRoot":"","sources":["../../../../src/editor/EditState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;CAC7C;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM;IACtC,sCAAsC;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,6BAA6B;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,KAAK,EAAE,CAAC,CAAC;IACT;;;OAGG;IACH,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;IACrB,4FAA4F;IAC5F,gBAAgB,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC9C,gEAAgE;IAChE,SAAS,EAAE,OAAO,CAAC;IACnB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { default as React, CSSProperties } from 'react';
|
|
2
|
+
import { EditCommitArgs } from './EditState';
|
|
3
|
+
import { IEditable } from './DefaultEditable';
|
|
4
|
+
import { EditorInputProps } from './EditorInput';
|
|
5
|
+
/**
|
|
6
|
+
* Props for {@link EditorDiv}.
|
|
7
|
+
*
|
|
8
|
+
* @typeParam C - clean value type. @typeParam D - dirty value type. @typeParam A - commit args.
|
|
9
|
+
*/
|
|
10
|
+
export interface EditorDivProps<C, D = string, A = EditCommitArgs> {
|
|
11
|
+
/** The shared editable (the same instance the grid's {@link EditorLayer} uses). */
|
|
12
|
+
editable: IEditable<C, D, A>;
|
|
13
|
+
/**
|
|
14
|
+
* Swap in a custom input. Defaults to {@link DefaultEditorInput} (`C` = `D` = `string`). The
|
|
15
|
+
* cell-aware input is passed here for the formula bar, the same way it is for `EditorLayer`.
|
|
16
|
+
*/
|
|
17
|
+
renderEditor?: (props: EditorInputProps<C, D>) => React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* The `clean` to show when there is **no active session** — i.e. the field displaying the active
|
|
20
|
+
* cell while idle (the formula bar's job). When a session is active, the session's own `clean` is
|
|
21
|
+
* used instead. The host is value-agnostic, so the caller supplies this (for the sheet, a live cell
|
|
22
|
+
* getter).
|
|
23
|
+
*/
|
|
24
|
+
idleClean?: C | null;
|
|
25
|
+
/**
|
|
26
|
+
* Optional transform applied to the resolved `clean` (session **or** idle) before the input sees it.
|
|
27
|
+
* The formula bar uses this to restyle the cell — `c => () => c().createCell({ style })` —
|
|
28
|
+
* so the **same** input renders in the bar's default font instead of the cell's, with no per-input
|
|
29
|
+
* "rich styling" flag. Runs in the host, so the input stays a pure renderer.
|
|
30
|
+
*/
|
|
31
|
+
mapClean?: (clean: C | null) => C | null;
|
|
32
|
+
/**
|
|
33
|
+
* This host's LOGICAL editor id, parked on the session when focus lands here (see
|
|
34
|
+
* {@link EditSession.setActiveEditorId}) so another host — e.g. the grid's in-cell editor returning from a
|
|
35
|
+
* sheet switch — can tell the user's active editor was THIS one and leave its focus alone. Identity is a
|
|
36
|
+
* host concern; the input it renders stays identity-free.
|
|
37
|
+
*/
|
|
38
|
+
editorId?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Display-only mode: the field shows {@link idleClean} (or a live session's value) but focusing it does
|
|
41
|
+
* **not** start an edit, and the rendered input is `readOnly`. The formula bar sets this when the anchor
|
|
42
|
+
* cell is protected (or the workbook is write-protected), so the value stays visible/copyable but can't
|
|
43
|
+
* be typed into — and, crucially, focus never reaches `startEdit` (which throws on a read-only workbook).
|
|
44
|
+
*/
|
|
45
|
+
readOnly?: boolean;
|
|
46
|
+
className?: string;
|
|
47
|
+
style?: CSSProperties;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A **non-grid** editor host: the `<div>` counterpart of {@link EditorLayer}. It binds to the same
|
|
51
|
+
* {@link IEditable} and renders the same swappable input — but in a plain box, with no pane / placement
|
|
52
|
+
* / overflow growth. Built for the **formula bar** (and any non-grid embedding): focusing it starts an
|
|
53
|
+
* edit on the active cell, and because it shares the editable, typing here drives the very same
|
|
54
|
+
* {@link EditSession} the in-grid editor shows (live two-way sync, no bus).
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* Unlike the layer, this is **always visible** — while idle it shows {@link EditorDivProps.idleClean}
|
|
58
|
+
* (the active cell). It never auto-grabs focus (`autoFocus: false`): the field is focused by the
|
|
59
|
+
* user's click, so the in-grid editor and the formula bar don't fight over focus when an edit begins.
|
|
60
|
+
*/
|
|
61
|
+
export declare function EditorDiv<C, D = string, A = EditCommitArgs>(props: EditorDivProps<C, D, A>): React.ReactElement;
|
|
62
|
+
export declare namespace EditorDiv {
|
|
63
|
+
var displayName: string;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=EditorDiv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorDiv.d.ts","sourceRoot":"","sources":["../../../../src/editor/EditorDiv.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAMlD,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,cAAc;IAC/D,mFAAmF;IACnF,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAClE;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CAqD/G;yBArDe,SAAS"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { CellCoords, Size } from '@sheetxl/utils';
|
|
2
|
+
import { EditorMode, EditorTextSelection, EditCommitArgs } from './EditState';
|
|
3
|
+
/**
|
|
4
|
+
* Props passed to the (swappable) editor input — the visual + keyboard surface of the editor. The
|
|
5
|
+
* surrounding `EditorLayer` owns the session lifecycle and placement; the input only renders
|
|
6
|
+
* the value and translates keystrokes into the callbacks below.
|
|
7
|
+
*
|
|
8
|
+
* @typeParam C - The **clean** value type (see {@link IEditable}). The input projects it to the
|
|
9
|
+
* displayed text. @typeParam D - The **dirty** (working) value type — `string` for the basic input.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* Replace the default input by passing `EditorLayerProps.renderEditor`. The richer, cell-aware
|
|
13
|
+
* editor (`@sheetxl/react`) is just a different input — `C` = a cell handle — swapped in here.
|
|
14
|
+
* This module is host-agnostic: both the grid layer (`EditorLayer`) and the plain-div host
|
|
15
|
+
* (`EditorDiv`, the formula bar) import it, and it pulls in no grid layer code.
|
|
16
|
+
*/
|
|
17
|
+
export interface EditorInputProps<C, D = string> {
|
|
18
|
+
/** Whether a session is active. The input stays mounted either way; it just hides when closed. */
|
|
19
|
+
open: boolean;
|
|
20
|
+
/** The current {@link EditorMode} (drives arrow-key behavior). */
|
|
21
|
+
mode: EditorMode;
|
|
22
|
+
/**
|
|
23
|
+
* The cell being edited (or `null` when closed). The basic input ignores it; a cell-aware input
|
|
24
|
+
* (the extended `SheetCellEditor`) uses it to read the cell's style / number-format from the model.
|
|
25
|
+
*/
|
|
26
|
+
coords: CellCoords | null;
|
|
27
|
+
/** The clean value (or `null` when closed) — projected to display text when {@link dirty} is unset. */
|
|
28
|
+
clean: C | null;
|
|
29
|
+
/** The working (dirty) value, or `undefined` when unmodified (show {@link clean}). */
|
|
30
|
+
dirty: D | undefined;
|
|
31
|
+
/** Bumped on each session open; watch it to (re)focus and (re)apply the initial selection. */
|
|
32
|
+
token: number;
|
|
33
|
+
/**
|
|
34
|
+
* Whether to grab focus on open. The **host** decides this — it is the one seam through which a host
|
|
35
|
+
* expresses "you should (not) take focus", so an input never needs to know about editor identity or
|
|
36
|
+
* visibility (see `EditSession.getActiveEditorId`). Under frozen panes the grid host gates it on the
|
|
37
|
+
* pane's visibility, so exactly ONE mounted input (the on-screen pane's) focuses; it may flip `true`
|
|
38
|
+
* after `open` (the edited cell scrolled into view), so watch it alongside {@link token}.
|
|
39
|
+
*/
|
|
40
|
+
autoFocus: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* When `true`, the input is a **display-only** view: the textarea is `readOnly` — still focusable and
|
|
43
|
+
* selectable (so the value can be read / copied) but not typeable. The formula bar sets this for a
|
|
44
|
+
* **protected** anchor cell (or a write-protected workbook); a read-only host also does not start an
|
|
45
|
+
* edit on focus (see `EditorDiv`). The basic input honors it too, though the in-grid editor never
|
|
46
|
+
* opens for a non-editable cell.
|
|
47
|
+
*/
|
|
48
|
+
readOnly?: boolean;
|
|
49
|
+
/** Selection to apply on focus (consumed once per {@link token}). */
|
|
50
|
+
initialSelection?: EditorTextSelection | null;
|
|
51
|
+
/** Current pane zoom. */
|
|
52
|
+
zoom: number;
|
|
53
|
+
/**
|
|
54
|
+
* The edited cell's **own** box in **logical** (un-zoomed) px — a single cell, before any overflow
|
|
55
|
+
* growth. The basic input ignores it; a cell-aware input uses its width as the wrap width (so the
|
|
56
|
+
* mirror wraps exactly as the textarea will) and may use it as the vertical-align reference.
|
|
57
|
+
*/
|
|
58
|
+
cellSize?: Size | null;
|
|
59
|
+
/** Push a change to the working (dirty) value. */
|
|
60
|
+
onDirtyChange(dirty: D): void;
|
|
61
|
+
/** Request a mode change (e.g. the user clicked into the text ⇒ `'edit'`). */
|
|
62
|
+
onModeChange(mode: EditorMode): void;
|
|
63
|
+
/**
|
|
64
|
+
* Commit the current edit and return whether it succeeded. Does NOT navigate — the editor never
|
|
65
|
+
* moves the selection. On a "leave" key (Enter/Tab/enter-mode arrow) the input commits and, **only
|
|
66
|
+
* if it succeeded**, lets the key propagate to the selection layer to perform the move; on failure
|
|
67
|
+
* (a rejected/invalid value) the input keeps the session open and stops the key so the selection
|
|
68
|
+
* does not move away.
|
|
69
|
+
*
|
|
70
|
+
* `args` carries the commit "signal" — e.g. {@link EditCommitArgs.broadcast} for a Ctrl+Enter fill.
|
|
71
|
+
*/
|
|
72
|
+
onCommit(args?: EditCommitArgs): boolean;
|
|
73
|
+
/** Cancel/revert the edit. */
|
|
74
|
+
onCancel(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Report the natural (content) text size in **logical** (un-zoomed) px so the layer can grow the
|
|
77
|
+
* box past the cell. Optional — an input that does not measure simply will not overflow.
|
|
78
|
+
*/
|
|
79
|
+
onNaturalSize?(size: Size): void;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The default, dependency-free editor input (`C` = `D` = `string`): a single `<textarea>` as a
|
|
83
|
+
* linear text buffer with the standard spreadsheet keyMap (Enter/Tab to commit, Alt/Meta+Enter for a
|
|
84
|
+
* newline, F2 to toggle mode, Escape to cancel, arrows that navigate in `enter` mode and move the
|
|
85
|
+
* caret in `edit` mode).
|
|
86
|
+
*/
|
|
87
|
+
export declare const DefaultEditorInput: React.FC<EditorInputProps<string, string>>;
|
|
88
|
+
//# sourceMappingURL=EditorInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorInput.d.ts","sourceRoot":"","sources":["../../../../src/editor/EditorInput.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAS7F;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM;IAC7C,kGAAkG;IAClG,IAAI,EAAE,OAAO,CAAC;IACd,kEAAkE;IAClE,IAAI,EAAE,UAAU,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,uGAAuG;IACvG,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,sFAAsF;IACtF,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;IACrB,8FAA8F;IAC9F,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC9C,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,kDAAkD;IAClD,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;IACzC,8BAA8B;IAC9B,QAAQ,IAAI,IAAI,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;CAClC;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAmGzE,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { CellCoords } from '@sheetxl/utils';
|
|
2
|
+
import { VirtualDivProps } from '../layer';
|
|
3
|
+
import { EditCommitArgs } from './EditState';
|
|
4
|
+
import { IEditable } from './DefaultEditable';
|
|
5
|
+
import { EditorInputProps } from './EditorInput';
|
|
6
|
+
import { EditorAlignment } from './EditorPlacement';
|
|
7
|
+
/**
|
|
8
|
+
* Props for {@link EditorLayer}.
|
|
9
|
+
*
|
|
10
|
+
* @typeParam C - The clean value type. @typeParam D - The dirty value type. @typeParam A - Commit args.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* The editor depends only on the {@link IEditable} — anchor + the single current edit. The same
|
|
14
|
+
* `editable` instance is shared with peers (e.g. the formula bar); its anchor is the same instance the
|
|
15
|
+
* selection layer writes. The editor reads the anchor but cannot move it — navigation stays the
|
|
16
|
+
* selection's job. There is no data-source prop; how an edit is created lives inside the editable.
|
|
17
|
+
*/
|
|
18
|
+
export interface EditorLayerProps<C, D = string, A = EditCommitArgs> extends VirtualDivProps {
|
|
19
|
+
/**
|
|
20
|
+
* Stacking override, read by the grid's sorter **off this element** when the editor is a grid
|
|
21
|
+
* child (law 1: z belongs to Layers; the editor's Layer takes its slot from the sorted order).
|
|
22
|
+
*/
|
|
23
|
+
zIndex?: number;
|
|
24
|
+
/** The editable. Construct the default with `new DefaultEditable(anchor, createEdit)`. */
|
|
25
|
+
editable: IEditable<C, D, A>;
|
|
26
|
+
/**
|
|
27
|
+
* Swap in a custom editor input. Defaults to {@link DefaultEditorInput} (which requires `C` = `D` =
|
|
28
|
+
* `string`).
|
|
29
|
+
*/
|
|
30
|
+
renderEditor?: (props: EditorInputProps<C, D>) => React.ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* Horizontal anchor used when the editor grows past its cell (Excel-style overflow).
|
|
33
|
+
*
|
|
34
|
+
* @defaultValue `'left'`
|
|
35
|
+
*/
|
|
36
|
+
alignment?: EditorAlignment;
|
|
37
|
+
/**
|
|
38
|
+
* Background fill for the editor box (behind the input). A string, or a **resolver** called with the
|
|
39
|
+
* cell being placed — the cell-aware editor passes a resolver that returns the grid cell→normal→body
|
|
40
|
+
* fill (so the box covers the cell while editing). The basic editor defaults to white.
|
|
41
|
+
*
|
|
42
|
+
* @defaultValue `'#ffffff'`
|
|
43
|
+
*/
|
|
44
|
+
background?: string | ((coords: CellCoords) => string | undefined);
|
|
45
|
+
/**
|
|
46
|
+
* Active-border color.
|
|
47
|
+
*
|
|
48
|
+
* @defaultValue Excel-like green.
|
|
49
|
+
*/
|
|
50
|
+
borderColor?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Active-border width, in **device** px (matches the selection rectangle's stroke so the two line
|
|
53
|
+
* up). Snapped to the device grid; the border centerline sits on the cell boundary.
|
|
54
|
+
*
|
|
55
|
+
* @defaultValue `2`
|
|
56
|
+
*/
|
|
57
|
+
borderWidth?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Always-mounted inline cell editor, as a grid layer.
|
|
61
|
+
*
|
|
62
|
+
* @remarks
|
|
63
|
+
* The input is mounted for the life of the grid (hidden when idle);
|
|
64
|
+
* starting an edit just seeds the first character **by value** into the {@link IEditable} and
|
|
65
|
+
* focuses the input. Render it inside `renderLayers`; with frozen panes each pane instantiates one,
|
|
66
|
+
* and only the pane containing the active cell shows it.
|
|
67
|
+
*/
|
|
68
|
+
export declare function EditorLayer<C, D = string, A = EditCommitArgs>(props: EditorLayerProps<C, D, A>): React.ReactElement;
|
|
69
|
+
//# sourceMappingURL=EditorLayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorLayer.d.ts","sourceRoot":"","sources":["../../../../src/editor/EditorLayer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAA0B,MAAM,gBAAgB,CAAC;AAMzE,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAEnE,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE1E,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,cAAc,CAAE,SAAQ,eAAe;IAC1F;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;IAClE;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC;IACnE;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,cAAc,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CAmLnH"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CellCoords, Bounds, Size } from '@sheetxl/utils';
|
|
2
|
+
import { IGridPane } from '../surface';
|
|
3
|
+
/**
|
|
4
|
+
* Horizontal anchor used when the editor grows past its cell. `left` grows rightward, `right` grows
|
|
5
|
+
* leftward, `center` grows both ways. (Vertical growth is always downward.)
|
|
6
|
+
*/
|
|
7
|
+
export type EditorAlignment = 'left' | 'right' | 'center';
|
|
8
|
+
/**
|
|
9
|
+
* The result of {@link expandEditorBounds}: the placed box plus whether it is currently on-screen.
|
|
10
|
+
*/
|
|
11
|
+
export interface EditorPlacement {
|
|
12
|
+
/** View-pixel bounds for the editor box. */
|
|
13
|
+
bounds: Bounds;
|
|
14
|
+
/** `false` when the cell is scrolled out of the visible pane (caller should hide, keep focus). */
|
|
15
|
+
inView: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Compute the editor box bounds for a cell, expanding past the cell when the natural text size is
|
|
19
|
+
* larger — Excel-style overflow. (no React, no model).
|
|
20
|
+
*
|
|
21
|
+
* @param pane The pane the cell lives in.
|
|
22
|
+
* @param coords The cell being edited.
|
|
23
|
+
* @param natural The measured natural text size in **logical** (un-zoomed) px, or `null` for none.
|
|
24
|
+
* @param alignment Horizontal growth anchor.
|
|
25
|
+
* @param edgeInset View px of clearance to leave between the box's right edge and the surface edge.
|
|
26
|
+
* Defaults to `0` (flush, the original behavior). A host that draws a border ON the box edge passes
|
|
27
|
+
* its stroke width so the trailing border stays inside the viewport instead of being clipped by it —
|
|
28
|
+
* without that the box runs flush and a wrapped editor gives no visual sign it stopped at the edge.
|
|
29
|
+
*
|
|
30
|
+
* @returns The placement, or `null` when no bounds can be resolved.
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
* Width grows across whole neighbor columns (bounded by the pane range and the surface); height
|
|
34
|
+
* grows freely (bounded by the surface). The pane metrics already include zoom, so `natural` is
|
|
35
|
+
* scaled by zoom here to compare against view-pixel cell bounds.
|
|
36
|
+
*/
|
|
37
|
+
export declare const expandEditorBounds: (pane: IGridPane, coords: CellCoords, natural: Size | null | undefined, alignment?: EditorAlignment, edgeInset?: number) => EditorPlacement | null;
|
|
38
|
+
//# sourceMappingURL=EditorPlacement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorPlacement.d.ts","sourceRoot":"","sources":["../../../../src/editor/EditorPlacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,SAAS,EACf,QAAQ,UAAU,EAClB,SAAS,IAAI,GAAG,IAAI,GAAG,SAAS,EAChC,YAAW,eAAwB,EACnC,YAAW,MAAU,KACpB,eAAe,GAAG,IA4DpB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { EditorMode, EditorTextSelection, EditState, EditCommitArgs } from './EditState';
|
|
2
|
+
export type { StartEditOptions } from './EditSession';
|
|
3
|
+
export * from './EditSession';
|
|
4
|
+
export * from './useEditorKeymap';
|
|
5
|
+
export * from './DefaultEditable';
|
|
6
|
+
export * from './EditorPlacement';
|
|
7
|
+
export * from './EditorInput';
|
|
8
|
+
export * from './EditorLayer';
|
|
9
|
+
export * from './EditorDiv';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/editor/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9F,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { Direction, RangeAxis } from '@sheetxl/utils';
|
|
3
|
+
import { EditorMode, EditCommitArgs } from './EditState';
|
|
4
|
+
import { StartEditOptions } from './EditSession';
|
|
5
|
+
/**
|
|
6
|
+
* Map a keystroke (while no session is active) to an open request, or `null` if it should not start
|
|
7
|
+
* an edit. F2 ⇒ edit mode; Backspace ⇒ clear; a printable character ⇒ seed it (by value). The seed
|
|
8
|
+
* is a string (a keystroke); the built-in start path therefore assumes a string dirty. Used by
|
|
9
|
+
* `EditorLayer`'s start-key handler.
|
|
10
|
+
*/
|
|
11
|
+
export declare const startEventFromKey: (e: KeyboardEvent) => StartEditOptions<string> | null;
|
|
12
|
+
/**
|
|
13
|
+
* Deterministic caret placement across a controlled-value re-render: call the returned setter with the
|
|
14
|
+
* desired caret offset *before* pushing the new value (`onDirtyChange`), and a layout effect applies it
|
|
15
|
+
* synchronously after the new value commits to the DOM — no `requestAnimationFrame` race (a repeated
|
|
16
|
+
* keystroke can land between the render and a deferred frame, acting on a caret still parked at the end).
|
|
17
|
+
*
|
|
18
|
+
* The input owns its textarea ref and value; the keymap consumes the setter via
|
|
19
|
+
* {@link EditorKeymapProps.setCaret}.
|
|
20
|
+
*/
|
|
21
|
+
export declare const usePendingCaret: (inputRef: RefObject<HTMLTextAreaElement | null>, value: string) => ((caret: number) => void);
|
|
22
|
+
/**
|
|
23
|
+
* Inputs to {@link useEditorKeymap}. The editor input passes its current {@link EditorMode}, the
|
|
24
|
+
* current text (needed for newline insertion), and the lifecycle callbacks.
|
|
25
|
+
*/
|
|
26
|
+
export interface EditorKeymapProps {
|
|
27
|
+
mode: EditorMode;
|
|
28
|
+
/** The current text, so Alt/Meta+Enter can splice a newline at the caret. */
|
|
29
|
+
value: string;
|
|
30
|
+
onDirtyChange(dirty: string): void;
|
|
31
|
+
onModeChange(mode: EditorMode): void;
|
|
32
|
+
onCommit(args?: EditCommitArgs): boolean;
|
|
33
|
+
onCancel(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Optional. When provided, a successful **enter-mode arrow** commit **navigates here, in the input**,
|
|
36
|
+
* and the key is consumed (not propagated). Used by inputs with no selection layer beneath them — the
|
|
37
|
+
* cell-aware sheet editor and the formula bar. When omitted, the arrow propagates instead so a
|
|
38
|
+
* selection layer can navigate (the default/grid behavior).
|
|
39
|
+
*/
|
|
40
|
+
onNavigate?(direction: Direction): void;
|
|
41
|
+
/**
|
|
42
|
+
* Optional. When provided, a successful **Tab/Enter** commit **traverses here, in the input**, and
|
|
43
|
+
* the key is consumed (not propagated). Traversal differs from navigation: it cycles the active cell
|
|
44
|
+
* *within* the current selection rather than moving it — the Excel Tab/Enter contract. `Tab` ⇒ `Row`
|
|
45
|
+
* axis, `Enter` ⇒ `Column` axis; Shift reverses. Used by the same input hosts as {@link onNavigate};
|
|
46
|
+
* when omitted, the key propagates so a selection layer can traverse (the default/grid behavior).
|
|
47
|
+
*/
|
|
48
|
+
onTraverse?(axis: RangeAxis, reverse: boolean): void;
|
|
49
|
+
/**
|
|
50
|
+
* Optional. Deterministic caret placement across a value re-render (see {@link usePendingCaret}) —
|
|
51
|
+
* used by the Alt/Meta+Enter newline splice to restore the caret after the new value renders. When
|
|
52
|
+
* omitted, falls back to a `requestAnimationFrame` restore (racy under key repeat; our inputs all
|
|
53
|
+
* supply it).
|
|
54
|
+
*/
|
|
55
|
+
setCaret?(caret: number): void;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The shared spreadsheet editor keymap, as a `<textarea>` `onKeyDown` handler. Both the default and
|
|
59
|
+
* the cell-aware inputs use it so the interaction contract stays identical:
|
|
60
|
+
*
|
|
61
|
+
* - **Escape** cancels (consumed).
|
|
62
|
+
* - **F2** toggles `enter` ↔ `edit` (consumed).
|
|
63
|
+
* - **Alt/Meta+Enter** splices a hard newline at the caret (consumed).
|
|
64
|
+
* - **edit-mode arrows** move the caret (consumed).
|
|
65
|
+
* - **Enter / Tab / enter-mode arrow** commit, then let the key **propagate** so the selection layer
|
|
66
|
+
* moves — but only if the commit succeeded; on a rejected value the key is stopped so the selection
|
|
67
|
+
* stays put. Tab/Enter *traverse* (cycle within the selection); arrows *navigate* (move the cell).
|
|
68
|
+
* - **IME composition** is left entirely to the textarea (kept off the grid).
|
|
69
|
+
*
|
|
70
|
+
* Movement is intentionally NOT handled here by default — the editor only commits; the selection layer
|
|
71
|
+
* moves. Inputs with no layer beneath them opt in via {@link onNavigate}/{@link onTraverse}.
|
|
72
|
+
*/
|
|
73
|
+
export declare const useEditorKeymap: (props: EditorKeymapProps) => ((e: React.KeyboardEvent<HTMLTextAreaElement>) => void);
|
|
74
|
+
//# sourceMappingURL=useEditorKeymap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEditorKeymap.d.ts","sourceRoot":"","sources":["../../../../src/editor/useEditorKeymap.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAItD,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,GAAG,aAAa,KAAG,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAuB/E,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,EAC/C,OAAO,MAAM,KACZ,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAS1B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,UAAU,CAAC;IACjB,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;IACzC,QAAQ,IAAI,IAAI,CAAC;IACjB;;;;;OAKG;IACH,UAAU,CAAC,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IACxC;;;;;;OAMG;IACH,UAAU,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAcD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,iBAAiB,KACvB,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,KAAK,IAAI,CA+GxD,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { GridProps, IGrid } from './IGrid';
|
|
3
|
+
/**
|
|
4
|
+
* A virtualized grid: a thin wrapper around {@link GridSurface} that re-adds the cell + gridline
|
|
5
|
+
* rendering the surface itself is agnostic to. It composes a `CellLayer` (cells), a `GridlineLayer`
|
|
6
|
+
* (gridlines) and an optional `renderBorders` slot as ordinary layers — in the conventional z-order
|
|
7
|
+
* (gridlines → borders → below-layers → cells → above-layers) — and owns the content cache token the
|
|
8
|
+
* cells bust on. Everything else is forwarded to the surface.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* This is the batteries-included entry point (what most callers want and what the stories use). A
|
|
12
|
+
* consumer that wants to own the cells itself (e.g. a sheet that drives its own partial invalidation)
|
|
13
|
+
* can skip `Grid` and compose a `CellLayer` straight onto {@link GridSurface}'s layer slots.
|
|
14
|
+
*/
|
|
15
|
+
export declare const Grid: React.NamedExoticComponent<Omit<GridProps, "ref"> & React.RefAttributes<IGrid>>;
|
|
16
|
+
//# sourceMappingURL=Grid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Grid.d.ts","sourceRoot":"","sources":["../../../../src/grid/Grid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAQrD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI,iFAgGd,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { CellCoords, RangeCoords, OrientationFlags } from '@sheetxl/utils';
|
|
2
|
+
import { ItemSizer } from '../metrics';
|
|
3
|
+
import { CellRendererProps, VisibleCell } from '../cell';
|
|
4
|
+
import { LayerNode } from '../layer';
|
|
5
|
+
import { GridSurfaceProps, IGridSurface } from '../surface/IGridSurface';
|
|
6
|
+
import { IGridPane } from '../surface/IGridPane';
|
|
7
|
+
/**
|
|
8
|
+
* Props for {@link Grid}.
|
|
9
|
+
*
|
|
10
|
+
* @remarks
|
|
11
|
+
* `Grid` is the batteries-included grid: it renders cells ({@link GridProps.renderCells}) and
|
|
12
|
+
* gridlines ({@link GridProps.showGridLines}) and adds the size conveniences
|
|
13
|
+
* ({@link GridProps.getRowHeight} / {@link GridProps.getColumnWidth}) most apps want out of the box.
|
|
14
|
+
*
|
|
15
|
+
* It builds those features as ordinary layers — a `CellLayer`, a `GridlineLayer`, and the optional
|
|
16
|
+
* border/below slots — on top of {@link GridSurface}, the pure layer/pane engine, and owns the
|
|
17
|
+
* content cache they bust on (see {@link IGrid.invalidate}). The extra props here are all additive;
|
|
18
|
+
* reach for `GridSurface` directly only when you want to compose everything as layers yourself.
|
|
19
|
+
*/
|
|
20
|
+
export interface GridProps extends GridSurfaceProps {
|
|
21
|
+
/**
|
|
22
|
+
* Row height — a number (uniform) or a `(index) => number`. The size-convenience over the surface's
|
|
23
|
+
* raw `metrics`: `Grid` builds the metrics from this. Ignored when `metrics` is provided.
|
|
24
|
+
*/
|
|
25
|
+
getRowHeight?: ItemSizer | number;
|
|
26
|
+
/**
|
|
27
|
+
* Column width — a number (uniform) or a `(index) => number`. Ignored when `metrics` is provided.
|
|
28
|
+
*/
|
|
29
|
+
getColumnWidth?: ItemSizer | number;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the element to render for a cell. There can be many cells, so keep this cheap. By default
|
|
32
|
+
* the cell's `pointerEvents` are `none`; override to enable interaction.
|
|
33
|
+
*/
|
|
34
|
+
renderCells?: (props: CellRendererProps) => React.ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* Layer(s) rendered BELOW the cells/borders (but above the gridlines) — the place for fills and
|
|
37
|
+
* highlights. The `children` are the layers ABOVE the cells/borders.
|
|
38
|
+
*/
|
|
39
|
+
renderBelow?: LayerNode;
|
|
40
|
+
/**
|
|
41
|
+
* Optional border layer(s), rendered just below the cells (above {@link GridProps.renderBelow} /
|
|
42
|
+
* gridlines). A render slot for a custom border treatment — distinct from the light
|
|
43
|
+
* {@link GridProps.showGridLines} gridlines.
|
|
44
|
+
*/
|
|
45
|
+
renderBorders?: LayerNode;
|
|
46
|
+
/**
|
|
47
|
+
* Show grid lines. Useful for spreadsheets.
|
|
48
|
+
*/
|
|
49
|
+
showGridLines?: boolean | Partial<OrientationFlags>;
|
|
50
|
+
/**
|
|
51
|
+
* Customize grid line color.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* Overridden per-axis by {@link GridProps.propsGridLineRows} / {@link GridProps.propsGridLineColumns}.
|
|
55
|
+
*/
|
|
56
|
+
gridLineColor?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Gridline props for rows.
|
|
59
|
+
*/
|
|
60
|
+
propsGridLineRows?: React.SVGProps<SVGPathElement>;
|
|
61
|
+
/**
|
|
62
|
+
* Gridline props for columns.
|
|
63
|
+
*/
|
|
64
|
+
propsGridLineColumns?: React.SVGProps<SVGPathElement>;
|
|
65
|
+
/**
|
|
66
|
+
* Optimization hook: return exactly the cells worth rendering for a pane. When omitted every
|
|
67
|
+
* visible cell is iterated and {@link GridProps.hiddenCellAt} is consulted. The value is passed to
|
|
68
|
+
* the cell renderer.
|
|
69
|
+
*/
|
|
70
|
+
getVisibleCells?: (pane: IGridPane) => (VisibleCell | CellCoords)[];
|
|
71
|
+
/**
|
|
72
|
+
* Skip rendering a cell that has nothing to render. Ignored when {@link GridProps.getVisibleCells}
|
|
73
|
+
* is provided.
|
|
74
|
+
*/
|
|
75
|
+
hiddenCellAt?: (coords: CellCoords) => boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Imperative handle for {@link Grid}, obtained from its `ref`. Exposes the full grid API — scrolling,
|
|
79
|
+
* coordinate conversion, pane access (see {@link IGridSurfaceAttributes}) — plus a cell-aware
|
|
80
|
+
* {@link IGrid.invalidate}.
|
|
81
|
+
*/
|
|
82
|
+
export interface IGrid extends IGridSurface {
|
|
83
|
+
/**
|
|
84
|
+
* Invalidate the cells (content) and re-render them. Geometry and panes are left intact, so this
|
|
85
|
+
* is the cheap path for "the data changed." Change props for layout or geometry changes.
|
|
86
|
+
*
|
|
87
|
+
* @param coords Reserved for partial invalidation — currently **ignored**: every call drops the
|
|
88
|
+
* whole grid's cached cell output. (Per-range tile dirtying is a planned follow-up; see the
|
|
89
|
+
* invalidation-model item in GRID-CLEAN §Architecture.)
|
|
90
|
+
*/
|
|
91
|
+
invalidate: (coords?: CellCoords | RangeCoords) => void;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=IGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IGrid.d.ts","sourceRoot":"","sources":["../../../../src/grid/IGrid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE1F,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,SAAU,SAAQ,gBAAgB;IACjD;;;OAGG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAClC;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,KAAK,CAAC,SAAS,CAAC;IAC5D;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACpD;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACnD;;OAEG;IACH,oBAAoB,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACtD;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC,EAAE,CAAC;IACpE;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;CAChD;AAED;;;;GAIG;AACH,MAAM,WAAW,KAAM,SAAQ,YAAY;IACzC;;;;;;;OAOG;IACH,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,KAAK,IAAI,CAAC;CACzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/grid/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC"}
|