@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.
Files changed (172) hide show
  1. package/README.md +502 -2
  2. package/browser/cjs/index.cjs +3 -12
  3. package/browser/esm/index.mjs +5797 -1867
  4. package/licenses/dependencies.txt +143 -41
  5. package/node/esm/index.mjs +4951 -1861
  6. package/package.json +7 -6
  7. package/types/index.d.ts +2 -1497
  8. package/types/src/cell/CellLayer.d.ts +70 -0
  9. package/types/src/cell/CellLayer.d.ts.map +1 -0
  10. package/types/src/cell/CellRenderer.d.ts +42 -0
  11. package/types/src/cell/CellRenderer.d.ts.map +1 -0
  12. package/types/src/cell/DefaultCellRenderer.d.ts +6 -0
  13. package/types/src/cell/DefaultCellRenderer.d.ts.map +1 -0
  14. package/types/src/cell/GridlineLayer.d.ts +38 -0
  15. package/types/src/cell/GridlineLayer.d.ts.map +1 -0
  16. package/types/src/cell/Types.d.ts +12 -0
  17. package/types/src/cell/Types.d.ts.map +1 -0
  18. package/types/src/cell/_CellModel.d.ts +82 -0
  19. package/types/src/cell/_CellModel.d.ts.map +1 -0
  20. package/types/src/cell/index.d.ts +6 -0
  21. package/types/src/cell/index.d.ts.map +1 -0
  22. package/types/src/editor/DefaultEditable.d.ts +121 -0
  23. package/types/src/editor/DefaultEditable.d.ts.map +1 -0
  24. package/types/src/editor/EditSession.d.ts +182 -0
  25. package/types/src/editor/EditSession.d.ts.map +1 -0
  26. package/types/src/editor/EditState.d.ts +61 -0
  27. package/types/src/editor/EditState.d.ts.map +1 -0
  28. package/types/src/editor/EditorDiv.d.ts +65 -0
  29. package/types/src/editor/EditorDiv.d.ts.map +1 -0
  30. package/types/src/editor/EditorInput.d.ts +88 -0
  31. package/types/src/editor/EditorInput.d.ts.map +1 -0
  32. package/types/src/editor/EditorLayer.d.ts +69 -0
  33. package/types/src/editor/EditorLayer.d.ts.map +1 -0
  34. package/types/src/editor/EditorPlacement.d.ts +38 -0
  35. package/types/src/editor/EditorPlacement.d.ts.map +1 -0
  36. package/types/src/editor/index.d.ts +10 -0
  37. package/types/src/editor/index.d.ts.map +1 -0
  38. package/types/src/editor/useEditorKeymap.d.ts +74 -0
  39. package/types/src/editor/useEditorKeymap.d.ts.map +1 -0
  40. package/types/src/grid/Grid.d.ts +16 -0
  41. package/types/src/grid/Grid.d.ts.map +1 -0
  42. package/types/src/grid/IGrid.d.ts +93 -0
  43. package/types/src/grid/IGrid.d.ts.map +1 -0
  44. package/types/src/grid/index.d.ts +3 -0
  45. package/types/src/grid/index.d.ts.map +1 -0
  46. package/types/src/header/HeaderDividerAnchor.d.ts +120 -0
  47. package/types/src/header/HeaderDividerAnchor.d.ts.map +1 -0
  48. package/types/src/header/index.d.ts +3 -0
  49. package/types/src/header/index.d.ts.map +1 -0
  50. package/types/src/header/useHeaderSelectionPointer.d.ts +122 -0
  51. package/types/src/header/useHeaderSelectionPointer.d.ts.map +1 -0
  52. package/types/src/index.d.ts +13 -0
  53. package/types/src/index.d.ts.map +1 -0
  54. package/types/src/layer/HoverTipLayer.d.ts +74 -0
  55. package/types/src/layer/HoverTipLayer.d.ts.map +1 -0
  56. package/types/src/layer/Layer.d.ts +92 -0
  57. package/types/src/layer/Layer.d.ts.map +1 -0
  58. package/types/src/layer/LayerTypes.d.ts +47 -0
  59. package/types/src/layer/LayerTypes.d.ts.map +1 -0
  60. package/types/src/layer/RangePrompt.d.ts +42 -0
  61. package/types/src/layer/RangePrompt.d.ts.map +1 -0
  62. package/types/src/layer/Stage.d.ts +147 -0
  63. package/types/src/layer/Stage.d.ts.map +1 -0
  64. package/types/src/layer/StickyAnchor.d.ts +83 -0
  65. package/types/src/layer/StickyAnchor.d.ts.map +1 -0
  66. package/types/src/layer/StickyFloat.d.ts +65 -0
  67. package/types/src/layer/StickyFloat.d.ts.map +1 -0
  68. package/types/src/layer/VirtualDiv.d.ts +59 -0
  69. package/types/src/layer/VirtualDiv.d.ts.map +1 -0
  70. package/types/src/layer/_Utils.d.ts +37 -0
  71. package/types/src/layer/_Utils.d.ts.map +1 -0
  72. package/types/src/layer/index.d.ts +11 -0
  73. package/types/src/layer/index.d.ts.map +1 -0
  74. package/types/src/layer/useGridAnchor.d.ts +157 -0
  75. package/types/src/layer/useGridAnchor.d.ts.map +1 -0
  76. package/types/src/layer/useHoverIntent.d.ts +49 -0
  77. package/types/src/layer/useHoverIntent.d.ts.map +1 -0
  78. package/types/src/layer/useLayerResponder.d.ts +29 -0
  79. package/types/src/layer/useLayerResponder.d.ts.map +1 -0
  80. package/types/src/layer/usePlacement.d.ts +18 -0
  81. package/types/src/layer/usePlacement.d.ts.map +1 -0
  82. package/types/src/layer/useRangeHover.d.ts +35 -0
  83. package/types/src/layer/useRangeHover.d.ts.map +1 -0
  84. package/types/src/list/CheckboxList.d.ts +63 -0
  85. package/types/src/list/CheckboxList.d.ts.map +1 -0
  86. package/types/src/list/List.d.ts +55 -0
  87. package/types/src/list/List.d.ts.map +1 -0
  88. package/types/src/list/index.d.ts +3 -0
  89. package/types/src/list/index.d.ts.map +1 -0
  90. package/types/src/metrics/Types.d.ts +23 -0
  91. package/types/src/metrics/Types.d.ts.map +1 -0
  92. package/types/src/metrics/index.d.ts +3 -0
  93. package/types/src/metrics/index.d.ts.map +1 -0
  94. package/types/src/metrics/useGridMetrics.d.ts +67 -0
  95. package/types/src/metrics/useGridMetrics.d.ts.map +1 -0
  96. package/types/src/range/DragHandle.d.ts +129 -0
  97. package/types/src/range/DragHandle.d.ts.map +1 -0
  98. package/types/src/range/Draggable.d.ts +86 -0
  99. package/types/src/range/Draggable.d.ts.map +1 -0
  100. package/types/src/range/FillHandle.d.ts +54 -0
  101. package/types/src/range/FillHandle.d.ts.map +1 -0
  102. package/types/src/range/RangeRect.d.ts +36 -0
  103. package/types/src/range/RangeRect.d.ts.map +1 -0
  104. package/types/src/range/RangeResizer.d.ts +68 -0
  105. package/types/src/range/RangeResizer.d.ts.map +1 -0
  106. package/types/src/range/RangeStyle.d.ts +8 -0
  107. package/types/src/range/RangeStyle.d.ts.map +1 -0
  108. package/types/src/range/index.d.ts +13 -0
  109. package/types/src/range/index.d.ts.map +1 -0
  110. package/types/src/selection/DefaultSelection.d.ts +59 -0
  111. package/types/src/selection/DefaultSelection.d.ts.map +1 -0
  112. package/types/src/selection/ICellAnchor.d.ts +21 -0
  113. package/types/src/selection/ICellAnchor.d.ts.map +1 -0
  114. package/types/src/selection/ISelection.d.ts +65 -0
  115. package/types/src/selection/ISelection.d.ts.map +1 -0
  116. package/types/src/selection/RangesPickerLayer.d.ts +128 -0
  117. package/types/src/selection/RangesPickerLayer.d.ts.map +1 -0
  118. package/types/src/selection/SelectionLayer.d.ts +179 -0
  119. package/types/src/selection/SelectionLayer.d.ts.map +1 -0
  120. package/types/src/selection/SelectionStyle.d.ts +28 -0
  121. package/types/src/selection/SelectionStyle.d.ts.map +1 -0
  122. package/types/src/selection/SelectionTouchGrips.d.ts +29 -0
  123. package/types/src/selection/SelectionTouchGrips.d.ts.map +1 -0
  124. package/types/src/selection/SelectionUtils.d.ts +2 -0
  125. package/types/src/selection/SelectionUtils.d.ts.map +1 -0
  126. package/types/src/selection/Types.d.ts +67 -0
  127. package/types/src/selection/Types.d.ts.map +1 -0
  128. package/types/src/selection/_SelectionNavigation.d.ts +6 -0
  129. package/types/src/selection/_SelectionNavigation.d.ts.map +1 -0
  130. package/types/src/selection/_SelectionUtils.d.ts +7 -0
  131. package/types/src/selection/_SelectionUtils.d.ts.map +1 -0
  132. package/types/src/selection/index.d.ts +12 -0
  133. package/types/src/selection/index.d.ts.map +1 -0
  134. package/types/src/selection/useDragCells.d.ts +218 -0
  135. package/types/src/selection/useDragCells.d.ts.map +1 -0
  136. package/types/src/selection/useSelectionPointer.d.ts +70 -0
  137. package/types/src/selection/useSelectionPointer.d.ts.map +1 -0
  138. package/types/src/surface/GridPane.d.ts +85 -0
  139. package/types/src/surface/GridPane.d.ts.map +1 -0
  140. package/types/src/surface/GridPaneProvider.d.ts +37 -0
  141. package/types/src/surface/GridPaneProvider.d.ts.map +1 -0
  142. package/types/src/surface/GridSurface.d.ts +11 -0
  143. package/types/src/surface/GridSurface.d.ts.map +1 -0
  144. package/types/src/surface/IGridPane.d.ts +288 -0
  145. package/types/src/surface/IGridPane.d.ts.map +1 -0
  146. package/types/src/surface/IGridSurface.d.ts +141 -0
  147. package/types/src/surface/IGridSurface.d.ts.map +1 -0
  148. package/types/src/surface/SurfaceStateProvider.d.ts +50 -0
  149. package/types/src/surface/SurfaceStateProvider.d.ts.map +1 -0
  150. package/types/src/surface/_GridUtils.d.ts +37 -0
  151. package/types/src/surface/_GridUtils.d.ts.map +1 -0
  152. package/types/src/surface/index.d.ts +7 -0
  153. package/types/src/surface/index.d.ts.map +1 -0
  154. package/types/src/surface/useGridPane.d.ts +31 -0
  155. package/types/src/surface/useGridPane.d.ts.map +1 -0
  156. package/types/src/surface/useSurfaceState.d.ts +22 -0
  157. package/types/src/surface/useSurfaceState.d.ts.map +1 -0
  158. package/types/src/svg/LineSVG.d.ts +13 -0
  159. package/types/src/svg/LineSVG.d.ts.map +1 -0
  160. package/types/src/svg/RectangleSVG.d.ts +114 -0
  161. package/types/src/svg/RectangleSVG.d.ts.map +1 -0
  162. package/types/src/svg/ShapeBounds.d.ts +15 -0
  163. package/types/src/svg/ShapeBounds.d.ts.map +1 -0
  164. package/types/src/svg/Types.d.ts +37 -0
  165. package/types/src/svg/Types.d.ts.map +1 -0
  166. package/types/src/svg/index.d.ts +9 -0
  167. package/types/src/svg/index.d.ts.map +1 -0
  168. package/types/src/theme/GridTheme.d.ts +56 -0
  169. package/types/src/theme/GridTheme.d.ts.map +1 -0
  170. package/types/src/theme/index.d.ts +2 -0
  171. package/types/src/theme/index.d.ts.map +1 -0
  172. 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,3 @@
1
+ export * from './List';
2
+ export * from './CheckboxList';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,3 @@
1
+ export * from './Types';
2
+ export * from './useGridMetrics';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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"}