@ankhorage/react-native-reanimated-dnd-web 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Added split entrypoints: `index.native` and `index.web`.
6
+ - Native entry now re-exports upstream `react-native-reanimated-dnd`.
7
+ - Web entry mirrors upstream export names, implements sortable components, and stubs unsupported symbols.
8
+ - Covered by shared contract tests for export-surface parity and web import/runtime stub behavior in `@ankh/dnd`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ankhorage
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @ankhorage/react-native-reanimated-dnd-web
2
+
3
+ This package is a platform-specific web adapter used internally by the `@ankh/dnd` boundary package in this monorepo.
4
+
5
+ It is not intended to be installed directly from this repository.
6
+
7
+ To consume DnD functionality in monorepo apps/packages, install and import `@ankh/dnd` instead.
@@ -0,0 +1 @@
1
+ export * from 'react-native-reanimated-dnd';
@@ -0,0 +1,2 @@
1
+ export * from "react-native-reanimated-dnd";
2
+ //# sourceMappingURL=index.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.native.ts"],"sourcesContent":["export * from 'react-native-reanimated-dnd';\n"],"mappings":"AAAA,cAAc;","names":[]}
@@ -0,0 +1,414 @@
1
+ import { Fragment, jsx } from "react/jsx-runtime";
2
+ import {
3
+ memo,
4
+ useCallback,
5
+ useEffect,
6
+ useMemo,
7
+ useRef,
8
+ useState
9
+ } from "react";
10
+ import { StyleSheet, View } from "react-native";
11
+ const DRAG_THRESHOLD = 6;
12
+ const WEB_ERROR_PREFIX = "[@ankhorage/react-native-reanimated-dnd-web:web]";
13
+ function createUnsupportedError(symbol) {
14
+ return new Error(
15
+ `${WEB_ERROR_PREFIX} ${symbol} is not supported on web yet. Use Sortable/SortableItem for sortable lists.`
16
+ );
17
+ }
18
+ function unsupportedFunction(symbol) {
19
+ const unsupported = (() => {
20
+ throw createUnsupportedError(symbol);
21
+ });
22
+ return unsupported;
23
+ }
24
+ function unsupportedComponent(symbol) {
25
+ const Unsupported = () => {
26
+ throw createUnsupportedError(symbol);
27
+ };
28
+ Unsupported.displayName = `Unsupported${symbol}`;
29
+ return Unsupported;
30
+ }
31
+ function isRecord(value) {
32
+ return typeof value === "object" && value !== null && !Array.isArray(value);
33
+ }
34
+ function getWebWindow() {
35
+ if (typeof globalThis === "undefined") return null;
36
+ const maybeWindow = globalThis;
37
+ if (typeof maybeWindow.addEventListener !== "function" || typeof maybeWindow.removeEventListener !== "function") {
38
+ return null;
39
+ }
40
+ return maybeWindow;
41
+ }
42
+ function toPositionMap(candidate) {
43
+ if (!isRecord(candidate)) {
44
+ return {};
45
+ }
46
+ const next = {};
47
+ for (const [key, value] of Object.entries(candidate)) {
48
+ if (typeof value === "number" && Number.isFinite(value)) {
49
+ next[key] = value;
50
+ }
51
+ }
52
+ return next;
53
+ }
54
+ function readPositions(positions) {
55
+ if (isRecord(positions) && "value" in positions) {
56
+ return toPositionMap(positions.value);
57
+ }
58
+ return toPositionMap(positions);
59
+ }
60
+ function writePositions(positions, next) {
61
+ if (isRecord(positions) && "value" in positions) {
62
+ positions.value = next;
63
+ return;
64
+ }
65
+ if (!isRecord(positions)) {
66
+ return;
67
+ }
68
+ for (const key of Object.keys(positions)) {
69
+ delete positions[key];
70
+ }
71
+ Object.assign(positions, next);
72
+ }
73
+ function writeSharedValue(sharedValue, value) {
74
+ if (!isRecord(sharedValue) || !("value" in sharedValue)) {
75
+ return;
76
+ }
77
+ sharedValue.value = value;
78
+ }
79
+ function defaultItemKeyExtractor(item, index) {
80
+ if (isRecord(item) && typeof item.id === "string" && item.id.trim().length > 0) {
81
+ return item.id;
82
+ }
83
+ return `item-${index}`;
84
+ }
85
+ function createPositionsFromIds(ids) {
86
+ const next = {};
87
+ for (const [index, id] of ids.entries()) {
88
+ next[id] = index;
89
+ }
90
+ return next;
91
+ }
92
+ function createPositionSharedValue(positionMap) {
93
+ return { value: positionMap };
94
+ }
95
+ var ScrollDirection = /* @__PURE__ */ ((ScrollDirection2) => {
96
+ ScrollDirection2["None"] = "none";
97
+ ScrollDirection2["Up"] = "up";
98
+ ScrollDirection2["Down"] = "down";
99
+ return ScrollDirection2;
100
+ })(ScrollDirection || {});
101
+ function clamp(value, lowerBound, upperBound) {
102
+ return Math.min(Math.max(value, lowerBound), upperBound);
103
+ }
104
+ function objectMove(object, from, to) {
105
+ const entries = Object.entries(object).sort(([, indexA], [, indexB]) => indexA - indexB);
106
+ if (entries.length === 0) {
107
+ return {};
108
+ }
109
+ const safeFrom = clamp(from, 0, entries.length - 1);
110
+ const safeTo = clamp(to, 0, entries.length - 1);
111
+ const [moved] = entries.splice(safeFrom, 1);
112
+ if (!moved) {
113
+ return object;
114
+ }
115
+ entries.splice(safeTo, 0, moved);
116
+ const next = {};
117
+ for (const [index, [id]] of entries.entries()) {
118
+ next[id] = index;
119
+ }
120
+ return next;
121
+ }
122
+ function listToObject(list) {
123
+ const next = {};
124
+ for (const [index, item] of list.entries()) {
125
+ next[item.id] = index;
126
+ }
127
+ return next;
128
+ }
129
+ function setPosition(positionY, itemsCount, positions, id, itemHeight) {
130
+ if (!id || itemsCount <= 0 || itemHeight <= 0) {
131
+ return;
132
+ }
133
+ const currentPositions = readPositions(positions);
134
+ const from = currentPositions[id];
135
+ if (typeof from !== "number") {
136
+ return;
137
+ }
138
+ const nextPosition = clamp(Math.round(positionY / itemHeight), 0, itemsCount - 1);
139
+ writePositions(positions, objectMove(currentPositions, from, nextPosition));
140
+ }
141
+ function setAutoScroll(positionY, lowerBound, upperBound, scrollThreshold, autoScroll) {
142
+ if (positionY <= lowerBound + scrollThreshold) {
143
+ writeSharedValue(autoScroll, "up" /* Up */);
144
+ return;
145
+ }
146
+ if (positionY >= upperBound - scrollThreshold) {
147
+ writeSharedValue(autoScroll, "down" /* Down */);
148
+ return;
149
+ }
150
+ writeSharedValue(autoScroll, "none" /* None */);
151
+ }
152
+ function SortableHandle({ children, style }) {
153
+ return /* @__PURE__ */ jsx(View, { style, children });
154
+ }
155
+ function SortableItemBase({
156
+ id,
157
+ positions,
158
+ itemsCount,
159
+ itemHeight = 0,
160
+ gap = 0,
161
+ children,
162
+ style,
163
+ onMove,
164
+ onDragStart,
165
+ onDrop,
166
+ onDragging
167
+ }) {
168
+ const [isDragging, setIsDragging] = useState(false);
169
+ const dragContextRef = useRef(null);
170
+ const pendingContextRef = useRef(null);
171
+ const listenersRef = useRef({ move: null, up: null });
172
+ const rowStep = itemHeight + gap;
173
+ const clearListeners = useCallback(() => {
174
+ const webWindow = getWebWindow();
175
+ if (!webWindow) return;
176
+ const currentMove = listenersRef.current.move;
177
+ if (currentMove) {
178
+ webWindow.removeEventListener("pointermove", currentMove);
179
+ }
180
+ const currentUp = listenersRef.current.up;
181
+ if (currentUp) {
182
+ webWindow.removeEventListener("pointerup", currentUp);
183
+ webWindow.removeEventListener("pointercancel", currentUp);
184
+ }
185
+ listenersRef.current = { move: null, up: null };
186
+ }, []);
187
+ const resetDragState = useCallback(() => {
188
+ dragContextRef.current = null;
189
+ pendingContextRef.current = null;
190
+ setIsDragging(false);
191
+ clearListeners();
192
+ }, [clearListeners]);
193
+ useEffect(() => {
194
+ return () => {
195
+ clearListeners();
196
+ };
197
+ }, [clearListeners]);
198
+ const updateDragTarget = useCallback(
199
+ (pageY) => {
200
+ const drag = dragContextRef.current;
201
+ if (!drag || rowStep <= 0) return;
202
+ const dy = pageY - drag.startPageY;
203
+ const deltaRows = Math.round(dy / rowStep);
204
+ const nextTarget = clamp(drag.sourceIndex + deltaRows, 0, Math.max(0, itemsCount - 1));
205
+ if (nextTarget !== drag.targetIndex) {
206
+ drag.targetIndex = nextTarget;
207
+ onDragging?.(id, null, pageY);
208
+ }
209
+ },
210
+ [id, itemsCount, onDragging, rowStep]
211
+ );
212
+ const handleDrop = useCallback(() => {
213
+ const drag = dragContextRef.current;
214
+ if (!drag) {
215
+ resetDragState();
216
+ return;
217
+ }
218
+ if (drag.targetIndex !== drag.sourceIndex) {
219
+ const currentPositions = readPositions(positions);
220
+ const from = currentPositions[id];
221
+ if (typeof from === "number") {
222
+ writePositions(positions, objectMove(currentPositions, from, drag.targetIndex));
223
+ }
224
+ onMove?.(id, drag.sourceIndex, drag.targetIndex);
225
+ onDrop?.(id, drag.targetIndex);
226
+ }
227
+ resetDragState();
228
+ }, [id, onDrop, onMove, positions, resetDragState]);
229
+ const beginTracking = useCallback(
230
+ (event) => {
231
+ const webWindow = getWebWindow();
232
+ if (!webWindow) return;
233
+ const sourceIndex = readPositions(positions)[id] ?? 0;
234
+ pendingContextRef.current = {
235
+ pointerId: event.pointerId,
236
+ sourceIndex,
237
+ startPageX: event.pageX,
238
+ startPageY: event.pageY
239
+ };
240
+ const handleMove = (moveEvent) => {
241
+ const drag = dragContextRef.current;
242
+ if (drag) {
243
+ if (drag.pointerId !== moveEvent.pointerId) return;
244
+ updateDragTarget(moveEvent.pageY);
245
+ return;
246
+ }
247
+ const pending = pendingContextRef.current;
248
+ if (pending?.pointerId !== moveEvent.pointerId) return;
249
+ const dy = moveEvent.pageY - pending.startPageY;
250
+ const dx = moveEvent.pageX - pending.startPageX;
251
+ if (!(Math.abs(dy) > DRAG_THRESHOLD && Math.abs(dy) > Math.abs(dx))) {
252
+ return;
253
+ }
254
+ dragContextRef.current = {
255
+ pointerId: pending.pointerId,
256
+ sourceIndex: pending.sourceIndex,
257
+ targetIndex: pending.sourceIndex,
258
+ startPageY: pending.startPageY
259
+ };
260
+ pendingContextRef.current = null;
261
+ setIsDragging(true);
262
+ onDragStart?.(id, dragContextRef.current.sourceIndex);
263
+ updateDragTarget(moveEvent.pageY);
264
+ };
265
+ const handleUp = (upEvent) => {
266
+ const drag = dragContextRef.current;
267
+ if (drag) {
268
+ if (drag.pointerId !== upEvent.pointerId) return;
269
+ handleDrop();
270
+ return;
271
+ }
272
+ const pending = pendingContextRef.current;
273
+ if (pending?.pointerId === upEvent.pointerId) {
274
+ pendingContextRef.current = null;
275
+ clearListeners();
276
+ }
277
+ };
278
+ clearListeners();
279
+ listenersRef.current = { move: handleMove, up: handleUp };
280
+ webWindow.addEventListener("pointermove", handleMove);
281
+ webWindow.addEventListener("pointerup", handleUp);
282
+ webWindow.addEventListener("pointercancel", handleUp);
283
+ },
284
+ [clearListeners, handleDrop, id, onDragStart, positions, updateDragTarget]
285
+ );
286
+ const handlePointerDown = useCallback(
287
+ (event) => {
288
+ const { nativeEvent } = event;
289
+ if (!nativeEvent) return;
290
+ if (typeof nativeEvent.button === "number" && nativeEvent.button !== 0) {
291
+ return;
292
+ }
293
+ const { pointerId } = nativeEvent;
294
+ const { pageX } = nativeEvent;
295
+ const { pageY } = nativeEvent;
296
+ if (typeof pointerId !== "number" || typeof pageX !== "number" || typeof pageY !== "number") {
297
+ return;
298
+ }
299
+ beginTracking({
300
+ pointerId,
301
+ pageX,
302
+ pageY,
303
+ button: nativeEvent.button
304
+ });
305
+ },
306
+ [beginTracking]
307
+ );
308
+ return /* @__PURE__ */ jsx(
309
+ View,
310
+ {
311
+ onPointerDown: handlePointerDown,
312
+ style: [
313
+ itemHeight > 0 ? { height: itemHeight } : null,
314
+ style,
315
+ isDragging ? webStyles.dragging : null
316
+ ],
317
+ children
318
+ }
319
+ );
320
+ }
321
+ const SortableItem = Object.assign(SortableItemBase, {
322
+ Handle: SortableHandle
323
+ });
324
+ function SortableImpl({
325
+ data,
326
+ renderItem,
327
+ direction,
328
+ itemHeight,
329
+ itemWidth,
330
+ gap,
331
+ paddingHorizontal,
332
+ style,
333
+ contentContainerStyle,
334
+ itemKeyExtractor
335
+ }) {
336
+ const keyExtractor = itemKeyExtractor ?? defaultItemKeyExtractor;
337
+ const ids = useMemo(
338
+ () => data.map((item, index) => keyExtractor(item, index)),
339
+ [data, keyExtractor]
340
+ );
341
+ const positions = useMemo(() => createPositionSharedValue(createPositionsFromIds(ids)), [ids]);
342
+ const renderSortableItem = useCallback(
343
+ (item, index) => {
344
+ const id = ids[index] ?? keyExtractor(item, index);
345
+ const marginBottom = gap ?? 0;
346
+ const renderProps = {
347
+ item,
348
+ index,
349
+ id,
350
+ positions,
351
+ direction,
352
+ itemsCount: data.length,
353
+ itemHeight,
354
+ itemWidth,
355
+ gap,
356
+ paddingHorizontal
357
+ };
358
+ return /* @__PURE__ */ jsx(
359
+ View,
360
+ {
361
+ style: index < data.length - 1 && marginBottom > 0 ? { marginBottom } : null,
362
+ children: renderItem(renderProps)
363
+ },
364
+ id
365
+ );
366
+ },
367
+ [
368
+ data.length,
369
+ direction,
370
+ gap,
371
+ ids,
372
+ itemHeight,
373
+ itemWidth,
374
+ keyExtractor,
375
+ paddingHorizontal,
376
+ positions,
377
+ renderItem
378
+ ]
379
+ );
380
+ return /* @__PURE__ */ jsx(View, { style, children: /* @__PURE__ */ jsx(View, { style: contentContainerStyle, children: data.map(renderSortableItem) }) });
381
+ }
382
+ const Sortable = memo(SortableImpl);
383
+ function DropProvider({ children }) {
384
+ return /* @__PURE__ */ jsx(Fragment, { children });
385
+ }
386
+ const Draggable = unsupportedComponent("Draggable");
387
+ const Droppable = unsupportedComponent("Droppable");
388
+ const useDraggable = unsupportedFunction("useDraggable");
389
+ const useDroppable = unsupportedFunction("useDroppable");
390
+ const useSortable = unsupportedFunction("useSortable");
391
+ const useSortableList = unsupportedFunction("useSortableList");
392
+ const webStyles = StyleSheet.create({
393
+ dragging: {
394
+ opacity: 0.7
395
+ }
396
+ });
397
+ export {
398
+ Draggable,
399
+ DropProvider,
400
+ Droppable,
401
+ ScrollDirection,
402
+ Sortable,
403
+ SortableItem,
404
+ clamp,
405
+ listToObject,
406
+ objectMove,
407
+ setAutoScroll,
408
+ setPosition,
409
+ useDraggable,
410
+ useDroppable,
411
+ useSortable,
412
+ useSortableList
413
+ };
414
+ //# sourceMappingURL=index.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.web.tsx"],"sourcesContent":["import React, {\n memo,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { type StyleProp, StyleSheet, View, type ViewStyle } from 'react-native';\nimport type {\n SortableHandleProps,\n SortableItemProps,\n SortableProps,\n SortableRenderItemProps,\n} from 'react-native-reanimated-dnd';\n\ntype PositionMap = Record<string, number>;\ntype PointerEventLike = {\n pointerId: number;\n pageX: number;\n pageY: number;\n button?: number;\n};\ntype WebWindowLike = {\n addEventListener: (\n type: 'pointermove' | 'pointerup' | 'pointercancel',\n listener: (event: PointerEventLike) => void,\n ) => void;\n removeEventListener: (\n type: 'pointermove' | 'pointerup' | 'pointercancel',\n listener: (event: PointerEventLike) => void,\n ) => void;\n};\ntype PointerListeners = {\n move: ((event: PointerEventLike) => void) | null;\n up: ((event: PointerEventLike) => void) | null;\n};\n\nconst DRAG_THRESHOLD = 6;\nconst WEB_ERROR_PREFIX = '[@ankhorage/react-native-reanimated-dnd-web:web]';\n\nfunction createUnsupportedError(symbol: string): Error {\n return new Error(\n `${WEB_ERROR_PREFIX} ${symbol} is not supported on web yet. Use Sortable/SortableItem for sortable lists.`,\n );\n}\n\nfunction unsupportedFunction<T extends (...args: never[]) => unknown>(symbol: string): T {\n const unsupported = (() => {\n throw createUnsupportedError(symbol);\n }) as T;\n\n return unsupported;\n}\n\nfunction unsupportedComponent<P extends object>(symbol: string): React.FC<P> {\n const Unsupported: React.FC<P> = () => {\n throw createUnsupportedError(symbol);\n };\n\n Unsupported.displayName = `Unsupported${symbol}`;\n return Unsupported;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction getWebWindow(): WebWindowLike | null {\n if (typeof globalThis === 'undefined') return null;\n\n const maybeWindow = globalThis as unknown as Partial<WebWindowLike>;\n if (\n typeof maybeWindow.addEventListener !== 'function' ||\n typeof maybeWindow.removeEventListener !== 'function'\n ) {\n return null;\n }\n\n return maybeWindow as WebWindowLike;\n}\n\nfunction toPositionMap(candidate: unknown): PositionMap {\n if (!isRecord(candidate)) {\n return {};\n }\n\n const next: PositionMap = {};\n for (const [key, value] of Object.entries(candidate)) {\n if (typeof value === 'number' && Number.isFinite(value)) {\n next[key] = value;\n }\n }\n return next;\n}\n\nfunction readPositions(positions: unknown): PositionMap {\n if (isRecord(positions) && 'value' in positions) {\n return toPositionMap(positions.value);\n }\n\n return toPositionMap(positions);\n}\n\nfunction writePositions(positions: unknown, next: PositionMap): void {\n if (isRecord(positions) && 'value' in positions) {\n (positions as { value: PositionMap }).value = next;\n return;\n }\n\n if (!isRecord(positions)) {\n return;\n }\n\n for (const key of Object.keys(positions)) {\n delete positions[key];\n }\n Object.assign(positions, next);\n}\n\nfunction writeSharedValue<T>(sharedValue: unknown, value: T): void {\n if (!isRecord(sharedValue) || !('value' in sharedValue)) {\n return;\n }\n\n (sharedValue as { value: T }).value = value;\n}\n\nfunction defaultItemKeyExtractor<TData>(item: TData, index: number): string {\n if (isRecord(item) && typeof item.id === 'string' && item.id.trim().length > 0) {\n return item.id;\n }\n\n return `item-${index}`;\n}\n\nfunction createPositionsFromIds(ids: string[]): PositionMap {\n const next: PositionMap = {};\n for (const [index, id] of ids.entries()) {\n next[id] = index;\n }\n return next;\n}\n\ntype PositionSharedValue = SortableRenderItemProps<unknown>['positions'];\n\nfunction createPositionSharedValue(positionMap: PositionMap): PositionSharedValue {\n // Keep a SharedValue-like shape (`{ value }`) so both web logic and upstream prop types align.\n return { value: positionMap } as PositionSharedValue;\n}\n\nexport enum ScrollDirection {\n None = 'none',\n Up = 'up',\n Down = 'down',\n}\n\nexport function clamp(value: number, lowerBound: number, upperBound: number): number {\n return Math.min(Math.max(value, lowerBound), upperBound);\n}\n\nexport function objectMove(object: PositionMap, from: number, to: number): PositionMap {\n const entries = Object.entries(object).sort(([, indexA], [, indexB]) => indexA - indexB);\n if (entries.length === 0) {\n return {};\n }\n\n const safeFrom = clamp(from, 0, entries.length - 1);\n const safeTo = clamp(to, 0, entries.length - 1);\n const [moved] = entries.splice(safeFrom, 1);\n if (!moved) {\n return object;\n }\n\n entries.splice(safeTo, 0, moved);\n\n const next: PositionMap = {};\n for (const [index, [id]] of entries.entries()) {\n next[id] = index;\n }\n return next;\n}\n\nexport function listToObject<T extends { id: string }>(list: T[]): PositionMap {\n const next: PositionMap = {};\n for (const [index, item] of list.entries()) {\n next[item.id] = index;\n }\n return next;\n}\n\nexport function setPosition(\n positionY: number,\n itemsCount: number,\n positions: unknown,\n id: string,\n itemHeight: number,\n): void {\n if (!id || itemsCount <= 0 || itemHeight <= 0) {\n return;\n }\n\n const currentPositions = readPositions(positions);\n const from = currentPositions[id];\n if (typeof from !== 'number') {\n return;\n }\n\n const nextPosition = clamp(Math.round(positionY / itemHeight), 0, itemsCount - 1);\n writePositions(positions, objectMove(currentPositions, from, nextPosition));\n}\n\nexport function setAutoScroll(\n positionY: number,\n lowerBound: number,\n upperBound: number,\n scrollThreshold: number,\n autoScroll: unknown,\n): void {\n if (positionY <= lowerBound + scrollThreshold) {\n writeSharedValue(autoScroll, ScrollDirection.Up);\n return;\n }\n\n if (positionY >= upperBound - scrollThreshold) {\n writeSharedValue(autoScroll, ScrollDirection.Down);\n return;\n }\n\n writeSharedValue(autoScroll, ScrollDirection.None);\n}\n\ntype SortableItemDragContext = {\n pointerId: number;\n sourceIndex: number;\n targetIndex: number;\n startPageY: number;\n};\n\ntype SortableItemPendingContext = {\n pointerId: number;\n sourceIndex: number;\n startPageX: number;\n startPageY: number;\n};\n\nfunction SortableHandle({ children, style }: SortableHandleProps): React.JSX.Element {\n return <View style={style}>{children}</View>;\n}\n\nfunction SortableItemBase<T>({\n id,\n positions,\n itemsCount,\n itemHeight = 0,\n gap = 0,\n children,\n style,\n onMove,\n onDragStart,\n onDrop,\n onDragging,\n}: SortableItemProps<T>): React.JSX.Element {\n const [isDragging, setIsDragging] = useState(false);\n const dragContextRef = useRef<SortableItemDragContext | null>(null);\n const pendingContextRef = useRef<SortableItemPendingContext | null>(null);\n const listenersRef = useRef<PointerListeners>({ move: null, up: null });\n const rowStep = itemHeight + gap;\n\n const clearListeners = useCallback(() => {\n const webWindow = getWebWindow();\n if (!webWindow) return;\n\n const currentMove = listenersRef.current.move;\n if (currentMove) {\n webWindow.removeEventListener('pointermove', currentMove);\n }\n\n const currentUp = listenersRef.current.up;\n if (currentUp) {\n webWindow.removeEventListener('pointerup', currentUp);\n webWindow.removeEventListener('pointercancel', currentUp);\n }\n\n listenersRef.current = { move: null, up: null };\n }, []);\n\n const resetDragState = useCallback(() => {\n dragContextRef.current = null;\n pendingContextRef.current = null;\n setIsDragging(false);\n clearListeners();\n }, [clearListeners]);\n\n useEffect(() => {\n return () => {\n clearListeners();\n };\n }, [clearListeners]);\n\n const updateDragTarget = useCallback(\n (pageY: number) => {\n const drag = dragContextRef.current;\n if (!drag || rowStep <= 0) return;\n\n const dy = pageY - drag.startPageY;\n const deltaRows = Math.round(dy / rowStep);\n const nextTarget = clamp(drag.sourceIndex + deltaRows, 0, Math.max(0, itemsCount - 1));\n if (nextTarget !== drag.targetIndex) {\n drag.targetIndex = nextTarget;\n onDragging?.(id, null, pageY);\n }\n },\n [id, itemsCount, onDragging, rowStep],\n );\n\n const handleDrop = useCallback(() => {\n const drag = dragContextRef.current;\n if (!drag) {\n resetDragState();\n return;\n }\n\n if (drag.targetIndex !== drag.sourceIndex) {\n const currentPositions = readPositions(positions);\n const from = currentPositions[id];\n if (typeof from === 'number') {\n writePositions(positions, objectMove(currentPositions, from, drag.targetIndex));\n }\n\n onMove?.(id, drag.sourceIndex, drag.targetIndex);\n onDrop?.(id, drag.targetIndex);\n }\n\n resetDragState();\n }, [id, onDrop, onMove, positions, resetDragState]);\n\n const beginTracking = useCallback(\n (event: PointerEventLike) => {\n const webWindow = getWebWindow();\n if (!webWindow) return;\n\n const sourceIndex = readPositions(positions)[id] ?? 0;\n pendingContextRef.current = {\n pointerId: event.pointerId,\n sourceIndex,\n startPageX: event.pageX,\n startPageY: event.pageY,\n };\n\n const handleMove = (moveEvent: PointerEventLike) => {\n const drag = dragContextRef.current;\n if (drag) {\n if (drag.pointerId !== moveEvent.pointerId) return;\n updateDragTarget(moveEvent.pageY);\n return;\n }\n\n const pending = pendingContextRef.current;\n if (pending?.pointerId !== moveEvent.pointerId) return;\n\n const dy = moveEvent.pageY - pending.startPageY;\n const dx = moveEvent.pageX - pending.startPageX;\n if (!(Math.abs(dy) > DRAG_THRESHOLD && Math.abs(dy) > Math.abs(dx))) {\n return;\n }\n\n dragContextRef.current = {\n pointerId: pending.pointerId,\n sourceIndex: pending.sourceIndex,\n targetIndex: pending.sourceIndex,\n startPageY: pending.startPageY,\n };\n pendingContextRef.current = null;\n setIsDragging(true);\n onDragStart?.(id, dragContextRef.current.sourceIndex);\n updateDragTarget(moveEvent.pageY);\n };\n\n const handleUp = (upEvent: PointerEventLike) => {\n const drag = dragContextRef.current;\n if (drag) {\n if (drag.pointerId !== upEvent.pointerId) return;\n handleDrop();\n return;\n }\n\n const pending = pendingContextRef.current;\n if (pending?.pointerId === upEvent.pointerId) {\n pendingContextRef.current = null;\n clearListeners();\n }\n };\n\n clearListeners();\n listenersRef.current = { move: handleMove, up: handleUp };\n webWindow.addEventListener('pointermove', handleMove);\n webWindow.addEventListener('pointerup', handleUp);\n webWindow.addEventListener('pointercancel', handleUp);\n },\n [clearListeners, handleDrop, id, onDragStart, positions, updateDragTarget],\n );\n\n const handlePointerDown = useCallback(\n (event: { nativeEvent?: Partial<PointerEventLike> }) => {\n const { nativeEvent } = event;\n if (!nativeEvent) return;\n\n if (typeof nativeEvent.button === 'number' && nativeEvent.button !== 0) {\n return;\n }\n\n const { pointerId } = nativeEvent;\n const { pageX } = nativeEvent;\n const { pageY } = nativeEvent;\n\n if (typeof pointerId !== 'number' || typeof pageX !== 'number' || typeof pageY !== 'number') {\n return;\n }\n\n beginTracking({\n pointerId,\n pageX,\n pageY,\n button: nativeEvent.button,\n });\n },\n [beginTracking],\n );\n\n return (\n <View\n onPointerDown={handlePointerDown}\n style={[\n itemHeight > 0 ? { height: itemHeight } : null,\n style as StyleProp<ViewStyle>,\n isDragging ? webStyles.dragging : null,\n ]}\n >\n {children}\n </View>\n );\n}\n\nexport const SortableItem = Object.assign(SortableItemBase, {\n Handle: SortableHandle,\n});\n\nfunction SortableImpl<TData>({\n data,\n renderItem,\n direction,\n itemHeight,\n itemWidth,\n gap,\n paddingHorizontal,\n style,\n contentContainerStyle,\n itemKeyExtractor,\n}: SortableProps<TData>): React.JSX.Element {\n const keyExtractor = itemKeyExtractor ?? defaultItemKeyExtractor<TData>;\n const ids = useMemo(\n () => data.map((item, index) => keyExtractor(item, index)),\n [data, keyExtractor],\n );\n const positions = useMemo(() => createPositionSharedValue(createPositionsFromIds(ids)), [ids]);\n\n const renderSortableItem = useCallback(\n (item: TData, index: number) => {\n const id = ids[index] ?? keyExtractor(item, index);\n const marginBottom = gap ?? 0;\n const renderProps: SortableRenderItemProps<TData> = {\n item,\n index,\n id,\n positions,\n direction,\n itemsCount: data.length,\n itemHeight,\n itemWidth,\n gap,\n paddingHorizontal,\n };\n\n return (\n <View\n key={id}\n style={index < data.length - 1 && marginBottom > 0 ? { marginBottom } : null}\n >\n {renderItem(renderProps)}\n </View>\n );\n },\n [\n data.length,\n direction,\n gap,\n ids,\n itemHeight,\n itemWidth,\n keyExtractor,\n paddingHorizontal,\n positions,\n renderItem,\n ],\n );\n\n return (\n <View style={style}>\n <View style={contentContainerStyle}>{data.map(renderSortableItem)}</View>\n </View>\n );\n}\n\nexport const Sortable = memo(SortableImpl) as typeof SortableImpl;\n\ninterface DropProviderProps {\n children?: ReactNode;\n}\n\nexport function DropProvider({ children }: DropProviderProps): React.JSX.Element {\n return <>{children}</>;\n}\n\nexport const Draggable = unsupportedComponent<Record<string, unknown>>('Draggable');\nexport const Droppable = unsupportedComponent<Record<string, unknown>>('Droppable');\nexport const useDraggable = unsupportedFunction<(...args: never[]) => never>('useDraggable');\nexport const useDroppable = unsupportedFunction<(...args: never[]) => never>('useDroppable');\nexport const useSortable = unsupportedFunction<(...args: never[]) => never>('useSortable');\nexport const useSortableList = unsupportedFunction<(...args: never[]) => never>('useSortableList');\n\nconst webStyles = StyleSheet.create({\n dragging: {\n opacity: 0.7,\n },\n});\n\nexport type * from 'react-native-reanimated-dnd';\n"],"mappings":"AAwPS,SAkRA,UAlRA;AAxPT;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAyB,YAAY,YAA4B;AA8BjE,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AAEzB,SAAS,uBAAuB,QAAuB;AACrD,SAAO,IAAI;AAAA,IACT,GAAG,gBAAgB,IAAI,MAAM;AAAA,EAC/B;AACF;AAEA,SAAS,oBAA6D,QAAmB;AACvF,QAAM,eAAe,MAAM;AACzB,UAAM,uBAAuB,MAAM;AAAA,EACrC;AAEA,SAAO;AACT;AAEA,SAAS,qBAAuC,QAA6B;AAC3E,QAAM,cAA2B,MAAM;AACrC,UAAM,uBAAuB,MAAM;AAAA,EACrC;AAEA,cAAY,cAAc,cAAc,MAAM;AAC9C,SAAO;AACT;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,eAAqC;AAC5C,MAAI,OAAO,eAAe,YAAa,QAAO;AAE9C,QAAM,cAAc;AACpB,MACE,OAAO,YAAY,qBAAqB,cACxC,OAAO,YAAY,wBAAwB,YAC3C;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,WAAiC;AACtD,MAAI,CAAC,SAAS,SAAS,GAAG;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,OAAoB,CAAC;AAC3B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,QAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,GAAG;AACvD,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,WAAiC;AACtD,MAAI,SAAS,SAAS,KAAK,WAAW,WAAW;AAC/C,WAAO,cAAc,UAAU,KAAK;AAAA,EACtC;AAEA,SAAO,cAAc,SAAS;AAChC;AAEA,SAAS,eAAe,WAAoB,MAAyB;AACnE,MAAI,SAAS,SAAS,KAAK,WAAW,WAAW;AAC/C,IAAC,UAAqC,QAAQ;AAC9C;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,SAAS,GAAG;AACxB;AAAA,EACF;AAEA,aAAW,OAAO,OAAO,KAAK,SAAS,GAAG;AACxC,WAAO,UAAU,GAAG;AAAA,EACtB;AACA,SAAO,OAAO,WAAW,IAAI;AAC/B;AAEA,SAAS,iBAAoB,aAAsB,OAAgB;AACjE,MAAI,CAAC,SAAS,WAAW,KAAK,EAAE,WAAW,cAAc;AACvD;AAAA,EACF;AAEA,EAAC,YAA6B,QAAQ;AACxC;AAEA,SAAS,wBAA+B,MAAa,OAAuB;AAC1E,MAAI,SAAS,IAAI,KAAK,OAAO,KAAK,OAAO,YAAY,KAAK,GAAG,KAAK,EAAE,SAAS,GAAG;AAC9E,WAAO,KAAK;AAAA,EACd;AAEA,SAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,uBAAuB,KAA4B;AAC1D,QAAM,OAAoB,CAAC;AAC3B,aAAW,CAAC,OAAO,EAAE,KAAK,IAAI,QAAQ,GAAG;AACvC,SAAK,EAAE,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAIA,SAAS,0BAA0B,aAA+C;AAEhF,SAAO,EAAE,OAAO,YAAY;AAC9B;AAEO,IAAK,kBAAL,kBAAKA,qBAAL;AACL,EAAAA,iBAAA,UAAO;AACP,EAAAA,iBAAA,QAAK;AACL,EAAAA,iBAAA,UAAO;AAHG,SAAAA;AAAA,GAAA;AAML,SAAS,MAAM,OAAe,YAAoB,YAA4B;AACnF,SAAO,KAAK,IAAI,KAAK,IAAI,OAAO,UAAU,GAAG,UAAU;AACzD;AAEO,SAAS,WAAW,QAAqB,MAAc,IAAyB;AACrF,QAAM,UAAU,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,MAAM,MAAM,SAAS,MAAM;AACvF,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,SAAS,CAAC;AAClD,QAAM,SAAS,MAAM,IAAI,GAAG,QAAQ,SAAS,CAAC;AAC9C,QAAM,CAAC,KAAK,IAAI,QAAQ,OAAO,UAAU,CAAC;AAC1C,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,UAAQ,OAAO,QAAQ,GAAG,KAAK;AAE/B,QAAM,OAAoB,CAAC;AAC3B,aAAW,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,QAAQ,QAAQ,GAAG;AAC7C,SAAK,EAAE,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAEO,SAAS,aAAuC,MAAwB;AAC7E,QAAM,OAAoB,CAAC;AAC3B,aAAW,CAAC,OAAO,IAAI,KAAK,KAAK,QAAQ,GAAG;AAC1C,SAAK,KAAK,EAAE,IAAI;AAAA,EAClB;AACA,SAAO;AACT;AAEO,SAAS,YACd,WACA,YACA,WACA,IACA,YACM;AACN,MAAI,CAAC,MAAM,cAAc,KAAK,cAAc,GAAG;AAC7C;AAAA,EACF;AAEA,QAAM,mBAAmB,cAAc,SAAS;AAChD,QAAM,OAAO,iBAAiB,EAAE;AAChC,MAAI,OAAO,SAAS,UAAU;AAC5B;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,KAAK,MAAM,YAAY,UAAU,GAAG,GAAG,aAAa,CAAC;AAChF,iBAAe,WAAW,WAAW,kBAAkB,MAAM,YAAY,CAAC;AAC5E;AAEO,SAAS,cACd,WACA,YACA,YACA,iBACA,YACM;AACN,MAAI,aAAa,aAAa,iBAAiB;AAC7C,qBAAiB,YAAY,aAAkB;AAC/C;AAAA,EACF;AAEA,MAAI,aAAa,aAAa,iBAAiB;AAC7C,qBAAiB,YAAY,iBAAoB;AACjD;AAAA,EACF;AAEA,mBAAiB,YAAY,iBAAoB;AACnD;AAgBA,SAAS,eAAe,EAAE,UAAU,MAAM,GAA2C;AACnF,SAAO,oBAAC,QAAK,OAAe,UAAS;AACvC;AAEA,SAAS,iBAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4C;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,iBAAiB,OAAuC,IAAI;AAClE,QAAM,oBAAoB,OAA0C,IAAI;AACxE,QAAM,eAAe,OAAyB,EAAE,MAAM,MAAM,IAAI,KAAK,CAAC;AACtE,QAAM,UAAU,aAAa;AAE7B,QAAM,iBAAiB,YAAY,MAAM;AACvC,UAAM,YAAY,aAAa;AAC/B,QAAI,CAAC,UAAW;AAEhB,UAAM,cAAc,aAAa,QAAQ;AACzC,QAAI,aAAa;AACf,gBAAU,oBAAoB,eAAe,WAAW;AAAA,IAC1D;AAEA,UAAM,YAAY,aAAa,QAAQ;AACvC,QAAI,WAAW;AACb,gBAAU,oBAAoB,aAAa,SAAS;AACpD,gBAAU,oBAAoB,iBAAiB,SAAS;AAAA,IAC1D;AAEA,iBAAa,UAAU,EAAE,MAAM,MAAM,IAAI,KAAK;AAAA,EAChD,GAAG,CAAC,CAAC;AAEL,QAAM,iBAAiB,YAAY,MAAM;AACvC,mBAAe,UAAU;AACzB,sBAAkB,UAAU;AAC5B,kBAAc,KAAK;AACnB,mBAAe;AAAA,EACjB,GAAG,CAAC,cAAc,CAAC;AAEnB,YAAU,MAAM;AACd,WAAO,MAAM;AACX,qBAAe;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,mBAAmB;AAAA,IACvB,CAAC,UAAkB;AACjB,YAAM,OAAO,eAAe;AAC5B,UAAI,CAAC,QAAQ,WAAW,EAAG;AAE3B,YAAM,KAAK,QAAQ,KAAK;AACxB,YAAM,YAAY,KAAK,MAAM,KAAK,OAAO;AACzC,YAAM,aAAa,MAAM,KAAK,cAAc,WAAW,GAAG,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC;AACrF,UAAI,eAAe,KAAK,aAAa;AACnC,aAAK,cAAc;AACnB,qBAAa,IAAI,MAAM,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA,IACA,CAAC,IAAI,YAAY,YAAY,OAAO;AAAA,EACtC;AAEA,QAAM,aAAa,YAAY,MAAM;AACnC,UAAM,OAAO,eAAe;AAC5B,QAAI,CAAC,MAAM;AACT,qBAAe;AACf;AAAA,IACF;AAEA,QAAI,KAAK,gBAAgB,KAAK,aAAa;AACzC,YAAM,mBAAmB,cAAc,SAAS;AAChD,YAAM,OAAO,iBAAiB,EAAE;AAChC,UAAI,OAAO,SAAS,UAAU;AAC5B,uBAAe,WAAW,WAAW,kBAAkB,MAAM,KAAK,WAAW,CAAC;AAAA,MAChF;AAEA,eAAS,IAAI,KAAK,aAAa,KAAK,WAAW;AAC/C,eAAS,IAAI,KAAK,WAAW;AAAA,IAC/B;AAEA,mBAAe;AAAA,EACjB,GAAG,CAAC,IAAI,QAAQ,QAAQ,WAAW,cAAc,CAAC;AAElD,QAAM,gBAAgB;AAAA,IACpB,CAAC,UAA4B;AAC3B,YAAM,YAAY,aAAa;AAC/B,UAAI,CAAC,UAAW;AAEhB,YAAM,cAAc,cAAc,SAAS,EAAE,EAAE,KAAK;AACpD,wBAAkB,UAAU;AAAA,QAC1B,WAAW,MAAM;AAAA,QACjB;AAAA,QACA,YAAY,MAAM;AAAA,QAClB,YAAY,MAAM;AAAA,MACpB;AAEA,YAAM,aAAa,CAAC,cAAgC;AAClD,cAAM,OAAO,eAAe;AAC5B,YAAI,MAAM;AACR,cAAI,KAAK,cAAc,UAAU,UAAW;AAC5C,2BAAiB,UAAU,KAAK;AAChC;AAAA,QACF;AAEA,cAAM,UAAU,kBAAkB;AAClC,YAAI,SAAS,cAAc,UAAU,UAAW;AAEhD,cAAM,KAAK,UAAU,QAAQ,QAAQ;AACrC,cAAM,KAAK,UAAU,QAAQ,QAAQ;AACrC,YAAI,EAAE,KAAK,IAAI,EAAE,IAAI,kBAAkB,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,IAAI;AACnE;AAAA,QACF;AAEA,uBAAe,UAAU;AAAA,UACvB,WAAW,QAAQ;AAAA,UACnB,aAAa,QAAQ;AAAA,UACrB,aAAa,QAAQ;AAAA,UACrB,YAAY,QAAQ;AAAA,QACtB;AACA,0BAAkB,UAAU;AAC5B,sBAAc,IAAI;AAClB,sBAAc,IAAI,eAAe,QAAQ,WAAW;AACpD,yBAAiB,UAAU,KAAK;AAAA,MAClC;AAEA,YAAM,WAAW,CAAC,YAA8B;AAC9C,cAAM,OAAO,eAAe;AAC5B,YAAI,MAAM;AACR,cAAI,KAAK,cAAc,QAAQ,UAAW;AAC1C,qBAAW;AACX;AAAA,QACF;AAEA,cAAM,UAAU,kBAAkB;AAClC,YAAI,SAAS,cAAc,QAAQ,WAAW;AAC5C,4BAAkB,UAAU;AAC5B,yBAAe;AAAA,QACjB;AAAA,MACF;AAEA,qBAAe;AACf,mBAAa,UAAU,EAAE,MAAM,YAAY,IAAI,SAAS;AACxD,gBAAU,iBAAiB,eAAe,UAAU;AACpD,gBAAU,iBAAiB,aAAa,QAAQ;AAChD,gBAAU,iBAAiB,iBAAiB,QAAQ;AAAA,IACtD;AAAA,IACA,CAAC,gBAAgB,YAAY,IAAI,aAAa,WAAW,gBAAgB;AAAA,EAC3E;AAEA,QAAM,oBAAoB;AAAA,IACxB,CAAC,UAAuD;AACtD,YAAM,EAAE,YAAY,IAAI;AACxB,UAAI,CAAC,YAAa;AAElB,UAAI,OAAO,YAAY,WAAW,YAAY,YAAY,WAAW,GAAG;AACtE;AAAA,MACF;AAEA,YAAM,EAAE,UAAU,IAAI;AACtB,YAAM,EAAE,MAAM,IAAI;AAClB,YAAM,EAAE,MAAM,IAAI;AAElB,UAAI,OAAO,cAAc,YAAY,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC3F;AAAA,MACF;AAEA,oBAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,YAAY;AAAA,MACtB,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAe;AAAA,MACf,OAAO;AAAA,QACL,aAAa,IAAI,EAAE,QAAQ,WAAW,IAAI;AAAA,QAC1C;AAAA,QACA,aAAa,UAAU,WAAW;AAAA,MACpC;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEO,MAAM,eAAe,OAAO,OAAO,kBAAkB;AAAA,EAC1D,QAAQ;AACV,CAAC;AAED,SAAS,aAAoB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4C;AAC1C,QAAM,eAAe,oBAAoB;AACzC,QAAM,MAAM;AAAA,IACV,MAAM,KAAK,IAAI,CAAC,MAAM,UAAU,aAAa,MAAM,KAAK,CAAC;AAAA,IACzD,CAAC,MAAM,YAAY;AAAA,EACrB;AACA,QAAM,YAAY,QAAQ,MAAM,0BAA0B,uBAAuB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;AAE7F,QAAM,qBAAqB;AAAA,IACzB,CAAC,MAAa,UAAkB;AAC9B,YAAM,KAAK,IAAI,KAAK,KAAK,aAAa,MAAM,KAAK;AACjD,YAAM,eAAe,OAAO;AAC5B,YAAM,cAA8C;AAAA,QAClD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY,KAAK;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,QAAQ,KAAK,SAAS,KAAK,eAAe,IAAI,EAAE,aAAa,IAAI;AAAA,UAEvE,qBAAW,WAAW;AAAA;AAAA,QAHlB;AAAA,MAIP;AAAA,IAEJ;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SACE,oBAAC,QAAK,OACJ,8BAAC,QAAK,OAAO,uBAAwB,eAAK,IAAI,kBAAkB,GAAE,GACpE;AAEJ;AAEO,MAAM,WAAW,KAAK,YAAY;AAMlC,SAAS,aAAa,EAAE,SAAS,GAAyC;AAC/E,SAAO,gCAAG,UAAS;AACrB;AAEO,MAAM,YAAY,qBAA8C,WAAW;AAC3E,MAAM,YAAY,qBAA8C,WAAW;AAC3E,MAAM,eAAe,oBAAiD,cAAc;AACpF,MAAM,eAAe,oBAAiD,cAAc;AACpF,MAAM,cAAc,oBAAiD,aAAa;AAClF,MAAM,kBAAkB,oBAAiD,iBAAiB;AAEjG,MAAM,YAAY,WAAW,OAAO;AAAA,EAClC,UAAU;AAAA,IACR,SAAS;AAAA,EACX;AACF,CAAC;","names":["ScrollDirection"]}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@ankhorage/react-native-reanimated-dnd-web",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "private": false,
6
+ "keywords": ["react-native", "drag-and-drop", "dnd", "expo", "react-native-web", "reanimated"],
7
+ "description": "Web adapter for react-native-reanimated-dnd with native passthrough and web-safe stubs.",
8
+ "type": "module",
9
+ "main": "dist/index.web.js",
10
+ "react-native": "dist/index.native.js",
11
+ "browser": "dist/index.web.js",
12
+ "types": "dist/index.d.ts",
13
+ "sideEffects": false,
14
+ "files": ["dist", "README.md", "LICENSE", "CHANGELOG.md"],
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "dependencies": {
19
+ "react-native-reanimated-dnd": "~1.1.0"
20
+ },
21
+ "peerDependencies": {
22
+ "react": ">=18",
23
+ "react-native": ">=0.73",
24
+ "react-native-gesture-handler": ">=2",
25
+ "react-native-reanimated": ">=3"
26
+ },
27
+ "peerDependenciesMeta": {
28
+ "react-native": {
29
+ "optional": true
30
+ },
31
+ "react-native-gesture-handler": {
32
+ "optional": true
33
+ },
34
+ "react-native-reanimated": {
35
+ "optional": true
36
+ }
37
+ },
38
+ "scripts": {
39
+ "build": "tsup --config tsup.config.ts && bun run build:assert-artifacts",
40
+ "build:assert-artifacts": "node ./scripts/assert-artifacts.mjs",
41
+ "release:validate-meta": "node ./scripts/verify-version-sync.mjs",
42
+ "lint": "eslint src --max-warnings=0",
43
+ "test": "bun test src --pass-with-no-tests",
44
+ "pack:smoke": "rm -rf .artifacts .npm-cache && mkdir -p .artifacts .npm-cache && NPM_CONFIG_CACHE=.npm-cache npm pack --pack-destination .artifacts . && node ./scripts/verify-pack.mjs .artifacts",
45
+ "release:check": "bun run release:validate-meta && bun run build && bun run test && bun run pack:smoke"
46
+ },
47
+ "devDependencies": {
48
+ "tsup": "^8.5.1",
49
+ "typescript": "^5.9.3"
50
+ }
51
+ }