Overlays

Tooltip.

A dark label in small mono type that appears on hover or keyboard focus. Good for naming icon buttons.

Installation#

With the CLI

$npx lanterncn add tooltip

This also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/tooltip. See Installation if your project is not set up yet.

Manually

  1. Install the dependencies

    npm install radix-ui
  2. Copy the source into your project

    components/ui/tooltip.tsx
    "use client";
    
    import * as React from "react";
    import { Tooltip as TooltipPrimitive } from "radix-ui";
    
    import { cn } from "@/lib/utils";
    
    function TooltipProvider({ delayDuration = 150, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
      return <TooltipPrimitive.Provider data-slot="tooltip-provider" delayDuration={delayDuration} {...props} />;
    }
    
    function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
      return (
        <TooltipProvider>
          <TooltipPrimitive.Root data-slot="tooltip" {...props} />
        </TooltipProvider>
      );
    }
    
    function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
      return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
    }
    
    function TooltipContent({
      className,
      sideOffset = 6,
      children,
      ...props
    }: React.ComponentProps<typeof TooltipPrimitive.Content>) {
      return (
        <TooltipPrimitive.Portal>
          <TooltipPrimitive.Content
            data-slot="tooltip-content"
            sideOffset={sideOffset}
            className={cn(
              "z-50 w-fit max-w-[calc(100vw-1.5rem)] origin-(--radix-tooltip-content-transform-origin) rounded-sm border border-[#3a463e] bg-[#0b0f0d] px-2 py-1.5 font-mono text-[10px] leading-snug tracking-[0.12em] text-foreground uppercase",
              "animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
              "data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
              className,
            )}
            {...props}
          >
            {children}
            <TooltipPrimitive.Arrow className="z-50 fill-[#0b0f0d]" width={8} height={4} />
          </TooltipPrimitive.Content>
        </TooltipPrimitive.Portal>
      );
    }
    
    export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
  3. Update the import paths to match your project

    The source imports cn from @/lib/utils.

Usage#

import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
<Tooltip>
  <TooltipTrigger asChild>
    <Button size="icon" aria-label="Copy address"><CopyIcon /></Button>
  </TooltipTrigger>
  <TooltipContent>Copy address</TooltipContent>
</Tooltip>

Each Tooltip brings its own provider. Wrap a group in TooltipProvider to share the open delay so moving between buttons shows the next tooltip instantly.

Tooltips do not show on touch screens. Keep an aria-label on icon-only buttons.