Im using React Native Web in Expo. Ive read that it does accessibility properly however I can't see how to have a label for the input:
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
https://reactnative.dev/docs/0.53/textinput
For clarification and because it's weird name, I'm using React Native Web not React DOM:
You don't need to do anything special, you can just wrap the <textInput>
in a label as you would with any input.
Your code still outputs HTML at the end of the day.
Something along the lines of (I don't know React so just use this is an example)
import React, { Component } from 'react';
import { AppRegistry, TextInput } from 'react-native';
export default class UselessTextInput extends Component {
constructor(props) {
super(props);
this.state = { text: 'Useless Placeholder' };
}
render() {
return (
<label>Text Label
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/></label>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => UselessTextInput);
As you are using React I presume you have no need to support Internet Explorer 8 and below so wrapping an input in a label will work correctly with all screen reader and browser combinations.
If for any reason you do need to support the ancient stuff then you need to create an id
on the input so you can use for="itemID"
on the label. (the for
on the label should contain the id
of the input). Please note that you need to wrap them in a <div>
if you do this due to the way React works.
import React, { Component } from 'react';
import { AppRegistry, TextInput } from 'react-native';
export default class UselessTextInput extends Component {
constructor(props) {
super(props);
this.state = { text: 'Useless Placeholder' };
}
render() {
return (
<div>
<label for='itemID'>Text Label</label>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
id="itemID"
/></div>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => UselessTextInput);
Finally you can add aria
as you would any other property
render() {
return (
<label>Text Label
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
aria-labelledby="id(s)OfElement(s)ToLabelThisInput"
/></label>
);
}