# Tooltip
> Tooltip whose bubble grows out of its arrow pixel by pixel on hover or keyboard focus before the text fades in; Escape hides it.
- React: `import { PxTooltip } from "@/components/lumesec/px-tooltip"`
- Collection: Pixel UI (https://elements.lumesec.ai/components/pixel-ui)
- Registry item: https://elements.lumesec.ai/r/px-tooltip.json
- Page: https://elements.lumesec.ai/components/pixel-ui/tooltip



Live preview: https://elements.lumesec.ai/view/px-tooltip

Demo source:

```tsx
import { PxTooltip } from "@/components/lumesec/px-tooltip";

const iconButton = "grid size-9 place-items-center rounded-[9px] border border-border bg-card p-0 text-foreground";
const iconSvg = "size-4 fill-none stroke-current [stroke-linecap:round] [stroke-linejoin:round] [stroke-width:1.6]";

export default function PxTooltipDemo() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-2.5">
      <PxTooltip content="Copy link">
        <button type="button" className={iconButton} aria-label="Copy link">
          <svg viewBox="0 0 16 16" aria-hidden="true" className={iconSvg}>
            <path d="M6.5 9.5l3-3M7 4.5l1-1a2.5 2.5 0 0 1 3.5 3.5l-1 1M9 11.5l-1 1A2.5 2.5 0 0 1 4.5 9l1-1" />
          </svg>
        </button>
      </PxTooltip>
      <PxTooltip content="Share">
        <button type="button" className={iconButton} aria-label="Share">
          <svg viewBox="0 0 16 16" aria-hidden="true" className={iconSvg}>
            <path d="M8 2.5v7M5 5.5l3-3 3 3M3.5 9v3.5h9V9" />
          </svg>
        </button>
      </PxTooltip>
      <PxTooltip content="Delete" placement="bottom">
        <button type="button" className={iconButton} aria-label="Delete">
          <svg viewBox="0 0 16 16" aria-hidden="true" className={iconSvg}>
            <path d="M2.5 4h11M6 4V2.6h4V4M3.8 4l.7 9.2c.1.8.7 1.3 1.5 1.3h4c.8 0 1.4-.5 1.5-1.3L12.2 4" />
          </svg>
        </button>
      </PxTooltip>
    </div>
  );
}
```

## Playground

Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.

## Installation

```bash
npx shadcn@latest add @lumesec/px-tooltip
```

First time with the @lumesec registry? Register it once, or install by URL:

```bash
npx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json
npx shadcn@latest add https://elements.lumesec.ai/r/px-tooltip.json
```

## Usage

React:

```tsx
import { PxTooltip } from "@/components/lumesec/px-tooltip";

export function Example() {
  return (
    <PxTooltip content="Copy link">
      <button type="button">Copy</button>
    </PxTooltip>
  );
}
```

## Behaviour

The bubble grows out of its arrow pixel by pixel on hover or keyboard focus, then the text fades in. Escape hides it.

## API reference

### Props

Also accepts every prop of `<span>` (`React.ComponentProps<"span">`), spread onto the root element.

| Prop           | Type                      | Default | Description                                                                                      |
| -------------- | ------------------------- | ------- | ------------------------------------------------------------------------------------------------ |
| `content`      | `React.ReactNode`         | —       | Tooltip text. It does not wrap.                                                                  |
| `children`     | `React.ReactNode`         | —       | The trigger, usually a button. A single element gets `aria-describedby` pointing at the tooltip. |
| `placement`    | `"top" \| "bottom"`       | `"top"` | `bottom` places the bubble below the trigger.                                                    |
| `delay`        | `number`                  | `250`   | Milliseconds of hover or focus before the bubble opens.                                          |
| `open`         | `boolean`                 | —       | Controlled open state. Use with `onOpenChange`.                                                  |
| `defaultOpen`  | `boolean`                 | `false` | Initial open state when uncontrolled.                                                            |
| `onOpenChange` | `(open: boolean) => void` | —       | Called when hover, focus or Escape opens or closes the tooltip.                                  |

### Ref

`ref` points at the root `HTMLSpanElement`.

## Keyboard

| Keys   | Action                               |
| ------ | ------------------------------------ |
| Escape | Hide the tooltip, wherever focus is. |

## Accessibility

* The bubble has `role="tooltip"` and stays in the DOM (hidden when closed); the trigger references it with `aria-describedby`, merged with any value the trigger already has.
* It opens on keyboard focus as well as hover, and closes 60 ms after focus or the pointer leaves.
* The bubble does not take pointer events.
* Reduced motion: the bubble appears at full size at once instead of growing from the arrow.

## Theming

Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from `--lumesec`. See [Theming](/docs/theming).

This component reads `--foreground`, `--muted` and `--card`.

## Notes

* The bubble is centred on the trigger, does not wrap its text and does not flip or shift to stay inside the viewport.
* The root is an inline-block `span` around the trigger; pointer and focus handlers passed to it still run.


