Fix iOS Safari auto-zoom on input fields
- Changed all input/textarea/select font-size from text-sm to text-base (16px minimum) - Added blur handler to reset viewport zoom on InlineItemCreate - Prevents iOS Safari from auto-zooming when focusing on form fields - Ensures zoom resets properly when closing forms
This commit is contained in:
@@ -63,6 +63,10 @@ export default function InlineItemCreate({ listId }: InlineItemCreateProps) {
|
|||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setTitle('')
|
setTitle('')
|
||||||
setIsCreating(false)
|
setIsCreating(false)
|
||||||
|
// Reset zoom on iOS Safari
|
||||||
|
if (document.activeElement instanceof HTMLElement) {
|
||||||
|
document.activeElement.blur()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||||
@@ -71,6 +75,11 @@ export default function InlineItemCreate({ listId }: InlineItemCreateProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
// Force viewport reset on iOS Safari
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
if (!isCreating) {
|
if (!isCreating) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@@ -94,10 +103,11 @@ export default function InlineItemCreate({ listId }: InlineItemCreateProps) {
|
|||||||
setError('')
|
setError('')
|
||||||
}}
|
}}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
|
onBlur={handleBlur}
|
||||||
placeholder="Enter task title..."
|
placeholder="Enter task title..."
|
||||||
autoFocus
|
autoFocus
|
||||||
maxLength={200}
|
maxLength={200}
|
||||||
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-sm sm:text-base ${
|
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-base ${
|
||||||
error ? 'border-red-500 focus:ring-red-500' : 'border-gray-300 focus:ring-blue-500'
|
error ? 'border-red-500 focus:ring-red-500' : 'border-gray-300 focus:ring-blue-500'
|
||||||
}`}
|
}`}
|
||||||
aria-invalid={error ? 'true' : 'false'}
|
aria-invalid={error ? 'true' : 'false'}
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ export default function ItemForm({ listId, item, mode = 'edit', canEdit = true }
|
|||||||
onChange={(e) => setTitle(e.target.value)}
|
onChange={(e) => setTitle(e.target.value)}
|
||||||
onBlur={() => handleBlur('title')}
|
onBlur={() => handleBlur('title')}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-sm sm:text-base ${
|
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-base ${
|
||||||
errors.title && touched.title
|
errors.title && touched.title
|
||||||
? 'border-red-500 focus:ring-red-500'
|
? 'border-red-500 focus:ring-red-500'
|
||||||
: 'border-gray-300 focus:ring-blue-500'
|
: 'border-gray-300 focus:ring-blue-500'
|
||||||
@@ -293,7 +293,7 @@ export default function ItemForm({ listId, item, mode = 'edit', canEdit = true }
|
|||||||
onBlur={() => handleBlur('description')}
|
onBlur={() => handleBlur('description')}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
rows={3}
|
rows={3}
|
||||||
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-sm sm:text-base resize-y ${
|
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-base resize-y ${
|
||||||
errors.description && touched.description
|
errors.description && touched.description
|
||||||
? 'border-red-500 focus:ring-red-500'
|
? 'border-red-500 focus:ring-red-500'
|
||||||
: 'border-gray-300 focus:ring-blue-500'
|
: 'border-gray-300 focus:ring-blue-500'
|
||||||
@@ -320,7 +320,7 @@ export default function ItemForm({ listId, item, mode = 'edit', canEdit = true }
|
|||||||
value={priority}
|
value={priority}
|
||||||
onChange={(e) => setPriority(e.target.value as 'low' | 'medium' | 'high')}
|
onChange={(e) => setPriority(e.target.value as 'low' | 'medium' | 'high')}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
className={`w-full px-3 sm:px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm sm:text-base tap-target ${!canEdit ? 'bg-gray-100 cursor-not-allowed' : ''}`}
|
className={`w-full px-3 sm:px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-base tap-target ${!canEdit ? 'bg-gray-100 cursor-not-allowed' : ''}`}
|
||||||
>
|
>
|
||||||
<option value="low">Low</option>
|
<option value="low">Low</option>
|
||||||
<option value="medium">Medium</option>
|
<option value="medium">Medium</option>
|
||||||
@@ -340,7 +340,7 @@ export default function ItemForm({ listId, item, mode = 'edit', canEdit = true }
|
|||||||
onChange={(e) => setDueDate(e.target.value)}
|
onChange={(e) => setDueDate(e.target.value)}
|
||||||
onBlur={() => handleBlur('dueDate')}
|
onBlur={() => handleBlur('dueDate')}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-sm sm:text-base tap-target ${
|
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-base tap-target ${
|
||||||
errors.dueDate && touched.dueDate
|
errors.dueDate && touched.dueDate
|
||||||
? 'border-red-500 focus:ring-red-500'
|
? 'border-red-500 focus:ring-red-500'
|
||||||
: 'border-gray-300 focus:ring-blue-500'
|
: 'border-gray-300 focus:ring-blue-500'
|
||||||
@@ -370,7 +370,7 @@ export default function ItemForm({ listId, item, mode = 'edit', canEdit = true }
|
|||||||
onChange={(e) => setTagInput(e.target.value)}
|
onChange={(e) => setTagInput(e.target.value)}
|
||||||
onKeyDown={handleKeyDown}
|
onKeyDown={handleKeyDown}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
className={`flex-1 px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-sm sm:text-base ${
|
className={`flex-1 px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-base ${
|
||||||
errors.tagInput
|
errors.tagInput
|
||||||
? 'border-red-500 focus:ring-red-500'
|
? 'border-red-500 focus:ring-red-500'
|
||||||
: 'border-gray-300 focus:ring-blue-500'
|
: 'border-gray-300 focus:ring-blue-500'
|
||||||
@@ -432,7 +432,7 @@ export default function ItemForm({ listId, item, mode = 'edit', canEdit = true }
|
|||||||
onBlur={() => handleBlur('notes')}
|
onBlur={() => handleBlur('notes')}
|
||||||
disabled={!canEdit}
|
disabled={!canEdit}
|
||||||
rows={5}
|
rows={5}
|
||||||
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-sm sm:text-base resize-y ${
|
className={`w-full px-3 sm:px-4 py-3 border rounded-lg focus:outline-none focus:ring-2 text-base resize-y ${
|
||||||
errors.notes && touched.notes
|
errors.notes && touched.notes
|
||||||
? 'border-red-500 focus:ring-red-500'
|
? 'border-red-500 focus:ring-red-500'
|
||||||
: 'border-gray-300 focus:ring-blue-500'
|
: 'border-gray-300 focus:ring-blue-500'
|
||||||
|
|||||||
Reference in New Issue
Block a user