Skip to content

Commit fb69481

Browse files
1 parent a15e0ed commit fb69481

File tree

4 files changed

+318
-47
lines changed

4 files changed

+318
-47
lines changed

Diff for: packages/docs-reanimated/docs/advanced/dispatchCommand.mdx

+58-47
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,82 @@ sidebar_position: 7
44

55
# dispatchCommand
66

7-
import DocsCompatibilityInfo from '../_shared/_docs_compatibility_info.mdx';
7+
import DispatchCommandSrc from '!!raw-loader!@site/src/examples/DispatchCommand';
88

9-
<DocsCompatibilityInfo />
9+
`dispatchCommand` allows you to run commands on a native component from the UI thread directly.
1010

11-
Allows to dispatch command on a native component synchronously from the UI thread.
11+
## Reference
12+
13+
```javascript
14+
import { dispatchCommand } from 'react-native-reanimated';
15+
16+
function App() {
17+
const animatedRef = useAnimatedRef();
18+
19+
const gesture = Gesture.Tap().onStart(() => {
20+
// highlight-next-line
21+
dispatchCommand(animatedRef, 'focus');
22+
});
23+
24+
return (
25+
<>
26+
<AnimatedTextInput ref={animatedRef} style={styles.input} />
27+
<GestureDetector gesture={gesture}>
28+
<Button title="Focus" />
29+
</GestureDetector>
30+
</>
31+
);
32+
}
33+
```
34+
35+
<details>
36+
<summary>Type definitions</summary>
37+
38+
```typescript
39+
function dispatchCommand<T extends Component>(
40+
animatedRef: AnimatedRef<T>,
41+
commandName: string,
42+
args?: unknown[]
43+
) => void;
44+
```
45+
46+
</details>
1247

1348
### Arguments
1449

1550
#### `animatedRef`
1651

17-
The product of [`useAnimatedRef`](/docs/core/useAnimatedRef) which is Reanimated's extension of a standard React ref (delivers the view tag on the UI thread).
52+
An [animated ref](/docs/core/useAnimatedRef#returns) connected to the component you'd want to update. The animated ref has to be passed either to an [Animated component](/docs/fundamentals/glossary#animated-component) or a React Native built-in component.
1853

19-
#### `commandName` [String]
54+
#### `commandName`
2055

21-
The name of the command to execute, e.g. `focus` or `scrollToEnd`.
56+
The name of the command to execute, e.g. `'focus'` or `'scrollToEnd'`.
2257

23-
#### `args` [Array<any\>]
58+
#### `args` <Optional />
2459

2560
The array of command arguments. Defaults to an empty array.
2661

27-
### Returns
62+
## Example
2863

29-
`void`
64+
<ExampleVideo
65+
sources={{
66+
android: '/react-native-reanimated/recordings/dispatchCommand_android.mov',
67+
ios: '/react-native-reanimated/recordings/dispatchCommand_ios.mov',
68+
}}
69+
/>
3070

31-
### Example
71+
<CollapsibleCode src={DispatchCommandSrc} showLines={[29, 32]} />
3272

33-
```ts
34-
import Animated, {
35-
dispatchCommand,
36-
useAnimatedRef,
37-
} from 'react-native-reanimated';
38-
import { Button, StyleSheet, TextInput, View } from 'react-native';
39-
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
73+
## Remarks
4074

41-
import React from 'react';
75+
- Commands differ from component to component. Check relevant sources i.e. React Native documentation on [components](https://reactnative.dev/docs/components-and-apis) to see which commands are available.
4276

43-
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
77+
## Platform compatibility
4478

45-
export default function DispatchCommandExample() {
46-
const aref = useAnimatedRef<TextInput>();
79+
<div className="platform-compatibility">
4780

48-
const gesture = Gesture.Tap().onStart(() => {
49-
dispatchCommand(aref, 'focus');
50-
});
81+
| Android | iOS | Web |
82+
| ------- | --- | --- |
83+
||||
5184

52-
return (
53-
<View style={styles.container}>
54-
<AnimatedTextInput ref={aref} style={styles.input} />
55-
<GestureDetector gesture={gesture}>
56-
<Button title="Focus" />
57-
</GestureDetector>
58-
</View>
59-
);
60-
}
61-
62-
const styles = StyleSheet.create({
63-
container: {
64-
flex: 1,
65-
alignItems: 'center',
66-
justifyContent: 'center',
67-
},
68-
input: {
69-
borderWidth: 1,
70-
width: 200,
71-
padding: 5,
72-
},
73-
});
74-
```
85+
</div>
+260
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
import Animated, {
2+
dispatchCommand,
3+
useAnimatedRef,
4+
} from 'react-native-reanimated';
5+
import {
6+
SafeAreaView,
7+
StyleSheet,
8+
TextInput,
9+
View,
10+
Text,
11+
Alert,
12+
Pressable,
13+
} from 'react-native';
14+
import {
15+
Gesture,
16+
GestureDetector,
17+
GestureHandlerRootView,
18+
} from 'react-native-gesture-handler';
19+
import React, { useState } from 'react';
20+
21+
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
22+
23+
export default function LoginFormExample() {
24+
const tosRef = useAnimatedRef();
25+
const loginRef = useAnimatedRef();
26+
27+
const [login, setLogin] = useState('');
28+
const [password, setPassword] = useState('');
29+
30+
const goDown = Gesture.Tap().onStart(() => {
31+
dispatchCommand(tosRef, 'scrollToEnd', [true]);
32+
dispatchCommand(loginRef, 'focus');
33+
});
34+
35+
const handleLogin = () => {
36+
Alert.alert(`Welcome ${login}`, 'Successfully logged in!');
37+
};
38+
39+
return (
40+
<SafeAreaView style={styles.safeArea}>
41+
<GestureHandlerRootView style={styles.container}>
42+
<Animated.ScrollView
43+
stickyHeaderIndices={[1]}
44+
ref={tosRef}
45+
contentContainerStyle={styles.tosContainer}>
46+
<View style={styles.background} />
47+
<View style={styles.stickyButtonContainer}>
48+
<GestureDetector gesture={goDown}>
49+
<Pressable style={styles.button}>
50+
<Text style={styles.buttonText}>I'm tired of reading.</Text>
51+
</Pressable>
52+
</GestureDetector>
53+
</View>
54+
<Text style={styles.tosTitle}>Terms of Service</Text>
55+
<Text style={styles.tosContent}>
56+
Welcome to Services! These Terms of Service ("Terms") govern your
57+
use of our website, products, and services ("Services"). By
58+
accessing or using our Services, you agree to be bound by these
59+
Terms. If you do not agree to these Terms, do not use our Services.
60+
</Text>
61+
<Text style={styles.tosSubtitle}>1. Acceptance of Terms</Text>
62+
<Text style={styles.tosContent}>
63+
By using our Services, you affirm that you are at least 18 years
64+
old, or if you are under 18 years old, that you have the consent of
65+
your parent or legal guardian.
66+
</Text>
67+
<Text style={styles.tosSubtitle}>2. Changes to Terms</Text>
68+
<Text style={styles.tosContent}>
69+
We reserve the right to modify these Terms at any time. We will
70+
notify you of any changes by posting the new Terms on our website.
71+
You are advised to review these Terms periodically for any changes.
72+
Your continued use of the Services after the changes are posted
73+
constitutes your acceptance of the new Terms.
74+
</Text>
75+
<Text style={styles.tosSubtitle}>3. Use of Services</Text>
76+
<Text style={styles.tosContent}>
77+
You agree to use the Services only for lawful purposes and in
78+
accordance with these Terms. You agree not to use the Services:
79+
{'\n'}• In any way that violates any applicable federal, state,
80+
local, or international law or regulation.
81+
{'\n'}• For the purpose of exploiting, harming, or attempting to
82+
exploit or harm minors in any way.
83+
{'\n'}• To transmit, or procure the sending of, any advertising or
84+
promotional material, including any "junk mail," "chain letters,"
85+
"spam," or any other similar solicitation.
86+
{'\n'}• To impersonate or attempt to impersonate Services, a
87+
Services employee, another user, or any other person or entity.
88+
{'\n'}• In any way that infringes upon the rights of others, or in
89+
any way is illegal, threatening, fraudulent, or harmful, or in
90+
connection with any unlawful, illegal, fraudulent, or harmful
91+
purpose or activity.
92+
{'\n'}• To engage in any other conduct that restricts or inhibits
93+
anyone's use or enjoyment of the Services, or which, as determined
94+
by us, may harm Services or users of the Services, or expose them to
95+
liability.
96+
</Text>
97+
<Text style={styles.tosSubtitle}>4. User Accounts</Text>
98+
<Text style={styles.tosContent}>
99+
To access some of the Services, you may be required to create an
100+
account. You agree to provide accurate, current, and complete
101+
information during the registration process and to update such
102+
information to keep it accurate, current, and complete. You are
103+
responsible for safeguarding your password and agree not to disclose
104+
your password to any third party. You agree that you are solely
105+
responsible for any activities or actions under your account,
106+
whether you have authorized such activities or actions. You will
107+
immediately notify us of any unauthorized use of your account.
108+
</Text>
109+
<Text style={styles.tosSubtitle}>5. Termination</Text>
110+
<Text style={styles.tosContent}>
111+
We may terminate or suspend your access to the Services immediately,
112+
without prior notice or liability, for any reason whatsoever,
113+
including without limitation if you breach the Terms. Upon
114+
termination, your right to use the Services will immediately cease.
115+
If you wish to terminate your account, you may simply discontinue
116+
using the Services.
117+
</Text>
118+
<Text style={styles.tosSubtitle}>6. Limitation of Liability</Text>
119+
<Text style={styles.tosContent}>
120+
In no event shall Services, nor its directors, employees, partners,
121+
agents, suppliers, or affiliates, be liable for any indirect,
122+
incidental, special, consequential, or punitive damages, including
123+
without limitation, loss of profits, data, use, goodwill, or other
124+
intangible losses, resulting from (i) your use or inability to use
125+
the Service; (ii) any unauthorized access to or use of our servers
126+
and/or any personal information stored therein; (iii) any
127+
interruption or cessation of transmission to or from the Service;
128+
(iv) any bugs, viruses, trojan horses, or the like that may be
129+
transmitted to or through our Service by any third party; (v) any
130+
errors or omissions in any content or for any loss or damage
131+
incurred as a result of your use of any content posted, emailed,
132+
transmitted, or otherwise made available through the Service; and/or
133+
(vi) the defamatory, offensive, or illegal conduct of any third
134+
party. In no event shall Services be liable for any claims,
135+
proceedings, liabilities, obligations, damages, losses, or costs in
136+
an amount exceeding the amount you paid to Services hereunder or
137+
$100.00, whichever is greater.
138+
</Text>
139+
<Text style={styles.tosSubtitle}>7. Governing Law</Text>
140+
<Text style={styles.tosContent}>
141+
These Terms shall be governed and construed in accordance with the
142+
laws of Poland, without regard to its conflict of law provisions.
143+
Our failure to enforce any right or provision of these Terms will
144+
not be considered a waiver of those rights. If any provision of
145+
these Terms is held to be invalid or unenforceable by a court, the
146+
remaining provisions of these Terms will remain in effect. These
147+
Terms constitute the entire agreement between us regarding our
148+
Service, and supersede and replace any prior agreements we might
149+
have had between us regarding the Service.
150+
</Text>
151+
<View style={styles.loginForm}>
152+
<Text style={styles.loginFormTitle}>Welcome!</Text>
153+
<Text style={styles.loginFormSubtitle}>
154+
By logging in you accept our Terms of Service.
155+
</Text>
156+
<AnimatedTextInput
157+
ref={loginRef}
158+
style={styles.input}
159+
placeholder="Login"
160+
value={login}
161+
onChangeText={setLogin}
162+
/>
163+
<AnimatedTextInput
164+
style={styles.input}
165+
placeholder="Password"
166+
value={password}
167+
onChangeText={setPassword}
168+
secureTextEntry
169+
/>
170+
<Pressable style={styles.button} onPress={handleLogin}>
171+
<Text style={styles.buttonText}>Login</Text>
172+
</Pressable>
173+
</View>
174+
</Animated.ScrollView>
175+
</GestureHandlerRootView>
176+
</SafeAreaView>
177+
);
178+
}
179+
180+
const styles = StyleSheet.create({
181+
safeArea: {
182+
flex: 1,
183+
backgroundColor: '#f8f9fa',
184+
},
185+
container: {
186+
flex: 1,
187+
},
188+
tosContainer: {
189+
alignItems: 'center',
190+
paddingHorizontal: 20,
191+
},
192+
background: {
193+
width: '10%',
194+
},
195+
tosTitle: {
196+
fontSize: 22,
197+
fontWeight: '700',
198+
marginVertical: 16,
199+
color: '#001a72',
200+
},
201+
tosSubtitle: {
202+
fontSize: 18,
203+
fontWeight: '600',
204+
marginVertical: 16,
205+
color: '#001a72',
206+
},
207+
tosContent: {
208+
fontFamily: 'Aeonik',
209+
fontSize: 16,
210+
marginBottom: 8,
211+
color: '#001a72',
212+
},
213+
input: {
214+
borderWidth: 1,
215+
borderColor: '#ced4da',
216+
color: '#001a72',
217+
borderRadius: 8,
218+
width: '80%',
219+
padding: 12,
220+
fontSize: 16,
221+
marginBottom: 20,
222+
},
223+
stickyButtonContainer: {
224+
backgroundColor: '#f8f9ff',
225+
paddingVertical: 16,
226+
paddingHorizontal: 48,
227+
width: '100%',
228+
},
229+
button: {
230+
backgroundColor: '#b58df1',
231+
marginVertical: 16,
232+
paddingVertical: 12,
233+
paddingHorizontal: 48,
234+
borderRadius: 32,
235+
},
236+
buttonText: {
237+
fontSize: 18,
238+
color: '#f8f9ff',
239+
textAlign: 'center',
240+
},
241+
loginForm: {
242+
marginVertical: 32,
243+
width: '100%',
244+
display: 'flex',
245+
justifyContent: 'center',
246+
alignItems: 'center',
247+
},
248+
loginFormTitle: {
249+
fontSize: 22,
250+
fontFamily: 'Aeonik',
251+
color: '#001a72',
252+
fontWeight: '600',
253+
marginBottom: 8,
254+
},
255+
loginFormSubtitle: {
256+
fontFamily: 'Aeonik',
257+
color: '#001a7299',
258+
marginBottom: 16,
259+
},
260+
});
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)