Skip to content

Commit 34c4f15

Browse files
committed
feat(DraggableStack): expose refreshOffsets method
1 parent 4581bfd commit 34c4f15

File tree

3 files changed

+85
-54
lines changed

3 files changed

+85
-54
lines changed

example/src/App.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ import {DraggableGridExample} from './pages/DraggableGridExample';
44
import {DraggableStackExample} from './pages/DraggableStackExample';
55
import {DraggableBasicExample} from './pages/DraggableBasicExample';
66
import {SafeAreaView, StyleSheet} from 'react-native';
7+
import {configureReanimatedLogger} from 'react-native-reanimated';
8+
9+
// This is the default configuration
10+
configureReanimatedLogger({
11+
// level: ReanimatedLogLevel.warn,
12+
strict: false, // Reanimated runs in strict mode by default
13+
});
714

815
export const App: FunctionComponent = () => {
916
return (

example/src/pages/DraggableStackExample.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,14 @@ import {
22
DndProvider,
33
Draggable,
44
DraggableStack,
5-
UniqueIdentifier,
5+
type DraggableStackHandle,
6+
type UniqueIdentifier,
67
type DraggableStackProps,
78
type ObjectWithId,
89
} from '@mgcrea/react-native-dnd/src';
910
import React, {useCallback, useState, type FunctionComponent} from 'react';
1011
import {Button, StyleSheet, Text, View} from 'react-native';
11-
import {configureReanimatedLogger} from 'react-native-reanimated';
12-
13-
// This is the default configuration
14-
configureReanimatedLogger({
15-
// level: ReanimatedLogLevel.warn,
16-
strict: false, // Reanimated runs in strict mode by default
17-
});
12+
import {runOnUI} from 'react-native-reanimated';
1813

1914
const items = ['🤓', '🤖🤖', '👻👻👻', '👾👾👾👾'];
2015
const data = items.map((letter, index) => ({
@@ -25,13 +20,13 @@ const data = items.map((letter, index) => ({
2520
export const DraggableStackExample: FunctionComponent = () => {
2621
const [items, setItems] = useState(data);
2722
const [fontSize, setFontSize] = useState(32);
23+
const ref = React.useRef<DraggableStackHandle>(null);
2824

2925
const onStackOrderChange: DraggableStackProps['onOrderChange'] = useCallback(
3026
(order: UniqueIdentifier[]) => {
3127
console.log('onStackOrderChange', order);
3228
setTimeout(() => {
3329
// setItems(items => order.map(id => items.find(item => item.id === id)!));
34-
// setFontSize(fontSize => fontSize + 1);
3530
}, 1000);
3631
},
3732
[],
@@ -49,7 +44,8 @@ export const DraggableStackExample: FunctionComponent = () => {
4944
gap={10}
5045
style={styles.stack}
5146
onOrderChange={onStackOrderChange}
52-
onOrderUpdate={onStackOrderUpdate}>
47+
onOrderUpdate={onStackOrderUpdate}
48+
ref={ref}>
5349
{items.map(letter => (
5450
<Draggable
5551
key={letter.id}
@@ -85,16 +81,24 @@ export const DraggableStackExample: FunctionComponent = () => {
8581
/>
8682

8783
<Button
88-
title="Plus"
84+
title="Increase size"
8985
onPress={() => {
9086
setFontSize(prevFontSize => prevFontSize + 1);
87+
if (ref.current) {
88+
const {refreshOffsets} = ref.current;
89+
runOnUI(refreshOffsets)();
90+
}
9191
}}
9292
/>
9393

9494
<Button
95-
title="Minus"
95+
title="Decrease size"
9696
onPress={() => {
9797
setFontSize(prevFontSize => prevFontSize - 1);
98+
if (ref.current) {
99+
const {refreshOffsets} = ref.current;
100+
runOnUI(refreshOffsets)();
101+
}
98102
}}
99103
/>
100104
</View>
Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import React, { useEffect, useMemo, type FunctionComponent, type PropsWithChildren } from "react";
1+
import React, {
2+
forwardRef,
3+
useEffect,
4+
useImperativeHandle,
5+
useMemo,
6+
type FunctionComponent,
7+
type PropsWithChildren,
8+
} from "react";
29
import { type FlexStyle, type ViewProps } from "react-native";
310
import Animated, { runOnUI } from "react-native-reanimated";
411
import { useChildrenIds } from "../../../hooks";
@@ -10,44 +17,57 @@ export type DraggableStackProps = Pick<ViewProps, "style"> &
1017
gap?: number;
1118
};
1219

13-
export const DraggableStack: FunctionComponent<PropsWithChildren<DraggableStackProps>> = ({
14-
children,
15-
direction = "row",
16-
gap = 0,
17-
onOrderChange,
18-
onOrderUpdate,
19-
shouldSwapWorklet,
20-
style: styleProp,
21-
}) => {
22-
const initialOrder = useChildrenIds(children);
23-
24-
const style = useMemo(
25-
() =>
26-
Object.assign(
27-
{
28-
flexDirection: direction,
29-
gap,
30-
},
31-
styleProp,
32-
),
33-
[gap, direction, styleProp],
34-
);
35-
36-
const horizontal = ["row", "row-reverse"].includes(style.flexDirection);
37-
38-
const { refreshOffsets } = useDraggableStack({
39-
gap: style.gap,
40-
horizontal,
41-
initialOrder,
42-
onOrderChange,
43-
onOrderUpdate,
44-
shouldSwapWorklet,
45-
});
46-
47-
useEffect(() => {
48-
// Refresh offsets when children change
49-
runOnUI(refreshOffsets)();
50-
}, [initialOrder, refreshOffsets]);
51-
52-
return <Animated.View style={style}>{children}</Animated.View>;
53-
};
20+
export type DraggableStackHandle = Pick<ReturnType<typeof useDraggableStack>, "refreshOffsets">;
21+
22+
export const DraggableStack = forwardRef<DraggableStackHandle, PropsWithChildren<DraggableStackProps>>(
23+
function DraggableStack(
24+
{
25+
children,
26+
direction = "row",
27+
gap = 0,
28+
onOrderChange,
29+
onOrderUpdate,
30+
shouldSwapWorklet,
31+
style: styleProp,
32+
},
33+
ref,
34+
) {
35+
const initialOrder = useChildrenIds(children);
36+
37+
const style = useMemo(
38+
() =>
39+
Object.assign(
40+
{
41+
flexDirection: direction,
42+
gap,
43+
},
44+
styleProp,
45+
),
46+
[gap, direction, styleProp],
47+
);
48+
49+
const horizontal = ["row", "row-reverse"].includes(style.flexDirection);
50+
51+
const { refreshOffsets } = useDraggableStack({
52+
gap: style.gap,
53+
horizontal,
54+
initialOrder,
55+
onOrderChange,
56+
onOrderUpdate,
57+
shouldSwapWorklet,
58+
});
59+
60+
useImperativeHandle(ref, () => {
61+
return {
62+
refreshOffsets,
63+
};
64+
}, [refreshOffsets]);
65+
66+
useEffect(() => {
67+
// Refresh offsets when children change
68+
runOnUI(refreshOffsets)();
69+
}, [initialOrder, refreshOffsets]);
70+
71+
return <Animated.View style={style}>{children}</Animated.View>;
72+
},
73+
);

0 commit comments

Comments
 (0)