Skip to content

Commit fe66694

Browse files
Abbondanzofacebook-github-bot
authored andcommitted
Add example for focus events on Android (#51725)
Summary: Pull Request resolved: #51725 This change builds upon the focus/blur portion showcased in ViewExample but showcases several more components all in one spot. This can be shared with additional platforms or expanded to include more component examples like Image, but the goal is to target Android and not distract from the primary use cases. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D75747410 fbshipit-source-id: 7d53366d9f32192ca6b3da45dd127836fb6efdf6
1 parent e960a28 commit fe66694

2 files changed

Lines changed: 196 additions & 0 deletions

File tree

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
* @format
9+
*/
10+
11+
'use strict';
12+
13+
import RNTesterText from '../../components/RNTesterText';
14+
import {useState} from 'react';
15+
import {Alert, Pressable, StyleSheet, TextInput, View} from 'react-native';
16+
17+
type SectionProps = {
18+
children: React.Node,
19+
};
20+
21+
const FocusEventSection = ({children}: SectionProps): React.Node => {
22+
const [outerFocused, setOuterFocused] = useState(false);
23+
24+
return (
25+
<View
26+
onFocus={() => setOuterFocused(true)}
27+
onBlur={() => setOuterFocused(false)}>
28+
<RNTesterText style={styles.sectionSubtitle}>
29+
Section focused: {outerFocused ? 'true' : 'false'}
30+
</RNTesterText>
31+
{children}
32+
</View>
33+
);
34+
};
35+
36+
const ViewExampleInnerRow = ({focusable}: {focusable: boolean}) => {
37+
const [focused, setFocused] = useState(false);
38+
return (
39+
<View
40+
focusable={focusable}
41+
onFocus={() => setFocused(true)}
42+
onBlur={() => setFocused(false)}
43+
style={[styles.viewInnerRow]}>
44+
<RNTesterText style={styles.viewInnerRowTextColor}>
45+
Focusable: {focusable ? 'true' : 'false'}
46+
</RNTesterText>
47+
<RNTesterText style={styles.viewInnerRowTextColor}>
48+
Focused: {focused ? 'true' : 'false'}
49+
</RNTesterText>
50+
</View>
51+
);
52+
};
53+
54+
const ViewExample = () => {
55+
return (
56+
<FocusEventSection>
57+
<ViewExampleInnerRow focusable={true} />
58+
<ViewExampleInnerRow focusable={true} />
59+
<ViewExampleInnerRow focusable={false} />
60+
<ViewExampleInnerRow focusable={true} />
61+
</FocusEventSection>
62+
);
63+
};
64+
65+
const PressableExample = () => {
66+
const [highlightFocused, setHighlightFocused] = useState(false);
67+
const [pressableFocused, setPressableFocused] = useState(false);
68+
const [disabledPressableFocused, setDisabledPressableFocused] =
69+
useState(false);
70+
71+
return (
72+
<FocusEventSection>
73+
<Pressable
74+
onPress={() => Alert.alert('Pressable pressed!')}
75+
onFocus={() => setPressableFocused(true)}
76+
onBlur={() => setPressableFocused(false)}>
77+
<RNTesterText>
78+
Pressable focused: {pressableFocused ? 'true' : 'false'}
79+
</RNTesterText>
80+
</Pressable>
81+
<Pressable
82+
disabled={true}
83+
onPress={() => Alert.alert('Disabled Pressable pressed!')}
84+
onFocus={() => setDisabledPressableFocused(true)}
85+
onBlur={() => setDisabledPressableFocused(false)}>
86+
<RNTesterText>
87+
Disabled Pressable focused:{' '}
88+
{disabledPressableFocused ? 'true' : 'false'}
89+
</RNTesterText>
90+
</Pressable>
91+
</FocusEventSection>
92+
);
93+
};
94+
95+
const TextInputExample = () => {
96+
const [input1Focused, setInput1Focused] = useState(false);
97+
const [input2Focused, setInput2Focused] = useState(false);
98+
const [input3Focused, setInput3Focused] = useState(false);
99+
100+
return (
101+
<FocusEventSection>
102+
<TextInput
103+
onFocus={() => setInput1Focused(true)}
104+
onBlur={() => setInput1Focused(false)}
105+
style={[styles.textInput, input1Focused && styles.textInputFocused]}
106+
placeholder={`Focused: ${input1Focused ? 'true' : 'false'}`}
107+
/>
108+
<TextInput
109+
onFocus={() => setInput2Focused(true)}
110+
onBlur={() => setInput2Focused(false)}
111+
style={[styles.textInput, input2Focused && styles.textInputFocused]}
112+
placeholder={`Focused: ${input2Focused ? 'true' : 'false'}`}
113+
/>
114+
<TextInput
115+
onFocus={() => setInput3Focused(true)}
116+
onBlur={() => setInput3Focused(false)}
117+
style={[styles.textInput, input3Focused && styles.textInputFocused]}
118+
placeholder={`Not editable focused: ${input3Focused ? 'true' : 'false'}`}
119+
editable={false}
120+
/>
121+
</FocusEventSection>
122+
);
123+
};
124+
125+
const styles = StyleSheet.create({
126+
container: {
127+
padding: 8,
128+
rowGap: 16,
129+
},
130+
sectionSubtitle: {
131+
paddingBottom: 8,
132+
},
133+
sectionTitle: {
134+
paddingBottom: 2,
135+
fontSize: 20,
136+
},
137+
sectionWrapperFocused: {
138+
borderColor: 'blue',
139+
},
140+
textFocused: {
141+
backgroundColor: 'lightblue',
142+
},
143+
textLink: {color: 'blue'},
144+
textInput: {
145+
borderColor: 'rgba(40, 40, 40, 0.3)',
146+
borderRadius: 4,
147+
borderWidth: 1,
148+
marginTop: 4,
149+
},
150+
textInputFocused: {
151+
borderColor: 'blue',
152+
},
153+
viewInnerRow: {
154+
backgroundColor: '#424B54',
155+
borderRadius: 8,
156+
borderColor: 'transparent',
157+
borderWidth: 2,
158+
height: 50,
159+
marginTop: 4,
160+
padding: 4,
161+
width: '100%',
162+
},
163+
viewInnerRowTextColor: {
164+
color: 'white',
165+
},
166+
});
167+
168+
export default {
169+
title: 'Focus Events',
170+
description: 'Examples that show how Focus events can be used.',
171+
examples: [
172+
{
173+
title: 'View Example',
174+
render: function (): React.Node {
175+
return <ViewExample />;
176+
},
177+
},
178+
{
179+
title: 'TextInput Example',
180+
render: function (): React.Node {
181+
return <TextInputExample />;
182+
},
183+
},
184+
{
185+
title: 'Pressable Example',
186+
render: function (): React.Node {
187+
return <PressableExample />;
188+
},
189+
},
190+
],
191+
};

packages/rn-tester/js/utils/RNTesterList.android.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ const APIs: Array<RNTesterModuleInfo> = ([
225225
module: require('../examples/DisplayContents/DisplayContentsExample')
226226
.default,
227227
},
228+
{
229+
key: 'FocusEventsExample',
230+
module: require('../examples/FocusEventsExample/FocusEventsExample')
231+
.default,
232+
},
228233
{
229234
key: 'InvalidPropsExample',
230235
module: require('../examples/InvalidProps/InvalidPropsExample'),

0 commit comments

Comments
 (0)