Tooltip
View .mdA tooltip provides supplemental, contextual information elevated near its target component. Tooltips should be used to provide helpful but non-essential, plaintext information.
Default
Loading interactive example. Full source is available below.
View example source
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { TooltipProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { SlideTextRegular } from "@fluentui/react-icons";
import * as React from 'react';
export const Default = (props: Partial<TooltipProps>): JSXElement => (<Tooltip content="Example tooltip" relationship="label" {...props}>
<Button icon={<SlideTextRegular />} size="large"/>
</Tooltip>);
export default Default;
Resources
Best practices
Do
- Use tooltips for helpful, non-essential, plaintext information.
- Provide additional information rather than repeating visible content.
- Position the tooltip so it does not obscure important information.
Don't
- Use tooltips to communicate system feedback.
- Add end punctuation unless the tooltip contains a complete sentence.
Behavior and states
- Tooltips open when the target receives hover or focus.
- They close on blur or when the pointer leaves the target or tooltip container.
- Tooltips appear 4 pixels from their target by default.
- The optional arrow always points to the target element.
- Don't use them to communicate system feedback.
- If you need to deliver robust, formatted information, use a popover instead.
API referenceGenerated CoreAI prop and type summaries
API
Generated CoreAI prop summaries, not replacement type declarations. Most native DOM/event and ARIA props are omitted. ? means optional; JSDoc shows defaults, deprecations, and conditional requirements. Defaults assume the standard CoreAI provider.
Tooltip API
A tooltip provides light weight contextual information on top of its target element.
interface TooltipProps {
/**
* The tooltip's visual appearance.
* * `normal` - Uses the theme's background and text colors.
* * `inverted` - Higher contrast variant that uses the theme's inverted colors.
* @default normal
*/
appearance?: "inverted" | "normal";
children?: ReactElement<any, string | JSXElementConstructor<any>> | ((props: TooltipTriggerProps) => ReactElement<any, string | JSXElementConstructor<any>> | null) | null;
/**
* The text or JSX content of the tooltip.
*/
content: NonNullable<WithSlotShorthandValue<{ as?: "div" | undefined; } & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ref?: ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined; }, "children"> & { children?: any; }> | null>;
/**
* Delay before the tooltip is hidden, in milliseconds.
* @default 250
*/
hideDelay?: number;
/**
* Where the portal children are mounted on DOM
* @default a new element on document.body without any styling
*/
mountNode?: HTMLElement | { element?: HTMLElement | null; className?: string; } | null | undefined;
/**
* Notification when the visibility of the tooltip is changing.
*
* **Note**: for backwards compatibility, `event` will be undefined if this was triggered by a keyboard event on
* the document element. Use `data.documentKeyboardEvent` if the keyboard event object is needed.
*/
onVisibleChange?: ((event: PointerEvent<HTMLElement> | FocusEvent<HTMLElement, Element>, data: OnVisibleChangeData) => void);
/**
* Configure the positioning of the tooltip
* @default above
*/
positioning?: PositioningShorthand;
/**
* (Required) Specifies whether this tooltip is acting as the description or label of its trigger element.
*
* * `label` - The tooltip sets the trigger's aria-label or aria-labelledby attribute. This is useful for buttons
* displaying only an icon, for example.
* * `description` - The tooltip sets the trigger's aria-description or aria-describedby attribute.
* * `inaccessible` - No aria attributes are set on the trigger. This makes the tooltip's content inaccessible to
* screen readers, and should only be used if the tooltip's text is available by some other means.
*/
relationship: "label" | "description" | "inaccessible";
/**
* Delay before the tooltip is shown, in milliseconds.
* @default 250
*/
showDelay?: number;
/**
* Control the tooltip's visibility programatically.
*
* This can be used in conjunction with onVisibleChange to modify the tooltip's show and hide behavior.
*
* If not provided, the visibility will be controlled by the tooltip itself, based on hover and focus events on the
* trigger (child) element.
* @default false
*/
visible?: boolean;
/**
* Render an arrow pointing to the target element
* @default false
*/
withArrow?: boolean;
}
Implementation
CoreAI 0.12.0; Fluent 9.74.9.
Import components from @coreai-ds/react-components. CoreAI guidance above takes precedence over API demonstration examples.
Note: Storybook-only layout decorators are omitted. Examples use the documentation preview spacing instead.
Controlled
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { Tooltip } from "@coreai-ds/react-components";
import { Checkbox } from "@coreai-ds/react-components";
export const Controlled = (): JSXElement => {
const [visible, setVisible] = React.useState(false);
const [enabled, setEnabled] = React.useState(false);
return (<Tooltip content="The checkbox controls whether the tooltip can show on hover or focus" relationship="description" visible={visible && enabled} onVisibleChange={(_ev, data) => setVisible(data.visible)}>
<Checkbox label="Enable the tooltip" onChange={(_ev, { checked }) => setEnabled(!!checked)}/>
</Tooltip>);
};
export default Controlled;
Custom Mount
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { TooltipProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { SlideTextRegular } from "@fluentui/react-icons";
export const CustomMount = (props: Partial<TooltipProps>): JSXElement => {
const [ref, setRef] = React.useState<HTMLElement | null>();
return (<>
<Tooltip mountNode={ref} content="Example tooltip" relationship="label" {...props}>
<Button icon={<SlideTextRegular />} size="large"/>
</Tooltip>
<div ref={setRef}/>
</>);
};
export default CustomMount;
Icon
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { InfoLabelProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { InfoLabel } from "@coreai-ds/react-components";
import { Link } from "@coreai-ds/react-components";
import * as React from 'react';
export const Icon = (props: Partial<InfoLabelProps>): JSXElement => {
return (<InfoLabel info={<>
This is example information for an InfoLabel. <Link href="https://react.fluentui.dev">Learn more</Link>
</>} {...props}>
This is an icon with an InfoLabel to show extra information
</InfoLabel>);
};
export default Icon;
Appearance: inverted
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { SlideTextFilled } from "@fluentui/react-icons";
import * as React from 'react';
export const Inverted = (): JSXElement => (<Tooltip appearance="inverted" content="Example inverted tooltip" relationship="label">
<Button icon={<SlideTextFilled />} size="large"/>
</Tooltip>);
export default Inverted;
Positioning
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { ArrowStepOverRegular } from "@fluentui/react-icons";
import { ArrowStepOutRegular } from "@fluentui/react-icons";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
export const Positioning = (): JSXElement => {
/* eslint-disable react/jsx-key */
const positions = [
['above-start', <ArrowStepOverRegular transform="rotate(-90)"/>],
['above', <ArrowStepOutRegular />],
['above-end', <ArrowStepOverRegular transform="rotate(90) scale(-1 1)"/>],
['before-top', <ArrowStepOverRegular transform="scale(-1 1)"/>],
['before', <ArrowStepOutRegular transform="rotate(-90)"/>],
['before-bottom', <ArrowStepOverRegular transform="rotate(180)"/>],
['after-top', <ArrowStepOverRegular />],
['after', <ArrowStepOutRegular transform="rotate(90)"/>],
['after-bottom', <ArrowStepOverRegular transform="rotate(180) scale(-1 1)"/>],
['below-start', <ArrowStepOverRegular transform="rotate(-90) scale(-1 1)"/>],
['below', <ArrowStepOutRegular transform="rotate(180)"/>],
['below-end', <ArrowStepOverRegular transform="rotate(90)"/>],
] as const;
return (<div style={{
display: 'grid',
margin: '24px 128px',
gap: '4px',
gridTemplateAreas: '". above-start above above-end . "' +
'"before-top . . . after-top "' +
'"before . . . after "' +
'"before-bottom . . . after-bottom "' +
'". below-start below below-end . "',
}}>
{positions.map(([position, icon]) => (<Tooltip key={position} withArrow positioning={position} content={position} relationship="label">
<Button icon={icon} size="large" style={{ gridArea: position, minWidth: '64px', height: '64px' }}/>
</Tooltip>))}
</div>);
};
export default Positioning;
Relationship: description
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import * as React from 'react';
export const RelationshipDescription = (): JSXElement => (<Tooltip content="This is the description of the button" relationship="description">
<Button>Button</Button>
</Tooltip>);
export default RelationshipDescription;
Relationship: label
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { TextBoldRegular } from "@fluentui/react-icons";
import { TextItalicRegular } from "@fluentui/react-icons";
import { TextUnderlineRegular } from "@fluentui/react-icons";
import * as React from 'react';
export const RelationshipLabel = (): JSXElement => (<>
<Tooltip content="Bold" relationship="label">
<Button icon={<TextBoldRegular />}/>
</Tooltip>
<Tooltip content="Italic" relationship="label">
<Button icon={<TextItalicRegular />}/>
</Tooltip>
<Tooltip content="Underline" relationship="label">
<Button icon={<TextUnderlineRegular />}/>
</Tooltip>
</>);
export default RelationshipLabel;
Styled
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { TooltipProps } from "@coreai-ds/react-components";
import type { JSXElement } from "@coreai-ds/react-components";
import { makeStyles } from "@coreai-ds/react-components";
import { tokens } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { SlideTextRegular } from "@fluentui/react-icons";
import * as React from 'react';
const useStyles = makeStyles({
tooltip: {
backgroundColor: tokens.colorBrandBackground,
color: tokens.colorNeutralForegroundInverted,
},
});
export const Styled = (props: Partial<TooltipProps>): JSXElement => {
const styles = useStyles();
return (<Tooltip withArrow content={{ children: 'Example tooltip', className: styles.tooltip }} relationship="label" {...props}>
<Button icon={<SlideTextRegular />} size="large"/>
</Tooltip>);
};
export default Styled;
Target
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import * as React from 'react';
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { ArrowRoutingRegular } from "@fluentui/react-icons";
export const Target = (): JSXElement => {
const [iconRef, setIconRef] = React.useState<HTMLSpanElement | null>(null);
return (<Tooltip positioning={{ target: iconRef }} withArrow content="This tooltip points to the icon" relationship="description">
<Button icon={{ ref: setIconRef, children: <ArrowRoutingRegular /> }}>Button with icon</Button>
</Tooltip>);
};
export default Target;
With Arrow
Loading interactive example. Full source is available below.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import type { JSXElement } from "@coreai-ds/react-components";
import { Tooltip } from "@coreai-ds/react-components";
import { Button } from "@coreai-ds/react-components";
import { ArrowStepInRegular } from "@fluentui/react-icons";
import * as React from 'react';
export const WithArrow = (): JSXElement => (<Tooltip withArrow content="Example tooltip with an arrow" relationship="label">
<Button icon={<ArrowStepInRegular />} size="large"/>
</Tooltip>);
export default WithArrow;