Skip to content

Overflow

Container-aware overflow handling for items (dynamic fitting with indicator) and text (line clamping with auto-tooltip when truncated).

Preview

Installation

$pnpm exec dgadd add ui/overflow
[Installs to]src/components/ui/overflow[Item]ui/overflow

dgadd is not public on npm yet. Until the first release, pack @diffgazer/add from the repository and install that tarball into this app, which is what puts dgadd on pnpm exec.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS once packages are available.

Usage

tsx
"use client";import { Overflow } from "@/components/ui/overflow";const tags = ["React", "TypeScript", "Tailwind", "Node.js", "Vitest", "Zod", "Prisma"];// Each chip is passed as its own React child so Overflow measures them individually;// a child may be any element or component, as long as one child means one measured item.const CHIP_CLASS =  "inline-flex items-center rounded-sm border border-foreground/30 px-2 py-0.5 font-mono text-xs text-foreground";export default function OverflowItemsExample() {  return (    <div className="flex flex-col gap-4">      <div className="space-y-1.5">        <span className="text-xs font-mono text-muted-foreground">          default indicator — dashed badge shipped by the component        </span>        <div className="w-80 border border-dashed border-foreground/20 p-2">          <Overflow mode="items" className="gap-1.5">            {tags.map((tag) => (              <span key={tag} className={CHIP_CLASS}>                {tag}              </span>            ))}          </Overflow>        </div>      </div>      <div className="space-y-1.5">        <span className="text-xs font-mono text-muted-foreground">          custom indicator — solid, tight radius, matches the chips        </span>        <div className="w-80 border border-dashed border-foreground/20 p-2">          <Overflow            mode="items"            className="gap-1.5"            indicator={({ count }) => (              <span className="inline-flex items-center rounded-sm border border-foreground/30 bg-foreground/10 px-2 py-0.5 font-mono text-xs text-muted-foreground">                +{count} more              </span>            )}          >            {tags.map((tag) => (              <span key={tag} className={CHIP_CLASS}>                {tag}              </span>            ))}          </Overflow>        </div>      </div>    </div>  );}

Examples

Avatars

Preview

Text

Preview

API Reference

Overflow

NameTypeDefaultDescription
mode"text" | "items""text"Selects fitting-items mode when set to items; text clamps string content with optional auto-tooltip, while items measures children and renders an overflow indicator for those that do not fit.
childrenrequiredstring (text mode) | ReactNode (items mode)Items to fit into the available width; string to clamp (text mode) or items to measure (items mode).
linesnumber1Text mode only. 1 truncates; 2+ uses CSS line-clamp.
tooltipReactNode | booleanText mode only. true/ReactNode renders a Tooltip when content is actually clipped (auto-derived from children when true). false disables the tooltip.
indicatorReactNode | ((props: { count: number }) => ReactNode)dashed ellipsis badgeCustom indicator shown for items that do not fit. Items mode only; render function or static node shown when items overflow.
getOverflowLabel(count: number) => stringcount => count + " more items"Items mode only. Localizes the accessible name announced for the overflow indicator.
classNamestringMerged onto the root. Items mode ships gap-1 between items and indicator; override it here (for example gap-1.5).

Accessibility

Notes

Two Modes

Text mode is the default: CSS truncation with useOverflowDetection hook detecting actual overflow + Tooltip that only appears when content is truly clipped. Items mode requires mode="items" and measures children against container width via ResizeObserver, showing what fits plus an overflow indicator.

Items Mode

Uses a hidden measurement row to calculate widths before paint (no flicker). Default indicator is an ellipsis badge. Customize via the indicator prop — pass a render function ({ count }) => ReactNode or static ReactNode.

Indicator Convention

The built-in indicator is a dashed badge: dashed means 'the library put this here'. Custom indicators are solid so a consumer-authored count reads as content. Keep custom indicators on the tight radius (rounded-sm or none) so they match neighbouring chips.

Text Mode

Set lines={1} for single-line truncate or lines={2+} for multi-line clamping. Tooltip auto-derives content from string children. Set tooltip={false} to disable, or tooltip={<custom>} for custom content.

useOverflowDetection Hook

The overflow detection logic is available as a standalone hook (overflow-detection registry item). Use it independently for custom overflow UIs.

Source

Install via CLI: pnpm exec dgadd add ui/overflow. Keyboard hooks are included as standalone copies. For the full experience, use --integration keys.

Highlighted source loads after this disclosure opens. Browse the source repository.