Components / Overlays & disclosure

ExpandableText

Long text clamped to a few lines with a soft fade that glides open with Read more and closes with Show less, shown only when the text overflows.

Install

npx shadcn@latest add https://irisui.dev/r/expandable-text.json
import { ExpandableText } from "@/components/iris/expandable-text/expandable-text";
Registry item expandable-textBrings in foundationRegistry JSON

Preview

ExpandableText

Long text clamped to a few lines with a soft fade, opened with Read more and closed with Show less only when it actually overflows.

When to use

  • Release notes, descriptions, reviews, and bios inside cards or lists where length varies.
  • Keeping rows a consistent height while letting readers open the full text in place.
  • Not for structured sections: use Accordion. Not for a scrollable fixed-height region: use ScrollArea.

Usage

import { ExpandableText } from "@/components/iris/expandable-text/expandable-text";

h(ExpandableText, { lines: 3 }, releaseNotes);
h(ExpandableText, { lines: 2, moreLabel: "Show full notes", lessLabel: "Collapse" }, releaseNotes);

Props

Prop Type Default Description
children ReactNode — Required. Plain text, paragraphs, or inline links.
lines number 3 Lines shown while collapsed.
expanded boolean — Controlled open state.
defaultExpanded boolean false Initial state when uncontrolled.
onExpandedChange (expanded: boolean) => void — Called when toggled.
moreLabel string "Read more" Toggle label while collapsed.
lessLabel string "Show less" Toggle label while open.
…div props className, style, aria-*.

Notes

  • The toggle appears only when the text overflows its line clamp, and stays correct as the width or font changes.
  • The full text stays available to screen readers while clamped; the toggle is a button with aria-expanded.
  • Closing brings the start of the text back into view if it had scrolled away. Height eases open; reduced motion snaps.
  • Reads --ink, --ink-2, --ink-3, --text-sm, --leading-body.