@sheetxl/grid-react 0.8.0-beta.2 → 0.8.0-beta.20
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/LICENSE.md +8 -7
- package/README.md +21 -8
- package/browser/esm/index.mjs +3617 -3107
- package/licenses/dependencies.txt +0 -208
- package/node/esm/index.mjs +3955 -2532
- package/package.json +9 -13
- package/types/src/cell/CellRenderer.d.ts +32 -0
- package/types/src/cell/GridlineLayer.d.ts +39 -1
- package/types/src/editor/DefaultEditable.d.ts +16 -6
- package/types/src/editor/EditSession.d.ts +28 -5
- package/types/src/editor/EditorDiv.d.ts +3 -2
- package/types/src/editor/EditorInput.d.ts +5 -2
- 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 +7 -2
- package/types/src/grid/Grid.d.ts +1 -1
- package/types/src/grid/IGrid.d.ts +4 -4
- package/types/src/header/GridFreezeAnchor.d.ts +29 -0
- package/types/src/header/HeaderDividerAnchor.d.ts +36 -1
- 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 +4 -4
- package/types/src/layer/GestureTip.d.ts +77 -0
- package/types/src/layer/GridFloatPanel.d.ts +3 -2
- package/types/src/layer/Layer.d.ts +6 -0
- package/types/src/layer/RangeFloatLayer.d.ts +145 -53
- package/types/src/layer/RangePrompt.d.ts +8 -8
- package/types/src/layer/RangeTooltip.d.ts +128 -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 +104 -0
- package/types/src/layer/_Utils.d.ts +9 -3
- package/types/src/layer/index.d.ts +6 -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 +18 -2
- package/types/src/list/ListSearch.d.ts +24 -3
- package/types/src/list/PickList.d.ts +6 -1
- package/types/src/range/DragHandle.d.ts +13 -6
- package/types/src/range/Draggable.d.ts +29 -3
- package/types/src/range/FillHandle.d.ts +11 -2
- package/types/src/range/RangeGlide.d.ts +160 -0
- package/types/src/range/RangeRect.d.ts +7 -0
- package/types/src/range/RangeResizer.d.ts +7 -1
- package/types/src/range/index.d.ts +2 -0
- package/types/src/range/useRangeGlide.d.ts +11 -0
- package/types/src/selection/RangesPickerLayer.d.ts +4 -1
- package/types/src/selection/SelectionLayer.d.ts +71 -15
- package/types/src/selection/SelectionStyle.d.ts +4 -1
- package/types/src/selection/SelectionTouchGrips.d.ts +6 -4
- package/types/src/selection/_SelectionUtils.d.ts +6 -0
- package/types/src/selection/useDragCells.d.ts +29 -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 +29 -0
- package/types/src/svg/RectangleSVG.d.ts +21 -4
- 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,13 +1,13 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
import { Bounds, Point, AnchorLocation } from '@sheetxl/utils';
|
|
3
3
|
import { IGridPane } from '../surface';
|
|
4
|
-
import { GridAnchor, GridAnchorReference, GridPlacement, GridBoundary, GridWhenOff, GridSlide } from './useGridAnchor';
|
|
4
|
+
import { GridAnchor, GridAnchorReference, GridPlacement, GridBoundary, GridWhenOff, GridWhenPartial, GridSlide } from './useGridAnchor';
|
|
5
5
|
/**
|
|
6
6
|
* The state a {@link StickyAnchor} publishes to its child. Carries the resolved `anchorPoint` (+ owner /
|
|
7
7
|
* clip / slide state) so the child alone decides how to render:
|
|
8
8
|
*
|
|
9
9
|
* - a **render-prop** child self-positions — e.g. a portal that escapes the clip and flows past the
|
|
10
|
-
* pane bounds (this is what {@link
|
|
10
|
+
* pane bounds (this is what {@link StickyPortal} does for you);
|
|
11
11
|
* - a plain **node** ("just a div") is positioned INLINE by StickyAnchor, clipping with the pane.
|
|
12
12
|
*
|
|
13
13
|
* `StickyAnchor` itself is portal-agnostic; it only resolves the anchor and positions inline divs.
|
|
@@ -17,8 +17,10 @@ export interface StickyState {
|
|
|
17
17
|
reference: GridAnchorReference;
|
|
18
18
|
/** Client-space boundary rect (for `flip`/`shift`/`hide` limiters). */
|
|
19
19
|
getBoundaryRect: () => DOMRect;
|
|
20
|
-
/** The placement's anchor pixel (client px). */
|
|
20
|
+
/** The placement's anchor pixel (client px) — a render-time snapshot. */
|
|
21
21
|
anchorPoint: Point;
|
|
22
|
+
/** Live accessor for the anchor pixel (client px); stable identity, reads between renders. */
|
|
23
|
+
getAnchorPoint: () => Point;
|
|
22
24
|
/** Pane-relative range bounds (for an in-grid child) — only meaningful on the owner pane, else null. */
|
|
23
25
|
bounds: Bounds | null;
|
|
24
26
|
/** The pane that owns the anchor pixel (null when clipped off every pane). */
|
|
@@ -35,7 +37,10 @@ export interface StickyState {
|
|
|
35
37
|
* (keep showing) from "off-screen" (show a goto affordance).
|
|
36
38
|
*/
|
|
37
39
|
outOfView: boolean;
|
|
38
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* The placement **actually used**: the requested one, or its opposite on an axis that
|
|
42
|
+
* {@link StickyAnchorProps.whenPartial} flipped to the range's other visible edge.
|
|
43
|
+
*/
|
|
39
44
|
placement: GridPlacement;
|
|
40
45
|
/** This instance's pane (null outside a `GridPaneProvider`). */
|
|
41
46
|
pane: IGridPane | null;
|
|
@@ -63,6 +68,11 @@ export interface StickyAnchorProps {
|
|
|
63
68
|
boundary?: GridBoundary;
|
|
64
69
|
/** What happens when the anchor pixel leaves the data area. @defaultValue 'hide' */
|
|
65
70
|
whenOff?: GridWhenOff;
|
|
71
|
+
/**
|
|
72
|
+
* What happens, per axis, while the range is partly obstructed — in view, but the anchored edge is
|
|
73
|
+
* not. @defaultValue `{ side: 'flip', align: 'slide' }`
|
|
74
|
+
*/
|
|
75
|
+
whenPartial?: GridWhenPartial;
|
|
66
76
|
/** Px overlap below which a geometried anchor reads as clipped. @defaultValue 0 */
|
|
67
77
|
minVisible?: number;
|
|
68
78
|
/** The child — a node, or a render function `(state) => node`. Reads state via {@link useSticky} too. */
|
|
@@ -71,7 +81,7 @@ export interface StickyAnchorProps {
|
|
|
71
81
|
/**
|
|
72
82
|
* A **sticky** grid layer: it resolves an {@link GridAnchor} (via {@link useGridAnchor}) to a live
|
|
73
83
|
* anchor point and positions its child there. A plain `<div>` child is placed **inline** (clips with
|
|
74
|
-
* the pane); a **render-prop** child self-positions (e.g. a portal — see {@link
|
|
84
|
+
* the pane); a **render-prop** child self-positions (e.g. a portal — see {@link StickyPortal}). It owns
|
|
75
85
|
* no portal and knows nothing about Floating UI.
|
|
76
86
|
*
|
|
77
87
|
* Rendered per pane like any layer; each instance publishes its own `isOwner`, so only the owner pane
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { FloatPopperProps } from '@sheetxl/utils-react';
|
|
3
|
+
import { StickyState } from './StickyAnchor';
|
|
4
|
+
import { GridAnchor, GridPlacement, GridBoundary, GridWhenOff, GridWhenPartial } from './useGridAnchor';
|
|
5
|
+
/** The lifecycle a {@link StickyPortal} reports — {@link FloatPopper}'s. */
|
|
6
|
+
export type StickyPortalLifecycle = Pick<FloatPopperProps, 'onMount' | 'onOpening' | 'onOpen' | 'onClosing' | 'onClose'>;
|
|
7
|
+
/**
|
|
8
|
+
* Props for {@link StickyPortal}.
|
|
9
|
+
*/
|
|
10
|
+
export interface StickyPortalProps extends StickyPortalLifecycle {
|
|
11
|
+
/** WHERE to anchor — a grid coordinate (range / cell / bounds / edge / point). */
|
|
12
|
+
anchor: GridAnchor;
|
|
13
|
+
/** Which side + align the float attaches to. @defaultValue `{ side: 't', align: 'center' }` */
|
|
14
|
+
placement?: GridPlacement;
|
|
15
|
+
/** What happens when the anchor leaves the data area. @defaultValue 'hide' */
|
|
16
|
+
whenOff?: GridWhenOff;
|
|
17
|
+
/**
|
|
18
|
+
* What happens, per axis, while the range is partly obstructed — in view, but the anchored edge is
|
|
19
|
+
* not. @defaultValue `{ side: 'flip', align: 'slide' }`
|
|
20
|
+
*/
|
|
21
|
+
whenPartial?: GridWhenPartial;
|
|
22
|
+
/**
|
|
23
|
+
* Where the float may LIVE — one rect, resolved by {@link GridBoundary}: it is both the anchor's
|
|
24
|
+
* clip / clamp boundary and the rect `flip` / `shift` collide against. @defaultValue 'data'
|
|
25
|
+
*/
|
|
26
|
+
boundary?: GridBoundary;
|
|
27
|
+
/** Px overlap below which a geometried anchor reads as clipped. @defaultValue 0 */
|
|
28
|
+
minVisible?: number;
|
|
29
|
+
/** Gap (px) between the anchor edge and the float. @defaultValue 4 */
|
|
30
|
+
offset?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Offset (px) along the anchor EDGE — only applies to `start` / `end` alignment (a centered float has
|
|
33
|
+
* no edge to slide along). Positive insets the float inward from the corner. @defaultValue 0
|
|
34
|
+
*/
|
|
35
|
+
alignOffset?: number;
|
|
36
|
+
/** Controlled visibility (e.g. a hover tooltip). @defaultValue true */
|
|
37
|
+
open?: boolean;
|
|
38
|
+
/** Portal container. @defaultValue the fullscreen-aware root (`useFullscreenPortal`). */
|
|
39
|
+
container?: Element;
|
|
40
|
+
className?: string;
|
|
41
|
+
style?: React.CSSProperties;
|
|
42
|
+
/** The stacking band — a number, or a `zIndexVar` expression. @defaultValue `zIndexVar('grid')` */
|
|
43
|
+
zIndex?: number | string;
|
|
44
|
+
/**
|
|
45
|
+
* Whose theme the float wears: the anchor's (`'anchor'` — a grid label themes with its grid, even where
|
|
46
|
+
* the grid's mode differs from the app's) or the app's (`'provider'` — chrome, such as a gesture
|
|
47
|
+
* readout). @defaultValue 'anchor'
|
|
48
|
+
*/
|
|
49
|
+
themeFrom?: 'provider' | 'anchor';
|
|
50
|
+
/**
|
|
51
|
+
* Drawn **instead of** the child while the anchored range has no visible portion (`state.outOfView`) —
|
|
52
|
+
* the presence left behind under `whenOff: 'clamp'`: an edge marker, a "go to range" pill. Without it
|
|
53
|
+
* the child itself is drawn, clamped to the edge.
|
|
54
|
+
*/
|
|
55
|
+
renderOffscreen?: (state: StickyState) => React.ReactNode;
|
|
56
|
+
/** The float content — a node, or a render function `(state) => node` (e.g. to react to `slid`). */
|
|
57
|
+
children?: React.ReactNode | ((state: StickyState) => React.ReactNode);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The **portal renderer** of the grid float family: a {@link StickyAnchor} whose child is drawn by
|
|
61
|
+
* {@link FloatPopper} at the resolved anchor, in a **portal** (escaping the pane clip, so it can flow past
|
|
62
|
+
* the pane bounds — e.g. overhang a freeze line). The common case — `<StickyPortal anchor={{ range }}>
|
|
63
|
+
* A1:B4</StickyPortal>` — with no hand-written positioner. For an in-grid (clipping) label, use
|
|
64
|
+
* `<StickyAnchor>` with a plain `<div>` child instead.
|
|
65
|
+
*
|
|
66
|
+
* @remarks
|
|
67
|
+
* The resolver (`StickyAnchor`) decides WHERE — the owner pane, the live client rect, the boundary and the
|
|
68
|
+
* clip / clamp / slide state; the positioner (`FloatPopper`, the same one app menus use) decides how the
|
|
69
|
+
* box fits there. Both kinds of grid float — a persistent `RangeFloat` and a hover `RangeTooltip` — are
|
|
70
|
+
* one of these; what differs is who opens and closes them.
|
|
71
|
+
*/
|
|
72
|
+
export declare const StickyPortal: React.FC<StickyPortalProps>;
|
|
73
|
+
//# sourceMappingURL=StickyPortal.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { RenderSlotFn } from '@sheetxl/utils-react';
|
|
3
|
+
import { GridPlacement } from './useGridAnchor';
|
|
4
|
+
import { HoverTipProps } from './useHoverIntent';
|
|
5
|
+
/**
|
|
6
|
+
* The dwell timing of the tooltip group — MUI's model.
|
|
7
|
+
*/
|
|
8
|
+
export interface TooltipTiming {
|
|
9
|
+
/** Dwell (ms) over a target before the first tip shows. @defaultValue 300 */
|
|
10
|
+
enterDelay: number;
|
|
11
|
+
/** Dwell (ms) while the group is **armed** (a tip closed within {@link armedFor}) — the next tip is instant. @defaultValue 0 */
|
|
12
|
+
enterNextDelay: number;
|
|
13
|
+
/** The window (ms) after a close in which the next open is fast — MUI's hysteresis. @defaultValue 800 */
|
|
14
|
+
armedFor: number;
|
|
15
|
+
/** The linger (ms) after leaving before a tip hides — lets the pointer cross onto an interactive tip, and a tip does not vanish the moment the pointer leaves the grid. @defaultValue 400 */
|
|
16
|
+
leaveDelay: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const DEFAULT_TOOLTIP_TIMING: TooltipTiming;
|
|
19
|
+
/** What the host's tooltip bubble is handed. */
|
|
20
|
+
export interface TooltipRenderProps {
|
|
21
|
+
/** The tip's content. */
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
/** The edge the tip hangs on — for an arrow. */
|
|
24
|
+
placement: GridPlacement;
|
|
25
|
+
/** Whether the tip stays open while the pointer is on it (and so takes the pointer at all). */
|
|
26
|
+
interactive: boolean;
|
|
27
|
+
/** Spread onto the bubble root: the keep-open handlers and the element registration. */
|
|
28
|
+
tipProps: HoverTipProps;
|
|
29
|
+
className?: string;
|
|
30
|
+
style?: React.CSSProperties;
|
|
31
|
+
}
|
|
32
|
+
/** The bubble around a tip's content — the host's chrome, arrow and theme. */
|
|
33
|
+
export type RenderTooltip = RenderSlotFn<TooltipRenderProps>;
|
|
34
|
+
/**
|
|
35
|
+
* A tip registered with its {@link TooltipGroup}. One per `useHoverIntent`; the per-pane copies of a
|
|
36
|
+
* layer share a `key`, so they count as one tip.
|
|
37
|
+
*/
|
|
38
|
+
export interface TooltipClient {
|
|
39
|
+
/** Identity: the copies of one tip share it; two tips on the same cell do not. */
|
|
40
|
+
readonly key: string;
|
|
41
|
+
/**
|
|
42
|
+
* A gesture tip holds the group: hover tips may not open while it is up. It is not closed by a press
|
|
43
|
+
* or Escape, and its close does not arm the group.
|
|
44
|
+
*/
|
|
45
|
+
readonly gesture: boolean;
|
|
46
|
+
/** The tip's element once mounted — a pointerdown inside it does not close it. */
|
|
47
|
+
getElement(): Element | null;
|
|
48
|
+
/** Close now, no grace (the group took the slot, or the user pressed elsewhere or hit Escape). */
|
|
49
|
+
forceClose(): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The single-open coordinator: at most one tip (by key) is up at a time, the next open is fast for
|
|
53
|
+
* {@link TooltipTiming.armedFor} after a close, a gesture tip preempts hover, and a pointerdown outside
|
|
54
|
+
* an open hover tip or Escape closes it (a gesture tip closes with its gesture). No other key and no
|
|
55
|
+
* selection change closes a tip; a layer's owner closes one for its own reasons through `dismiss`. Owned
|
|
56
|
+
* by the top {@link TooltipProvider} (or one that `isolate`s); a built-in default serves a tree with no
|
|
57
|
+
* provider.
|
|
58
|
+
*/
|
|
59
|
+
export interface TooltipGroup {
|
|
60
|
+
/** `client` is opening: every client open on another key closes first, with no grace. */
|
|
61
|
+
claim(client: TooltipClient): void;
|
|
62
|
+
/** `client` closed. The group arms when the last client on the open key releases. */
|
|
63
|
+
release(client: TooltipClient): void;
|
|
64
|
+
/** A tip closed less than `armedFor` ms ago. */
|
|
65
|
+
isArmed(armedFor: number): boolean;
|
|
66
|
+
/** A gesture tip is up. */
|
|
67
|
+
isHeld(): boolean;
|
|
68
|
+
/** Close every open tip now. */
|
|
69
|
+
closeAll(): void;
|
|
70
|
+
}
|
|
71
|
+
export declare const createTooltipGroup: () => TooltipGroup;
|
|
72
|
+
/** The ambient tooltip configuration a tip reads. */
|
|
73
|
+
export interface TooltipSurface {
|
|
74
|
+
timing: TooltipTiming;
|
|
75
|
+
/** The host's bubble; `undefined` = the grid's plain default. */
|
|
76
|
+
renderTooltip?: RenderTooltip;
|
|
77
|
+
group: TooltipGroup;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The ambient {@link TooltipSurface}. Works with no provider: MUI timing, the plain bubble and a shared
|
|
81
|
+
* default group.
|
|
82
|
+
*/
|
|
83
|
+
export declare const useTooltipSurface: () => TooltipSurface;
|
|
84
|
+
export interface TooltipProviderProps {
|
|
85
|
+
/** Override any of the dwell timings; the rest are inherited. */
|
|
86
|
+
timing?: Partial<TooltipTiming>;
|
|
87
|
+
/** The bubble tips in this subtree open in. Inherited when omitted. */
|
|
88
|
+
renderTooltip?: RenderTooltip;
|
|
89
|
+
/**
|
|
90
|
+
* Own a separate single-open group for this subtree instead of sharing the enclosing one. The top
|
|
91
|
+
* provider (no enclosing one) always owns a group.
|
|
92
|
+
*/
|
|
93
|
+
isolate?: boolean;
|
|
94
|
+
children?: React.ReactNode;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Configures the grid's tooltips for a subtree: the dwell timing, the bubble (`renderTooltip`, the way
|
|
98
|
+
* `FloatProvider` takes `renderFloatPanel`) and the single-open group. Nested providers override only
|
|
99
|
+
* what they are given and inherit the rest; a hook outside any provider gets the built-in defaults.
|
|
100
|
+
*/
|
|
101
|
+
export declare const TooltipProvider: React.FC<TooltipProviderProps>;
|
|
102
|
+
/** The grid's default bubble — used when no provider supplies `renderTooltip`. */
|
|
103
|
+
export declare const defaultRenderTooltip: RenderTooltip;
|
|
104
|
+
//# sourceMappingURL=TooltipProvider.d.ts.map
|
|
@@ -2,6 +2,8 @@ import { RangeCoords } from '@sheetxl/utils';
|
|
|
2
2
|
import { LayerNode } from './LayerTypes';
|
|
3
3
|
/** Content key for a range — stable across object identity (dedupe / memo / hover-target keys). */
|
|
4
4
|
export declare const rangeKey: (r: RangeCoords) => string;
|
|
5
|
+
/** Where a cell's hover tip stacks: over the grid's other floats, and under any menu. */
|
|
6
|
+
export declare const GRID_TIP_Z_INDEX: string;
|
|
5
7
|
/**
|
|
6
8
|
* A layer's **derived stacking order** — its index in the normalized layer list, i.e. the react list
|
|
7
9
|
* order with explicit-`zIndex` overrides already folded in (see {@link normalizeLayers}). This is the
|
|
@@ -18,11 +20,15 @@ export declare const LayerOrderContext: import('react').Context<number>;
|
|
|
18
20
|
*/
|
|
19
21
|
export declare const LayerScopeContext: import('react').Context<boolean>;
|
|
20
22
|
/**
|
|
21
|
-
* Normalize the layers (the grid's children) for rendering: sort by `zIndex`
|
|
22
|
-
* **derived order index** (its position in the sorted list = its effective z).
|
|
23
|
-
* through unchanged.
|
|
23
|
+
* Normalize the layers (the grid's children) for rendering: flatten nested arrays, sort by `zIndex`
|
|
24
|
+
* and stamp each with its **derived order index** (its position in the sorted list = its effective z).
|
|
25
|
+
* A non-array passes through unchanged.
|
|
24
26
|
*
|
|
25
27
|
* @remarks
|
|
28
|
+
* Nested arrays are flattened first, so a host's array of layers placed as one entry among the
|
|
29
|
+
* built-in ones still gives each of its layers its own `zIndex` and its own slot. A flattened layer
|
|
30
|
+
* keeps its own key, so keys must be unique across the whole stack, not only within their array.
|
|
31
|
+
*
|
|
26
32
|
* Ordering matches the CSS model: sort by `zIndex` **ascending** (higher paints later = on top); a layer
|
|
27
33
|
* without a `zIndex` counts as `0`, and `Array.prototype.sort` is stable so same-`zIndex` layers keep
|
|
28
34
|
* **declaration order** — exactly as `z-index: auto` behaves. The `zIndex` is read off the top-level
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export * from './LayerTypes';
|
|
2
2
|
export * from './Layer';
|
|
3
3
|
export * from './VirtualDiv';
|
|
4
|
-
export type { GridAnchor, GridAnchorReference, GridPlacement, GridWhenOff, GridBoundary, GridFloatSide, GridAlign, GridSlide } from './useGridAnchor';
|
|
4
|
+
export type { GridAnchor, GridAnchorReference, GridPlacement, GridWhenOff, GridWhenPartial, GridPartialPolicy, GridBoundary, GridFloatSide, GridAlign, GridSlide } from './useGridAnchor';
|
|
5
5
|
export * from './StickyAnchor';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './StickyPortal';
|
|
7
7
|
export * from './GridFloatPanel';
|
|
8
|
+
export * from './TooltipProvider';
|
|
8
9
|
export * from './useHoverIntent';
|
|
9
|
-
export * from './useRangeHover';
|
|
10
10
|
export * from './RangeFloatLayer';
|
|
11
|
-
export * from './
|
|
11
|
+
export * from './RangeTooltipLayer';
|
|
12
|
+
export * from './GestureTip';
|
|
12
13
|
export * from './RangePrompt';
|
|
14
|
+
export * from './RangeTooltip';
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -25,6 +25,27 @@ export interface GridPlacement {
|
|
|
25
25
|
* the owner becomes the pane under the clamped pixel and {@link GridAnchorResolved.slid} is set.
|
|
26
26
|
*/
|
|
27
27
|
export type GridWhenOff = 'hide' | 'clamp';
|
|
28
|
+
/**
|
|
29
|
+
* What a float does on ONE axis while the range is **partly obstructed** — in view, but the edge the
|
|
30
|
+
* float hangs on is not (scrolled under a frozen pane, a header, or the window edge).
|
|
31
|
+
*
|
|
32
|
+
* - `'slide'` — the anchor pixel rides the visible edge, over the obstruction, until the range is
|
|
33
|
+
* fully out ({@link GridAnchorResolved.slid} reports how far).
|
|
34
|
+
* - `'flip'` — the float moves to the **opposite edge of the range** when that edge is in view (the
|
|
35
|
+
* resolved {@link GridAnchorResolved.placement} reports it); slides when neither edge is. Meaningless
|
|
36
|
+
* for a `center` align, which slides.
|
|
37
|
+
* - `'hide'` — the range counts as out of view as soon as the anchored edge is obstructed.
|
|
38
|
+
*/
|
|
39
|
+
export type GridPartialPolicy = 'slide' | 'flip' | 'hide';
|
|
40
|
+
/**
|
|
41
|
+
* The {@link GridPartialPolicy} per axis: `side` governs the axis the float sits on (its `side`), `align`
|
|
42
|
+
* the axis it is aligned along.
|
|
43
|
+
* @defaultValue `{ side: 'flip', align: 'slide' }`
|
|
44
|
+
*/
|
|
45
|
+
export interface GridWhenPartial {
|
|
46
|
+
side?: GridPartialPolicy;
|
|
47
|
+
align?: GridPartialPolicy;
|
|
48
|
+
}
|
|
28
49
|
/**
|
|
29
50
|
* How far the anchor pixel was pushed to stay in frame (the `clamp` fallback). Handed to the sticky
|
|
30
51
|
* child so it can render differently when slid — an arrow toward the true (off-frame) anchor, etc.
|
|
@@ -61,14 +82,18 @@ export type GridAnchor = {
|
|
|
61
82
|
};
|
|
62
83
|
/**
|
|
63
84
|
* The clip / clamp boundary — a **rect fed to the positioning math**, NOT a DOM parent. One prop, one
|
|
64
|
-
* meaning: *where may this thing live*. It governs the anchor's clip / clamp AND (via `
|
|
85
|
+
* meaning: *where may this thing live*. It governs the anchor's clip / clamp AND (via `StickyPortal`)
|
|
65
86
|
* where `flip` / `shift` may land the float. This is how "don't slide under the headers" is expressed:
|
|
66
87
|
* clamp to the data viewport.
|
|
67
88
|
*
|
|
89
|
+
* Every grid-derived boundary is further cut to the **browser window** (the layout viewport): a float
|
|
90
|
+
* the grid does not obscure can still run off the screen, so the edge is always the grid edge ∩ the
|
|
91
|
+
* window edge. An explicit {@link Bounds} is used verbatim.
|
|
92
|
+
*
|
|
68
93
|
* - `'data'` — the union of the panes' cell areas (headers excluded). Default.
|
|
69
94
|
* - `'pane'` — just the resolving pane's cell area.
|
|
70
95
|
* - `'grid'` — currently the same as `'data'` (until a surface/header rect is threaded).
|
|
71
|
-
* - `'viewport'` — the browser
|
|
96
|
+
* - `'viewport'` — the browser window alone: the opt-out, for a float that may cover grid chrome.
|
|
72
97
|
* - a {@link Bounds} — an explicit **client-px** rect.
|
|
73
98
|
*/
|
|
74
99
|
export type GridBoundary = 'data' | 'pane' | 'grid' | 'viewport' | Bounds;
|
|
@@ -105,9 +130,15 @@ export interface GridAnchorResolved {
|
|
|
105
130
|
/**
|
|
106
131
|
* The anchor's range has **no visible portion** (fully scrolled off) — independent of `whenOff`. Unlike
|
|
107
132
|
* {@link clipped} (which `clamp` forces false), this stays true under `clamp`, so a presence can tell
|
|
108
|
-
* "partially obstructed / clamped" (still show) from "off-screen" (show a goto affordance).
|
|
133
|
+
* "partially obstructed / clamped" (still show) from "off-screen" (show a goto affordance). A
|
|
134
|
+
* `whenPartial: 'hide'` axis also sets it once its edge is obstructed.
|
|
109
135
|
*/
|
|
110
136
|
outOfView: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* The placement **actually used** — the requested one, or its opposite on an axis a
|
|
139
|
+
* `whenPartial: 'flip'` moved to the range's other edge. What the float positions by.
|
|
140
|
+
*/
|
|
141
|
+
placement: GridPlacement;
|
|
111
142
|
}
|
|
112
143
|
/**
|
|
113
144
|
* The Floating UI **virtual reference** for a grid anchor. Stable identity (so `autoUpdate` subscribes
|
|
@@ -134,6 +165,11 @@ export interface UseGridAnchorResult {
|
|
|
134
165
|
reference: GridAnchorReference;
|
|
135
166
|
/** Live accessor for the boundary rect (for `shift`/`flip`/`hide` limiters). */
|
|
136
167
|
getBoundaryRect: () => DOMRect;
|
|
168
|
+
/**
|
|
169
|
+
* Live accessor for the placement's anchor pixel (client px) — the live counterpart of
|
|
170
|
+
* {@link anchorPoint}, for a child that positions itself on the point between React renders.
|
|
171
|
+
*/
|
|
172
|
+
getAnchorPoint: () => Point;
|
|
137
173
|
/** Render-time snapshot: anchor outside the boundary. Updates each scroll frame (pane re-render). */
|
|
138
174
|
clipped: boolean;
|
|
139
175
|
/** Render-time snapshot: which side the anchor is off, when clipped. */
|
|
@@ -146,17 +182,21 @@ export interface UseGridAnchorResult {
|
|
|
146
182
|
slid: GridSlide | null;
|
|
147
183
|
/** Render-time snapshot: the range is fully scrolled off (stays true under `clamp`; see resolved). */
|
|
148
184
|
outOfView: boolean;
|
|
185
|
+
/** Render-time snapshot: the placement actually used (see {@link GridAnchorResolved.placement}). */
|
|
186
|
+
placement: GridPlacement;
|
|
149
187
|
/** The pane the anchor resolves against (null outside a `GridPaneProvider`). */
|
|
150
188
|
pane: IGridPane | null;
|
|
151
189
|
}
|
|
152
190
|
/** @internal The shared placement default (`StickyAnchor` and the resolver must agree on it). */
|
|
153
191
|
export declare const DEFAULT_PLACEMENT: GridPlacement;
|
|
192
|
+
/** @internal The shared partial-obstruction default: today's behavior made explicit. */
|
|
193
|
+
export declare const DEFAULT_WHEN_PARTIAL: Required<GridWhenPartial>;
|
|
154
194
|
/**
|
|
155
195
|
* Resolve a {@link GridAnchor} to a client rect + clip state against a boundary. **Pure** (given a
|
|
156
196
|
* pane) — no React, no live DOM beyond `getBoundingClientRect`, so it is directly unit-testable with a
|
|
157
197
|
* fake {@link IGridPane}. Shared by {@link useGridAnchor} (the live closures call this per frame).
|
|
158
198
|
*/
|
|
159
|
-
export declare const resolveGridAnchor: (pane: IGridPane | null, anchor: GridAnchor, boundary?: GridBoundary, minVisible?: number, placement?: GridPlacement, whenOff?: GridWhenOff) => GridAnchorResolved;
|
|
199
|
+
export declare const resolveGridAnchor: (pane: IGridPane | null, anchor: GridAnchor, boundary?: GridBoundary, minVisible?: number, placement?: GridPlacement, whenOff?: GridWhenOff, whenPartial?: GridWhenPartial) => GridAnchorResolved;
|
|
160
200
|
/**
|
|
161
201
|
* Bridge a {@link GridAnchor} (grid coordinate) to a **live Floating UI virtual reference** plus clip
|
|
162
202
|
* state. The pane already re-renders every layer on scroll (so the snapshot values update per frame),
|
|
@@ -170,5 +210,6 @@ export declare const useGridAnchor: (anchor: GridAnchor, options?: {
|
|
|
170
210
|
minVisible?: number;
|
|
171
211
|
placement?: GridPlacement;
|
|
172
212
|
whenOff?: GridWhenOff;
|
|
213
|
+
whenPartial?: GridWhenPartial;
|
|
173
214
|
}) => UseGridAnchorResult;
|
|
174
215
|
//# sourceMappingURL=useGridAnchor.d.ts.map
|
|
@@ -2,13 +2,39 @@
|
|
|
2
2
|
* Options for {@link useHoverIntent}.
|
|
3
3
|
*/
|
|
4
4
|
export interface UseHoverIntentOptions {
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Dwell (ms) over a target before opening — kills pass-through flicker.
|
|
7
|
+
* @defaultValue the tooltip group's `enterDelay` (300), or its `enterNextDelay` (0) while armed
|
|
8
|
+
*/
|
|
6
9
|
openDelay?: number;
|
|
7
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Grace (ms) after leaving before closing — lets the pointer cross the gap to the float.
|
|
12
|
+
* @defaultValue the tooltip group's `leaveDelay` (400)
|
|
13
|
+
*/
|
|
8
14
|
closeDelay?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Join the grid's tooltip group: one tip open at a time, a fast re-open while armed, closed by a
|
|
17
|
+
* pointerdown outside it or Escape, refused while a gesture tip or a popup is up. `false` for a hover-opened float that is not
|
|
18
|
+
* a tooltip — a table toolbar, a note's box — which must survive a tip opening beside it.
|
|
19
|
+
* @defaultValue true
|
|
20
|
+
*/
|
|
21
|
+
group?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The tip's identity in the group. A layer rendered once per pane passes one name so its copies count
|
|
24
|
+
* as ONE tip (they aim and open in lockstep); two layers on the same cell must differ.
|
|
25
|
+
* @defaultValue this hook instance
|
|
26
|
+
*/
|
|
27
|
+
name?: string;
|
|
28
|
+
/**
|
|
29
|
+
* A gesture readout: opens at once (no dwell) and holds the group, so no hover tip can open until it
|
|
30
|
+
* closes. @defaultValue false
|
|
31
|
+
*/
|
|
32
|
+
gesture?: boolean;
|
|
9
33
|
}
|
|
10
34
|
/** Props to spread onto the floated element so hovering IT keeps the float open. */
|
|
11
35
|
export interface HoverTipProps {
|
|
36
|
+
/** Registers the element with the tooltip group, so a press inside an interactive tip does not close it. */
|
|
37
|
+
ref: React.RefCallback<Element>;
|
|
12
38
|
onPointerEnter: () => void;
|
|
13
39
|
onPointerLeave: () => void;
|
|
14
40
|
style: React.CSSProperties;
|
|
@@ -37,13 +63,14 @@ export interface UseHoverIntentResult {
|
|
|
37
63
|
close: () => void;
|
|
38
64
|
}
|
|
39
65
|
/**
|
|
40
|
-
* The
|
|
41
|
-
*
|
|
42
|
-
* (
|
|
43
|
-
*
|
|
66
|
+
* The **hover-intent state machine** behind a tip — the per-tip client of the grid's tooltip group
|
|
67
|
+
* ({@link TooltipProvider}): dwell / grace timing, keep-open-on-tip-hover, and the group's rules
|
|
68
|
+
* (single open, armed re-open, gesture and popup preempt hover, closed by a press outside it or Escape). It does NO
|
|
69
|
+
* hit-testing: feed it a target key via {@link UseHoverIntentResult.setTarget} (`null` = nothing) and
|
|
70
|
+
* spread {@link UseHoverIntentResult.tipProps} on the float.
|
|
44
71
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
72
|
+
* `RangeFloatLayer` drives it from a probe; a dynamic consumer (a layer discovering the hovered note)
|
|
73
|
+
* drives `setTarget` itself.
|
|
47
74
|
*/
|
|
48
75
|
export declare const useHoverIntent: (options?: UseHoverIntentOptions) => UseHoverIntentResult;
|
|
49
76
|
//# sourceMappingURL=useHoverIntent.d.ts.map
|
|
@@ -15,11 +15,22 @@ export interface ICheckboxListElement extends HTMLDivElement, CheckboxListAttrib
|
|
|
15
15
|
/**
|
|
16
16
|
* Props for {@link CheckboxList}.
|
|
17
17
|
*/
|
|
18
|
+
/** What {@link CheckboxListProps.renderCheckbox} is handed. */
|
|
19
|
+
export interface CheckboxRenderProps {
|
|
20
|
+
checked: boolean;
|
|
21
|
+
/** Set for the `(Select All)` tri-state when only some rows are checked. */
|
|
22
|
+
indeterminate?: boolean;
|
|
23
|
+
}
|
|
18
24
|
export interface CheckboxListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
19
25
|
/** Number of rows. */
|
|
20
26
|
itemCount: number;
|
|
21
27
|
/** Whether the item at `index` is checked. */
|
|
22
28
|
isChecked: (index: number) => boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the item at `index` is partly checked: a row standing for several values (a group)
|
|
31
|
+
* with some of them checked. Drawn as the tri-state; the row still toggles to `!isChecked`.
|
|
32
|
+
*/
|
|
33
|
+
isIndeterminate?: (index: number) => boolean;
|
|
23
34
|
/**
|
|
24
35
|
* Set `indices` to `checked`. Called with a single index on a click, every selected row on a keyboard
|
|
25
36
|
* toggle (Space/Enter), and every row from `(Select All)`. The caller maps `index` to its own store.
|
|
@@ -32,16 +43,21 @@ export interface CheckboxListProps extends React.HTMLAttributes<HTMLDivElement>
|
|
|
32
43
|
* `pointerEvents:none`). `indeterminate` is set for the `(Select All)` tri-state. Override to use a
|
|
33
44
|
* styled control (MUI etc.). @defaultValue a native checkbox.
|
|
34
45
|
*/
|
|
35
|
-
renderCheckbox?: (
|
|
46
|
+
renderCheckbox?: (props: CheckboxRenderProps) => React.ReactNode;
|
|
36
47
|
/**
|
|
37
48
|
* Render a divider between the `(Select All)` header and the list, or elsewhere as needed.
|
|
38
49
|
*/
|
|
39
50
|
renderDivider?: () => React.ReactNode;
|
|
40
51
|
/**
|
|
41
52
|
* Show a tri-state **(Select All)** header with this label. It operates over *all* rows — which in a
|
|
42
|
-
* filtered list are the filtered ones, so it's "Select all (filtered)" automatically.
|
|
53
|
+
* filtered list are the filtered ones, so it's "Select all (filtered)" automatically. It sits
|
|
54
|
+
* above the rows, outside the scroll, so it never leaves the view.
|
|
43
55
|
*/
|
|
44
56
|
selectAllLabel?: React.ReactNode;
|
|
57
|
+
/** The header's accessible name and tooltip, when its label does not say what it is (a count). */
|
|
58
|
+
selectAllTitle?: string;
|
|
59
|
+
/** The Select All row's own attributes (a surface, a class), over its defaults. */
|
|
60
|
+
propsSelectAll?: React.HTMLAttributes<HTMLDivElement>;
|
|
45
61
|
/** Uniform row height in px. @defaultValue 24 */
|
|
46
62
|
itemHeight?: number;
|
|
47
63
|
/** Selection model (highlight + Arrow nav). Created internally if omitted. */
|
|
@@ -9,6 +9,20 @@ export interface ListSearchProps extends Omit<React.InputHTMLAttributes<HTMLInpu
|
|
|
9
9
|
onChange: (value: string) => void;
|
|
10
10
|
/** Escape on an empty field: the search has nothing left to clear, so the host closes. */
|
|
11
11
|
onClose?: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* The name of the clear button shown in the field while it holds text (its tooltip and
|
|
14
|
+
* accessible name). Without one the button is unnamed, not absent.
|
|
15
|
+
*/
|
|
16
|
+
clearLabel?: string;
|
|
17
|
+
/**
|
|
18
|
+
* In place of the search glyph inside the field: a control over the search itself (a menu of
|
|
19
|
+
* its options, drawn with {@link ListSearchGlyph}). The default is the glyph alone.
|
|
20
|
+
*/
|
|
21
|
+
glyph?: React.ReactNode;
|
|
22
|
+
/** Shown before the field, on its line: an action over the rows in view. */
|
|
23
|
+
leading?: React.ReactNode;
|
|
24
|
+
/** Shown after the field, on its line: an action on the typed text (an Add). */
|
|
25
|
+
trailing?: React.ReactNode;
|
|
12
26
|
/** Ref for the input. */
|
|
13
27
|
ref?: React.Ref<HTMLInputElement>;
|
|
14
28
|
}
|
|
@@ -18,14 +32,21 @@ export interface ListSearchProps extends Omit<React.InputHTMLAttributes<HTMLInpu
|
|
|
18
32
|
export declare const filterByText: <T extends {
|
|
19
33
|
text: string;
|
|
20
34
|
}>(items: readonly T[], query: string) => readonly T[];
|
|
35
|
+
/** The search glyph: a magnifier, drawn in the current color. */
|
|
36
|
+
export declare const ListSearchGlyph: (props: {
|
|
37
|
+
className?: string;
|
|
38
|
+
}) => React.ReactElement;
|
|
21
39
|
/**
|
|
22
40
|
* The **search field** shown above a list ({@link PickList}, `CheckboxList`): a plain input that
|
|
23
|
-
* narrows the rows as typed
|
|
41
|
+
* narrows the rows as typed, a search glyph before the text and a clear button after it while
|
|
42
|
+
* there is text. Filtering itself is the host's, with {@link filterByText}.
|
|
24
43
|
*
|
|
25
44
|
* @remarks
|
|
26
45
|
* Escape clears the text first and closes only when there is none left, so a mistyped search is
|
|
27
|
-
* one key from a full list and two from a closed one.
|
|
28
|
-
*
|
|
46
|
+
* one key from a full list and two from a closed one. The clear button does the first of those
|
|
47
|
+
* without taking the focus, as the next thing typed is usually another search. Every other key
|
|
48
|
+
* is the host's through `onKeyDown`, which is how the arrows and Enter reach the list while the
|
|
49
|
+
* field keeps focus.
|
|
29
50
|
*/
|
|
30
51
|
export declare const ListSearch: React.ForwardRefExoticComponent<Omit<ListSearchProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
31
52
|
//# sourceMappingURL=ListSearch.d.ts.map
|
|
@@ -5,6 +5,11 @@ export interface PickListItem {
|
|
|
5
5
|
/** The row's text. */
|
|
6
6
|
text: string;
|
|
7
7
|
}
|
|
8
|
+
/** What {@link PickListProps.renderItem} is handed. */
|
|
9
|
+
export interface PickListItemRenderProps {
|
|
10
|
+
item: PickListItem;
|
|
11
|
+
index: number;
|
|
12
|
+
}
|
|
8
13
|
export interface PickListAttributes {
|
|
9
14
|
isPickList: () => true;
|
|
10
15
|
/** The highlighted row, or `-1` when the list is empty. */
|
|
@@ -47,7 +52,7 @@ export interface PickListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
47
52
|
*/
|
|
48
53
|
measureText?: (text: string) => number;
|
|
49
54
|
/** Render a row's content. @defaultValue the text, clipped with an ellipsis. */
|
|
50
|
-
renderItem?: (
|
|
55
|
+
renderItem?: (props: PickListItemRenderProps) => React.ReactNode;
|
|
51
56
|
/** Take focus on mount, so the Arrow keys work without a click first. @defaultValue false */
|
|
52
57
|
autoFocus?: boolean;
|
|
53
58
|
/** The scroll state, when the caller owns it (see `ListSurfaceProps.viewport`). */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CellCoords, RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
import { RangeGlide } from './RangeGlide';
|
|
2
3
|
/** Which corner (`tl`/`tr`/`bl`/`br`) or edge-midpoint (`t`/`b`/`l`/`r`) of the range to sit on. */
|
|
3
4
|
export type HandleAnchor = 'tl' | 'tr' | 'bl' | 'br' | 't' | 'b' | 'l' | 'r';
|
|
4
5
|
/**
|
|
@@ -24,6 +25,8 @@ export interface DragHandleRenderProps {
|
|
|
24
25
|
handleProps: {
|
|
25
26
|
/** The handle's identifying class(es) — `drag-handle` plus whatever the flavor tagged it with. */
|
|
26
27
|
className?: string;
|
|
28
|
+
/** The handle element, which a glide moves frame by frame. Any element type takes it. */
|
|
29
|
+
ref: (element: HTMLElement | null) => void;
|
|
27
30
|
onPointerDown: (e: React.PointerEvent) => void;
|
|
28
31
|
onDoubleClick?: (e: React.MouseEvent) => void;
|
|
29
32
|
onPointerEnter?: (e: React.PointerEvent) => void;
|
|
@@ -54,8 +57,11 @@ export interface DragHandleProps {
|
|
|
54
57
|
dragCursor?: string;
|
|
55
58
|
/** Default-dot background, and the theme color handed to {@link DragHandleProps.renderHandle}. */
|
|
56
59
|
background?: string;
|
|
57
|
-
/**
|
|
58
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Drag started; `cell` is under the pointer at press. `cancel` aborts this drag as Escape would
|
|
62
|
+
* ({@link DragHandleProps.onDragCancel} follows) — hand it to chrome that offers a way out.
|
|
63
|
+
*/
|
|
64
|
+
onDragStart?: (cell: CellCoords, e: React.PointerEvent, cancel: () => void) => void;
|
|
59
65
|
/** The pointer moved to a new cell during the drag (`from` = press cell, `to` = current). */
|
|
60
66
|
onDragMove?: (from: CellCoords, to: CellCoords, e: React.PointerEvent) => void;
|
|
61
67
|
/** Drag ended (`from` = press cell, `to` = last cell). */
|
|
@@ -85,11 +91,12 @@ export interface DragHandleProps {
|
|
|
85
91
|
*/
|
|
86
92
|
hoverStyle?: React.CSSProperties;
|
|
87
93
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
94
|
+
* Ride this glide's frames while it is in flight — the same clock as a {@link RangeRect} given the
|
|
95
|
+
* same glide, so the handle stays on the outline's corner. The glide must be heading to `range`. A
|
|
96
|
+
* handle pinned to the view ({@link DragHandleProps.clampToView}) hides until the glide lands: its
|
|
97
|
+
* pinned edge has no place along the way.
|
|
91
98
|
*/
|
|
92
|
-
|
|
99
|
+
glide?: RangeGlide | null;
|
|
93
100
|
/**
|
|
94
101
|
* Pin the handle centre INSIDE the pane's viewport instead of letting it sit at the range's true
|
|
95
102
|
* anchored corner. When that corner is far off-grid — e.g. a whole-row / whole-column fill selection
|