@sheetxl/grid-react 0.7.27 → 0.7.28-beta.2
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 -1503
- package/types/src/cell/CellLayer.d.ts +70 -0
- package/types/src/cell/CellRenderer.d.ts +42 -0
- package/types/src/cell/DefaultCellRenderer.d.ts +6 -0
- package/types/src/cell/GridlineLayer.d.ts +38 -0
- package/types/src/cell/Types.d.ts +12 -0
- package/types/src/cell/_CellModel.d.ts +82 -0
- package/types/src/cell/index.d.ts +6 -0
- package/types/src/editor/DefaultEditable.d.ts +121 -0
- package/types/src/editor/EditSession.d.ts +182 -0
- package/types/src/editor/EditState.d.ts +61 -0
- package/types/src/editor/EditorDiv.d.ts +65 -0
- package/types/src/editor/EditorInput.d.ts +88 -0
- package/types/src/editor/EditorLayer.d.ts +69 -0
- package/types/src/editor/EditorPlacement.d.ts +38 -0
- package/types/src/editor/index.d.ts +10 -0
- package/types/src/editor/useEditorKeymap.d.ts +74 -0
- package/types/src/grid/Grid.d.ts +16 -0
- package/types/src/grid/IGrid.d.ts +93 -0
- package/types/src/grid/index.d.ts +3 -0
- package/types/src/header/HeaderDividerAnchor.d.ts +120 -0
- package/types/src/header/index.d.ts +3 -0
- package/types/src/header/useHeaderSelectionPointer.d.ts +122 -0
- package/types/src/index.d.ts +13 -0
- package/types/src/layer/HoverTipLayer.d.ts +74 -0
- package/types/src/layer/Layer.d.ts +92 -0
- package/types/src/layer/LayerTypes.d.ts +47 -0
- package/types/src/layer/RangePrompt.d.ts +42 -0
- package/types/src/layer/Stage.d.ts +147 -0
- package/types/src/layer/StickyAnchor.d.ts +83 -0
- package/types/src/layer/StickyFloat.d.ts +65 -0
- package/types/src/layer/VirtualDiv.d.ts +59 -0
- package/types/src/layer/_Utils.d.ts +37 -0
- package/types/src/layer/index.d.ts +11 -0
- package/types/src/layer/useGridAnchor.d.ts +157 -0
- package/types/src/layer/useHoverIntent.d.ts +49 -0
- package/types/src/layer/useLayerResponder.d.ts +29 -0
- package/types/src/layer/usePlacement.d.ts +18 -0
- package/types/src/layer/useRangeHover.d.ts +35 -0
- package/types/src/list/CheckboxList.d.ts +63 -0
- package/types/src/list/List.d.ts +55 -0
- package/types/src/list/index.d.ts +3 -0
- package/types/src/metrics/Types.d.ts +23 -0
- package/types/src/metrics/index.d.ts +3 -0
- package/types/src/metrics/useGridMetrics.d.ts +67 -0
- package/types/src/range/DragHandle.d.ts +129 -0
- package/types/src/range/Draggable.d.ts +86 -0
- package/types/src/range/FillHandle.d.ts +54 -0
- package/types/src/range/RangeRect.d.ts +36 -0
- package/types/src/range/RangeResizer.d.ts +68 -0
- package/types/src/range/RangeStyle.d.ts +8 -0
- package/types/src/range/index.d.ts +13 -0
- package/types/src/selection/DefaultSelection.d.ts +59 -0
- package/types/src/selection/ICellAnchor.d.ts +21 -0
- package/types/src/selection/ISelection.d.ts +65 -0
- package/types/src/selection/RangesPickerLayer.d.ts +128 -0
- package/types/src/selection/SelectionLayer.d.ts +179 -0
- package/types/src/selection/SelectionStyle.d.ts +28 -0
- package/types/src/selection/SelectionTouchGrips.d.ts +29 -0
- package/types/src/selection/SelectionUtils.d.ts +2 -0
- package/types/src/selection/Types.d.ts +67 -0
- package/types/src/selection/_SelectionNavigation.d.ts +6 -0
- package/types/src/selection/_SelectionUtils.d.ts +7 -0
- package/types/src/selection/index.d.ts +12 -0
- package/types/src/selection/useDragCells.d.ts +218 -0
- package/types/src/selection/useSelectionPointer.d.ts +70 -0
- package/types/src/surface/GridPane.d.ts +85 -0
- package/types/src/surface/GridPaneProvider.d.ts +37 -0
- package/types/src/surface/GridSurface.d.ts +11 -0
- package/types/src/surface/IGridPane.d.ts +288 -0
- package/types/src/surface/IGridSurface.d.ts +141 -0
- package/types/src/surface/SurfaceStateProvider.d.ts +50 -0
- package/types/src/surface/_GridUtils.d.ts +37 -0
- package/types/src/surface/index.d.ts +7 -0
- package/types/src/surface/useGridPane.d.ts +31 -0
- package/types/src/surface/useSurfaceState.d.ts +22 -0
- package/types/src/svg/LineSVG.d.ts +13 -0
- package/types/src/svg/RectangleSVG.d.ts +114 -0
- package/types/src/svg/ShapeBounds.d.ts +15 -0
- package/types/src/svg/Types.d.ts +37 -0
- package/types/src/svg/index.d.ts +9 -0
- package/types/src/theme/GridTheme.d.ts +56 -0
- package/types/src/theme/index.d.ts +2 -0
- package/node/assets/style.css +0 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { VisualSVGProps } from '../svg';
|
|
3
|
+
import { HandleAnchor, DragHandleRenderProps } from '../range';
|
|
4
|
+
import { LayerProps } from '../layer';
|
|
5
|
+
import { ISelection } from './ISelection';
|
|
6
|
+
/**
|
|
7
|
+
* The range-reference palette, in rotation order. The default {@link RangesPickerLayer} look cycles `stroke`
|
|
8
|
+
* through this so each range gets its own color — `PICKER_COLORS[i % length]` — and the fill is derived
|
|
9
|
+
* automatically (a low-alpha tint of the same color).
|
|
10
|
+
*
|
|
11
|
+
* These are the shared `--sxl-color-series-*` theme tokens (the SAME hues the formula editor colors reference
|
|
12
|
+
* text with, so a range's text and its rectangle match), so they follow light/dark automatically. The literal
|
|
13
|
+
* fallback keeps a bare (un-themed) grid — storybook / SDK-free reference use — colored.
|
|
14
|
+
*/
|
|
15
|
+
export declare const PICKER_COLORS: readonly string[];
|
|
16
|
+
/**
|
|
17
|
+
* Props for {@link RangesPickerLayer}. It **renders a {@link Layer}** at its root (extends
|
|
18
|
+
* {@link LayerProps}: `zIndex`, tap handlers), so a consumer stacks it like any layer. The shared
|
|
19
|
+
* base outline look for every range is {@link RangesPickerLayerProps.rangeStyle}, with
|
|
20
|
+
* {@link RangesPickerLayerProps.getRangeStyle} overriding per range (default: cycle `stroke`
|
|
21
|
+
* through the {@link PICKER_COLORS}).
|
|
22
|
+
*/
|
|
23
|
+
export interface RangesPickerLayerProps extends LayerProps {
|
|
24
|
+
/** Shared base outline look for every range (`stroke`, `strokeWidth`, …), merged UNDER `getRangeStyle`. */
|
|
25
|
+
rangeStyle?: VisualSVGProps;
|
|
26
|
+
/**
|
|
27
|
+
* The selection model this layer renders + edits (like {@link SelectionLayer}, and typically a
|
|
28
|
+
* `SheetSelection` over an sdk `IRangeSelection.createSelection()`). It reads the model's
|
|
29
|
+
* {@link SelectionCoords} — one resizable + movable rectangle per range, the `rangeIndex` range
|
|
30
|
+
* **active** — and writes every move / resize / draw back through `setSelection`, setting
|
|
31
|
+
* `rangeIndex` to the edited range so a text-backed model can rewrite exactly that reference.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Unlike {@link SelectionLayer} it renders *only ranges* (never an anchor cell — Excel doesn't draw
|
|
35
|
+
* the formula's home). A gesture over an empty picker (or a click while the caret isn't on a reference)
|
|
36
|
+
* APPENDS a new range, so it doubles as the "insert a new reference" surface.
|
|
37
|
+
*/
|
|
38
|
+
selection: ISelection;
|
|
39
|
+
/**
|
|
40
|
+
* Per-range outline props, merged over the layer's shared base ({@link VisualSVGProps}). Receives the
|
|
41
|
+
* range `index` and whether it's `active`. Defaults to cycling `stroke` through {@link PICKER_COLORS}
|
|
42
|
+
* (`PICKER_COLORS[index % length]`). The layer still derives the fill (a low-alpha tint of `stroke`
|
|
43
|
+
* unless you set `fill`), the active animation, and the hover/drag emphasis on top of what you return.
|
|
44
|
+
*
|
|
45
|
+
* Return `null` to OMIT that range from this layer entirely — no outline, no resize/move handles, not
|
|
46
|
+
* interactive. The model (`selection`) is untouched; this is a per-INSTANCE render filter, not a data
|
|
47
|
+
* filter. Lets a consumer share one multi-range model across several layers and have each show only
|
|
48
|
+
* the subset relevant to it (e.g. a formula's references split across per-sheet panes) with no index
|
|
49
|
+
* remapping — writes still go back through `selection.setSelection` at the range's real, unfiltered
|
|
50
|
+
* index, since the model itself was never filtered.
|
|
51
|
+
*/
|
|
52
|
+
getRangeStyle?: (index: number, active: boolean) => VisualSVGProps | null;
|
|
53
|
+
/**
|
|
54
|
+
* Which resize handles to show. @defaultValue {@link RESIZE_ANCHORS_4} (corners). Pass
|
|
55
|
+
* {@link RESIZE_ANCHORS_8} for corners + edge midpoints.
|
|
56
|
+
*/
|
|
57
|
+
anchors?: readonly HandleAnchor[];
|
|
58
|
+
/** Enable the move grip (drag the border to relocate a range, keeping its size). @defaultValue false */
|
|
59
|
+
enabledMove?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Don't claim the grid-wide **draw** gesture — the pointer-drag over empty grid that re-scopes the
|
|
62
|
+
* **active** range from scratch. Ranges stay movable/resizable via their border + corners.
|
|
63
|
+
* @defaultValue false
|
|
64
|
+
*/
|
|
65
|
+
disableDraw?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Allow Ctrl/Cmd+click (and drag) on the draw surface to **append** a brand-new range even while a
|
|
68
|
+
* range is active — the multi-range pick gesture (Excel point mode's Ctrl+click; a text-backed
|
|
69
|
+
* consumer renders the appended range after a `,` separator). Set `false` for a picker whose value
|
|
70
|
+
* is a single rectangle (a chart series / table range field): the modifier is then ignored and the
|
|
71
|
+
* gesture is a plain draw. There is deliberately no Ctrl+click *deselect* counterpart (unlike the
|
|
72
|
+
* body selection's `useSelectionPointer`) — Excel does not remove a reference by clicking it.
|
|
73
|
+
*
|
|
74
|
+
* @defaultValue true
|
|
75
|
+
*/
|
|
76
|
+
allowMulti?: boolean;
|
|
77
|
+
/** Resize handle size (px). @defaultValue 8 */
|
|
78
|
+
size?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Animate the **active** range's outline with a marching-ants stroke (the others stay static).
|
|
81
|
+
*
|
|
82
|
+
* @defaultValue false
|
|
83
|
+
*/
|
|
84
|
+
animated?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Render the resize corner grips yourself (headless) — forwarded to {@link RangeResizer}'s
|
|
87
|
+
* `renderHandle` per anchor. Replaces the default grips.
|
|
88
|
+
*/
|
|
89
|
+
renderHandle?: (props: DragHandleRenderProps) => React.ReactNode;
|
|
90
|
+
/**
|
|
91
|
+
* Keep whatever had focus across a drag (draw / move / resize) rather than letting the gesture move
|
|
92
|
+
* focus to the grid's `tabIndex` Stage. The picker is used *while editing a formula*, so a handle drag
|
|
93
|
+
* must not blur the editor's textarea — it preserves the existing focus (nothing to restore). Turn off
|
|
94
|
+
* only for a picker used outside an editor. @defaultValue true
|
|
95
|
+
*/
|
|
96
|
+
preserveFocus?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Called when a rectangle gesture (draw / move / resize) starts (`true`) and ends (`false`) — one
|
|
99
|
+
* aggregated signal across all of them. Lets a host react to "a reference drag is in progress" as a whole,
|
|
100
|
+
* e.g. the formula editor hiding its hint popup for the duration. `index` is the range being moved/resized
|
|
101
|
+
* (so a host can highlight exactly that reference), or `null` for a DRAW (no existing range yet) / idle.
|
|
102
|
+
*/
|
|
103
|
+
onDragActiveChange?: (active: boolean, index: number | null) => void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The default per-range look: cycle the stroke through {@link PICKER_COLORS}. Exported so a consumer
|
|
107
|
+
* wrapping {@link RangesPickerLayerProps.getRangeStyle} (e.g. to add a per-instance visibility filter —
|
|
108
|
+
* see that prop's doc) can fall back to it instead of reimplementing the color cycle.
|
|
109
|
+
*/
|
|
110
|
+
export declare const defaultRangeStyle: (index: number) => VisualSVGProps;
|
|
111
|
+
/**
|
|
112
|
+
* A **multi-rectangle** range picker — each rectangle resizable + movable — used to re-scope a set of
|
|
113
|
+
* **formula references** or a **chart's data ranges**. Like {@link SelectionLayer} it binds to an
|
|
114
|
+
* {@link ISelection} model, but it renders *only ranges* (never an anchor cell — Excel doesn't draw the
|
|
115
|
+
* formula's home).
|
|
116
|
+
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* Each range is a {@link RangeResizer} (outline + corners) wrapped in a {@link Draggable}
|
|
119
|
+
* (border-ring move), colored from {@link RangesPickerLayerProps.getRangeStyle} (default: cycle
|
|
120
|
+
* {@link PICKER_COLORS}). The model's `rangeIndex` range is **active** — the grid draw re-scopes it and it
|
|
121
|
+
* animates; interacting with a range makes it active. Every gesture writes back through
|
|
122
|
+
* `selection.setSelection`, setting `rangeIndex` to the edited range. A draw while the caret isn't on a
|
|
123
|
+
* reference (`rangeIndex < 0`) APPENDS a new range instead (insert / draw-from-empty). Shift+draw
|
|
124
|
+
* EXTENDS the active range from its start corner; Ctrl/Cmd+draw appends a new range even while one is
|
|
125
|
+
* active (gated by {@link RangesPickerLayerProps.allowMulti}).
|
|
126
|
+
*/
|
|
127
|
+
export declare const RangesPickerLayer: React.FC<RangesPickerLayerProps>;
|
|
128
|
+
//# sourceMappingURL=RangesPickerLayer.d.ts.map
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { CellCoords, RangeCoords } from '@sheetxl/utils';
|
|
3
|
+
import { LayerProps, GridPlacement } from '../layer';
|
|
4
|
+
import { VisualSVGProps } from '../svg';
|
|
5
|
+
import { ISelection } from './ISelection';
|
|
6
|
+
import { SelectionNavigation } from './Types';
|
|
7
|
+
import { SelectionRangeStyle } from './SelectionStyle';
|
|
8
|
+
/**
|
|
9
|
+
* The in-flight selection gesture passed to {@link SelectionLayerProps.renderTip}:
|
|
10
|
+
* - `select` — a drag-select growing the active range (Excel's live R×C);
|
|
11
|
+
* - `move` — the built-in move grip (border drag); `to` is the in-flight destination;
|
|
12
|
+
* - `fill` — the fill handle; `destination` is the in-flight fill range.
|
|
13
|
+
*/
|
|
14
|
+
export type SelectionGesture = {
|
|
15
|
+
kind: 'select';
|
|
16
|
+
range: RangeCoords;
|
|
17
|
+
} | {
|
|
18
|
+
kind: 'move';
|
|
19
|
+
from: RangeCoords;
|
|
20
|
+
to: RangeCoords;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'fill';
|
|
23
|
+
template: RangeCoords;
|
|
24
|
+
destination: RangeCoords;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Props for {@link SelectionLayer}.
|
|
28
|
+
*/
|
|
29
|
+
export interface SelectionLayerProps extends LayerProps {
|
|
30
|
+
/**
|
|
31
|
+
* The writable selection model this layer owns.
|
|
32
|
+
*/
|
|
33
|
+
selection: ISelection;
|
|
34
|
+
/**
|
|
35
|
+
* The content (used-range) bounds the `…End` keys (End / Ctrl+End) jump to. Supply it from a tier that
|
|
36
|
+
* knows the used range (the sheet layer) so those keys land on the last cell *with content*; omit it
|
|
37
|
+
* and they fall back to the grid edge (correct for the dumb {@link DefaultSelection} tier, which has no
|
|
38
|
+
* used range). It stays a plain bounds getter here — the layer never learns it's a sheet.
|
|
39
|
+
*/
|
|
40
|
+
getContentBounds?: () => RangeCoords;
|
|
41
|
+
/**
|
|
42
|
+
* The bounding REGION enclosing a cell — a table's data range from a tier that knows tables (the sheet
|
|
43
|
+
* layer), else `null` (the bare sheet). Drives Tab/Enter wrapping inside a table and the row/column
|
|
44
|
+
* span of Ctrl/Shift+Space. Omit it (the dumb {@link DefaultSelection} tier) and there is no enclosing
|
|
45
|
+
* region: Tab is a plain move and Ctrl/Shift+Space select the whole grid. The layer never learns it's a
|
|
46
|
+
* sheet — just a `cell → bounds | null` getter; any escalation lives in the provider.
|
|
47
|
+
*/
|
|
48
|
+
getRegionBounds?: (cell: CellCoords) => RangeCoords | null;
|
|
49
|
+
/**
|
|
50
|
+
* The scroll executor for keyboard selection. Supply it from a tier that OWNS scrolling — e.g. the
|
|
51
|
+
* sheet layer, which routes to `sheet.scrollTo` so the UI and scripting scroll through one path. When
|
|
52
|
+
* supplied, the layer delegates every keyboard scroll here and lets the model own the arrow-`navigate`
|
|
53
|
+
* scroll (it already scrolls to the moved edge) so the two don't compete. When omitted, the layer
|
|
54
|
+
* scrolls its own pane (correct for a standalone grid, whose {@link DefaultSelection} has no sheet).
|
|
55
|
+
*/
|
|
56
|
+
scrollIntoView?: (cell: Partial<CellCoords>) => void;
|
|
57
|
+
/** The single-range look. Merged (slot-by-slot) over {@link DEFAULT_SINGLE_STYLE}. */
|
|
58
|
+
singleStyle?: SelectionRangeStyle;
|
|
59
|
+
/** The multi-range look. Merged (slot-by-slot) over {@link DEFAULT_MULTI_STYLE}. */
|
|
60
|
+
multiStyle?: SelectionRangeStyle;
|
|
61
|
+
/** The active-cell border within a **multi**-range selection. Merged over {@link DEFAULT_ANCHOR_STYLE}. */
|
|
62
|
+
multiAnchorStyle?: VisualSVGProps;
|
|
63
|
+
/**
|
|
64
|
+
* A border drawn on the active cell within a **single**-range selection. Off by default (Excel draws
|
|
65
|
+
* none — the selection rectangle is the only outline). Set it to mark the anchor when the fill covers
|
|
66
|
+
* the whole row (see {@link SelectionLayerProps.anchorHole}) — e.g. a list's focus ring. An `inset`
|
|
67
|
+
* border stays within the row, so it never clips at the viewport edge.
|
|
68
|
+
*/
|
|
69
|
+
singleAnchorStyle?: VisualSVGProps;
|
|
70
|
+
/** The Ctrl/Cmd-drag remove rubber-band. Merged (slot-by-slot) over {@link DEFAULT_REMOVE_PREVIEW_STYLE}. */
|
|
71
|
+
removePreviewStyle?: SelectionRangeStyle;
|
|
72
|
+
/**
|
|
73
|
+
* Stacked layers (fill, move, …) rendered when a single range is selected.
|
|
74
|
+
*/
|
|
75
|
+
singleLayer?: React.ReactNode;
|
|
76
|
+
/**
|
|
77
|
+
* Stacked layers rendered when multiple ranges are selected.
|
|
78
|
+
*/
|
|
79
|
+
multiLayer?: React.ReactNode;
|
|
80
|
+
/**
|
|
81
|
+
* Disable the built-in move grip on a single range (drag the border to move it, Excel-style).
|
|
82
|
+
*
|
|
83
|
+
* @defaultValue false
|
|
84
|
+
*/
|
|
85
|
+
enabledMove?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Called when the single range is moved by its border — `from` is the original range, `to` the new
|
|
88
|
+
* one. The selection follows automatically; use this for the data side-effect (cut-move).
|
|
89
|
+
*/
|
|
90
|
+
onMove?: (from: RangeCoords, to: RangeCoords, e: React.PointerEvent) => void;
|
|
91
|
+
/** The move drag started (before any translation) — `from` is the range being moved. */
|
|
92
|
+
onMoveStart?: (from: RangeCoords, e: React.PointerEvent) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Live during the move drag — `to` is the in-flight translated range. `e` carries the current
|
|
95
|
+
* modifiers (Ctrl = copy, Shift = insert), so a consumer can reflect the mode (cursor/description).
|
|
96
|
+
*/
|
|
97
|
+
onMoveUpdate?: (from: RangeCoords, to: RangeCoords, e: React.PointerEvent) => void;
|
|
98
|
+
/**
|
|
99
|
+
* The move drag ended (fires on release regardless of whether the range actually moved) — for teardown
|
|
100
|
+
* of anything {@link SelectionLayerProps.onMoveStart}/`onMoveUpdate` set (e.g. clearing a drag mode).
|
|
101
|
+
*/
|
|
102
|
+
onMoveEnd?: () => void;
|
|
103
|
+
/**
|
|
104
|
+
* Enable the built-in fill handle on a single range (the Excel fill square at the bottom-right
|
|
105
|
+
* corner; drag to fill). Opt-in (unlike the always-on move grip) because it adds a visible handle.
|
|
106
|
+
*
|
|
107
|
+
* @defaultValue false
|
|
108
|
+
*/
|
|
109
|
+
enableFill?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Called when the single range is filled via the handle — `template` is the source range, `destination`
|
|
112
|
+
* the filled range (which includes the template). The selection extends to `destination` automatically;
|
|
113
|
+
* use this for the data side-effect (the actual fill).
|
|
114
|
+
*/
|
|
115
|
+
onFill?: (template: RangeCoords, destination: RangeCoords, e: React.PointerEvent) => void;
|
|
116
|
+
/**
|
|
117
|
+
* Adjust the raw fill destination before it drives the preview + fill callbacks — e.g. snap the fill
|
|
118
|
+
* edge to a merged-cell boundary so the dashed preview and the committed fill agree and never land on
|
|
119
|
+
* an illegal interval. Given the template and the pointer-derived destination, return the destination
|
|
120
|
+
* to use. Omit for no snapping.
|
|
121
|
+
*/
|
|
122
|
+
snapFillDestination?: (template: RangeCoords, destination: RangeCoords) => RangeCoords;
|
|
123
|
+
/** The fill drag started — `template` is the source range. */
|
|
124
|
+
onFillStart?: (template: RangeCoords, e: React.PointerEvent) => void;
|
|
125
|
+
/**
|
|
126
|
+
* Live during the fill drag — `destination` is the in-flight fill range (incl. the template). Use it
|
|
127
|
+
* to preview what will be filled (e.g. a value tooltip). The fill axis is `template` vs `destination`.
|
|
128
|
+
*/
|
|
129
|
+
onFillPreview?: (template: RangeCoords, destination: RangeCoords, e: React.PointerEvent) => void;
|
|
130
|
+
/**
|
|
131
|
+
* The fill drag ended (fires on release regardless of whether a fill was drawn) — for teardown of
|
|
132
|
+
* anything {@link SelectionLayerProps.onFillPreview} set (e.g. closing the preview tooltip).
|
|
133
|
+
*/
|
|
134
|
+
onFillEnd?: () => void;
|
|
135
|
+
/**
|
|
136
|
+
* Fired when a selection pointer interaction ends (click/drag settled) — "act on the just-selected
|
|
137
|
+
* range" (e.g. the format painter applies the copied format to the new selection). See
|
|
138
|
+
* {@link SelectionPointerOptions.onSelectionEnd}.
|
|
139
|
+
*/
|
|
140
|
+
onSelectionEnd?: (e: React.PointerEvent) => void;
|
|
141
|
+
/**
|
|
142
|
+
* Render a transient tip during a gesture — a drag-select ({@link SelectionGesture} `select`, live
|
|
143
|
+
* R×C), a move (`move`, the destination address), or a fill (`fill`, the preview). Return a falsy node
|
|
144
|
+
* for no tip (e.g. skip a 1×1 drag-select). The tip floats on the in-flight range (non-interactive).
|
|
145
|
+
*/
|
|
146
|
+
renderTip?: (gesture: SelectionGesture) => React.ReactNode;
|
|
147
|
+
/** Placement of the gesture tip relative to the in-flight range. @defaultValue `{ side: 'b', align: 'end' }` */
|
|
148
|
+
tipPlacement?: GridPlacement;
|
|
149
|
+
/**
|
|
150
|
+
* Disable the layer's **built-in keyboard** routing (arrows → {@link ISelection.navigate}, Tab/Enter
|
|
151
|
+
* → {@link ISelection.traverse}) so an external command system owns the keyboard instead — without it,
|
|
152
|
+
* both would fire the same navigation. Pointer routing is unaffected.
|
|
153
|
+
*
|
|
154
|
+
* @defaultValue false
|
|
155
|
+
*/
|
|
156
|
+
disableKeyboard?: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Cut the active (anchor) cell out of the fill — the Excel "current cell" cutout. For a selection that
|
|
159
|
+
* is just the 1×1 active cell the cutout covers the *entire* range, so the fill vanishes; set `false`
|
|
160
|
+
* to fill the whole selected row (then mark the anchor with {@link SelectionLayerProps.singleAnchorStyle},
|
|
161
|
+
* since the anchor is still the live Space/scroll target).
|
|
162
|
+
*
|
|
163
|
+
* @defaultValue true
|
|
164
|
+
*/
|
|
165
|
+
anchorHole?: boolean;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* The selection layer: renders the selection (single-range "rich" treatment vs multi-range), routes
|
|
169
|
+
* pointer + keyboard to the model, owns the {@link SelectionRangeStyle} theme, and mounts the
|
|
170
|
+
* single/multi handle slots bound to the active range. The only piece that knows about
|
|
171
|
+
* {@link ISelection}; the handle layers stay dumb, controlled RangeHandles.
|
|
172
|
+
*
|
|
173
|
+
* @remarks
|
|
174
|
+
* Slot children are cloned with `range` = the active range injected and their `onDragEnd` wrapped so
|
|
175
|
+
* the committed range updates the selection (the child's own `onDragEnd`, e.g. a data fill, still
|
|
176
|
+
* runs after). Handles inherit the active style via {@link SelectionStyleContext}.
|
|
177
|
+
*/
|
|
178
|
+
export declare const SelectionLayer: React.ForwardRefExoticComponent<SelectionLayerProps & React.RefAttributes<SelectionNavigation>>;
|
|
179
|
+
//# sourceMappingURL=SelectionLayer.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { VisualSVGProps } from '../svg';
|
|
2
|
+
/**
|
|
3
|
+
* The style of one selection range: a stack of up to three rectangles — a `fill`, a `border` outline,
|
|
4
|
+
* and an optional `inner` accent ring (the white inner edge of the Excel-style two-tone border). Each
|
|
5
|
+
* slot is a {@link VisualSVGProps} (a single rectangle's visual override; geometry/hole are supplied by
|
|
6
|
+
* the layer); a `null` or omitted slot draws no rectangle. Per-mode overrides merge slot-by-slot over
|
|
7
|
+
* the `DEFAULT_*_STYLE`.
|
|
8
|
+
*/
|
|
9
|
+
export interface SelectionRangeStyle {
|
|
10
|
+
/** The interior fill (the active cell is cut out via the layer-supplied `hole`). */
|
|
11
|
+
fill?: VisualSVGProps | null;
|
|
12
|
+
/** The main outline. */
|
|
13
|
+
border?: VisualSVGProps | null;
|
|
14
|
+
/** The inner accent ring, inset inside the border. Omit for a single-tone outline. */
|
|
15
|
+
inner?: VisualSVGProps | null;
|
|
16
|
+
}
|
|
17
|
+
/** The rich single-range style: tinted fill, thick outline, inner ring (the two-tone border). */
|
|
18
|
+
export declare const DEFAULT_SINGLE_STYLE: SelectionRangeStyle;
|
|
19
|
+
/** The quieter multi-range style: lighter fill, thin outline, thin inner ring. */
|
|
20
|
+
export declare const DEFAULT_MULTI_STYLE: SelectionRangeStyle;
|
|
21
|
+
/**
|
|
22
|
+
* The active-cell border drawn over a multi-range selection (the anchor cell within the rich range).
|
|
23
|
+
* Inset so it sits just inside the cell, leaving a gap to the range's outer border.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DEFAULT_ANCHOR_STYLE: VisualSVGProps;
|
|
26
|
+
/** The transient rubber-band shown while Ctrl/Cmd-dragging to remove an area (fill + border stack). */
|
|
27
|
+
export declare const DEFAULT_REMOVE_PREVIEW_STYLE: SelectionRangeStyle;
|
|
28
|
+
//# sourceMappingURL=SelectionStyle.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ISelection } from './ISelection';
|
|
3
|
+
/**
|
|
4
|
+
* Props for {@link SelectionTouchGrips}.
|
|
5
|
+
*/
|
|
6
|
+
export interface SelectionTouchGripsProps {
|
|
7
|
+
/** The selection the touch handles read (for placement) and extend (via `modify`). */
|
|
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
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Touch selection handles: round grips at the active range's corners (or edges, for a whole row/column)
|
|
16
|
+
* that drag to **extend the selection** via {@link ISelection.modify}, reusing the exact range math the
|
|
17
|
+
* mouse path uses. See {@link computeGrips} for the per-selection grip layout.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Each grip is a {@link StickyAnchor} rendered through a **portal** (via the fullscreen-aware root) so it
|
|
21
|
+
* escapes the pane clip. StickyAnchor's owner/clip gating means exactly ONE pane renders each grip, and
|
|
22
|
+
* anchoring to a cell makes the grip vanish the moment that cell scrolls off — no slide-to-edge.
|
|
23
|
+
*
|
|
24
|
+
* The drag runs on **window** pointer listeners owned by this (always-mounted) component — not
|
|
25
|
+
* pointer-capture on the grip element — so the gesture survives the grip hiding mid-drag (the grips fade
|
|
26
|
+
* to `opacity: 0` while dragging so the finger isn't dragging a dot it can't see past).
|
|
27
|
+
*/
|
|
28
|
+
export declare const SelectionTouchGrips: React.FC<SelectionTouchGripsProps>;
|
|
29
|
+
//# sourceMappingURL=SelectionTouchGrips.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { CellCoords, RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
import { IKeyStroke } from '@sheetxl/utils-react';
|
|
3
|
+
import { IGridPane } from '../surface';
|
|
4
|
+
import { ISelection } from './ISelection';
|
|
5
|
+
/**
|
|
6
|
+
* One navigation binding: its **default** keystroke(s) + the method to run. The single source for a
|
|
7
|
+
* selection navigation capability — keystroke handling (the layer's `onKeyDown`), the imperative
|
|
8
|
+
* handle (`invoke`), and the command catalog (which derives its shortcut + adds chrome) all read it.
|
|
9
|
+
*/
|
|
10
|
+
export interface NavBinding {
|
|
11
|
+
/**
|
|
12
|
+
* The default keystroke(s). The command catalog seeds its (re-mappable) shortcut from this. Omitted
|
|
13
|
+
* for a command-only binding (invokable by name, no default chord) — every chord maps to exactly ONE
|
|
14
|
+
* binding, so a method whose natural chord is already taken ships without one.
|
|
15
|
+
*/
|
|
16
|
+
shortcut?: IKeyStroke | IKeyStroke[];
|
|
17
|
+
/** The behavior — a composition of {@link ISelection} (model) + {@link IGridPane} (view). */
|
|
18
|
+
run: () => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The selection navigation capability owned by `SelectionLayer`.
|
|
22
|
+
*/
|
|
23
|
+
export interface SelectionNavigation {
|
|
24
|
+
/** Run a binding by name (the command front-end). Returns `false` if the name is unknown. */
|
|
25
|
+
invoke(name: string): boolean;
|
|
26
|
+
/** Match a keyboard event to a binding and run it (the layer's keyboard front-end). */
|
|
27
|
+
handleKey(event: React.KeyboardEvent): boolean;
|
|
28
|
+
/** Whether a binding name exists. */
|
|
29
|
+
supports(name: string): boolean;
|
|
30
|
+
/** The full binding map — `name → { shortcut, run }` (the command catalog seeds shortcuts from it). */
|
|
31
|
+
getBindings(): ReadonlyMap<string, NavBinding>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Options for {@link createSelectionNavigation} — the live getters a navigation capability is built
|
|
35
|
+
* over. `getSelection` / `getPane` are read on *every* action so the capability stays valid across
|
|
36
|
+
* re-renders and scroll (never captured once). The bounds getters inject sheet-tier knowledge; the
|
|
37
|
+
* dumb {@link DefaultSelection} tier omits them and everything falls back to the grid edge.
|
|
38
|
+
*/
|
|
39
|
+
export interface SelectionNavigationOptions {
|
|
40
|
+
/** The writable selection model, read live. */
|
|
41
|
+
getSelection: () => ISelection;
|
|
42
|
+
/** The grid view (metrics + scroll), read live so bindings stay correct across scroll. */
|
|
43
|
+
getPane: () => IGridPane;
|
|
44
|
+
/**
|
|
45
|
+
* The content (used-range) bounds the `…End` keys (End / Ctrl+End) jump to. A **sheet-global**
|
|
46
|
+
* property — the used range — so it is deliberately **cell-independent**: Ctrl+End lands on the same
|
|
47
|
+
* used-range corner wherever the cursor sits. (Contrast {@link getRegionBounds}, a *positional*
|
|
48
|
+
* query — that difference is why one takes a `cell` and this one does not; it is not an oversight.)
|
|
49
|
+
* Omit it (the dumb tier, which has no sheet ⇒ no used range) ⇒ the grid edge.
|
|
50
|
+
*/
|
|
51
|
+
getContentBounds?: () => RangeCoords;
|
|
52
|
+
/**
|
|
53
|
+
* The scroll executor for keyboard selection. Supply it from a tier that OWNS scrolling (the sheet
|
|
54
|
+
* layer → `sheet.scrollTo`) so UI and scripting scroll through one path; the model then owns the
|
|
55
|
+
* arrow-`navigate` scroll and the two don't compete. Omit it and the layer scrolls its own pane.
|
|
56
|
+
*/
|
|
57
|
+
getScrollIntoView?: () => ((cell: Partial<CellCoords>) => void) | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* The bounding REGION enclosing a cell — a table's data range, or `null` on the bare sheet. A
|
|
60
|
+
* **positional** query (hence the `cell`, unlike the sheet-global {@link getContentBounds}): drives
|
|
61
|
+
* Tab/Enter wrapping inside a table and the row/column span of Ctrl/Shift+Space. Omit it (the dumb
|
|
62
|
+
* tier) ⇒ no enclosing region (Tab moves, Ctrl/Shift+Space select the whole grid). Any escalation
|
|
63
|
+
* (data → table → sheet) is the provider's job, not the consumer's.
|
|
64
|
+
*/
|
|
65
|
+
getRegionBounds?: (cell: CellCoords) => RangeCoords | null;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=Types.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SelectionNavigation, SelectionNavigationOptions } from './Types';
|
|
2
|
+
/**
|
|
3
|
+
* Build the navigation capability over the live getters in {@link SelectionNavigationOptions}.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createSelectionNavigation(options: SelectionNavigationOptions): SelectionNavigation;
|
|
6
|
+
//# sourceMappingURL=_SelectionNavigation.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SelectionRangeStyle } from './SelectionStyle';
|
|
2
|
+
/**
|
|
3
|
+
* Merge a {@link SelectionRangeStyle} override over a base, slot-by-slot (each rectangle merges
|
|
4
|
+
* independently).
|
|
5
|
+
*/
|
|
6
|
+
export declare const mergeSelectionStyle: (base: SelectionRangeStyle, over?: SelectionRangeStyle) => SelectionRangeStyle;
|
|
7
|
+
//# sourceMappingURL=_SelectionUtils.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from './Types';
|
|
2
|
+
export * from './SelectionUtils';
|
|
3
|
+
export * from './ICellAnchor';
|
|
4
|
+
export * from './ISelection';
|
|
5
|
+
export * from './DefaultSelection';
|
|
6
|
+
export * from './SelectionStyle';
|
|
7
|
+
export * from './useDragCells';
|
|
8
|
+
export * from './useSelectionPointer';
|
|
9
|
+
export * from './SelectionTouchGrips';
|
|
10
|
+
export * from './SelectionLayer';
|
|
11
|
+
export * from './RangesPickerLayer';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|