react-native-layout-dnd 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +262 -0
- package/lib/module/adapters/coordinates.js +135 -0
- package/lib/module/adapters/coordinates.js.map +1 -0
- package/lib/module/adapters/scroll.js +81 -0
- package/lib/module/adapters/scroll.js.map +1 -0
- package/lib/module/adapters/virtualizedList.js +69 -0
- package/lib/module/adapters/virtualizedList.js.map +1 -0
- package/lib/module/components/DndProvider.js +1144 -0
- package/lib/module/components/DndProvider.js.map +1 -0
- package/lib/module/components/DragHandle.js +65 -0
- package/lib/module/components/DragHandle.js.map +1 -0
- package/lib/module/components/GridController.js +151 -0
- package/lib/module/components/GridController.js.map +1 -0
- package/lib/module/components/GridDragHandle.js +15 -0
- package/lib/module/components/GridDragHandle.js.map +1 -0
- package/lib/module/components/GridZoneView.js +59 -0
- package/lib/module/components/GridZoneView.js.map +1 -0
- package/lib/module/components/SortableGrid.js +305 -0
- package/lib/module/components/SortableGrid.js.map +1 -0
- package/lib/module/components/SortableList.js +714 -0
- package/lib/module/components/SortableList.js.map +1 -0
- package/lib/module/components/dndTypes.js +4 -0
- package/lib/module/components/dndTypes.js.map +1 -0
- package/lib/module/components/gridTypes.js +4 -0
- package/lib/module/components/gridTypes.js.map +1 -0
- package/lib/module/components/handleViewProps.js +13 -0
- package/lib/module/components/handleViewProps.js.map +1 -0
- package/lib/module/contracts.js +4 -0
- package/lib/module/contracts.js.map +1 -0
- package/lib/module/controller/approval.js +98 -0
- package/lib/module/controller/approval.js.map +1 -0
- package/lib/module/controller/coordinatorBase.js +93 -0
- package/lib/module/controller/coordinatorBase.js.map +1 -0
- package/lib/module/controller/dndSession.js +621 -0
- package/lib/module/controller/dndSession.js.map +1 -0
- package/lib/module/controller/dndState.js +103 -0
- package/lib/module/controller/dndState.js.map +1 -0
- package/lib/module/controller/gridAdapter.js +191 -0
- package/lib/module/controller/gridAdapter.js.map +1 -0
- package/lib/module/controller/gridState.js +101 -0
- package/lib/module/controller/gridState.js.map +1 -0
- package/lib/module/controller/locations.js +48 -0
- package/lib/module/controller/locations.js.map +1 -0
- package/lib/module/controller/previewPath.js +73 -0
- package/lib/module/controller/previewPath.js.map +1 -0
- package/lib/module/controller/sessionCore.js +222 -0
- package/lib/module/controller/sessionCore.js.map +1 -0
- package/lib/module/controller/useDndState.js +9 -0
- package/lib/module/controller/useDndState.js.map +1 -0
- package/lib/module/controller/useGridState.js +9 -0
- package/lib/module/controller/useGridState.js.map +1 -0
- package/lib/module/controller/useStoreState.js +15 -0
- package/lib/module/controller/useStoreState.js.map +1 -0
- package/lib/module/defaults.js +7 -0
- package/lib/module/defaults.js.map +1 -0
- package/lib/module/diagnostics.js +16 -0
- package/lib/module/diagnostics.js.map +1 -0
- package/lib/module/engine/gridPlacements.js +54 -0
- package/lib/module/engine/gridPlacements.js.map +1 -0
- package/lib/module/engine/index.js +19 -0
- package/lib/module/engine/index.js.map +1 -0
- package/lib/module/engine/layout.js +36 -0
- package/lib/module/engine/layout.js.map +1 -0
- package/lib/module/engine/layoutMove.js +326 -0
- package/lib/module/engine/layoutMove.js.map +1 -0
- package/lib/module/engine/layoutState.js +344 -0
- package/lib/module/engine/layoutState.js.map +1 -0
- package/lib/module/engine/list.js +172 -0
- package/lib/module/engine/list.js.map +1 -0
- package/lib/module/engine/listIndex.js +125 -0
- package/lib/module/engine/listIndex.js.map +1 -0
- package/lib/module/engine/move.js +216 -0
- package/lib/module/engine/move.js.map +1 -0
- package/lib/module/engine/movementPolicy.js +77 -0
- package/lib/module/engine/movementPolicy.js.map +1 -0
- package/lib/module/engine/orderedTarget.js +71 -0
- package/lib/module/engine/orderedTarget.js.map +1 -0
- package/lib/module/engine/pack.js +30 -0
- package/lib/module/engine/pack.js.map +1 -0
- package/lib/module/engine/rectangles.js +12 -0
- package/lib/module/engine/rectangles.js.map +1 -0
- package/lib/module/engine/sameLayout.js +29 -0
- package/lib/module/engine/sameLayout.js.map +1 -0
- package/lib/module/engine/search.js +159 -0
- package/lib/module/engine/search.js.map +1 -0
- package/lib/module/engine/spatial.js +27 -0
- package/lib/module/engine/spatial.js.map +1 -0
- package/lib/module/engine/spatialAppRotation.js +39 -0
- package/lib/module/engine/spatialAppRotation.js.map +1 -0
- package/lib/module/engine/spatialExchange.js +164 -0
- package/lib/module/engine/spatialExchange.js.map +1 -0
- package/lib/module/engine/spatialInsertion.js +135 -0
- package/lib/module/engine/spatialInsertion.js.map +1 -0
- package/lib/module/engine/spatialPolicy.js +41 -0
- package/lib/module/engine/spatialPolicy.js.map +1 -0
- package/lib/module/engine/spatialRotation.js +48 -0
- package/lib/module/engine/spatialRotation.js.map +1 -0
- package/lib/module/engine/validation.js +205 -0
- package/lib/module/engine/validation.js.map +1 -0
- package/lib/module/gesture/DndGestureGroup.js +268 -0
- package/lib/module/gesture/DndGestureGroup.js.map +1 -0
- package/lib/module/gesture/DndGestureHost.js +32 -0
- package/lib/module/gesture/DndGestureHost.js.map +1 -0
- package/lib/module/gesture/gestureConfig.js +81 -0
- package/lib/module/gesture/gestureConfig.js.map +1 -0
- package/lib/module/gesture/gestureGrouping.js +122 -0
- package/lib/module/gesture/gestureGrouping.js.map +1 -0
- package/lib/module/gesture/gestureHost.js +106 -0
- package/lib/module/gesture/gestureHost.js.map +1 -0
- package/lib/module/index.js +23 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/pointer/dndTarget.js +101 -0
- package/lib/module/pointer/dndTarget.js.map +1 -0
- package/lib/module/pointer/geometry.js +363 -0
- package/lib/module/pointer/geometry.js.map +1 -0
- package/lib/module/pointer/layoutTarget.js +307 -0
- package/lib/module/pointer/layoutTarget.js.map +1 -0
- package/lib/module/pointer/listCellMotion.js +99 -0
- package/lib/module/pointer/listCellMotion.js.map +1 -0
- package/lib/module/pointer/listTarget.js +42 -0
- package/lib/module/pointer/listTarget.js.map +1 -0
- package/lib/module/pointer/motion.js +37 -0
- package/lib/module/pointer/motion.js.map +1 -0
- package/lib/module/runtime/dndPresentation.js +81 -0
- package/lib/module/runtime/dndPresentation.js.map +1 -0
- package/lib/module/runtime/dndRenderStore.js +129 -0
- package/lib/module/runtime/dndRenderStore.js.map +1 -0
- package/lib/module/runtime/dndRuntime.js +135 -0
- package/lib/module/runtime/dndRuntime.js.map +1 -0
- package/lib/module/runtime/dndSettlement.js +77 -0
- package/lib/module/runtime/dndSettlement.js.map +1 -0
- package/lib/module/runtime/gridRuntime.js +37 -0
- package/lib/module/runtime/gridRuntime.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/adapters/coordinates.d.ts +9 -0
- package/lib/typescript/src/adapters/coordinates.d.ts.map +1 -0
- package/lib/typescript/src/adapters/scroll.d.ts +49 -0
- package/lib/typescript/src/adapters/scroll.d.ts.map +1 -0
- package/lib/typescript/src/adapters/virtualizedList.d.ts +22 -0
- package/lib/typescript/src/adapters/virtualizedList.d.ts.map +1 -0
- package/lib/typescript/src/components/DndProvider.d.ts +4 -0
- package/lib/typescript/src/components/DndProvider.d.ts.map +1 -0
- package/lib/typescript/src/components/DragHandle.d.ts +4 -0
- package/lib/typescript/src/components/DragHandle.d.ts.map +1 -0
- package/lib/typescript/src/components/GridController.d.ts +21 -0
- package/lib/typescript/src/components/GridController.d.ts.map +1 -0
- package/lib/typescript/src/components/GridDragHandle.d.ts +8 -0
- package/lib/typescript/src/components/GridDragHandle.d.ts.map +1 -0
- package/lib/typescript/src/components/GridZoneView.d.ts +8 -0
- package/lib/typescript/src/components/GridZoneView.d.ts.map +1 -0
- package/lib/typescript/src/components/SortableGrid.d.ts +4 -0
- package/lib/typescript/src/components/SortableGrid.d.ts.map +1 -0
- package/lib/typescript/src/components/SortableList.d.ts +4 -0
- package/lib/typescript/src/components/SortableList.d.ts.map +1 -0
- package/lib/typescript/src/components/dndTypes.d.ts +94 -0
- package/lib/typescript/src/components/dndTypes.d.ts.map +1 -0
- package/lib/typescript/src/components/gridTypes.d.ts +84 -0
- package/lib/typescript/src/components/gridTypes.d.ts.map +1 -0
- package/lib/typescript/src/components/handleViewProps.d.ts +6 -0
- package/lib/typescript/src/components/handleViewProps.d.ts.map +1 -0
- package/lib/typescript/src/contracts.d.ts +145 -0
- package/lib/typescript/src/contracts.d.ts.map +1 -0
- package/lib/typescript/src/controller/approval.d.ts +66 -0
- package/lib/typescript/src/controller/approval.d.ts.map +1 -0
- package/lib/typescript/src/controller/coordinatorBase.d.ts +37 -0
- package/lib/typescript/src/controller/coordinatorBase.d.ts.map +1 -0
- package/lib/typescript/src/controller/dndSession.d.ts +152 -0
- package/lib/typescript/src/controller/dndSession.d.ts.map +1 -0
- package/lib/typescript/src/controller/dndState.d.ts +27 -0
- package/lib/typescript/src/controller/dndState.d.ts.map +1 -0
- package/lib/typescript/src/controller/gridAdapter.d.ts +44 -0
- package/lib/typescript/src/controller/gridAdapter.d.ts.map +1 -0
- package/lib/typescript/src/controller/gridState.d.ts +18 -0
- package/lib/typescript/src/controller/gridState.d.ts.map +1 -0
- package/lib/typescript/src/controller/locations.d.ts +9 -0
- package/lib/typescript/src/controller/locations.d.ts.map +1 -0
- package/lib/typescript/src/controller/previewPath.d.ts +49 -0
- package/lib/typescript/src/controller/previewPath.d.ts.map +1 -0
- package/lib/typescript/src/controller/sessionCore.d.ts +106 -0
- package/lib/typescript/src/controller/sessionCore.d.ts.map +1 -0
- package/lib/typescript/src/controller/useDndState.d.ts +8 -0
- package/lib/typescript/src/controller/useDndState.d.ts.map +1 -0
- package/lib/typescript/src/controller/useGridState.d.ts +8 -0
- package/lib/typescript/src/controller/useGridState.d.ts.map +1 -0
- package/lib/typescript/src/controller/useStoreState.d.ts +16 -0
- package/lib/typescript/src/controller/useStoreState.d.ts.map +1 -0
- package/lib/typescript/src/defaults.d.ts +5 -0
- package/lib/typescript/src/defaults.d.ts.map +1 -0
- package/lib/typescript/src/diagnostics.d.ts +9 -0
- package/lib/typescript/src/diagnostics.d.ts.map +1 -0
- package/lib/typescript/src/engine/gridPlacements.d.ts +22 -0
- package/lib/typescript/src/engine/gridPlacements.d.ts.map +1 -0
- package/lib/typescript/src/engine/index.d.ts +28 -0
- package/lib/typescript/src/engine/index.d.ts.map +1 -0
- package/lib/typescript/src/engine/layout.d.ts +4 -0
- package/lib/typescript/src/engine/layout.d.ts.map +1 -0
- package/lib/typescript/src/engine/layoutMove.d.ts +46 -0
- package/lib/typescript/src/engine/layoutMove.d.ts.map +1 -0
- package/lib/typescript/src/engine/layoutState.d.ts +22 -0
- package/lib/typescript/src/engine/layoutState.d.ts.map +1 -0
- package/lib/typescript/src/engine/list.d.ts +68 -0
- package/lib/typescript/src/engine/list.d.ts.map +1 -0
- package/lib/typescript/src/engine/listIndex.d.ts +32 -0
- package/lib/typescript/src/engine/listIndex.d.ts.map +1 -0
- package/lib/typescript/src/engine/move.d.ts +10 -0
- package/lib/typescript/src/engine/move.d.ts.map +1 -0
- package/lib/typescript/src/engine/movementPolicy.d.ts +34 -0
- package/lib/typescript/src/engine/movementPolicy.d.ts.map +1 -0
- package/lib/typescript/src/engine/orderedTarget.d.ts +32 -0
- package/lib/typescript/src/engine/orderedTarget.d.ts.map +1 -0
- package/lib/typescript/src/engine/pack.d.ts +3 -0
- package/lib/typescript/src/engine/pack.d.ts.map +1 -0
- package/lib/typescript/src/engine/rectangles.d.ts +9 -0
- package/lib/typescript/src/engine/rectangles.d.ts.map +1 -0
- package/lib/typescript/src/engine/sameLayout.d.ts +4 -0
- package/lib/typescript/src/engine/sameLayout.d.ts.map +1 -0
- package/lib/typescript/src/engine/search.d.ts +28 -0
- package/lib/typescript/src/engine/search.d.ts.map +1 -0
- package/lib/typescript/src/engine/spatial.d.ts +16 -0
- package/lib/typescript/src/engine/spatial.d.ts.map +1 -0
- package/lib/typescript/src/engine/spatialAppRotation.d.ts +4 -0
- package/lib/typescript/src/engine/spatialAppRotation.d.ts.map +1 -0
- package/lib/typescript/src/engine/spatialExchange.d.ts +5 -0
- package/lib/typescript/src/engine/spatialExchange.d.ts.map +1 -0
- package/lib/typescript/src/engine/spatialInsertion.d.ts +5 -0
- package/lib/typescript/src/engine/spatialInsertion.d.ts.map +1 -0
- package/lib/typescript/src/engine/spatialPolicy.d.ts +9 -0
- package/lib/typescript/src/engine/spatialPolicy.d.ts.map +1 -0
- package/lib/typescript/src/engine/spatialRotation.d.ts +8 -0
- package/lib/typescript/src/engine/spatialRotation.d.ts.map +1 -0
- package/lib/typescript/src/engine/validation.d.ts +9 -0
- package/lib/typescript/src/engine/validation.d.ts.map +1 -0
- package/lib/typescript/src/gesture/DndGestureGroup.d.ts +33 -0
- package/lib/typescript/src/gesture/DndGestureGroup.d.ts.map +1 -0
- package/lib/typescript/src/gesture/DndGestureHost.d.ts +12 -0
- package/lib/typescript/src/gesture/DndGestureHost.d.ts.map +1 -0
- package/lib/typescript/src/gesture/gestureConfig.d.ts +15 -0
- package/lib/typescript/src/gesture/gestureConfig.d.ts.map +1 -0
- package/lib/typescript/src/gesture/gestureGrouping.d.ts +66 -0
- package/lib/typescript/src/gesture/gestureGrouping.d.ts.map +1 -0
- package/lib/typescript/src/gesture/gestureHost.d.ts +23 -0
- package/lib/typescript/src/gesture/gestureHost.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +38 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/pointer/dndTarget.d.ts +14 -0
- package/lib/typescript/src/pointer/dndTarget.d.ts.map +1 -0
- package/lib/typescript/src/pointer/geometry.d.ts +28 -0
- package/lib/typescript/src/pointer/geometry.d.ts.map +1 -0
- package/lib/typescript/src/pointer/layoutTarget.d.ts +43 -0
- package/lib/typescript/src/pointer/layoutTarget.d.ts.map +1 -0
- package/lib/typescript/src/pointer/listCellMotion.d.ts +43 -0
- package/lib/typescript/src/pointer/listCellMotion.d.ts.map +1 -0
- package/lib/typescript/src/pointer/listTarget.d.ts +7 -0
- package/lib/typescript/src/pointer/listTarget.d.ts.map +1 -0
- package/lib/typescript/src/pointer/motion.d.ts +20 -0
- package/lib/typescript/src/pointer/motion.d.ts.map +1 -0
- package/lib/typescript/src/runtime/dndPresentation.d.ts +37 -0
- package/lib/typescript/src/runtime/dndPresentation.d.ts.map +1 -0
- package/lib/typescript/src/runtime/dndRenderStore.d.ts +46 -0
- package/lib/typescript/src/runtime/dndRenderStore.d.ts.map +1 -0
- package/lib/typescript/src/runtime/dndRuntime.d.ts +138 -0
- package/lib/typescript/src/runtime/dndRuntime.d.ts.map +1 -0
- package/lib/typescript/src/runtime/dndSettlement.d.ts +18 -0
- package/lib/typescript/src/runtime/dndSettlement.d.ts.map +1 -0
- package/lib/typescript/src/runtime/gridRuntime.d.ts +54 -0
- package/lib/typescript/src/runtime/gridRuntime.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +180 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +136 -0
- package/src/adapters/coordinates.ts +181 -0
- package/src/adapters/scroll.ts +147 -0
- package/src/adapters/virtualizedList.ts +112 -0
- package/src/components/DndProvider.tsx +1836 -0
- package/src/components/DragHandle.tsx +89 -0
- package/src/components/GridController.tsx +213 -0
- package/src/components/GridDragHandle.tsx +11 -0
- package/src/components/GridZoneView.tsx +57 -0
- package/src/components/SortableGrid.tsx +449 -0
- package/src/components/SortableList.tsx +1028 -0
- package/src/components/dndTypes.ts +102 -0
- package/src/components/gridTypes.ts +90 -0
- package/src/components/handleViewProps.ts +35 -0
- package/src/contracts.ts +149 -0
- package/src/controller/approval.ts +179 -0
- package/src/controller/coordinatorBase.ts +118 -0
- package/src/controller/dndSession.ts +1058 -0
- package/src/controller/dndState.ts +198 -0
- package/src/controller/gridAdapter.ts +268 -0
- package/src/controller/gridState.ts +187 -0
- package/src/controller/locations.ts +67 -0
- package/src/controller/previewPath.ts +90 -0
- package/src/controller/sessionCore.ts +390 -0
- package/src/controller/useDndState.ts +26 -0
- package/src/controller/useGridState.ts +22 -0
- package/src/controller/useStoreState.ts +27 -0
- package/src/defaults.ts +4 -0
- package/src/diagnostics.ts +23 -0
- package/src/engine/gridPlacements.ts +85 -0
- package/src/engine/index.ts +99 -0
- package/src/engine/layout.ts +29 -0
- package/src/engine/layoutMove.ts +401 -0
- package/src/engine/layoutState.ts +490 -0
- package/src/engine/list.ts +307 -0
- package/src/engine/listIndex.ts +174 -0
- package/src/engine/move.ts +274 -0
- package/src/engine/movementPolicy.ts +151 -0
- package/src/engine/orderedTarget.ts +131 -0
- package/src/engine/pack.ts +24 -0
- package/src/engine/rectangles.ts +18 -0
- package/src/engine/sameLayout.ts +50 -0
- package/src/engine/search.ts +174 -0
- package/src/engine/spatial.ts +36 -0
- package/src/engine/spatialAppRotation.ts +53 -0
- package/src/engine/spatialExchange.ts +212 -0
- package/src/engine/spatialInsertion.ts +157 -0
- package/src/engine/spatialPolicy.ts +48 -0
- package/src/engine/spatialRotation.ts +56 -0
- package/src/engine/validation.ts +358 -0
- package/src/gesture/DndGestureGroup.tsx +357 -0
- package/src/gesture/DndGestureHost.tsx +50 -0
- package/src/gesture/gestureConfig.ts +123 -0
- package/src/gesture/gestureGrouping.ts +210 -0
- package/src/gesture/gestureHost.tsx +163 -0
- package/src/index.ts +162 -0
- package/src/pointer/dndTarget.ts +213 -0
- package/src/pointer/geometry.ts +584 -0
- package/src/pointer/layoutTarget.ts +515 -0
- package/src/pointer/listCellMotion.ts +174 -0
- package/src/pointer/listTarget.ts +56 -0
- package/src/pointer/motion.ts +66 -0
- package/src/runtime/dndPresentation.ts +113 -0
- package/src/runtime/dndRenderStore.ts +246 -0
- package/src/runtime/dndRuntime.ts +311 -0
- package/src/runtime/dndSettlement.ts +117 -0
- package/src/runtime/gridRuntime.ts +73 -0
- package/src/types.ts +189 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import type { PanGesture } from 'react-native-gesture-handler';
|
|
2
|
+
|
|
3
|
+
import { sameGestureRelations } from './gestureConfig';
|
|
4
|
+
|
|
5
|
+
import type { GestureRelations } from '../components/gridTypes';
|
|
6
|
+
|
|
7
|
+
/** One registered handle as the gesture host sees it. */
|
|
8
|
+
export type GestureOwner<Registration> = {
|
|
9
|
+
id: number;
|
|
10
|
+
registration: Registration;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type GestureRegistry<Registration> = {
|
|
14
|
+
getSnapshot(): readonly GestureOwner<Registration>[];
|
|
15
|
+
subscribe(listener: () => void): () => void;
|
|
16
|
+
setOwners(next: readonly GestureOwner<Registration>[]): void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/** Handle mounts update their native owners without rendering the controller. */
|
|
20
|
+
export function createGestureRegistry<
|
|
21
|
+
Registration,
|
|
22
|
+
>(): GestureRegistry<Registration> {
|
|
23
|
+
let owners: readonly GestureOwner<Registration>[] = [];
|
|
24
|
+
const listeners = new Set<() => void>();
|
|
25
|
+
return {
|
|
26
|
+
getSnapshot: () => owners,
|
|
27
|
+
subscribe(listener) {
|
|
28
|
+
listeners.add(listener);
|
|
29
|
+
return () => {
|
|
30
|
+
listeners.delete(listener);
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
setOwners(next) {
|
|
34
|
+
if (
|
|
35
|
+
next.length === owners.length &&
|
|
36
|
+
next.every(
|
|
37
|
+
(owner, index) =>
|
|
38
|
+
owner.id === owners[index]!.id &&
|
|
39
|
+
owner.registration === owners[index]!.registration,
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
return;
|
|
43
|
+
owners = next.map(({ id, registration }) => ({ id, registration }));
|
|
44
|
+
for (const listener of Array.from(listeners)) listener();
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Delivers a group's hit targets without re-rendering the group. A re-render
|
|
51
|
+
* would make Reanimated and Gesture Handler rebuild and re-register the native
|
|
52
|
+
* event handler, which costs a serialization of every callback closure.
|
|
53
|
+
*/
|
|
54
|
+
export type TargetChannel<Target> = {
|
|
55
|
+
readonly targets: readonly Target[];
|
|
56
|
+
subscribe(listener: (targets: readonly Target[]) => void): () => void;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type PublishedTargetChannel<Target> = TargetChannel<Target> & {
|
|
60
|
+
set(targets: readonly Target[]): void;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function createTargetChannel<Target>(
|
|
64
|
+
initial: readonly Target[],
|
|
65
|
+
): PublishedTargetChannel<Target> {
|
|
66
|
+
let targets = initial;
|
|
67
|
+
const listeners = new Set<(targets: readonly Target[]) => void>();
|
|
68
|
+
return {
|
|
69
|
+
get targets() {
|
|
70
|
+
return targets;
|
|
71
|
+
},
|
|
72
|
+
set(next) {
|
|
73
|
+
if (next === targets) return;
|
|
74
|
+
targets = next;
|
|
75
|
+
for (const listener of Array.from(listeners)) listener(next);
|
|
76
|
+
},
|
|
77
|
+
subscribe(listener) {
|
|
78
|
+
listeners.add(listener);
|
|
79
|
+
return () => {
|
|
80
|
+
listeners.delete(listener);
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Props of one shared-recognizer component rendered by a gesture host. */
|
|
87
|
+
export type GestureGroupProps<Runtime, Target> = {
|
|
88
|
+
groupId: number;
|
|
89
|
+
relations: GestureRelations | undefined;
|
|
90
|
+
channel: TargetChannel<Target>;
|
|
91
|
+
runtime: Runtime;
|
|
92
|
+
publish(groupId: number, gesture: PanGesture | null): void;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/** Handles sharing one relation signature share one native recognizer. */
|
|
96
|
+
export type GestureGroupSnapshot<Target> = {
|
|
97
|
+
groupId: number;
|
|
98
|
+
relations: GestureRelations | undefined;
|
|
99
|
+
targets: readonly Target[];
|
|
100
|
+
/** Stable per group; the group element never re-renders for target changes. */
|
|
101
|
+
channel: PublishedTargetChannel<Target>;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export type GroupingState<Registration, Target> = {
|
|
105
|
+
targets: Map<number, { registration: Registration; target: Target }>;
|
|
106
|
+
signatures: Array<{
|
|
107
|
+
relations: GestureRelations | undefined;
|
|
108
|
+
groupId: number;
|
|
109
|
+
}>;
|
|
110
|
+
nextGroupId: number;
|
|
111
|
+
groups: readonly GestureGroupSnapshot<Target>[];
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export function createGroupingState<Registration, Target>(): GroupingState<
|
|
115
|
+
Registration,
|
|
116
|
+
Target
|
|
117
|
+
> {
|
|
118
|
+
return { targets: new Map(), signatures: [], nextGroupId: 0, groups: [] };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function sameTargets<Target>(
|
|
122
|
+
previous: readonly Target[],
|
|
123
|
+
next: readonly Target[],
|
|
124
|
+
): boolean {
|
|
125
|
+
return (
|
|
126
|
+
previous.length === next.length &&
|
|
127
|
+
previous.every((target, index) => target === next[index])
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Groups the published owners by gesture relation signature. Target objects
|
|
133
|
+
* stay identical while their registration is unchanged and a group's target
|
|
134
|
+
* array stays identical while its content is unchanged, so an unchanged group
|
|
135
|
+
* publishes nothing to the UI runtime.
|
|
136
|
+
*/
|
|
137
|
+
export function groupGestureOwners<
|
|
138
|
+
Registration extends { gestureRelations?: GestureRelations },
|
|
139
|
+
Target,
|
|
140
|
+
>(
|
|
141
|
+
owners: readonly GestureOwner<Registration>[],
|
|
142
|
+
state: GroupingState<Registration, Target>,
|
|
143
|
+
toTarget: (owner: GestureOwner<Registration>) => Target,
|
|
144
|
+
): readonly GestureGroupSnapshot<Target>[] {
|
|
145
|
+
const targets = new Map<
|
|
146
|
+
number,
|
|
147
|
+
{ registration: Registration; target: Target }
|
|
148
|
+
>();
|
|
149
|
+
const collected = new Map<
|
|
150
|
+
number,
|
|
151
|
+
{ relations: GestureRelations | undefined; targets: Target[] }
|
|
152
|
+
>();
|
|
153
|
+
for (const owner of owners) {
|
|
154
|
+
const cached = state.targets.get(owner.id);
|
|
155
|
+
const target =
|
|
156
|
+
cached?.registration === owner.registration
|
|
157
|
+
? cached.target
|
|
158
|
+
: toTarget(owner);
|
|
159
|
+
targets.set(owner.id, { registration: owner.registration, target });
|
|
160
|
+
let signature = state.signatures.find(entry =>
|
|
161
|
+
sameGestureRelations(
|
|
162
|
+
entry.relations,
|
|
163
|
+
owner.registration.gestureRelations,
|
|
164
|
+
),
|
|
165
|
+
);
|
|
166
|
+
if (!signature) {
|
|
167
|
+
signature = {
|
|
168
|
+
relations: owner.registration.gestureRelations,
|
|
169
|
+
groupId: ++state.nextGroupId,
|
|
170
|
+
};
|
|
171
|
+
state.signatures.push(signature);
|
|
172
|
+
}
|
|
173
|
+
const group = collected.get(signature.groupId);
|
|
174
|
+
if (group) group.targets.push(target);
|
|
175
|
+
else
|
|
176
|
+
collected.set(signature.groupId, {
|
|
177
|
+
relations: signature.relations,
|
|
178
|
+
targets: [target],
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
state.targets = targets;
|
|
182
|
+
// A signature without handles releases its native recognizer.
|
|
183
|
+
state.signatures = state.signatures.filter(entry =>
|
|
184
|
+
collected.has(entry.groupId),
|
|
185
|
+
);
|
|
186
|
+
const groups = Array.from(collected, ([groupId, group]) => {
|
|
187
|
+
const previous = state.groups.find(entry => entry.groupId === groupId);
|
|
188
|
+
const hitTargets =
|
|
189
|
+
previous && sameTargets(previous.targets, group.targets)
|
|
190
|
+
? previous.targets
|
|
191
|
+
: group.targets;
|
|
192
|
+
return {
|
|
193
|
+
groupId,
|
|
194
|
+
relations: previous?.relations ?? group.relations,
|
|
195
|
+
targets: hitTargets,
|
|
196
|
+
channel: previous?.channel ?? createTargetChannel(hitTargets),
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
state.groups =
|
|
200
|
+
groups.length === state.groups.length &&
|
|
201
|
+
groups.every(
|
|
202
|
+
(group, index) =>
|
|
203
|
+
group.groupId === state.groups[index]!.groupId &&
|
|
204
|
+
group.targets === state.groups[index]!.targets &&
|
|
205
|
+
group.relations === state.groups[index]!.relations,
|
|
206
|
+
)
|
|
207
|
+
? state.groups
|
|
208
|
+
: groups;
|
|
209
|
+
return state.groups;
|
|
210
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
memo,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
useSyncExternalStore,
|
|
11
|
+
type ComponentType,
|
|
12
|
+
type ReactElement,
|
|
13
|
+
} from 'react';
|
|
14
|
+
import {
|
|
15
|
+
GestureDetector,
|
|
16
|
+
useCompetingGestures,
|
|
17
|
+
useManualGesture,
|
|
18
|
+
type ManualGestureConfig,
|
|
19
|
+
type PanGesture,
|
|
20
|
+
} from 'react-native-gesture-handler';
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
createGroupingState,
|
|
24
|
+
groupGestureOwners,
|
|
25
|
+
type GestureGroupProps,
|
|
26
|
+
type GestureOwner,
|
|
27
|
+
type GestureRegistry,
|
|
28
|
+
} from './gestureGrouping';
|
|
29
|
+
import type { GestureRelations } from '../components/gridTypes';
|
|
30
|
+
|
|
31
|
+
export type GestureHostProps<Registration, Runtime> = {
|
|
32
|
+
registry: GestureRegistry<Registration>;
|
|
33
|
+
runtime: Runtime;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const SENTINEL_CONFIG: ManualGestureConfig = {
|
|
37
|
+
enabled: false,
|
|
38
|
+
onTouchesDown: () => {
|
|
39
|
+
'worklet';
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Builds a host that owns one native recognizer per gesture relation
|
|
45
|
+
* signature. Handle mounts publish through the registry; the host groups them,
|
|
46
|
+
* renders one `Group` per signature and composes their recognizers on a single
|
|
47
|
+
* detector around the root content. Root content updates never render the
|
|
48
|
+
* detector or the groups.
|
|
49
|
+
*/
|
|
50
|
+
export function createGestureHost<
|
|
51
|
+
Registration extends { gestureRelations?: GestureRelations },
|
|
52
|
+
Target,
|
|
53
|
+
Runtime,
|
|
54
|
+
>({
|
|
55
|
+
Group,
|
|
56
|
+
toTarget,
|
|
57
|
+
}: {
|
|
58
|
+
Group: ComponentType<GestureGroupProps<Runtime, Target>>;
|
|
59
|
+
toTarget(owner: GestureOwner<Registration>): Target;
|
|
60
|
+
}) {
|
|
61
|
+
const RootContentContext = createContext<ReactElement | null>(null);
|
|
62
|
+
|
|
63
|
+
// Only this descendant consumes changing root content. Its context update does
|
|
64
|
+
// not render the detector or re-run the gesture composition hooks above it.
|
|
65
|
+
function NativeRoot() {
|
|
66
|
+
return useContext(RootContentContext);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const GestureGroup = memo(Group);
|
|
70
|
+
|
|
71
|
+
const NativeGestureDetector = memo(function NativeGestureDetectorImpl({
|
|
72
|
+
nativeGestures,
|
|
73
|
+
}: {
|
|
74
|
+
nativeGestures: ReadonlyMap<number, PanGesture>;
|
|
75
|
+
}) {
|
|
76
|
+
// Keep the native component type stable while no handle is registered.
|
|
77
|
+
const sentinel = useManualGesture(SENTINEL_CONFIG);
|
|
78
|
+
const gesture = useCompetingGestures(sentinel, ...nativeGestures.values());
|
|
79
|
+
return (
|
|
80
|
+
<GestureDetector gesture={gesture}>
|
|
81
|
+
<NativeRoot />
|
|
82
|
+
</GestureDetector>
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const GestureHost = memo(function GestureHostImpl({
|
|
87
|
+
registry,
|
|
88
|
+
runtime,
|
|
89
|
+
}: GestureHostProps<Registration, Runtime>) {
|
|
90
|
+
const owners = useSyncExternalStore(
|
|
91
|
+
registry.subscribe,
|
|
92
|
+
registry.getSnapshot,
|
|
93
|
+
registry.getSnapshot,
|
|
94
|
+
);
|
|
95
|
+
const mounted = useRef(true);
|
|
96
|
+
const gestureValues = useRef(new Map<number, PanGesture>());
|
|
97
|
+
const [gestureVersion, setGestureVersion] = useState(0);
|
|
98
|
+
// Group layout effects can publish several changes in one commit. Update
|
|
99
|
+
// their private map in O(1), then copy once when React renders the combined
|
|
100
|
+
// update. Never mutate the snapshot passed to the memoized detector.
|
|
101
|
+
const nativeGestures = useMemo(
|
|
102
|
+
() => new Map(gestureValues.current),
|
|
103
|
+
// The version explicitly invalidates this snapshot of the mutable registry.
|
|
104
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
105
|
+
[gestureVersion],
|
|
106
|
+
);
|
|
107
|
+
useLayoutEffect(() => {
|
|
108
|
+
mounted.current = true;
|
|
109
|
+
return () => {
|
|
110
|
+
mounted.current = false;
|
|
111
|
+
};
|
|
112
|
+
}, []);
|
|
113
|
+
const publish = useCallback((id: number, gesture: PanGesture | null) => {
|
|
114
|
+
if (!mounted.current) return;
|
|
115
|
+
const current = gestureValues.current;
|
|
116
|
+
if (gesture ? current.get(id) === gesture : !current.has(id)) return;
|
|
117
|
+
if (gesture) current.set(id, gesture);
|
|
118
|
+
else current.delete(id);
|
|
119
|
+
setGestureVersion(version => version + 1);
|
|
120
|
+
}, []);
|
|
121
|
+
const grouping = useRef(
|
|
122
|
+
createGroupingState<Registration, Target>(),
|
|
123
|
+
).current;
|
|
124
|
+
// Re-running this for the same owners is idempotent, which keeps StrictMode
|
|
125
|
+
// and discarded renders from producing different group identities.
|
|
126
|
+
const groups = useMemo(
|
|
127
|
+
() => groupGestureOwners(owners, grouping, toTarget),
|
|
128
|
+
[owners, grouping],
|
|
129
|
+
);
|
|
130
|
+
// Publish after commit: the group's subscription effect is registered first.
|
|
131
|
+
useLayoutEffect(() => {
|
|
132
|
+
for (const group of groups) group.channel.set(group.targets);
|
|
133
|
+
}, [groups]);
|
|
134
|
+
|
|
135
|
+
return (
|
|
136
|
+
<>
|
|
137
|
+
<NativeGestureDetector nativeGestures={nativeGestures} />
|
|
138
|
+
{groups.map(group => (
|
|
139
|
+
<GestureGroup
|
|
140
|
+
key={group.groupId}
|
|
141
|
+
groupId={group.groupId}
|
|
142
|
+
relations={group.relations}
|
|
143
|
+
channel={group.channel}
|
|
144
|
+
runtime={runtime}
|
|
145
|
+
publish={publish}
|
|
146
|
+
/>
|
|
147
|
+
))}
|
|
148
|
+
</>
|
|
149
|
+
);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return function Host({
|
|
153
|
+
children,
|
|
154
|
+
registry,
|
|
155
|
+
runtime,
|
|
156
|
+
}: GestureHostProps<Registration, Runtime> & { children: ReactElement }) {
|
|
157
|
+
return (
|
|
158
|
+
<RootContentContext value={children}>
|
|
159
|
+
<GestureHost registry={registry} runtime={runtime} />
|
|
160
|
+
</RootContentContext>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export { GridController } from './components/GridController';
|
|
2
|
+
export { DndProvider } from './components/DndProvider';
|
|
3
|
+
export { SortableList } from './components/SortableList';
|
|
4
|
+
export { SortableGrid } from './components/SortableGrid';
|
|
5
|
+
export { resolveListVirtualization } from './adapters/virtualizedList';
|
|
6
|
+
export type {
|
|
7
|
+
ListVirtualizationOptions,
|
|
8
|
+
ListVirtualizationResult,
|
|
9
|
+
} from './adapters/virtualizedList';
|
|
10
|
+
export { DragHandle } from './components/DragHandle';
|
|
11
|
+
export type {
|
|
12
|
+
DndProviderHandle,
|
|
13
|
+
DndProviderProps,
|
|
14
|
+
SortableListProps,
|
|
15
|
+
SortableGridProps,
|
|
16
|
+
GridItemRenderArgs,
|
|
17
|
+
DragHandleProps,
|
|
18
|
+
DragHandleViewProps,
|
|
19
|
+
ListItemRenderArgs,
|
|
20
|
+
DndPreviewArgs,
|
|
21
|
+
DndMotionConfig,
|
|
22
|
+
} from './components/dndTypes';
|
|
23
|
+
export { useDndState } from './controller/useDndState';
|
|
24
|
+
export type { DndState } from './controller/useDndState';
|
|
25
|
+
export {
|
|
26
|
+
createDndStateStore,
|
|
27
|
+
respondToDndProposal,
|
|
28
|
+
} from './controller/dndState';
|
|
29
|
+
export type {
|
|
30
|
+
DndValue,
|
|
31
|
+
DndProposal,
|
|
32
|
+
DndProposalResult,
|
|
33
|
+
DndStateStore,
|
|
34
|
+
DndStateUpdate,
|
|
35
|
+
} from './controller/dndState';
|
|
36
|
+
export type {
|
|
37
|
+
DndCancelReason,
|
|
38
|
+
DndDragEndEvent,
|
|
39
|
+
DndDropFailureReason,
|
|
40
|
+
GridItemLayoutResolverArgs,
|
|
41
|
+
} from './controller/dndSession';
|
|
42
|
+
export {
|
|
43
|
+
computeListLayout,
|
|
44
|
+
computeListIndex,
|
|
45
|
+
ListSizeCache,
|
|
46
|
+
} from './engine/list';
|
|
47
|
+
export type {
|
|
48
|
+
ListLayout,
|
|
49
|
+
ListLayoutEntry,
|
|
50
|
+
ListLayoutInput,
|
|
51
|
+
ListLayoutResult,
|
|
52
|
+
ListMeasurementContext,
|
|
53
|
+
} from './engine/list';
|
|
54
|
+
export { computeLayoutMove } from './engine/layoutMove';
|
|
55
|
+
export type {
|
|
56
|
+
GridItemLayout,
|
|
57
|
+
LayoutMoveInput,
|
|
58
|
+
LayoutMoveResult,
|
|
59
|
+
} from './engine/layoutMove';
|
|
60
|
+
export {
|
|
61
|
+
computeAutoScroll,
|
|
62
|
+
constrainDragPoint,
|
|
63
|
+
validateAutoScrollOptions,
|
|
64
|
+
} from './adapters/scroll';
|
|
65
|
+
export type {
|
|
66
|
+
AutoScrollInput,
|
|
67
|
+
AutoScrollOptions,
|
|
68
|
+
AutoScrollOptionsValidationResult,
|
|
69
|
+
AutoScrollResult,
|
|
70
|
+
DragAxis,
|
|
71
|
+
} from './adapters/scroll';
|
|
72
|
+
export { GridDragHandle } from './components/GridDragHandle';
|
|
73
|
+
export { GridZoneView } from './components/GridZoneView';
|
|
74
|
+
export { useGridState } from './controller/useGridState';
|
|
75
|
+
export type { GridState } from './controller/useGridState';
|
|
76
|
+
export {
|
|
77
|
+
createGridStateStore,
|
|
78
|
+
respondToGridProposal,
|
|
79
|
+
} from './controller/gridState';
|
|
80
|
+
export type {
|
|
81
|
+
GridStateStore,
|
|
82
|
+
GridStateUpdate,
|
|
83
|
+
GridProposalResult,
|
|
84
|
+
} from './controller/gridState';
|
|
85
|
+
export type { GridMotionConfig } from './pointer/motion';
|
|
86
|
+
export type { HandleViewProps } from './components/handleViewProps';
|
|
87
|
+
export { DEFAULT_ACTIVATION_DELAY_MS, DEFAULT_SEARCH_BUDGET } from './defaults';
|
|
88
|
+
export {
|
|
89
|
+
DEFAULT_GRID_MOVEMENT_POLICY,
|
|
90
|
+
HOME_GRID_MOVEMENT_POLICY,
|
|
91
|
+
resolveGridMovementPolicy,
|
|
92
|
+
validateGridMovementPolicy,
|
|
93
|
+
} from './engine/movementPolicy';
|
|
94
|
+
export type {
|
|
95
|
+
GridMoveCandidate,
|
|
96
|
+
GridMovementPolicy,
|
|
97
|
+
ResolvedGridMovementPolicy,
|
|
98
|
+
} from './engine/movementPolicy';
|
|
99
|
+
export type * from './contracts';
|
|
100
|
+
export {
|
|
101
|
+
validateLayoutState,
|
|
102
|
+
fromGridValue,
|
|
103
|
+
toGridValue,
|
|
104
|
+
} from './engine/layoutState';
|
|
105
|
+
export {
|
|
106
|
+
screenToContent,
|
|
107
|
+
contentToScreen,
|
|
108
|
+
screenRectToContent,
|
|
109
|
+
contentRectToScreen,
|
|
110
|
+
validateRectMeasurement,
|
|
111
|
+
} from './adapters/coordinates';
|
|
112
|
+
export type {
|
|
113
|
+
DragPreviewArgs,
|
|
114
|
+
GestureRelations,
|
|
115
|
+
GridControllerHandle,
|
|
116
|
+
GridControllerProps,
|
|
117
|
+
GridDragHandleProps,
|
|
118
|
+
GridInsets,
|
|
119
|
+
GridZoneViewProps,
|
|
120
|
+
ItemRenderArgs,
|
|
121
|
+
ZoneGeometry,
|
|
122
|
+
} from './components/gridTypes';
|
|
123
|
+
export type { OrderedIndexInput, OrderedIndexResult } from './engine';
|
|
124
|
+
export {
|
|
125
|
+
computeMove,
|
|
126
|
+
computeOrderedIndex,
|
|
127
|
+
computeZoneLayout,
|
|
128
|
+
hasSameLayout,
|
|
129
|
+
packItems,
|
|
130
|
+
validateValue,
|
|
131
|
+
} from './engine';
|
|
132
|
+
export type {
|
|
133
|
+
CancelReason,
|
|
134
|
+
CanDropArgs,
|
|
135
|
+
CellPosition,
|
|
136
|
+
CellSpan,
|
|
137
|
+
CleanupReason,
|
|
138
|
+
DragEndEvent,
|
|
139
|
+
DragStartEvent,
|
|
140
|
+
DropDecision,
|
|
141
|
+
GridChange,
|
|
142
|
+
GridDiagnosticEvent,
|
|
143
|
+
GridItem,
|
|
144
|
+
GridProposal,
|
|
145
|
+
GridValue,
|
|
146
|
+
GridZone,
|
|
147
|
+
ItemLocation,
|
|
148
|
+
ItemPlacement,
|
|
149
|
+
MoveInput,
|
|
150
|
+
MoveResult,
|
|
151
|
+
OrderedZone,
|
|
152
|
+
PackInput,
|
|
153
|
+
PackResult,
|
|
154
|
+
PositionedItem,
|
|
155
|
+
RevisionedGridValue,
|
|
156
|
+
ProposalInterruptReason,
|
|
157
|
+
SpatialZone,
|
|
158
|
+
ValidationCode,
|
|
159
|
+
ValidationIssue,
|
|
160
|
+
ValidationResult,
|
|
161
|
+
ZoneLayoutResult,
|
|
162
|
+
} from './types';
|