Score: 85/100 · 1 error · 77 warnings
Copy as prompt
Fix the following React Review diagnostics in my codebase.
## Errors (1)
1. [error] require-reduced-motion — package.json:0
Project uses a motion library but has no prefers-reduced-motion handling — required for accessibility (WCAG 2.3.3)
## Warnings (77)
2. [warning] no-react19-deprecated-apis — app/_components/ui/popover.jsx:14
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
3. [warning] no-react19-deprecated-apis — app/_components/ui/flipbook-viewer/flipbook/flipbook-loader.jsx:1
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
4. [warning] rerender-functional-setstate — app/_components/ui/flipbook-viewer/flipbook/flipbook-loader.jsx:27
setViewerStates({ ...viewerStates, ... }) — use functional update `setViewerStates(prev => ({ ...prev, ... }))` to avoid stale closures
5. [warning] no-array-index-as-key — app/_components/ui/flipbook-viewer/flipbook/flipbook-loader.jsx:54
Array index "index" used as key — causes bugs when list is reordered or filtered
6. [warning] design-no-redundant-size-axes — app/_components/ui/message.jsx:48
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
7. [warning] rerender-functional-setstate — app/_components/ui/flipbook-viewer/flipbook-viewer.jsx:52
setViewerStates({ ...viewerStates, ... }) — use functional update `setViewerStates(prev => ({ ...prev, ... }))` to avoid stale closures
8. [warning] no-render-prop-children — app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:17
3 render-prop slots on the same element (renderAnnotationLayer, renderForms, renderTextLayer…) — collapse into compound subcomponents or `children` so consumers don't need to know about every customization point
9. [warning] no-array-index-as-key — app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:14
Array index "index" used as key — causes bugs when list is reordered or filtered
10. [warning] no-render-prop-children — app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:27
3 render-prop slots on the same element (renderAnnotationLayer, renderForms, renderTextLayer…) — collapse into compound subcomponents or `children` so consumers don't need to know about every customization point
11. [warning] no-array-index-as-key — app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:24
Array index "index" used as key — causes bugs when list is reordered or filtered
12. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:25
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
13. [warning] design-no-redundant-size-axes — app/_components/ui/dropdown-menu.jsx:35
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
14. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:41
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
15. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:53
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
16. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:68
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
17. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:80
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
18. [warning] design-no-redundant-size-axes — app/_components/ui/dropdown-menu.jsx:89
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
19. [warning] design-no-redundant-size-axes — app/_components/ui/dropdown-menu.jsx:91
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
20. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:100
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
21. [warning] design-no-redundant-size-axes — app/_components/ui/dropdown-menu.jsx:108
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)
22. [warning] design-no-redundant-size-axes — app/_components/ui/dropdown-menu.jsx:110
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
23. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:118
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
24. [warning] no-react19-deprecated-apis — app/_components/ui/dropdown-menu.jsx:126
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
25. [warning] rendering-svg-precision — app/_components/ui/flipbook-viewer/pad-loading/pdf-loading.jsx:78
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
26. [warning] design-no-three-period-ellipsis — app/_components/ui/flipbook-viewer/pad-loading/pdf-loading.jsx:82
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
27. [warning] no-react19-deprecated-apis — app/_components/ui/dialog.jsx:17
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
28. [warning] no-react19-deprecated-apis — app/_components/ui/dialog.jsx:28
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
29. [warning] design-no-redundant-size-axes — app/_components/ui/dialog.jsx:41
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
30. [warning] no-react19-deprecated-apis — app/_components/ui/dialog.jsx:69
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
31. [warning] no-react19-deprecated-apis — app/_components/ui/dialog.jsx:77
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
32. [warning] no-react19-deprecated-apis — app/_components/ui/flipbook-viewer/flipbook/pdf-page.jsx:2
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
33. [warning] click-events-have-key-events — app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:125
Enforce a clickable non-interactive element has at least one keyboard event listener.
34. [warning] no-static-element-interactions — app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:125
Static HTML elements with event handlers require a role.
35. [warning] prefer-useReducer — app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:7
Component "Slider" has 5 useState calls — consider useReducer for related state
36. [warning] rerender-state-only-in-handlers — app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:8
useState "value" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
37. [warning] no-derived-state-effect — app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:94
Derived state in useEffect — compute during render instead
38. [warning] no-prop-callback-in-effect — app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:101
useEffect calls prop callback "onSlideChange" 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
39. [warning] no-react19-deprecated-apis — app/_components/ui/button.jsx:37
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
40. [warning] advanced-event-handler-refs — app/_components/ui/flipbook-viewer/flipbook/flipbook.jsx:40
useEffect re-subscribes a "handleFullscreenChange" 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
41. [warning] no-react19-deprecated-apis — app/_components/ui/toast.jsx:11
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
42. [warning] no-react19-deprecated-apis — app/_components/ui/toast.jsx:38
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
43. [warning] no-react19-deprecated-apis — app/_components/ui/toast.jsx:48
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
44. [warning] no-react19-deprecated-apis — app/_components/ui/toast.jsx:59
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
45. [warning] design-no-redundant-size-axes — app/_components/ui/toast.jsx:68
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
46. [warning] no-react19-deprecated-apis — app/_components/ui/toast.jsx:73
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
47. [warning] no-react19-deprecated-apis — app/_components/ui/toast.jsx:81
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
48. [warning] heading-has-content — app/_components/ui/alert.jsx:32
Headings must have content and the content must be accessible by a screen reader.
49. [warning] no-react19-deprecated-apis — app/_components/ui/alert.jsx:22
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
50. [warning] no-react19-deprecated-apis — app/_components/ui/alert.jsx:31
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
51. [warning] no-react19-deprecated-apis — app/_components/ui/alert.jsx:39
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
52. [warning] no-react19-deprecated-apis — app/_components/ui/tooltip.jsx:14
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
53. [warning] no-react19-deprecated-apis — app/_components/ui/alert-dialog.jsx:15
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
54. [warning] no-react19-deprecated-apis — app/_components/ui/alert-dialog.jsx:26
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
55. [warning] no-react19-deprecated-apis — app/_components/ui/alert-dialog.jsx:60
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
56. [warning] no-react19-deprecated-apis — app/_components/ui/alert-dialog.jsx:65
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
57. [warning] no-react19-deprecated-apis — app/_components/ui/alert-dialog.jsx:74
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
58. [warning] no-react19-deprecated-apis — app/_components/ui/alert-dialog.jsx:79
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
59. [warning] no-react19-deprecated-apis — app/_components/ui/toggle.jsx:31
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
60. [warning] no-unknown-property — app/_components/ui/share.jsx:46
Unknown property found
61. [warning] no-unknown-property — app/_components/ui/share.jsx:52
Unknown property found
62. [warning] no-unknown-property — app/_components/ui/share.jsx:64
Unknown property found
63. [warning] rendering-svg-precision — app/_components/ui/share.jsx:46
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
64. [warning] rendering-svg-precision — app/_components/ui/share.jsx:46
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
65. [warning] rendering-svg-precision — app/_components/ui/share.jsx:52
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
66. [warning] no-react19-deprecated-apis — app/_components/ui/toggle-group.jsx:13
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
67. [warning] no-react19-deprecated-apis — app/_components/ui/toggle-group.jsx:26
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
68. [warning] no-react19-deprecated-apis — app/_components/ui/toggle-group.jsx:27
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
69. [warning] rendering-svg-precision — app/_components/ui/share-expanded.jsx:32
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
70. [warning] rendering-svg-precision — app/_components/ui/share-expanded.jsx:32
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
71. [warning] rendering-svg-precision — app/_components/ui/share-expanded.jsx:37
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
72. [warning] no-react19-deprecated-apis — app/_components/ui/separator.jsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
73. [warning] nextjs-missing-metadata — app/(pages)/(website)/page.jsx:1
Page without metadata or generateMetadata export — hurts SEO
74. [warning] design-no-default-tailwind-palette — app/(pages)/(website)/page.jsx:23
text-gray-800 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
75. [warning] design-no-default-tailwind-palette — app/(pages)/(website)/page.jsx:23
border-gray-200 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
76. [warning] design-no-default-tailwind-palette — app/(pages)/(website)/page.jsx:23
bg-gray-50 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
77. [warning] design-no-default-tailwind-palette — app/(pages)/(website)/page.jsx:36
text-gray-600 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
78. [warning] design-no-default-tailwind-palette — app/(pages)/(website)/page.jsx:42
border-gray-100 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)❌ Errors (1)
require-reduced-motion
Project uses a motion library but has no prefers-reduced-motion handling — required for accessibility (WCAG 2.3.3)
Add
useReducedMotion()from your animation library, or a@media (prefers-reduced-motion: reduce)CSS query
⚠️ Warnings (77)
no-react19-deprecated-apis
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
Pass
refas a regular prop on function components —forwardRefis no longer needed in React 19+. ReplaceuseContext(X)withuse(X)for branch-aware context reads. Only enabled on projects detected as React 19+.
app/_components/ui/popover.jsx:14
app/_components/ui/flipbook-viewer/flipbook/flipbook-loader.jsx:1
app/_components/ui/dropdown-menu.jsx:25
app/_components/ui/dropdown-menu.jsx:41
app/_components/ui/dropdown-menu.jsx:53
app/_components/ui/dropdown-menu.jsx:68
app/_components/ui/dropdown-menu.jsx:80
app/_components/ui/dropdown-menu.jsx:100
app/_components/ui/dropdown-menu.jsx:118
app/_components/ui/dropdown-menu.jsx:126
app/_components/ui/dialog.jsx:17
app/_components/ui/dialog.jsx:28
app/_components/ui/dialog.jsx:69
app/_components/ui/dialog.jsx:77
app/_components/ui/flipbook-viewer/flipbook/pdf-page.jsx:2
app/_components/ui/button.jsx:37
app/_components/ui/toast.jsx:11
app/_components/ui/toast.jsx:38
app/_components/ui/toast.jsx:48
app/_components/ui/toast.jsx:59
app/_components/ui/toast.jsx:73
app/_components/ui/toast.jsx:81
app/_components/ui/alert.jsx:22
app/_components/ui/alert.jsx:31
app/_components/ui/alert.jsx:39
app/_components/ui/tooltip.jsx:14
app/_components/ui/alert-dialog.jsx:15
app/_components/ui/alert-dialog.jsx:26
app/_components/ui/alert-dialog.jsx:60
app/_components/ui/alert-dialog.jsx:65
app/_components/ui/alert-dialog.jsx:74
app/_components/ui/alert-dialog.jsx:79
app/_components/ui/toggle.jsx:31
app/_components/ui/toggle-group.jsx:13
app/_components/ui/toggle-group.jsx:26
app/_components/ui/toggle-group.jsx:27
app/_components/ui/separator.jsx:8
design-no-redundant-size-axes
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
Collapse
w-N h-Ntosize-N(Tailwind v3.4+) when both axes match
app/_components/ui/message.jsx:48
app/_components/ui/dropdown-menu.jsx:35
app/_components/ui/dropdown-menu.jsx:89
app/_components/ui/dropdown-menu.jsx:91
app/_components/ui/dropdown-menu.jsx:108
app/_components/ui/dropdown-menu.jsx:110
app/_components/ui/dialog.jsx:41
app/_components/ui/toast.jsx:68
rendering-svg-precision
SVG d attribute uses 4+ decimal precision — truncate to 1–2 decimals to shrink markup with no visible difference
Truncate path/points/transform decimals to 1–2 digits — sub-pixel precision adds bytes with no visible difference
app/_components/ui/flipbook-viewer/pad-loading/pdf-loading.jsx:78
app/_components/ui/share.jsx:46
app/_components/ui/share.jsx:46
app/_components/ui/share.jsx:52
app/_components/ui/share-expanded.jsx:32
app/_components/ui/share-expanded.jsx:32
app/_components/ui/share-expanded.jsx:37
design-no-default-tailwind-palette
text-gray-800 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)
Replace
indigo-*/gray-*/slate-*with project tokens, your brand color, or a less-default neutral (zinc,neutral,stone)
app/(pages)/(website)/page.jsx:23
app/(pages)/(website)/page.jsx:23
app/(pages)/(website)/page.jsx:23
app/(pages)/(website)/page.jsx:36
app/(pages)/(website)/page.jsx:42
no-array-index-as-key
Array index "index" used as key — causes bugs when list is reordered or filtered
Use a stable unique identifier:
key={item.id}orkey={item.slug}— index keys break on reorder/filter
app/_components/ui/flipbook-viewer/flipbook/flipbook-loader.jsx:54
app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:14
app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:24
no-unknown-property
Unknown property found
Use 'strokeLinejoin' instead
app/_components/ui/share.jsx:46
app/_components/ui/share.jsx:52
app/_components/ui/share.jsx:64
rerender-functional-setstate
setViewerStates({ ...viewerStates, ... }) — use functional update setViewerStates(prev => ({ ...prev, ... })) to avoid stale closures
Use the callback form:
setState(prev => prev + 1)to always read the latest value
app/_components/ui/flipbook-viewer/flipbook/flipbook-loader.jsx:27
app/_components/ui/flipbook-viewer/flipbook-viewer.jsx:52
no-render-prop-children
3 render-prop slots on the same element (renderAnnotationLayer, renderForms, renderTextLayer…) — collapse into compound subcomponents or children so consumers don't need to know about every customization point
Replace
renderXxxprops with compound subcomponents (e.g.<Modal.Header>) orchildrenso the parent doesn't dictate every customization point
app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:17
app/_components/ui/flipbook-viewer/toolbar/slider-nav/hover-item.jsx:27
design-no-three-period-ellipsis
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or …)
Use the typographic ellipsis "…" (or
…) instead of three periods — pairs with action-with-followup labels ("Rename…", "Loading…")
app/_components/ui/flipbook-viewer/pad-loading/pdf-loading.jsx:82
click-events-have-key-events
Enforce a clickable non-interactive element has at least one keyboard event listener.
Visible, non-interactive elements with click handlers must have one of
keyup,keydown, orkeypresslistener.
app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:125
no-static-element-interactions
Static HTML elements with event handlers require a role.
Add a role attribute to this element, or use a semantic HTML element instead.
app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:125
prefer-useReducer
Component "Slider" has 5 useState calls — consider useReducer for related state
Group related state:
const [state, dispatch] = useReducer(reducer, { field1, field2, ... })
app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:7
rerender-state-only-in-handlers
useState "value" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
Replace useState with useRef when the value is only mutated and never read in render —
ref.current = ...updates without re-rendering the component
app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:8
no-derived-state-effect
Derived state in useEffect — compute during render instead
For derived state, compute inline:
const x = fn(dep). For state resets on prop change, use a key prop:<Component key={prop} />. See https://react.dev/learn/you-might-not-need-an-effect
app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:94
no-prop-callback-in-effect
useEffect calls prop callback "onSlideChange" 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
Lift the shared state into a Provider so both sides read the same source — no useEffect-driven sync needed
app/_components/ui/flipbook-viewer/toolbar/slider-nav/slider.jsx:101
advanced-event-handler-refs
useEffect re-subscribes a "handleFullscreenChange" 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
Store the handler in a ref and have the listener read
handlerRef.current()— the subscription stays put while the latest handler is always called
app/_components/ui/flipbook-viewer/flipbook/flipbook.jsx:40
heading-has-content
Headings must have content and the content must be accessible by a screen reader.
Provide screen reader accessible content when using heading elements.
app/_components/ui/alert.jsx:32
nextjs-missing-metadata
Page without metadata or generateMetadata export — hurts SEO
Add
export const metadata = { title: '...', description: '...' }orexport async function generateMetadata()
app/(pages)/(website)/page.jsx:1
Last scored May 14, 2026 at 7:35 AM UTC. Maintained by React Review.
Activity
0No activity yet.