# Tooltip

> Tooltip names an icon-only control on hover or focus; Popover holds a small interactive panel anchored to a trigger.

Component · Overlays · Pro kit · [Live page](https://ui.twentyfirst.media/pro/components/Tooltip/)

`Tooltip` names an icon-only control on hover or focus; `Popover` holds a small interactive panel anchored to a trigger.

Tooltip props: `label`, `shortcut`, `side` ("top" | "bottom" | "left" | "right"), one child element.
Popover props: `trigger` (element, or `({open, toggle}) => element`), `open`/`onOpenChange` (optional control), `align` ("start" | "end"), `side` ("top"), `width`, `flush` (no padding, for Menus), `block`, children or `({close}) => children`.

- Tooltips only add a name or a shortcut. Anything you must read or click goes in a Popover.
- Tooltips appear after 350 ms on hover, immediately on keyboard focus, and close on Esc.
- Popovers close on outside click and Esc. Use a Modal when the task needs more than a few fields.

## Example

```tsx
import { Button, Combobox, Icon, Popover, Tooltip } from "@twentyfirstmedia/pro";

function App() {
  return (
    <div
      className="tf-panel"
      style={{
        gap: 40,
        paddingTop: 56,
      }}
    >
      <div
        className="tf-row"
        style={{
          gap: 16,
        }}
      >
        <Tooltip label="Archive" shortcut="E">
          <button type="button" className="tf-iconbtn tf-iconbtn-soft" aria-label="Archive">
            <Icon name="inbox" />
          </button>
        </Tooltip>
        <Tooltip label="Star">
          <button type="button" className="tf-iconbtn tf-iconbtn-soft" aria-label="Star">
            <Icon name="star" />
          </button>
        </Tooltip>
        <Tooltip label="Opens in a new tab" side="bottom">
          <button type="button" className="tf-btn tf-btn-secondary">
            View invoice
          </button>
        </Tooltip>
        <Tooltip label="Copy share link" shortcut="⌘L" defaultOpen>
          <button type="button" className="tf-iconbtn tf-iconbtn-soft" aria-label="Share">
            <Icon name="share" />
          </button>
        </Tooltip>
      </div>
      <div
        className="tf-row"
        style={{
          gap: 16,
          alignItems: "flex-start",
          // room for the open popover, so the preview shows it whole
          minHeight: 260,
        }}
      >
        <Popover
          open
          width={280}
          trigger={
            <button type="button" className="tf-btn tf-btn-soft">
              <Icon name="users" size={15} />
              Assign
            </button>
          }
        >
          <div
            className="tf-col"
            style={{
              gap: 12,
            }}
          >
            <b>Assign to</b>
            <Combobox
              options={["Ava Vogel", "Ben Okafor", "Clara Haddad"]}
              placeholder="Search people"
            />
            <div
              className="tf-row"
              style={{
                justifyContent: "flex-end",
              }}
            >
              <Button size="sm">Assign</Button>
            </div>
          </div>
        </Popover>
      </div>
    </div>
  );
}
export default App;
```

## Props

### Button

| Prop | Type | Notes |
| --- | --- | --- |
| `variant?` | `"primary" \| "secondary" \| "soft" \| "ghost" \| "danger" \| "danger-solid"` |  |
| `size?` | `"md" \| "sm"` |  |
| `icon?` | `IconName` |  |
| `iconRight?` | `IconName` |  |
| `disabled?` | `boolean` |  |
| `type?` | `"button" \| "submit" \| "reset"` |  |
| `onClick?` | `(e: MouseEvent<HTMLButtonElement>) => void` |  |
| `children?` | `ReactNode` |  |
| `asChild?` | `boolean` | Render the single child element (a link, a router Link) with the button's look instead of a <button>. |
| `id?` | `string` |  |
| `name?` | `string` | Form field name and value, sent with the form when this button submits it. |
| `value?` | `string` |  |
| `form?` | `string` | The id of the form this button belongs to, when it sits outside it. |
| `title?` | `string` |  |
| `tabIndex?` | `number` |  |
| `autoFocus?` | `boolean` |  |
| `aria-label?` | `string` |  |
| `aria-labelledby?` | `string` |  |
| `aria-describedby?` | `string` |  |
| `aria-expanded?` | `boolean \| "true" \| "false"` | For disclosure and menu triggers: whether what the button controls is open. |
| `aria-controls?` | `string` |  |
| `aria-haspopup?` | `boolean \| "true" \| "false" \| "menu" \| "listbox" \| "tree" \| "grid" \| "dialog"` |  |
| `aria-pressed?` | `boolean \| "true" \| "false" \| "mixed"` | For toggle buttons. |
| `aria-current?` | `boolean \| "true" \| "false" \| "page" \| "step" \| "location" \| "date" \| "time"` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Combobox

| Prop | Type | Notes |
| --- | --- | --- |
| `label?` | `string` |  |
| `options` | `(string \| Option)[]` | Required |
| `value?` | `string \| string[] \| null` |  |
| `defaultValue?` | `string \| string[]` |  |
| `onChange?` | `(v: string \| string[] \| null) => void` |  |
| `multiple?` | `boolean` |  |
| `creatable?` | `boolean` |  |
| `placeholder?` | `string` |  |
| `hint?` | `string` |  |
| `error?` | `string` |  |
| `required?` | `boolean` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Icon

| Prop | Type | Notes |
| --- | --- | --- |
| `name` | `IconName` | Required |
| `size?` | `number` |  |
| `label?` | `string` |  |
| `className?` | `string` |  |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Popover

| Prop | Type | Notes |
| --- | --- | --- |
| `trigger` | `ReactNode \| ((s: { open: boolean; toggle: () => void }) => ReactNode)` | Required |
| `open?` | `boolean` |  |
| `onOpenChange?` | `(o: boolean) => void` |  |
| `align?` | `"start" \| "end"` |  |
| `side?` | `"top" \| "bottom"` |  |
| `width?` | `number` |  |
| `flush?` | `boolean` |  |
| `block?` | `boolean` |  |
| `role?` | `string` |  |
| `children?` | `ReactNode \| ((s: { close: () => void }) => ReactNode)` |  |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |

### Tooltip

| Prop | Type | Notes |
| --- | --- | --- |
| `label` | `ReactNode` | Required |
| `shortcut?` | `string` |  |
| `side?` | `"top" \| "bottom" \| "left" \| "right"` |  |
| `defaultOpen?` | `boolean` | Starts open (for demos and onboarding hints); it still closes on blur and Escape. |
| `children` | `ReactNode` | Required |
| `className?` | `string` | Extra class on the root element. |
| `style?` | `CSSProperties` | Inline style on the root element. |
