Lynx Text Composition
Build a continuous text composition around one outer <text>. Treat that element as the owner of paragraph measurement and line layout.
Workflow
- Separate block layout from continuous text layout.
- Use an outer
<view> for the card, background, padding, and other block concerns.
- Put the complete naturally wrapping paragraph in one outer
<text>.
- Nest
<text> only when a span has different styling, semantics, or events.
- Nest
<image> directly for an inline image. Nest <view> for an atomic inline structure with multiple children.
- Put paragraph properties such as
line-height, text-align, text-indent, text-maxline, and truncation on the outer <text>.
- Keep adjacent Chinese fragments adjacent. Write
{" "} when a real space is required.
- Verify narrow and wide containers, dynamic copy, font scaling, and every target platform.
Canonical structure
<view className="card">
<text className="paragraph">
{"Continuous body copy stays in one string. "}
<text className="emphasis">{"Only distinct spans are nested."}</text>{" "}
<image className="icon" src={icon} />{" "}
<view className="badge">
<text className="badgeDot">{"●"}</text>
<text className="badgeLabel">{"Label"}</text>
</view>
</text>
</view>;
.paragraph {
overflow: hidden;
font-size: 28rpx;
line-height: 44rpx;
text-align: left;
text-overflow: ellipsis;
}
.icon,
.badge {
vertical-align: center;
}
.badge {
display: flex;
flex-direction: row;
align-items: center;
}
The nested position gives image/view nodes their inline identity. display on the badge controls only how the badge lays out its children.
Guardrails
- Put every visible string inside
<text>.
- Do not split a paragraph into flex rows or strings based on a design width.
- Do not use Web-only
display: inline, inline-block, inline-flex, or inline-grid values.
- Do not rely on
flex, flex-grow, or flex-shrink on inline nodes to allocate text-line space.
- Set
vertical-align on each nested text/image/view that needs it; the property does not inherit.
- Do not set paragraph
line-height on an inline child and expect it to change the paragraph line box.
- Preserve source state transitions and event boundaries when migrating regression cases.
- Replace private resources and retired host switches with public deterministic equivalents, and document the compatibility boundary instead of inventing an API.
Review and validation
Read README.md for the complete guide, official documentation links, and the 24-case source mapping.
Use src/components/TextCompositionArticle.tsx as the production-oriented composition example.
Use src/cases/registry.tsx and the case implementations for focused regression inputs; historical bad cases are test fixtures, not recommended patterns.
Run:
pnpm --filter @lynx-example/text-composition run build
pnpm dprint check
pnpm meta-updater --test
Capture each relevant case on a Lynx runtime. Confirm wrapping, truncation, events, direction, and vertical alignment rather than checking only that the page loads.
1---2name: text-composition3description: Use when implementing or reviewing ReactLynx content that needs continuous text measurement, natural wrapping, nested text/image/view composition, truncation, vertical alignment, bidirectional text, or language-aware line breaking.4---56# Lynx Text Composition78Build a continuous text composition around one outer `<text>`. Treat that element as the owner of paragraph measurement and line layout.910## Workflow11121. Separate block layout from continuous text layout.132. Use an outer `<view>` for the card, background, padding, and other block concerns.143. Put the complete naturally wrapping paragraph in one outer `<text>`.154. Nest `<text>` only when a span has different styling, semantics, or events.165. Nest `<image>` directly for an inline image. Nest `<view>` for an atomic inline structure with multiple children.176. Put paragraph properties such as `line-height`, `text-align`, `text-indent`, `text-maxline`, and truncation on the outer `<text>`.187. Keep adjacent Chinese fragments adjacent. Write `{" "}` when a real space is required.198. Verify narrow and wide containers, dynamic copy, font scaling, and every target platform.2021## Canonical structure2223```tsx24<view className="card">25 <text className="paragraph">26 {"Continuous body copy stays in one string. "}27 <text className="emphasis">{"Only distinct spans are nested."}</text>{" "}28 <image className="icon" src={icon} />{" "}29 <view className="badge">30 <text className="badgeDot">{"●"}</text>31 <text className="badgeLabel">{"Label"}</text>32 </view>33 </text>34</view>;35```3637```css38.paragraph {39 overflow: hidden;40 font-size: 28rpx;41 line-height: 44rpx;42 text-align: left;43 text-overflow: ellipsis;44}4546.icon,47.badge {48 vertical-align: center;49}5051.badge {52 display: flex;53 flex-direction: row;54 align-items: center;55}56```5758The nested position gives image/view nodes their inline identity. `display` on the badge controls only how the badge lays out its children.5960## Guardrails6162- Put every visible string inside `<text>`.63- Do not split a paragraph into flex rows or strings based on a design width.64- Do not use Web-only `display: inline`, `inline-block`, `inline-flex`, or `inline-grid` values.65- Do not rely on `flex`, `flex-grow`, or `flex-shrink` on inline nodes to allocate text-line space.66- Set `vertical-align` on each nested text/image/view that needs it; the property does not inherit.67- Do not set paragraph `line-height` on an inline child and expect it to change the paragraph line box.68- Preserve source state transitions and event boundaries when migrating regression cases.69- Replace private resources and retired host switches with public deterministic equivalents, and document the compatibility boundary instead of inventing an API.7071## Review and validation72731. Read [README.md](README.md) for the complete guide, official documentation links, and the 24-case source mapping.742. Use [src/components/TextCompositionArticle.tsx](src/components/TextCompositionArticle.tsx) as the production-oriented composition example.753. Use [src/cases/registry.tsx](src/cases/registry.tsx) and the case implementations for focused regression inputs; historical bad cases are test fixtures, not recommended patterns.764. Run:7778 ```bash79 pnpm --filter @lynx-example/text-composition run build80 pnpm dprint check81 pnpm meta-updater --test82 ```83845. Capture each relevant case on a Lynx runtime. Confirm wrapping, truncation, events, direction, and vertical alignment rather than checking only that the page loads.