@xsolla/xui-tooltip
v0.170.3
Published
A hover- or focus-triggered popover that displays contextual information next to a trigger element. Web-only rendering (uses a portal); on React Native the trigger is rendered without the tooltip surface.
Readme
Tooltip
A hover- or focus-triggered popover that displays contextual information next to a trigger element. Web-only rendering (uses a portal); on React Native the trigger is rendered without the tooltip surface.
Installation
npm install @xsolla/xui-tooltipImports
import {
Tooltip,
type TooltipProps,
type TooltipPlacement,
type TooltipSize,
} from "@xsolla/xui-tooltip";Quick start
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Button } from "@xsolla/xui-button";
export default function Example() {
return (
<Tooltip content="This is a helpful tip">
<Button>Hover me</Button>
</Tooltip>
);
}API Reference
<Tooltip>
| Prop | Type | Default | Description |
| ------------------- | ------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------- |
| content | ReactNode | — | Required. Tooltip content. Strings/numbers render as themed text. |
| children | ReactNode | — | Required. Trigger element. |
| size | "sm" \| "md" \| "lg" \| "xl" | "md" | Typography size. |
| placement | TooltipPlacement | "top" | Position relative to trigger. |
| offset | number | 12 | Distance from trigger in pixels. |
| delayEnter | number | 0 | Delay before showing (ms). |
| delayLeave | number | 0 | Delay before hiding (ms). |
| controlledVisible | boolean | — | Externally controlled visibility. Overrides hover/focus state. |
| style | CSSProperties | — | Custom styles applied to the tooltip surface (web only). |
| className | string | — | Custom class for the trigger wrapper. |
| data-testid | string | — | Test identifier. |
| testID | string | — | Test ID for testing frameworks. On web this renders as data-testid; on React Native it renders as testID. |
Inherits ThemeOverrideProps (themeMode, themeProductContext).
TooltipPlacement is "top" | "top-left" | "top-right" | "bottom" | "bottom-left" | "bottom-right" | "left" | "right".
Size typography
| Size | Font size | Line height |
| ---- | --------- | ----------- |
| sm | 14px | 16px |
| md | 16px | 18px |
| lg | 18px | 20px |
| xl | 20px | 22px |
Examples
Placements
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Button } from "@xsolla/xui-button";
export default function Placements() {
return (
<div
style={{
display: "grid",
gridTemplateColumns: "repeat(3, 1fr)",
gap: 16,
padding: 48,
}}
>
<Tooltip content="Top left" placement="top-left">
<Button variant="secondary">Top Left</Button>
</Tooltip>
<Tooltip content="Top centre" placement="top">
<Button variant="secondary">Top</Button>
</Tooltip>
<Tooltip content="Top right" placement="top-right">
<Button variant="secondary">Top Right</Button>
</Tooltip>
<Tooltip content="Left" placement="left">
<Button variant="secondary">Left</Button>
</Tooltip>
<div />
<Tooltip content="Right" placement="right">
<Button variant="secondary">Right</Button>
</Tooltip>
<Tooltip content="Bottom left" placement="bottom-left">
<Button variant="secondary">Bottom Left</Button>
</Tooltip>
<Tooltip content="Bottom centre" placement="bottom">
<Button variant="secondary">Bottom</Button>
</Tooltip>
<Tooltip content="Bottom right" placement="bottom-right">
<Button variant="secondary">Bottom Right</Button>
</Tooltip>
</div>
);
}Sizes
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Button } from "@xsolla/xui-button";
export default function Sizes() {
return (
<div style={{ display: "flex", gap: 16 }}>
<Tooltip content="Small" size="sm">
<Button variant="secondary">Small</Button>
</Tooltip>
<Tooltip content="Medium" size="md">
<Button variant="secondary">Medium</Button>
</Tooltip>
<Tooltip content="Large" size="lg">
<Button variant="secondary">Large</Button>
</Tooltip>
<Tooltip content="Extra large" size="xl">
<Button variant="secondary">XL</Button>
</Tooltip>
</div>
);
}With delay
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Button } from "@xsolla/xui-button";
export default function Delays() {
return (
<div style={{ display: "flex", gap: 16 }}>
<Tooltip content="Appears immediately" delayEnter={0}>
<Button variant="secondary">No delay</Button>
</Tooltip>
<Tooltip content="Appears after 500ms" delayEnter={500}>
<Button variant="secondary">500ms enter</Button>
</Tooltip>
<Tooltip content="Stays for 500ms" delayLeave={500}>
<Button variant="secondary">Slow hide</Button>
</Tooltip>
</div>
);
}Rich content
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Avatar } from "@xsolla/xui-avatar";
export default function Rich() {
return (
<Tooltip
content={
<div style={{ textAlign: "center" }}>
<strong>John Doe</strong>
<br />
<span style={{ opacity: 0.7 }}>Senior Developer</span>
</div>
}
>
<Avatar text="JD" />
</Tooltip>
);
}Icons with tooltip
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Edit, TrashCan, MoreHr } from "@xsolla/xui-icons-base";
export default function Icons() {
return (
<div style={{ display: "flex", gap: 16 }}>
<Tooltip content="Edit item">
<Edit style={{ cursor: "pointer" }} />
</Tooltip>
<Tooltip content="Delete item">
<TrashCan style={{ cursor: "pointer" }} />
</Tooltip>
<Tooltip content="More options">
<MoreHr style={{ cursor: "pointer" }} />
</Tooltip>
</div>
);
}Controlled visibility
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Button } from "@xsolla/xui-button";
export default function Controlled() {
const [visible, setVisible] = React.useState(false);
return (
<div style={{ display: "flex", gap: 16 }}>
<Tooltip content="I'm controlled" controlledVisible={visible}>
<Button variant="secondary">Target</Button>
</Tooltip>
<Button onPress={() => setVisible((v) => !v)}>
{visible ? "Hide" : "Show"}
</Button>
</div>
);
}Disabled trigger
disabled elements do not emit pointer events; wrap them so the tooltip can still register hover.
import * as React from "react";
import { Tooltip } from "@xsolla/xui-tooltip";
import { Button } from "@xsolla/xui-button";
export default function DisabledTrigger() {
return (
<Tooltip content="Complete the form first">
<span>
<Button disabled>Submit</Button>
</span>
</Tooltip>
);
}Accessibility
- Tooltip surface uses
role="tooltip"andaria-hiddenreflects visibility. - Trigger receives
aria-describedbywhile the tooltip is visible. - Press Escape to dismiss.
- Tooltip content is non-interactive — for interactive content, prefer Toggletip.
Related
- Toggletip — click-triggered popover with rich content.
