Skip to content

feat(mobile-expo): TextRenderer section component#323

Merged
up-tandem merged 2 commits intomainfrom
feat/308-text-renderer
Mar 10, 2026
Merged

feat(mobile-expo): TextRenderer section component#323
up-tandem merged 2 commits intomainfrom
feat/308-text-renderer

Conversation

@up-tandem
Copy link
Contributor

@up-tandem up-tandem commented Mar 10, 2026

Summary

  • Replaces the Text stub renderer with a real implementation
  • Heading sized by headingLevel (h1=32px through h6=16px), defaults to h2
  • Optional subtitle with muted styling
  • Content text with variant support: lead (larger/prominent), small (compact), default (standard)
  • Graceful handling of missing optional fields
  • Accessible heading role

Contracts Changed

No

Regeneration Required

No

Validation

  • pnpm --filter @forge/expo lint — passes with 0 warnings
  • pnpm --filter @forge/expo test -- --testPathPattern=TextRenderer — 10/10 tests pass
  • pnpm --filter @forge/expo test -- --testPathPattern=SectionDispatcher — 11/11 tests pass (no regressions)

Resolves #308

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Implemented TextRenderer component with support for heading levels (h1–h6), lead and small variants, and accessibility features.
    • Added CardRenderer, SectionWrapperRenderer, and ContainerRenderer components.
  • Tests

    • Added comprehensive unit tests for TextRenderer covering all configurations and variants.

Replace the Text stub with a real renderer that displays heading (sized
by headingLevel h1-h6), subtitle, and content text with default/lead/small
variant styling.

Resolves #308

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Walkthrough

Replace the TextStub placeholder with a fully-featured TextRenderer component that displays rich text content blocks with dynamic heading levels (h1–h6), optional subtitle, variant support (default, lead, small), and comprehensive unit tests.

Changes

Cohort / File(s) Summary
TextRenderer Implementation
mobile/expo/src/components/sections/TextRenderer.tsx
New React Native component that renders text sections with configurable heading levels, subtitle support, and three variants (default, lead, small) with associated styling adjustments.
TextRenderer Tests
mobile/expo/src/components/sections/TextRenderer.test.tsx
New test suite covering full field rendering, minimal field handling, variant rendering (lead/small), and parameterized tests for all heading levels (h1–h6).
Module Updates
mobile/expo/src/components/sections/SectionDispatcher.tsx, mobile/expo/src/components/sections/index.ts, mobile/expo/src/components/sections/TextStub.tsx
Import source updated from TextStub to TextRenderer; export source changed; TextStub removed; new exports added for CardRenderer, SectionWrapperRenderer, and ContainerRenderer.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing a new TextRenderer component for the mobile Expo platform, which aligns with the primary objective of replacing the stub implementation.
Linked Issues check ✅ Passed The pull request successfully implements all acceptance criteria from issue #308: renders heading with headingLevel sizing (h1–h6), renders optional subtitle, renders content, supports variant styling (default/lead/small), handles missing optional fields gracefully, replaces the Text stub in SectionDispatcher, and includes proper accessibility and styling.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the TextRenderer component as specified in issue #308. The exports of CardRenderer and SectionWrapperRenderer in index.ts appear to be ancillary additions not related to the core objective but are minor and support the component's integration.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/308-text-renderer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

# Conflicts:
#	mobile/expo/src/components/sections/index.ts
@up-tandem
Copy link
Contributor Author

Test results (b092243)

Check Result
CI pass (build-and-test, commits, generated-code, CodeRabbit all green)
Lint pass
Tests 57 passed, 6 suites
iOS verified — default, lead, small variants render correctly
Android verified — same
Reviews no review comments

No changes needed. Ready to merge.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
mobile/expo/src/components/sections/TextRenderer.test.tsx (1)

18-22: Consider using render-based tests for better coverage.

createElement only creates a React element object; it doesn't invoke the render function. Runtime errors inside TextRenderer (e.g., style computation, conditional rendering bugs) won't be caught.

Using render from @testing-library/react-native would actually mount the component and exercise the render path, providing stronger guarantees.

♻️ Example using React Native Testing Library
-import { createElement } from "react"
+import { render, screen } from "@testing-library/react-native"

 import type { TextSection } from "../../lib/sectionModels"
 import { TextRenderer } from "./TextRenderer"

 // ...

 describe("TextRenderer", () => {
   it("renders without throwing with all fields", () => {
-    expect(() =>
-      createElement(TextRenderer, { section: baseSection }),
-    ).not.toThrow()
+    render(<TextRenderer section={baseSection} />)
+    expect(screen.getByText("The Real Easter Story")).toBeTruthy()
   })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mobile/expo/src/components/sections/TextRenderer.test.tsx` around lines 18 -
22, The test currently uses createElement(TextRenderer, { section: baseSection
}) which only constructs a React element and won't exercise rendering logic;
replace the createElement assertion with mounting via render from
`@testing-library/react-native` (import render) and call render(<TextRenderer
section={baseSection} />) then assert that rendering does not throw and/or query
for expected output; update the test case name if desired and keep references to
TextRenderer and baseSection so the rendered component is actually mounted
instead of just created.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@mobile/expo/src/components/sections/TextRenderer.test.tsx`:
- Around line 18-22: The test currently uses createElement(TextRenderer, {
section: baseSection }) which only constructs a React element and won't exercise
rendering logic; replace the createElement assertion with mounting via render
from `@testing-library/react-native` (import render) and call render(<TextRenderer
section={baseSection} />) then assert that rendering does not throw and/or query
for expected output; update the test case name if desired and keep references to
TextRenderer and baseSection so the rendered component is actually mounted
instead of just created.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5aa85e49-4fa2-491a-a79e-fb98657fdc65

📥 Commits

Reviewing files that changed from the base of the PR and between 794529b and b092243.

📒 Files selected for processing (5)
  • mobile/expo/src/components/sections/SectionDispatcher.tsx
  • mobile/expo/src/components/sections/TextRenderer.test.tsx
  • mobile/expo/src/components/sections/TextRenderer.tsx
  • mobile/expo/src/components/sections/TextStub.tsx
  • mobile/expo/src/components/sections/index.ts
💤 Files with no reviewable changes (1)
  • mobile/expo/src/components/sections/TextStub.tsx

@up-tandem up-tandem merged commit eb5d917 into main Mar 10, 2026
21 checks passed
@up-tandem up-tandem deleted the feat/308-text-renderer branch March 10, 2026 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(mobile-expo): TextRenderer section component

2 participants