Content
- Plain sentences that say what the number or label means, and how it's counted.
Explain-this bubbles: an ⓘ that opens on hover or tap, and tooltips for chips and controls.
import { … } from "@brdgapp/ui/components/info-hint"Bridge has one look for "explain this" bubbles, in three forms. InfoHint is an ⓘ next to a label that opens on hover, keyboard focus or tap. HoverTip wraps a chip or count in a button with a tooltip. Tip adds a tooltip to something that is already a control. The usual mistake is the browser's title attribute: it is slow, unstyled, and invisible to keyboard and touch users.
title attribute for an explanation.One of each
Bridge has one button, one label, one menu, one tooltip, one confirm dialog and one table. Before building a control, look for it here. Never hand-make a second version (a <button> with pill classes, a <span> chip, a new kebab), even if it looks the same today: copies drift.
Every control has a name
Every control says what it does to a screen reader. An icon-only button carries an aria-label naming the action ("Close", not "X"); a group of filters or a table has a name; a tooltip is never the only name.
Intros where the person you introduced replied and agreed to meet, out of every intro you made this year.
Trigger. InfoHint: a 14px ⓘ. HoverTip: your content inside a button. Tip: your control itself.
Bubble. Raised surface, 1px border, 12px text, up to 16rem wide. Opens below and shifts to stay on screen.
Hover, focus or tap the ⓘ.
Detail on a chip.
Detail on an existing control.
| Rest | Hover | Focus | |
|---|---|---|---|
| InfoHint | |||
| HoverTip |
| State | What happens |
|---|---|
| Closed | Only the trigger shows. |
| Open | On hover or keyboard focus, instantly. InfoHint also opens on tap. |
focusable makes a plain label reachable by Tab; disabled hides the tip, for example while the control's own menu is open.Do
Keep it to one or two sentences.Don't
Put a paragraph or a link in a bubble.Do
Give the control its own name (aria-label).Don't
Rely on the tooltip to name an icon button.| Keys | Action |
|---|---|
| Tab | Focusing the trigger opens the bubble. |
| Esc | Closes it. |
InfoHint
The ⓘ with its explanation.
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | The explanation. Also the trigger's accessible name. |
className | string | — | Layout only. |
…other attributes | id, aria-*, data-*, event handlers | — | Passed to the ⓘ button. The component's own props win where they overlap. |
HoverTip
Wraps content that isn't a control.
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | The tooltip. |
children | ReactNode | — | What to wrap. |
…other attributes | id, aria-*, data-*, event handlers | — | Passed to the button it wraps the content in. The component's own props win where they overlap. |
className | string | — | Layout only, on the wrapping button. |
Tip
A tooltip on an existing control or label.
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | — | The tooltip. Without it, Tip renders its child unchanged. |
children | ReactElement | — | The control. It becomes the trigger. |
focusable | boolean | false | Wraps a plain label in a tab stop. |
disabled | boolean | false | Don't show the tip. |
What it's built from and where it's used, read from the code. When you change it, check these too.
Where the code still differs from the system. Follow the system, not the gap.
components.md → InfoHint / HoverTip, Tip; src/components/ui/info-hint.tsx.