@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,147 @@
|
|
|
1
|
+
import { RemoveListener } from '@sheetxl/utils';
|
|
2
|
+
import { IGridPane } from '../surface';
|
|
3
|
+
/**
|
|
4
|
+
* A handler in the dispatch walk. Receives the React synthetic event and the owning pane.
|
|
5
|
+
* Call `event.stopPropagation()` to consume the event — lower layers and the pane/app then do
|
|
6
|
+
* not see it (the one-bubble law's single consume signal).
|
|
7
|
+
*/
|
|
8
|
+
export type StageEventHandler = (event: React.SyntheticEvent, pane: IGridPane) => void;
|
|
9
|
+
/**
|
|
10
|
+
* A {@link Layer} tap's registration with the Stage.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* The Stage is the convergence hub: every Layer registers one tap and the Stage offers each event
|
|
14
|
+
* down the walk in slot order (higher first), then registration (render) order, stopping when one
|
|
15
|
+
* consumes.
|
|
16
|
+
*/
|
|
17
|
+
export interface StageResponder {
|
|
18
|
+
/**
|
|
19
|
+
* The layer's dispatch **slot** — its derived order index in the grid's normalized layer list
|
|
20
|
+
* (see `LayerOrderContext`). Higher is offered the event first; ties break by registration
|
|
21
|
+
* (render) order REVERSED, so the later-declared layer (which paints on top) is offered first.
|
|
22
|
+
*/
|
|
23
|
+
zIndex?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Live accessor for the layer's boundary div. The dispatch resolves an event's **layer
|
|
26
|
+
* membership** by ancestry against these elements (which layer does the target belong to?) — the
|
|
27
|
+
* point of the Layer being a real div. Optional for element-less responders (the pane command
|
|
28
|
+
* terminal, `addReactEventListener` shims), which have no membership to resolve.
|
|
29
|
+
*/
|
|
30
|
+
getElement?: () => Element | null;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the current handler for a native event type (`'pointerdown'`, `'keydown'`,
|
|
33
|
+
* …), or `undefined`. Called per-dispatch, so it always sees the latest closures — a
|
|
34
|
+
* responder is registered once (not per render) and handler identity may change freely.
|
|
35
|
+
*/
|
|
36
|
+
getHandler: (type: string) => StageEventHandler | undefined;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A geometried box's registration with the Stage (a {@link VirtualDiv}). Unlike a
|
|
40
|
+
* {@link StageResponder} (a Layer's zero-geometry tap), a box owns a real DOM element, so the
|
|
41
|
+
* DOM-driven dispatch can map a hit element to its box, resolve the boxes under the pointer, and
|
|
42
|
+
* skip the native target (whose handlers already fired in the "up your subtree" phase).
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Kept in a SEPARATE registry from the tap chain on purpose: there can be very many boxes
|
|
46
|
+
* (e.g. one fill per cell), and the tap chain is sorted on every event — boxes must not
|
|
47
|
+
* inflate that hot path. The dispatch resolves boxes geometrically (the DOM already stacks them),
|
|
48
|
+
* not by iterating this set per event.
|
|
49
|
+
*/
|
|
50
|
+
export interface LayerRegistration {
|
|
51
|
+
/**
|
|
52
|
+
* The box's enclosing Layer's dispatch **slot** (from `LayerOrderContext`). Interleaves the box
|
|
53
|
+
* with the Layer taps in the single walk: a box fires between the taps of the layers above and
|
|
54
|
+
* below its own.
|
|
55
|
+
*/
|
|
56
|
+
zIndex?: number;
|
|
57
|
+
/** Live accessor for the box's DOM element (null while culled / unmounted). */
|
|
58
|
+
getElement: () => Element | null;
|
|
59
|
+
/**
|
|
60
|
+
* Per-type handler accessor (as {@link StageResponder.getHandler}). The DOM-driven dispatch uses
|
|
61
|
+
* it to invoke a box that is BELOW the native target (so it did not receive the event natively;
|
|
62
|
+
* the hit box fires its own handlers natively — the up phase). Boxes with no handlers omit it.
|
|
63
|
+
*/
|
|
64
|
+
getHandler?: (type: string) => StageEventHandler | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Whether this box currently has any event handlers. Drives the dispatch fast-path: when NO
|
|
67
|
+
* registered box has handlers (the entire normal grid — fills / borders / selection visuals),
|
|
68
|
+
* the geometried pass is skipped entirely, so it adds zero per-event cost.
|
|
69
|
+
*/
|
|
70
|
+
hasHandlers?: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The event types a {@link VirtualDiv}'s registered handlers are invoked for on **other layers'
|
|
74
|
+
* turns** (a box below the hit layer, under the pointer). These are the positional, bubbling
|
|
75
|
+
* events. A box's handlers are ordinary native props — they fire natively when the box is on the
|
|
76
|
+
* event's target chain (its own layer's turn, phase 2); this registry map covers the pass-through
|
|
77
|
+
* case (phase 3). Relational (`enter`/`leave`), focus, and key events are targeted — the DOM's own
|
|
78
|
+
* delivery is already correct, so boxes never receive them positionally (Layer taps do, via the
|
|
79
|
+
* ordered walk).
|
|
80
|
+
*/
|
|
81
|
+
export declare const WALKED_EVENT_TYPE_TO_PROP: Record<string, string>;
|
|
82
|
+
/** The walk-dispatched box prop names (values of {@link WALKED_EVENT_TYPE_TO_PROP}). */
|
|
83
|
+
export declare const WALKED_EVENT_PROPS: string[];
|
|
84
|
+
/**
|
|
85
|
+
* The event types the **three-phase dispatch** fully orders (law 3: layers on top hear events
|
|
86
|
+
* first — keys and pointers alike): the positional walked types PLUS keys. For these:
|
|
87
|
+
* - **phase 1** — a native CAPTURE listener on the Stage offers the event to the taps of every
|
|
88
|
+
* layer ABOVE the hit layer (top first), before the native dispatch runs;
|
|
89
|
+
* - **phase 2** — the native dispatch runs the hit layer's own subtree, exactly as React does
|
|
90
|
+
* (inner content, then any boxes on the chain, then the layer's own boundary handlers);
|
|
91
|
+
* - **phase 3** — the Stage's bubble handlers continue the walk strictly BELOW the hit layer
|
|
92
|
+
* (under-pointer boxes + taps, in slot order).
|
|
93
|
+
* `stopPropagation()` anywhere ends the whole bubble. Everything else (enter/leave/focus/blur) is
|
|
94
|
+
* stage-relational: a single unbounded tap walk.
|
|
95
|
+
*/
|
|
96
|
+
export declare const ORDERED_EVENT_TYPES: readonly string[];
|
|
97
|
+
export interface IStageAttributes {
|
|
98
|
+
/**
|
|
99
|
+
* Add a listener for a single event type to the stage. Primarily grid-internal plumbing —
|
|
100
|
+
* external callers use {@link IGridPane.addReactEventListener} (which delegates here); layers
|
|
101
|
+
* use {@link Layer} taps instead.
|
|
102
|
+
*/
|
|
103
|
+
addReactEventListener(type: string, listener: (event: React.SyntheticEvent) => void, listenerPane?: (event: React.SyntheticEvent, pane: IGridPane) => void): RemoveListener;
|
|
104
|
+
isStage(): true;
|
|
105
|
+
}
|
|
106
|
+
export interface IStageElement extends HTMLDivElement, IStageAttributes {
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* @internal
|
|
110
|
+
* The responder registry the Stage implementation also provides. Deliberately kept off the public
|
|
111
|
+
* {@link IStageElement} — Layers join the dispatch walk via their tap, which reaches
|
|
112
|
+
* this through {@link IStageElementInternal}.
|
|
113
|
+
*/
|
|
114
|
+
export interface IStageResponderHost {
|
|
115
|
+
/** Register a (non-visual, broadcast) responder in the responder chain. Returns a remover. */
|
|
116
|
+
registerResponder(responder: StageResponder): RemoveListener;
|
|
117
|
+
/**
|
|
118
|
+
* Register a geometried layer (a {@link Layer}). Returns a remover. Stored
|
|
119
|
+
* apart from the responder chain (see {@link LayerRegistration}); consumed by the DOM-driven
|
|
120
|
+
* dispatch, not by the per-event responder fan-out.
|
|
121
|
+
*/
|
|
122
|
+
registerLayer(layer: LayerRegistration): RemoveListener;
|
|
123
|
+
}
|
|
124
|
+
/** @internal Stage element augmented with the responder registry (used by `Layer` / `useLayerResponder`). */
|
|
125
|
+
export interface IStageElementInternal extends IStageElement, IStageResponderHost {
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* @internal
|
|
129
|
+
* Resolve a pane's Stage element WITH the responder registry (grid-internal; the registry is
|
|
130
|
+
* deliberately off the public pane API — external callers get {@link IGridPane.addReactEventListener}).
|
|
131
|
+
* The pane's surface element IS its Stage, brand-checked via `isStage` so a non-stage host (e.g. a
|
|
132
|
+
* static-border stub pane) resolves to `null` and the caller skips registration.
|
|
133
|
+
*/
|
|
134
|
+
export declare const getStageInternal: (pane: IGridPane | null | undefined) => IStageElementInternal | null;
|
|
135
|
+
export interface StageProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
136
|
+
/**
|
|
137
|
+
* Ref for the HTMLDivElement
|
|
138
|
+
*/
|
|
139
|
+
ref?: React.Ref<IStageElement>;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Stage
|
|
143
|
+
*
|
|
144
|
+
* Internally used to distinguish the main grid area.
|
|
145
|
+
*/
|
|
146
|
+
export declare const Stage: import('react').NamedExoticComponent<Omit<StageProps, "ref"> & import('react').RefAttributes<IStageElement>>;
|
|
147
|
+
//# sourceMappingURL=Stage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Stage.d.ts","sourceRoot":"","sources":["../../../../src/layer/Stage.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAIzD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;AAEvF;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;CAC7D;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,UAAU,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,iBAAiB,GAAG,SAAS,CAAC;IAC7D;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK5D,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,kBAAkB,EAAE,MAAM,EAA6C,CAAC;AAErF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAEhD,CAAC;AAGF,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,EAC/C,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,GACpE,cAAc,CAAC;IAElB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc,EAAE,gBAAgB;CAAG;AAE1E;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,8FAA8F;IAC9F,iBAAiB,CAAC,SAAS,EAAE,cAAc,GAAG,cAAc,CAAC;IAC7D;;;;OAIG;IACH,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,cAAc,CAAC;CACzD;AAED,6GAA6G;AAC7G,MAAM,WAAW,qBAAsB,SAAQ,aAAa,EAAE,mBAAmB;CAAG;AAEpF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,GAAG,IAAI,GAAG,SAAS,KAAG,qBAAqB,GAAG,IAG7F,CAAC;AAEF,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACtE;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;CAChC;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK,8GA4Yf,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { Bounds, Point, AnchorLocation } from '@sheetxl/utils';
|
|
3
|
+
import { IGridPane } from '../surface';
|
|
4
|
+
import { GridAnchor, GridPlacement, GridBoundary, GridWhenOff, GridSlide } from './useGridAnchor';
|
|
5
|
+
/**
|
|
6
|
+
* The state a {@link StickyAnchor} publishes to its child. Carries the resolved `anchorPoint` (+ owner /
|
|
7
|
+
* clip / slide state) so the child alone decides how to render:
|
|
8
|
+
*
|
|
9
|
+
* - a **render-prop** child self-positions — e.g. a portal that escapes the clip and flows past the
|
|
10
|
+
* pane bounds (this is what {@link StickyFloat} does for you);
|
|
11
|
+
* - a plain **node** ("just a div") is positioned INLINE by StickyAnchor, clipping with the pane.
|
|
12
|
+
*
|
|
13
|
+
* `StickyAnchor` itself is portal-agnostic; it only resolves the anchor and positions inline divs.
|
|
14
|
+
*/
|
|
15
|
+
export interface StickyState {
|
|
16
|
+
/** Client-space Floating UI virtual reference (stable identity; reads live). */
|
|
17
|
+
reference: {
|
|
18
|
+
getBoundingClientRect: () => DOMRect;
|
|
19
|
+
};
|
|
20
|
+
/** Client-space boundary rect (for `flip`/`shift`/`hide` limiters). */
|
|
21
|
+
getBoundaryRect: () => DOMRect;
|
|
22
|
+
/** The placement's anchor pixel (client px). */
|
|
23
|
+
anchorPoint: Point;
|
|
24
|
+
/** Pane-relative range bounds (for an in-grid child) — only meaningful on the owner pane, else null. */
|
|
25
|
+
bounds: Bounds | null;
|
|
26
|
+
/** The pane that owns the anchor pixel (null when clipped off every pane). */
|
|
27
|
+
owner: AnchorLocation | null;
|
|
28
|
+
/** Whether THIS instance's pane is the owner — the child self-gates on it (render once / correct pane). */
|
|
29
|
+
isOwner: boolean;
|
|
30
|
+
/** Anchor outside the boundary. */
|
|
31
|
+
clipped: boolean;
|
|
32
|
+
/** The clamp slide (distance/direction) when `whenOff: 'clamp'` pushed it in-frame, else null. */
|
|
33
|
+
slid: GridSlide | null;
|
|
34
|
+
/**
|
|
35
|
+
* The anchored range is **fully scrolled off** (no visible portion) — stays true under `whenOff:
|
|
36
|
+
* 'clamp'` (unlike {@link clipped}), so a presence can distinguish "partially obstructed / clamped"
|
|
37
|
+
* (keep showing) from "off-screen" (show a goto affordance).
|
|
38
|
+
*/
|
|
39
|
+
outOfView: boolean;
|
|
40
|
+
/** The resolved placement. */
|
|
41
|
+
placement: GridPlacement;
|
|
42
|
+
/** This instance's pane (null outside a `GridPaneProvider`). */
|
|
43
|
+
pane: IGridPane | null;
|
|
44
|
+
/**
|
|
45
|
+
* Scroll the anchor's top-left cell into view — the grid-level "reveal" for a render-prop child (e.g.
|
|
46
|
+
* a clamped Presence label whose click should bring its range back on-screen). No-op for anchors
|
|
47
|
+
* without a cell (`bounds` / `edge` / `point`) or outside a pane. This is reveal only; selection lives
|
|
48
|
+
* a layer up (`sheet.getRange(addr).select()`).
|
|
49
|
+
*/
|
|
50
|
+
scrollIntoView: (options?: globalThis.ScrollIntoViewOptions | boolean) => Promise<unknown>;
|
|
51
|
+
}
|
|
52
|
+
/** Read the enclosing {@link StickyAnchor}'s state. Throws outside one. */
|
|
53
|
+
export declare const useSticky: () => StickyState;
|
|
54
|
+
/** Read the enclosing {@link StickyAnchor}'s state, or null outside one. */
|
|
55
|
+
export declare const useStickyOptional: () => StickyState | null;
|
|
56
|
+
/**
|
|
57
|
+
* Props for {@link StickyAnchor}.
|
|
58
|
+
*/
|
|
59
|
+
export interface StickyAnchorProps {
|
|
60
|
+
/** WHERE to anchor — a grid coordinate (range / cell / bounds / edge / point). */
|
|
61
|
+
anchor: GridAnchor;
|
|
62
|
+
/** Which side + align of the anchor the float attaches to (picks the single anchor pixel). */
|
|
63
|
+
placement?: GridPlacement;
|
|
64
|
+
/** Clip / clamp boundary (client-space math input, not a DOM parent). @defaultValue 'data' */
|
|
65
|
+
boundary?: GridBoundary;
|
|
66
|
+
/** What happens when the anchor pixel leaves the data area. @defaultValue 'hide' */
|
|
67
|
+
whenOff?: GridWhenOff;
|
|
68
|
+
/** Px overlap below which a geometried anchor reads as clipped. @defaultValue 0 */
|
|
69
|
+
minVisible?: number;
|
|
70
|
+
/** The child — a node, or a render function `(state) => node`. Reads state via {@link useSticky} too. */
|
|
71
|
+
children?: React.ReactNode | ((state: StickyState) => React.ReactNode);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* A **sticky** grid layer: it resolves an {@link GridAnchor} (via {@link useGridAnchor}) to a live
|
|
75
|
+
* anchor point and positions its child there. A plain `<div>` child is placed **inline** (clips with
|
|
76
|
+
* the pane); a **render-prop** child self-positions (e.g. a portal — see {@link StickyFloat}). It owns
|
|
77
|
+
* no portal and knows nothing about Floating UI.
|
|
78
|
+
*
|
|
79
|
+
* Rendered per pane like any layer; each instance publishes its own `isOwner`, so only the owner pane
|
|
80
|
+
* renders the child (once).
|
|
81
|
+
*/
|
|
82
|
+
export declare const StickyAnchor: React.FC<StickyAnchorProps>;
|
|
83
|
+
//# sourceMappingURL=StickyAnchor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StickyAnchor.d.ts","sourceRoot":"","sources":["../../../../src/layer/StickyAnchor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmF,MAAM,OAAO,CAAC;AAExG,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,KAAK,EAAmB,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE1F,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAEL,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EACzF,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,SAAS,EAAE;QAAE,qBAAqB,EAAE,MAAM,OAAO,CAAA;KAAE,CAAC;IACpD,uEAAuE;IACvE,eAAe,EAAE,MAAM,OAAO,CAAC;IAC/B,gDAAgD;IAChD,WAAW,EAAE,KAAK,CAAC;IACnB,wGAAwG;IACxG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,8EAA8E;IAC9E,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAC7B,2GAA2G;IAC3G,OAAO,EAAE,OAAO,CAAC;IACjB,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,kGAAkG;IAClG,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,8BAA8B;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,gEAAgE;IAChE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IACvB;;;;;OAKG;IACH,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,qBAAqB,GAAG,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F;AAID,2EAA2E;AAC3E,eAAO,MAAM,SAAS,QAAO,WAI5B,CAAC;AAEF,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,QAAO,WAAW,GAAG,IAAiC,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,MAAM,EAAE,UAAU,CAAC;IACnB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,oFAAoF;IACpF,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;CACxE;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAqGpD,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { ThemeAttrs } from '@sheetxl/utils-react';
|
|
3
|
+
import { IGridPane } from '../surface';
|
|
4
|
+
import { StickyState } from './StickyAnchor';
|
|
5
|
+
import { GridAnchor, GridPlacement, GridBoundary, GridWhenOff } from './useGridAnchor';
|
|
6
|
+
/**
|
|
7
|
+
* Carry a grid float's theme **across the portal boundary**. A grid float portals into the shared,
|
|
8
|
+
* theme-free fullscreen root, where the grid's `--sxl-color-*` tokens do NOT cascade in (the CSS cascade
|
|
9
|
+
* doesn't cross a portal — unlike MUI content, which rides React context and so themes for free). Returns
|
|
10
|
+
* the `className` + `data-sxl-theme-*` attrs to put on the portaled element so the token rules resolve —
|
|
11
|
+
* the same mechanism `FloatPopper` uses for menus.
|
|
12
|
+
*
|
|
13
|
+
* Two parts, because the app themes with `@scope` (per-instance), not just global attribute rules:
|
|
14
|
+
* - **attrs** — the pane's live `mode` / `surface` (grid surface, and the grid's own mode even if it
|
|
15
|
+
* differs from the app). These select WHICH token values apply.
|
|
16
|
+
* - **className** — the theme **scope class(es)** (the float surface's, plus the nearest token provider's
|
|
17
|
+
* `scopeClass` when the instance is isolated). Without a scope class the portaled element is outside
|
|
18
|
+
* every `@scope` root, so the `@scope (.cls){ :scope[mode][surface]{…} }` rules never match it and the
|
|
19
|
+
* attrs alone resolve nothing. The class makes the portal a `:scope` root so those rules apply.
|
|
20
|
+
*/
|
|
21
|
+
export declare const useGridFloatTheme: (pane: IGridPane | null | undefined) => {
|
|
22
|
+
className?: string;
|
|
23
|
+
attrs: ThemeAttrs;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Props for {@link StickyFloat}.
|
|
27
|
+
*/
|
|
28
|
+
export interface StickyFloatProps {
|
|
29
|
+
/** WHERE to anchor — a grid coordinate (range / cell / bounds / edge / point). */
|
|
30
|
+
anchor: GridAnchor;
|
|
31
|
+
/** Which side + align the float attaches to. @defaultValue `{ side: 't', align: 'center' }` */
|
|
32
|
+
placement?: GridPlacement;
|
|
33
|
+
/** What happens when the anchor leaves the data area. @defaultValue 'hide' */
|
|
34
|
+
whenOff?: GridWhenOff;
|
|
35
|
+
/** Clip / clamp boundary. @defaultValue 'data' */
|
|
36
|
+
boundary?: GridBoundary;
|
|
37
|
+
/** Px overlap below which a geometried anchor reads as clipped. @defaultValue 0 */
|
|
38
|
+
minVisible?: number;
|
|
39
|
+
/** Gap (px) between the anchor edge and the float. @defaultValue 4 */
|
|
40
|
+
offset?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Offset (px) along the anchor EDGE — only applies to `start` / `end` alignment (a centered float has
|
|
43
|
+
* no edge to slide along). Positive insets the float inward from the corner. @defaultValue 0
|
|
44
|
+
*/
|
|
45
|
+
alignOffset?: number;
|
|
46
|
+
/** Controlled visibility (e.g. a hover tooltip). @defaultValue true */
|
|
47
|
+
open?: boolean;
|
|
48
|
+
/** Portal container. @defaultValue the fullscreen-aware root ({@link useFullscreenPortal}). */
|
|
49
|
+
container?: Element;
|
|
50
|
+
className?: string;
|
|
51
|
+
style?: React.CSSProperties;
|
|
52
|
+
/** @defaultValue 1250 (a below-modal band; see FLOATING-DESIGN §z-index). */
|
|
53
|
+
zIndex?: number;
|
|
54
|
+
/** The float content — a node, or a render function `(state) => node` (e.g. to react to `slid`). */
|
|
55
|
+
children?: React.ReactNode | ((state: StickyState) => React.ReactNode);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The ergonomic **floating label**: a {@link StickyAnchor} that renders its child in a **portal**
|
|
59
|
+
* (escaping the pane clip, so it can flow past the pane bounds — e.g. overhang a freeze line) anchored
|
|
60
|
+
* at the resolved point. The common case — `<StickyFloat anchor={{ range }}>A1:B4</StickyFloat>` —
|
|
61
|
+
* with no hand-written `createPortal`. For an in-grid (clipping) label, use `<StickyAnchor>` with a plain
|
|
62
|
+
* `<div>` child instead.
|
|
63
|
+
*/
|
|
64
|
+
export declare const StickyFloat: React.FC<StickyFloatProps>;
|
|
65
|
+
//# sourceMappingURL=StickyFloat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StickyFloat.d.ts","sourceRoot":"","sources":["../../../../src/layer/StickyFloat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,EAEgC,KAAK,UAAU,EACrD,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EACL,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EACzE,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,SAAS,GAAG,IAAI,GAAG,SAAS,KACjC;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAiBzC,CAAC;AAwDF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,MAAM,EAAE,UAAU,CAAC;IACnB,+FAA+F;IAC/F,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+FAA+F;IAC/F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oGAAoG;IACpG,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;CACxE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAiBlD,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { VirtualDivPlacement } from './LayerTypes';
|
|
2
|
+
export interface VirtualDivProps extends React.HTMLAttributes<HTMLDivElement>, VirtualDivPlacement {
|
|
3
|
+
/**
|
|
4
|
+
* Skip device-pixel edge alignment. By default the box edges are snapped to the
|
|
5
|
+
* device grid (so content stays crisp and adjacent boxes sharing an edge resolve to
|
|
6
|
+
* the same pixel — no seam). Turn off for a raw, unaligned box.
|
|
7
|
+
*
|
|
8
|
+
* @defaultValue false
|
|
9
|
+
*/
|
|
10
|
+
disableAlign?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Extend the right/bottom edges by 1 device px so the box covers all four of its
|
|
13
|
+
* gridline pixels (a gridline paints the boundary PIXEL `[B, B+1]`). Adjacent boxes
|
|
14
|
+
* then overlap by 1px at the shared boundary — intended, like Excel cell fills.
|
|
15
|
+
*
|
|
16
|
+
* @defaultValue false
|
|
17
|
+
*/
|
|
18
|
+
coverGridlines?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Render an aligned **border** of this many DEVICE px instead of a fill. The edges are placed on
|
|
21
|
+
* the boundary centerline (`edgeCenter`, leading straddles / trailing grows outward) — the same
|
|
22
|
+
* rule as gridlines and {@link RectangleSVG} — so the border lines up with the selection rectangle
|
|
23
|
+
* exactly. The box is `border-box`; set the color via `style.borderColor`.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* This is the HTML-`border-box` counterpart of {@link RectangleSVG}'s stroke. Use it for a
|
|
27
|
+
* **content-hosting** box that needs a matching border (the cell editor: the content auto-insets
|
|
28
|
+
* inside the border). For a pure outline/fill overlay, prefer {@link RectangleSVG}/`RangeRect`.
|
|
29
|
+
*/
|
|
30
|
+
alignWidth?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Keep the element mounted (positioned off-screen) instead of culling to `null` when off-screen.
|
|
33
|
+
* For always-mounted content such as the cell editor, whose input must never unmount.
|
|
34
|
+
*
|
|
35
|
+
* @defaultValue false
|
|
36
|
+
*/
|
|
37
|
+
keepMounted?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A **VirtualDiv**: a `<div>` whose bounds are driven by the grid metrics. Place it at a `range`
|
|
41
|
+
* (cell coordinates), `bounds` (grid-space pixels), or `fill` (the whole view); it resolves the
|
|
42
|
+
* placement via the current pane, culls when off-screen, and device-aligns its edges — then hosts
|
|
43
|
+
* any content (CSS background/gradient/pattern for fills, children like images / widgets /
|
|
44
|
+
* movables, or SVG shape leaves like {@link RectangleSVG}).
|
|
45
|
+
*
|
|
46
|
+
* Everything you know about divs applies — pointer events, focus (`tabIndex`), refs, CSS, children —
|
|
47
|
+
* and means what it always means. It is **hittable by default**, exactly like a real div; a
|
|
48
|
+
* decoration opts out with `style.pointerEvents:'none'` (never a hit target; a child shape can
|
|
49
|
+
* re-enable `pointer-events` on its stroke to opt back in). Its handlers are ordinary native props
|
|
50
|
+
* that fire **at its layer's turn** in the ordered bubble (law 3: layers on top hear events first —
|
|
51
|
+
* when the hit is inside this box the native dispatch IS its layer's turn; when the box sits in a
|
|
52
|
+
* lower layer under the pointer, the Stage invokes its positional handlers at that slot). Call
|
|
53
|
+
* `event.stopPropagation()` to consume — there is no auto-consume and no passthrough flag. Render
|
|
54
|
+
* it inside a {@link Layer} (which is what gives it — and everything inside it — its layer
|
|
55
|
+
* membership); with frozen panes each pane instantiates one. For multiple ranges, map it in the
|
|
56
|
+
* consumer (one per range).
|
|
57
|
+
*/
|
|
58
|
+
export declare const VirtualDiv: import('react').NamedExoticComponent<VirtualDivProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
59
|
+
//# sourceMappingURL=VirtualDiv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VirtualDiv.d.ts","sourceRoot":"","sources":["../../../../src/layer/VirtualDiv.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASxD,MAAM,WAAW,eAAgB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,mBAAmB;IAChG;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,UAAU,uGA+HpB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { RangeCoords } from '@sheetxl/utils';
|
|
2
|
+
import { LayerNode } from './LayerTypes';
|
|
3
|
+
/** Content key for a range — stable across object identity (dedupe / memo / hover-target keys). */
|
|
4
|
+
export declare const rangeKey: (r: RangeCoords) => string;
|
|
5
|
+
/**
|
|
6
|
+
* A layer's **derived stacking order** — its index in the normalized layer list, i.e. the react list
|
|
7
|
+
* order with explicit-`zIndex` overrides already folded in (see {@link normalizeLayers}). This is the
|
|
8
|
+
* "effective z" a dev means by *visual order* — **not** the raw `zIndex` prop. The {@link Layer} at
|
|
9
|
+
* each slot registers its event tap at it, and descendant command scopes read it (via `useLayer`) so
|
|
10
|
+
* keystroke / command dispatch follows the visual stack. Derived purely from the React list — **no
|
|
11
|
+
* DOM, no registration timing**.
|
|
12
|
+
*/
|
|
13
|
+
export declare const LayerOrderContext: import('react').Context<number>;
|
|
14
|
+
/**
|
|
15
|
+
* Whether the current subtree is inside a {@link Layer}. Backs the flat-stack law (law 4): a `Layer`
|
|
16
|
+
* dev-errors when it finds itself already inside one, and a {@link VirtualDiv} dev-warns when it is
|
|
17
|
+
* NOT inside one. Purely a dev-time diagnostic — no runtime behavior branches on it.
|
|
18
|
+
*/
|
|
19
|
+
export declare const LayerScopeContext: import('react').Context<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* Normalize the layers (the grid's children) for rendering: sort by `zIndex` and stamp each with its
|
|
22
|
+
* **derived order index** (its position in the sorted list = its effective z). A non-array passes
|
|
23
|
+
* through unchanged.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Ordering matches the CSS model: sort by `zIndex` **ascending** (higher paints later = on top); a layer
|
|
27
|
+
* without a `zIndex` counts as `0`, and `Array.prototype.sort` is stable so same-`zIndex` layers keep
|
|
28
|
+
* **declaration order** — exactly as `z-index: auto` behaves. The `zIndex` is read off the top-level
|
|
29
|
+
* child element (a `<Layer zIndex>` or a composite forwarding one) — this is the ONLY place z is
|
|
30
|
+
* honored; a Layer's dispatch slot always comes from the resulting order index. Each sorted layer is
|
|
31
|
+
* wrapped in a {@link LayerOrderContext} carrying its index, so its `Layer` (and any descendant command
|
|
32
|
+
* scope) reads its effective stacking order — the react-list analog of CSS paint order. That index is
|
|
33
|
+
* stable across remounts / effect re-runs (it is the LIST position, not when a responder registered)
|
|
34
|
+
* and needs **no DOM**. Keyed by the element's own key so a reorder re-slots (not remounts).
|
|
35
|
+
*/
|
|
36
|
+
export declare const normalizeLayers: (layers: LayerNode) => React.ReactNode;
|
|
37
|
+
//# sourceMappingURL=_Utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_Utils.d.ts","sourceRoot":"","sources":["../../../../src/layer/_Utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,mGAAmG;AACnG,eAAO,MAAM,QAAQ,GAAI,GAAG,WAAW,KAAG,MAA+D,CAAC;AAG1G;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,iCAA2B,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,kCAAgC,CAAC;AAE/D;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,SAAS,KAAG,KAAK,CAAC,SAYzD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './LayerTypes';
|
|
2
|
+
export * from './Layer';
|
|
3
|
+
export * from './VirtualDiv';
|
|
4
|
+
export type { GridAnchor, GridPlacement, GridWhenOff, GridBoundary, GridFloatSide, GridAlign, GridSlide } from './useGridAnchor';
|
|
5
|
+
export * from './StickyAnchor';
|
|
6
|
+
export * from './StickyFloat';
|
|
7
|
+
export * from './useHoverIntent';
|
|
8
|
+
export * from './useRangeHover';
|
|
9
|
+
export * from './HoverTipLayer';
|
|
10
|
+
export * from './RangePrompt';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/layer/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAK7B,YAAY,EACV,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAC1F,MAAM,iBAAiB,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { CellCoords, RangeCoords, Bounds, Point, AnchorLocation } from '@sheetxl/utils';
|
|
2
|
+
import { IGridPane } from '../surface';
|
|
3
|
+
/**
|
|
4
|
+
* A viewport edge (used by `edge` anchors and reported by {@link GridAnchorResolved.clampedTo}).
|
|
5
|
+
*/
|
|
6
|
+
export type GridFloatSide = 't' | 'l' | 'r' | 'b';
|
|
7
|
+
/** Alignment along the anchored edge (which end the anchor pixel sits at). */
|
|
8
|
+
export type GridAlign = 'start' | 'center' | 'end';
|
|
9
|
+
/**
|
|
10
|
+
* WHERE the float attaches to the range — the `side` it sits on plus the `align` along that edge.
|
|
11
|
+
* This picks a **single anchor pixel** (a corner / edge-midpoint) which decides pane ownership and
|
|
12
|
+
* clip (that one pixel is in exactly one pane), while positioning still uses the whole range rect.
|
|
13
|
+
* Maps to a Floating UI `Placement` at the `FloatPopper` boundary (`t-start` → `top-start`, …).
|
|
14
|
+
*/
|
|
15
|
+
export interface GridPlacement {
|
|
16
|
+
side: GridFloatSide;
|
|
17
|
+
/** @defaultValue 'center' */
|
|
18
|
+
align?: GridAlign;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* What happens when **no pane owns the anchor pixel** (it scrolled off the data area).
|
|
22
|
+
*
|
|
23
|
+
* - `'hide'` — not rendered (touch handles once their range is gone; ephemeral tooltips). Default.
|
|
24
|
+
* - `'clamp'` — project the pixel onto the nearest data edge and slide it there (sticky / presence);
|
|
25
|
+
* the owner becomes the pane under the clamped pixel and {@link GridAnchorResolved.slid} is set.
|
|
26
|
+
*/
|
|
27
|
+
export type GridWhenOff = 'hide' | 'clamp';
|
|
28
|
+
/**
|
|
29
|
+
* How far the anchor pixel was pushed to stay in frame (the `clamp` fallback). Handed to the sticky
|
|
30
|
+
* child so it can render differently when slid — an arrow toward the true (off-frame) anchor, etc.
|
|
31
|
+
*/
|
|
32
|
+
export interface GridSlide {
|
|
33
|
+
/** Client-px offset applied to the anchor to clamp it into the boundary. */
|
|
34
|
+
dx: number;
|
|
35
|
+
dy: number;
|
|
36
|
+
/** Magnitude of the push (`hypot(dx, dy)`). */
|
|
37
|
+
distance: number;
|
|
38
|
+
/** The edge it slid to — the direction of the true, off-frame anchor. */
|
|
39
|
+
direction: GridFloatSide;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* WHERE a grid float is anchored — a **grid coordinate**, resolved live to a client rect via the
|
|
43
|
+
* pane. The float tracks it across scroll / zoom / resize / freeze.
|
|
44
|
+
*
|
|
45
|
+
* - `range` — a cell range (the primary "virtual range" case).
|
|
46
|
+
* - `cell` — a single cell.
|
|
47
|
+
* - `bounds` — pane **view-relative** bounds (same space `getBoundsFromRange` returns).
|
|
48
|
+
* - `edge` — the midpoint of a viewport edge (touch handles / scrollbars).
|
|
49
|
+
* - `point` — a **client-px** point (drag readouts that follow the pointer).
|
|
50
|
+
*/
|
|
51
|
+
export type GridAnchor = {
|
|
52
|
+
range: RangeCoords;
|
|
53
|
+
} | {
|
|
54
|
+
cell: CellCoords;
|
|
55
|
+
} | {
|
|
56
|
+
bounds: Bounds;
|
|
57
|
+
} | {
|
|
58
|
+
edge: GridFloatSide;
|
|
59
|
+
} | {
|
|
60
|
+
point: Point;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The clip / clamp boundary — a **rect fed to the positioning math**, NOT a DOM parent. This is how
|
|
64
|
+
* "don't slide under the headers" is expressed: clamp to the data viewport.
|
|
65
|
+
*
|
|
66
|
+
* - `'data'` — the union of the panes' cell areas (headers excluded). Default.
|
|
67
|
+
* - `'pane'` — just the resolving pane's cell area.
|
|
68
|
+
* - `'grid'` — currently the same as `'data'` (until a surface/header rect is threaded).
|
|
69
|
+
* - a {@link Bounds} — an explicit **client-px** rect.
|
|
70
|
+
*/
|
|
71
|
+
export type GridBoundary = 'data' | 'pane' | 'grid' | Bounds;
|
|
72
|
+
/** A `DOMRect`-shaped plain object (works in Floating UI and in Node tests without a DOM). */
|
|
73
|
+
export interface GridAnchorRect {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
width: number;
|
|
77
|
+
height: number;
|
|
78
|
+
top: number;
|
|
79
|
+
left: number;
|
|
80
|
+
right: number;
|
|
81
|
+
bottom: number;
|
|
82
|
+
}
|
|
83
|
+
/** The full resolution of a {@link GridAnchor} at a moment in time. */
|
|
84
|
+
export interface GridAnchorResolved {
|
|
85
|
+
/** The anchor's client rect (what Floating UI positions against). */
|
|
86
|
+
rect: GridAnchorRect;
|
|
87
|
+
/** True when the anchor is fully outside {@link boundaryRect}. */
|
|
88
|
+
clipped: boolean;
|
|
89
|
+
/** The clip / clamp boundary in client px. */
|
|
90
|
+
boundaryRect: GridAnchorRect;
|
|
91
|
+
/** When clipped, which side the anchor is off (for `clamp` / presence); else `null`. */
|
|
92
|
+
clampedTo: GridFloatSide | null;
|
|
93
|
+
/**
|
|
94
|
+
* The single anchor pixel (client px) the `placement` picks out — the corner / edge-midpoint that
|
|
95
|
+
* decides ownership + clip. For a straddling range this pixel lives in exactly one pane.
|
|
96
|
+
*/
|
|
97
|
+
anchorPoint: Point;
|
|
98
|
+
/** The pane (by anchor location) that owns the anchor pixel — the single render owner. */
|
|
99
|
+
owner: AnchorLocation | null;
|
|
100
|
+
/** Set (non-null) only under the `clamp` fallback when the anchor slid to stay in frame. */
|
|
101
|
+
slid: GridSlide | null;
|
|
102
|
+
/**
|
|
103
|
+
* The anchor's range has **no visible portion** (fully scrolled off) — independent of `whenOff`. Unlike
|
|
104
|
+
* {@link clipped} (which `clamp` forces false), this stays true under `clamp`, so a presence can tell
|
|
105
|
+
* "partially obstructed / clamped" (still show) from "off-screen" (show a goto affordance).
|
|
106
|
+
*/
|
|
107
|
+
outOfView: boolean;
|
|
108
|
+
}
|
|
109
|
+
/** The hook result: stable live accessors + render-time snapshot values. */
|
|
110
|
+
export interface UseGridAnchorResult {
|
|
111
|
+
/**
|
|
112
|
+
* A Floating UI **virtual reference** with **stable identity** — its `getBoundingClientRect` reads
|
|
113
|
+
* the anchor **live** on every call (Floating UI's `autoUpdate` invokes it between React renders).
|
|
114
|
+
*/
|
|
115
|
+
reference: {
|
|
116
|
+
getBoundingClientRect: () => DOMRect;
|
|
117
|
+
};
|
|
118
|
+
/** Live accessor for the boundary rect (for `shift`/`flip`/`hide` limiters). */
|
|
119
|
+
getBoundaryRect: () => DOMRect;
|
|
120
|
+
/** Render-time snapshot: anchor outside the boundary. Updates each scroll frame (pane re-render). */
|
|
121
|
+
clipped: boolean;
|
|
122
|
+
/** Render-time snapshot: which side the anchor is off, when clipped. */
|
|
123
|
+
clampedTo: GridFloatSide | null;
|
|
124
|
+
/** Render-time snapshot: the placement's anchor pixel (client px). */
|
|
125
|
+
anchorPoint: Point;
|
|
126
|
+
/** Render-time snapshot: the pane (by anchor location) that owns the anchor pixel. */
|
|
127
|
+
owner: AnchorLocation | null;
|
|
128
|
+
/** Render-time snapshot: the slide applied by the `clamp` fallback (else `null`). */
|
|
129
|
+
slid: GridSlide | null;
|
|
130
|
+
/** Render-time snapshot: the range is fully scrolled off (stays true under `clamp`; see resolved). */
|
|
131
|
+
outOfView: boolean;
|
|
132
|
+
/** The pane the anchor resolves against (null outside a `GridPaneProvider`). */
|
|
133
|
+
pane: IGridPane | null;
|
|
134
|
+
}
|
|
135
|
+
/** @internal The shared placement default (`StickyAnchor` and the resolver must agree on it). */
|
|
136
|
+
export declare const DEFAULT_PLACEMENT: GridPlacement;
|
|
137
|
+
/**
|
|
138
|
+
* Resolve a {@link GridAnchor} to a client rect + clip state against a boundary. **Pure** (given a
|
|
139
|
+
* pane) — no React, no live DOM beyond `getBoundingClientRect`, so it is directly unit-testable with a
|
|
140
|
+
* fake {@link IGridPane}. Shared by {@link useGridAnchor} (the live closures call this per frame).
|
|
141
|
+
*/
|
|
142
|
+
export declare const resolveGridAnchor: (pane: IGridPane | null, anchor: GridAnchor, boundary?: GridBoundary, minVisible?: number, placement?: GridPlacement, whenOff?: GridWhenOff) => GridAnchorResolved;
|
|
143
|
+
/**
|
|
144
|
+
* Bridge a {@link GridAnchor} (grid coordinate) to a **live Floating UI virtual reference** plus clip
|
|
145
|
+
* state. The pane already re-renders every layer on scroll (so the snapshot values update per frame),
|
|
146
|
+
* and the returned {@link UseGridAnchorResult.reference} reads live on each `getBoundingClientRect`
|
|
147
|
+
* call so `autoUpdate` keeps the float glued between renders. No hidden measure element, no
|
|
148
|
+
* scroll-parent walk. Read the pane from context, or pass one explicitly.
|
|
149
|
+
*/
|
|
150
|
+
export declare const useGridAnchor: (anchor: GridAnchor, options?: {
|
|
151
|
+
pane?: IGridPane;
|
|
152
|
+
boundary?: GridBoundary;
|
|
153
|
+
minVisible?: number;
|
|
154
|
+
placement?: GridPlacement;
|
|
155
|
+
whenOff?: GridWhenOff;
|
|
156
|
+
}) => UseGridAnchorResult;
|
|
157
|
+
//# sourceMappingURL=useGridAnchor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridAnchor.d.ts","sourceRoot":"","sources":["../../../../src/layer/useGridAnchor.ts"],"names":[],"mappings":"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"}
|