Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .jules/palette.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 2024-05-18 - Wrap Inputs in Forms for Native Submit
**Learning:** Wrapping `<input>` and a corresponding `<button>` in a `<form onSubmit={...}>` provides highly reliable, accessible native Enter-to-submit behavior and eliminates the need for manual, brittle `onKeyDown` listeners (which often fail to account for assistive tech or autofill).
**Action:** When creating or modifying inputs designed to execute a single action, always prefer a native `<form>` element over a standalone input with an `onKeyDown` Enter listener. Remember to set the button to `type="submit"` and use `e.preventDefault()` in the `onSubmit` handler to prevent page reloads.
14 changes: 9 additions & 5 deletions src/features/library/components/CoverPickerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -516,14 +516,19 @@ export function CoverPickerModal({
{/* URL Input */}
{showUrlInput ? (
<div className="border-b border-slate-100 px-6 py-3 dark:border-slate-800">
<div className="flex items-center gap-2">
<form
onSubmit={(e) => {
e.preventDefault()
void handleCustomUrl()
}}
className="flex items-center gap-2"
>
<input
aria-label="Cover image URL"
type="url"
value={customUrl}
onChange={(e) => handleCustomUrlChange(e.target.value)}
onPaste={handleCustomUrlPaste}
onKeyDown={(e) => { if (e.key === 'Enter') void handleCustomUrl() }}
placeholder="https://example.com/cover.jpg"
aria-invalid={customUrlError ? true : undefined}
aria-describedby={customUrlError || isCheckingCustomUrl ? 'cover-url-status' : undefined}
Expand All @@ -540,15 +545,14 @@ export function CoverPickerModal({
title={!customUrl.trim() ? 'Enter a valid image URL' : isCheckingCustomUrl ? 'Checking image link...' : undefined}
>
<button
type="button"
onClick={() => { void handleCustomUrl() }}
type="submit"
disabled={!customUrl.trim() || isCheckingCustomUrl}
className="rounded-lg bg-accent-600 px-3 py-1.5 text-xs font-medium text-white transition hover:bg-accent-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:ring-offset-slate-900"
>
{isCheckingCustomUrl ? 'Checking' : 'Add'}
</button>
</span>
</div>
</form>
{customUrlError ? (
<p id="cover-url-status" role="alert" className="mt-2 text-sm text-rose-600 dark:text-rose-400">
{customUrlError}
Expand Down