Tooltip

Display container for Tooltip content. Has a directional arrow dependent on its placement.

installyarn add @adobe/react-spectrum
version3.0.0
usageimport {Tooltip} from '@adobe/react-spectrum'

Examples#


<TooltipTrigger>
  <ActionButton aria-label="Edit Name">
    <Edit />
  </ActionButton>
  <Tooltip>Change Name</Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Edit Name">
    <Edit />
  </ActionButton>
  <Tooltip>Change Name</Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Edit Name">
    <Edit />
  </ActionButton>
  <Tooltip>
    Change Name
  </Tooltip>
</TooltipTrigger>

Content#


Tooltips accept content as children. All content should be internationalized.

Accessibility#

Tooltip triggers must be focusable and hoverable in order to ensure that all users can activate them. When displayed, TooltipTrigger automatically associates the tooltip with the trigger element so that it is described by the tooltip content.

Tooltip Delay#


Tooltips should appear after a short delay when hovering the trigger, or instantly when using keyboard focus. This delay can be adjusted for hover. View guidelines

<TooltipTrigger delay={0}>
  <ActionButton aria-label="Save">
    <Save />
  </ActionButton>
  <Tooltip>Saving applies your new settings right away.</Tooltip>
</TooltipTrigger>
<TooltipTrigger delay={0}>
  <ActionButton aria-label="Save">
    <Save />
  </ActionButton>
  <Tooltip>
    Saving applies your new settings right away.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger
  delay={0}>
  <ActionButton aria-label="Save">
    <Save />
  </ActionButton>
  <Tooltip>
    Saving applies your
    new settings right
    away.
  </Tooltip>
</TooltipTrigger>

Warmup / Cooldown#

Tooltips have a warm up and cool down period, see guidelines. Only one tooltip can be open at a time.

<Flex gap="size-200">
  <TooltipTrigger>
    <ActionButton>Hover me</ActionButton>
    <Tooltip>I come up after a delay.</Tooltip>
  </TooltipTrigger>
  <TooltipTrigger>
    <ActionButton>Then hover me</ActionButton>
    <Tooltip>If you did it quickly, I appear immediately.</Tooltip>
  </TooltipTrigger>
</Flex>
<Flex gap="size-200">
  <TooltipTrigger>
    <ActionButton>Hover me</ActionButton>
    <Tooltip>I come up after a delay.</Tooltip>
  </TooltipTrigger>
  <TooltipTrigger>
    <ActionButton>Then hover me</ActionButton>
    <Tooltip>
      If you did it quickly, I appear immediately.
    </Tooltip>
  </TooltipTrigger>
</Flex>
<Flex gap="size-200">
  <TooltipTrigger>
    <ActionButton>
      Hover me
    </ActionButton>
    <Tooltip>
      I come up after a
      delay.
    </Tooltip>
  </TooltipTrigger>
  <TooltipTrigger>
    <ActionButton>
      Then hover me
    </ActionButton>
    <Tooltip>
      If you did it
      quickly, I appear
      immediately.
    </Tooltip>
  </TooltipTrigger>
</Flex>

Tooltip placement#


Tooltips support a variety of placement options.

Placement#

The Tooltip's placement with respect to its trigger element can be adjusted using the placement prop. See the props table below for a full list of available placement combinations.

<TooltipTrigger placement="end">
  <ActionButton aria-label="Foo">Placement</ActionButton>
  <Tooltip>
    In left-to-right, this is on the right. In right-to-left, this is on the
    left.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger placement="end">
  <ActionButton aria-label="Foo">Placement</ActionButton>
  <Tooltip>
    In left-to-right, this is on the right. In
    right-to-left, this is on the left.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger placement="end">
  <ActionButton aria-label="Foo">
    Placement
  </ActionButton>
  <Tooltip>
    In left-to-right,
    this is on the
    right. In
    right-to-left, this
    is on the left.
  </Tooltip>
</TooltipTrigger>

Offset and cross offset#

The Tooltip's offset with respect to its trigger can be adjusted using the offset and crossOffset props. The offset prop controls the spacing applied along the main axis between the element and its trigger whereas the crossOffset prop handles the spacing applied along the cross axis.

Below is a tooltip offset by an additional 50px above the trigger.

<TooltipTrigger offset={50}>
  <ActionButton aria-label="Offset from trigger">Offset</ActionButton>
  <Tooltip>This will shift up.</Tooltip>
</TooltipTrigger>
<TooltipTrigger offset={50}>
  <ActionButton aria-label="Offset from trigger">
    Offset
  </ActionButton>
  <Tooltip>This will shift up.</Tooltip>
</TooltipTrigger>
<TooltipTrigger
  offset={50}>
  <ActionButton aria-label="Offset from trigger">
    Offset
  </ActionButton>
  <Tooltip>
    This will shift up.
  </Tooltip>
</TooltipTrigger>

Below is a tooltip cross offset by an additional 100px to the right of the trigger.

<TooltipTrigger crossOffset={100} placement="bottom">
  <ActionButton aria-label="Cross Offset from trigger">
    Cross Offset
  </ActionButton>
  <Tooltip>This will shift over to the right.</Tooltip>
</TooltipTrigger>
<TooltipTrigger crossOffset={100} placement="bottom">
  <ActionButton aria-label="Cross Offset from trigger">
    Cross Offset
  </ActionButton>
  <Tooltip>This will shift over to the right.</Tooltip>
</TooltipTrigger>
<TooltipTrigger
  crossOffset={100}
  placement="bottom">
  <ActionButton aria-label="Cross Offset from trigger">
    Cross Offset
  </ActionButton>
  <Tooltip>
    This will shift
    over to the right.
  </Tooltip>
</TooltipTrigger>

Events#


TooltipTrigger accepts an onOpenChange handler which is triggered whenever the Tooltip is shown or hidden.

The example below uses onOpenChange to update a separate element with the current open state of the Dialog.

function Example() {
  let [state, setState] = React.useState(false);

  return (
    <Flex alignItems="center" gap="size-100">
      <TooltipTrigger onOpenChange={(isOpen) => setState(isOpen)}>
        <ActionButton aria-label="Resize">
          <Resize />
        </ActionButton>
        <Tooltip>Resize text.</Tooltip>
      </TooltipTrigger>
      <Text>Current open state: {state.toString()}</Text>
    </Flex>
  );
}
function Example() {
  let [state, setState] = React.useState(false);

  return (
    <Flex alignItems="center" gap="size-100">
      <TooltipTrigger
        onOpenChange={(isOpen) => setState(isOpen)}>
        <ActionButton aria-label="Resize">
          <Resize />
        </ActionButton>
        <Tooltip>Resize text.</Tooltip>
      </TooltipTrigger>
      <Text>Current open state: {state.toString()}</Text>
    </Flex>
  );
}
function Example() {
  let [
    state,
    setState
  ] = React.useState(
    false
  );

  return (
    <Flex
      alignItems="center"
      gap="size-100">
      <TooltipTrigger
        onOpenChange={(
          isOpen
        ) =>
          setState(
            isOpen
          )
        }>
        <ActionButton aria-label="Resize">
          <Resize />
        </ActionButton>
        <Tooltip>
          Resize text.
        </Tooltip>
      </TooltipTrigger>
      <Text>
        Current open
        state:{' '}
        {state.toString()}
      </Text>
    </Flex>
  );
}

Props#


TooltipTrigger Props#

NameTypeDefaultDescription
children[ ReactElement, ReactElement ]
isDisabledbooleanWhether the tooltip should be disabled, independent from the trigger.
delaynumberThe delay time for the tooltip to show up. See guidelines.
offsetnumber7The additional offset applied along the main axis between the element and its anchor element.
crossOffsetnumber0The additional offset applied along the cross axis between the element and its anchor element.
isOpenbooleanWhether the overlay is open by default (controlled).
defaultOpenbooleanWhether the overlay is open by default (uncontrolled).
placementPlacement'bottom'The placement of the element with respect to its anchor element.
containerPaddingnumber12The placement padding that should be applied between the element and its surrounding container.
shouldFlipbooleantrueWhether the element should flip its orientation (e.g. top to bottom or left to right) when there is insufficient room for it to render completely.
Events
NameTypeDefaultDescription
onOpenChange( (isOpen: boolean )) => voidHandler that is called when the overlay's open state changes.

Tooltip Props#

NameTypeDefaultDescription
childrenReactNode
variant'neutral''positive''negative''info'The visual style of the Tooltip.
placement'start''end''right''left''top''bottom''top'The placement of the element with respect to its anchor element.
showIconbooleanWhether the element is rendered.
isOpenboolean
Layout
NameTypeDefaultDescription
flexstringnumberbooleanWhen used in a flex layout, specifies how the element will grow or shrink to fit the space available. See MDN.
flexGrownumberWhen used in a flex layout, specifies how the element will grow to fit the space available. See MDN.
flexShrinknumberWhen used in a flex layout, specifies how the element will shrink to fit the space available. See MDN.
flexBasisnumberstringWhen used in a flex layout, specifies the initial main size of the element. See MDN.
alignSelf'auto''normal''start''end''center''flex-start''flex-end''self-start''self-end''stretch'Overrides the alignItems property of a flex or grid container. See MDN.
justifySelf'auto''normal''start''end''flex-start''flex-end''self-start''self-end''center''left''right''stretch'Specifies how the element is justified inside a flex or grid container. See MDN.
ordernumberThe layout order for the element within a flex or grid container. See MDN.
gridAreastringWhen used in a grid layout, specifies the named grid area that the element should be placed in within the grid. See MDN.
gridColumnstringWhen used in a grid layout, specifies the column the element should be placed in within the grid. See MDN.
gridRowstringWhen used in a grid layout, specifies the row the element should be placed in within the grid. See MDN.
gridColumnStartstringWhen used in a grid layout, specifies the starting column to span within the grid. See MDN.
gridColumnEndstringWhen used in a grid layout, specifies the ending column to span within the grid. See MDN.
gridRowStartstringWhen used in a grid layout, specifies the starting row to span within the grid. See MDN.
gridRowEndstringWhen used in a grid layout, specifies the ending row to span within the grid. See MDN.
Spacing
NameTypeDefaultDescription
marginDimensionValueThe margin for all four sides of the element. See MDN.
marginTopDimensionValueThe margin for the top side of the element. See MDN.
marginBottomDimensionValueThe margin for the bottom side of the element. See MDN.
marginStartDimensionValueThe margin for the logical start side of the element, depending on layout direction. See MDN.
marginEndDimensionValueThe margin for the logical end side of an element, depending on layout direction. See MDN.
marginXDimensionValueThe margin for both the left and right sides of the element. See MDN.
marginYDimensionValueThe margin for both the top and bottom sides of the element. See MDN.
Sizing
NameTypeDefaultDescription
widthDimensionValueThe width of the element. See MDN.
minWidthDimensionValueThe minimum width of the element. See MDN.
maxWidthDimensionValueThe maximum width of the element. See MDN.
heightDimensionValueThe height of the element. See MDN.
minHeightDimensionValueThe minimum height of the element. See MDN.
maxHeightDimensionValueThe maximum height of the element. See MDN.
Positioning
NameTypeDefaultDescription
position'static''relative''absolute''fixed''sticky'Specifies how the element is positioned. See MDN.
topDimensionValueThe top position for the element. See MDN.
bottomDimensionValueThe bottom position for the element. See MDN.
leftDimensionValueThe left position for the element. See MDN. Consider using start instead for RTL support.
rightDimensionValueThe right position for the element. See MDN. Consider using start instead for RTL support.
startDimensionValueThe logical start position for the element, depending on layout direction. See MDN.
endDimensionValueThe logical end position for the element, depending on layout direction. See MDN.
zIndexnumberThe stacking order for the element. See MDN.
isHiddenbooleanHides the element.
Accessibility
NameTypeDefaultDescription
idstringThe element's unique identifier. See MDN.
aria-labelstringDefines a string value that labels the current element.
aria-labelledbystringIdentifies the element (or elements) that labels the current element.
aria-describedbystringIdentifies the element (or elements) that describes the object.
aria-detailsstringIdentifies the element (or elements) that provide a detailed, extended description for the object.
Advanced
NameTypeDefaultDescription
UNSAFE_classNamestringSets the CSS className for the element. Only use as a last resort. Use style props instead.
UNSAFE_styleCSSPropertiesSets inline style for the element. Only use as a last resort. Use style props instead.

Visual options#


View guidelines

Positive

<TooltipTrigger>
  <ActionButton aria-label="Approve">
    <ThumbUp />
  </ActionButton>
  <Tooltip variant="positive" showIcon>
    Approve workflow.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Approve">
    <ThumbUp />
  </ActionButton>
  <Tooltip variant="positive" showIcon>
    Approve workflow.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Approve">
    <ThumbUp />
  </ActionButton>
  <Tooltip
    variant="positive"
    showIcon>
    Approve workflow.
  </Tooltip>
</TooltipTrigger>

Information

<TooltipTrigger>
  <ActionButton aria-label="Information">
    <Question />
  </ActionButton>
  <Tooltip variant="info" showIcon>
    More information menu.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Information">
    <Question />
  </ActionButton>
  <Tooltip variant="info" showIcon>
    More information menu.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Information">
    <Question />
  </ActionButton>
  <Tooltip
    variant="info"
    showIcon>
    More information
    menu.
  </Tooltip>
</TooltipTrigger>

Negative

<TooltipTrigger>
  <ActionButton aria-label="Danger Will Robinson">
    <Delete />
  </ActionButton>
  <Tooltip variant="negative" showIcon>
    Dangerous action.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Danger Will Robinson">
    <Delete />
  </ActionButton>
  <Tooltip variant="negative" showIcon>
    Dangerous action.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger>
  <ActionButton aria-label="Danger Will Robinson">
    <Delete />
  </ActionButton>
  <Tooltip
    variant="negative"
    showIcon>
    Dangerous action.
  </Tooltip>
</TooltipTrigger>

Options#


A TooltipTrigger can be disabled without disabling the trigger it displays on.

isDisabled

<TooltipTrigger isDisabled>
  <ActionButton
    aria-label="Danger Will Robinson"
    onPress={() => alert('pressed trigger')}>
    <Delete />
  </ActionButton>
  <Tooltip variant="negative" showIcon>
    Dangerous action.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger isDisabled>
  <ActionButton
    aria-label="Danger Will Robinson"
    onPress={() => alert('pressed trigger')}>
    <Delete />
  </ActionButton>
  <Tooltip variant="negative" showIcon>
    Dangerous action.
  </Tooltip>
</TooltipTrigger>
<TooltipTrigger
  isDisabled>
  <ActionButton
    aria-label="Danger Will Robinson"
    onPress={() =>
      alert(
        'pressed trigger'
      )
    }>
    <Delete />
  </ActionButton>
  <Tooltip
    variant="negative"
    showIcon>
    Dangerous action.
  </Tooltip>
</TooltipTrigger>