feat(lab): LineClamp — clamp arbitrary content to N lines (port from XDSLineClamp)
Open
@cixzhang is already working on this.
Since Sep 2, 2026.
component
enhancement
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 1.1k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 669
Description
Summary
Add a LineClamp component that truncates arbitrary content to a fixed number of lines with an ellipsis, ported from the internal XDSLineClamp component. Port the value and behavior, not the internal structure.
Why a dedicated component
Astryx already clamps text via Text's maxLines prop (backed by useTruncation). LineClamp is a different primitive: a standalone wrapper that clamps whatever you put inside it to N lines — not just a Text node.
Text maxLines |
LineClamp |
|
|---|---|---|
| Scope | Truncates the Text component's own string content |
Clamps any children to N lines |
| Use | "This label is one Text, cap it at 2 lines" |
"Cap this block of mixed/inline content at N lines" |
| Composition | Built into Text |
Composable around arbitrary content |
So this is not a duplicate of Text — it's the reusable clamp primitive that other components and consumers can wrap around content that isn't a single Text.
Proposed behavior (to confirm against the internal source during the port)
lines(ormaxLines) — number of lines to clamp to.- Clamps via
-webkit-line-clamp(the same mechanismText/useTruncationalready rely on), with a block/overflow setup that works cross-browser. - Truncation detection should reuse the existing
useTruncationhook rather than reinventing overflow measurement — it already handles the multi-lineRange.getBoundingClientRect()case and shares a singleResizeObserver. - Optional tooltip / "show more" affordance on overflow (mirror what the internal component does; decide during the port).
- Extends
BaseProps,xstyle/className/styleescape hatches,displayName,'use client'.
Scope
- Land in
@astryxdesign/labfirst (canary-only), following the standard lab → core graduation path. - Full component surface:
LineClamp.tsx, colocatedLineClamp.test.tsx,LineClamp.doc.mjs,index.tsexport, Storybook story, showcase block. - Reuse
useTruncationand semantic tokens; StyleX only.
Open questions for the port
- Prop name:
linesvsmaxLines(align withText's existingmaxLinesfor consistency?). - Does the internal component own the overflow-detection/tooltip behavior, or is that left to the consumer? Decide what to port vs. drop.
- Any semantic-name/API differences from the internal version get resolved to Astryx conventions (port the value, not the internal API shape).
Acceptance criteria
-
LineClampclamps arbitrary children to N lines with an ellipsis. - Reuses
useTruncationfor overflow detection (no reinvented measurement). - StyleX only, tokens,
BasePropsescape hatches,displayName,'use client'. - Colocated test,
.doc.mjs, Storybook story, showcase block,index.tsexport. - Lands in
@astryxdesign/lab; documented as lab/canary.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.