#1

React Review Audit

Openreact-doctor[bot]opened 6mo ago

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

package.json:0


⚠️ 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 ref as a regular prop on function components — forwardRef is no longer needed in React 19+. Replace useContext(X) with use(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-N to size-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} or key={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 renderXxx props with compound subcomponents (e.g. <Modal.Header>) or children so 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, or keypress listener.

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: '...' } or export async function generateMetadata()

app/(pages)/(website)/page.jsx:1


Last scored May 14, 2026 at 7:35 AM UTC. Maintained by React Review.

Activity

0

No activity yet.