useTooltipTrigger
Provides the behavior and accessibility implementation for a tooltip trigger, e.g. a button that shows a description when focused or hovered.
install | yarn add @react-aria/tooltip |
---|---|
version | 3.1.7 |
usage | import {useTooltipTrigger, useTooltip} from '@react-aria/tooltip' |
API#
useTooltipTrigger(
props: TooltipTriggerProps,
state: TooltipTriggerState,
ref: RefObject<HTMLElement>
): TooltipTriggerAria
useTooltip(
(props: AriaTooltipProps,
, state?: TooltipTriggerState
)): TooltipAria
Features#
The HTML title
attribute can be used to create a tooltip, but it cannot be styled. Custom styled
tooltips can be hard to build in an accessible way. useTooltipTrigger
and useTooltip
help build
fully accessible tooltips that can be styled as needed.
- Keyboard focus management and cross browser normalization
- Hover management and cross browser normalization
- Labeling support for screen readers (aria-describedby)
- Exposed as a tooltip to assistive technology via ARIA
- Matches native tooltip behavior with delay on hover of first tooltip and no delay on subsequent tooltips.
Anatomy#
A tooltip consists of two parts: the trigger element and the tooltip itself. Users may reveal the tooltip by hovering or focusing the trigger.
useTooltipTrigger
returns props to be spread onto its target trigger and the tooltip:
Name | Type | Description |
triggerProps | HTMLAttributes<HTMLElement>
& PressProps
& HoverProps
& FocusEvents | Props for the trigger element. |
tooltipProps | HTMLAttributes<HTMLElement> | Props for the overlay container element. |
useTooltip
returns props to be spread onto the tooltip:
Name | Type | Description |
tooltipProps | HTMLAttributes<HTMLElement> | Props for the tooltip element. |
Tooltip state is managed by the useTooltipTriggerState
hook in @react-stately/tooltip
. The state object should be passed as an option to useTooltipTrigger
and useTooltip
.
Example#
This example implements a Tooltip that renders in an absolute position next to its target. The useTooltip
hook applies the correct ARIA attributes to the tooltip, and useTooltipTrigger
associates it to the trigger element.
Two instances of the example are rendered to demonstrate the behavior of the delay on hover. If you hover over the first button, the tooltip will be shown after a delay. Hovering over the second button shows the tooltip immediately. If you wait for a delay before hovering another element, the delay restarts.
import {useTooltip, useTooltipTrigger} from '@react-aria/tooltip';
import {useTooltipTriggerState} from '@react-stately/tooltip';
import {mergeProps} from '@react-aria/utils';
function Tooltip({state, ...props}) {
let {tooltipProps} = useTooltip(props, state);
return (
<span
style={{
position: 'absolute',
left: '5px',
top: '100%',
marginTop: '10px',
backgroundColor: 'white',
color: 'black',
padding: '5px'
}}
{...mergeProps(props, tooltipProps)} >
{props.children}
</span>
);
}
function Example(props) {
let state = useTooltipTriggerState(props);
let ref = React.useRef();
// Get props for the trigger and its tooltip
let {triggerProps, tooltipProps} = useTooltipTrigger(props, state, ref);
return (
<span style={{position: 'relative'}}>
<button ref={ref} {...triggerProps}>I have a tooltip</button>
{state.isOpen && (
<Tooltip state={state} {...tooltipProps}>
And the tooltip tells you more information.
</Tooltip>
)}
</span>
);
}
<Example />
<Example />
import {
useTooltip,
useTooltipTrigger
} from '@react-aria/tooltip';
import {useTooltipTriggerState} from '@react-stately/tooltip';
import {mergeProps} from '@react-aria/utils';
function Tooltip({ state, ...props }) {
let { tooltipProps } = useTooltip(props, state);
return (
<span
style={{
position: 'absolute',
left: '5px',
top: '100%',
marginTop: '10px',
backgroundColor: 'white',
color: 'black',
padding: '5px'
}}
{...mergeProps(props, tooltipProps)}
>
{props.children}
</span>
);
}
function Example(props) {
let state = useTooltipTriggerState(props);
let ref = React.useRef();
// Get props for the trigger and its tooltip
let { triggerProps, tooltipProps } = useTooltipTrigger(
props,
state,
ref
);
return (
<span style={{ position: 'relative' }}>
<button ref={ref} {...triggerProps}>
I have a tooltip
</button>
{state.isOpen &&
(
<Tooltip state={state} {...tooltipProps}>
And the tooltip tells you more information.
</Tooltip>
)}
</span>
);
}
<Example />
<Example />
import {
useTooltip,
useTooltipTrigger
} from '@react-aria/tooltip';
import {useTooltipTriggerState} from '@react-stately/tooltip';
import {mergeProps} from '@react-aria/utils';
function Tooltip(
{ state, ...props }
) {
let { tooltipProps } =
useTooltip(
props,
state
);
return (
<span
style={{
position:
'absolute',
left: '5px',
top: '100%',
marginTop:
'10px',
backgroundColor:
'white',
color: 'black',
padding: '5px'
}}
{...mergeProps(
props,
tooltipProps
)}
>
{props.children}
</span>
);
}
function Example(props) {
let state =
useTooltipTriggerState(
props
);
let ref = React
.useRef();
// Get props for the trigger and its tooltip
let {
triggerProps,
tooltipProps
} = useTooltipTrigger(
props,
state,
ref
);
return (
<span
style={{
position:
'relative'
}}
>
<button
ref={ref}
{...triggerProps}
>
I have a tooltip
</button>
{state.isOpen &&
(
<Tooltip
state={state}
{...tooltipProps}
>
And the
tooltip tells
you more
information.
</Tooltip>
)}
</span>
);
}
<Example />
<Example />
Internationalization#
RTL#
In right-to-left languages, tooltips should be mirrored across trigger. Ensure that your CSS and overlay positioning (if any) accounts for this.