react-native-reanimated-dnd 1.0.1
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 +21 -0
- package/README.md +633 -0
- package/lib/components/Draggable.d.ts +5 -0
- package/lib/components/Draggable.js +265 -0
- package/lib/components/Droppable.d.ts +264 -0
- package/lib/components/Droppable.js +284 -0
- package/lib/components/Sortable.d.ts +184 -0
- package/lib/components/Sortable.js +225 -0
- package/lib/components/SortableItem.d.ts +158 -0
- package/lib/components/SortableItem.js +251 -0
- package/lib/components/sortableUtils.d.ts +21 -0
- package/lib/components/sortableUtils.js +50 -0
- package/lib/context/DropContext.d.ts +118 -0
- package/lib/context/DropContext.js +233 -0
- package/lib/hooks/index.d.ts +4 -0
- package/lib/hooks/index.js +5 -0
- package/lib/hooks/useDraggable.d.ts +101 -0
- package/lib/hooks/useDraggable.js +567 -0
- package/lib/hooks/useDroppable.d.ts +129 -0
- package/lib/hooks/useDroppable.js +261 -0
- package/lib/hooks/useSortable.d.ts +174 -0
- package/lib/hooks/useSortable.js +361 -0
- package/lib/hooks/useSortableList.d.ts +182 -0
- package/lib/hooks/useSortableList.js +211 -0
- package/lib/index.d.ts +11 -0
- package/lib/index.js +16 -0
- package/lib/types/context.d.ts +166 -0
- package/lib/types/context.js +80 -0
- package/lib/types/draggable.d.ts +313 -0
- package/lib/types/draggable.js +31 -0
- package/lib/types/droppable.d.ts +197 -0
- package/lib/types/droppable.js +1 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/index.js +8 -0
- package/lib/types/sortable.d.ts +432 -0
- package/lib/types/sortable.js +6 -0
- package/package.json +59 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { useRef, useCallback } from "react";
|
|
2
|
+
import { scrollTo, useAnimatedReaction, useAnimatedRef, useAnimatedScrollHandler, useSharedValue, } from "react-native-reanimated";
|
|
3
|
+
import { listToObject } from "../components/sortableUtils";
|
|
4
|
+
import { ScrollDirection } from "../types/sortable";
|
|
5
|
+
/**
|
|
6
|
+
* A hook for managing sortable lists with drag-and-drop reordering capabilities.
|
|
7
|
+
*
|
|
8
|
+
* This hook provides the foundational state management and utilities needed to create
|
|
9
|
+
* sortable lists. It handles position tracking, scroll synchronization, auto-scrolling,
|
|
10
|
+
* and provides helper functions for individual sortable items.
|
|
11
|
+
*
|
|
12
|
+
* @template TData - The type of data items in the sortable list (must extend `{ id: string }`)
|
|
13
|
+
* @param options - Configuration options for the sortable list
|
|
14
|
+
* @returns Object containing shared values, refs, handlers, and utilities for the sortable list
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* Basic sortable list setup:
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { useSortableList } from './hooks/useSortableList';
|
|
20
|
+
* import { SortableItem } from './components/SortableItem';
|
|
21
|
+
*
|
|
22
|
+
* interface Task {
|
|
23
|
+
* id: string;
|
|
24
|
+
* title: string;
|
|
25
|
+
* completed: boolean;
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* function TaskList() {
|
|
29
|
+
* const [tasks, setTasks] = useState<Task[]>([
|
|
30
|
+
* { id: '1', title: 'Learn React Native', completed: false },
|
|
31
|
+
* { id: '2', title: 'Build an app', completed: false },
|
|
32
|
+
* { id: '3', title: 'Deploy to store', completed: false }
|
|
33
|
+
* ]);
|
|
34
|
+
*
|
|
35
|
+
* const {
|
|
36
|
+
* scrollViewRef,
|
|
37
|
+
* dropProviderRef,
|
|
38
|
+
* handleScroll,
|
|
39
|
+
* handleScrollEnd,
|
|
40
|
+
* contentHeight,
|
|
41
|
+
* getItemProps,
|
|
42
|
+
* } = useSortableList({
|
|
43
|
+
* data: tasks,
|
|
44
|
+
* itemHeight: 60,
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* return (
|
|
48
|
+
* <GestureHandlerRootView style={styles.container}>
|
|
49
|
+
* <DropProvider ref={dropProviderRef}>
|
|
50
|
+
* <Animated.ScrollView
|
|
51
|
+
* ref={scrollViewRef}
|
|
52
|
+
* onScroll={handleScroll}
|
|
53
|
+
* scrollEventThrottle={16}
|
|
54
|
+
* style={styles.scrollView}
|
|
55
|
+
* contentContainerStyle={{ height: contentHeight }}
|
|
56
|
+
* onScrollEndDrag={handleScrollEnd}
|
|
57
|
+
* onMomentumScrollEnd={handleScrollEnd}
|
|
58
|
+
* >
|
|
59
|
+
* {tasks.map((task, index) => {
|
|
60
|
+
* const itemProps = getItemProps(task, index);
|
|
61
|
+
* return (
|
|
62
|
+
* <SortableItem key={task.id} {...itemProps}>
|
|
63
|
+
* <View style={styles.taskItem}>
|
|
64
|
+
* <Text>{task.title}</Text>
|
|
65
|
+
* </View>
|
|
66
|
+
* </SortableItem>
|
|
67
|
+
* );
|
|
68
|
+
* })}
|
|
69
|
+
* </Animated.ScrollView>
|
|
70
|
+
* </DropProvider>
|
|
71
|
+
* </GestureHandlerRootView>
|
|
72
|
+
* );
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* Sortable list with custom key extractor:
|
|
78
|
+
* ```typescript
|
|
79
|
+
* interface CustomItem {
|
|
80
|
+
* uuid: string;
|
|
81
|
+
* name: string;
|
|
82
|
+
* order: number;
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* function CustomSortableList() {
|
|
86
|
+
* const [items, setItems] = useState<CustomItem[]>(data);
|
|
87
|
+
*
|
|
88
|
+
* const sortableListProps = useSortableList({
|
|
89
|
+
* data: items,
|
|
90
|
+
* itemHeight: 50,
|
|
91
|
+
* itemKeyExtractor: (item) => item.uuid, // Use uuid instead of id
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* const { getItemProps, ...otherProps } = sortableListProps;
|
|
95
|
+
*
|
|
96
|
+
* return (
|
|
97
|
+
* <SortableListContainer {...otherProps}>
|
|
98
|
+
* {items.map((item, index) => {
|
|
99
|
+
* const itemProps = getItemProps(item, index);
|
|
100
|
+
* return (
|
|
101
|
+
* <SortableItem key={item.uuid} {...itemProps}>
|
|
102
|
+
* <View style={styles.customItem}>
|
|
103
|
+
* <Text>{item.name}</Text>
|
|
104
|
+
* <Text>Order: {item.order}</Text>
|
|
105
|
+
* </View>
|
|
106
|
+
* </SortableItem>
|
|
107
|
+
* );
|
|
108
|
+
* })}
|
|
109
|
+
* </SortableListContainer>
|
|
110
|
+
* );
|
|
111
|
+
* }
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* Sortable list with reordering logic:
|
|
116
|
+
* ```typescript
|
|
117
|
+
* function ReorderableTaskList() {
|
|
118
|
+
* const [tasks, setTasks] = useState(initialTasks);
|
|
119
|
+
*
|
|
120
|
+
* const handleReorder = useCallback((id: string, from: number, to: number) => {
|
|
121
|
+
* setTasks(prevTasks => {
|
|
122
|
+
* const newTasks = [...prevTasks];
|
|
123
|
+
* const [movedTask] = newTasks.splice(from, 1);
|
|
124
|
+
* newTasks.splice(to, 0, movedTask);
|
|
125
|
+
* return newTasks;
|
|
126
|
+
* });
|
|
127
|
+
* }, []);
|
|
128
|
+
*
|
|
129
|
+
* const sortableProps = useSortableList({
|
|
130
|
+
* data: tasks,
|
|
131
|
+
* itemHeight: 80,
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* return (
|
|
135
|
+
* <SortableListContainer {...sortableProps}>
|
|
136
|
+
* {tasks.map((task, index) => {
|
|
137
|
+
* const itemProps = sortableProps.getItemProps(task, index);
|
|
138
|
+
* return (
|
|
139
|
+
* <SortableItem
|
|
140
|
+
* key={task.id}
|
|
141
|
+
* {...itemProps}
|
|
142
|
+
* onMove={handleReorder}
|
|
143
|
+
* >
|
|
144
|
+
* <TaskCard task={task} />
|
|
145
|
+
* </SortableItem>
|
|
146
|
+
* );
|
|
147
|
+
* })}
|
|
148
|
+
* </SortableListContainer>
|
|
149
|
+
* );
|
|
150
|
+
* }
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* @see {@link UseSortableListOptions} for configuration options
|
|
154
|
+
* @see {@link UseSortableListReturn} for return value details
|
|
155
|
+
* @see {@link useSortable} for individual item management
|
|
156
|
+
* @see {@link SortableItem} for component implementation
|
|
157
|
+
* @see {@link Sortable} for high-level sortable list component
|
|
158
|
+
* @see {@link DropProvider} for drag-and-drop context
|
|
159
|
+
*/
|
|
160
|
+
export function useSortableList(options) {
|
|
161
|
+
const { data, itemHeight, itemKeyExtractor = (item) => item.id } = options;
|
|
162
|
+
// Set up shared values
|
|
163
|
+
const positions = useSharedValue(listToObject(data));
|
|
164
|
+
const scrollY = useSharedValue(0);
|
|
165
|
+
const autoScroll = useSharedValue(ScrollDirection.None);
|
|
166
|
+
const scrollViewRef = useAnimatedRef();
|
|
167
|
+
const dropProviderRef = useRef(null);
|
|
168
|
+
// Scrolling synchronization
|
|
169
|
+
useAnimatedReaction(() => scrollY.value, (scrolling) => {
|
|
170
|
+
scrollTo(scrollViewRef, 0, scrolling, false);
|
|
171
|
+
});
|
|
172
|
+
// Handle scroll events
|
|
173
|
+
const handleScroll = useAnimatedScrollHandler((event) => {
|
|
174
|
+
scrollY.value = event.contentOffset.y;
|
|
175
|
+
});
|
|
176
|
+
const handleScrollEnd = useCallback(() => {
|
|
177
|
+
let localScrollTimeout = null;
|
|
178
|
+
if (localScrollTimeout) {
|
|
179
|
+
clearTimeout(localScrollTimeout);
|
|
180
|
+
}
|
|
181
|
+
localScrollTimeout = setTimeout(() => {
|
|
182
|
+
var _a;
|
|
183
|
+
(_a = dropProviderRef.current) === null || _a === void 0 ? void 0 : _a.requestPositionUpdate();
|
|
184
|
+
}, 50);
|
|
185
|
+
}, []);
|
|
186
|
+
// Calculate content height
|
|
187
|
+
const contentHeight = data.length * itemHeight;
|
|
188
|
+
// Helper to get props for each sortable item
|
|
189
|
+
const getItemProps = useCallback((item, index) => {
|
|
190
|
+
const id = itemKeyExtractor(item, index);
|
|
191
|
+
return {
|
|
192
|
+
id,
|
|
193
|
+
positions,
|
|
194
|
+
lowerBound: scrollY,
|
|
195
|
+
autoScrollDirection: autoScroll,
|
|
196
|
+
itemsCount: data.length,
|
|
197
|
+
itemHeight,
|
|
198
|
+
};
|
|
199
|
+
}, [data.length, itemHeight, itemKeyExtractor, positions, scrollY, autoScroll]);
|
|
200
|
+
return {
|
|
201
|
+
positions,
|
|
202
|
+
scrollY,
|
|
203
|
+
autoScroll,
|
|
204
|
+
scrollViewRef,
|
|
205
|
+
dropProviderRef,
|
|
206
|
+
handleScroll,
|
|
207
|
+
handleScrollEnd,
|
|
208
|
+
contentHeight,
|
|
209
|
+
getItemProps,
|
|
210
|
+
};
|
|
211
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { Draggable } from "./components/Draggable";
|
|
2
|
+
export { Droppable } from "./components/Droppable";
|
|
3
|
+
export { Sortable } from "./components/Sortable";
|
|
4
|
+
export { SortableItem } from "./components/SortableItem";
|
|
5
|
+
export { DropProvider } from "./context/DropContext";
|
|
6
|
+
export * from "./types";
|
|
7
|
+
export { listToObject, setAutoScroll, setPosition, clamp, objectMove, ScrollDirection, } from "./components/sortableUtils";
|
|
8
|
+
export { useDraggable } from "./hooks/useDraggable";
|
|
9
|
+
export { useDroppable } from "./hooks/useDroppable";
|
|
10
|
+
export { useSortable } from "./hooks/useSortable";
|
|
11
|
+
export { useSortableList } from "./hooks/useSortableList";
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Components
|
|
2
|
+
export { Draggable } from "./components/Draggable";
|
|
3
|
+
export { Droppable } from "./components/Droppable";
|
|
4
|
+
export { Sortable } from "./components/Sortable";
|
|
5
|
+
export { SortableItem } from "./components/SortableItem";
|
|
6
|
+
// Context
|
|
7
|
+
export { DropProvider } from "./context/DropContext";
|
|
8
|
+
// Types
|
|
9
|
+
export * from "./types";
|
|
10
|
+
// Utils
|
|
11
|
+
export { listToObject, setAutoScroll, setPosition, clamp, objectMove, ScrollDirection, } from "./components/sortableUtils";
|
|
12
|
+
// Hooks
|
|
13
|
+
export { useDraggable } from "./hooks/useDraggable";
|
|
14
|
+
export { useDroppable } from "./hooks/useDroppable";
|
|
15
|
+
export { useSortable } from "./hooks/useSortable";
|
|
16
|
+
export { useSortableList } from "./hooks/useSortableList";
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Alignment options for positioning dropped items within a droppable area.
|
|
4
|
+
*
|
|
5
|
+
* Determines where within the droppable bounds the draggable item will be positioned
|
|
6
|
+
* when successfully dropped. Can be combined with DropOffset for fine-tuning.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Center the dropped item (default)
|
|
11
|
+
* const centerAlignment: DropAlignment = 'center';
|
|
12
|
+
*
|
|
13
|
+
* // Position at top-left corner
|
|
14
|
+
* const topLeftAlignment: DropAlignment = 'top-left';
|
|
15
|
+
*
|
|
16
|
+
* // Position at bottom edge, centered horizontally
|
|
17
|
+
* const bottomCenterAlignment: DropAlignment = 'bottom-center';
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @see {@link DropOffset} for additional positioning control
|
|
21
|
+
* @see {@link UseDroppableOptions} for usage in droppables
|
|
22
|
+
*/
|
|
23
|
+
export type DropAlignment = "center" | "top-left" | "top-center" | "top-right" | "center-left" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
24
|
+
/**
|
|
25
|
+
* Pixel offset to apply after alignment positioning.
|
|
26
|
+
*
|
|
27
|
+
* Provides fine-grained control over the exact position where dropped items
|
|
28
|
+
* are placed within a droppable area. Applied after the DropAlignment calculation.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* // No offset (default)
|
|
33
|
+
* const noOffset: DropOffset = { x: 0, y: 0 };
|
|
34
|
+
*
|
|
35
|
+
* // Move 10px right and 5px down from aligned position
|
|
36
|
+
* const customOffset: DropOffset = { x: 10, y: 5 };
|
|
37
|
+
*
|
|
38
|
+
* // Move 20px left from aligned position
|
|
39
|
+
* const leftOffset: DropOffset = { x: -20, y: 0 };
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @see {@link DropAlignment} for base positioning
|
|
43
|
+
* @see {@link UseDroppableOptions} for usage in droppables
|
|
44
|
+
*/
|
|
45
|
+
export interface DropOffset {
|
|
46
|
+
/** Horizontal offset in pixels (positive = right, negative = left) */
|
|
47
|
+
x: number;
|
|
48
|
+
/** Vertical offset in pixels (positive = down, negative = up) */
|
|
49
|
+
y: number;
|
|
50
|
+
}
|
|
51
|
+
export interface DroppedItemsMap<TData = unknown> {
|
|
52
|
+
[draggableId: string]: {
|
|
53
|
+
droppableId: string;
|
|
54
|
+
data: TData;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export interface DropSlot<TData = unknown> {
|
|
58
|
+
id: string;
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
width: number;
|
|
62
|
+
height: number;
|
|
63
|
+
onDrop: (data: TData) => void;
|
|
64
|
+
dropAlignment?: DropAlignment;
|
|
65
|
+
dropOffset?: DropOffset;
|
|
66
|
+
capacity?: number;
|
|
67
|
+
}
|
|
68
|
+
export type PositionUpdateListener = () => void;
|
|
69
|
+
export interface SlotsContextValue<TData = unknown> {
|
|
70
|
+
register: (id: number, slot: DropSlot<TData>) => void;
|
|
71
|
+
unregister: (id: number) => void;
|
|
72
|
+
getSlots: () => Record<number, DropSlot<TData>>;
|
|
73
|
+
isRegistered: (id: number) => boolean;
|
|
74
|
+
setActiveHoverSlot: (id: number | null) => void;
|
|
75
|
+
activeHoverSlotId: number | null;
|
|
76
|
+
registerPositionUpdateListener: (id: string, listener: PositionUpdateListener) => void;
|
|
77
|
+
unregisterPositionUpdateListener: (id: string) => void;
|
|
78
|
+
requestPositionUpdate: () => void;
|
|
79
|
+
registerDroppedItem: (draggableId: string, droppableId: string, itemData: any) => void;
|
|
80
|
+
unregisterDroppedItem: (draggableId: string) => void;
|
|
81
|
+
getDroppedItems: () => DroppedItemsMap<any>;
|
|
82
|
+
hasAvailableCapacity: (droppableId: string) => boolean;
|
|
83
|
+
onDragging?: (payload: {
|
|
84
|
+
x: number;
|
|
85
|
+
y: number;
|
|
86
|
+
tx: number;
|
|
87
|
+
ty: number;
|
|
88
|
+
itemData: any;
|
|
89
|
+
}) => void;
|
|
90
|
+
onDragStart?: (data: any) => void;
|
|
91
|
+
onDragEnd?: (data: any) => void;
|
|
92
|
+
}
|
|
93
|
+
export declare const SlotsContext: import("react").Context<SlotsContextValue<any>>;
|
|
94
|
+
/**
|
|
95
|
+
* Props for the DropProvider component.
|
|
96
|
+
*
|
|
97
|
+
* @see {@link DropProvider} for component usage
|
|
98
|
+
*/
|
|
99
|
+
export interface DropProviderProps {
|
|
100
|
+
/** The child components that will have access to the drag-and-drop context */
|
|
101
|
+
children: ReactNode;
|
|
102
|
+
/**
|
|
103
|
+
* Callback fired when layout updates are complete.
|
|
104
|
+
* Useful for triggering additional UI updates after position recalculations.
|
|
105
|
+
*/
|
|
106
|
+
onLayoutUpdateComplete?: () => void;
|
|
107
|
+
/**
|
|
108
|
+
* Callback fired when the dropped items mapping changes.
|
|
109
|
+
* Provides access to the current state of which items are dropped where.
|
|
110
|
+
*
|
|
111
|
+
* @param droppedItems - Current mapping of draggable IDs to their drop locations
|
|
112
|
+
*/
|
|
113
|
+
onDroppedItemsUpdate?: (droppedItems: DroppedItemsMap) => void;
|
|
114
|
+
/**
|
|
115
|
+
* Global callback fired during drag operations.
|
|
116
|
+
* Receives position updates for all draggable items.
|
|
117
|
+
*
|
|
118
|
+
* @param payload - Position and data information for the dragging item
|
|
119
|
+
*/
|
|
120
|
+
onDragging?: (payload: {
|
|
121
|
+
x: number;
|
|
122
|
+
y: number;
|
|
123
|
+
tx: number;
|
|
124
|
+
ty: number;
|
|
125
|
+
itemData: any;
|
|
126
|
+
}) => void;
|
|
127
|
+
/**
|
|
128
|
+
* Global callback fired when any drag operation starts.
|
|
129
|
+
* @param data - The data associated with the draggable item
|
|
130
|
+
*/
|
|
131
|
+
onDragStart?: (data: any) => void;
|
|
132
|
+
/**
|
|
133
|
+
* Global callback fired when any drag operation ends.
|
|
134
|
+
* @param data - The data associated with the draggable item
|
|
135
|
+
*/
|
|
136
|
+
onDragEnd?: (data: any) => void;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Imperative handle interface for the DropProvider component.
|
|
140
|
+
* Provides methods that can be called on the DropProvider ref.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* const dropProviderRef = useRef<DropProviderRef>(null);
|
|
145
|
+
*
|
|
146
|
+
* // Trigger position update
|
|
147
|
+
* dropProviderRef.current?.requestPositionUpdate();
|
|
148
|
+
*
|
|
149
|
+
* // Get current dropped items
|
|
150
|
+
* const droppedItems = dropProviderRef.current?.getDroppedItems();
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* @see {@link DropProvider} for component usage
|
|
154
|
+
*/
|
|
155
|
+
export interface DropProviderRef {
|
|
156
|
+
/**
|
|
157
|
+
* Manually trigger a position update for all registered droppables and draggables.
|
|
158
|
+
* Useful after layout changes or when positions may have become stale.
|
|
159
|
+
*/
|
|
160
|
+
requestPositionUpdate: () => void;
|
|
161
|
+
/**
|
|
162
|
+
* Get the current mapping of dropped items.
|
|
163
|
+
* @returns Object mapping draggable IDs to their drop information
|
|
164
|
+
*/
|
|
165
|
+
getDroppedItems: () => DroppedItemsMap;
|
|
166
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Define DropAlignment and DropOffset types here
|
|
2
|
+
import { createContext } from "react";
|
|
3
|
+
// Default context value using 'any' for broad compatibility
|
|
4
|
+
const defaultSlotsContextValue = {
|
|
5
|
+
register: (_id, _slot) => {
|
|
6
|
+
if (process.env.NODE_ENV !== "production") {
|
|
7
|
+
console.warn("SlotsContext: register called without a Provider.");
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
unregister: (_id) => {
|
|
11
|
+
if (process.env.NODE_ENV !== "production") {
|
|
12
|
+
console.warn("SlotsContext: unregister called without a Provider.");
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
getSlots: () => {
|
|
16
|
+
if (process.env.NODE_ENV !== "production") {
|
|
17
|
+
console.warn("SlotsContext: getSlots called without a Provider.");
|
|
18
|
+
}
|
|
19
|
+
return {};
|
|
20
|
+
},
|
|
21
|
+
isRegistered: (_id) => {
|
|
22
|
+
if (process.env.NODE_ENV !== "production") {
|
|
23
|
+
console.warn("SlotsContext: isRegistered called without a Provider.");
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
},
|
|
27
|
+
setActiveHoverSlot: (_id) => {
|
|
28
|
+
if (process.env.NODE_ENV !== "production") {
|
|
29
|
+
console.warn("SlotsContext: setActiveHoverSlot called without a Provider.");
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
activeHoverSlotId: null,
|
|
33
|
+
registerPositionUpdateListener: (_id, _listener) => {
|
|
34
|
+
if (process.env.NODE_ENV !== "production") {
|
|
35
|
+
console.warn("SlotsContext: registerPositionUpdateListener called without a Provider.");
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
unregisterPositionUpdateListener: (_id) => {
|
|
39
|
+
if (process.env.NODE_ENV !== "production") {
|
|
40
|
+
console.warn("SlotsContext: unregisterPositionUpdateListener called without a Provider.");
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
requestPositionUpdate: () => {
|
|
44
|
+
if (process.env.NODE_ENV !== "production") {
|
|
45
|
+
console.warn("SlotsContext: requestPositionUpdate called without a Provider (internally).");
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
// Update default implementations
|
|
49
|
+
registerDroppedItem: (_draggableId, _droppableId, _itemData) => {
|
|
50
|
+
if (process.env.NODE_ENV !== "production") {
|
|
51
|
+
console.warn("SlotsContext: registerDroppedItem called without a Provider.");
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
unregisterDroppedItem: (_draggableId) => {
|
|
55
|
+
if (process.env.NODE_ENV !== "production") {
|
|
56
|
+
console.warn("SlotsContext: unregisterDroppedItem called without a Provider.");
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
getDroppedItems: () => {
|
|
60
|
+
if (process.env.NODE_ENV !== "production") {
|
|
61
|
+
console.warn("SlotsContext: getDroppedItems called without a Provider.");
|
|
62
|
+
}
|
|
63
|
+
return {};
|
|
64
|
+
},
|
|
65
|
+
hasAvailableCapacity: (_droppableId) => {
|
|
66
|
+
if (process.env.NODE_ENV !== "production") {
|
|
67
|
+
console.warn("SlotsContext: hasAvailableCapacity called without a Provider.");
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
},
|
|
71
|
+
onDragging: (payload) => {
|
|
72
|
+
if (process.env.NODE_ENV !== "production") {
|
|
73
|
+
console.warn("SlotsContext: onDragging called without a Provider.");
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
onDragStart: undefined,
|
|
77
|
+
onDragEnd: undefined,
|
|
78
|
+
};
|
|
79
|
+
// Create the context
|
|
80
|
+
export const SlotsContext = createContext(defaultSlotsContextValue);
|