[fix] Accessibility ref lists

Generate string-separated values for accessibility props that accept an array
of id strings.

Close #2021
This commit is contained in:
Andrew Hayward
2021-05-13 14:30:20 -07:00
committed by Nicolas Gallagher
parent c9eb794790
commit db9df2b55f
4 changed files with 35 additions and 11 deletions
@@ -53,7 +53,7 @@ Equivalent to [aria-colindex](https://www.w3.org/TR/wai-aria-1.2/#aria-colindex)
Equivalent to [aria-colspan](https://www.w3.org/TR/wai-aria-1.2/#aria-colspan).
{% endcall %}
{% call macro.prop('accessibilityControls', '?string') %}
{% call macro.prop('accessibilityControls', '?(string | Array<string>)') %}
Equivalent to [aria-controls](https://www.w3.org/TR/wai-aria-1.2/#aria-controls).
{% endcall %}
@@ -61,7 +61,7 @@ Equivalent to [aria-controls](https://www.w3.org/TR/wai-aria-1.2/#aria-controls)
Equivalent to [aria-current](https://www.w3.org/TR/wai-aria-1.2/#aria-current).
{% endcall %}
{% call macro.prop('accessibilityDescribedBy', '?string') %}
{% call macro.prop('accessibilityDescribedBy', '?(string | Array<string>)') %}
Equivalent to [aria-describedby](https://www.w3.org/TR/wai-aria-1.2/#aria-describedby).
{% endcall %}
@@ -81,7 +81,7 @@ Equivalent to [aria-errormessage](https://www.w3.org/TR/wai-aria-1.2/#aria-error
Equivalent to [aria-expanded](https://www.w3.org/TR/wai-aria-1.2/#aria-expanded).
{% endcall %}
{% call macro.prop('accessibilityFlowTo', '?string') %}
{% call macro.prop('accessibilityFlowTo', '?(string | Array<string>)') %}
Equivalent to [aria-flowto](https://www.w3.org/TR/wai-aria-1.2/#aria-flowto).
{% endcall %}
@@ -105,7 +105,7 @@ Equivalent to [aria-keyshortcuts](https://www.w3.org/TR/wai-aria-1.2/#aria-keysh
Equivalent to [aria-label](https://www.w3.org/TR/wai-aria-1.2/#aria-label).
{% endcall %}
{% call macro.prop('accessibilityLabelledBy', '?string') %}
{% call macro.prop('accessibilityLabelledBy', '?(string | Array<string>)') %}
Equivalent to [aria-labelledby](https://www.w3.org/TR/wai-aria-1.2/#aria-labelledby).
{% endcall %}
@@ -133,7 +133,7 @@ Equivalent to [aria-multiselectable](https://www.w3.org/TR/wai-aria-1.2/#aria-mu
Equivalent to [aria-orientation](https://www.w3.org/TR/wai-aria-1.2/#aria-orientation).
{% endcall %}
{% call macro.prop('accessibilityOwns', '?string') %}
{% call macro.prop('accessibilityOwns', '?(string | Array<string>)') %}
Equivalent to [aria-owns](https://www.w3.org/TR/wai-aria-1.2/#aria-owns).
{% endcall %}
+1 -1
View File
@@ -35,7 +35,7 @@ export type AccessibilityProps = {|
accessibilityColumnSpan?: ?number,
accessibilityControls?: ?idRefList,
accessibilityCurrent?: ?(boolean | 'page' | 'step' | 'location' | 'date' | 'time'),
accessibilityDescribedBy?: ?idRef,
accessibilityDescribedBy?: ?idRefList,
accessibilityDetails?: ?idRef,
accessibilityDisabled?: ?boolean,
accessibilityErrorMessage?: ?idRef,
@@ -111,6 +111,10 @@ describe('exports/createElement', () => {
createElement('div', { accessibilityControls: 'abc' })
);
expect(getAttribute(hasValue, 'aria-controls')).toBe('abc');
const { container: hasMultipleValues } = render(
createElement('div', { accessibilityControls: ['abc', 'def'] })
);
expect(getAttribute(hasMultipleValues, 'aria-controls')).toBe('abc def');
});
test('accessibilityCurrent', () => {
@@ -131,6 +135,10 @@ describe('exports/createElement', () => {
createElement('div', { accessibilityDescribedBy: 'abc' })
);
expect(getAttribute(hasValue, 'aria-describedby')).toBe('abc');
const { container: hasMultipleValues } = render(
createElement('div', { accessibilityDescribedBy: ['abc', 'def'] })
);
expect(getAttribute(hasMultipleValues, 'aria-describedby')).toBe('abc def');
});
test('accessibilityDetails', () => {
@@ -176,6 +184,10 @@ describe('exports/createElement', () => {
expect(getAttribute(isEmpty, 'aria-flowto')).toBeNull();
const { container: hasValue } = render(createElement('div', { accessibilityFlowTo: 'abc' }));
expect(getAttribute(hasValue, 'aria-flowto')).toBe('abc');
const { container: hasMultipleValues } = render(
createElement('div', { accessibilityFlowTo: ['abc', 'def'] })
);
expect(getAttribute(hasMultipleValues, 'aria-flowto')).toBe('abc def');
});
test('accessibilityHasPopup', () => {
@@ -230,6 +242,10 @@ describe('exports/createElement', () => {
createElement('div', { accessibilityLabelledBy: 'abc' })
);
expect(getAttribute(hasValue, 'aria-labelledby')).toBe('abc');
const { container: hasMultipleValues } = render(
createElement('div', { accessibilityLabelledBy: ['abc', 'def'] })
);
expect(getAttribute(hasMultipleValues, 'aria-labelledby')).toBe('abc def');
});
test('accessibilityLevel', () => {
@@ -293,6 +309,10 @@ describe('exports/createElement', () => {
expect(getAttribute(isEmpty, 'aria-owns')).toBeNull();
const { container: hasValue } = render(createElement('div', { accessibilityOwns: 'abc' }));
expect(getAttribute(hasValue, 'aria-owns')).toBe('abc');
const { container: hasMultipleValues } = render(
createElement('div', { accessibilityOwns: ['abc', 'def'] })
);
expect(getAttribute(hasMultipleValues, 'aria-owns')).toBe('abc def');
});
test('accessibilityPlaceholder', () => {
@@ -15,6 +15,7 @@ import { STYLE_GROUPS } from '../../exports/StyleSheet/constants';
const emptyObject = {};
const hasOwnProperty = Object.prototype.hasOwnProperty;
const isArray = Array.isArray;
const uppercasePattern = /[A-Z]/g;
function toHyphenLower(match) {
@@ -23,6 +24,9 @@ function toHyphenLower(match) {
function hyphenateString(str: string): string {
return str.replace(uppercasePattern, toHyphenLower);
}
function processIDRefList(idRefList: string | Array<string>): string {
return isArray(idRefList) ? idRefList.join(' ') : idRefList;
}
// Reset styles for heading, link, and list DOM elements
const classes = css.create(
@@ -193,13 +197,13 @@ const createDOMProps = (elementType, props) => {
domProps['aria-colspan'] = accessibilityColumnSpan;
}
if (accessibilityControls != null) {
domProps['aria-controls'] = accessibilityControls;
domProps['aria-controls'] = processIDRefList(accessibilityControls);
}
if (accessibilityCurrent != null) {
domProps['aria-current'] = accessibilityCurrent;
}
if (accessibilityDescribedBy != null) {
domProps['aria-describedby'] = accessibilityDescribedBy;
domProps['aria-describedby'] = processIDRefList(accessibilityDescribedBy);
}
if (accessibilityDetails != null) {
domProps['aria-details'] = accessibilityDetails;
@@ -224,7 +228,7 @@ const createDOMProps = (elementType, props) => {
domProps['aria-expanded'] = accessibilityExpanded;
}
if (accessibilityFlowTo != null) {
domProps['aria-flowto'] = accessibilityFlowTo;
domProps['aria-flowto'] = processIDRefList(accessibilityFlowTo);
}
if (accessibilityHasPopup != null) {
domProps['aria-haspopup'] = accessibilityHasPopup;
@@ -242,7 +246,7 @@ const createDOMProps = (elementType, props) => {
domProps['aria-label'] = accessibilityLabel;
}
if (accessibilityLabelledBy != null) {
domProps['aria-labelledby'] = accessibilityLabelledBy;
domProps['aria-labelledby'] = processIDRefList(accessibilityLabelledBy);
}
if (accessibilityLevel != null) {
domProps['aria-level'] = accessibilityLevel;
@@ -263,7 +267,7 @@ const createDOMProps = (elementType, props) => {
domProps['aria-orientation'] = accessibilityOrientation;
}
if (accessibilityOwns != null) {
domProps['aria-owns'] = accessibilityOwns;
domProps['aria-owns'] = processIDRefList(accessibilityOwns);
}
if (accessibilityPlaceholder != null) {
domProps['aria-placeholder'] = accessibilityPlaceholder;