Skip to content

Commit d709b68

Browse files
authored
🤖 fix: iPadOS PWA keyboard accessory bar layout shift (#799)
On iPadOS 26 with external keyboard in PWA mode, Safari shows an input accessory bar (language switch, up/down arrows, microphone) that can cause layout shifts when focusing the chat input. **Changes:** - Add `viewport-fit=cover` to viewport meta for safe area inset support - Use `100dvh` (dynamic viewport height) to account for browser chrome and keyboard bars, with `100vh` fallback for older browsers - Add CSS `env()` safe-area-inset handling for notched devices - Add `enterKeyHint="send"` to textarea for better mobile keyboard UX The `dvh` unit automatically adjusts when the keyboard accessory bar appears/disappears, preventing the chat input from being pushed around. --- _Generated with `mux`_
1 parent 3e25841 commit d709b68

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

index.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta
66
name="viewport"
7-
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content"
7+
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover, interactive-widget=resizes-content"
88
/>
99
<meta name="description" content="Parallel agentic development with Electron + React" />
1010
<meta name="theme-color" content="#1e1e1e" />
@@ -20,7 +20,8 @@
2020
background: var(--color-background, #1e1e1e);
2121
}
2222
#root {
23-
height: 100vh;
23+
height: 100vh; /* fallback for older browsers */
24+
height: 100dvh;
2425
overflow: hidden;
2526
}
2627
</style>

src/browser/components/VimTextArea.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ export const VimTextArea = React.forwardRef<HTMLTextAreaElement, VimTextAreaProp
244244
autoCorrect="off"
245245
autoCapitalize="none"
246246
autoComplete="off"
247+
// Optimize for iPadOS/iOS keyboard behavior
248+
enterKeyHint="send"
247249
{...rest}
248250
style={{
249251
...(rest.style ?? {}),

src/browser/styles/globals.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,47 @@ body,
10111011
}
10121012

10131013
/* Tailwind utility extensions for dark theme surfaces */
1014+
/*
1015+
* iPadOS/iOS keyboard accessory bar fix
1016+
*
1017+
* On iPadOS with external keyboard (and iOS with software keyboard),
1018+
* Safari shows an input accessory bar above the keyboard containing
1019+
* language switch, form navigation arrows, and microphone/dictation.
1020+
* This bar can cause layout shifts when focusing inputs.
1021+
*
1022+
* The visual viewport API tracks the actual visible area excluding
1023+
* system UI like keyboard accessory bars. We use CSS environment
1024+
* variables to handle safe areas and ensure content stays visible.
1025+
*/
1026+
1027+
/* Ensure the app uses the full viewport height accounting for browser chrome */
1028+
html,
1029+
body,
1030+
#root {
1031+
/* Use dvh (dynamic viewport height) on supported browsers - this accounts for
1032+
mobile browser chrome and keyboard accessory bars */
1033+
min-height: 100dvh;
1034+
/* Fallback for older browsers */
1035+
min-height: 100vh;
1036+
}
1037+
1038+
/* Handle safe areas for notched devices and keyboard accessory bars */
1039+
@supports (padding: env(safe-area-inset-top)) {
1040+
/* Apply padding to account for iOS safe areas (notch at top, home indicator at bottom) */
1041+
#root {
1042+
padding-top: env(safe-area-inset-top, 0);
1043+
padding-bottom: env(safe-area-inset-bottom, 0);
1044+
padding-left: env(safe-area-inset-left, 0);
1045+
padding-right: env(safe-area-inset-right, 0);
1046+
}
1047+
}
1048+
1049+
/* For PWA mode, ensure the viewport meta tag handles the keyboard properly
1050+
Note: This is a CSS-only solution; the actual fix requires the viewport
1051+
meta tag to include 'interactive-widget=resizes-content' which is handled
1052+
in index.html */
1053+
1054+
10141055
@utility plan-surface {
10151056
background: var(--surface-plan-gradient);
10161057
border: 1px solid var(--surface-plan-border);

0 commit comments

Comments
 (0)