mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 07:53:09 +00:00
feat(dialogs): the focus starts inside a dialog and Tab stays there
Every dialog, the shared frame and the older modal alike, moves the focus in when it opens: on a desktop into the first text field, on a phone onto the panel so no keyboard pops up. Tab wraps around inside instead of running through the page behind, and closing hands the focus back to what opened it. Fields that open a list on focus are skipped, and the older modal's close button got a label and a tooltip. (#1302)
This commit is contained in:
@@ -89,6 +89,8 @@ export default function AddressInput({ value, onChange, placeholder, className }
|
||||
value={value}
|
||||
placeholder={placeholder}
|
||||
onChange={e => { onChange(e.target.value); setOpen(true); search(e.target.value) }}
|
||||
// Opens its list on focus, so a dialog must not focus it by itself (#1302).
|
||||
data-no-autofocus
|
||||
onFocus={() => setOpen(true)}
|
||||
onKeyDown={onKey}
|
||||
className={className}
|
||||
|
||||
@@ -113,6 +113,8 @@ export default function AirportSelect({ value, onChange, placeholder, style }: P
|
||||
value={query}
|
||||
placeholder={placeholder ?? t('airport.searchPlaceholder')}
|
||||
onChange={(e) => { setQuery(e.target.value); setOpen(true); if (value) onChange(null) }}
|
||||
// Opens its list on focus, so a dialog must not focus it by itself (#1302).
|
||||
data-no-autofocus
|
||||
onFocus={() => setOpen(true)}
|
||||
onKeyDown={onKey}
|
||||
className="bg-transparent text-content"
|
||||
|
||||
@@ -115,6 +115,8 @@ export default function LocationSelect({ value, onChange, placeholder, style, pl
|
||||
value={query}
|
||||
placeholder={placeholder ?? t('reservations.searchLocation')}
|
||||
onChange={(e) => { setQuery(e.target.value); setOpen(true); setHighlight(-1); if (value) onChange(null) }}
|
||||
// Opens its list on focus, so a dialog must not focus it by itself (#1302).
|
||||
data-no-autofocus
|
||||
onFocus={() => setOpen(true)}
|
||||
onKeyDown={onKey}
|
||||
className="bg-transparent text-content"
|
||||
|
||||
@@ -939,7 +939,9 @@ export default function PlaceFormModal(props: PlaceFormModalProps) {
|
||||
labelId={titleId}
|
||||
onClose={onClose}
|
||||
eyebrow={title}
|
||||
// Never focused on opening: a new place starts at the search, an edit at the dialog.
|
||||
// Not autoFocused itself: a new place starts at the search, and otherwise the
|
||||
// dialog's own first-field focus lands here on a desktop (#1302), so a place
|
||||
// brought in from the map or opened to edit is ready for its name.
|
||||
titleInput={{
|
||||
value: form.name,
|
||||
onChange: value => handleChange('name', value),
|
||||
|
||||
@@ -256,6 +256,8 @@ function StopPicker({ label, value, onPick, quickPicks, near, placeholder }: {
|
||||
<input
|
||||
value={display}
|
||||
onChange={e => search(e.target.value)}
|
||||
// Opens its list on focus, so a dialog must not focus it by itself (#1302).
|
||||
data-no-autofocus
|
||||
onFocus={() => setOpen(true)}
|
||||
placeholder={placeholder}
|
||||
className="text-content"
|
||||
|
||||
Reference in New Issue
Block a user