Overflow Hint

Shows the full text of a truncated label on hover.

  • Fix broken chat dragging
  • Redesign split chats so both panes keep their own scroll position
  • Hide empty threads
  • Move the model picker into the composer toolbar and remember the last choice per project

Installation

pnpm dlx shadcn@latest add @paneui/overflow-hint

Usage

Composition

Examples

Line Clamp

Parts

Use the parts when the hint shows something other than the label.

When it opens

The trigger is measured when the pointer rests on it, and the hint opens only if its text is cut off (wider or taller than its box). Text that fits never opens it, so it is safe on every row.

Selecting text

The pointer can move from the trigger into the hint without closing it, and the text there can be selected and copied. Presses inside the hint don't reach the trigger's row or tab. Pressing the trigger closes the hint until the pointer leaves, so clicks and drags don't bring it back.

Long text

The hint wraps at 320px (or the viewport less 16px), breaks long paths and scrolls past 192px of height. Line breaks in a string are kept.

Accessibility

Truncation is visual, so screen readers already get the full label from the trigger. The hint opens on hover only, which keeps it out of the way of keyboard focus on tabs and rows.

Motion

The hint opens and closes over 150ms with a slight scale and a 4px nudge from the trigger; with reduced motion it only fades.

API Reference

Built on the Preview Card primitive. Only the props this library adds or changes are listed; everything else passes through.

OverflowHintText

A trigger and its hint in one. Takes every OverflowHintTrigger prop. Also accepts every prop of OverflowHintTrigger.

hint
ReactNode
Hint content. Defaults to children.
side= "top"
"top" | "right" | "bottom" | "left"
Side of the text to open on.
align= "center"
"start" | "center" | "end"
Alignment against the text.
sideOffset= 6
number
Gap from the text in px.
alignOffset= 0
number
Shift along the text in px.
PropTypeDefaultDescription
hintReactNode—Hint content. Defaults to children.
side"top" | "right" | "bottom" | "left""top"Side of the text to open on.
align"start" | "center" | "end""center"Alignment against the text.
sideOffsetnumber6Gap from the text in px.
alignOffsetnumber0Shift along the text in px.

OverflowHint

Root. Keeps the hint closed while the trigger's text fits. Also accepts every prop of PreviewCard.Root.

open
boolean
Controlled open state.
onOpenChange
(open: boolean, eventDetails) => void
Called when the hint opens or closes; never called to open untruncated text.
PropTypeDefaultDescription
openboolean—Controlled open state.
onOpenChange(open: boolean, eventDetails) => void—Called when the hint opens or closes; never called to open untruncated text.

OverflowHintTrigger

The text that truncates and gets measured. Renders a block span. Also accepts every prop of PreviewCard.Trigger.

lines= 1
1 | 2 | 3
Lines before the text is cut off with an ellipsis.
delay= 300
number
Milliseconds before the hint opens.
closeDelay= 150
number
Milliseconds before it closes after the pointer leaves.
PropTypeDefaultDescription
lines1 | 2 | 31Lines before the text is cut off with an ellipsis.
delaynumber300Milliseconds before the hint opens.
closeDelaynumber150Milliseconds before it closes after the pointer leaves.

OverflowHintContent

Portal, positioner and popup in one. Also accepts every prop of PreviewCard.Popup.

side= "top"
"top" | "right" | "bottom" | "left"
Side of the trigger to open on.
sideOffset= 6
number
Gap from the trigger in px.
align= "center"
"start" | "center" | "end"
Alignment against the trigger.
alignOffset= 0
number
Shift along the trigger in px.
collisionPadding= 8
number
Space kept from the viewport edges in px.
PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""top"Side of the trigger to open on.
sideOffsetnumber6Gap from the trigger in px.
align"start" | "center" | "end""center"Alignment against the trigger.
alignOffsetnumber0Shift along the trigger in px.
collisionPaddingnumber8Space kept from the viewport edges in px.
data-side
The side it actually opened on, after collision handling.
Data attributeDescription
data-sideThe side it actually opened on, after collision handling.