Tooltip
A tooltip that displays informative text when users press and hold an element.
This is a tooltip
Web preview — components render natively on iOS & Android
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
import { Text } from "react-native";
export function MyScreen() {
return (
<Tooltip>
<TooltipTrigger>
<Text>Press and hold me</Text>
</TooltipTrigger>
<TooltipContent>This is a tooltip</TooltipContent>
</Tooltip>
);
}Installation#
npx @aniui/cli add tooltipThis component requires @rn-primitives/tooltip, @rn-primitives/portal, and react-native-reanimated.
Usage#
app/index.tsx
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
import { Text } from "react-native";
export function MyScreen() {
return (
<Tooltip>
<TooltipTrigger>
<Text>Press and hold me</Text>
</TooltipTrigger>
<TooltipContent>This is a tooltip</TooltipContent>
</Tooltip>
);
}Tooltip Position#
Tooltip above
Tooltip below
Web preview — components render natively on iOS & Android
<Tooltip>
<TooltipTrigger><Text>Top tooltip</Text></TooltipTrigger>
<TooltipContent side="top">Tooltip above</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger><Text>Bottom tooltip</Text></TooltipTrigger>
<TooltipContent side="bottom">Tooltip below</TooltipContent>
</Tooltip>Props#
Tooltip#
PropTypeDefault
openboolean—onOpenChange(open: boolean) => void—childrenReact.ReactNoderequiredTooltipTrigger#
PropTypeDefault
classNamestring—childrenReact.ReactNode—TooltipContent#
PropTypeDefault
childrenReact.ReactNode | stringrequiredside"top" | "bottom" | "left" | "right""top"sideOffsetnumber8classNamestring—Accessibility#
- Uses
@rn-primitives/tooltipfor trigger-relative positioning - Collision detection prevents overflow
accessibilityRole="button"on trigger- Requires
<PortalHost />at app root
Source#
components/ui/tooltip.tsx
import React from "react";
import { View, Text, Pressable } from "react-native";
import * as TooltipPrimitive from "@rn-primitives/tooltip";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
import { cn } from "@/lib/utils";
export interface TooltipProps {
children: React.ReactNode;
open?: boolean;
onOpenChange?: (open: boolean) => void;
}
export function Tooltip({ children, open, onOpenChange }: TooltipProps) {
return <TooltipPrimitive.Root open={open} onOpenChange={onOpenChange}>{children}</TooltipPrimitive.Root>;
}
export interface TooltipTriggerProps extends React.ComponentPropsWithoutRef<typeof Pressable> {
className?: string;
children?: React.ReactNode;
}
export function TooltipTrigger({ className, children, ...props }: TooltipTriggerProps) {
return (
<TooltipPrimitive.Trigger asChild>
<Pressable className={cn("min-h-12 min-w-12", className)} accessible={true} accessibilityRole="button" {...props}>
{children}
</Pressable>
</TooltipPrimitive.Trigger>
);
}
export interface TooltipContentProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
children?: React.ReactNode;
side?: "top" | "bottom" | "left" | "right";
sideOffset?: number;
}
export function TooltipContent({ className, children, side = "top", sideOffset = 8, ...props }: TooltipContentProps) {
return (
<TooltipPrimitive.Portal>
<TooltipPrimitive.Content side={side} sideOffset={sideOffset} avoidCollisions>
<Animated.View entering={FadeIn.duration(150)} exiting={FadeOut.duration(100)}>
<View className={cn("rounded-md bg-primary px-3 py-1.5", className)} {...props}>
{typeof children === "string" ? (
<Text className="text-xs text-primary-foreground text-center">{children}</Text>
) : children}
</View>
</Animated.View>
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
);
}