@sheetxl/grid-react 0.8.0-beta.1 → 0.8.0-beta.11
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 +16 -5
- package/browser/esm/index.mjs +3504 -2846
- package/licenses/dependencies.txt +0 -208
- package/node/esm/index.mjs +3861 -2284
- package/package.json +8 -12
- package/types/src/cell/CellRenderer.d.ts +14 -3
- package/types/src/cell/GridlineLayer.d.ts +39 -1
- package/types/src/editor/DefaultEditable.d.ts +25 -6
- package/types/src/editor/EditSession.d.ts +34 -5
- package/types/src/editor/EditState.d.ts +6 -0
- package/types/src/editor/EditorDiv.d.ts +3 -2
- package/types/src/editor/EditorInput.d.ts +7 -3
- package/types/src/editor/EditorLayer.d.ts +9 -4
- package/types/src/editor/EditorStartLayer.d.ts +33 -0
- package/types/src/editor/index.d.ts +1 -0
- package/types/src/editor/useEditorKeymap.d.ts +18 -2
- package/types/src/header/GridFreezeAnchor.d.ts +29 -0
- package/types/src/header/HeaderDividerAnchor.d.ts +29 -0
- package/types/src/header/HeaderFreezeAnchor.d.ts +37 -0
- package/types/src/header/_freezeSnap.d.ts +28 -0
- package/types/src/header/_useFreezeGrip.d.ts +28 -0
- package/types/src/header/index.d.ts +2 -0
- package/types/src/header/useHeaderSelectionPointer.d.ts +10 -6
- package/types/src/layer/GestureTip.d.ts +69 -0
- package/types/src/layer/GridFloatPanel.d.ts +19 -0
- package/types/src/layer/Layer.d.ts +6 -0
- package/types/src/layer/RangeFloatLayer.d.ts +143 -51
- package/types/src/layer/RangePrompt.d.ts +8 -8
- package/types/src/layer/RangeTooltip.d.ts +123 -0
- package/types/src/layer/RangeTooltipLayer.d.ts +53 -0
- package/types/src/layer/StickyAnchor.d.ts +15 -5
- package/types/src/layer/StickyPortal.d.ts +73 -0
- package/types/src/layer/TooltipProvider.d.ts +101 -0
- package/types/src/layer/index.d.ts +7 -4
- package/types/src/layer/useGridAnchor.d.ts +45 -4
- package/types/src/layer/useHoverIntent.d.ts +35 -8
- package/types/src/list/CheckboxList.d.ts +22 -1
- package/types/src/list/List.d.ts +11 -2
- package/types/src/list/ListSearch.d.ts +52 -0
- package/types/src/list/ListSurface.d.ts +25 -5
- package/types/src/list/PickList.d.ts +71 -0
- package/types/src/list/_measureText.d.ts +14 -0
- package/types/src/list/index.d.ts +2 -0
- package/types/src/range/DragHandle.d.ts +19 -2
- package/types/src/range/Draggable.d.ts +132 -7
- package/types/src/range/FillHandle.d.ts +33 -3
- package/types/src/range/RangeInsertBar.d.ts +91 -0
- package/types/src/range/index.d.ts +2 -0
- package/types/src/selection/SelectionLayer.d.ts +128 -15
- package/types/src/selection/SelectionStyle.d.ts +33 -0
- package/types/src/selection/SelectionTouchGrips.d.ts +0 -4
- package/types/src/selection/_SelectionUtils.d.ts +6 -0
- package/types/src/selection/useDragCells.d.ts +65 -9
- package/types/src/surface/GridPane.d.ts +2 -0
- package/types/src/surface/IGridPane.d.ts +15 -2
- package/types/src/surface/SurfaceStateProvider.d.ts +1 -1
- package/types/src/surface/getPrimaryPane.d.ts +13 -0
- package/types/src/surface/index.d.ts +1 -0
- package/types/src/surface/useSurfaceState.d.ts +19 -0
- package/types/src/svg/_Glide.d.ts +9 -0
- package/types/src/theme/GridTheme.d.ts +1 -1
- package/browser/cjs/index.cjs +0 -3
- package/types/src/layer/HoverTipLayer.d.ts +0 -47
- package/types/src/layer/StickyFloat.d.ts +0 -68
- package/types/src/layer/useRangeHover.d.ts +0 -36
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { CellCoords, RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
import { RangeAxis, CellCoords, RangeCoords } from '@sheetxl/utils';
|
|
3
3
|
import { LayerProps, GridPlacement } from '../layer';
|
|
4
4
|
import { VisualSVGProps } from '../svg';
|
|
5
5
|
import { RangeEdge } from '../range';
|
|
6
6
|
import { ISelection } from './ISelection';
|
|
7
7
|
import { SelectionNavigation } from './Types';
|
|
8
|
-
import { SelectionRangeStyle } from './SelectionStyle';
|
|
8
|
+
import { SelectionRangeStyle, InsertBarStyle } from './SelectionStyle';
|
|
9
9
|
/**
|
|
10
10
|
* The in-flight selection gesture passed to {@link SelectionLayerProps.renderTip}:
|
|
11
11
|
* - `select` — a drag-select growing the active range (Excel's live R×C);
|
|
@@ -19,11 +19,44 @@ export type SelectionGesture = {
|
|
|
19
19
|
kind: 'move';
|
|
20
20
|
from: RangeCoords;
|
|
21
21
|
to: RangeCoords;
|
|
22
|
+
drop: MoveDrop;
|
|
22
23
|
} | {
|
|
23
24
|
kind: 'fill';
|
|
24
25
|
template: RangeCoords;
|
|
25
26
|
destination: RangeCoords;
|
|
26
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* What a move drag would DO if released now — the destination plus the mode its modifiers select.
|
|
30
|
+
* Excel's three grip gestures, as data: drag relocates, Ctrl+drag copies, Shift+drag inserts (and
|
|
31
|
+
* Ctrl+Shift inserts a copy).
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* The mode lives here rather than being re-derived from a pointer event by each consumer, because the
|
|
35
|
+
* modifiers change with the pointer standing still — see {@link DragMoveInfo}.
|
|
36
|
+
*/
|
|
37
|
+
export interface MoveDrop {
|
|
38
|
+
/**
|
|
39
|
+
* Where the block lands. For an insert this is the block RE-ANCHORED on the pointer's cell, not the
|
|
40
|
+
* drag's translation — take the destination from here rather than re-deriving it.
|
|
41
|
+
*/
|
|
42
|
+
to: RangeCoords;
|
|
43
|
+
/** Ctrl / Cmd is held: the source is copied rather than cut. */
|
|
44
|
+
copy: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Shift is held: INSERT at {@link MoveDrop.to} instead of dropping over it — the cells already there
|
|
47
|
+
* step aside along this axis (`Row` = down, `Column` = right), which is also the edge of `to` the
|
|
48
|
+
* I-beam is drawn on. Absent for a plain overwrite drop.
|
|
49
|
+
*/
|
|
50
|
+
insert?: RangeAxis;
|
|
51
|
+
/**
|
|
52
|
+
* The drop cannot be performed and a release does nothing: a cut INSERT whose line falls inside the
|
|
53
|
+
* block being dragged, or one that would shift only part of it (see `CoordUtils.classifyInsertCut`
|
|
54
|
+
* - the same call the model makes, so a beam drawn as legal is one the model will accept), or
|
|
55
|
+
* whatever else {@link SelectionLayerProps.isDropRefused} rules out. The preview draws the I-beam
|
|
56
|
+
* (or the ghost) in the refused color instead, and `onMove` never fires.
|
|
57
|
+
*/
|
|
58
|
+
refused?: boolean;
|
|
59
|
+
}
|
|
27
60
|
/**
|
|
28
61
|
* Props for {@link SelectionLayer}.
|
|
29
62
|
*/
|
|
@@ -41,7 +74,7 @@ export interface SelectionLayerProps extends LayerProps {
|
|
|
41
74
|
getContentBounds?: () => RangeCoords;
|
|
42
75
|
/**
|
|
43
76
|
* The bounding REGION enclosing a cell — a table's data range from a tier that knows tables (the sheet
|
|
44
|
-
* layer), else `null` (the bare sheet). Drives Tab
|
|
77
|
+
* layer), else `null` (the bare sheet). Drives Tab wrapping inside a table and the row/column
|
|
45
78
|
* span of Ctrl/Shift+Space. Omit it (the dumb {@link DefaultSelection} tier) and there is no enclosing
|
|
46
79
|
* region: Tab is a plain move and Ctrl/Shift+Space select the whole grid. The layer never learns it's a
|
|
47
80
|
* sheet — just a `cell → bounds | null` getter; any escalation lives in the provider.
|
|
@@ -70,6 +103,35 @@ export interface SelectionLayerProps extends LayerProps {
|
|
|
70
103
|
singleAnchorStyle?: VisualSVGProps;
|
|
71
104
|
/** The Ctrl/Cmd-drag remove rubber-band. Merged (slot-by-slot) over {@link DEFAULT_REMOVE_PREVIEW_STYLE}. */
|
|
72
105
|
removePreviewStyle?: SelectionRangeStyle;
|
|
106
|
+
/** The Shift-drag insert I-beam. Merged over {@link DEFAULT_INSERT_BAR_STYLE}. */
|
|
107
|
+
insertBarStyle?: InsertBarStyle;
|
|
108
|
+
/**
|
|
109
|
+
* Whether a drop would be REFUSED - drawn as a refused I-beam (or ghost), and inert on release.
|
|
110
|
+
* Asked for every drop, insert or not; a copy INSERT is never refused, as it leaves no gap to
|
|
111
|
+
* resolve. Defaults to the geometry a grid can see on its own (`CoordUtils.classifyInsertCut`: a
|
|
112
|
+
* cut whose gap the insert would only half close, or a line dropped inside the block itself); a
|
|
113
|
+
* plain drop is then never refused.
|
|
114
|
+
*
|
|
115
|
+
* @remarks
|
|
116
|
+
* A model knows more than the grid does - a merge the shift would tear, a table it would split, a
|
|
117
|
+
* merged cell a drop would land across - so a host that has one should answer from it
|
|
118
|
+
* (`ICellRange.canInsertFrom`, `ICellRange.getDropTarget`), which is what keeps the preview honest
|
|
119
|
+
* about drops the grid could not have ruled out.
|
|
120
|
+
*/
|
|
121
|
+
isDropRefused?: (from: RangeCoords, drop: MoveDrop) => boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Adjust where a plain (non-insert) move drop lands before it drives the ghost, the tip and the
|
|
124
|
+
* callbacks - e.g. onto the whole of a merged cell a single cell is dropped onto, so the ghost shows
|
|
125
|
+
* what the drop will cover. Given the source and the pointer-derived drop, return the destination
|
|
126
|
+
* to use. Omit for no snapping.
|
|
127
|
+
*/
|
|
128
|
+
snapMoveDestination?: (from: RangeCoords, drop: MoveDrop) => RangeCoords;
|
|
129
|
+
/**
|
|
130
|
+
* The mute drawn over the source while a **cut** (plain) move drag is in flight — see
|
|
131
|
+
* {@link DEFAULT_MOVE_SOURCE_STYLE}, which it merges over. `null` draws no mute, leaving the cursor
|
|
132
|
+
* as the only cut-vs-copy tell.
|
|
133
|
+
*/
|
|
134
|
+
moveSourceStyle?: SelectionRangeStyle | null;
|
|
73
135
|
/**
|
|
74
136
|
* Stacked layers (fill, move, …) rendered when a single range is selected.
|
|
75
137
|
*/
|
|
@@ -86,21 +148,37 @@ export interface SelectionLayerProps extends LayerProps {
|
|
|
86
148
|
enabledMove?: boolean;
|
|
87
149
|
/**
|
|
88
150
|
* Called when the single range is moved by its border — `from` is the original range, `to` the new
|
|
89
|
-
* one. The selection follows automatically; use this for the data
|
|
151
|
+
* one (`drop.to`, snapped when inserting). The selection follows automatically; use this for the data
|
|
152
|
+
* side-effect, which `drop` describes: a cut-move, a copy, or an insert along `drop.insert`.
|
|
153
|
+
*/
|
|
154
|
+
onMove?: (from: RangeCoords, to: RangeCoords, e: React.PointerEvent, drop: MoveDrop) => void;
|
|
155
|
+
/**
|
|
156
|
+
* The move drag started (before any translation) — `from` is the range being moved. `cancel` aborts
|
|
157
|
+
* the drag as Escape would ({@link SelectionLayerProps.onMoveEnd} follows, nothing moved) — for a
|
|
158
|
+
* mode's chrome cancel.
|
|
90
159
|
*/
|
|
91
|
-
|
|
92
|
-
/** The move drag started (before any translation) — `from` is the range being moved. */
|
|
93
|
-
onMoveStart?: (from: RangeCoords, e: React.PointerEvent) => void;
|
|
160
|
+
onMoveStart?: (from: RangeCoords, e: React.PointerEvent, drop: MoveDrop, cancel: () => void) => void;
|
|
94
161
|
/**
|
|
95
|
-
* Live during the move drag — `to` is the in-flight
|
|
96
|
-
*
|
|
162
|
+
* Live during the move drag — `to` is the in-flight destination and `drop` what a release would do.
|
|
163
|
+
* Fires on every change, INCLUDING a modifier pressed or released with the pointer standing still
|
|
164
|
+
* (that is the whole point: the mode must be reflected — cursor, status description — the instant
|
|
165
|
+
* the key goes down). Take the mode from `drop`; `e` is merely the last pointer event.
|
|
97
166
|
*/
|
|
98
|
-
onMoveUpdate?: (from: RangeCoords, to: RangeCoords, e: React.PointerEvent) => void;
|
|
167
|
+
onMoveUpdate?: (from: RangeCoords, to: RangeCoords, e: React.PointerEvent, drop: MoveDrop) => void;
|
|
99
168
|
/**
|
|
100
169
|
* The move drag ended (fires on release regardless of whether the range actually moved) — for teardown
|
|
101
170
|
* of anything {@link SelectionLayerProps.onMoveStart}/`onMoveUpdate` set (e.g. clearing a drag mode).
|
|
102
171
|
*/
|
|
103
172
|
onMoveEnd?: () => void;
|
|
173
|
+
/**
|
|
174
|
+
* The cursor to paint while the move grip is dragged — pass one derived from the live
|
|
175
|
+
* {@link MoveDrop} (`copy` while Ctrl is held, say) to show the drop mode under the pointer. The
|
|
176
|
+
* grip is pointer-captured for the duration, so this is the cursor the browser shows anywhere on
|
|
177
|
+
* screen, and it is the only place a mode cursor can come from during the drag.
|
|
178
|
+
*
|
|
179
|
+
* @defaultValue 'grabbing'
|
|
180
|
+
*/
|
|
181
|
+
moveCursor?: string;
|
|
104
182
|
/**
|
|
105
183
|
* Enable the built-in fill handle on a single range (the Excel fill square at the bottom-right
|
|
106
184
|
* corner; drag to fill). Opt-in (unlike the always-on move grip) because it adds a visible handle.
|
|
@@ -121,8 +199,11 @@ export interface SelectionLayerProps extends LayerProps {
|
|
|
121
199
|
* to use. Omit for no snapping.
|
|
122
200
|
*/
|
|
123
201
|
snapFillDestination?: (template: RangeCoords, destination: RangeCoords) => RangeCoords;
|
|
124
|
-
/**
|
|
125
|
-
|
|
202
|
+
/**
|
|
203
|
+
* The fill drag started — `template` is the source range. `cancel` aborts the drag as Escape would
|
|
204
|
+
* ({@link SelectionLayerProps.onFillEnd} follows, nothing filled) — for a mode's chrome cancel.
|
|
205
|
+
*/
|
|
206
|
+
onFillStart?: (template: RangeCoords, e: React.PointerEvent, cancel: () => void) => void;
|
|
126
207
|
/**
|
|
127
208
|
* Live during the fill drag — `destination` is the in-flight fill range (incl. the template). Use it
|
|
128
209
|
* to preview what will be filled (e.g. a value tooltip). The fill axis is `template` vs `destination`.
|
|
@@ -133,6 +214,17 @@ export interface SelectionLayerProps extends LayerProps {
|
|
|
133
214
|
* anything {@link SelectionLayerProps.onFillPreview} set (e.g. closing the preview tooltip).
|
|
134
215
|
*/
|
|
135
216
|
onFillEnd?: () => void;
|
|
217
|
+
/**
|
|
218
|
+
* A **right-button** fill drag was released — Excel's right-drag of the fill handle, which offers a
|
|
219
|
+
* menu of fills at the pointer instead of filling. Fires INSTEAD of {@link SelectionLayerProps.onFill}
|
|
220
|
+
* for that gesture, and the selection is NOT extended: nothing has been decided yet, so the consumer
|
|
221
|
+
* extends it (or not) once a menu entry is chosen. Supplying it is what enables the right-button drag;
|
|
222
|
+
* left-drag is untouched.
|
|
223
|
+
*
|
|
224
|
+
* The dashed fill preview stays up while the menu decides; call `done` once it has answered or closed
|
|
225
|
+
* without answering, and the preview clears.
|
|
226
|
+
*/
|
|
227
|
+
onFillMenu?: (template: RangeCoords, destination: RangeCoords, e: React.PointerEvent, done: () => void) => void;
|
|
136
228
|
/**
|
|
137
229
|
* Resolve the destination for a **double-clicked** fill handle — Excel's "ride the rails" fill,
|
|
138
230
|
* whose extent comes from the data flanking the template rather than from a drag. Return the
|
|
@@ -154,13 +246,34 @@ export interface SelectionLayerProps extends LayerProps {
|
|
|
154
246
|
* {@link SelectionPointerOptions.onSelectionEnd}.
|
|
155
247
|
*/
|
|
156
248
|
onSelectionEnd?: (e: React.PointerEvent) => void;
|
|
249
|
+
/**
|
|
250
|
+
* The pointer drag-select started (`'extend'` / `'remove'`) or ended (`null`) — for reflecting an
|
|
251
|
+
* in-flight selection somewhere this layer's own {@link SelectionLayerProps.renderTip} can't reach
|
|
252
|
+
* (the name box's live `nR x nC`). Read off the drag engine rather than a start/end callback pair,
|
|
253
|
+
* so it is balanced by construction: the `null` also arrives for an aborted drag (Escape /
|
|
254
|
+
* `pointercancel`), which never reaches a release.
|
|
255
|
+
*/
|
|
256
|
+
onDragModeChange?: (dragMode: 'extend' | 'remove' | null) => void;
|
|
257
|
+
/**
|
|
258
|
+
* The active range is being grown by a drag this layer's own tap cannot see — a header drag, which
|
|
259
|
+
* writes through the model. The gesture tip shows for it as for a body drag-select, off the corner
|
|
260
|
+
* being pulled.
|
|
261
|
+
* @defaultValue false
|
|
262
|
+
*/
|
|
263
|
+
externalDrag?: boolean;
|
|
157
264
|
/**
|
|
158
265
|
* Render a transient tip during a gesture — a drag-select ({@link SelectionGesture} `select`, live
|
|
159
|
-
* R×C), a move (`move`, the destination address), or a fill (`fill`, the preview). Return
|
|
160
|
-
* for no tip (e.g. skip a 1×1 drag-select). The tip floats on the
|
|
266
|
+
* R×C), a move (`move`, the destination address), or a fill (`fill`, the preview). Return an empty
|
|
267
|
+
* node for no tip (e.g. skip a 1×1 drag-select). The tip is a {@link GestureTip}: it floats on the
|
|
268
|
+
* in-flight range in the tooltip group's bubble, and no hover tip opens while the gesture runs.
|
|
161
269
|
*/
|
|
162
270
|
renderTip?: (gesture: SelectionGesture) => React.ReactNode;
|
|
163
|
-
/**
|
|
271
|
+
/**
|
|
272
|
+
* Fixed placement of the gesture tip relative to the in-flight range. By default the tip follows the
|
|
273
|
+
* gesture: off the corner a drag-select is pulling (the one opposite the anchor cell, or the touch grip
|
|
274
|
+
* held), trailing the edge a fill grows from, on the far side of an insert's I-beam, and at the
|
|
275
|
+
* bottom-right of a plain move.
|
|
276
|
+
*/
|
|
164
277
|
tipPlacement?: GridPlacement;
|
|
165
278
|
/**
|
|
166
279
|
* Disable the layer's **built-in keyboard** routing (arrows → {@link ISelection.navigate}, Tab/Enter
|
|
@@ -25,4 +25,37 @@ export declare const DEFAULT_MULTI_STYLE: SelectionRangeStyle;
|
|
|
25
25
|
export declare const DEFAULT_ANCHOR_STYLE: VisualSVGProps;
|
|
26
26
|
/** The transient rubber-band shown while Ctrl/Cmd-dragging to remove an area (fill + border stack). */
|
|
27
27
|
export declare const DEFAULT_REMOVE_PREVIEW_STYLE: SelectionRangeStyle;
|
|
28
|
+
/** The look of the insert I-beam — the `RangeInsertBar` shown while Shift-dragging the move grip. */
|
|
29
|
+
export interface InsertBarStyle {
|
|
30
|
+
/** The bar color. */
|
|
31
|
+
color?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The bar color when the drop would be REFUSED (`MoveDrop.refused`) - the theme's warning. A refused
|
|
34
|
+
* plain drop draws its ghost in it too.
|
|
35
|
+
*/
|
|
36
|
+
refusedColor?: string;
|
|
37
|
+
/** Bar thickness in DEVICE px (the same currency as a border's `alignWidth`). */
|
|
38
|
+
alignWidth?: number;
|
|
39
|
+
/** How far each end cap reaches past the bar, per side, in DEVICE px. */
|
|
40
|
+
capExtent?: number;
|
|
41
|
+
/** How long the bar takes to travel to a new line, in ms. `0` places it instantly. */
|
|
42
|
+
transitionDuration?: number;
|
|
43
|
+
/** The curve it travels on - a hard decelerate reads as a snap onto the line. */
|
|
44
|
+
transitionEasing?: string;
|
|
45
|
+
/** How long the beam takes to grow into a new ORIENTATION, in ms. `0` shows it at once. */
|
|
46
|
+
axisDuration?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The insert I-beam: the selection color, heavier than the selection outline so it reads as a drop
|
|
50
|
+
* target rather than a border. A drop the model would refuse draws in the theme's WARNING instead
|
|
51
|
+
* (the same token the remove rubber-band uses) - the gesture stays visible, it just says no.
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_INSERT_BAR_STYLE: InsertBarStyle;
|
|
54
|
+
/**
|
|
55
|
+
* The **mute** laid over the SOURCE of a move (cut) drag — a scrim in the grid's own surface color,
|
|
56
|
+
* drawn under the selection visuals so it fades the cell content while the outline stays crisp. The
|
|
57
|
+
* content reads as already lifted out; a Ctrl (copy) drag draws no mute, so the two modes are
|
|
58
|
+
* distinguishable at a glance rather than by cursor alone.
|
|
59
|
+
*/
|
|
60
|
+
export declare const DEFAULT_MOVE_SOURCE_STYLE: SelectionRangeStyle;
|
|
28
61
|
//# sourceMappingURL=SelectionStyle.d.ts.map
|
|
@@ -6,10 +6,6 @@ import { ISelection } from './ISelection';
|
|
|
6
6
|
export interface SelectionTouchGripsProps {
|
|
7
7
|
/** The selection the touch handles read (for placement) and extend (via `modify`). */
|
|
8
8
|
selection: ISelection;
|
|
9
|
-
/** The ring color (the fill is the surface/"window" color). @defaultValue the theme primary. */
|
|
10
|
-
color?: string;
|
|
11
|
-
/** Handle diameter (px). Touch-sized. @defaultValue 22 */
|
|
12
|
-
size?: number;
|
|
13
9
|
}
|
|
14
10
|
/**
|
|
15
11
|
* Touch selection handles: round grips at the active range's corners (or edges, for a whole row/column)
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { SelectionRangeStyle } from './SelectionStyle';
|
|
2
|
+
/**
|
|
3
|
+
* The surface cell a touch grip holds while it drags: the corner it pulls, as the placement a tip hangs
|
|
4
|
+
* off (`null` between drags). The grips and the selection layer are siblings, so the layer learns of
|
|
5
|
+
* the drag here rather than from its own pointer tap.
|
|
6
|
+
*/
|
|
7
|
+
export declare const GRIP_DRAG_KEY = "selection-grip-drag";
|
|
2
8
|
/**
|
|
3
9
|
* Merge a {@link SelectionRangeStyle} override over a base, slot-by-slot (each rectangle merges
|
|
4
10
|
* independently).
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { CellCoords } from '@sheetxl/utils';
|
|
2
2
|
import { IGridPane } from '../surface';
|
|
3
|
+
/**
|
|
4
|
+
* A drag engine's pane: the pane itself, or a getter for the CURRENT one.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* A getter is what a hook passes. Panes are rebuilt on structural changes — including any model change
|
|
8
|
+
* that invalidates the grid — and a drag is transient UI that must outlive that: an engine built per pane
|
|
9
|
+
* would drop the gesture in flight the moment a live edit (a reference picked into a field that writes
|
|
10
|
+
* per change) touched the model.
|
|
11
|
+
*/
|
|
12
|
+
export type DragCellsPane = IGridPane | (() => IGridPane);
|
|
3
13
|
/**
|
|
4
14
|
* Repeat interval (ms) for the held-still auto-scroll. While a drag is parked past the viewport edge no
|
|
5
15
|
* pointer-move events fire, so the engine re-applies the drag at the last pointer position on this
|
|
@@ -36,6 +46,23 @@ export declare const edgeScrollPane: (pane: IGridPane, point: {
|
|
|
36
46
|
x?: boolean;
|
|
37
47
|
y?: boolean;
|
|
38
48
|
}) => boolean;
|
|
49
|
+
/**
|
|
50
|
+
* The modifier keys held during a drag — Excel's *mode* keys: Ctrl turns a move into a copy, Shift
|
|
51
|
+
* into an insert. Tracked by the engine off BOTH the pointer and the keyboard, so it stays true while
|
|
52
|
+
* the pointer stands still (pressing Ctrl fires no pointer event).
|
|
53
|
+
*/
|
|
54
|
+
export interface DragModifiers {
|
|
55
|
+
ctrlKey: boolean;
|
|
56
|
+
shiftKey: boolean;
|
|
57
|
+
altKey: boolean;
|
|
58
|
+
metaKey: boolean;
|
|
59
|
+
}
|
|
60
|
+
/** Nothing held — what a drag starts from unless its pointer-down says otherwise. */
|
|
61
|
+
export declare const NO_DRAG_MODIFIERS: DragModifiers;
|
|
62
|
+
/** Snapshot the modifier flags off any event that carries them (pointer, mouse, or keyboard). */
|
|
63
|
+
export declare const readDragModifiers: (e: Partial<DragModifiers>) => DragModifiers;
|
|
64
|
+
/** Whether two modifier snapshots describe the same held keys. */
|
|
65
|
+
export declare const isSameDragModifiers: (a: DragModifiers, b: DragModifiers) => boolean;
|
|
39
66
|
/**
|
|
40
67
|
* The in-flight gesture returned by {@link DragCellsOptions.onStart}. It carries the *policy* — how a
|
|
41
68
|
* given cell-drag mutates the model — while the engine owns the *mechanics* (pointer capture, `lastCell`
|
|
@@ -56,6 +83,25 @@ export interface DragCellsSession {
|
|
|
56
83
|
* (no pointer event fires while the pointer is parked past the edge), so treat it as optional.
|
|
57
84
|
*/
|
|
58
85
|
drag: (cell: CellCoords, e?: React.PointerEvent) => void;
|
|
86
|
+
/**
|
|
87
|
+
* The pointer is AT a position — fired on every move (including one that stays inside the cell it is
|
|
88
|
+
* already in) and on every held-still auto-scroll tick, right after any `drag` the same position
|
|
89
|
+
* triggered. For policies whose result is sub-cell, which the per-cell `drag` cannot express: a move
|
|
90
|
+
* drag's insert line snaps to the nearer HALF of the cell under the cursor, so it has to see the
|
|
91
|
+
* pointer cross a midpoint. `cell` is the cell resolved at that point; `e` is absent on an
|
|
92
|
+
* auto-scroll tick. Fires only when a cell resolved.
|
|
93
|
+
*
|
|
94
|
+
* It is called at pointer rate, so a consumer should report onward only what actually changed.
|
|
95
|
+
*/
|
|
96
|
+
point?: (cell: CellCoords, clientX: number, clientY: number, e?: React.PointerEvent) => void;
|
|
97
|
+
/**
|
|
98
|
+
* The held modifier keys CHANGED mid-drag — fired on every press/release of Ctrl / Shift / Alt / Meta
|
|
99
|
+
* (never on start, and only on an actual change). Excel's mode keys take effect the instant they are
|
|
100
|
+
* pressed, even with the pointer standing still — and a key press fires no pointer event, so `drag`
|
|
101
|
+
* alone can never see it. Wire this to whatever reflects the mode (a status description, a cursor, a
|
|
102
|
+
* drop preview).
|
|
103
|
+
*/
|
|
104
|
+
modifiers?: (mods: DragModifiers) => void;
|
|
59
105
|
/**
|
|
60
106
|
* The auto-scroll step: given the pointer's client `point`, scroll the viewport ONE cell toward any edge
|
|
61
107
|
* the pointer is at (see {@link edgeScrollPane}), and return whether an edge is still engaged so the
|
|
@@ -78,7 +124,7 @@ export interface DragCellsSession {
|
|
|
78
124
|
* Abort cleanup for a CANCELLED gesture — the OS/browser seized the pointer (`pointercancel`: a touch
|
|
79
125
|
* became a system pan/zoom, a pen left range, a window blurred), OR the user pressed **Escape**
|
|
80
126
|
* (Windows-style drag abort). The engine always runs the mechanical teardown (stop the auto-scroll
|
|
81
|
-
* timer,
|
|
127
|
+
* timer, release capture); this hook is for the policy's own rollback —
|
|
82
128
|
* restore the pre-drag selection, clear a rubber-band / preview — WITHOUT committing, since a cancel is
|
|
83
129
|
* an abort, not a release. {@link DragCellsSession.end} never runs on a cancel. The event is absent on
|
|
84
130
|
* an Escape abort (no pointer event drives it).
|
|
@@ -139,7 +185,7 @@ export interface DragCellsController {
|
|
|
139
185
|
onPointerUp: (e: React.PointerEvent) => void;
|
|
140
186
|
/** Abort the in-flight drag (see {@link DragCellsResult.onPointerCancel}). */
|
|
141
187
|
onPointerCancel: (e: React.PointerEvent) => void;
|
|
142
|
-
/** Stop the auto-scroll timer
|
|
188
|
+
/** Stop the auto-scroll timer. Call on unmount (the hook wires this). */
|
|
143
189
|
dispose: () => void;
|
|
144
190
|
}
|
|
145
191
|
/**
|
|
@@ -164,7 +210,7 @@ export interface DragCellsController {
|
|
|
164
210
|
* @param onDragModeChange Notified when the active session's `dragMode` changes (a hook turns this into
|
|
165
211
|
* React state); omit for a headless controller that doesn't surface it.
|
|
166
212
|
*/
|
|
167
|
-
export declare const createDragCells: (pane:
|
|
213
|
+
export declare const createDragCells: (pane: DragCellsPane, onStart: (cell: CellCoords, e: React.PointerEvent) => DragCellsSession | null, onDragModeChange?: (mode: string | null) => void) => DragCellsController;
|
|
168
214
|
/** The headless controller behind {@link useWindowDragCells}. */
|
|
169
215
|
export interface WindowDragCellsController {
|
|
170
216
|
/**
|
|
@@ -173,7 +219,13 @@ export interface WindowDragCellsController {
|
|
|
173
219
|
* `window` regardless, surviving the element repositioning / unmounting. Defaults to `e.currentTarget`.
|
|
174
220
|
*/
|
|
175
221
|
start: (e: React.PointerEvent, cursorEl?: Element | null) => void;
|
|
176
|
-
/**
|
|
222
|
+
/**
|
|
223
|
+
* Abort the in-flight gesture exactly as Escape does: the session's `cancel` rollback, no commit. A
|
|
224
|
+
* no-op between gestures. For a cancel offered by chrome (the status bar's ✕), which a phone needs
|
|
225
|
+
* because it has no Escape.
|
|
226
|
+
*/
|
|
227
|
+
cancel: () => void;
|
|
228
|
+
/** Stop any in-flight gesture (drop the `window` listeners + timer). Call on unmount. */
|
|
177
229
|
dispose: () => void;
|
|
178
230
|
}
|
|
179
231
|
/**
|
|
@@ -187,15 +239,16 @@ export interface WindowDragCellsController {
|
|
|
187
239
|
* The source element is still pointer-captured (for its CURSOR only — see {@link WindowDragCellsController.start});
|
|
188
240
|
* the actual move / up / cancel are `window` listeners, so a re-render or unmount of the handle never
|
|
189
241
|
* interrupts the gesture. Consumers supply `onStart` policy exactly as for the tap engine, and get the
|
|
190
|
-
* same held-still auto-scroll,
|
|
242
|
+
* same held-still auto-scroll, per-cell de-dup, and abort-on-cancel.
|
|
191
243
|
*/
|
|
192
|
-
export declare function createWindowDragCells(pane:
|
|
244
|
+
export declare function createWindowDragCells(pane: DragCellsPane, onStart: (cell: CellCoords, e: React.PointerEvent) => DragCellsSession | null, onDragModeChange?: (mode: string | null) => void,
|
|
193
245
|
/** Override cell resolution (a touch grip resolves against the pane the finger is over). */
|
|
194
246
|
resolveCell?: (clientX: number, clientY: number) => CellCoords | null): WindowDragCellsController;
|
|
195
247
|
/**
|
|
196
248
|
* The React hook over {@link createDragCells}: reads the pane from context, owns the `dragMode` state,
|
|
197
|
-
* and stops the auto-scroll timer on unmount. `onStart`
|
|
198
|
-
* closure over changing values (selection, options) needs no handler rebuild
|
|
249
|
+
* and stops the auto-scroll timer on unmount. `onStart` and the pane are read live, so a consumer's
|
|
250
|
+
* closure over changing values (selection, options) needs no handler rebuild — and a pane rebuilt
|
|
251
|
+
* mid-drag does not end the drag (see {@link DragCellsPane}).
|
|
199
252
|
*/
|
|
200
253
|
export declare const useDragCells: (onStart: (cell: CellCoords, e: React.PointerEvent) => DragCellsSession | null) => DragCellsResult;
|
|
201
254
|
/** Handlers + transient `dragMode` produced by {@link useWindowDragCells}. */
|
|
@@ -206,13 +259,16 @@ export interface WindowDragCellsResult {
|
|
|
206
259
|
* `currentTarget` other than that element (e.g. a grip below an interactive child).
|
|
207
260
|
*/
|
|
208
261
|
start: (e: React.PointerEvent, cursorEl?: Element | null) => void;
|
|
262
|
+
/** Abort the in-flight gesture as Escape does (see {@link WindowDragCellsController.cancel}). */
|
|
263
|
+
cancel: () => void;
|
|
209
264
|
/** The active session's `dragMode`, or `null` between drags (flips only on start / end). */
|
|
210
265
|
dragMode: string | null;
|
|
211
266
|
}
|
|
212
267
|
/**
|
|
213
268
|
* The React hook over {@link createWindowDragCells}: reads the pane from context, owns the `dragMode`
|
|
214
269
|
* state, and disposes the gesture on unmount. For handle / grip flavors (fill, resize, move, touch grips)
|
|
215
|
-
* whose element repositions or unmounts mid-drag. `onStart`
|
|
270
|
+
* whose element repositions or unmounts mid-drag. `onStart` and the pane are read live, as in
|
|
271
|
+
* {@link useDragCells}.
|
|
216
272
|
*/
|
|
217
273
|
export declare const useWindowDragCells: (onStart: (cell: CellCoords, e: React.PointerEvent) => DragCellsSession | null) => WindowDragCellsResult;
|
|
218
274
|
//# sourceMappingURL=useDragCells.d.ts.map
|
|
@@ -35,6 +35,8 @@ export interface GridPaneDef {
|
|
|
35
35
|
rowIndex: number;
|
|
36
36
|
elemStage: React.ReactNode;
|
|
37
37
|
refStage: IStageElement | null;
|
|
38
|
+
/** See {@link IGridPane.registerFocusTarget}. */
|
|
39
|
+
focusTarget?: (() => HTMLElement | null) | null;
|
|
38
40
|
scrollOrientation: OrientationFlags;
|
|
39
41
|
insets: Rectangle;
|
|
40
42
|
}
|
|
@@ -6,9 +6,22 @@ import { IGridMetrics } from '../metrics';
|
|
|
6
6
|
*/
|
|
7
7
|
export interface IGridPane {
|
|
8
8
|
/**
|
|
9
|
-
* Sets focus to the view.
|
|
9
|
+
* Sets focus to the view: its surface, or its {@link getFocusTarget | focus target} when there is one.
|
|
10
10
|
*/
|
|
11
11
|
focus(options?: FocusOptions): void;
|
|
12
|
+
/**
|
|
13
|
+
* Register a focus target: an element inside the pane that takes the pane's focus in place of its
|
|
14
|
+
* surface while `target` returns it. A key aimed at it is a key aimed at the surface. The latest
|
|
15
|
+
* registration wins.
|
|
16
|
+
*
|
|
17
|
+
* @param target Asked each time the pane is focused; `null` lets the surface take focus.
|
|
18
|
+
*/
|
|
19
|
+
registerFocusTarget(target: () => HTMLElement | null): RemoveListener;
|
|
20
|
+
/**
|
|
21
|
+
* The element focusing the pane lands on in place of its surface right now, or `null` for the
|
|
22
|
+
* surface itself.
|
|
23
|
+
*/
|
|
24
|
+
getFocusTarget(): HTMLElement | null;
|
|
12
25
|
/**
|
|
13
26
|
* Set pointer capture to the view.
|
|
14
27
|
*/
|
|
@@ -161,7 +174,7 @@ export interface IGridPane {
|
|
|
161
174
|
* For the freeze STRUCTURE use {@link getAllPanes} — the `Top` / `Left` / `TopLeft` entries exist only
|
|
162
175
|
* when frozen — and each frozen pane's {@link getPaneRange} is exactly its frozen cell band, so
|
|
163
176
|
* `getPaneRange().colEnd + 1` / `.rowEnd + 1` gives the frozen column / row COUNT. The configured
|
|
164
|
-
* freeze count as a model value lives on `
|
|
177
|
+
* freeze count as a model value lives on `IWorksheetView.getFreezePanes().coords`.
|
|
165
178
|
*/
|
|
166
179
|
getFreezeTopLeft(): TopLeft;
|
|
167
180
|
/**
|
|
@@ -36,7 +36,7 @@ export interface SurfaceStateProviderProps {
|
|
|
36
36
|
*
|
|
37
37
|
* 1. an explicit {@link SurfaceStateProviderProps.store} prop (override);
|
|
38
38
|
* 2. a store **inherited** from an ancestor `SurfaceStateProvider` — so a wider parent (e.g. a
|
|
39
|
-
* `
|
|
39
|
+
* `WorksheetElement` wrapping its top-left corner + both header `GridSurface`s + the main `GridSurface`)
|
|
40
40
|
* shares one scope across sibling surfaces, letting a layer keyed the same in a header and in the body
|
|
41
41
|
* read one cell;
|
|
42
42
|
* 3. otherwise a **lazily-created own** store (the standalone default).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AnchorLocation } from '@sheetxl/utils';
|
|
2
|
+
import { IGridPane } from './IGridPane';
|
|
3
|
+
/**
|
|
4
|
+
* The pane to use when no particular pane is called for: the one that owns a once-per-grid job, or
|
|
5
|
+
* takes focus and scrolling with nothing else to go by. The center (scrolling) pane when there is
|
|
6
|
+
* one, else the first frozen pane.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* The center pane is not always there: a freeze larger than the view leaves it no room, and the grid
|
|
10
|
+
* builds no pane without room. `null` only while the grid has no panes at all (it has no size).
|
|
11
|
+
*/
|
|
12
|
+
export declare const getPrimaryPane: (panes: Readonly<Partial<Record<AnchorLocation, IGridPane>>>) => IGridPane | null;
|
|
13
|
+
//# sourceMappingURL=getPrimaryPane.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import { SurfaceStateStore } from './SurfaceStateProvider';
|
|
2
3
|
/**
|
|
3
4
|
* Like {@link React.useState}, but the cell is **keyed** and scoped to the enclosing {@link GridSurface},
|
|
4
5
|
* so every pane that renders this layer reads/writes the SAME cell — writing it from the pane that owns a
|
|
@@ -19,4 +20,22 @@ import { Dispatch, SetStateAction } from 'react';
|
|
|
19
20
|
* store, so it still behaves like ordinary local state.
|
|
20
21
|
*/
|
|
21
22
|
export declare function useSurfaceState<T>(key: string, initialValue: T | (() => T)): [T, Dispatch<SetStateAction<T>>];
|
|
23
|
+
/**
|
|
24
|
+
* The setter half of {@link useSurfaceState}, for a producer that writes a cell but never reads it. It does
|
|
25
|
+
* not subscribe, so writing the cell (e.g. on every move of a drag) does not re-render the producer.
|
|
26
|
+
*
|
|
27
|
+
* @param key The cell's key, as given to `useSurfaceState`.
|
|
28
|
+
* @param initialValue The value an updater function receives while the cell has never been written.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useSurfaceStateSetter<T>(key: string, initialValue: T): Dispatch<SetStateAction<T>>;
|
|
31
|
+
/**
|
|
32
|
+
* Read one {@link useSurfaceState} cell from a given store — for the component that OWNS the store and so
|
|
33
|
+
* sits above its {@link SurfaceStateProvider} (it passes the store to the provider and reads it here).
|
|
34
|
+
* Read-only; re-renders when the cell changes.
|
|
35
|
+
*
|
|
36
|
+
* @param store The store handed to the provider (from {@link createSurfaceStateStore}).
|
|
37
|
+
* @param key The cell's key, as given to `useSurfaceState`.
|
|
38
|
+
* @param initialValue The value while the cell has never been written.
|
|
39
|
+
*/
|
|
40
|
+
export declare function useSurfaceStateValue<T>(store: SurfaceStateStore, key: string, initialValue: T): T;
|
|
22
41
|
//# sourceMappingURL=useSurfaceState.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a moving range outline glides between cells. What travels with it — its corner handles, its
|
|
3
|
+
* gesture tip — rides the same timing, or it reads as trailing.
|
|
4
|
+
*/
|
|
5
|
+
export declare const RANGE_GLIDE: {
|
|
6
|
+
readonly duration: 60;
|
|
7
|
+
readonly easing: "ease-in-out";
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=_Glide.d.ts.map
|
|
@@ -48,7 +48,7 @@ export interface GridThemeCSSOptions {
|
|
|
48
48
|
/**
|
|
49
49
|
* grid-react's theme stylesheet — the app baseline (utils-react `defaultTheme`, or a passed one) + the
|
|
50
50
|
* `grid` / `header` surface overrides, compiled to the `data-sxl-theme-*` attribute matrix. Called by the
|
|
51
|
-
* react `
|
|
51
|
+
* react `WorksheetElement` with neutral defaults into `@layer sxl-defaults` (so even a chromeless sheet is
|
|
52
52
|
* themed), and by studio-mui with MUI-derived values into `sxl-app` on top; clients override in
|
|
53
53
|
* `sxl-overrides`. Consumers just set `data-sxl-theme-*` attributes.
|
|
54
54
|
*/
|