@@ -12,10 +12,14 @@
1212const React = require('react');
1313const {
1414 AccessibilityInfo,
15+ Button,
1516 Text,
1617 View,
1718 TouchableOpacity,
1819 Alert,
20+ UIManager,
21+ findNodeHandle,
22+ Platform,
1923} = require('react-native');
20242125const RNTesterBlock = require('./RNTesterBlock');
@@ -138,6 +142,274 @@ class AccessibilityExample extends React.Component {
138142}
139143}
140144145+class CheckboxExample extends React.Component {
146+state = {
147+checkboxState: 'checked',
148+};
149+150+_onCheckboxPress = () => {
151+const checkboxState =
152+this.state.checkboxState === 'checked' ? 'unchecked' : 'checked';
153+154+this.setState({
155+checkboxState: checkboxState,
156+});
157+158+if (Platform.OS === 'android') {
159+UIManager.sendAccessibilityEvent(
160+findNodeHandle(this),
161+UIManager.AccessibilityEventTypes.typeViewClicked,
162+);
163+}
164+};
165+166+render() {
167+return (
168+<TouchableOpacity
169+onPress={this._onCheckboxPress}
170+accessibilityLabel="element 2"
171+accessibilityRole="checkbox"
172+accessibilityStates={[this.state.checkboxState]}
173+accessibilityHint="click me to change state">
174+<Text>Checkbox example</Text>
175+</TouchableOpacity>
176+);
177+}
178+}
179+180+class SwitchExample extends React.Component {
181+state = {
182+switchState: 'checked',
183+};
184+185+_onSwitchToggle = () => {
186+const switchState =
187+this.state.switchState === 'checked' ? 'unchecked' : 'checked';
188+189+this.setState({
190+switchState: switchState,
191+});
192+193+if (Platform.OS === 'android') {
194+UIManager.sendAccessibilityEvent(
195+findNodeHandle(this),
196+UIManager.AccessibilityEventTypes.typeViewClicked,
197+);
198+}
199+};
200+201+render() {
202+return (
203+<TouchableOpacity
204+onPress={this._onSwitchToggle}
205+accessibilityLabel="element 12"
206+accessibilityRole="switch"
207+accessibilityStates={[this.state.switchState]}
208+accessible={true}>
209+<Text>Switch example</Text>
210+</TouchableOpacity>
211+);
212+}
213+}
214+215+class SelectionExample extends React.Component {
216+constructor(props) {
217+super(props);
218+this.selectableElement = React.createRef();
219+}
220+221+state = {
222+isSelected: true,
223+isEnabled: false,
224+};
225+226+render() {
227+let accessibilityStates = [];
228+let accessibilityHint = 'click me to select';
229+if (this.state.isSelected) {
230+accessibilityStates.push('selected');
231+accessibilityHint = 'click me to unselect';
232+}
233+if (!this.state.isEnabled) {
234+accessibilityStates.push('disabled');
235+accessibilityHint = 'use the button on the right to enable selection';
236+}
237+let buttonTitle = this.state.isEnabled
238+ ? 'Disable selection'
239+ : 'Enable selection';
240+241+return (
242+<View style={{flex: 1, flexDirection: 'row'}}>
243+<TouchableOpacity
244+ref={this.selectableElement}
245+accessible={true}
246+onPress={() => {
247+this.setState({
248+isSelected: !this.state.isSelected,
249+});
250+251+if (Platform.OS === 'android') {
252+UIManager.sendAccessibilityEvent(
253+findNodeHandle(this.selectableElement.current),
254+UIManager.AccessibilityEventTypes.typeViewClicked,
255+);
256+}
257+}}
258+accessibilityLabel="element 19"
259+accessibilityStates={accessibilityStates}
260+accessibilityHint={accessibilityHint}>
261+<Text>Selectable element example</Text>
262+</TouchableOpacity>
263+<Button
264+onPress={() => {
265+this.setState({
266+isEnabled: !this.state.isEnabled,
267+});
268+}}
269+title={buttonTitle}
270+/>
271+</View>
272+);
273+}
274+}
275+276+class ExpandableElementExample extends React.Component {
277+state = {
278+expandState: 'collapsed',
279+};
280+281+_onElementPress = () => {
282+const expandState =
283+this.state.expandState === 'collapsed' ? 'expanded' : 'collapsed';
284+285+this.setState({
286+expandState: expandState,
287+});
288+289+if (Platform.OS === 'android') {
290+UIManager.sendAccessibilityEvent(
291+findNodeHandle(this),
292+UIManager.AccessibilityEventTypes.typeViewClicked,
293+);
294+}
295+};
296+297+render() {
298+return (
299+<TouchableOpacity
300+onPress={this._onElementPress}
301+accessibilityLabel="element 18"
302+accessibilityStates={[this.state.expandState]}
303+accessibilityHint="click me to change state">
304+<Text>Expandable element example</Text>
305+</TouchableOpacity>
306+);
307+}
308+}
309+310+class AccessibilityRoleAndStateExample extends React.Component<{}> {
311+render() {
312+return (
313+<View>
314+<View
315+accessibilityLabel="element 1"
316+accessibilityRole="alert"
317+accessible={true}>
318+<Text>Alert example</Text>
319+</View>
320+<CheckboxExample />
321+<View
322+accessibilityLabel="element 3"
323+accessibilityRole="combobox"
324+accessible={true}>
325+<Text>Combobox example</Text>
326+</View>
327+<View
328+accessibilityLabel="element 4"
329+accessibilityRole="menu"
330+accessible={true}>
331+<Text>Menu example</Text>
332+</View>
333+<View
334+accessibilityLabel="element 5"
335+accessibilityRole="menubar"
336+accessible={true}>
337+<Text>Menu bar example</Text>
338+</View>
339+<View
340+accessibilityLabel="element 6"
341+accessibilityRole="menuitem"
342+accessible={true}>
343+<Text>Menu item example</Text>
344+</View>
345+<View
346+accessibilityLabel="element 7"
347+accessibilityRole="progressbar"
348+accessible={true}>
349+<Text>Progress bar example</Text>
350+</View>
351+<View
352+accessibilityLabel="element 8"
353+accessibilityRole="radio"
354+accessible={true}>
355+<Text>Radio button example</Text>
356+</View>
357+<View
358+accessibilityLabel="element 9"
359+accessibilityRole="radiogroup"
360+accessible={true}>
361+<Text>Radio group example</Text>
362+</View>
363+<View
364+accessibilityLabel="element 10"
365+accessibilityRole="scrollbar"
366+accessible={true}>
367+<Text>Scrollbar example</Text>
368+</View>
369+<View
370+accessibilityLabel="element 11"
371+accessibilityRole="spinbutton"
372+accessible={true}>
373+<Text>Spin button example</Text>
374+</View>
375+<SwitchExample />
376+<View
377+accessibilityLabel="element 13"
378+accessibilityRole="tab"
379+accessible={true}>
380+<Text>Tab example</Text>
381+</View>
382+<View
383+accessibilityLabel="element 14"
384+accessibilityRole="tablist"
385+accessible={true}>
386+<Text>Tab list example</Text>
387+</View>
388+<View
389+accessibilityLabel="element 15"
390+accessibilityRole="timer"
391+accessible={true}>
392+<Text>Timer example</Text>
393+</View>
394+<View
395+accessibilityLabel="element 16"
396+accessibilityRole="toolbar"
397+accessible={true}>
398+<Text>Toolbar example</Text>
399+</View>
400+<View
401+accessibilityLabel="element 17"
402+accessibilityStates={['busy']}
403+accessible={true}>
404+<Text>State busy example</Text>
405+</View>
406+<ExpandableElementExample />
407+<SelectionExample />
408+</View>
409+);
410+}
411+}
412+141413class ScreenReaderStatusExample extends React.Component<{}> {
142414 state = {
143415screenReaderEnabled: false,
@@ -189,6 +461,12 @@ exports.examples = [
189461 return <AccessibilityExample />;
190462},
191463},
464+{
465+title: 'New accessibility roles and states',
466+render(): React.Element<typeof AccessibilityRoleAndStateExamples> {
467+ return <AccessibilityRoleAndStateExample />;
468+},
469+},
192470{
193471title: 'Check if the screen reader is enabled',
194472render(): React.Element<typeof ScreenReaderStatusExample> {