Truncate

Cuts one line of text that does not fit and keeps the full value one hover or one Tab away.

Examples

IDs that share a prefix

  • run_01J9ZKQX8M2V4E7Q
  • run_01J9ZKR3T5W8N2PA
  • run_01J9ZM0B7C4D6F9H

A path

src/agents/support-agent/tools/refund/handler.ts

A title

Ana Marsh says the refund for order 4812 never arrived and asks for a call back

Resize the box

run_01J9ZKQX8M2V4E7Qsrc/agents/support-agent/tools/refund/handler.tsDrag the lower right corner.

Position

  • Refund for order 4812 never arrived

    enddefault

  • run_01J9ZKQX8M2V4E7Q

    middle

States

  • run_4812

    fits

  • run_01J9ZKQX8M2V4E7Q

    cut

Usage

When to use it
Use
An ID, hash or path sits in a column or a header that cannot grow.
Use
A title or message preview must stay on one line.
Not for
The text is the content of the page. Let it wrap.
Not for
The person needs to copy the value and read it whole. Use Copy button.
Not for
The value is code to read. Use Code block.

Rules

7 rules
Must
Pass position="middle" for IDs, hashes and paths; keep the default end cut for natural text. Because IDs of one kind share a prefix, so an end cut makes run_01J9ZK… of three different runs look the same.
Must
Pass the value as one string child, never as nodes. Because the hint, the middle split and the copy handler all work from the string, so a node would show a hint of nothing.
Must
Give the parent a width to cut against: a grid or flex cell with min-w-0, or a fixed or max width. Because an unbounded parent grows to fit the text, so nothing is ever cut and the row overflows.
Should
Set tail for names with an extension or a suffix that matters. Because the default tail is the last path segment or 6 characters, which can cut ".json" off a file name.
Should
Keep hint and focusable on, so a keyboard user reaches the full value. Because a cut value with no hint hides information from everyone, and one with a hint but no tab stop hides it from the keyboard.
Never
Cut a value with truncate or text-ellipsis classes on a Quartz surface. Because a plain ellipsis can land on half a glyph and gives no hint, no tab stop and no copy of the whole value.
Never
Cut a value the person must read to act, like an error message or a confirmation name. Because a hint is not shown on touch until a tap and is easy to miss, so the person acts on half the text.

Accessibility

5 checks
The DOM holds the whole string, so screen readers, find-in-page and copy get the full value.
Only a value that is actually cut becomes a tab stop and shows a hint; a value that fits adds no Tab.
The hint opens on hover and focus, closes on Escape, and on touch a tap toggles it.
The middle cut copies the full string, not the head and tail with an ellipsis.
Focus shows a 2px ink outline.

Edge cases

9 edge cases
Value fits
Plain text, no hint, no tab stop, no mask.
Container resizes
It re-measures and moves the cut; a hint appears or goes with it.
Emoji or accented letters
The cut lands between characters a person sees, never inside one.
Tail longer than the value
The whole value is the tail and nothing is cut at the head.
Path with a long last segment
Over 32 characters it falls back to the last 6 characters.
Right to left
The end fade flips to the left side; the middle cut sets dir="auto" on the text.
Before fonts load
It measures again when the fonts are ready, so the cut does not stay at the fallback font width.
Narrow phone
The hint is capped at the viewport less the gutters and wraps anywhere.
Zoom 200%
The cut follows the new width.

API

6 props
children
string default required
position
'end' | 'middle' default 'end'
tail
number | 'auto' default 'auto'
hint
boolean default true
focusable
boolean default true
TextHint content
ReactNode default required

Tokens

8 tokens
--hint-width
420px
--gutter-sm
16px
--radius-soft
6px
--surface-inverse
var(--ink)
--text-inverse
var(--paper)
--line-focus
2px
--border-focus
var(--ink)
--space-6
24px

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.