MC Tooltip
A popup that displays information on hover or focus.
Overview
The mc-tooltip is a core component of Micro Club UI. Built on the @base-ui/react tooltip primitive, it combines world-class accessibility with Micro Club's signature styling via Tailwind CSS v4.
As a part of Micro Club UI, this component is designed for instant deployment into your codebase, giving you full ownership of its look and behavior.
Preview
import { McButton } from '@/components/ui/mc-button';import { McTooltip, McTooltipContent, McTooltipTrigger } from '@/components/ui/mc-tooltip';export default function McTooltipDemo() { return ( <McTooltip> <McTooltipTrigger render={<McButton variant="secondary">Hover</McButton>} /> <McTooltipContent title="Lovely tooltip title" description="There are a lot of things you can do in space, and space essentially is unlimited resources." /> </McTooltip> );}Add to Your Project
Deploy the mc-tooltip directly to your components/ui directory:
Manual Setup
If you prefer manual control:
'use client';import * as React from 'react';import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip';import { cn } from '@/lib/utils';function McTooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) { return <TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />;}function McTooltip({ ...props }: TooltipPrimitive.Root.Props) { return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;}function McTooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) { return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;}function McTooltipContent({ className, side = 'top', sideOffset = 16, align = 'center', alignOffset = 0, arrow = true, title, description, desc, children, ...props}: Omit<TooltipPrimitive.Popup.Props, 'title'> & Pick<TooltipPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'> & { /** Show the arrow pointing at the trigger. */ arrow?: boolean; /** Bold first line of the tooltip. */ title?: React.ReactNode; /** Body text below the title. */ description?: React.ReactNode; /** @deprecated Use `description`. */ desc?: React.ReactNode; }) { const body = description ?? desc; return ( <TooltipPrimitive.Portal> <TooltipPrimitive.Positioner align={align} alignOffset={alignOffset} side={side} sideOffset={sideOffset} className="isolate z-50" > <TooltipPrimitive.Popup data-slot="tooltip-content" className={cn( 'relative z-50 flex w-fit max-w-58 origin-(--transform-origin) flex-col gap-2 rounded-sm bg-card p-4 text-xs text-card-foreground drop-shadow-[0_1px_4px_var(--border)]', 'data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95', 'data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2', className )} {...props} > {title && <p className="font-semibold text-foreground">{title}</p>} {body && <p className="leading-4.5 text-muted-foreground">{body}</p>} {children} {arrow && ( // The arrow box is 20×15 and points up; it is rotated per side and pushed past the // popup edge so 14px sticks out (1px overlaps the popup to avoid a seam). Rotated // boxes need 2.5px more because the box is wider than it is tall. The popup's // drop-shadow follows the combined outline, so the arrow is shadowed too. <TooltipPrimitive.Arrow className={cn( 'flex h-[15px] w-5', 'data-[side=bottom]:-top-3.5', 'data-[side=top]:-bottom-3.5 data-[side=top]:rotate-180', 'data-[side=left]:-right-[16.5px] data-[side=left]:rotate-90 data-[side=inline-start]:-right-[16.5px] data-[side=inline-start]:rotate-90', 'data-[side=right]:-left-[16.5px] data-[side=right]:-rotate-90 data-[side=inline-end]:-left-[16.5px] data-[side=inline-end]:-rotate-90' )} > <svg width="20" height="15" viewBox="0 0 20 15" aria-hidden className="fill-card"> <path d="M0 15L8.5 2.25Q10 0 11.5 2.25L20 15Z" /> </svg> </TooltipPrimitive.Arrow> )} </TooltipPrimitive.Popup> </TooltipPrimitive.Positioner> </TooltipPrimitive.Portal> );}export { McTooltip, McTooltipTrigger, McTooltipContent, McTooltipProvider };Ensure your @/lib/utils or equivalent classname helper is correctly imported.
Usage
import {
McTooltip,
McTooltipTrigger,
McTooltipContent,
McTooltipProvider,
} from '@/components/ui/mc-tooltip';
export default function Example() {
return (
<McTooltipProvider>
<McTooltip>
<McTooltipTrigger>Hover me</McTooltipTrigger>
<McTooltipContent title="Tooltip title" description="This is a description." />
</McTooltip>
</McTooltipProvider>
);
}McTooltipTrigger renders a <button>. To use your own element, pass it through render instead of nesting it:
<McTooltipTrigger render={<McButton variant="secondary">Hover me</McButton>} />Tooltip content isn't announced by screen readers. Give icon-only triggers an aria-label.
Examples
Positioning
<McTooltip>
<McTooltipTrigger>Bottom</McTooltipTrigger>
<McTooltipContent side="bottom" align="start" title="Bottom start" />
</McTooltip>Without Arrow
<McTooltip>
<McTooltipTrigger>Hover me</McTooltipTrigger>
<McTooltipContent arrow={false} title="Tooltip title" description="No arrow." />
</McTooltip>With Custom Content
Children render below the title and description.
<McTooltip>
<McTooltipTrigger>Custom</McTooltipTrigger>
<McTooltipContent title="Shortcuts">
<p>
Press <kbd>⌘K</kbd> to search.
</p>
</McTooltipContent>
</McTooltip>API Reference
McTooltipProvider Props
| Prop | Type | Default | Description |
|---|---|---|---|
delay | number | 0 | Delay in ms before showing tooltip |
All other props from @base-ui/react/tooltip/provider are supported.
McTooltip Props
All props from @base-ui/react/tooltip/root are supported.
McTooltipTrigger Props
All props from @base-ui/react/tooltip/trigger are supported.
McTooltipContent Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | undefined | Additional CSS classes |
side | "top" | "bottom" | "left" | "right" | "top" | The side of the trigger to position the tooltip |
sideOffset | number | 16 | The offset from the trigger |
align | "start" | "center" | "end" | "center" | The alignment of the tooltip |
alignOffset | number | 0 | The offset for alignment |
arrow | boolean | true | Show the arrow pointing at the trigger |
title | ReactNode | undefined | The title text of the tooltip |
description | ReactNode | undefined | The description text of the tooltip |
desc | ReactNode | undefined | Deprecated alias for description |
children | ReactNode | undefined | Custom content for the tooltip |
All other props from @base-ui/react/tooltip/popup and @base-ui/react/tooltip/positioner are supported.