celeroncoder / celeroncoder/calendar-clone

React Review Audit

Open
#4 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1
Forks
0
PR merge metrics
No merged PRs in 30d

Description

**Score: 90/100** · 0 errors · 53 warnings

Copy as prompt

```text
Fix the following React Review diagnostics in my codebase.

## Warnings (53)

1. [warning] no-react19-deprecated-apis — src/components/ui/input.tsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

2. [warning] rendering-hydration-mismatch-time — src/components/Calendar/TimeBlocks/WeekListRow.tsx:13
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

3. [warning] no-array-index-as-key — src/components/Calendar/TimeBlocks/WeekListRow.tsx:10
Array index "idx" used as key — causes bugs when list is reordered or filtered

4. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeBlocks/WeekListRow.tsx:11
border-slate-300 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

5. [warning] rendering-hydration-mismatch-time — src/components/Calendar/TimeBlocks/WeekListRow.tsx:13
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

6. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeBlocks/WeekListRow.tsx:23
text-slate-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

7. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeBlocks/WeekListRow.tsx:24
text-slate-500 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

8. [warning] design-no-redundant-size-axes — src/components/ui/calendar.tsx:55
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

9. [warning] design-no-redundant-size-axes — src/components/ui/calendar.tsx:56
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

10. [warning] design-no-three-period-ellipsis — src/components/Calendar/TimeBlocks/TimeBlockRow.tsx:15
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)

11. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeColumn.tsx:3
border-slate-300 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

12. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeColumn.tsx:4
border-slate-300 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

13. [warning] no-array-index-as-key — src/components/Calendar/TimeColumn.tsx:9
Array index "idx" used as key — causes bugs when list is reordered or filtered

14. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeColumn.tsx:10
border-slate-300 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

15. [warning] no-react19-deprecated-apis — src/components/ui/button.tsx:38
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

16. [warning] prefer-useReducer — src/components/Calendar/TimeBlocks/NewAppointment.tsx:34
Component "NewAppointment" has 7 useState calls — consider useReducer for related state

17. [warning] rerender-lazy-state-init — src/components/Calendar/TimeBlocks/NewAppointment.tsx:43
useState(generateTimeSlots()) calls initializer on every render — use useState(() => generateTimeSlots()) for lazy initialization

18. [warning] design-no-vague-button-label — src/components/Calendar/TimeBlocks/NewAppointment.tsx:178
Vague button label "Submit" — name the action ("Save changes", "Send invite", "Delete account") so screen readers and hesitant users know what happens

19. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeBlocks/index.tsx:9
border-slate-300 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

20. [warning] design-no-redundant-size-axes — src/components/ui/DatePicker.tsx:37
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

21. [warning] design-no-space-on-flex-children — src/components/ui/DatePicker.tsx:41
space-y-2 on a flex/grid parent — use gap-y-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL

22. [warning] rendering-hydration-mismatch-time — src/components/ui/DatePicker.tsx:44
new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

23. [warning] click-events-have-key-events — src/components/Calendar/TimeBlocks/Block.tsx:46
Enforce a clickable non-interactive element has at least one keyboard event listener.

24. [warning] no-static-element-interactions — src/components/Calendar/TimeBlocks/Block.tsx:46
Static HTML elements with event handlers require a role.

25. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeBlocks/Block.tsx:30
border-slate-300 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

26. [warning] design-no-redundant-size-axes — src/components/Calendar/TimeBlocks/Block.tsx:38
w-[10px] h-[10px] → use the shorthand size-[10px] (Tailwind v3.4+)

27. [warning] design-no-default-tailwind-palette — src/components/Calendar/TimeBlocks/Block.tsx:50
text-slate-700 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

28. [warning] no-react19-deprecated-apis — src/components/ui/toast.tsx:10
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

29. [warning] no-react19-deprecated-apis — src/components/ui/toast.tsx:41
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

30. [warning] no-react19-deprecated-apis — src/components/ui/toast.tsx:56
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 — src/components/ui/toast.tsx:71
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

32. [warning] design-no-redundant-size-axes — src/components/ui/toast.tsx:84
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

33. [warning] no-react19-deprecated-apis — src/components/ui/toast.tsx:89
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

34. [warning] no-react19-deprecated-apis — src/components/ui/toast.tsx:101
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

35. [warning] prefer-useReducer — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:22
Component "AppointmentDetails" has 6 useState calls — consider useReducer for related state

36. [warning] no-derived-useState — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:23
useState initialized from prop "event" — if this value should stay in sync with the prop, derive it during render instead

37. [warning] rerender-lazy-state-init — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:25
useState(generateTimeSlots()) calls initializer on every render — use useState(() => generateTimeSlots()) for lazy initialization

38. [warning] no-derived-useState — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:29
useState initialized from prop "event" — if this value should stay in sync with the prop, derive it during render instead

39. [warning] no-derived-useState — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:30
useState initialized from prop "event" — if this value should stay in sync with the prop, derive it during render instead

40. [warning] no-derived-useState — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:32
useState initialized from prop "event" — if this value should stay in sync with the prop, derive it during render instead

41. [warning] design-no-space-on-flex-children — src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:62
space-y-2 on a flex/grid parent — use gap-y-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL

42. [warning] no-react19-deprecated-apis — src/components/ui/select.tsx:15
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

43. [warning] design-no-redundant-size-axes — src/components/ui/select.tsx:29
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

44. [warning] no-react19-deprecated-apis — src/components/ui/select.tsx:35
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

45. [warning] no-react19-deprecated-apis — src/components/ui/select.tsx:64
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

46. [warning] no-react19-deprecated-apis — src/components/ui/select.tsx:76
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

47. [warning] design-no-redundant-size-axes — src/components/ui/select.tsx:88
w-3.5 h-3.5 → use the shorthand size-3.5 (Tailwind v3.4+)

48. [warning] design-no-redundant-size-axes — src/components/ui/select.tsx:90
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)

49. [warning] no-react19-deprecated-apis — src/components/ui/select.tsx:99
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly

50. [warning] design-no-default-tailwind-palette — src/pages/index.tsx:6
bg-slate-50 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

51. [warning] design-no-default-tailwind-palette — src/pages/index.tsx:7
text-slate-600 reads as the Tailwind template default — use zinc (true neutral), neutral (warmer), or stone (warmest)

52. [warning] no-react19-deprecated-apis — src/components/ui/popover.tsx:12
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 — src/components/ui/label.tsx:13
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
```

---

### ⚠️ Warnings (53)

**`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+.

[`src/components/ui/input.tsx:8`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/input.tsx#L8)
[`src/components/ui/button.tsx:38`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/button.tsx#L38)
[`src/components/ui/toast.tsx:10`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L10)
[`src/components/ui/toast.tsx:41`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L41)
[`src/components/ui/toast.tsx:56`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L56)
[`src/components/ui/toast.tsx:71`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L71)
[`src/components/ui/toast.tsx:89`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L89)
[`src/components/ui/toast.tsx:101`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L101)
[`src/components/ui/select.tsx:15`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L15)
[`src/components/ui/select.tsx:35`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L35)
[`src/components/ui/select.tsx:64`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L64)
[`src/components/ui/select.tsx:76`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L76)
[`src/components/ui/select.tsx:99`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L99)
[`src/components/ui/popover.tsx:12`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/popover.tsx#L12)
[`src/components/ui/label.tsx:13`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/label.tsx#L13)

**`design-no-default-tailwind-palette`**

border-slate-300 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`)

[`src/components/Calendar/TimeBlocks/WeekListRow.tsx:11`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/WeekListRow.tsx#L11)
[`src/components/Calendar/TimeBlocks/WeekListRow.tsx:23`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/WeekListRow.tsx#L23)
[`src/components/Calendar/TimeBlocks/WeekListRow.tsx:24`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/WeekListRow.tsx#L24)
[`src/components/Calendar/TimeColumn.tsx:3`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeColumn.tsx#L3)
[`src/components/Calendar/TimeColumn.tsx:4`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeColumn.tsx#L4)
[`src/components/Calendar/TimeColumn.tsx:10`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeColumn.tsx#L10)
[`src/components/Calendar/TimeBlocks/index.tsx:9`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/index.tsx#L9)
[`src/components/Calendar/TimeBlocks/Block.tsx:30`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/Block.tsx#L30)
[`src/components/Calendar/TimeBlocks/Block.tsx:50`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/Block.tsx#L50)
[`src/pages/index.tsx:6`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/pages/index.tsx#L6)
[`src/pages/index.tsx:7`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/pages/index.tsx#L7)

**`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

[`src/components/ui/calendar.tsx:55`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/calendar.tsx#L55)
[`src/components/ui/calendar.tsx:56`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/calendar.tsx#L56)
[`src/components/ui/DatePicker.tsx:37`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/DatePicker.tsx#L37)
[`src/components/Calendar/TimeBlocks/Block.tsx:38`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/Block.tsx#L38)
[`src/components/ui/toast.tsx:84`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/toast.tsx#L84)
[`src/components/ui/select.tsx:29`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L29)
[`src/components/ui/select.tsx:88`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L88)
[`src/components/ui/select.tsx:90`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/select.tsx#L90)

**`no-derived-useState`**

useState initialized from prop "event" — if this value should stay in sync with the prop, derive it during render instead

> Remove useState and compute the value inline: `const value = transform(propName)`

[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:23`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L23)
[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:29`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L29)
[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:30`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L30)
[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:32`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L32)

**`rendering-hydration-mismatch-time`**

new Date() reachable from JSX renders differently on server vs client — wrap in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

> Wrap dynamic time/random values in useEffect+useState (client-only) or add suppressHydrationWarning to the parent if intentional

[`src/components/Calendar/TimeBlocks/WeekListRow.tsx:13`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/WeekListRow.tsx#L13)
[`src/components/Calendar/TimeBlocks/WeekListRow.tsx:13`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/WeekListRow.tsx#L13)
[`src/components/ui/DatePicker.tsx:44`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/DatePicker.tsx#L44)

**`no-array-index-as-key`**

Array index "idx" 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

[`src/components/Calendar/TimeBlocks/WeekListRow.tsx:10`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/WeekListRow.tsx#L10)
[`src/components/Calendar/TimeColumn.tsx:9`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeColumn.tsx#L9)

**`prefer-useReducer`**

Component "NewAppointment" has 7 useState calls — consider useReducer for related state

> Group related state: `const [state, dispatch] = useReducer(reducer, { field1, field2, ... })`

[`src/components/Calendar/TimeBlocks/NewAppointment.tsx:34`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/NewAppointment.tsx#L34)
[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:22`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L22)

**`rerender-lazy-state-init`**

useState(generateTimeSlots()) calls initializer on every render — use useState(() => generateTimeSlots()) for lazy initialization

> Wrap in an arrow function so it only runs once: `useState(() => expensiveComputation())`

[`src/components/Calendar/TimeBlocks/NewAppointment.tsx:43`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/NewAppointment.tsx#L43)
[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:25`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L25)

**`design-no-space-on-flex-children`**

space-y-2 on a flex/grid parent — use gap-y-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL

> Use `gap-*` on the flex/grid parent. `space-x-*` / `space-y-*` produce phantom gaps when a sibling is conditionally rendered, lose vertical spacing on wrapped lines, and don't mirror in RTL

[`src/components/ui/DatePicker.tsx:41`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/ui/DatePicker.tsx#L41)
[`src/components/Calendar/TimeBlocks/AppointmentDetails.tsx:62`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/AppointmentDetails.tsx#L62)

**`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…")

[`src/components/Calendar/TimeBlocks/TimeBlockRow.tsx:15`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/TimeBlockRow.tsx#L15)

**`design-no-vague-button-label`**

Vague button label "Submit" — name the action ("Save changes", "Send invite", "Delete account") so screen readers and hesitant users know what happens

> Name the action: "Save changes" instead of "Continue", "Send invite" instead of "Submit", "Delete account" instead of "OK". The label IS the button's accessible name

[`src/components/Calendar/TimeBlocks/NewAppointment.tsx:178`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/NewAppointment.tsx#L178)

**`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.

[`src/components/Calendar/TimeBlocks/Block.tsx:46`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/Block.tsx#L46)

**`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.

[`src/components/Calendar/TimeBlocks/Block.tsx:46`](https://github.com/celeroncoder/calendar-clone/blob/d1916221199ddd8a0e163140591a474693cd1402/src/components/Calendar/TimeBlocks/Block.tsx#L46)

---

Last scored May 14, 2026 at 9:39 AM UTC. Maintained by [React Review](https://github.com/millionco/react-review).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.