View: additional accessibility props

* Add `accessibilityLiveRegion` for `aria-live` support.
* Add `accessibilityRole` for `role` support.

Fix #11
This commit is contained in:
Nicolas Gallagher
2015-09-08 00:09:09 -07:00
parent 7eff1a644e
commit 3b848fe378
6 changed files with 73 additions and 12 deletions

View File

@@ -10,17 +10,37 @@ NOTE: `View` will transfer all other props to the rendered HTML element.
**accessibilityLabel** string
Overrides the text that's read by the screen reader when the user interacts
with the element. (This is implemented using `aria-label`.)
Defines the text available to assistive technologies upon interaction with the
element. (This is implemented using `aria-label`.)
**accessible** bool
When `false`, the view is hidden from screenreaders. Default: `true`. (This is
When `false`, the view is hidden from assistive technologies. Default: `true`. (This is
implemented using `aria-hidden`.)
**accessibilityLiveRegion** oneOf('assertive', 'off', 'polite')
Indicates to assistive technologies whether to notify the user when the view
changes. The values of this attribute are expressed in degrees of importance.
When regions are specified as `polite` (recommended), updates take low
priority. When regions are specified as `assertive`, assistive technologies
will interrupt and immediately notify the user. Default: `off`. (This is
implemented using [`aria-live`](http://www.w3.org/TR/wai-aria/states_and_properties#aria-live).)
**accessibilityRole** oneOf(roles)
Allows assistive technologies to present and support interaction with the view
in a manner that is consistent with user expectations for similar views of that
type. For example, marking a touchable view with an `accessibilityRole` of
`button`. (This is implemented using [ARIA roles](http://www.w3.org/TR/wai-aria/roles#role_definitions)).
Note: Avoid changing `accessibilityRole` values over time or after user
actions. Generally, accessibility APIs do not provide a means of notifying
assistive technologies of a `role` value change.
**component** function, string
Default: `div`.
The React Component for this view. Default: `div`.
**pointerEvents** oneOf('auto', 'box-only', 'box-none', 'none')

View File

@@ -53,7 +53,7 @@ class Example extends Component {
render() {
return (
<View style={styles.root}>
<View style={styles.root} accessibilityRole='main'>
<Heading level='1' size='xlarge'>React Native for Web: examples</Heading>
<Heading level='2' size='large'>Image</Heading>

View File

@@ -31,15 +31,12 @@ const styles = {
class View extends React.Component {
static propTypes = {
accessibilityLabel: PropTypes.string,
accessibilityLiveRegion: PropTypes.oneOf(['assertive', 'off', 'polite']),
accessibilityRole: PropTypes.string,
accessible: PropTypes.bool,
children: PropTypes.any,
component: CoreComponent.propTypes.component,
pointerEvents: PropTypes.oneOf([
'auto',
'box-none',
'box-only',
'none'
]),
pointerEvents: PropTypes.oneOf(['auto', 'box-none', 'box-only', 'none']),
style: PropTypes.shape(ViewStylePropTypes),
testID: CoreComponent.propTypes.testID
}
@@ -53,7 +50,17 @@ class View extends React.Component {
}
render() {
const { accessible, accessibilityLabel, pointerEvents, style, testID, ...other } = this.props
const {
accessibilityLabel,
accessibilityLiveRegion,
accessibilityRole,
accessible,
pointerEvents,
style,
testID,
...other
} = this.props
const pointerEventsStyle = pointerEvents && { pointerEvents }
const resolvedStyle = pickProps(style, viewStyleKeys)
@@ -62,7 +69,9 @@ class View extends React.Component {
{...other}
aria-hidden={accessible ? null : true}
aria-label={accessibilityLabel}
aria-live={accessibilityLiveRegion}
className={'View'}
role={accessibilityRole}
style={{
...(styles.initial),
...resolvedStyle,

View File

@@ -11,6 +11,14 @@ suite('View', () => {
assertProps.accessibilityLabel(View)
})
test('prop "accessibilityLiveRegion"', () => {
assertProps.accessibilityLiveRegion(View)
})
test('prop "accessibilityRole"', () => {
assertProps.accessibilityRole(View)
})
test('prop "accessible"', () => {
assertProps.accessible(View)
})

View File

@@ -14,6 +14,26 @@ export const assertProps = {
assert.equal(dom.getAttribute('aria-label'), accessibilityLabel)
},
accessibilityLiveRegion: function (Component) {
// no live
let dom = renderToDOM(<Component />)
assert.equal(dom.getAttribute('aria-live'), null)
// with live
const accessibilityLiveRegion = 'polite'
dom = renderToDOM(<Component accessibilityLiveRegion={accessibilityLiveRegion} />)
assert.equal(dom.getAttribute('aria-live'), accessibilityLiveRegion)
},
accessibilityRole: function (Component) {
// no role
let dom = renderToDOM(<Component />)
assert.equal(dom.getAttribute('role'), null)
// with role
const accessibilityRole = 'main'
dom = renderToDOM(<Component accessibilityRole={accessibilityRole} />)
assert.equal(dom.getAttribute('role'), accessibilityRole)
},
accessible: function (Component) {
// accessible
let dom = renderToDOM(<Component accessible={true} />)

View File

@@ -245,6 +245,10 @@
.color-inherit { color: inherit; }
.color-transparent { color: transparent; }
/* cursor */
.cursor-pointer { cursor: pointer; }
/* direction */
.direction-inherit { direction: inherit; }