Open mlshv opened 1 year ago
Related https://github.com/adobe/react-spectrum/issues/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.
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.
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/
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.)
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.
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!
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
@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.
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 π
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.
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 π
π 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:
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