Fix the following React Review diagnostics in my codebase.
## Warnings (94)
1. [warning] rerender-functional-setstate — src/components/ApiSettings.tsx:30
setLocalConfig({ ...localConfig, ... }) — use functional update `setLocalConfig(prev => ({ ...prev, ... }))` to avoid stale closures
2. [warning] rerender-functional-setstate — src/components/ApiSettings.tsx:38
setLocalConfig({ ...localConfig, ... }) — use functional update `setLocalConfig(prev => ({ ...prev, ... }))` to avoid stale closures
3. [warning] rerender-functional-setstate — src/components/ApiSettings.tsx:102
setLocalConfig({ ...localConfig, ... }) — use functional update `setLocalConfig(prev => ({ ...prev, ... }))` to avoid stale closures
4. [warning] rerender-functional-setstate — src/components/ApiSettings.tsx:117
setLocalConfig({ ...localConfig, ... }) — use functional update `setLocalConfig(prev => ({ ...prev, ... }))` to avoid stale closures
5. [warning] no-giant-component — src/App.tsx:33
Component "App" is 515 lines — consider breaking it into smaller focused components
6. [warning] prefer-useReducer — src/App.tsx:33
Component "App" has 19 useState calls — consider useReducer for related state
7. [warning] rerender-state-only-in-handlers — src/App.tsx:42
useState "outline" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
8. [warning] async-defer-await — src/App.tsx:138
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
9. [warning] async-defer-await — src/App.tsx:142
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
10. [warning] async-defer-await — src/App.tsx:220
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
11. [warning] no-cascading-set-state — src/App.tsx:244
3 setState calls in a single useEffect — consider using useReducer or deriving state
12. [warning] no-generic-handler-names — src/components/UploadZone.tsx:71
Non-descriptive handler name "handleClick" — name should describe what it does, not when it runs
13. [warning] no-inline-bounce-easing — src/components/UploadZone.tsx:82
animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration
14. [warning] async-defer-await — src/hooks/usePdfSearch.ts:143
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
15. [warning] async-defer-await — src/hooks/usePdfSearch.ts:157
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
16. [warning] async-defer-await — src/hooks/usePdfSearch.ts:165
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
17. [warning] async-defer-await — src/hooks/usePdfSearch.ts:177
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
18. [warning] async-await-in-loop — src/hooks/usePdfSearch.ts:143
await inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
19. [warning] async-await-in-loop — src/hooks/usePdfSearch.ts:165
await inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
20. [warning] no-react19-deprecated-apis — src/components/ui/scroll-area.tsx:5
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
21. [warning] no-giant-component — src/components/PdfToolbar.tsx:87
Component "PdfToolbarComponent" is 394 lines — consider breaking it into smaller focused components
22. [warning] no-many-boolean-props — src/components/PdfToolbar.tsx:87
Component "PdfToolbarComponent" takes 4 boolean-like props (isSearchOpen, isSearching, isSettingsOpen…) — consider compound components or explicit variants instead of stacking flags
23. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:133
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
24. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:137
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
25. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:143
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
26. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:147
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
27. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:158
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
28. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:163
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
29. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:189
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
30. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:194
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
31. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:205
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
32. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:209
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
33. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:217
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
34. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:221
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
35. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:226
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
36. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:231
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
37. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:233
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
38. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:305
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
39. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:310
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
40. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:316
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
41. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:321
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
42. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:328
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
43. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:355
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
44. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:371
w-7 h-7 → use the shorthand size-7 (Tailwind v3.4+)
45. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:376
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
46. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:381
w-7 h-7 → use the shorthand size-7 (Tailwind v3.4+)
47. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:386
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
48. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:441
w-7 h-7 → use the shorthand size-7 (Tailwind v3.4+)
49. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:445
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
50. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:453
w-7 h-7 → use the shorthand size-7 (Tailwind v3.4+)
51. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:457
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
52. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:463
w-9 h-9 → use the shorthand size-9 (Tailwind v3.4+)
53. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:468
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
54. [warning] design-no-redundant-size-axes — src/components/PdfToolbar.tsx:470
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
55. [warning] no-inline-bounce-easing — src/components/ChatPanel.tsx:42
animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration
56. [warning] no-inline-bounce-easing — src/components/ChatPanel.tsx:46
animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration
57. [warning] no-inline-bounce-easing — src/components/ChatPanel.tsx:50
animate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration
58. [warning] no-giant-component — src/components/ChatPanel.tsx:82
Component "ChatPanel" is 333 lines — consider breaking it into smaller focused components
59. [warning] design-no-redundant-size-axes — src/components/ChatPanel.tsx:180
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
60. [warning] design-no-redundant-size-axes — src/components/ChatPanel.tsx:191
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
61. [warning] design-no-redundant-size-axes — src/components/ChatPanel.tsx:201
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
62. [warning] design-no-redundant-size-axes — src/components/ChatPanel.tsx:211
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
63. [warning] js-batch-dom-css — src/components/ChatPanel.tsx:385
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
64. [warning] rendering-usetransition-loading — src/hooks/useChat.ts:55
useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead
65. [warning] async-await-in-loop — src/hooks/useChat.ts:151
await inside a while-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
66. [warning] rerender-state-only-in-handlers — src/components/TextSelectionPopup.tsx:34
useState "selectedText" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
67. [warning] advanced-event-handler-refs — src/components/TextSelectionPopup.tsx:132
useEffect re-subscribes a "handleMouseUp" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps
68. [warning] design-no-redundant-size-axes — src/components/TextSelectionPopup.tsx:184
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
69. [warning] design-no-redundant-size-axes — src/components/TextSelectionPopup.tsx:197
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
70. [warning] design-no-redundant-size-axes — src/components/PdfSidebar.tsx:159
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
71. [warning] design-no-redundant-size-axes — src/components/PdfSidebar.tsx:161
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
72. [warning] design-no-redundant-size-axes — src/components/PdfSidebar.tsx:181
w-3 h-3 → use the shorthand size-3 (Tailwind v3.4+)
73. [warning] design-no-redundant-size-axes — src/components/PdfSidebar.tsx:370
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
74. [warning] design-no-redundant-size-axes — src/components/PdfSidebar.tsx:374
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
75. [warning] design-no-redundant-size-axes — src/components/PdfSidebar.tsx:402
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
76. [warning] no-giant-component — src/components/PdfViewer.tsx:97
Component "PdfViewer" is 1002 lines — consider breaking it into smaller focused components
77. [warning] prefer-useReducer — src/components/PdfViewer.tsx:108
Component "PdfViewer" has 25 useState calls — consider useReducer for related state
78. [warning] rerender-state-only-in-handlers — src/components/PdfViewer.tsx:136
useState "outlinePageMap" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
79. [warning] rerender-state-only-in-handlers — src/components/PdfViewer.tsx:137
useState "thumbnailAnchor" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
80. [warning] rendering-usetransition-loading — src/components/PdfViewer.tsx:116
useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead
81. [warning] no-derived-useState — src/components/PdfViewer.tsx:150
useState initialized from prop "initialAutoFollow" — if this value should stay in sync with the prop, derive it during render instead
82. [warning] no-derived-useState — src/components/PdfViewer.tsx:151
useState initialized from prop "initialContextWindow" — if this value should stay in sync with the prop, derive it during render instead
83. [warning] no-prop-callback-in-effect — src/components/PdfViewer.tsx:576
useEffect calls prop callback "onCurrentPageChange" with local state in deps — this is the "lift state via callback" anti-pattern; lift state into a shared Provider so both sides read the same source
84. [warning] no-prop-callback-in-effect — src/components/PdfViewer.tsx:593
useEffect calls prop callback "onPageRangeChange" with local state in deps — this is the "lift state via callback" anti-pattern; lift state into a shared Provider so both sides read the same source
85. [warning] no-cascading-set-state — src/components/PdfViewer.tsx:641
3 setState calls in a single useEffect — consider using useReducer or deriving state
86. [warning] no-cascading-set-state — src/components/PdfViewer.tsx:664
25 setState calls in a single useEffect — consider using useReducer or deriving state
87. [warning] no-cascading-set-state — src/components/PdfViewer.tsx:711
8 setState calls in a single useEffect — consider using useReducer or deriving state
88. [warning] async-defer-await — src/components/PdfViewer.tsx:721
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
89. [warning] async-defer-await — src/components/PdfViewer.tsx:735
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
90. [warning] async-defer-await — src/components/PdfViewer.tsx:776
await blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast
91. [warning] design-no-redundant-size-axes — src/components/PdfViewer.tsx:1022
w-10 h-10 → use the shorthand size-10 (Tailwind v3.4+)
92. [warning] design-no-redundant-size-axes — src/components/PdfViewer.tsx:1049
w-10 h-10 → use the shorthand size-10 (Tailwind v3.4+)
93. [warning] design-no-redundant-size-axes — src/components/PdfViewer.tsx:1068
w-12 h-12 → use the shorthand size-12 (Tailwind v3.4+)
94. [warning] design-no-redundant-size-axes — src/components/PdfViewer.tsx:1079
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
Copy as prompt
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+) · 48 in 5 files
design-no-redundant-size-axessrc/components/PdfToolbar.tsxsrc/components/PdfSidebar.tsxsrc/components/ChatPanel.tsxsrc/components/PdfViewer.tsxsrc/components/TextSelectionPopup.tsxawait blocks the function before an early-return that doesn't use the awaited value — move the await after the synchronous guard so the skip path stays fast · 10 in 3 files
async-defer-awaitsrc/hooks/usePdfSearch.tssrc/App.tsxsrc/components/PdfViewer.tsxsetLocalConfig({ ...localConfig, ... }) — use functional update `setLocalConfig(prev => ({ ...prev, ... }))` to avoid stale closures · 4 in 1 file
rerender-functional-setstatesrc/components/ApiSettings.tsxComponent "App" is 515 lines — consider breaking it into smaller focused components · 4 in 4 files
no-giant-componentsrc/App.tsxsrc/components/PdfToolbar.tsxsrc/components/ChatPanel.tsxsrc/components/PdfViewer.tsxuseState "outline" is updated but never read in the component's return — use useRef so updates don't trigger re-renders · 4 in 3 files
rerender-state-only-in-handlerssrc/components/PdfViewer.tsxsrc/App.tsxsrc/components/TextSelectionPopup.tsx3 setState calls in a single useEffect — consider using useReducer or deriving state · 4 in 2 files
no-cascading-set-statesrc/components/PdfViewer.tsxsrc/App.tsxanimate-bounce feels dated and tacky — use a subtle ease-out transform for natural deceleration · 4 in 2 files
no-inline-bounce-easingsrc/components/ChatPanel.tsxsrc/components/UploadZone.tsxawait inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently · 3 in 2 files
async-await-in-loopsrc/hooks/usePdfSearch.tssrc/hooks/useChat.tsComponent "App" has 19 useState calls — consider useReducer for related state · 2 in 2 files
prefer-useReducersrc/App.tsxsrc/components/PdfViewer.tsxuseState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead · 2 in 2 files
rendering-usetransition-loadingsrc/hooks/useChat.tssrc/components/PdfViewer.tsxuseState initialized from prop "initialAutoFollow" — if this value should stay in sync with the prop, derive it during render instead · 2 in 1 file
no-derived-useStatesrc/components/PdfViewer.tsxuseEffect calls prop callback "onCurrentPageChange" with local state in deps — this is the "lift state via callback" anti-pattern; lift state into a shared Provider so both sides read the same source · 2 in 1 file
no-prop-callback-in-effectsrc/components/PdfViewer.tsxNon-descriptive handler name "handleClick" — name should describe what it does, not when it runs · 1 in 1 file
no-generic-handler-namessrc/components/UploadZone.tsxforwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly · 1 in 1 file
no-react19-deprecated-apissrc/components/ui/scroll-area.tsxComponent "PdfToolbarComponent" takes 4 boolean-like props (isSearchOpen, isSearching, isSettingsOpen…) — consider compound components or explicit variants instead of stacking flags · 1 in 1 file
no-many-boolean-propssrc/components/PdfToolbar.tsxMultiple sequential element.style assignments — batch with cssText or classList for fewer reflows · 1 in 1 file
js-batch-dom-csssrc/components/ChatPanel.tsxuseEffect re-subscribes a "handleMouseUp" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps · 1 in 1 file
advanced-event-handler-refssrc/components/TextSelectionPopup.tsxReviewed by reactreview for commit 714e0c3. Configure here.