# Tooltip

A tooltip is a small, contextual message that appears when users hover over or
focus an element, providing additional information without cluttering the
interface. Also known as hint, info tip, or hover label.

Keep the text concise (1–2 lines). Prefer desktop or non-essential use — the
current pattern is not mobile-friendly.

## Installation

Install the tooltip, the theme package, and **the font package matching your
project's brand**:

**Leroy Merlin projects**

```bash
npm install @ptlm-azulejo/tooltip @ptlm-azulejo/themes @ptlm-azulejo/fonts-leroy-merlin
# or
yarn add @ptlm-azulejo/tooltip @ptlm-azulejo/themes @ptlm-azulejo/fonts-leroy-merlin
```

**Adeo projects**

```bash
npm install @ptlm-azulejo/tooltip @ptlm-azulejo/themes @ptlm-azulejo/fonts-adeo
# or
yarn add @ptlm-azulejo/tooltip @ptlm-azulejo/themes @ptlm-azulejo/fonts-adeo
```

## Styles & theming

The component ships no colors or typeface of its own — it reads design tokens from
CSS variables at runtime. Those tokens come from `@ptlm-azulejo/themes`, and **the
brand is selected by a class on your app's `<html>` element**, so switching brand
never touches component code.

| Project      | Preset stylesheet                               | Root class    | Typeface        | Font package                       |
| ------------ | ----------------------------------------------- | ------------- | --------------- | ---------------------------------- |
| Leroy Merlin | `@ptlm-azulejo/themes/presets/leroy-merlin.css` | `preset-lm`   | LeroyMerlinSans | `@ptlm-azulejo/fonts-leroy-merlin` |
| Adeo         | `@ptlm-azulejo/themes/presets/adeo.css`         | `preset-adeo` | Roboto          | `@ptlm-azulejo/fonts-adeo`         |

**Leroy Merlin projects**

```js
import '@ptlm-azulejo/themes/presets/leroy-merlin.css'
import '@ptlm-azulejo/fonts-leroy-merlin'
import '@ptlm-azulejo/tooltip/style.css'
```

```html
<html lang="pt" class="preset-lm"></html>
```

**Adeo projects**

```js
import '@ptlm-azulejo/themes/presets/adeo.css'
import '@ptlm-azulejo/fonts-adeo'
import '@ptlm-azulejo/tooltip/style.css'
```

```html
<html lang="pt" class="preset-adeo"></html>
```

> The preset class is what resolves the brand at runtime. Without it — even with
> the stylesheets imported — the component renders uncolored and in a fallback
> typeface. See the [themes package](../themes/README.md) for brand switching,
> dark mode, and custom brands.

### Light and dark mode

Add `data-theme` alongside the brand class to pin the color scheme. Leave it off
and the preset follows the OS `prefers-color-scheme`:

```html
<html lang="pt" class="preset-lm" data-theme="dark"></html>
```

### Why the font package is separate

The preset only _names_ its typeface in `--font-family` and ships no font files.
[Loading them is your app's job](../themes/README.md#fonts), as with upstream
Mozaic, so you keep control of hosting, subsetting and preload. Without the
matching font package, `font-sans` falls back to a generic sans-serif. A
multi-brand app can install both and switch by swapping the `.preset-*` class:
only the active brand's file is ever downloaded.

### Custom property

| Name                | Type     | Default | Description                                 |
| ------------------- | -------- | ------- | ------------------------------------------- |
| `--tooltip-z-index` | `number` | `1`     | Customise the z-index of the tooltip bubble |

## Props

| Name         | Type                                     | Default | Description                                                |
| ------------ | ---------------------------------------- | ------- | ---------------------------------------------------------- |
| `id`         | `string`                                 | —       | Unique id for `aria-describedby` / content `id` (required) |
| `text`       | `string`                                 | —       | Tooltip content; keep concise (required)                   |
| `position`   | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | Position relative to the trigger                           |
| `pointer`    | `boolean`                                | `true`  | Show the origin arrow pointing at the trigger              |
| `helpCursor` | `boolean`                                | `false` | Show the help cursor (`?`) on hover / focus                |
| `radius`     | `'none' \| 'sm' \| 'md' \| 'lg'`         | `'md'`  | Bubble border radius (`none` or `--border-radius-s/m/l`)   |
| `standalone` | `boolean`                                | `false` | Always visible, in normal flow (no hover gate)             |
| `ui`         | `TooltipUi`                              | `{}`    | Per-part Tailwind class overrides                          |

### `:ui` keys

Pass Tailwind class strings; they **merge** with defaults via `cn()` (conflicting utilities win).

| Key       | Targets                                                   | `data-testid`     |
| --------- | --------------------------------------------------------- | ----------------- |
| `root`    | Wrapper around the trigger and bubble                     | `tooltip`         |
| `content` | The bubble (`role="tooltip"`)                             | `tooltip-content` |
| `text`    | The label inside the bubble                               | `tooltip-text`    |
| `pointer` | Origin arrow wrapper (masked triangle on the bubble edge) | `tooltip-pointer` |

```vue
<AzTooltip
  id="styled-tip"
  text="Custom look"
  standalone
  :ui="{
    root: 'shadow-lg',
    content: 'bg-[color:var(--color-background-accent-inverse)] border-transparent',
    text: 'uppercase tracking-wide',
    pointer:
      '[--tooltip-pointer-fill:var(--color-background-accent-inverse)] [--tooltip-pointer-border:transparent]',
  }"
>
  Trigger
</AzTooltip>
```

When you recolour `content`, set `--tooltip-pointer-fill` / `--tooltip-pointer-border` on `pointer` so the arrow stays connected.

## Accessibility

Aligned with the [ARIA tooltip pattern](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Roles/tooltip_role) and WCAG **1.4.13 Content on Hover or Focus**:

| Requirement        | Behavior                                                                                                                          |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| Name / role        | Bubble has `role="tooltip"` and a stable `id`                                                                                     |
| Relationship       | `aria-describedby` is set on the **owning control** — a focusable slotted element if present, otherwise the root (`tabindex="0"`) |
| Keyboard           | Opens on focus; Escape dismisses without moving focus                                                                             |
| Hoverable          | Gap is sized so the arrow bridges trigger → bubble; hover stays on the root                                                       |
| Persistent         | Stays open until blur / mouse leave / Escape                                                                                      |
| Decorative arrow   | `aria-hidden="true"`                                                                                                              |
| Non-essential only | Do not put critical information only in the tooltip (touch / some AT may miss it)                                                 |

## Slots

| Name      | Description                                                     |
| --------- | --------------------------------------------------------------- |
| `default` | The tooltip will point to the content of the slot (the trigger) |

## Basic usage

```vue
<script setup>
import { AzTooltip } from '@ptlm-azulejo/tooltip'
</script>

<template>
  <AzTooltip id="help-tip" text="Keep the tooltip text concise."> Hover me </AzTooltip>
</template>
```

With an interactive trigger (the button receives `aria-describedby`):

```vue
<AzTooltip id="save-tip" text="Saves your draft">
  <button type="button">Save</button>
</AzTooltip>
```
