Skip to content

Commit

Permalink
fix(FileUploaderDropContainer): fix a11y violations, update tests (#1…
Browse files Browse the repository at this point in the history
…3323)

* fix(FileUploaderDropContainer): fix a11y violations, update tests

* test(snapshot): update snapshots

* fix(FileUploaderDropContainer): prevent enter key default action

* fix(FileUploaderDropContainer): prevent enter key default action on file

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
tw15egan and kodiakhq[bot] authored Mar 16, 2023
1 parent 591569b commit 8a9c2e9
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 35 deletions.
15 changes: 8 additions & 7 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3168,7 +3168,6 @@ Map {
"multiple": false,
"onAddFiles": [Function],
"pattern": ".[0-9a-z]+$",
"tabIndex": 0,
},
"propTypes": Object {
"accept": Object {
Expand Down Expand Up @@ -3201,15 +3200,14 @@ Map {
"onAddFiles": Object {
"type": "func",
},
"pattern": Object {
"type": "string",
"onClick": Object {
"type": "func",
},
"role": Object {
"pattern": Object {
"type": "string",
},
"tabIndex": Object {
"type": "number",
},
"role": [Function],
"tabIndex": [Function],
},
},
"FileUploaderItem" => Object {
Expand Down Expand Up @@ -3281,6 +3279,9 @@ Map {
"invalid": Object {
"type": "bool",
},
"name": Object {
"type": "string",
},
"status": Object {
"args": Array [
Array [
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/FileUploader/FileUploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ export default class FileUploader extends React.Component {
</p>
<span className={`${prefix}--file__state-container`}>
<Filename
name={name}
iconDescription={iconDescription}
aria-describedby={name}
status={filenameStatus}
onKeyDown={(evt) => {
if (matches(evt, [keys.Enter, keys.Space])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import classNames from 'classnames';
import { keys, matches } from '../../internal/keyboard';
import uniqueId from '../../tools/uniqueId';
import { usePrefix } from '../../internal/usePrefix';
import { composeEventHandlers } from '../../tools/events';
import deprecate from '../../prop-types/deprecate';

function FileUploaderDropContainer({
accept,
Expand All @@ -21,9 +23,8 @@ function FileUploaderDropContainer({
multiple,
name,
onAddFiles,
onClick,
pattern,
role,
tabIndex,
// eslint-disable-next-line react/prop-types
innerRef,
...rest
Expand All @@ -32,13 +33,15 @@ function FileUploaderDropContainer({
const inputRef = useRef(null);
const { current: uid } = useRef(id || uniqueId());
const [isActive, setActive] = useState(false);
const labelClasses = classNames(`${prefix}--file-browse-btn`, {
[`${prefix}--file-browse-btn--disabled`]: disabled,
});
const dropareaClasses = classNames(`${prefix}--file__drop-container`, {
[`${prefix}--file__drop-container--drag-over`]: isActive,
[className]: className,
});
const dropareaClasses = classNames(
`${prefix}--file__drop-container`,
`${prefix}--file-browse-btn`,
{
[`${prefix}--file__drop-container--drag-over`]: isActive,
[`${prefix}--file-browse-btn--disabled`]: disabled,
[className]: className,
}
);

/**
* Filters the array of added files based on file type restrictions
Expand Down Expand Up @@ -79,6 +82,12 @@ function FileUploaderDropContainer({
return onAddFiles(event, { addedFiles });
}

const handleClick = () => {
if (!disabled) {
inputRef.current.click();
}
};

return (
<div
className={`${prefix}--file`}
Expand Down Expand Up @@ -109,21 +118,22 @@ function FileUploaderDropContainer({
setActive(false);
handleChange(evt);
}}>
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
<label
<button
type="button"
className={dropareaClasses}
ref={innerRef}
className={labelClasses}
htmlFor={uid}
tabIndex={tabIndex || 0}
onKeyDown={(evt) => {
if (matches(evt, [keys.Enter, keys.Space])) {
evt.preventDefault();
inputRef.current.click();
}
}}
onClick={composeEventHandlers([onClick, handleClick])}
{...rest}>
<div className={dropareaClasses} role={role || 'button'}>
{labelText}
</div>
{labelText}
</button>
<label htmlFor={uid} className={`${prefix}--visually-hidden`}>
{labelText}
</label>
<input
type="file"
Expand Down Expand Up @@ -187,6 +197,12 @@ FileUploaderDropContainer.propTypes = {
*/
onAddFiles: PropTypes.func,

/**
* Provide an optional function to be called when the button element
* is clicked
*/
onClick: PropTypes.func,

/**
* Provide a custom regex pattern for the acceptedTypes
*/
Expand All @@ -195,16 +211,23 @@ FileUploaderDropContainer.propTypes = {
/**
* Provide an accessibility role for the `<FileUploaderButton>`
*/
role: PropTypes.string,
role: deprecate(
PropTypes.number,
'The `role` prop for `FileUploaderButton` has ' +
'been deprecated since it now renders a button element by default, and has an implicit role of button.'
),

/**
* Provide a custom tabIndex value for the `<FileUploaderButton>`
*/
tabIndex: PropTypes.number,
tabIndex: deprecate(
PropTypes.number,
'The `tabIndex` prop for `FileUploaderButton` has ' +
'been deprecated since it now renders a button element by default.'
),
};

FileUploaderDropContainer.defaultProps = {
tabIndex: 0,
labelText: 'Add file',
multiple: false,
onAddFiles: () => {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ function FileUploaderItem({
</p>
<span className={`${prefix}--file__state-container`}>
<Filename
name={name}
iconDescription={iconDescription}
aria-describedby={name}
status={status}
invalid={invalid}
onKeyDown={(evt) => {
if (matches(evt, [keys.Enter, keys.Space])) {
if (status === 'edit') {
evt.preventDefault();
onDelete(evt, { uuid: id });
}
}
Expand Down
9 changes: 7 additions & 2 deletions packages/react/src/components/FileUploader/Filename.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import React from 'react';
import Loading from '../Loading';
import { usePrefix } from '../../internal/usePrefix';

function Filename({ iconDescription, status, invalid, ...rest }) {
function Filename({ iconDescription, status, invalid, name, ...rest }) {
const prefix = usePrefix();
switch (status) {
case 'uploading':
Expand All @@ -23,7 +23,7 @@ function Filename({ iconDescription, status, invalid, ...rest }) {
<>
{invalid && <WarningFilled className={`${prefix}--file-invalid`} />}
<button
aria-label={iconDescription}
aria-label={`${iconDescription} - ${name}`}
className={`${prefix}--file-close`}
type="button"
{...rest}>
Expand Down Expand Up @@ -57,6 +57,11 @@ Filename.propTypes = {
*/
invalid: PropTypes.bool,

/**
* Name of the uploaded file
*/
name: PropTypes.string,

/**
* Status of the file upload
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@ describe('FileUploader', () => {
);

const complete = getByLabel(container, description);
expect(edit.parentNode).not.toEqual(complete.parentNode);
expect(edit).not.toEqual(complete);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('FileUploaderDropContainer', () => {
const { container } = render(
<FileUploaderDropContainer className="test" />
);
const dropArea = container.querySelector('[role="button"]');
const dropArea = container.querySelector('button');
expect(dropArea.classList.contains('test')).toBe(true);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('FileUploaderItem', () => {
/>
);

let removeFile = getByLabel(edit.container, description);
let removeFile = getByLabel(edit.container, 'test-description - edit');
Simulate.click(removeFile);
expect(onDelete).toHaveBeenCalledTimes(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@ describe('Filename', () => {
const onClick = jest.fn();
const { container: edit } = render(
<Filename
name="File 1"
iconDescription="test description"
status="edit"
onClick={onClick}
/>
);

Simulate.click(edit.querySelector(`[aria-label="test description"]`));
Simulate.click(
edit.querySelector(`[aria-label="test description - File 1"]`)
);
expect(onClick).toHaveBeenCalledTimes(1);

onClick.mockReset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@use '../../theme' as *;
@use '../../type' as *;

@use '../../utilities/button-reset';
@use '../../utilities/convert' as *;
@use '../../utilities/focus-outline' as *;
@use '../../utilities/high-contrast-mode' as *;
Expand Down Expand Up @@ -320,6 +321,8 @@
}

.#{$prefix}--file__drop-container {
@include button-reset.reset;

display: flex;
overflow: hidden;
height: rem(96px);
Expand Down

0 comments on commit 8a9c2e9

Please sign in to comment.