Skip to content

Add Pretext virtualized text example#1178

Merged
tannerlinsley merged 1 commit into
mainfrom
taren/pretext-example-docs
May 27, 2026
Merged

Add Pretext virtualized text example#1178
tannerlinsley merged 1 commit into
mainfrom
taren/pretext-example-docs

Conversation

@tannerlinsley
Copy link
Copy Markdown
Member

@tannerlinsley tannerlinsley commented May 27, 2026

Summary

  • add a Pretext guide covering text-height estimation with TanStack Virtual
  • add a React Pretext chat-style virtualized example
  • wire docs/example routes and verification scripts

Testing

  • pnpm run test:docs
  • pnpm exec prettier --check docs/pretext.md examples/react/pretext/src/main.tsx examples/react/pretext/src/index.css examples/react/pretext/package.json package.json scripts/verify-links.ts scripts/verify-examples.ts
  • pnpm --filter @tanstack/react-virtual... build
  • pnpm --filter tanstack-react-virtual-example-pretext build
  • EXAMPLE_FILTER=examples/react/pretext SKIP_PACKAGE_BUILD=true pnpm run verify-examples

Summary by CodeRabbit

  • New Features

    • Introduced Pretext integration for precise text-based height measurement in virtualized lists
    • Added React example demonstrating virtualized text-heavy user interfaces with Pretext
  • Documentation

    • Comprehensive guide for integrating Pretext with TanStack Virtual
    • Updated documentation navigation with Text Measurement and Pretext example entries
  • Chores

    • Enhanced example build verification tooling
    • Improved documentation consistency validation

Review Change Stack

@tannerlinsley tannerlinsley requested a review from a team as a code owner May 27, 2026 17:38
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

This PR adds end-to-end Pretext integration to TanStack Virtual: comprehensive documentation explaining when and how to use Pretext for text-height estimation in virtualized UIs, a fully functional React example rendering a virtualized chat log with variable row heights, and verification infrastructure ensuring examples remain buildable and documentation routes remain consistent.

Changes

Pretext Integration

Layer / File(s) Summary
Pretext Documentation and Navigation
docs/pretext.md, docs/config.json
A comprehensive integration guide covering Pretext's role, do/don't criteria, installation, a complete React caching and measurement pattern, a robustness checklist, and navigation updates to surface the guide and new example.
React Pretext Example Application
examples/react/pretext/, examples/react/pretext/src/main.tsx, examples/react/pretext/src/index.css, examples/react/pretext/package.json, examples/react/pretext/tsconfig.json, examples/react/pretext/vite.config.js, examples/react/pretext/index.html, examples/react/pretext/README.md
A complete chat-log example demonstrating virtualized text-heavy UI with Pretext measuring row height, a useElementWidth hook managing viewport width changes, TanStack Virtual handling virtualization, and font-readiness logic triggering stable re-measurement.
Example Build Verification Script
scripts/verify-examples.ts, package.json
New verification script that discovers all example packages, ensures they have buildable configurations, and validates successful builds with optional filtering and Nx-coordinated workspace builds.
Enhanced Documentation Link and Route Verification
scripts/verify-links.ts
Rewritten verifier that validates markdown links within docs/, cross-checks docs/config.json example routes against the filesystem and discovered examples, and reports structured route/link errors.
TypeScript Configuration Standardization
examples/lit/dynamic/tsconfig.json, examples/lit/fixed/tsconfig.json
Lit example TypeScript configurations updated to explicitly declare Node.js ambient types, supporting the new example verification infrastructure.

Sequence Diagram

sequenceDiagram
  participant App
  participant useVirtualizer as TanStack Virtual
  participant Pretext
  participant ResizeObserver
  participant FontReady as document.fonts

  App->>App: Initialize messages (2000 synthetic items)
  App->>ResizeObserver: Attach to viewport container
  ResizeObserver->>App: Report initial width
  App->>useVirtualizer: Create virtualizer with estimateSize callback
  useVirtualizer->>Pretext: Call estimateSize for visible row
  Pretext->>Pretext: Lookup cached prepare result
  Pretext->>Pretext: Call layout() with current width
  Pretext-->>useVirtualizer: Return row height
  useVirtualizer-->>App: Provide height, start, key for rendering
  ResizeObserver->>App: Report width change
  App->>useVirtualizer: Call measure() to recompute layout
  FontReady->>App: Emit fonts loaded event
  App->>Pretext: Call clearCache()
  App->>useVirtualizer: Clear measurement cache
  App->>App: Bump fontVersion to trigger re-estimation
  App->>useVirtualizer: Virtualizer remeasures with font metrics
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A Pretext of virtualization, now complete,
Text heights measured true, no more guessing defeat,
React renders chat with scrolls that glide,
Font-ready and caching side by side,
Examples verified, docs aligned just right,
Pretext brings precision to TanStack's height!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description deviates significantly from the required template. It lacks the structured sections (🎯 Changes, ✅ Checklist, 🚀 Release Impact) and does not follow the expected format, though testing information is provided. Restructure the description to follow the template: add a 🎯 Changes section with motivation, complete the ✅ Checklist with required items, and clarify the 🚀 Release Impact (whether a changeset is needed or if this is docs/CI-only).
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 (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a Pretext example for virtualized text, which aligns with the primary objective of the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taren/pretext-example-docs

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

examples/react/pretext/vite.config.js

Parsing error: "parserOptions.project" has been provided for @typescript-eslint/parser.
The file was not found in any of the provided project(s): examples/react/pretext/vite.config.js


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

@github-actions
Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

No changeset entries found. Merging this PR will not cause a version bump for any packages.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 27, 2026

View your CI Pipeline Execution ↗ for commit df21b3e

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 18s View ↗
nx run-many --target=build --exclude=examples/** ✅ Succeeded 17s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-27 17:41:09 UTC

@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​chenglou/​pretext@​0.0.77910010092100

View full report

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 27, 2026

More templates

@tanstack/angular-virtual

npm i https://pkg.pr.new/@tanstack/angular-virtual@1178

@tanstack/lit-virtual

npm i https://pkg.pr.new/@tanstack/lit-virtual@1178

@tanstack/react-virtual

npm i https://pkg.pr.new/@tanstack/react-virtual@1178

@tanstack/solid-virtual

npm i https://pkg.pr.new/@tanstack/solid-virtual@1178

@tanstack/svelte-virtual

npm i https://pkg.pr.new/@tanstack/svelte-virtual@1178

@tanstack/virtual-core

npm i https://pkg.pr.new/@tanstack/virtual-core@1178

@tanstack/vue-virtual

npm i https://pkg.pr.new/@tanstack/vue-virtual@1178

commit: df21b3e

Copy link
Copy Markdown

@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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/react/pretext/tsconfig.json`:
- Around line 2-3: Move the "composite" setting into the "compilerOptions"
object so TypeScript recognizes it: locate the tsconfig JSON where "composite":
true is at root level and remove it from root and add "composite": true inside
the existing "compilerOptions" object (ensure the JSON remains valid and does
not duplicate keys), referencing the "composite" and "compilerOptions"
properties to find where to change.

In `@scripts/verify-examples.ts`:
- Around line 54-56: After applying the .filter((example) => !filter ||
example.directory.includes(filter)) step, add a guard that fails fast when a
non-empty EXAMPLE_FILTER (the local variable filter) matches zero examples:
compute the filtered array (e.g., filteredExamples or reuse the variable that
holds the pipeline result), then if filter is truthy and filtered array length
is 0 throw a clear Error (or process.exit with non-zero) so CI fails rather than
silently passing; place this check immediately after the filter/sort pipeline
that produces the list used by the rest of the script.

In `@scripts/verify-links.ts`:
- Line 244: The current tail-call verifyLinks().catch(console.error) only logs
errors but leaves the process exit code at 0; change the catch handler on the
verifyLinks invocation so it logs the error (e.g., via console.error or
processLogger) and sets a non-zero exit (either process.exitCode = 1 or
process.exit(1)) to ensure CI fails on errors; update the catch attached to
verifyLinks() accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 84dbf2d6-86bf-4e0c-9666-54877fb93ce2

📥 Commits

Reviewing files that changed from the base of the PR and between 693d915 and df21b3e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • docs/config.json
  • docs/pretext.md
  • examples/lit/dynamic/tsconfig.json
  • examples/lit/fixed/tsconfig.json
  • examples/react/pretext/README.md
  • examples/react/pretext/index.html
  • examples/react/pretext/package.json
  • examples/react/pretext/src/index.css
  • examples/react/pretext/src/main.tsx
  • examples/react/pretext/tsconfig.json
  • examples/react/pretext/vite.config.js
  • package.json
  • scripts/verify-examples.ts
  • scripts/verify-links.ts

Comment on lines +2 to +3
"composite": true,
"compilerOptions": {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In TypeScript tsconfig.json, is "composite" only valid under "compilerOptions" (and ignored if placed at the root)?

💡 Result:

Yes, the composite option is only valid under the compilerOptions object in a tsconfig.json file [1][2][3]. If you place composite at the root of your tsconfig.json file, it will be ignored by the TypeScript compiler [4][5]. The composite option is a compiler setting that enables project references and enforces specific constraints—such as requiring declaration to be true and ensuring all source files are explicitly included—to allow for faster, incremental builds [1][2][6]. Because it directly modifies how the compiler handles the compilation and emission of the project, it must reside within the compilerOptions block, which is the designated location for all TypeScript compiler settings [1][4]. Placing configuration options directly at the root level that belong inside compilerOptions is a common mistake; the TypeScript compiler simply does not look for them there, and they will have no effect on your project configuration [5].

Citations:


Move composite under compilerOptions (examples/react/pretext/tsconfig.json, lines 2-3).

composite is only recognized when placed inside the compilerOptions object; root-level composite is ignored by TypeScript, so project-reference behavior won’t be enabled.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/react/pretext/tsconfig.json` around lines 2 - 3, Move the
"composite" setting into the "compilerOptions" object so TypeScript recognizes
it: locate the tsconfig JSON where "composite": true is at root level and remove
it from root and add "composite": true inside the existing "compilerOptions"
object (ensure the JSON remains valid and does not duplicate keys), referencing
the "composite" and "compilerOptions" properties to find where to change.

Comment on lines +54 to +56
.filter((example) => !filter || example.directory.includes(filter))
.sort((a, b) => a.directory.localeCompare(b.directory))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when EXAMPLE_FILTER matches nothing.

If the filter is wrong, the script currently passes without validating any example. Add a guard so CI cannot go green on zero matched targets.

Proposed fix
 const examples = packageJsonPaths
   .map((packageJsonPath) => {
@@
   .filter((example) => !filter || example.directory.includes(filter))
   .sort((a, b) => a.directory.localeCompare(b.directory))
+
+if (filter && examples.length === 0) {
+  console.log(`\nNo examples matched EXAMPLE_FILTER="${filter}".`)
+  process.exit(1)
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/verify-examples.ts` around lines 54 - 56, After applying the
.filter((example) => !filter || example.directory.includes(filter)) step, add a
guard that fails fast when a non-empty EXAMPLE_FILTER (the local variable
filter) matches zero examples: compute the filtered array (e.g.,
filteredExamples or reuse the variable that holds the pipeline result), then if
filter is truthy and filtered array length is 0 throw a clear Error (or
process.exit with non-zero) so CI fails rather than silently passing; place this
check immediately after the filter/sort pipeline that produces the list used by
the rest of the script.

Comment thread scripts/verify-links.ts
}

verifyMarkdownLinks().catch(console.error)
verifyLinks().catch(console.error)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Ensure exceptions fail the process.

Line 244 logs thrown errors but can still exit with code 0. Set a non-zero exit code in the catch path so CI fails on script errors.

Proposed fix
-verifyLinks().catch(console.error)
+verifyLinks().catch((error) => {
+  console.error(error)
+  process.exit(1)
+})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
verifyLinks().catch(console.error)
verifyLinks().catch((error) => {
console.error(error)
process.exit(1)
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/verify-links.ts` at line 244, The current tail-call
verifyLinks().catch(console.error) only logs errors but leaves the process exit
code at 0; change the catch handler on the verifyLinks invocation so it logs the
error (e.g., via console.error or processLogger) and sets a non-zero exit
(either process.exitCode = 1 or process.exit(1)) to ensure CI fails on errors;
update the catch attached to verifyLinks() accordingly.

@tannerlinsley tannerlinsley merged commit 59b1f84 into main May 27, 2026
10 checks passed
@tannerlinsley tannerlinsley deleted the taren/pretext-example-docs branch May 27, 2026 21:48
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.

1 participant