feat(frontend): responsive layout for iPhone 14 and Galaxy Tab S9 series#2409
Open
ATLAS-0321 wants to merge 1 commit intobytedance:mainfrom
Open
feat(frontend): responsive layout for iPhone 14 and Galaxy Tab S9 series#2409ATLAS-0321 wants to merge 1 commit intobytedance:mainfrom
ATLAS-0321 wants to merge 1 commit intobytedance:mainfrom
Conversation
Adds first-class support for the iPhone 14 family (390–430 px portrait) and the Samsung Galaxy Tab S9 series (800 px portrait via a new ``tab`` breakpoint) without refactoring the existing layout. Measurements and design decisions come from Apple HIG / Android Material / WebKit docs rather than ad-hoc guessing — notably the 44×44 px touch-target floor, ``env(safe-area-inset-*)`` for notch and home-indicator clearance, and cross-browser keyboard occlusion via ``window.visualViewport``. Highlights: - ``app/layout.tsx``: proper ``<Viewport>`` metadata with ``viewport-fit=cover`` (required for non-zero safe-area insets on iOS) and ``interactive-widget=resizes-content`` (Chromium keyboard behaviour). - ``styles/globals.css``: custom ``tab`` breakpoint at 800 px, safe-area utilities (``pt-safe`` / ``pb-safe`` / ``px-safe`` / …), combined keyboard inset (``env(keyboard-inset-*)`` max'd with a JS-measured fallback for Safari iOS), ``hoverable`` custom-variant for separating hover-capable pointers from touch, ``touch-target`` utility that only enforces the 44×44 minimum on coarse pointers, global ``-webkit-tap-highlight-color: transparent``. - ``hooks/use-mobile.ts``: splits ``useIsMobile`` into phone / tablet / narrow hooks at 640 / 1024 px so tablet-portrait no longer falls into the persistent-sidebar layout where it doesn't fit. - ``hooks/use-visual-viewport.ts`` (new): mirrors ``window.visualViewport.height`` to the ``--keyboard-inset-js`` CSS variable. This is the only cross-browser source on iOS Safari, which ships neither the VirtualKeyboard API nor ``interactive-widget``. - ``workspace/chats/chat-box.tsx``: below the ``lg`` breakpoint the artifact panel switches from 60/40 split to full-screen tab-switch — the 60/40 split at 800 px would leave both columns unreadable. - ``workspace/input-box.tsx``: suggestion chips are hidden below the narrow breakpoint because on short phone viewports they physically overlap the last lines of the response. Dropdown menu widths switch to ``min(20rem, calc(100vw-1.5rem))`` so they no longer overflow on 390 px viewports. - ``ai-elements/prompt-input.tsx``: textarea switches to 16 px base on narrow viewports to prevent iOS Safari's auto-zoom on focus. - ``ui/sidebar.tsx``: mobile drawer width capped at ``min(18rem, 85vw)`` so at least 15 % of the page behind it stays visible for dismissal. - ``workspace/copy-button.tsx``: gets the ``touch-target`` utility so icon buttons are comfortably tappable on touchscreens without enlarging them on desktop. - ``workspace/chats/[thread_id]/page.tsx``: wires ``useVisualViewport`` at the chat-page level and uses the new ``bottom-keyboard`` / ``px-safe`` utilities so the input box rides up with the on-screen keyboard and respects the safe area on devices with a home indicator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
viewportFit: "cover"andinteractiveWidget: "resizes-content"for proper safe-area + keyboard handlinguseIsMobileintouseIsPhone(<640 px),useIsTablet(640–1024 px),useIsNarrow(<1024 px); old name kept as alias for backwards compatibilityuse-visual-viewport.tsmirrorswindow.visualViewport.heightinto a CSS variable so layouts react to the on-screen keyboard on platforms withoutenv(keyboard-inset-*)--breakpoint-tab: 800 px(betweensmandmd)pt-safe,pb-safe, …) and combined keyboard inset viamax(env(keyboard-inset-bottom, 0px), var(--keyboard-inset-js, 0px))hoverable:custom variant for hover-only UI (coarse-pointer devices get tap-friendly alternatives)Motivation
Reference devices (physically tested):
The previous layout assumed desktop with gracefully-degrading mobile. On iPhone 14 Pro the suggestion chips overlapped the input; on Galaxy Tab S9 portrait the chat composer was cut off by the virtual keyboard.
Approach
dvh/svh/lvhinstead ofvhso browser-UI collapse is accounted for.visualViewport.heightfallback elsewhere.Testing
No unit tests — this is visual + DOM-layout behaviour that only manual verification meaningfully covers.