codefast/ui

Command Palette

Search for a command to run...

Source
Overlay

Tooltip

Hover label with delay and side placement control. Supports rich content including Kbd.

Examples

Placement

Anchor the tooltip to any side of the trigger.

23 lines
import { Button } from "@codefast/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@codefast/ui/tooltip";

export function TooltipSides() {
  return (
    <TooltipProvider>
      <div className="flex flex-wrap gap-2">
        {(["left", "top", "bottom", "right"] as const).map((side) => (
          <Tooltip key={side}>
            <TooltipTrigger asChild>
              <Button variant="outline" className="w-fit capitalize">
                {side}
              </Button>
            </TooltipTrigger>
            <TooltipContent side={side}>
              <p>Add to library</p>
            </TooltipContent>
          </Tooltip>
        ))}
      </div>
    </TooltipProvider>
  );
}

Disabled Button

Show a tooltip on a disabled button by wrapping it with a span.

21 lines
import { Button } from "@codefast/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@codefast/ui/tooltip";

export function TooltipDisabled() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger asChild>
          <span className="inline-block w-fit">
            <Button variant="outline" disabled>
              Disabled
            </Button>
          </span>
        </TooltipTrigger>
        <TooltipContent>
          <p>This feature is currently unavailable</p>
        </TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}

With Keyboard Shortcut

A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.

21 lines
import { Button } from "@codefast/ui/button";
import { Kbd } from "@codefast/ui/kbd";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@codefast/ui/tooltip";
import { SaveIcon } from "lucide-react";

export function TooltipKeyboard() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger asChild>
          <Button variant="outline" size="icon-sm">
            <SaveIcon />
          </Button>
        </TooltipTrigger>
        <TooltipContent>
          Save Changes <Kbd>S</Kbd>
        </TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

61 lines
import { Button } from "@codefast/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@codefast/ui/tooltip";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      content: "Add to library",
      left: "Left",
      top: "Top",
      bottom: "Bottom",
      right: "Right",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      content: "إضافة إلى المكتبة",
      left: "يسار",
      top: "أعلى",
      bottom: "أسفل",
      right: "يمين",
    },
  },
  he: {
    dir: "rtl",
    values: {
      content: "הוסף לספרייה",
      left: "שמאל",
      top: "למעלה",
      bottom: "למטה",
      right: "ימין",
    },
  },
};

const sides = ["left", "top", "bottom", "right"] as const;

export function TooltipRtl() {
  const { t } = useTranslation(translations, "ar");

  return (
    <TooltipProvider>
      <div className="flex flex-wrap gap-2">
        {sides.map((side) => (
          <Tooltip key={side}>
            <TooltipTrigger asChild>
              <Button variant="outline" className="w-fit capitalize">
                {t[side]}
              </Button>
            </TooltipTrigger>
            <TooltipContent side={side}>{t.content}</TooltipContent>
          </Tooltip>
        ))}
      </div>
    </TooltipProvider>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

17 lines
import { Button } from "@codefast/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@codefast/ui/tooltip";

export function TooltipUsage() {
  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger asChild>
          <Button variant="outline">Hover me</Button>
        </TooltipTrigger>
        <TooltipContent>
          <p>Add to library</p>
        </TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

TooltipProvider
└── Tooltip
├── TooltipTrigger
└── TooltipContent

Features

  • TooltipContent always renders its own arrow — no separate TooltipArrow needs to be added, unlike Popover or DropdownMenu.
  • Drop a Kbd inside TooltipContent to show a keyboard shortcut; it gets its own spacing and isolation styling automatically.

API reference

Props for each part of the component. All native element props are also forwarded.

TooltipProvider

Wrap your app (or a region) once; shares timing across tooltips.

delayDurationnumber

Milliseconds to hover before the tooltip opens — codefast overrides Radix's 700ms default to open instantly.

Default0

skipDelayDurationnumber

Window in which moving between triggers skips the delay.

Default300

TooltipContent

side"top" | "right" | "bottom" | "left"

Preferred side relative to the trigger.

Default"top"

sideOffsetnumber

Distance in px between the trigger and the content.

Default0

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

KeyFunction
TabFocusing the trigger opens the tooltip.
EscCloses the open tooltip.
  • The trigger must be a focusable element — use asChild over a Button or link.
  • Tooltips are supplementary: never put essential information or actions inside one.
  • Content is linked to the trigger via aria-describedby for screen readers.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Keep tooltip text to a short phrase.
  • Use for naming icon-only controls and surfacing shortcuts.

Don’t

  • Don’t place interactive controls inside a tooltip — use a Popover.
  • Don’t hide information the user needs to complete a task.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.