Skip to content

Commit 68fc4f6

Browse files
authored
allow CallExpressions in accessibilityActions (#101)
1 parent 3f02a1c commit 68fc4f6

File tree

2 files changed

+64
-42
lines changed

2 files changed

+64
-42
lines changed

__tests__/src/rules/has-valid-accessibility-actions-test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ ruleTester.run('has-valid-accessibility-actions', rule, {
5656
}}
5757
/>`,
5858
},
59+
{
60+
code: `<View
61+
accessibilityActions={useMemo()}
62+
onAccessibilityAction={useCallback()}
63+
/>`,
64+
},
5965
].map(parserOptionsMapper),
6066
invalid: [
6167
{

src/rules/has-valid-accessibility-actions.js

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import type { JSXOpeningElement } from 'ast-types-flow';
8-
import { getProp, getPropValue, hasProp } from 'jsx-ast-utils';
8+
import { getProp, getPropValue, hasEveryProp, hasProp } from 'jsx-ast-utils';
99
import { generateObjSchema } from '../util/schemas';
1010
import type { ESLintContext } from '../../flow/eslint';
1111

@@ -36,51 +36,67 @@ module.exports = {
3636
message,
3737
});
3838

39-
if (hasProp(node.attributes, 'accessibilityActions')) {
40-
if (
41-
typeof getPropValue(
42-
getProp(node.attributes, 'onAccessibilityAction')
43-
) !== 'function'
44-
) {
45-
error(
46-
'accessibilityActions: has accessibilityActions but onAccessibilityAction is not a function'
47-
);
39+
if (
40+
hasEveryProp(node.attributes, [
41+
'accessibilityActions',
42+
'onAccessibilityAction',
43+
])
44+
) {
45+
const handlerProp = getProp(node.attributes, 'onAccessibilityAction');
46+
const handlerPropType = handlerProp.value.expression.type;
47+
// CallExpressions are always assumed valid
48+
if (handlerPropType !== 'CallExpression') {
49+
const handlerPropValue = getPropValue(handlerProp);
50+
if (typeof handlerPropValue !== 'function') {
51+
error(
52+
'accessibilityActions: has accessibilityActions but onAccessibilityAction is not a function'
53+
);
54+
}
4855
}
4956

50-
const attrValue = getPropValue(
51-
getProp(node.attributes, 'accessibilityActions')
52-
);
57+
const actionsProp = getProp(node.attributes, 'accessibilityActions');
58+
const actionsPropType = actionsProp.value.expression.type;
59+
// CallExpressions are always assumed valid
60+
if (actionsPropType !== 'CallExpression') {
61+
const attrValue = getPropValue(actionsProp);
5362

54-
if (!Array.isArray(attrValue)) {
55-
error('accessibilityActions: value must be an Array');
56-
} else if (attrValue.length === 0) {
57-
error('accessibilityActions: Array cannot be empty');
58-
} else {
59-
attrValue.forEach((action) => {
60-
if (!action.name) {
61-
error('accessibilityActions: action missing name');
62-
} else if (
63-
standardActions.indexOf(action.name) < 0 &&
64-
!action.label
65-
) {
66-
error(
67-
`accessibilityActions: custom action "${action.name}" missing label`
68-
);
69-
}
70-
if (
71-
Object.keys(action).filter((f) => f !== 'name' && f !== 'label')
72-
.length > 0
73-
) {
74-
error(
75-
`accessibilityActions: action "${action.name}" contains unrecognised keys`
76-
);
77-
}
78-
});
63+
if (!Array.isArray(attrValue)) {
64+
error('accessibilityActions: value must be an Array');
65+
} else if (attrValue.length === 0) {
66+
error('accessibilityActions: Array cannot be empty');
67+
} else {
68+
attrValue.forEach((action) => {
69+
if (!action.name) {
70+
error('accessibilityActions: action missing name');
71+
} else if (
72+
standardActions.indexOf(action.name) < 0 &&
73+
!action.label
74+
) {
75+
error(
76+
`accessibilityActions: custom action "${action.name}" missing label`
77+
);
78+
}
79+
if (
80+
Object.keys(action).filter((f) => f !== 'name' && f !== 'label')
81+
.length > 0
82+
) {
83+
error(
84+
`accessibilityActions: action "${action.name}" contains unrecognised keys`
85+
);
86+
}
87+
});
88+
}
89+
}
90+
} else {
91+
if (hasProp(node.attributes, 'accessibilityActions')) {
92+
error(
93+
'accessibilityActions: has accessibilityActions but onAccessibilityAction is not a function'
94+
);
95+
} else if (hasProp(node.attributes, 'onAccessibilityAction')) {
96+
error(
97+
'accessibilityActions: has onAccessibilityAction function but no accessibilityActions Array'
98+
);
7999
}
80-
} else if (hasProp(node.attributes, 'onAccessibilityAction')) {
81-
error(
82-
'accessibilityActions: has onAccessibilityAction function but no accessibilityActions Array'
83-
);
84100
}
85101
},
86102
}),

0 commit comments

Comments
 (0)