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

Using TooltipV2 always sets aria associations on first child element #4525

Closed
marywhite opened this issue Apr 22, 2024 · 11 comments
Closed

Using TooltipV2 always sets aria associations on first child element #4525

marywhite opened this issue Apr 22, 2024 · 11 comments
Assignees
Labels
component: Tooltip Issues related to the Tooltip component react

Comments

@marywhite
Copy link
Contributor

I have a use case where I'd like to use <TooltipV2 /> with a label as the trigger element. In this scenario, the label element serves as the mouse target for a radio input. This results in aria-labelledby / aria-describedby (depending on the variant) getting set on the label element.

Example markup (removing style and class attributes):

<label aria-labelledby=":r8e:">
  <input type="radio" name=":r8d:" aria-checked="true" aria-required="false" aria-invalid="false" value="PINK" checked="">
  <span class="VisuallyHidden">Pink</span>
  <svg aria-hidden="true" focusable="false" role="img" class="octicon octicon-check-circle-fill"></svg>
</label>
<span data-direction="s" aria-hidden="true" id=":r8e:" popover="auto">Pink</span>

I'd like to instead set aria-describedby / aria-labelledby on the input element. Is this a pattern that could be considered for the TooltipV2 API?

@broccolinisoup broccolinisoup self-assigned this Apr 22, 2024
@broccolinisoup broccolinisoup added the component: Tooltip Issues related to the Tooltip component label Apr 22, 2024
@siddharthkp
Copy link
Member

siddharthkp commented Apr 23, 2024

Hi @marywhite! Thanks for taking the time to file an issue!

I think we usually discourage using tooltips in Forms in favor of visible captions (cc @mperrotti and @khiga8 to add nuance if needed!)

Questions for you:

  1. What is the tooltip used for, what additional information does it provide?
  2. Should that be visible information for all users using FormControl.Caption?

Screenshot of FormControl with caption


Some information for maintainers:

(Not sure if this is a good idea yet)

If you are using FormControl, the label should have a for attribute pointing to the input. However, when the label itself has aria-labelledby=<tooltip-id>, assistive technologies unfortunately don't follow that trail. It leaves the input without a label instead!

On our end, we can explore a solution where Tooltip and FormControl know of each other and wire up aria-describedby attribute on the input instead of the label (I don't think the input should be labelled by a tooltip)

Before we get into that, we first need to verify if this is a good direction from the view of design and accessibility.

This comment has been minimized.

@khiga8
Copy link
Contributor

khiga8 commented Apr 23, 2024

@siddharthkp Agreed that always persistent visible labels are preferred whenever possible. In scenarios where having a persistent label is difficult (e.g. there is no space in the design), then we recommend at least having a tooltip provide a visible label (*with the caveat that some mobile users may still not be able to access it). The same concern applies for things like Icon Buttons

Here's a screenshot of the scenario we're looking at. This may require some design input/updates to move to persistent labels 👀 .

Screenshot of tooltips providing a visible label for selecting colors via radio buttons. These radio buttons are lined horizontally

@siddharthkp
Copy link
Member

siddharthkp commented Apr 26, 2024

Ah I see! I should have asked for the use case before I suggested FormControl, my bad 😅

@broccolinisoup Do you have ideas?

Also, does this trigger validation rules for interactive elements if we wrap it around the label instead of input? https://github.com/primer/react/blob/main/packages/react/src/TooltipV2/Tooltip.tsx#L171-L186

The same concern applies for things like Icon Buttons

Sorry, can you tell me a bit more? @khiga8

@marywhite
Copy link
Contributor Author

@siddharthkp - the radio input is a child of the label, so I think it bypasses that validation. I wonder if the label could be considered interactive in this case though, as HTML labels support mouse events to select the corresponding radio control.

@khiga8
Copy link
Contributor

khiga8 commented Apr 26, 2024

Sorry, can you tell me a bit more? @khiga8

@siddharthkp sorry my wording might've been confusing! Whenever we use a control represented by only be an icon, it is ideally supplemented by a tooltip so that users have access to a text alternative in scenarios where the meaning of the icon isn't clear! In this scenario, some color blind users may have trouble selecting the color so tooltips provide value. I believe in PVC (and maybe Primer React?), IconButtons come with a tooltip by default for this reason. That said, tooltips still do come with the caveat that mobile users might not have access, so persistent text is the most accessible.

@siddharthkp siddharthkp self-assigned this Apr 29, 2024
@siddharthkp
Copy link
Member

@khiga8 thanks for the explanation, now I understand 😇

the radio input is a child of the label, so I think it bypasses that validation

Ah, I didn't realise the check also includes nested children. very cool @broccolinisoup!

I wonder if the label could be considered interactive in this case though, as HTML labels support mouse events to select the corresponding radio control.

Yep, same! Happy to follow @broccolinisoup's or @khiga8's lead on this

@siddharthkp
Copy link
Member

siddharthkp commented Apr 30, 2024

Back to the problem at hand, I see two options:

  1. Bake it into Tooltip

    If this is a repeatable pattern we make Tooltip aware of labels and "search" for the input to wire attributes instead of the label.

    I'm not very confident of this approach because we would need to make this work not just with FormControl (predictable usage) but also with custom labels, which makes it a bit unpredictable to do right. Can be done, but maybe not worth the effort if we have option 2?

  2. Wire up the label + input manually

    You can pass your own id to the Tooltip and it will use that instead of an auto-generated one. This way, you have a reliable id that you can use to manually set aria-attributes on the input.

    That still leaves the part where Tooltip should not set the same aria-attributes on the label because we already set them on the input. To do that, you can create a local/custom label component that accepts all props (including ones coming from Tooltip) but "skips" adding aria-labelledby and aria-describedby on the <label> element

Let me know if this is confusing, happy to set up a small prototype!

Can you also link to the code that you are using for this implementation, just to make sure I understand the details correctly.

@marywhite
Copy link
Contributor Author

@siddharthkp thank you for the suggestion! I had not though of using a custom label element to remove these aria attributes. I went ahead and implemented this in https://github.com/github/github/pull/323137. Let me know if this aligns with what you were thinking!

@broccolinisoup
Copy link
Member

Hello 👋

Sorry for the late reply! Love what @siddharthkp suggested ✨ and glad to hear that it is working for your case @marywhite.

If this is a repeatable pattern we make Tooltip aware of labels and "search" for the input to wire attributes instead of the label.

I like this! I would say we should wait to see if there are other similar cases then can look into baking into Tooltip. @marywhite if your issue is resolved and you don't have further questions, can I close the issue?

@marywhite
Copy link
Contributor Author

Yes, thanks @broccolinisoup! Feel free to close 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: Tooltip Issues related to the Tooltip component react
Projects
None yet
Development

No branches or pull requests

4 participants