@q42/tslint-react-native-a11y
Advanced tools
Comparing version 0.0.2 to 0.1.0
{ | ||
"name": "@q42/tslint-react-native-a11y", | ||
"version": "0.0.2", | ||
"description": "TSLint rules to enhance accessibility in React Native apps.", | ||
"name": "@q42/tslint-react-native-a11y", | ||
"version": "0.1.0", | ||
"description": "TSLint rules to enhance accessibility in React Native apps.", | ||
"private": false, | ||
"scripts": { | ||
"build": "tsc", | ||
"prepare": "yarn build", | ||
"test": "yarn test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Q42/tslint-react-native-a11y.git" | ||
}, | ||
"keywords": [ | ||
"tslint", | ||
"a11y", | ||
"accessibility", | ||
"q42", | ||
"react", | ||
"native" | ||
], | ||
"build": "tsc", | ||
"prepare": "yarn build", | ||
"test": "yarn test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Q42/tslint-react-native-a11y.git" | ||
}, | ||
"keywords": [ | ||
"tslint", | ||
"a11y", | ||
"accessibility", | ||
"q42", | ||
"react", | ||
"native" | ||
], | ||
"main": "./index.js", | ||
"author": "Jimmy (jimmy@q42.nl)", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/Q42/tslint-react-native-a11y/issues" | ||
}, | ||
"author": "Jimmy (jimmy@q42.nl)", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/Q42/tslint-react-native-a11y/issues" | ||
}, | ||
"files": [ | ||
@@ -34,8 +34,9 @@ "./rules", | ||
"homepage": "https://github.com/Q42/tslint-react-native-a11y#readme", | ||
"devDependencies": { | ||
"@types/node": "^12.7.1", | ||
"tslint": "^5.18.0", | ||
"tsutils": "^3.17.1", | ||
"typescript": "^3.5.3" | ||
} | ||
"devDependencies": { | ||
"@types/node": "^12.7.1", | ||
"prettier": "^1.18.2", | ||
"tslint": "^5.18.0", | ||
"tsutils": "^3.17.1", | ||
"typescript": "^3.5.3" | ||
} | ||
} |
@@ -63,11 +63,12 @@ "use strict"; | ||
Rule.metadata = { | ||
ruleName: 'accessible-touchable', | ||
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = __makeTemplateObject(["Warn if a touchable component misses an accessibility property."], ["Warn if a touchable component misses an accessibility property."]))), | ||
ruleName: 'tsx-a11y-touchables', | ||
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = __makeTemplateObject(["Warn if a touchable component misses accessible properties."], ["Warn if a touchable component misses accessible properties."]))), | ||
options: null, | ||
optionsDescription: '', | ||
optionExamples: ['true'], | ||
optionsDescription: 'Not configurable.', | ||
type: 'functionality', | ||
typescriptOnly: false, | ||
}; | ||
Rule.FAILURE_STRING = 'Touchable component misses an accessible / accessibilityLabel attribute.'; | ||
Rule.FAILURE_STRING_ACCESSIBLE = 'Touchable component misses accessible property.'; | ||
Rule.FAILURE_STRING_ACCESSIBILITYLABEL = 'Touchable and accessible component misses accessibilityLabel property.'; | ||
Rule.FAILURE_STRING_ACCESSIBILITYROLE = 'Touchable and accessible component misses accessibilityRole property.'; | ||
return Rule; | ||
@@ -78,41 +79,48 @@ }(Lint.Rules.AbstractRule)); | ||
return ts.forEachChild(ctx.sourceFile, function cb(node) { | ||
if (_3_0_1.isJsxElement(node) || _3_0_1.isJsxSelfClosingElement(node)) { | ||
checkElement(node, ctx); | ||
if (_3_0_1.isJsxElement(node) && isTouchableComponent(node.openingElement.tagName)) { | ||
assertAccessibilityProperties(ctx, node, node.openingElement.attributes); | ||
} | ||
if (_3_0_1.isJsxSelfClosingElement(node) && isTouchableComponent(node.tagName)) { | ||
assertAccessibilityProperties(ctx, node, node.attributes); | ||
} | ||
return ts.forEachChild(node, cb); | ||
}); | ||
} | ||
function checkElement(node, ctx) { | ||
if (_3_0_1.isJsxElement(node) && | ||
isTouchableComponent(node.openingElement.tagName) && | ||
!hasAccessibilityAttributes(node.openingElement.attributes) && | ||
!hasAccessibilityAttributesSpread(node.openingElement.attributes)) { | ||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING); | ||
function isTouchableComponent(tagName) { | ||
return (_3_0_1.isIdentifier(tagName) && | ||
tagName.escapedText | ||
.toString() | ||
.toLowerCase() | ||
.startsWith('touchable')); | ||
} | ||
var propsToCheck = ['accessible', 'accessibilityLabel', 'accessibilityRole']; | ||
function assertAccessibilityProperties(ctx, node, attributes) { | ||
var props = attributes.properties.filter(function (prop) { return _3_0_1.isJsxAttribute(prop) && propsToCheck.some(function (s) { return s === prop.name.text; }); }); | ||
/** | ||
* Assert accessible property | ||
*/ | ||
var accessibleAttribute = props.find(function (prop) { return prop.name.text === 'accessible'; }); | ||
if (!accessibleAttribute || | ||
!accessibleAttribute.initializer || | ||
!_3_0_1.isJsxExpression(accessibleAttribute.initializer)) { | ||
return ctx.addFailureAtNode(node, Rule.FAILURE_STRING_ACCESSIBLE); | ||
} | ||
if (_3_0_1.isJsxSelfClosingElement(node) && | ||
isTouchableComponent(node.tagName) && | ||
!hasAccessibilityAttributes(node.attributes) && | ||
!hasAccessibilityAttributesSpread(node.attributes)) { | ||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING); | ||
var expression = accessibleAttribute.initializer.expression; | ||
var isValueFalse = expression !== undefined && expression.kind === ts.SyntaxKind.FalseKeyword; | ||
if (isValueFalse) { | ||
return; | ||
} | ||
/** | ||
* Assert accessibilityLabel property | ||
*/ | ||
if (!props.some(function (prop) { return prop.name.text === 'accessibilityLabel'; })) { | ||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_ACCESSIBILITYLABEL); | ||
} | ||
/** | ||
* Assert accessibilityLabel property | ||
*/ | ||
if (!props.some(function (prop) { return prop.name.text === 'accessibilityRole'; })) { | ||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_ACCESSIBILITYROLE); | ||
} | ||
} | ||
function isTouchableComponent(tagName) { | ||
return _3_0_1.isIdentifier(tagName) && tagName.escapedText.toString().startsWith('Touchable'); | ||
} | ||
function hasAccessibilityAttributes(attributes) { | ||
return (attributes.properties | ||
.map(function (prop) { return _3_0_1.isJsxAttribute(prop) && prop.name.text === 'accessibilityLabel'; }) | ||
.indexOf(true) !== -1); | ||
} | ||
function hasAccessibilityAttributesSpread(attributes) { | ||
return attributes.properties.some(function (prop) { | ||
return _3_0_1.isJsxSpreadAttribute(prop) && | ||
_3_0_1.isObjectLiteralExpression(prop.expression) && | ||
prop.expression.properties.some(function (expProp) { | ||
return expProp.name !== undefined && | ||
_3_0_1.isIdentifier(expProp.name) && | ||
expProp.name.text === 'accessibilityLabel'; | ||
}); | ||
}); | ||
} | ||
var templateObject_1; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
9647
155
0
5