@sheetxl/grid-react 0.7.22 → 0.7.23-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 -1497
- package/types/src/cell/CellLayer.d.ts +70 -0
- package/types/src/cell/CellLayer.d.ts.map +1 -0
- package/types/src/cell/CellRenderer.d.ts +42 -0
- package/types/src/cell/CellRenderer.d.ts.map +1 -0
- package/types/src/cell/DefaultCellRenderer.d.ts +6 -0
- package/types/src/cell/DefaultCellRenderer.d.ts.map +1 -0
- package/types/src/cell/GridlineLayer.d.ts +38 -0
- package/types/src/cell/GridlineLayer.d.ts.map +1 -0
- package/types/src/cell/Types.d.ts +12 -0
- package/types/src/cell/Types.d.ts.map +1 -0
- package/types/src/cell/_CellModel.d.ts +82 -0
- package/types/src/cell/_CellModel.d.ts.map +1 -0
- package/types/src/cell/index.d.ts +6 -0
- package/types/src/cell/index.d.ts.map +1 -0
- package/types/src/editor/DefaultEditable.d.ts +121 -0
- package/types/src/editor/DefaultEditable.d.ts.map +1 -0
- package/types/src/editor/EditSession.d.ts +182 -0
- package/types/src/editor/EditSession.d.ts.map +1 -0
- package/types/src/editor/EditState.d.ts +61 -0
- package/types/src/editor/EditState.d.ts.map +1 -0
- package/types/src/editor/EditorDiv.d.ts +65 -0
- package/types/src/editor/EditorDiv.d.ts.map +1 -0
- package/types/src/editor/EditorInput.d.ts +88 -0
- package/types/src/editor/EditorInput.d.ts.map +1 -0
- package/types/src/editor/EditorLayer.d.ts +69 -0
- package/types/src/editor/EditorLayer.d.ts.map +1 -0
- package/types/src/editor/EditorPlacement.d.ts +38 -0
- package/types/src/editor/EditorPlacement.d.ts.map +1 -0
- package/types/src/editor/index.d.ts +10 -0
- package/types/src/editor/index.d.ts.map +1 -0
- package/types/src/editor/useEditorKeymap.d.ts +74 -0
- package/types/src/editor/useEditorKeymap.d.ts.map +1 -0
- package/types/src/grid/Grid.d.ts +16 -0
- package/types/src/grid/Grid.d.ts.map +1 -0
- package/types/src/grid/IGrid.d.ts +93 -0
- package/types/src/grid/IGrid.d.ts.map +1 -0
- package/types/src/grid/index.d.ts +3 -0
- package/types/src/grid/index.d.ts.map +1 -0
- package/types/src/header/HeaderDividerAnchor.d.ts +120 -0
- package/types/src/header/HeaderDividerAnchor.d.ts.map +1 -0
- package/types/src/header/index.d.ts +3 -0
- package/types/src/header/index.d.ts.map +1 -0
- package/types/src/header/useHeaderSelectionPointer.d.ts +122 -0
- package/types/src/header/useHeaderSelectionPointer.d.ts.map +1 -0
- package/types/src/index.d.ts +13 -0
- package/types/src/index.d.ts.map +1 -0
- package/types/src/layer/HoverTipLayer.d.ts +74 -0
- package/types/src/layer/HoverTipLayer.d.ts.map +1 -0
- package/types/src/layer/Layer.d.ts +92 -0
- package/types/src/layer/Layer.d.ts.map +1 -0
- package/types/src/layer/LayerTypes.d.ts +47 -0
- package/types/src/layer/LayerTypes.d.ts.map +1 -0
- package/types/src/layer/RangePrompt.d.ts +42 -0
- package/types/src/layer/RangePrompt.d.ts.map +1 -0
- package/types/src/layer/Stage.d.ts +147 -0
- package/types/src/layer/Stage.d.ts.map +1 -0
- package/types/src/layer/StickyAnchor.d.ts +83 -0
- package/types/src/layer/StickyAnchor.d.ts.map +1 -0
- package/types/src/layer/StickyFloat.d.ts +65 -0
- package/types/src/layer/StickyFloat.d.ts.map +1 -0
- package/types/src/layer/VirtualDiv.d.ts +59 -0
- package/types/src/layer/VirtualDiv.d.ts.map +1 -0
- package/types/src/layer/_Utils.d.ts +37 -0
- package/types/src/layer/_Utils.d.ts.map +1 -0
- package/types/src/layer/index.d.ts +11 -0
- package/types/src/layer/index.d.ts.map +1 -0
- package/types/src/layer/useGridAnchor.d.ts +157 -0
- package/types/src/layer/useGridAnchor.d.ts.map +1 -0
- package/types/src/layer/useHoverIntent.d.ts +49 -0
- package/types/src/layer/useHoverIntent.d.ts.map +1 -0
- package/types/src/layer/useLayerResponder.d.ts +29 -0
- package/types/src/layer/useLayerResponder.d.ts.map +1 -0
- package/types/src/layer/usePlacement.d.ts +18 -0
- package/types/src/layer/usePlacement.d.ts.map +1 -0
- package/types/src/layer/useRangeHover.d.ts +35 -0
- package/types/src/layer/useRangeHover.d.ts.map +1 -0
- package/types/src/list/CheckboxList.d.ts +63 -0
- package/types/src/list/CheckboxList.d.ts.map +1 -0
- package/types/src/list/List.d.ts +55 -0
- package/types/src/list/List.d.ts.map +1 -0
- package/types/src/list/index.d.ts +3 -0
- package/types/src/list/index.d.ts.map +1 -0
- package/types/src/metrics/Types.d.ts +23 -0
- package/types/src/metrics/Types.d.ts.map +1 -0
- package/types/src/metrics/index.d.ts +3 -0
- package/types/src/metrics/index.d.ts.map +1 -0
- package/types/src/metrics/useGridMetrics.d.ts +67 -0
- package/types/src/metrics/useGridMetrics.d.ts.map +1 -0
- package/types/src/range/DragHandle.d.ts +129 -0
- package/types/src/range/DragHandle.d.ts.map +1 -0
- package/types/src/range/Draggable.d.ts +86 -0
- package/types/src/range/Draggable.d.ts.map +1 -0
- package/types/src/range/FillHandle.d.ts +54 -0
- package/types/src/range/FillHandle.d.ts.map +1 -0
- package/types/src/range/RangeRect.d.ts +36 -0
- package/types/src/range/RangeRect.d.ts.map +1 -0
- package/types/src/range/RangeResizer.d.ts +68 -0
- package/types/src/range/RangeResizer.d.ts.map +1 -0
- package/types/src/range/RangeStyle.d.ts +8 -0
- package/types/src/range/RangeStyle.d.ts.map +1 -0
- package/types/src/range/index.d.ts +13 -0
- package/types/src/range/index.d.ts.map +1 -0
- package/types/src/selection/DefaultSelection.d.ts +59 -0
- package/types/src/selection/DefaultSelection.d.ts.map +1 -0
- package/types/src/selection/ICellAnchor.d.ts +21 -0
- package/types/src/selection/ICellAnchor.d.ts.map +1 -0
- package/types/src/selection/ISelection.d.ts +65 -0
- package/types/src/selection/ISelection.d.ts.map +1 -0
- package/types/src/selection/RangesPickerLayer.d.ts +128 -0
- package/types/src/selection/RangesPickerLayer.d.ts.map +1 -0
- package/types/src/selection/SelectionLayer.d.ts +179 -0
- package/types/src/selection/SelectionLayer.d.ts.map +1 -0
- package/types/src/selection/SelectionStyle.d.ts +28 -0
- package/types/src/selection/SelectionStyle.d.ts.map +1 -0
- package/types/src/selection/SelectionTouchGrips.d.ts +29 -0
- package/types/src/selection/SelectionTouchGrips.d.ts.map +1 -0
- package/types/src/selection/SelectionUtils.d.ts +2 -0
- package/types/src/selection/SelectionUtils.d.ts.map +1 -0
- package/types/src/selection/Types.d.ts +67 -0
- package/types/src/selection/Types.d.ts.map +1 -0
- package/types/src/selection/_SelectionNavigation.d.ts +6 -0
- package/types/src/selection/_SelectionNavigation.d.ts.map +1 -0
- package/types/src/selection/_SelectionUtils.d.ts +7 -0
- package/types/src/selection/_SelectionUtils.d.ts.map +1 -0
- package/types/src/selection/index.d.ts +12 -0
- package/types/src/selection/index.d.ts.map +1 -0
- package/types/src/selection/useDragCells.d.ts +218 -0
- package/types/src/selection/useDragCells.d.ts.map +1 -0
- package/types/src/selection/useSelectionPointer.d.ts +70 -0
- package/types/src/selection/useSelectionPointer.d.ts.map +1 -0
- package/types/src/surface/GridPane.d.ts +85 -0
- package/types/src/surface/GridPane.d.ts.map +1 -0
- package/types/src/surface/GridPaneProvider.d.ts +37 -0
- package/types/src/surface/GridPaneProvider.d.ts.map +1 -0
- package/types/src/surface/GridSurface.d.ts +11 -0
- package/types/src/surface/GridSurface.d.ts.map +1 -0
- package/types/src/surface/IGridPane.d.ts +288 -0
- package/types/src/surface/IGridPane.d.ts.map +1 -0
- package/types/src/surface/IGridSurface.d.ts +141 -0
- package/types/src/surface/IGridSurface.d.ts.map +1 -0
- package/types/src/surface/SurfaceStateProvider.d.ts +50 -0
- package/types/src/surface/SurfaceStateProvider.d.ts.map +1 -0
- package/types/src/surface/_GridUtils.d.ts +37 -0
- package/types/src/surface/_GridUtils.d.ts.map +1 -0
- package/types/src/surface/index.d.ts +7 -0
- package/types/src/surface/index.d.ts.map +1 -0
- package/types/src/surface/useGridPane.d.ts +31 -0
- package/types/src/surface/useGridPane.d.ts.map +1 -0
- package/types/src/surface/useSurfaceState.d.ts +22 -0
- package/types/src/surface/useSurfaceState.d.ts.map +1 -0
- package/types/src/svg/LineSVG.d.ts +13 -0
- package/types/src/svg/LineSVG.d.ts.map +1 -0
- package/types/src/svg/RectangleSVG.d.ts +114 -0
- package/types/src/svg/RectangleSVG.d.ts.map +1 -0
- package/types/src/svg/ShapeBounds.d.ts +15 -0
- package/types/src/svg/ShapeBounds.d.ts.map +1 -0
- package/types/src/svg/Types.d.ts +37 -0
- package/types/src/svg/Types.d.ts.map +1 -0
- package/types/src/svg/index.d.ts +9 -0
- package/types/src/svg/index.d.ts.map +1 -0
- package/types/src/theme/GridTheme.d.ts +56 -0
- package/types/src/theme/GridTheme.d.ts.map +1 -0
- package/types/src/theme/index.d.ts +2 -0
- package/types/src/theme/index.d.ts.map +1 -0
- package/node/assets/style.css +0 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link useHoverIntent}.
|
|
3
|
+
*/
|
|
4
|
+
export interface UseHoverIntentOptions {
|
|
5
|
+
/** Dwell (ms) over a target before opening — kills pass-through flicker. @defaultValue 300 */
|
|
6
|
+
openDelay?: number;
|
|
7
|
+
/** Grace (ms) after leaving before closing — lets the pointer cross the gap to the float. @defaultValue 150 */
|
|
8
|
+
closeDelay?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Props to spread onto the floated element so hovering IT keeps the float open. */
|
|
11
|
+
export interface HoverTipProps {
|
|
12
|
+
onPointerEnter: () => void;
|
|
13
|
+
onPointerLeave: () => void;
|
|
14
|
+
style: React.CSSProperties;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The result of {@link useHoverIntent}.
|
|
18
|
+
*/
|
|
19
|
+
export interface UseHoverIntentResult {
|
|
20
|
+
/** Whether the float should be shown. */
|
|
21
|
+
open: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Aim the intent at a target, or `null` for "nothing hovered". Idempotent per key: calling with the
|
|
24
|
+
* SAME key (e.g. every `pointermove` within one cell) does NOT restart the open timer. Changing the
|
|
25
|
+
* key while open re-aims without closing.
|
|
26
|
+
*/
|
|
27
|
+
setTarget: (key: string | null) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Spread onto the floated element so hovering IT keeps the float open (bridges the anchor→float
|
|
30
|
+
* gap). Sets `pointer-events: auto` and cancels / reschedules the close on enter / leave.
|
|
31
|
+
*/
|
|
32
|
+
tipProps: HoverTipProps;
|
|
33
|
+
/**
|
|
34
|
+
* Close the float **immediately**, bypassing the `closeDelay` grace — for a hard dismissal (e.g. the
|
|
35
|
+
* anchored cell entered edit mode) rather than the pointer merely wandering off.
|
|
36
|
+
*/
|
|
37
|
+
close: () => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The reusable **hover-intent state machine** behind a hover tooltip — delays + keep-open-on-tip-hover,
|
|
41
|
+
* with NO hit-testing of its own. Feed it a target key via {@link UseHoverIntentResult.setTarget}
|
|
42
|
+
* (`null` = nothing) and it debounces open / close; spread {@link UseHoverIntentResult.tipProps} on the
|
|
43
|
+
* float so moving onto the float itself keeps it open.
|
|
44
|
+
*
|
|
45
|
+
* {@link useRangeHover} wraps this with a pointer responder against a fixed range; a dynamic consumer
|
|
46
|
+
* (e.g. an error layer discovering the hovered cell) drives `setTarget` itself.
|
|
47
|
+
*/
|
|
48
|
+
export declare const useHoverIntent: (options?: UseHoverIntentOptions) => UseHoverIntentResult;
|
|
49
|
+
//# sourceMappingURL=useHoverIntent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHoverIntent.d.ts","sourceRoot":"","sources":["../../../../src/layer/useHoverIntent.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+GAA+G;IAC/G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,oFAAoF;AACpF,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;IACxB;;;OAGG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAID;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,UAAS,qBAA0B,KAAG,oBAwDpE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for {@link useLayerResponder}.
|
|
3
|
+
*/
|
|
4
|
+
export interface UseLayerResponderOptions {
|
|
5
|
+
/** Live accessor for the box's DOM element (null while culled / unmounted). */
|
|
6
|
+
getElement: () => Element | null;
|
|
7
|
+
/**
|
|
8
|
+
* The box's spread props (`...rest`). Its event handlers (`onPointerDown`, …) are exposed to the
|
|
9
|
+
* Stage so the box can be invoked when it sits BELOW the native target (where its own handlers
|
|
10
|
+
* did not fire natively). The handlers stay native on the element too — for the hit case (the
|
|
11
|
+
* "up your subtree" phase of the one-bubble law).
|
|
12
|
+
*
|
|
13
|
+
* (`any`: a JSX spread bag — heterogeneous by nature; only `function`-valued walked-event props
|
|
14
|
+
* are ever read, guarded by a `typeof` check.)
|
|
15
|
+
*/
|
|
16
|
+
handlerProps?: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Registers a geometried box ({@link VirtualDiv}) with its pane's Stage so the DOM-driven dispatch
|
|
20
|
+
* can resolve the box a hit element belongs to, interleave it with the layer taps at its **layer's
|
|
21
|
+
* slot** (read from {@link LayerOrderContext}), and invoke boxes below the native target.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Registration lives in a registry SEPARATE from the tap chain (see `Stage.LayerRegistration`); the
|
|
25
|
+
* latest accessors are read through a ref so the registration is stable for the box's life. Call it
|
|
26
|
+
* unconditionally (before any early `return null`).
|
|
27
|
+
*/
|
|
28
|
+
export declare const useLayerResponder: ({ getElement, handlerProps }: UseLayerResponderOptions) => void;
|
|
29
|
+
//# sourceMappingURL=useLayerResponder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLayerResponder.d.ts","sourceRoot":"","sources":["../../../../src/layer/useLayerResponder.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,+EAA+E;IAC/E,UAAU,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IACjC;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,8BAA8B,wBAAwB,KAAG,IAqC1F,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Bounds } from '@sheetxl/utils';
|
|
2
|
+
import { IGridPane } from '../surface';
|
|
3
|
+
import { VirtualDivPlacement } from './LayerTypes';
|
|
4
|
+
/** The resolved placement: the pane, the RAW (pre-snap) bounds, and whether it's fully off-screen. */
|
|
5
|
+
export interface Placement {
|
|
6
|
+
pane: IGridPane;
|
|
7
|
+
raw: Bounds;
|
|
8
|
+
/** True when fully off-screen. The caller decides whether to cull (`return null`) or keep mounted. */
|
|
9
|
+
culled: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a {@link VirtualDivPlacement} against the current pane: range → bounds (or explicit
|
|
13
|
+
* bounds, or the pane box for `fill`), plus the off-screen cull flag. Returns `null` when there is
|
|
14
|
+
* no pane or no placement to resolve. Shared by {@link VirtualDiv} / {@link RangeRect} so the
|
|
15
|
+
* resolve-and-cull logic lives once.
|
|
16
|
+
*/
|
|
17
|
+
export declare const usePlacement: ({ range, bounds, fill, clipInsets }: VirtualDivPlacement) => Placement | null;
|
|
18
|
+
//# sourceMappingURL=usePlacement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePlacement.d.ts","sourceRoot":"","sources":["../../../../src/layer/usePlacement.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,sGAAsG;AACtG,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,sGAAsG;IACtG,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,qCAAqC,mBAAmB,KAAG,SAAS,GAAG,IAkCnG,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
import { UseHoverIntentOptions, HoverTipProps } from './useHoverIntent';
|
|
3
|
+
/**
|
|
4
|
+
* The result of {@link useRangeHover}.
|
|
5
|
+
*/
|
|
6
|
+
export interface UseRangeHoverResult {
|
|
7
|
+
/** Whether a hover tooltip for the range should be shown (after the intent delays). */
|
|
8
|
+
open: boolean;
|
|
9
|
+
/** Spread onto the floated tip so hovering it keeps the tooltip open (see {@link HoverTipProps}). */
|
|
10
|
+
tipProps: HoverTipProps;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Tracks the pointer over a **fixed grid range** and drives hover-tooltip intent: returns `open` (with
|
|
14
|
+
* open / close delays) plus `tipProps` to keep the tip open while the pointer is on it. Pair with
|
|
15
|
+
* {@link StickyFloat} for the label:
|
|
16
|
+
*
|
|
17
|
+
* ```tsx
|
|
18
|
+
* const { open, tipProps } = useRangeHover(range);
|
|
19
|
+
* <StickyFloat anchor={{ range }} placement={{ side: 't' }} offset={6} open={open}>
|
|
20
|
+
* <div {...tipProps}>Value must be a positive number</div>
|
|
21
|
+
* </StickyFloat>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Must be called inside a grid (needs pane context). For a **dynamic** target (an error layer that
|
|
25
|
+
* discovers whichever hovered cell has errors), drive {@link useHoverIntent} directly instead.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* Registers a passive `pointermove` / `pointerleave` responder on the pane's Stage (mirrors
|
|
29
|
+
* a {@link Layer} tap); it never consumes the event. Because a grid child renders per pane, the tip
|
|
30
|
+
* resolves on the pane owning the anchor — for a range that straddles panes the open state follows the
|
|
31
|
+
* pointer's pane, which can differ from the owner (a known v1 limitation; small / single-cell ranges,
|
|
32
|
+
* the common error-tooltip case, are unaffected).
|
|
33
|
+
*/
|
|
34
|
+
export declare const useRangeHover: (range: RangeCoords, options?: UseHoverIntentOptions) => UseRangeHoverResult;
|
|
35
|
+
//# sourceMappingURL=useRangeHover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRangeHover.d.ts","sourceRoot":"","sources":["../../../../src/layer/useRangeHover.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAK9D,OAAO,EACW,KAAK,qBAAqB,EAAE,KAAK,aAAa,EAC/D,MAAM,kBAAkB,CAAC;AAK1B;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,IAAI,EAAE,OAAO,CAAC;IACd,qGAAqG;IACrG,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,WAAW,EAAE,UAAS,qBAA0B,KAAG,mBA+BvF,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ISelection } from '../selection';
|
|
3
|
+
export interface CheckboxListAttributes {
|
|
4
|
+
isCheckboxList: () => true;
|
|
5
|
+
}
|
|
6
|
+
export interface ICheckboxListElement extends HTMLDivElement, CheckboxListAttributes {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Props for {@link CheckboxList}.
|
|
10
|
+
*/
|
|
11
|
+
export interface CheckboxListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
/** Number of rows. */
|
|
13
|
+
itemCount: number;
|
|
14
|
+
/** Whether the item at `index` is checked. */
|
|
15
|
+
isChecked: (index: number) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Set `indices` to `checked`. Called with a single index on a click, every selected row on a keyboard
|
|
18
|
+
* toggle (Space/Enter), and every row from `(Select All)`. The caller maps `index` to its own store.
|
|
19
|
+
*/
|
|
20
|
+
onCheckedChange: (indices: number[], checked: boolean) => void;
|
|
21
|
+
/** The value/label content for `index`. */
|
|
22
|
+
renderValue: (index: number) => React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Render the checkbox **control** (visual only — the row owns the toggle, so it's forced
|
|
25
|
+
* `pointerEvents:none`). `indeterminate` is set for the `(Select All)` tri-state. Override to use a
|
|
26
|
+
* styled control (MUI etc.). @defaultValue a native checkbox.
|
|
27
|
+
*/
|
|
28
|
+
renderCheckbox?: (checked: boolean, indeterminate?: boolean) => React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Render a divider between the `(Select All)` header and the list, or elsewhere as needed.
|
|
31
|
+
*/
|
|
32
|
+
renderDivider?: () => React.ReactNode;
|
|
33
|
+
/**
|
|
34
|
+
* Show a tri-state **(Select All)** header with this label. It operates over *all* rows — which in a
|
|
35
|
+
* filtered list are the filtered ones, so it's "Select all (filtered)" automatically.
|
|
36
|
+
*/
|
|
37
|
+
selectAllLabel?: React.ReactNode;
|
|
38
|
+
/** Uniform row height in px. @defaultValue 24 */
|
|
39
|
+
itemHeight?: number;
|
|
40
|
+
/** Selection model (highlight + Arrow nav). Created internally if omitted. */
|
|
41
|
+
selection?: ISelection;
|
|
42
|
+
/** Content cache-bust; bump when checked state changes without `isChecked`'s identity changing. */
|
|
43
|
+
cacheToken?: unknown;
|
|
44
|
+
/** Ref for the Element. */
|
|
45
|
+
ref?: React.Ref<ICheckboxListElement>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A **checkbox list** on top of {@link List}: a virtualized multi-select with a checkbox per row and an
|
|
49
|
+
* optional tri-state `(Select All)` header.
|
|
50
|
+
*
|
|
51
|
+
* @remarks
|
|
52
|
+
* Owns the toggle behavior — the part worth not re-deriving:
|
|
53
|
+
* - **Click** (anywhere on a row) toggles that one row, and selects it.
|
|
54
|
+
* - **Space / Enter** toggles every *selected* row using the **anchor** (active cell) as the template:
|
|
55
|
+
* if the anchor is checked the whole selection clears, otherwise it sets — so a mixed multi-selection
|
|
56
|
+
* goes uniform rather than checkerboarding.
|
|
57
|
+
* - **(Select All)** sets every row to the opposite of the all-checked state.
|
|
58
|
+
*
|
|
59
|
+
* Checked state is the caller's store (`isChecked` / `onCheckedChange`), orthogonal to the selection.
|
|
60
|
+
* Styling is the caller's via {@link CheckboxListProps.renderValue} / {@link CheckboxListProps.renderCheckbox}.
|
|
61
|
+
*/
|
|
62
|
+
export declare const CheckboxList: React.ForwardRefExoticComponent<Omit<CheckboxListProps, "ref"> & React.RefAttributes<ICheckboxListElement>>;
|
|
63
|
+
//# sourceMappingURL=CheckboxList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckboxList.d.ts","sourceRoot":"","sources":["../../../../src/list/CheckboxList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAEN,MAAM,OAAO,CAAC;AAMf,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAIjE,MAAM,WAAW,sBAAsB;IACrC,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAqB,SAAQ,cAAc,EAAE,sBAAsB;CAAG;AAEvF;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC7E,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACtC;;;OAGG;IACH,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/D,2CAA2C;IAC3C,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAChD;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,OAAO,KAAK,KAAK,CAAC,SAAS,CAAC;IAChF;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;IACtC;;;OAGG;IACH,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB,mGAAmG;IACnG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;CACvC;AAqBD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,6GA2GvB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ISelection } from '../selection';
|
|
3
|
+
export interface ListAttributes {
|
|
4
|
+
isList: () => true;
|
|
5
|
+
}
|
|
6
|
+
export interface IListElement extends HTMLDivElement, ListAttributes {
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Props for {@link List}.
|
|
10
|
+
*/
|
|
11
|
+
export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
/** Number of rows. */
|
|
13
|
+
itemCount: number;
|
|
14
|
+
/**
|
|
15
|
+
* Content for the item at `index`. Called only for the *visible* rows (virtualized), so real
|
|
16
|
+
* interactive controls — checkboxes, buttons — are fine here. `index` is the row index (for a
|
|
17
|
+
* filtered list this is the *view* index — map it to your source store yourself).
|
|
18
|
+
*/
|
|
19
|
+
renderItem: (index: number) => React.ReactNode;
|
|
20
|
+
/** Uniform row height in px. @defaultValue 24 */
|
|
21
|
+
itemHeight?: number;
|
|
22
|
+
/**
|
|
23
|
+
* The selection model — the active-row highlight + Arrow-key navigation. The List's *state*. Owned
|
|
24
|
+
* by the caller (so it can read what's selected); a private one is created when omitted.
|
|
25
|
+
*/
|
|
26
|
+
selection?: ISelection;
|
|
27
|
+
/**
|
|
28
|
+
* Key events over the list. Forwarded into the grid's keyboard layer (so it fires even for keys the
|
|
29
|
+
* grid would otherwise consume, like Enter) — runs before the built-in Arrow navigation, so handle
|
|
30
|
+
* Space/Enter here and `stopPropagation` to override. Read {@link ListProps.selection} to act on the
|
|
31
|
+
* selected rows; Arrows you don't handle fall through to navigation.
|
|
32
|
+
*/
|
|
33
|
+
onKeyDown?: (e: React.KeyboardEvent) => void;
|
|
34
|
+
/**
|
|
35
|
+
* Opaque content cache-bust forwarded to the `CellLayer`. Bump (new identity) when an item's
|
|
36
|
+
* *rendered* content changed without `renderItem`'s identity changing.
|
|
37
|
+
*/
|
|
38
|
+
cacheToken?: unknown;
|
|
39
|
+
/** Ref for the Element. */
|
|
40
|
+
ref?: React.Ref<IListElement>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A virtualized **list** built on `GridSurface` with the grid's own layers — a `CellLayer` for the
|
|
44
|
+
* items and a `SelectionLayer` for the active-row highlight + Arrow keys (the same shape as the editor
|
|
45
|
+
* demo: a model passed to layers as props).
|
|
46
|
+
*
|
|
47
|
+
* @remarks
|
|
48
|
+
* The List's whole state is its {@link ListProps.selection}; it has no per-item callbacks and no notion
|
|
49
|
+
* of "checked" or "toggle". Pointer selection is the `SelectionLayer`'s job (it hit-tests the pointer),
|
|
50
|
+
* so the cells are inert, transparent content; the keyboard is the caller's via {@link ListProps.onKeyDown}.
|
|
51
|
+
* The active row fills (no Excel anchor hole) and carries an inset ring, since the anchor is the live
|
|
52
|
+
* Space/scroll target. See {@link CheckboxList} for the checkbox-list specialization.
|
|
53
|
+
*/
|
|
54
|
+
export declare const List: React.ForwardRefExoticComponent<Omit<ListProps, "ref"> & React.RefAttributes<IListElement>>;
|
|
55
|
+
//# sourceMappingURL=List.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"List.d.ts","sourceRoot":"","sources":["../../../../src/list/List.tsx"],"names":[],"mappings":"AAAA,OAAO,KAEN,MAAM,OAAO,CAAC;AAYf,OAAO,EAC6B,KAAK,UAAU,EAClD,MAAM,cAAc,CAAC;AAqBtB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc,EAAE,cAAc;CAAG;AAEvE;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACrE,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;IAC/C,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;IAC7C;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI,6FAyGf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/list/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function that returns the size of an item given its index.
|
|
3
|
+
*/
|
|
4
|
+
export type ItemSizer = (index: number) => number;
|
|
5
|
+
export interface IGridMetrics {
|
|
6
|
+
/**
|
|
7
|
+
* Returns the offset given an index.
|
|
8
|
+
*/
|
|
9
|
+
getColOffset: ItemSizer;
|
|
10
|
+
/**
|
|
11
|
+
* Returns the index given an offset.
|
|
12
|
+
*/
|
|
13
|
+
getColIndex: ItemSizer;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the offset given an index.
|
|
16
|
+
*/
|
|
17
|
+
getRowOffset: ItemSizer;
|
|
18
|
+
/**
|
|
19
|
+
* Returns the index given an offset.
|
|
20
|
+
*/
|
|
21
|
+
getRowIndex: ItemSizer;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=Types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Types.d.ts","sourceRoot":"","sources":["../../../../src/metrics/Types.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;AAElD,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,YAAY,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,WAAW,EAAE,SAAS,CAAC;IACvB;;OAEG;IACH,YAAY,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,WAAW,EAAE,SAAS,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/metrics/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ItemSizer, IGridMetrics } from './Types';
|
|
2
|
+
/**
|
|
3
|
+
* One axis (rows OR columns) of the grid: maps an item index ⇄ its pixel offset.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* The public {@link IGridMetrics} is exactly four of these (`get(Col|Row)(Offset|Index)`); an axis is
|
|
7
|
+
* the per-direction half. `getOffset` returns the LEADING edge of an item; `getIndex` is its inverse
|
|
8
|
+
* (the item whose span contains a pixel offset). Both clamp gracefully outside the grid: a negative
|
|
9
|
+
* index/offset → `0`, an offset at/past the total extent → `count` (one past the last) — on BOTH the
|
|
10
|
+
* uniform and variable paths. On a run of zero-size (hidden) items — an equal-offset plateau —
|
|
11
|
+
* `getIndex` deterministically resolves to the LAST index of the run: the following sized item, the
|
|
12
|
+
* one whose span actually contains the pixel (a zero-size span contains nothing).
|
|
13
|
+
*/
|
|
14
|
+
export interface Axis {
|
|
15
|
+
/** Leading-edge pixel offset of `index` (0 for `index <= 0`). */
|
|
16
|
+
getOffset: ItemSizer;
|
|
17
|
+
/** Item index whose span contains pixel `offset` (0 at/under the origin, clamped to `count`). */
|
|
18
|
+
getIndex: ItemSizer;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build an {@link Axis} from a fixed size or a per-index sizer.
|
|
22
|
+
*
|
|
23
|
+
* - **Uniform** (a `number`): closed-form arithmetic — no allocation, no cache, O(1) both ways. This
|
|
24
|
+
* is the overwhelmingly common case (every default grid, every fixed row height) and the supported
|
|
25
|
+
* large-grid mode.
|
|
26
|
+
* - **Variable** (an {@link ItemSizer}): offsets are MEASURED lazily and memoized in dense arrays
|
|
27
|
+
* (indices fill sequentially from 0). The *search* over the already-measured prefix is O(log n)
|
|
28
|
+
* (binary search, with an exponential probe to bracket a target past it) — but **measurement is
|
|
29
|
+
* linear and cumulative**: a jump to index N measures and permanently caches every offset `0..N`
|
|
30
|
+
* (O(N) time & memory on first touch; a far jump into a 1M-item axis walks ~1M sizer calls). This
|
|
31
|
+
* path is the convenience tier for human-scale variable axes. Grids that need large *and* variable
|
|
32
|
+
* don't use it — they pass a prebuilt {@link IGridMetrics} (e.g. the SDK's run-length metrics)
|
|
33
|
+
* instead of a sizer. (GRID-CLEAN F1: documented as-is by design; no sublinear tree here.)
|
|
34
|
+
*
|
|
35
|
+
* Exported for tests (uniform/variable edge parity — GRID-CLEAN B4/B5); not part of the package API.
|
|
36
|
+
*/
|
|
37
|
+
export declare const createAxis: (count: number, size: ItemSizer | number) => Axis;
|
|
38
|
+
export interface UseGridMetricOptions {
|
|
39
|
+
/**
|
|
40
|
+
* Number of columns in the grid.
|
|
41
|
+
*/
|
|
42
|
+
columnCount: number;
|
|
43
|
+
/**
|
|
44
|
+
* Number of rows in the grid.
|
|
45
|
+
*/
|
|
46
|
+
rowCount: number;
|
|
47
|
+
/**
|
|
48
|
+
* Row height: a fixed number (uniform) or a `(index) => number` sizer. Defaults to `20`.
|
|
49
|
+
*/
|
|
50
|
+
getRowHeight?: ItemSizer | number;
|
|
51
|
+
/**
|
|
52
|
+
* Column width: a fixed number (uniform) or a `(index) => number` sizer. Defaults to `75`.
|
|
53
|
+
*/
|
|
54
|
+
getColumnWidth?: ItemSizer | number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build an {@link IGridMetrics} (the index ⇄ offset mapping the surface needs) from a row/column
|
|
58
|
+
* count plus fixed sizes or per-index sizers.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* The returned object's IDENTITY changes only when the geometry inputs do (count or sizer) — never on
|
|
62
|
+
* scroll — which is exactly the signal the surface keys its pane recreation on. A `null` `props`
|
|
63
|
+
* yields `null` (the engine then falls back to its own default metrics). `IGridMetrics` is the entire
|
|
64
|
+
* consumed contract; nothing else is exposed.
|
|
65
|
+
*/
|
|
66
|
+
export declare const useGridMetrics: (props: UseGridMetricOptions | null) => IGridMetrics | null;
|
|
67
|
+
//# sourceMappingURL=useGridMetrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridMetrics.d.ts","sourceRoot":"","sources":["../../../../src/metrics/useGridMetrics.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAK5D;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,IAAI;IACnB,iEAAiE;IACjE,SAAS,EAAE,SAAS,CAAC;IACrB,iGAAiG;IACjG,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,EAAE,MAAM,SAAS,GAAG,MAAM,KAAG,IAgFpE,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAClC;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CACrC;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,oBAAoB,GAAG,IAAI,KAAG,YAAY,GAAG,IAkBlF,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { CellCoords, RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
/** Which corner (`tl`/`tr`/`bl`/`br`) or edge-midpoint (`t`/`b`/`l`/`r`) of the range to sit on. */
|
|
3
|
+
export type HandleAnchor = 'tl' | 'tr' | 'bl' | 'br' | 't' | 'b' | 'l' | 'r';
|
|
4
|
+
/**
|
|
5
|
+
* Resolved info passed to {@link DragHandleProps.renderHandle}.
|
|
6
|
+
*/
|
|
7
|
+
export interface DragHandleRenderProps {
|
|
8
|
+
/** The corner/edge this handle sits on. */
|
|
9
|
+
anchor: HandleAnchor;
|
|
10
|
+
/** Resolved size (px). */
|
|
11
|
+
size: number;
|
|
12
|
+
/** Resolved cursor (anchor-derived unless overridden). */
|
|
13
|
+
cursor: string;
|
|
14
|
+
/** Resolved background color — handy as a theme color for custom marks. */
|
|
15
|
+
background: string;
|
|
16
|
+
/** Whether the pointer is currently over the handle (for a hover affordance). */
|
|
17
|
+
hovered: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* **Spread onto your handle element** — this wires placement, pointer-capture, cursor, and the
|
|
20
|
+
* drag events. Without it the handle won't drag. Only pointer-DOWN is on the element; the drag's
|
|
21
|
+
* move/up are attached to `window` for the gesture's duration (so it survives the handle
|
|
22
|
+
* repositioning under an edge auto-scroll).
|
|
23
|
+
*/
|
|
24
|
+
handleProps: {
|
|
25
|
+
onPointerDown: (e: React.PointerEvent) => void;
|
|
26
|
+
onPointerEnter?: (e: React.PointerEvent) => void;
|
|
27
|
+
onPointerLeave?: (e: React.PointerEvent) => void;
|
|
28
|
+
style: React.CSSProperties;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Props for {@link DragHandle}.
|
|
33
|
+
*/
|
|
34
|
+
export interface DragHandleProps {
|
|
35
|
+
/** The range the handle is anchored to; it sits on the {@link DragHandleProps.anchor} corner. */
|
|
36
|
+
range: RangeCoords;
|
|
37
|
+
/** Which corner/edge of `range` to position on. */
|
|
38
|
+
anchor: HandleAnchor;
|
|
39
|
+
/** Visual size (px) of the handle. @defaultValue 8 */
|
|
40
|
+
size?: number;
|
|
41
|
+
/** Cursor while hovering/dragging. @defaultValue an anchor-appropriate resize cursor. */
|
|
42
|
+
cursor?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Cursor to show **only while a drag is in flight** (the pointer-capture target's cursor holds for
|
|
45
|
+
* the whole drag, even off the handle / off-window). Use it to swap the idle affordance for a neutral
|
|
46
|
+
* "manipulating" cursor — e.g. {@link RangeResizer} flips its directional resize cursors to
|
|
47
|
+
* `grabbing` so a corner drag doesn't keep implying you can still resize that way. Omit to keep
|
|
48
|
+
* {@link DragHandleProps.cursor} for the whole gesture (the fill / table-resize handles, which want
|
|
49
|
+
* their crosshair/resize cursor throughout).
|
|
50
|
+
*/
|
|
51
|
+
dragCursor?: string;
|
|
52
|
+
/** Default-dot background, and the theme color handed to {@link DragHandleProps.renderHandle}. */
|
|
53
|
+
background?: string;
|
|
54
|
+
/** Drag started; `cell` is under the pointer at press. */
|
|
55
|
+
onDragStart?: (cell: CellCoords, e: React.PointerEvent) => void;
|
|
56
|
+
/** The pointer moved to a new cell during the drag (`from` = press cell, `to` = current). */
|
|
57
|
+
onDragMove?: (from: CellCoords, to: CellCoords, e: React.PointerEvent) => void;
|
|
58
|
+
/** Drag ended (`from` = press cell, `to` = last cell). */
|
|
59
|
+
onDragEnd?: (from: CellCoords, to: CellCoords, e: React.PointerEvent) => void;
|
|
60
|
+
/**
|
|
61
|
+
* The drag was **aborted** — the user pressed Escape, or the OS cancelled the pointer (`pointercancel`).
|
|
62
|
+
* Fires INSTEAD of {@link DragHandleProps.onDragEnd} (nothing is committed). Use it to tear down any
|
|
63
|
+
* in-flight preview a flavor set in `onDragStart`/`onDragMove` (e.g. the fill's dashed preview) without
|
|
64
|
+
* applying it. Event-less — an Escape abort has no pointer event.
|
|
65
|
+
*/
|
|
66
|
+
onDragCancel?: () => void;
|
|
67
|
+
/** The pointer entered (`true`) / left (`false`) the handle — for a hover affordance on the host. */
|
|
68
|
+
onHoverChange?: (hovered: boolean) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Style merged onto the default dot **only while hovered** — e.g. {@link RangeResizer} recolors
|
|
71
|
+
* the thumb's border from the window color to the stroke color, so it appears to "grow" on hover
|
|
72
|
+
* (Excel-style). Use the same shorthand property as the base `style` (e.g. `border`) to avoid a
|
|
73
|
+
* React shorthand/longhand warning. Ignored for headless `renderHandle` consumers (they get
|
|
74
|
+
* {@link DragHandleRenderProps.hovered} to wire their own).
|
|
75
|
+
*/
|
|
76
|
+
hoverStyle?: React.CSSProperties;
|
|
77
|
+
/**
|
|
78
|
+
* Glide the handle to its new position (transition `left`/`top`) when `range` changes — pair with
|
|
79
|
+
* {@link RangeRect}'s `animatedTransition` so the corners track a move-drag's gliding outline
|
|
80
|
+
* instead of jumping. @defaultValue false
|
|
81
|
+
*/
|
|
82
|
+
animatedTransition?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Pin the handle centre INSIDE the pane's viewport instead of letting it sit at the range's true
|
|
85
|
+
* anchored corner. When that corner is far off-grid — e.g. a whole-row / whole-column fill selection
|
|
86
|
+
* whose corner is at the last column / row — this keeps the handle visible and reachable. When the
|
|
87
|
+
* range no longer intersects this pane at all, the handle is not rendered.
|
|
88
|
+
*
|
|
89
|
+
* Clamp a **single axis** to track the range along the other: `'y'` pins the vertical position but
|
|
90
|
+
* lets `x` follow the range (a whole-column `tr` handle — pinned to the top, scrolls with the column);
|
|
91
|
+
* `'x'` pins the horizontal but lets `y` follow (a whole-row `bl` handle — pinned to the left, scrolls
|
|
92
|
+
* with the row). `true` clamps both. @defaultValue false
|
|
93
|
+
*/
|
|
94
|
+
clampToView?: boolean | 'x' | 'y';
|
|
95
|
+
/**
|
|
96
|
+
* Render the handle **element** yourself (headless): return your element with `handleProps` spread
|
|
97
|
+
* onto it — that wires placement, pointer-capture, cursor, and events. Replaces the default dot and
|
|
98
|
+
* `children`. Use it for a configured look — e.g. an Excel table-resize tick.
|
|
99
|
+
*/
|
|
100
|
+
renderHandle?: (props: DragHandleRenderProps) => React.ReactNode;
|
|
101
|
+
/** Static content inside the default dot. Ignored when `renderHandle` is set. */
|
|
102
|
+
children?: React.ReactNode;
|
|
103
|
+
className?: string;
|
|
104
|
+
style?: React.CSSProperties;
|
|
105
|
+
/**
|
|
106
|
+
* Keep the currently-focused element focused across the drag (`preventDefault` on pointer-down, which
|
|
107
|
+
* suppresses the compat `mousedown` that would otherwise move focus to the grid's `tabIndex` Stage).
|
|
108
|
+
* Used by the reference-range picker so dragging a handle doesn't blur the formula editor's textarea —
|
|
109
|
+
* it preserves whatever had focus rather than stealing it. @defaultValue false
|
|
110
|
+
*/
|
|
111
|
+
preserveFocus?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A generic, draggable handle anchored to a corner/edge of a grid range. It owns only the **gesture
|
|
115
|
+
* mechanics** — placement, pointer capture, and cell hit-testing with edge auto-scroll — and reports
|
|
116
|
+
* the drag in **cell terms** (`from` → `to`). It holds no range math: flavors (fill, table-resize,
|
|
117
|
+
* touch-extend) own the cell→model conversion and any preview.
|
|
118
|
+
*
|
|
119
|
+
* @remarks
|
|
120
|
+
* The handle centre is placed with the shared {@link ReactUtils.edgeCenter} rule — the same one
|
|
121
|
+
* gridlines and cell borders use — so it lands on the boundary device-crisply and flush with the
|
|
122
|
+
* selection outline. It's a real DOM element (not a Stage responder): it captures the pointer on its
|
|
123
|
+
* own element so move/up survive leaving the handle, and it `stopPropagation`s pointer-down so the
|
|
124
|
+
* selection layer underneath does not also begin a gesture. Provide
|
|
125
|
+
* {@link DragHandleProps.renderHandle} to render the element yourself (spread the supplied
|
|
126
|
+
* `handleProps`).
|
|
127
|
+
*/
|
|
128
|
+
export declare const DragHandle: React.FC<DragHandleProps>;
|
|
129
|
+
//# sourceMappingURL=DragHandle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DragHandle.d.ts","sourceRoot":"","sources":["../../../../src/range/DragHandle.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAQnE,oGAAoG;AACpG,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,MAAM,EAAE,YAAY,CAAC;IACrB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,WAAW,EAAE;QACX,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QAC/C,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACjD,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QACjD,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iGAAiG;IACjG,KAAK,EAAE,WAAW,CAAC;IACnB,mDAAmD;IACnD,MAAM,EAAE,YAAY,CAAC;IACrB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kGAAkG;IAClG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAChE,6FAA6F;IAC7F,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAC/E,0DAA0D;IAC1D,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAC9E;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,qGAAqG;IACrG,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IACjC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;IAClC;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,KAAK,CAAC,SAAS,CAAC;IACjE,iFAAiF;IACjF,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA6GhD,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
/**
|
|
3
|
+
* Props for {@link Draggable}.
|
|
4
|
+
*/
|
|
5
|
+
export interface DraggableProps {
|
|
6
|
+
/**
|
|
7
|
+
* The range the wrapped content occupies (controlled). The drag's "from"; the result range comes out
|
|
8
|
+
* via `onDrag*`.
|
|
9
|
+
*/
|
|
10
|
+
range?: RangeCoords;
|
|
11
|
+
/**
|
|
12
|
+
* The content to make movable — any visual ({@link RangeRect}, `RangeResizer`, …), rendered at
|
|
13
|
+
* `range` and grabbable. `Draggable` draws nothing itself; the visuals are all composed children.
|
|
14
|
+
*/
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Where you can grab to move: the whole rectangle (`entire`, the default) or only its **border ring**
|
|
18
|
+
* (`edges` — interior clicks fall through, for a selection whose interior is for selecting/editing).
|
|
19
|
+
*
|
|
20
|
+
* @defaultValue 'entire'
|
|
21
|
+
*/
|
|
22
|
+
grip?: 'entire' | 'edges';
|
|
23
|
+
/**
|
|
24
|
+
* Grab slack in device px. For `grip: 'edges'` it's the border-ring hit thickness (centered on the
|
|
25
|
+
* border, so half reaches outside the range). For `grip: 'entire'` the whole rectangle is grabbable
|
|
26
|
+
* and this pads the hit area OUTWARD by the same amount, so you can grab just past the edge too.
|
|
27
|
+
*
|
|
28
|
+
* @defaultValue 10
|
|
29
|
+
*/
|
|
30
|
+
hitSize?: number;
|
|
31
|
+
/**
|
|
32
|
+
* The pointer entered (`true`) or left (`false`) the grip's hit area — the border ring for
|
|
33
|
+
* `grip: 'edges'`, the whole (outward-padded) rectangle for `grip: 'entire'`. Use it to render a
|
|
34
|
+
* hover affordance on the composed visual, e.g. Excel thickening the move border on hover. Fires only
|
|
35
|
+
* on a real enter/leave, not on every move.
|
|
36
|
+
*/
|
|
37
|
+
onHoverChange?: (hovered: boolean) => void;
|
|
38
|
+
/**
|
|
39
|
+
* The drag began (`true`) / ended (`false`) — fires on every press/release, even a press with no
|
|
40
|
+
* movement (unlike `onDragEnd`, which only fires on an actual translation). Separate from
|
|
41
|
+
* {@link DraggableProps.onHoverChange} because pointer-capture suppresses the grip's hover events
|
|
42
|
+
* mid-drag; use this to keep a drag affordance (e.g. the thickened move border) lit for the whole drag.
|
|
43
|
+
*/
|
|
44
|
+
onDragStateChange?: (dragging: boolean) => void;
|
|
45
|
+
/** Drag started; `range` is the original. */
|
|
46
|
+
onDragStart?: (range: RangeCoords, e: React.PointerEvent) => void;
|
|
47
|
+
/**
|
|
48
|
+
* The translated range during the drag. Wire it to update `range` (the content follows the pointer —
|
|
49
|
+
* "live"), or to position a composed ghost preview. `Draggable` itself stays silent.
|
|
50
|
+
*/
|
|
51
|
+
onDragMove?: (range: RangeCoords, e: React.PointerEvent) => void;
|
|
52
|
+
/** Drag released: commit the translated range. */
|
|
53
|
+
onDragEnd?: (range: RangeCoords, e: React.PointerEvent) => void;
|
|
54
|
+
/**
|
|
55
|
+
* Render a **ghost** at the in-flight translated range while a drag is in progress (nothing is rendered
|
|
56
|
+
* when idle). `Draggable` owns the preview state internally, so the consumer doesn't have to stash it
|
|
57
|
+
* — return e.g. a faded {@link RangeRect} to trail the pointer while the original stays put (the
|
|
58
|
+
* cut-move pattern). For a "live" feel (content follows the pointer) wire `onDragMove → range` instead.
|
|
59
|
+
*/
|
|
60
|
+
renderMove?: (range: RangeCoords) => React.ReactNode;
|
|
61
|
+
/**
|
|
62
|
+
* Keep the current focus across a move drag (`preventDefault` on pointer-down, suppressing the compat
|
|
63
|
+
* `mousedown` that would move focus to the grid's `tabIndex` Stage). Used by the reference-range picker
|
|
64
|
+
* so dragging a range doesn't blur the formula editor's textarea. @defaultValue false
|
|
65
|
+
*/
|
|
66
|
+
preserveFocus?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A **"make draggable" wrapper**: it makes its `children` movable (translate — same size, new location)
|
|
70
|
+
* and reports the translated range via `onDrag*`. It owns ONLY the gesture (pointer-capture +
|
|
71
|
+
* cell-delta translate + edge auto-scroll); it draws nothing. The consumer composes the visuals and
|
|
72
|
+
* decides what a drag means:
|
|
73
|
+
*
|
|
74
|
+
* - **Live** — `onDragMove` → update `range`; the wrapped child follows the pointer (e.g. a picker, or
|
|
75
|
+
* any draggable `RangeRect`). This is the default feel.
|
|
76
|
+
* - **Ghost** — pass `renderMove`; `Draggable` tracks the in-flight range internally and hands it to
|
|
77
|
+
* your callback to render a second, faded layer, while the original stays put and commits on
|
|
78
|
+
* `onDragEnd` (e.g. a selection's cut-move). No preview state to manage in the consumer.
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* The grip is the whole rectangle ({@link DraggableProps.grip} = `entire`) by default, or just its
|
|
82
|
+
* border ring (`edges`). Drawn first so child handles (resize corners) layered above stay grabbable;
|
|
83
|
+
* `stopPropagation` keeps a layer beneath from also reacting.
|
|
84
|
+
*/
|
|
85
|
+
export declare const Draggable: React.FC<DraggableProps>;
|
|
86
|
+
//# sourceMappingURL=Draggable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Draggable.d.ts","sourceRoot":"","sources":["../../../../src/range/Draggable.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAa/E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,6CAA6C;IAC7C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAClE;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IACjE,kDAAkD;IAClD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAChE;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,CAAC,SAAS,CAAC;IACrD;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAmI9C,CAAC"}
|