Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
7 changes: 7 additions & 0 deletions packages/react/src/Button/IconButton.features.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,10 @@ export const KeybindingHintOnDescription = () => (
)

export const KeybindingHint = () => <IconButton icon={BoldIcon} aria-label="Bold" keybindingHint="Mod+B" />

export const LongDelayedTooltip = () => (
// Ideal for cases where we don't want to show the tooltip immediately — for example, when the user is just passing over the element.
<Tooltip text="This is a tooltip with 1200ms delay" delay="long">
<IconButton icon={HeartIcon} aria-label="HeartIcon" />
Comment thread
broccolinisoup marked this conversation as resolved.
</Tooltip>
)
26 changes: 25 additions & 1 deletion packages/react/src/TooltipV2/Tooltip.features.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import {IconButton, Button, Link, ActionMenu, ActionList, VisuallyHidden} from '..'
import Octicon from '../Octicon'
import {Tooltip} from './Tooltip'
import {SearchIcon, BookIcon, CheckIcon, TriangleDownIcon, GitBranchIcon, InfoIcon} from '@primer/octicons-react'
import {
SearchIcon,
BookIcon,
CheckIcon,
TriangleDownIcon,
GitBranchIcon,
InfoIcon,
HeartIcon,
} from '@primer/octicons-react'
import classes from './Tooltip.features.stories.module.css'

export default {
Expand Down Expand Up @@ -194,3 +202,19 @@ export const KeybindingHint = () => (
</Tooltip>
</div>
)

export const WithMediumDelay = () => (
<div className={classes.PaddedContainer}>
<Tooltip text="Tooltip is delayed by 600ms" delay="medium">
Comment thread
broccolinisoup marked this conversation as resolved.
Outdated
<Button>With delay</Button>
</Tooltip>
</div>
)

export const WithLongDelay = () => (
<div className={classes.PaddedContainer}>
<Tooltip text="Tooltip is delayed by 1200ms" delay="long">
<IconButton icon={HeartIcon} variant="invisible" aria-label="Favorite" />
</Tooltip>
</div>
)
29 changes: 26 additions & 3 deletions packages/react/src/TooltipV2/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ export type TooltipProps = React.PropsWithChildren<
text: string
type?: 'label' | 'description'
keybindingHint?: KeybindingHintProps['keys']
/**
* Delay in milliseconds before showing the tooltip
* @default instant 50ms
* medium 400ms
* long 1200ms

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we leave a comment on how we picked these numbers?

They feel arbitrary in code so it would be nice to have the context (or a link to the context) so that, in the future when someone wants to change these, they have more information

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, good idea! I'll add some context.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

*/
delay?: 'instant' | 'medium' | 'long'
Comment thread
broccolinisoup marked this conversation as resolved.
Outdated
} & SxProp
> &
React.HTMLAttributes<HTMLElement>
Expand Down Expand Up @@ -83,7 +90,17 @@ export const TooltipContext = React.createContext<{tooltipId?: string}>({})

export const Tooltip = React.forwardRef(
(
{direction = 's', text, type = 'description', children, id, className, keybindingHint, ...rest}: TooltipProps,
{
direction = 's',
text,
type = 'description',
children,
id,
className,
keybindingHint,
delay = 'instant',
...rest
}: TooltipProps,
forwardedRef,
) => {
const tooltipId = useId(id)
Expand Down Expand Up @@ -284,14 +301,20 @@ export const Tooltip = React.forwardRef(
child.props.onFocus?.(event)
},
onMouseOverCapture: (event: React.MouseEvent) => {
const delayTimeMap = {
instant: 50,
medium: 400,
long: 1200,
}
const delayTime = delayTimeMap[delay] || 50
// We use a `capture` event to ensure this is called first before
// events that might cancel the opening timeout (like `onTouchEnd`)
// show tooltip after mouse has been hovering for at least 50ms
// show tooltip after mouse has been hovering for the specified delay time
// (prevent showing tooltip when mouse is just passing through)
openTimeoutRef.current = safeSetTimeout(() => {
openTooltip()
child.props.onMouseEnter?.(event)
}, 50)
}, delayTime)
},
onMouseLeave: (event: React.MouseEvent) => {
closeTooltip()
Expand Down
Loading