feat: add htmlDir and safeAreaInsetBottom props, and collapse hidden WebView on Android - #134
Open
carloseustaquio wants to merge 2 commits into
Open
Conversation
…WebView on Android - Collapse the always-mounted hidden WebView container to 0x0 so it cannot swallow touches on Android while no experience is shown - Add htmlDir prop: sets dir on the WebView document root and, for 'rtl', injects a bundled RTL stylesheet that mirrors the Ketch experiences - Add safeAreaInsetBottom prop so hosts can pass the real Android bottom inset in edge-to-edge apps where the Dimensions heuristic returns 0 - Reset the default body margin of the internal WebView document Co-authored-by: Cursor <cursoragent@cursor.com>
…t in the web experiences htmlDir now only sets the dir attribute on the WebView document root. That attribute is what activates Tailwind's rtl:/ltr: variants (which compile to [dir="rtl"]/[dir="ltr"] ancestor selectors), so the mirroring styles themselves belong in the Ketch web experience components rather than shipped as an override stylesheet in this SDK. Co-authored-by: Cursor <cursoragent@cursor.com>
jboileau99
approved these changes
Jul 30, 2026
Collaborator
|
@carloseustaquio thank you for these contributions! We've completed some internal testing and all looks good. |
Collaborator
|
@carloseustaquio if you're able to resubmit these changes with verified commits we'll be all set to merge. Thanks! |
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.
Description of this change
We run this SDK in a production React Native app serving both LTR and RTL locales. We have been carrying variants of the changes below as a
patch-packagepatch against0.21.2and would like to upstream them so we (and others) can drop the patch. Existing behavior is unchanged unless the new opt-in props are used, apart from the two small rendering fixes described in 1 and 4.1. Fix: hidden WebView blocks all touches on Android
The SDK keeps the WebView container mounted at all times so the consent logic keeps running, and relies on
opacity: 0+pointerEvents: 'none'while no experience is shown. On Android that is not enough: the nativeandroid.webkit.WebViewhandles touches itself and does not honour a React-level parentpointerEvents: 'none', so the invisible full-screen WebView swallows every tap and the app underneath becomes unresponsive.The
hiddenstyle now also collapses the container to 0x0 (width: 0,height: 0,overflow: 'hidden'). The WebView stays mounted — the JS engine,injectJavaScriptandonMessageall keep working — but it has no area to receive touches. When an experience is shown,styles.shownexpands it back to full screen as before.2. Feature: RTL enablement via a new
htmlDirpropThe value is applied as the
dirattribute on the WebView document root (<html dir="...">). Today the internal bootstrap HTML hardcodes<html>with nodir, so there is no way for direction-sensitive styling inside the experiences to ever activate, regardless of the device or app locale.Setting
dir="rtl"on the root:rtl:/ltr:variants compile to&:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *), so they key off exactly this attribute — and[dir='rtl']-scoped rules in acssOverridetake effect.Usage:
Note for maintainers: the experiences currently use physical utilities (e.g.
ketch-text-left,ketch-ml-auto), which pin the layout to LTR even in an RTL document. We would love to see the web experience components adopt Tailwind'srtl:/ltr:variants or logical properties/utilities (ms-*/me-*,text-start/text-end) for full native mirroring — this prop provides the document-leveldirsignal those rely on. We deliberately did not bundle an RTL override stylesheet in this SDK, since the mirroring belongs in the components themselves. In the interim, consumers can layer small[dir='rtl']-scoped tweaks viacssOverride(as we do in production today).3. Feature:
safeAreaInsetBottomprop for edge-to-edge Android appsThe current Android bottom padding heuristic,
(screen.height - window.height) / 2, returns 0 in edge-to-edge apps (wherescreen == window, the default on modern React Native / Android 15), which leaves the bottom of the experience rendered underneath the gesture/navigation bar. The new optional prop lets the host app pass the real inset, with the heuristic kept as the fallback:4. Fix: reset default body margin in the internal WebView document
The internal HTML document had no
margin: 0onbody, so the browser default 8px margin offset the experience content.Why is this change being made?
How was this tested? How can the reviewer verify your testing?
package/:npm run lint,npm run typecheckandnpm run prepare(bob build) all pass, plusjest(11 tests, including new coverage forinjectCssIntoHtmlandinjectDirIntoHtmlin__tests__/assets.test.ts).patch-packagepatch of the published package): taps reach the app while the experience is hidden on Android, thedir="rtl"document root correctly activates our[dir='rtl']-scoped styles on RTL locales, and the experience no longer renders under the Android gesture bar in edge-to-edge mode.Related issues
None filed — happy to open separate issues for the Android touch/inset bugs if you prefer to track them individually.
Checklist
htmlDironly accepts the three literal values.