feat(rn_cli_wallet): desktop-web device frame + web layout fixes#562
feat(rn_cli_wallet): desktop-web device frame + web layout fixes#562ignaciosantise wants to merge 4 commits into
Conversation
Constrain the web build to a phone-like framed surface on wide desktop viewports (>=1024px) instead of stretching full-width, plus related web-only layout/interaction fixes. - Add DesktopFrameWrapper (.web frame, native passthrough) wrapping the app root; centered ~430px surface with rounded corners + shadow on a neutral page background. Shared dims in constants/DesktopFrame.ts. - Header: add top padding on web (safe-area top is 0) so the logo/scan icon aren't flush to the top. - Tab bar (web): lighter theme-aware top divider + extra height/padding so labels aren't clipped in the frame. - Modal (web): cap sheet width to the frame and render inline (coverScreen=false) so it stays within the frame and clips to its rounded bottom instead of overflowing the viewport. - Settings: make the dark-mode Switch display-only (pointerEvents=none) so a tap flows to the card's single toggle; fixes web double-toggle where the switch click also bubbled to the card (net no change). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ignaciosantise's task in 4m 0s —— View job Code Review
Found 2 issue(s)Issue 1: Modal backdrop dismissal unreliable on desktop webID: modal-coverscreen-backdrop-dismiss-a7f2 Context:
Recommendation: Add an explicit // inside Modal(), alongside the existing RNModal
{Platform.OS === 'web' && open && (
<Pressable
style={StyleSheet.absoluteFillObject}
onPress={onClose}
/>
)}Or verify Issue 2:
|
Address PR review: replace `as object` (which suppressed type checking on the whole Switch spread) with a narrow type so TS keeps validating. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the review — actions taken: Issue 1 — Modal backdrop dismissal ( Issue 2 — |
There was a problem hiding this comment.
Pull request overview
Updates the rn_cli_wallet web experience to render more like a mobile wallet on desktop browsers by constraining the app to a framed surface and applying related web-only layout fixes.
Changes:
- Add a desktop-only web frame wrapper that centers the app in a fixed “device” surface on wide viewports.
- Adjust web layout for header padding and web tab bar spacing/dividers to prevent clipping inside the frame.
- Update modal behavior on web to render inline (non-portal) and constrain width to the frame; adjust Settings dark-mode interaction to avoid double-toggles on web.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| wallets/rn_cli_wallet/src/screens/Settings/index.tsx | Adjusts Switch handling to avoid double-toggle on web; updates web-only Switch prop typing. |
| wallets/rn_cli_wallet/src/screens/App.tsx | Wraps the app root with DesktopFrameWrapper. |
| wallets/rn_cli_wallet/src/navigators/HomeTabNavigator.web.tsx | Tweaks web tab bar style (divider color, height/padding) for frame compatibility. |
| wallets/rn_cli_wallet/src/constants/DesktopFrame.ts | Introduces shared desktop-frame dimensions and styling constants. |
| wallets/rn_cli_wallet/src/components/Modal.tsx | Web-only modal changes: inline rendering and max width constrained to the frame. |
| wallets/rn_cli_wallet/src/components/Header.tsx | Adds web-specific top padding so header content isn’t flush to top. |
| wallets/rn_cli_wallet/src/components/DesktopFrameWrapper.web.tsx | Implements the desktop web frame and viewport breakpoint logic. |
| wallets/rn_cli_wallet/src/components/DesktopFrameWrapper.tsx | Native passthrough wrapper (no-op off web). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| {/* Display-only: the whole card (PressableScale) owns the toggle. | ||
| pointerEvents="none" lets a tap on the switch pass through to the | ||
| card's onPress, so it toggles exactly once. Without this, on web | ||
| the switch's own click also bubbles to the card and toggles twice | ||
| (net no change). */} | ||
| <View pointerEvents="none" style={styles.switch}> | ||
| <Switch | ||
| value={themeMode === 'dark'} | ||
| trackColor={Platform.select({ | ||
| android: { | ||
| false: Theme['foreground-tertiary'], | ||
| true: Theme['bg-accent-primary'], | ||
| }, | ||
| })} | ||
| thumbColor={Platform.select({ android: Theme.white })} | ||
| {...webAccentSwitchProps} | ||
| /> | ||
| </View> |
There was a problem hiding this comment.
Good catch — fixed in 519988e. The display-only pointerEvents="none" path is now gated to web only; on native the Switch keeps its onValueChange and stays fully interactive/accessible (native never had the double-toggle).
| // On web, constrain the sheet to the desktop frame width and center it so it | ||
| // doesn't stretch full-viewport. Self-adjusts: fills the width on narrow | ||
| // screens, caps + centers on wide desktop. Backdrop still dims the full page. |
There was a problem hiding this comment.
Fixed in 519988e — updated the comment to say that with coverScreen={false} the backdrop dims only the frame area (its parent), not the full page.
| * Unlike the pos-app frame this deliberately avoids `transform: scale()` and a | ||
| * modal portal: rn_cli_wallet's <Modal /> and <Toast /> render as fixed | ||
| * full-viewport overlays and would fight a scaled frame. Those stay untouched. |
There was a problem hiding this comment.
Fixed in 519988e — updated the doc comment: on web <Modal /> now renders inline (coverScreen=false) and is clipped to the frame; <Toast /> still renders as a fixed full-viewport overlay and is left untouched.
- Settings: gate the display-only Switch (pointerEvents=none, no onValueChange) to web only; keep the Switch fully interactive and accessible on native, which never had the double-toggle bug. - Modal / DesktopFrameWrapper: correct stale comments — with coverScreen=false the web modal renders inline and its backdrop dims only the frame area, not the full page. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What
Makes the
rn_cli_walletweb build look right on desktop. Instead of stretching the mobile UI full-width, it's now constrained to a phone-like framed surface on wide viewports, with a set of related web-only layout/interaction fixes.Changes
DesktopFrameWrapper(.web.tsxframe + native passthrough.tsx) wraps the app root. On viewports ≥1024px the app is centered in a ~430px surface with rounded corners, a drop shadow, and a neutral page background; below that (mobile web) and on native it renders full-bleed, unchanged. Shared dimensions live inconstants/DesktopFrame.ts. Deliberately avoids the pos-appscale()/modal-portal machinery.topis 0 there) so the logo and scan icon aren't flush to the top edge.coverScreen={false}) so the sheet + backdrop stay inside the frame and clip to its rounded bottom instead of overflowing to the viewport edge.Switchis now display-only (pointerEvents="none"); the card'sPressableScaleowns the single toggle. Fixes a web bug where tapping the switch fired both the switch'sonValueChangeand the card'sonPress(double toggle → no net change).Scope / notes
.web.tsxvariants orPlatform.OS === 'web'branches); native (iOS/Android) is untouched.node_modules). To check:cd wallets/rn_cli_wallet && yarn && yarn web, then test wide desktop, narrow (<1024px), dark/light toggle, and a session-proposal modal.🤖 Generated with Claude Code