Skip to content

Commit

Permalink
Add support for accessibilityHint (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpdriver authored Feb 9, 2020
1 parent 15b882d commit df55ade
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Alternatively, you can enable all the recommended rules at once by adding `plugi
## Supported Rules

- [accessibility-label](docs/rules/accessibility-label.md): Enforce that views that have `accessible={true}`, also have an `accessibilityLabel` prop
- [has-accessibility-hint](docs/rules/has-accessibility-hint): Enforce `accessibilityHint` is used in conjunction with `accessibilityLabel`
- [has-accessibility-props](docs/rules/has-accessibility-props.md): Enforce all `<Touchable\*>` components have `accessibilityRole` prop or both `accessibilityTraits` and `accessibilityComponentType` props set
- [has-valid-accessibility-actions](docs/rules/has-valid-accessibility-actions.md): Enforce both `accessibilityActions` and `onAccessibilityAction` props are valid
- [has-valid-accessibility-role](docs/rules/has-valid-accessibility-role.md): Enforce `accessibilityRole` property value is valid
Expand Down
51 changes: 51 additions & 0 deletions __tests__/src/rules/has-accessibility-hint-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* eslint-env jest */
/**
* @fileoverview An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not apparent from the accessibility label.
* @author JP Driver
*/

// -----------------------------------------------------------------------------
// Requirements
// -----------------------------------------------------------------------------

import { RuleTester } from 'eslint';
import parserOptionsMapper from '../../__util__/parserOptionsMapper';
import rule from '../../../src/rules/has-accessibility-hint';

// -----------------------------------------------------------------------------
// Tests
// -----------------------------------------------------------------------------

const ruleTester = new RuleTester();

const expectedError = {
message: 'has accessibilityLabel prop but no accessibilityHint',
type: 'JSXOpeningElement'
};

ruleTester.run('has-accessibility-hint', rule, {
valid: [
{
code: `<TouchableOpacity />`
},
{
code: `<TouchableOpacity
accessibilityHint="Navigates to the previous screen"
/>`
},
{
code: `<TouchableOpacity
accessibilityLabel="Go back"
accessibilityHint="Navigates to the previous screen"
/>`
}
].map(parserOptionsMapper),
invalid: [
{
code: `<TouchableOpacity
accessibilityLabel="Go back"
/>`,
errors: [expectedError]
}
].map(parserOptionsMapper)
});
23 changes: 23 additions & 0 deletions docs/rules/has-accessibility-hint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# has-accessibility-hint

An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not apparent from the accessibility label.

### References

1. [React Native Docs - accessibilityHint (iOS, Android)](https://facebook.github.io/react-native/docs/accessibility#accessibilityhint-ios-android)

## Rule details

This rule takes no arguments.

### Succeed
```jsx
<TouchableOpacity />
<TouchableOpacity accessibilityHint="Navigates to the previous screen" />
<TouchableOpacity accessibilityHint="Navigates to the previous screen" accessibilityLabel="Go back" />
```

### Fail
```jsx
<TouchableOpacity accessibilityLabel="Go back" />
```
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module.exports = {
rules: {
'accessibility-label': require('./rules/accessibility-label'),
'has-accessibility-hint': require('./rules/has-accessibility-hint'),
'has-accessibility-props': require('./rules/has-accessibility-props'),
'has-valid-accessibility-actions': require('./rules/has-valid-accessibility-actions'),
'has-valid-accessibility-component-type': require('./rules/has-valid-accessibility-component-type'),
Expand All @@ -25,6 +26,7 @@ module.exports = {
},
rules: {
'react-native-a11y/accessibility-label': 'error',
'react-native-a11y/has-accessibility-hint': 'error',
'react-native-a11y/has-accessibility-props': 'error',
'react-native-a11y/has-valid-accessibility-actions': 'error',
'react-native-a11y/has-valid-accessibility-component-type': 'error',
Expand Down
39 changes: 39 additions & 0 deletions src/rules/has-accessibility-hint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @fileoverview An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not apparent from the accessibility label.
* @author JP Driver
* @flow
*/

// ----------------------------------------------------------------------------
// Rule Definition
// ----------------------------------------------------------------------------

import { hasProp } from 'jsx-ast-utils';
import type { JSXOpeningElement } from 'ast-types-flow';
import type { ESLintContext } from '../../flow/eslint';
import { generateObjSchema } from '../util/schemas';

const errorMessage = '';

const schema = generateObjSchema();

module.exports = {
meta: {
docs: {},
schema: [schema]
},

create: (context: ESLintContext) => ({
JSXOpeningElement: (node: JSXOpeningElement) => {
if (
hasProp(node.attributes, 'accessibilityLabel') &&
!hasProp(node.attributes, 'accessibilityHint')
) {
context.report({
node,
message: 'has accessibilityLabel prop but no accessibilityHint'
});
}
}
})
};

0 comments on commit df55ade

Please sign in to comment.