Skip to content

Commit

Permalink
fix(FileUploader): fix a11y issues (#3643)
Browse files Browse the repository at this point in the history
* fix(FileUploader): interactive elements no longer nested
* style(FileUploader): make dropzone text only use two lines
* fix(FileUploader): unnecessary aria label removed
* test(FileUploader): updated
  • Loading branch information
MEsteves22 committed Aug 25, 2023
1 parent b770c4e commit 9cab4b8
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const { staticClasses, useClasses } = createClasses("HvDropZone", {
border: `1px ${theme.fileUploader.dropZone.borderType} ${theme.colors.secondary}`,
},

"&:focus": {
"&:focus-within": {
background: `${theme.colors.atmo1}`,
border: `1px ${theme.fileUploader.dropZone.borderType} ${theme.colors.secondary}`,
...outlineStyles,
Expand Down Expand Up @@ -72,7 +72,7 @@ export const { staticClasses, useClasses } = createClasses("HvDropZone", {
},
dropZoneAreaLabels: {
display: "flex",
width: 115,
maxWidth: 120,
margin: "auto",
},
dropZoneAreaIcon: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,28 @@ const props: HvDropZoneProps = {
labels: {
dropzone: "Label",
sizeWarning: "Max. file size:",
acceptedFiles: "Accepted files:",
drag: "Drag and drop or",
selectFiles: "Select files",
dropFiles: "Drop files here",
fileSizeError: "The file exceeds the maximum upload size",
fileTypeError: "File type not allowed for upload",
},
acceptedFiles: [],
acceptedFiles: ["jpg"],
maxFileSize: 1,
};

describe("DropZone", () => {
it("should render drop zone button and labels", () => {
it("should render drop zone input and labels", () => {
render(<HvDropZone {...props} />);

expect(screen.getByText("Select files")).toBeInTheDocument();
expect(screen.getByText("Label", { selector: "label" })).toBeVisible();
expect(
screen.getByRole("button", { name: /Drag and drop or Select files/i })
screen.getByText("Max. file size: 1.00B (jpg)", { selector: "label" })
).toBeVisible();
expect(screen.getByText("Drag and drop or")).toBeVisible();
expect(screen.getByText("Select files")).toBeVisible();
expect(
screen.getByLabelText("Label", { selector: "input" })
).toBeInTheDocument();
});
});
69 changes: 28 additions & 41 deletions packages/core/src/components/FileUploader/DropZone/DropZone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import uniqueId from "lodash/uniqueId";

import accept from "attr-accept";

import { isKey } from "@core/utils/keyboardUtils";
import { setId } from "@core/utils/setId";
import { useUniqueId } from "@core/hooks/useUniqueId";

Expand Down Expand Up @@ -161,11 +160,7 @@ export const HvDropZone = ({
return (
<>
{!hideLabels && (
<div
id={id}
className={classes.dropZoneLabelsGroup}
aria-label="File Dropzone"
>
<div id={id} className={classes.dropZoneLabelsGroup}>
<HvLabel
id={setId(id, "input-file-label")}
htmlFor={setId(id, "input-file")}
Expand All @@ -183,48 +178,14 @@ export const HvDropZone = ({
</div>
)}
<div
id={setId(id, "button")}
id={setId(id, "input-file-container")}
className={cx(classes.dropZoneContainer, {
[classes.dragAction]: dragState,
[classes.dropZoneContainerDisabled]: disabled,
})}
role="button"
tabIndex={0}
onDragEnter={(event) => {
if (!disabled) {
enterDropArea();
event.stopPropagation();
event.preventDefault();
}
}}
onDragLeave={leaveDropArea}
onDropCapture={leaveDropArea}
onDragOver={(event) => {
if (!disabled) {
enterDropArea();
event.stopPropagation();
event.preventDefault();
}
}}
onDrop={(event) => {
if (!disabled) {
const { files } = event.dataTransfer;
if (multiple === true || files.length === 1) {
event.stopPropagation();
event.preventDefault();
onChangeHandler(files);
}
}
}}
onKeyDown={(e) => {
if (isKey(e, "Enter") || isKey(e, "Space")) {
inputRef.current?.click();
}
}}
>
<input
id={setId(id, "input-file")}
tabIndex={-1}
className={classes.inputArea}
type="file"
multiple={multiple}
Expand All @@ -240,6 +201,32 @@ export const HvDropZone = ({
onChangeHandler(inputRef.current.files);
}
}}
onDragEnter={(event) => {
if (!disabled) {
enterDropArea();
event.stopPropagation();
event.preventDefault();
}
}}
onDragLeave={leaveDropArea}
onDropCapture={leaveDropArea}
onDragOver={(event) => {
if (!disabled) {
enterDropArea();
event.stopPropagation();
event.preventDefault();
}
}}
onDrop={(event) => {
if (!disabled) {
const { files } = event.dataTransfer;
if (multiple === true || files.length === 1) {
event.stopPropagation();
event.preventDefault();
onChangeHandler(files);
}
}
}}
ref={inputRef}
accept={acceptedFiles.join(",")}
{...inputProps}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@ describe("FileUploader", () => {
it("should render the dropzone", () => {
render(<Main {...baseProps} />);

const dropZone = screen.getByRole("button", { name: /Label/ });
const dropZone = screen.getByLabelText("Label", { selector: "input" });

expect(dropZone).toBeVisible();
expect(dropZone).toBeInTheDocument();
});

it("should call file upload callback", () => {
const onFilesAddedMock = vi.fn();

render(<Main {...baseProps} onFilesAdded={onFilesAddedMock} />);

const dropZone = screen.getByRole("button", { name: /Label/ });
const dropZone = screen.getByLabelText("Label", { selector: "input" });

fireEvent.change(dropZone.querySelector("input") as Element, {});
fireEvent.change(dropZone, {});

expect(onFilesAddedMock).toHaveBeenCalled();
});
Expand Down

0 comments on commit 9cab4b8

Please sign in to comment.