# Tooltip

> A keyboard-friendly hint that surfaces on hover or focus. Renders as a CSS-only bubble - no portal, no JS, no third-party runtime.

- Category: overlay
- Status: stable (since 1.0.0)
- A11y pattern: https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/
- Tokens: --background-primary, --background-secondary, --foreground-primary, --foreground-muted
- Playground: https://design.freecodecamp.org/playground#tooltip
- npm dependencies: `react@>=18 <20`
- Registry dependencies: [theme](https://design.freecodecamp.org/registry/theme.md)
- Files:
  - `Tooltip.tsx` → `src/ui/tooltip/Tooltip.tsx` (raw: https://design.freecodecamp.org/registry/tooltip/Tooltip.tsx)
  - `tooltip.css` → `src/ui/tooltip/tooltip.css` (raw: https://design.freecodecamp.org/registry/tooltip/tooltip.css)

## Install (copy source)

1. Ensure the theme is installed once per project - tokens.css + base.css imported globally, fonts available. See https://design.freecodecamp.org/registry/theme.md and https://design.freecodecamp.org/registry/starter.md.
2. Copy the files below into `src/ui/tooltip/` (adjust to your project layout) and import the CSS once from your global stylesheet, e.g. `@import './ui/tooltip/tooltip.css';`.
3. Colors, spacing and type come from tokens - tailor the component by editing the copied source; recolour by editing tokens.css, not the component CSS.

## Usage

`<Tooltip>` wraps any trigger with a short explanatory hint. The bubble
renders inline next to the trigger so there is no portal or positioning
script - keep the hint under a dozen words.

## Usage

```tsx
import { Tooltip } from './ui/tooltip/Tooltip';
<Tooltip content='Copy link'>
  <button aria-label='Copy' className='btn btn--ghost'>
    🔗
  </button>
</Tooltip>;
```

## Accessibility

The bubble carries `role='tooltip'`; the trigger wrapper has `tabIndex={0}`
so keyboard users can focus it and see the hint. Tooltips are not a
substitute for a visible label: if the trigger has no text, give it an
`aria-label`.

## Example

```tsx
import { Tooltip } from './ui/tooltip/Tooltip';
import { Button } from './ui/button/Button';

<Tooltip content="Runs the public test suite against your code.">
  <Button>Run tests</Button>
</Tooltip>
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `content` | `ReactNode` | yes | - |  |
| `className` | `string` | no | `` |  |

## Source: Tooltip.tsx

```tsx
import React from 'react';

export interface TooltipProps {
  content: React.ReactNode;
  children: React.ReactNode;
  className?: string;
}

export const Tooltip = ({
  content,
  children,
  className = ''
}: TooltipProps) => {
  const classes = ['tip', className].filter(Boolean).join(' ');
  return (
    <span className={classes} tabIndex={0}>
      {children}
      <span role='tooltip' className='tip__bubble'>
        {content}
      </span>
    </span>
  );
};
Tooltip.displayName = 'Tooltip';
```

## Source: tooltip.css

```css
.tip {
  position: relative;
  display: inline-flex;
}
.tip__bubble {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  padding: 4px 10px;
  background: var(--foreground-primary);
  color: var(--background-primary);
  font: 500 13px/1.2 var(--font-mono);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms;
}
.tip:hover .tip__bubble,
.tip:focus-within .tip__bubble {
  opacity: 1;
}
```

## HTML / vanilla variant

```html
<span class="tip" data-tip="Runs the public test suite against your code.">
  <button class="btn">Run tests</button>
</span>
```

Interactive behaviours for plain HTML come from the vanilla runtime (data-uikit-* attributes): https://design.freecodecamp.org/registry/vanilla.md - or download https://design.freecodecamp.org/cdn/uikit.global.js once and self-host it (do not hotlink).

## For coding agents

This library is distributed as copyable source, not an npm package. Start at https://design.freecodecamp.org/registry/starter.md, discover components via https://design.freecodecamp.org/llms.txt, and copy files into the consuming project. Keep token names intact; recolour by editing the copied tokens.css.
