diff --git a/src/components/map/user-home-dialog.tsx b/src/components/map/user-home-dialog.tsx index 30fdcea..776a816 100644 --- a/src/components/map/user-home-dialog.tsx +++ b/src/components/map/user-home-dialog.tsx @@ -39,8 +39,6 @@ export function UserHomeDialog({ const [error, setError] = React.useState(null); const [wasOpen, setWasOpen] = React.useState(false); - // Re-fill the form during render (not an effect) each time the dialog - // opens, so there's no stale-data flash. if (open !== wasOpen) { setWasOpen(open); if (open) { @@ -73,7 +71,16 @@ export function UserHomeDialog({ const latNum = Number(lat); const lngNum = Number(lng); - const isValid = label.trim() && lat !== "" && lng !== "" && !Number.isNaN(latNum) && !Number.isNaN(lngNum); + const latError = lat !== "" && (Number.isNaN(latNum) || latNum < -90 || latNum > 90); + const lngError = lng !== "" && (Number.isNaN(lngNum) || lngNum < -180 || lngNum > 180); + const isValid = + label.trim() && + lat !== "" && + lng !== "" && + !Number.isNaN(latNum) && + !Number.isNaN(lngNum) && + !latError && + !lngError; async function handleSave() { if (!isValid) return; @@ -115,9 +122,6 @@ export function UserHomeDialog({ return ( e.preventDefault()} onInteractOutside={(e) => e.preventDefault()} > @@ -146,7 +150,11 @@ export function UserHomeDialog({ step="any" value={lat} onChange={(e) => setLat(e.target.value)} + aria-invalid={latError} /> + {latError && ( +

Latitude must be between -90 and 90.

+ )}
@@ -156,7 +164,11 @@ export function UserHomeDialog({ step="any" value={lng} onChange={(e) => setLng(e.target.value)} + aria-invalid={lngError} /> + {lngError && ( +

Longitude must be between -180 and 180.

+ )}
diff --git a/src/components/map/user-place-dialog.tsx b/src/components/map/user-place-dialog.tsx index 6c6abb9..1cc021f 100644 --- a/src/components/map/user-place-dialog.tsx +++ b/src/components/map/user-place-dialog.tsx @@ -60,8 +60,6 @@ export function UserPlaceDialog({ const [error, setError] = React.useState(null); const [lastResetKey, setLastResetKey] = React.useState(null); - // Re-fill the form during render (not an effect) each time the dialog - // opens, or opens for a different place, so there's no stale-data flash. const resetKey = open ? place?.id ?? "new" : null; if (resetKey !== lastResetKey) { setLastResetKey(resetKey); @@ -99,8 +97,17 @@ export function UserPlaceDialog({ const latNum = Number(lat); const lngNum = Number(lng); + const latError = lat !== "" && (Number.isNaN(latNum) || latNum < -90 || latNum > 90); + const lngError = lng !== "" && (Number.isNaN(lngNum) || lngNum < -180 || lngNum > 180); const isValid = - name.trim() && city.trim() && lat !== "" && lng !== "" && !Number.isNaN(latNum) && !Number.isNaN(lngNum); + name.trim() && + city.trim() && + lat !== "" && + lng !== "" && + !Number.isNaN(latNum) && + !Number.isNaN(lngNum) && + !latError && + !lngError; async function handleSave() { if (!isValid) return; @@ -154,9 +161,6 @@ export function UserPlaceDialog({ return ( e.preventDefault()} onInteractOutside={(e) => e.preventDefault()} > @@ -212,7 +216,11 @@ export function UserPlaceDialog({ step="any" value={lat} onChange={(e) => setLat(e.target.value)} + aria-invalid={latError} /> + {latError && ( +

Latitude must be between -90 and 90.

+ )}
@@ -222,7 +230,11 @@ export function UserPlaceDialog({ step="any" value={lng} onChange={(e) => setLng(e.target.value)} + aria-invalid={lngError} /> + {lngError && ( +

Longitude must be between -180 and 180.

+ )}