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

Allow disabled items to be focused #3662

Closed
mlshv opened this issue Oct 19, 2022 · 11 comments · Fixed by #6435
Closed

Allow disabled items to be focused #3662

mlshv opened this issue Oct 19, 2022 · 11 comments · Fixed by #6435

Comments

@mlshv
Copy link

mlshv commented Oct 19, 2022

🙋 Feature Request

I am using useLink and useButton hooks from react-aria, but I've noticed that if those are disabled, element doesn't get focus. According to this thread on stackexachange:

If disabled buttons are not focusable with TAB, our user would occasionally miss that the button ever exists, and they will never find it.

So I'd like to be able to enable focus on disabled elements like links or buttons.

🔦 Context

There are situations when a screenreader user wouldn't know about a UI element which is disabled.

💻 Examples

Disabled button is not focusable: https://react-spectrum.adobe.com/react-aria/useButton.html

@snowystinger
Copy link
Member

snowystinger commented Oct 19, 2022

Related #1696

Can you tell us more about your use case?

One thing to note is that if you have a control that is focusable, it must meet contrast ratio requirements. It can be hard to design a control that both looks disabled and meets contrast requirements.

@frontsideair
Copy link
Contributor

I'm also affected by this, using Button from react-aria-components. I'm surprised that the types allow adding an aria-disabled prop but it doesn't show up on DOM.

I was implementing this technique to make soft disabled buttons, but it doesn't work since the prop is discarded.

My use case is similar to the one in the article, I want to disable the form submit button for a progressively enhanced submit is in progress, but don't want the user to lose focus.

@snowystinger
Copy link
Member

We suggest using something like https://spectrum.adobe.com/page/contextual-help/ (as mentioned here https://react-spectrum.adobe.com/react-aria/Tooltip.html#accessibility) to help users understand that there is a disabled button and why it is disabled. Tooltips are not a fully accessible way to share information (touch users cannot see it) and as such, shouldn't be used to convey critical information such as the criteria for a field to be valid.

You could also use form validation and inline messaging to convey this to all users. something like https://spectrum.adobe.com/page/help-text/

@frontsideair
Copy link
Contributor

It may be possible to use contextual help to give the same information aria-disabled would provide, but I have to check with a screen reader first. Validation wouldn’t help though, as my use case is not related to validity of field values, just the busy state and why the button can’t be pressed while it’s submitting. (I’m not considering using tooltips by the way, for the said reasons.)

@snowystinger
Copy link
Member

Ah, I see, the link you shared described a submit button which was disabled until the form was valid. But your actual use case is that the form is complete and you're actively submitting something.
We just introduced this for React Spectrum components https://react-spectrum.adobe.com/react-spectrum/Button.html#pending I'm not sure if we have a plan to bring it over to RAC yet. Let me check with our team.

@frontsideair
Copy link
Contributor

I understand the confusion now, and I should've been more specific about the part I was referring to, there's a section that handles both incomplete and submitting states, and I thought aria-disabled would be good fit for this reason. (I don't use it for incomplete forms, relying on native constraint validation first and then server-side validation.)

Pending state for React Spectrum button seems perfect for my use case, as it seems to set aria-disabled and has a live region announcement. Can't wait for it to land on RAC too!

@snowystinger
Copy link
Member

You don't have to wait for it to land in RAC, you can create a RAC compatible button based on the hooks as described here https://react-spectrum.adobe.com/react-aria/Button.html#advanced-customization and you can include the little extra logic we incorporated into the Spectrum component there

@joonass-visma
Copy link

@snowystinger What's the status with having this for RAC? All we would need is to either allow aria-disabled to get passed for given component or having some prop like focusableWhenDisabled which would use aria-disabled instead of disabled when isDisabled prop is set.

@will-stone
Copy link

I have found a few tweaks to achieve "pending" like behaviour. Here's a stripped-back example, where we use isLoading as our pending indicator.

import { Button as RACButton } from "react-aria-components"
import clsx from "clsx"

export const Button = ({
  children,
  isDisabled = false,
  isLoading = false,
  onPress,
  type = "button",
}) => {
  const handlePress = (event) => {
    // Prevent usual press event when loading.
    if (!isLoading && onPress) {
      onPress(event)
    }
  }

  const isVisuallyDisabled = isLoading || isDisabled

  return (
    <RACButton
      className={clsx(isVisuallyDisabled ? "bg-gray-500" : "bg-blue-500")}
      isDisabled={
        // Override the disabled prop if loading, as this would circumvent
        // the efforts used to make this work correctly with screen-readers.
        !isLoading && isDisabled
      }
      onPress={handlePress}
      type={
        // Stop form submission when loading.
        isLoading ? "button" : type
      }
    >
      {isLoading ? <span>Loading</span> : children}
    </RACButton>
  )
}

Our tests are passing but please let me know if I missed something glaringly obvious 😖

@snowystinger
Copy link
Member

It's currently in progress RAC Pending Button

Note that in your example @will-stone that many screen reader/browser combinations will not read the updated label. It's not your fault, there is very poor support for this. Safari + VO will not announce anything.

We're still testing the PR, but hopefully it'll land soon and then you won't need to worry about things like that.

@snowystinger snowystinger mentioned this issue Aug 21, 2024
5 tasks
@will-stone
Copy link

You're right! I was testing in Firefox which worked perfectly. Even using aria-busy didn't work 😭 Well, at least my button keeps keyboard focus so... small wins 🤷‍♂️ Happy to see it's coming to RAC. Thank you 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants