Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Upload] File upload button not keyboard accessible #22141

Closed
2 tasks done
tcx opened this issue Aug 10, 2020 · 8 comments
Closed
2 tasks done

[Upload] File upload button not keyboard accessible #22141

tcx opened this issue Aug 10, 2020 · 8 comments
Labels
accessibility a11y component: button This is the name of the generic UI component, not the React module! component: upload This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation

Comments

@tcx
Copy link

tcx commented Aug 10, 2020

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.
    --> There is this related issue, but the discussion ended up shifting away from the file upload button.

Current Behavior 😯

Following the official file upload button example, once one of the upload button is keyboard focused, pressing on enter or the spacebar does not do anything.

Expected Behavior 🤔

Following the official file upload button example, once one of the upload button is keyboard focused, pressing on enter or the spacebar should open the file selection dialog.

Steps to Reproduce 🕹

Steps:

  1. Go to https://codesandbox.io/s/hidden-currying-e83y7
  2. Click on the browser part of the window.
  3. Press tab once or twice (to respectively select the first or the second button).
  4. Press enter or spacebar, nothing happens.

Context 🔦

This is an accessibility requirement: https://webaim.org/techniques/keyboard/#testing

Your Environment 🌎

Tech Version
Material-UI v4.11.0
React v16.13.1
Browser Firefox 79.0 and Chromium 84.0.4147.89 (on Linux)
@tcx tcx added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Aug 10, 2020
@eps1lon
Copy link
Member

eps1lon commented Aug 10, 2020

I can't reproduce the issue on Ubuntu 18.04.4 LTS with neither Chrome Version 84.0.4147.105 (Official Build) (64-bit) nor Firefox 79.0. Tried it with my existing profile and a new one.

Chrome:
recording in chrome
Firefox
recording in firefox

Maybe some extension is interfering? Can you reproduce this in an incognito tab (or preferably with a new user profile).

It could be caused by a setting in your operating system. In the end user agents decide what elements are keyboard focusable and which aren't. This is not defined universally in a web standard.

@eps1lon eps1lon added accessibility a11y component: button This is the name of the generic UI component, not the React module! status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 10, 2020
@tcx
Copy link
Author

tcx commented Aug 10, 2020

The problem is not about focusability, but about opening the file selection dialog.

  • If you mouse click on the button, you'll get a file selection dialog.
  • There is no way to open the same file selection dialog only with the keyboard.

With a vanilla <input type=file>, opening the file selection dialog can be achieved by focusing on the element and using enter or spacebar.

@eps1lon eps1lon added docs Improvements or additions to the documentation and removed status: waiting for author Issue with insufficient information labels Aug 10, 2020
@eps1lon
Copy link
Member

eps1lon commented Aug 10, 2020

That makes sense, thanks for helping me understand. The markup we have documented is fundamentally flawed since the file input won't even be part of the accessibility tree.

I don't have an easy solution to fix this right now. A standalone component that keeps the focus on <input type="file" /> and implements the desired button styles is probably the best route.

@eps1lon
Copy link
Member

eps1lon commented Aug 10, 2020

Something like https://codesandbox.io/s/e2kv9?file=/demo.js seems viable. Misses color styles and focus-visible specific styling. But keyboard accessibility and :focus styles should work.

@oliviertassinari
Copy link
Member

Should we use this issue as an opportunity to work on a dedicated upload component? At least, if we don't find a simple solution. Ant Design seems to solve the problem by manually triggering the file input https://github.com/react-component/upload/blob/master/src/AjaxUploader.jsx#L32.

I have been collecting comparison points for the Upload component at https://trello.com/c/uKckCoKm/1709-dropzone-upload-component.

@oliviertassinari oliviertassinari added the component: upload This is the name of the generic UI component, not the React module! label Aug 17, 2020
@oliviertassinari oliviertassinari changed the title File upload button not keyboard accessible [Upload] File upload button not keyboard accessible Aug 22, 2020
@eps1lon
Copy link
Member

eps1lon commented May 22, 2021

Closing in favor of https://github.com/mui/material-ui/issues/22434. A dedicated component would fix existing usages which we can't really do with demos.

@eps1lon eps1lon closed this as completed May 22, 2021
Bastian added a commit to Bastian/material-ui that referenced this issue Apr 11, 2023
The upload button example is completely inaccessible by anyone that is
not using a mouse. It lacks both support for keyboard interaction and
drag-and-drop, as well as not appearing in the accessibility tree.

See mui#22141 for a more detailed
discussion of the issue.
Bastian added a commit to Bastian/material-ui that referenced this issue Apr 11, 2023
The upload button example is completely inaccessible by anyone that is
not using a mouse. It lacks both support for keyboard interaction and
drag-and-drop, as well as not appearing in the accessibility tree.

See mui#22141 for a more detailed
discussion of the issue.
@mshahzebraza
Copy link

If anyone is still having this problem, here's a solution for you.

export const FileInput = forwardRef((props: IFileInput, ref) => {
    const inputElementRef = useRef<HTMLInputElement>()
    const {
        label,
    } = props;

    return (
        <Box ref={ref} >
            <Button
                onKeyDownCapture={e => {
                    if (!acceptableTriggerKeyCodes.includes(e.code)) return;
                    inputElementRef.current.click()
                }}
                htmlFor={label}
                component="label"
            >
                {label}

                <input
                    ref={inputElementRef}
                    id={label}
                    hidden
                    type="file"
                />
            </Button>
        </Box>
    );
});

You can use the component with any validation library and it will trigger the input upload against clicks and key events as well.
I've added a check to only allow the Enter and Space key to trigger the upload dialog appear event

@saewitz
Copy link

saewitz commented Nov 28, 2023

Thank you @mshahzebraza, this is what we needed

onKeyDown={(event) => {
    if (['Enter', 'Space'].includes(event.code)) {
        inputRef.current?.click();
    }
}}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accessibility a11y component: button This is the name of the generic UI component, not the React module! component: upload This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation
Projects
None yet
Development

No branches or pull requests

5 participants