Rules Hub
Coding Rules Library
Avoid manual DOM focus hacks
Avoid imperative DOM calls like .blur() or .stopPropagation() to control focus; use semantic HTML or accessible libraries instead.
Bad example
| 1 | const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => { |
| 2 | // BAD: Manually forcing blur to prevent keyboard or hack focus behavior |
| 3 | event.stopPropagation(); |
| 4 | event.target.blur(); |
| 5 | openModal(); |
| 6 | }; |
| 7 |
|
| 8 | return ( |
| 9 | <input |
| 10 | type="text" |
| 11 | placeholder="Search..." |
| 12 | onFocus={handleFocus} |
| 13 | /> |
| 14 | ); |
Explanation (EN)
Manually calling `blur()` to prevent the mobile keyboard or manipulate focus flow is a brittle hack. It confuses screen readers, breaks standard keyboard navigation, and fights against the browser's native behavior.
Objašnjenje (HR)
Ručno pozivanje `blur()` kako bi se spriječilo otvaranje tipkovnice ili manipuliralo fokusom je loša praksa. To zbunjuje čitače zaslona, kvari standardnu navigaciju tipkovnicom i bori se protiv nativnog ponašanja preglednika.
Good example
| 1 | import * as Dialog from '@radix-ui/react-dialog'; |
| 2 |
|
| 3 | // GOOD: Use a button for actions or a specialized accessible library |
| 4 | const SearchTrigger = () => { |
| 5 | const [open, setOpen] = useState(false); |
| 6 |
|
| 7 | return ( |
| 8 | <Dialog.Root open={open} onOpenChange={setOpen}> |
| 9 | <Dialog.Trigger asChild> |
| 10 | {/* Semantic button styled as input if needed */} |
| 11 | <button className="fake-input-style"> |
| 12 | Search... |
| 13 | </button> |
| 14 | </Dialog.Trigger> |
| 15 | <Dialog.Content> |
| 16 | {/* Library handles focus trap and restoration automatically */} |
| 17 | <SearchModalContent /> |
| 18 | </Dialog.Content> |
| 19 | </Dialog.Root> |
| 20 | ); |
| 21 | }; |
Explanation (EN)
Instead of hacking an input, use a semantic `<button>` if the element triggers an action (like opening a modal). For complex focus scenarios, rely on accessible UI libraries (like Radix UI or Headless UI) that manage focus trapping and restoration correctly.
Objašnjenje (HR)
Umjesto hakiranja input elementa, koristi semantički `<button>` ako element pokreće akciju (poput otvaranja modala). Za složene scenarije fokusa, osloni se na pristupačne UI biblioteke (poput Radix UI ili Headless UI) koje ispravno upravljaju hvatanjem i vraćanjem fokusa.
Notes (EN)
Using 'readonly' on an input is sometimes acceptable, but if the element solely functions as a button to open something else, a `<button>` tag is semantically superior.
Bilješke (HR)
Korištenje 'readonly' na inputu je ponekad prihvatljivo, ali ako element služi isključivo kao gumb za otvaranje nečeg drugog, `<button>` tag je semantički ispravniji.