Skip to content

Commit a293ba7

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 5566cdb commit a293ba7

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
@@ -257,6 +257,8 @@ export const VimTextArea = React.forwardRef<HTMLTextAreaElement, VimTextAreaProp
257257
autoCorrect="off"
258258
autoCapitalize="none"
259259
autoComplete="off"
260+
// Optimize for iPadOS/iOS keyboard behavior
261+
enterKeyHint="send"
260262
{...rest}
261263
style={{
262264
...(rest.style ?? {}),

src/browser/styles/globals.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,47 @@ body,
10511051
}
10521052

10531053
/* Tailwind utility extensions for dark theme surfaces */
1054+
/*
1055+
* iPadOS/iOS keyboard accessory bar fix
1056+
*
1057+
* On iPadOS with external keyboard (and iOS with software keyboard),
1058+
* Safari shows an input accessory bar above the keyboard containing
1059+
* language switch, form navigation arrows, and microphone/dictation.
1060+
* This bar can cause layout shifts when focusing inputs.
1061+
*
1062+
* The visual viewport API tracks the actual visible area excluding
1063+
* system UI like keyboard accessory bars. We use CSS environment
1064+
* variables to handle safe areas and ensure content stays visible.
1065+
*/
1066+
1067+
/* Ensure the app uses the full viewport height accounting for browser chrome */
1068+
html,
1069+
body,
1070+
#root {
1071+
/* Use dvh (dynamic viewport height) on supported browsers - this accounts for
1072+
mobile browser chrome and keyboard accessory bars */
1073+
min-height: 100dvh;
1074+
/* Fallback for older browsers */
1075+
min-height: 100vh;
1076+
}
1077+
1078+
/* Handle safe areas for notched devices and keyboard accessory bars */
1079+
@supports (padding: env(safe-area-inset-top)) {
1080+
/* Apply padding to account for iOS safe areas (notch at top, home indicator at bottom) */
1081+
#root {
1082+
padding-top: env(safe-area-inset-top, 0);
1083+
padding-bottom: env(safe-area-inset-bottom, 0);
1084+
padding-left: env(safe-area-inset-left, 0);
1085+
padding-right: env(safe-area-inset-right, 0);
1086+
}
1087+
}
1088+
1089+
/* For PWA mode, ensure the viewport meta tag handles the keyboard properly
1090+
Note: This is a CSS-only solution; the actual fix requires the viewport
1091+
meta tag to include 'interactive-widget=resizes-content' which is handled
1092+
in index.html */
1093+
1094+
10541095
@utility plan-surface {
10551096
background: var(--surface-plan-gradient);
10561097
border: 1px solid var(--surface-plan-border);

0 commit comments

Comments
 (0)