Truncate
Cuts one line of text that does not fit and keeps the full value one hover or one Tab away.
Examples
- run_01J9ZKQX8M2V4E7Q
- run_01J9ZKR3T5W8N2PA
- run_01J9ZM0B7C4D6F9H
src/agents/support-agent/tools/refund/handler.ts
Ana Marsh says the refund for order 4812 never arrived and asks for a call back
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
childrenstringdefaultrequiredposition'end' | 'middle'default'end'tailnumber | 'auto'default'auto'hintbooleandefaulttruefocusablebooleandefaulttrueTextHint contentReactNodedefaultrequired
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