fix(react): resolve React Compiler errors and refactor evidence components#300
fix(react): resolve React Compiler errors and refactor evidence components#300bensonwong merged 16 commits intomainfrom
Conversation
- Convert seenInlineSignalRef from useRef to useState in CitationDrawer so the compiler can track mutations during render - Extract useExpandedPageSideOffset hook from CitationComponent to isolate the setState-in-useLayoutEffect bailout to a small hook - Remove stable ref from useCallback deps in DefaultPopoverContent (fixes "value modification after hook" compiler error) - Add catch clause to try-finally in FileUpload (satisfies HIR builder) - Convert wasLoadingRef + useEffect to setState-during-render in example app page.tsx - Replace array-index keys with stable keys in CitationAnnotationOverlay and PopoverSnippetZone - Add label/select a11y association in example app Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the "View page" action bar in AnchorTextFocusedImage with a compact PagePill in EvidenceTrayFooter. This keeps the keyhole viewer focused on the evidence crop and surfaces page navigation in the footer alongside the outcome label and timestamp. - Remove page/onViewPageClick props from AnchorTextFocusedImage - Add pageNumber, onPageClick, isImage props to EvidenceTrayFooter - Export getStatusColorScheme and PagePill from VerificationLog - Simplify "View Image" → "Image" label in PagePill and docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract ZoomToolbar into its own component with improved thumb styling, locate dirty-bit detection, and de-emphasized state when on-target - Redesign EvidenceTrayFooter: replace PagePill with "View page" CTA, move expandable search log from SearchAnalysisSummary into footer - Remove keyhole fit-state tracking and "already full size" flash hints - Fix not_found → "unknown" URL access mapping in VerificationLog and urlAccessExplanation (text-not-found ≠ HTTP 404) - Add ExpandIcon for keyhole hover overlay Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Flatten the row structure, replace gray miss icon with red X for clearer pass/fail contrast, and remove verbose location text for a more compact search log display. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…splay Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ge view Adds overlayHidden state to InlineExpandedImage and an onDismiss prop to CitationAnnotationOverlay so users can hide the CSS spotlight/brackets to view the underlying page unobstructed. The overlay auto-restores on source change and scroll-to-annotation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the dismiss X from inside the spotlight cutout to straddle its top-right corner, increase icon size (3.5→4.5), and use rounded-full for a circular shape. Also update test selector for SourceContextHeader PagePill change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The annotation overlay dismiss button already provides a close affordance. PagePill X-state remains as the header-level close control. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
I have reviewed PR #300. Here is my comprehensive feedback: ✅ StrengthsReact Compiler Optimization:
Component Extraction:
Bug Fix:
UX & Code Quality:
|
✅ Playwright Test ReportStatus: Tests passed 📊 Download Report & Snapshots (see Artifacts section) What's in the Visual SnapshotsThe gallery includes visual snapshots for:
Run ID: 22382521848 |
…, hoist constant - ZoomToolbar: replace inline <style> tag with singleton useEffect pattern (ref-counted mount/unmount prevents duplicate style tags across instances) - useExpandedPageSideOffset: remove triggerRef from useLayoutEffect deps (refs have stable identity, should not be in dependency arrays) - FileUpload: remove no-op catch-rethrow block - icons: remove unused ExpandIcon (dead code) - EvidenceTray: hoist DRIFT_THRESHOLD to module-scope DRIFT_THRESHOLD_PX Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pull Request Review: #300SummaryThis PR addresses React Compiler bailouts and refactors evidence components. Overall, the changes are well-structured and improve code quality. ✅ Strengths
|
…ck button assertions - annotationOverlay + expandedPagePopover: use .first() on getByLabel(/Expand to full page/) to handle triple always-render EvidenceZone duplicate aria-labels in hidden DOM - proofLinkInteractions: replace removed Back button assertions with [data-dc-inline-expanded] visibility checks (Back button removed in 8cf3bc7) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PR Review: React Compiler Fixes and Evidence Component RefactoringOverall AssessmentThis is a well-structured PR that addresses React Compiler compatibility issues while improving component organization. The changes demonstrate strong understanding of React optimization patterns and follow the project's CLAUDE.md guidelines closely. ✅ Strengths
|
…ywright tests
- "rapid expand/collapse": replace getByText("View search log") with
getByRole("button", { name: /Expand search log|Collapse search log/i })
to match actual aria-label (visible text is "{N} searches")
- "second tap expands details": replace getByText(/Search details/i) with
locator("#verification-log-timeline") to match actual rendered element
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review - PR #300SummaryThis is a well-executed refactoring that addresses React Compiler optimization issues while improving code organization and fixing several UX bugs. The changes demonstrate strong understanding of React internals and compiler constraints. ✅ Strengths1. React Compiler Optimization ⭐The PR successfully eliminates compiler bailouts by:
This is exactly the right approach and follows React best practices. 2. Excellent Code Organization
3. Security & Correctness
4. UX Improvements
🔍 Issues & Suggestions1. ZoomToolbar Style Injection - Potential Memory Leak 🔴 CRITICALLocation: Issue: The ref-counting for style injection has a race condition that can cause memory leaks in strict mode or Fast Refresh scenarios: function mountThumbStyle() {
thumbStyleRefCount++;
if (thumbStyleRefCount === 1) {
thumbStyleElement = document.createElement("style");
// ...
}
}Problem: If two Solution: Ensure atomic check-and-increment: function mountThumbStyle() {
if (thumbStyleRefCount === 0) {
thumbStyleElement = document.createElement("style");
thumbStyleElement.setAttribute("data-dc-zoom-thumb", "");
thumbStyleElement.textContent = THUMB_CSS;
document.head.appendChild(thumbStyleElement);
}
thumbStyleRefCount++;
}Severity: High - can cause visual glitches in production when multiple zoom toolbars exist 2. Missing Null Check in Locate Dirty Detection 🟡 MODERATELocation: const onScroll = () => {
const target = annotationScrollTarget.current;
if (!target) return;
const dx = Math.abs(el.scrollLeft - target.left);
const dy = Math.abs(el.scrollTop - target.top);Issue: The check Recommendation: Store the element in a variable inside the effect to ensure it's not null during the callback. 3. Performance: Scroll Listener Not Passive ⚪ MINORLocation: el.addEventListener("scroll", onScroll, { passive: true });Good: Already using This is correct and optimal for scroll performance. 4. Type Safety: Discriminator Union ⚪ MINORThe PR description mentions fixing discriminated unions, but I don't see changes to citation type discriminators in the diff. This might be referring to a previous fix or planned follow-up. Recommendation: Verify that all 5. Test Coverage 🟢 GOODTest updates properly reflect the UI changes:
Suggestion: Consider adding a specific test for the locate button dirty-bit behavior to prevent regressions. 📊 Code Quality Metrics
🎯 RecommendationsMust Fix Before Merge:
Should Fix:
Consider for Follow-up:
📋 Checklist Review
VerdictConditional Approval - This is high-quality work that meaningfully improves the codebase. The React Compiler optimizations are well-executed and the code organization improvements are excellent. However, the style injection race condition in Once the critical issue is fixed, this PR will be ready to merge. Great work on the comprehensive refactoring! 🎉 |
…and scroll cleanup - ZoomToolbar: fix ref-count race in mountThumbStyle() — check === 0 BEFORE incrementing so concurrent StrictMode mounts don't skip element creation (increment-then-check allowed both calls to see count > 0) - EvidenceTray: reset isAnimatingScroll ref on scroll listener cleanup to prevent stale animation state if effect re-runs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code Review - PR #300This is a comprehensive refactoring that successfully addresses React Compiler bailouts while improving component architecture. Overall, the changes are well-executed and follow the project's coding standards. Below is my detailed feedback: ✅ Strengths1. React Compiler OptimizationThe core goal of resolving compiler bailouts is successfully achieved through clean patterns:
2. Component Extraction & Reusability
3. Bug Fixes
4. Code Quality
🔍 Issues & Concerns1. Scroll Listener Cleanup - Missing State Reset
|
- EvidenceTray: reset annotationScrollTarget ref in scroll listener cleanup to prevent stale coordinates after unmount/remount - page.tsx: add optional chaining on lastMessage.parts to guard against undefined parts array during content extraction Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pull Request ReviewThis PR successfully addresses React Compiler bailouts while also improving UI/UX across multiple components. The changes demonstrate strong attention to detail and adherence to best practices. Overall, this is high-quality work with only minor suggestions below. ✅ Strengths1. React Compiler OptimizationThe primary goal is well-executed:
2. Component Extraction
3. Bug Fixes
4. UI Improvements
5. Documentation & Tests
🔍 SuggestionsMinor: Accessibility
Minor: Code Quality
Minor: Performance
🔒 Security✅ No new security concerns - follows existing patterns 📝 Final Verdict✅ Approved with minor suggestions Production-ready PR. React Compiler fixes are sound, component extraction improves maintainability, and UI improvements are thoughtful. Minor suggestions are optional refinements, not blockers. Great work! 🎉 |
… robustness
- CitationAnnotationOverlay: add tabIndex={0} to dismiss button for
explicit keyboard focusability in pointer-events:none parent context
- ZoomToolbar: use cn() helper for locate button className consistency;
clamp ref-count to 0 in unmountThumbStyle to prevent negative drift
under StrictMode double-invoke
- EvidenceTray: document DRIFT_THRESHOLD_PX rationale (sub-pixel jitter
absorption vs intentional-pan detection)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code ReviewThis is a well-executed PR that addresses React Compiler optimization issues while making meaningful UX improvements. The code is high quality with excellent attention to detail. Below are my findings: ✅ Strengths1. React Compiler OptimizationThe compiler bailout fixes are properly implemented:
2. Component Extraction
3. Bug Fix:
|
Summary
CitationComponent,CitationDrawer,EvidenceTray,DefaultPopoverContent, and the example app — replaces patterns the compiler can't optimize (refs-as-state, setState-in-render without guards, inline closures over mutable refs) with compiler-friendly alternatives (useEffectEvent, prev-value guards, state promotions)ZoomToolbarinto its own component anduseExpandedPageSideOffsetinto a dedicated hook, reducingEvidenceTray.tsxandCitationComponent.tsxcomplexitynot_found→unknownstatus mapping — text search misses were incorrectly displayed as "Page Not Found (HTTP 404)" in both the verification log and URL access explanationQueryGroupRowlayoutTest plan
bun run lintpasses (164 files, 0 issues)bun testpasses (1460 tests, 0 failures)bun run buildsucceeds (all DTS + CSS emitted)