Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/selfish-drinks-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

Tooltip (draft): Do not expose the tooltip text to AT when it is not visible
76 changes: 30 additions & 46 deletions src/drafts/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,6 @@ import {getAnchoredPosition} from '@primer/behaviors'
import type {AnchorSide, AnchorAlignment} from '@primer/behaviors'
import {isSupported, apply} from '@oddbird/popover-polyfill/fn'

// Reusable styles to use for :popover-open (Chrome, Edge) and \:popover-open (Safari, Firefox) classes
const popoverStyles = `
padding: 0.5em 0.75em;
width: max-content;
height: fit-content;
margin: auto;
clip: auto;
white-space: normal;
/* for scrollbar */
overflow: visible;
`

const animationStyles = `
animation-name: tooltip-appear;
animation-duration: 0.1s;
Expand All @@ -32,43 +20,39 @@ const animationStyles = `
`

const StyledTooltip = styled.div`
/* tooltip element should be rendered visually hidden when it is not opened. */
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
position: fixed;
font: normal normal 11px/1.5 ${get('fonts.normal')};
-webkit-font-smoothing: subpixel-antialiased;
color: ${get('colors.fg.onEmphasis')};
text-align: center;

word-wrap: break-word;
background: ${get('colors.neutral.emphasisPlus')}; //bg--emphasis-color
border-radius: ${get('radii.2')};
border: 0;
opacity: 0;
max-width: 250px;
inset: auto;

@media (forced-colors: active) {
outline: 1px solid transparent;
/* Overriding the default popover styles */
display: none;
&[popover] {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was needed for firefox. Otherwise the styles wasn't applied due to [popover] having more specificity than the styled component's class name.

Copy link
Member Author

@broccolinisoup broccolinisoup Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trick caused a bit of a flashing though.

Rewatch.Screen.Recording.-.2023-11-07.at.12.15.mp4

Video description: There is a "Delete" button and the page is reloaded. The tooltip text without any styles appears right under the button very briefly like flashing then disappears

And if I load the style component (the tooltip element itself) with display: 'none' and then add display: 'block' when it is open, the flash is gone (commit for changes) but I am not sure if this is a good way to solve this. Let me know if you have any a way of solving this already or any other thoughts!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reasonable for now. The polyfill injecting CSS means that we suffer from a FOUC, which is also true for dotcom today. I'm looking into ways to minimise or remove the FOUC but given it's only Firefox, and Firefox will soon be shipping native popovers, it's not a blocking concern.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if I load the style component (the tooltip element itself) with display: 'none' and then add display: 'block' when it is open

I kinda like this as a temporary measure but also if the flash only happens in firefox, we can choose to ignore it. No strong feelings, up to you

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify, the fix that needed for firefox was adding the [popover] attribute selector to the class styling but this addition caused flashing in all browsers. So I guess it is better to keep it until Firefox catches up.

padding: 0.5em 0.75em;
width: max-content;
margin: auto;
clip: auto;
white-space: normal;
font: normal normal 11px/1.5 ${get('fonts.normal')};
-webkit-font-smoothing: subpixel-antialiased;
color: ${get('colors.fg.onEmphasis')};
text-align: center;
word-wrap: break-word;
background: ${get('colors.neutral.emphasisPlus')};
border-radius: ${get('radii.2')};
border: 0;
opacity: 0;
max-width: 250px;
inset: auto;
/* for scrollbar */
overflow: visible;
}
/* pollyfil */
z-index: 2147483647;
display: block;

/* class name in chrome is :popover-open */
&:popover-open {
${popoverStyles}
&[popover]:popover-open {
display: block;
}

/* class name in firefox and safari is \:popover-open */
&.\\:popover-open {
${popoverStyles}
&[popover].\\:popover-open {
display: block;
}

@media (forced-colors: active) {
outline: 1px solid transparent;
}

// This is needed to keep the tooltip open when the user leaves the trigger element to hover tooltip
Expand Down Expand Up @@ -284,7 +268,7 @@ export const Tooltip = React.forwardRef(

return (
<TooltipContext.Provider value={{tooltipId}}>
<Box sx={{display: 'inline-block'}} onMouseLeave={() => closeTooltip()}>
<Box onMouseLeave={() => closeTooltip()}>
{React.isValidElement(child) &&
React.cloneElement(child as React.ReactElement<TriggerPropsType>, {
ref: triggerRef,
Expand Down