Skip to content

fix(feedback): Present feedback form above native-stack sheets on iOS (experimental) - #6882

Draft
antonis wants to merge 7 commits into
mainfrom
fix/feedback-form-over-ios-native-sheet
Draft

antonis wants to merge 7 commits into
mainfrom
fix/feedback-form-over-ios-native-sheet

Conversation

@antonis

@antonis antonis commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

This adds an opt-in, experimental option so the form is rendered inside react-native-screens' FullWindowOverlay (window-level, above presented sheets) instead of a Modal:

feedbackIntegration({ _experiments: { presentOverNativeModals: true } })
  • iOS only; default off. Requires react-native-screens — no-ops (falls back to Modal, with a debug.warn) when it isn't installed.
  • Fixed at the provider level, so it covers both showFeedbackForm() and shake-to-report.
  • The existing Modal path is unchanged when the option is off.

Known limitation: with the overlay on, the screenshot attachment flows are limited over a presented native-stack sheet — the photo-library picker ("Add a screenshot") is presented behind the overlay, and "Take a screenshot" reveals its capture button in the root tree behind the sheet. Alerts (validation/success), typing, Cancel and swipe-to-dismiss are unaffected. This is documented in the option's JSDoc.

💡 Motivation and Context

Fixes #6875.

💚 How did you test it?

  • New unit tests/CI
  • Manually
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2026-10-13.at.13.43.37.mov

📝 Checklist

  • I added tests to verify changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed. ⚠️ I'd advocate on skipping in this experimental state for now
  • I updated the wizard if needed.
  • All tests passing.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

  • Make the image-library picker usable with the overlay — either hide the overlay while the picker is presented (JS coordination), or host the form in its own window/VC so it (and its picker) sit above everything (native; the path if this becomes the iOS default).
  • Docs + public-API review before the option is stabilised / considered as the default.

antonis and others added 4 commits October 13, 2026 11:31
On iOS a React Native `Modal` presents from the root view controller's
presentation chain. When a native-stack screen is already presented
(e.g. `presentation: 'formSheet'`), UIKit refuses the second
presentation and the feedback form silently fails to appear (#6875).

Render the form inside react-native-screens' `FullWindowOverlay` on iOS
when it resolves (optional require, Metro-optional dependency), falling
back to `Modal` otherwise. Android stays on `Modal`. This covers both
`showFeedbackForm()` and shake-to-report, since both go through
`FeedbackFormProvider`.

WIP: currently auto-enabled whenever react-native-screens is present.
Still TODO: opt-in experimental option (`_experiments.presentOverNativeModals`),
overlay-path unit tests, device-verify close/swipe-dismiss, CHANGELOG.

Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…presentOverNativeModals

Make the FullWindowOverlay presentation opt-in instead of auto-enabled:
`feedbackIntegration({ _experiments: { presentOverNativeModals: true } })`
(iOS only, requires react-native-screens; default off). When disabled or
when react-native-screens isn't installed, the form keeps using Modal; an
enabled-but-missing setup logs a debug warning.

- integration: add `_experiments.presentOverNativeModals` + exported
  `FeedbackExperiments` type and `isPresentOverNativeModalsEnabled()`.
- provider: gate the overlay branch on the option; warn on fallback.
- tests: default Modal / overlay-when-enabled / fallback-and-warn.
- api-report + CHANGELOG updated.

Verified on iOS sim (New Arch): with the option on, Sentry.showFeedbackForm()
renders above a native-stack formSheet with no "already presenting" error.

Still TODO: Old Architecture verification, device-verify close/swipe-dismiss
and interactive keyboard, decide whether to default-on in a later release.

Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add an "Open Form Sheet" entry to the Playground tab that presents a
  native-stack formSheet with a button to open the feedback form,
  demonstrating `_experiments.presentOverNativeModals`.
- Remove issue-number references from code comments and test names.

Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

⚪ None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix(feedback): Present feedback form above native-stack sheets on iOS (experimental) by antonis in #6882
  • chore(deps): bump futureware-tech/simulator-action from 5 to 6 by dependabot in #6878
  • chore(deps): bump getsentry/craft from 2.33.1 to 2.34.1 by dependabot in #6880
  • chore(deps): bump actions/download-artifact from 8.0.1 to 8.0.2 by dependabot in #6879
  • chore(deps): bump ruby/setup-ruby from 1.327.0 to 1.328.0 by dependabot in #6877
  • chore(deps): bump the codeql-action group with 3 updates by dependabot in #6876
  • build(deps): Pin tinypool to patched 2.x to resolve prototype-pollution advisories by antonis in #6869
  • build(deps): Bump sharp, shell-quote and smol-toml to patched versions by antonis in #6868
  • fix(core): Do not mark sendDefaultPii as deprecated in React Native options by alwx in #6864
  • ci(ios): Archive the SwiftPM app to catch xcframework signature collisions by alwx in #6871
  • feat(core): Support applicationKey and moduleMetadata in Metro config by alwx in #6863
  • chore(deps): update JavaScript SDK to v10.76.2 by antonis in #6866
  • ci(core): Guard the "sideEffects": false contract with a lint check by antonis in #6836
  • chore(deps): bump nx from 22.7.7 to 22.7.12 by dependabot in #6857
  • chore(deps): bump compression from 1.7.5 to 1.8.2 by dependabot in #6856
  • chore(deps): bump postcss-selector-parser from 7.1.4 to 7.1.6 by dependabot in #6855
  • chore(deps): bump source-map-js from 1.2.1 to 1.2.2 by dependabot in #6854
  • chore(deps): bump proxy-addr from 2.0.7 to 2.0.8 by dependabot in #6853
  • chore(deps): bump handlebars from 4.7.9 to 4.7.10 by dependabot in #6862
  • chore(deps): update Wizard to v8.0.1 by github-actions in #6852

🤖 This preview updates automatically when you update the PR.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/core/src/js/feedback/FeedbackFormProvider.tsx
Comment thread packages/core/src/js/feedback/FeedbackFormProvider.tsx
antonis and others added 2 commits October 13, 2026 13:48
Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rlay

Address review feedback on the experimental `presentOverNativeModals` option:

- Re-render the form on `Dimensions` change so the FullWindowOverlay stays
  full-screen after rotation/resize (it was sized once from
  `Dimensions.get('window')` at render).
- Document that the photo-library screenshot picker ("Add a screenshot") is
  presented behind the overlay and can't be used while the form is open;
  native "Take a screenshot", alerts, and text entry are unaffected.

Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@antonis antonis added the ready-to-merge Triggers the full CI test suite label Oct 13, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit edc646d. Configure here.

@sentry

sentry Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.30.0 (110) Release

⚙️ sentry-react-native Build Distribution Settings

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3853.72 ms 1232.37 ms -2621.35 ms
Size 5.15 MiB 6.95 MiB 1.80 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
038a6d7+dirty 3849.69 ms 1228.40 ms -2621.28 ms
d771cd5+dirty 3839.40 ms 1211.08 ms -2628.32 ms
41d6254+dirty 3845.71 ms 1224.51 ms -2621.20 ms
a858ac3+dirty 3836.62 ms 1222.56 ms -2614.06 ms
20fbd51+dirty 3827.47 ms 1213.32 ms -2614.15 ms
5920f6b+dirty 3866.23 ms 1239.47 ms -2626.76 ms
5748023+dirty 3840.49 ms 1227.43 ms -2613.05 ms
9ad4522+dirty 3850.40 ms 1222.40 ms -2628.00 ms
d0e3b3e+dirty 3854.77 ms 1218.58 ms -2636.19 ms
3b6e9f9+dirty 3851.90 ms 1233.33 ms -2618.57 ms

App size

Revision Plain With Sentry Diff
038a6d7+dirty 5.15 MiB 6.70 MiB 1.55 MiB
d771cd5+dirty 4.98 MiB 6.55 MiB 1.57 MiB
41d6254+dirty 5.15 MiB 6.70 MiB 1.54 MiB
a858ac3+dirty 4.98 MiB 6.51 MiB 1.53 MiB
20fbd51+dirty 4.98 MiB 6.46 MiB 1.49 MiB
5920f6b+dirty 5.15 MiB 6.93 MiB 1.78 MiB
5748023+dirty 5.15 MiB 6.68 MiB 1.53 MiB
9ad4522+dirty 4.98 MiB 6.56 MiB 1.58 MiB
d0e3b3e+dirty 4.98 MiB 6.51 MiB 1.53 MiB
3b6e9f9+dirty 5.15 MiB 6.68 MiB 1.53 MiB

Previous results on branch: fix/feedback-form-over-ios-native-sheet

Startup times

Revision Plain With Sentry Diff
942bc55+dirty 3874.28 ms 1232.98 ms -2641.31 ms

App size

Revision Plain With Sentry Diff
942bc55+dirty 5.15 MiB 6.95 MiB 1.80 MiB

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 451.04 ms 493.21 ms 42.17 ms
Size 50.56 MiB 56.62 MiB 6.06 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
23598c3+dirty 414.12 ms 426.24 ms 12.12 ms
bc8f61e+dirty 442.98 ms 506.56 ms 63.58 ms
0a9e622+dirty 420.73 ms 464.83 ms 44.10 ms
bf168a4+dirty 418.21 ms 489.74 ms 71.53 ms
b0d3373+dirty 557.66 ms 579.42 ms 21.76 ms
be120d6+dirty 536.61 ms 552.02 ms 15.41 ms
57e0069+dirty 413.82 ms 453.47 ms 39.65 ms
b9bebee+dirty 438.86 ms 452.21 ms 13.35 ms
0d9949d+dirty 403.57 ms 437.00 ms 33.43 ms
580fb5c+dirty 436.34 ms 471.63 ms 35.28 ms

App size

Revision Plain With Sentry Diff
23598c3+dirty 43.75 MiB 48.16 MiB 4.41 MiB
bc8f61e+dirty 49.74 MiB 55.09 MiB 5.35 MiB
0a9e622+dirty 49.74 MiB 55.09 MiB 5.34 MiB
bf168a4+dirty 49.74 MiB 55.09 MiB 5.35 MiB
b0d3373+dirty 48.30 MiB 53.58 MiB 5.28 MiB
be120d6+dirty 49.74 MiB 55.36 MiB 5.62 MiB
57e0069+dirty 49.74 MiB 54.85 MiB 5.11 MiB
b9bebee+dirty 48.30 MiB 53.58 MiB 5.28 MiB
0d9949d+dirty 43.75 MiB 48.13 MiB 4.37 MiB
580fb5c+dirty 49.74 MiB 54.79 MiB 5.05 MiB

Previous results on branch: fix/feedback-form-over-ios-native-sheet

Startup times

Revision Plain With Sentry Diff
942bc55+dirty 442.61 ms 457.14 ms 14.53 ms

App size

Revision Plain With Sentry Diff
942bc55+dirty 50.56 MiB 56.62 MiB 6.06 MiB

Comment thread packages/core/src/js/feedback/fullWindowOverlay.ts
Comment thread packages/core/src/js/feedback/FeedbackFormProvider.tsx
@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 454.91 ms 524.80 ms 69.89 ms
Size 50.56 MiB 56.62 MiB 6.06 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
038a6d7+dirty 499.02 ms 527.68 ms 28.66 ms
27d9693+dirty 438.63 ms 514.08 ms 75.46 ms
3d377b5+dirty 425.38 ms 440.67 ms 15.30 ms
0668149+dirty 410.52 ms 454.12 ms 43.60 ms
580fb5c+dirty 515.72 ms 585.38 ms 69.66 ms
0bd8916+dirty 400.15 ms 442.72 ms 42.57 ms
44c8b3f+dirty 492.13 ms 563.47 ms 71.34 ms
822d35b+dirty 472.69 ms 561.24 ms 88.56 ms
7d6fd3a+dirty 435.06 ms 458.78 ms 23.72 ms
7ff4d0f+dirty 403.38 ms 427.06 ms 23.68 ms

App size

Revision Plain With Sentry Diff
038a6d7+dirty 48.30 MiB 53.60 MiB 5.30 MiB
27d9693+dirty 49.74 MiB 55.09 MiB 5.34 MiB
3d377b5+dirty 43.94 MiB 49.00 MiB 5.06 MiB
0668149+dirty 50.56 MiB 56.59 MiB 6.03 MiB
580fb5c+dirty 49.74 MiB 54.79 MiB 5.05 MiB
0bd8916+dirty 48.30 MiB 53.57 MiB 5.26 MiB
44c8b3f+dirty 48.30 MiB 53.46 MiB 5.15 MiB
822d35b+dirty 49.74 MiB 54.84 MiB 5.10 MiB
7d6fd3a+dirty 43.94 MiB 49.00 MiB 5.06 MiB
7ff4d0f+dirty 48.30 MiB 53.60 MiB 5.30 MiB

Previous results on branch: fix/feedback-form-over-ios-native-sheet

Startup times

Revision Plain With Sentry Diff
942bc55+dirty 521.87 ms 531.09 ms 9.22 ms

App size

Revision Plain With Sentry Diff
942bc55+dirty 50.56 MiB 56.62 MiB 6.06 MiB

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3869.29 ms 1231.90 ms -2637.39 ms
Size 5.15 MiB 6.95 MiB 1.80 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
1122a96+dirty 3839.17 ms 1219.23 ms -2619.93 ms
9210ae6+dirty 3834.11 ms 1216.64 ms -2617.47 ms
fa21fca+dirty 3845.12 ms 1215.89 ms -2629.24 ms
5a23c47+dirty 3843.54 ms 1226.05 ms -2617.50 ms
3ce5254+dirty 1217.70 ms 1224.69 ms 6.99 ms
9474ead+dirty 3823.33 ms 1208.31 ms -2615.03 ms
a2585ce+dirty 3837.98 ms 1214.20 ms -2623.77 ms
7c6200e+dirty 3828.16 ms 1217.20 ms -2610.95 ms
04207c4+dirty 1228.55 ms 1226.04 ms -2.51 ms
606fb09+dirty 3850.45 ms 1229.81 ms -2620.63 ms

App size

Revision Plain With Sentry Diff
1122a96+dirty 5.15 MiB 6.68 MiB 1.53 MiB
9210ae6+dirty 5.15 MiB 6.68 MiB 1.53 MiB
fa21fca+dirty 4.98 MiB 6.55 MiB 1.57 MiB
5a23c47+dirty 4.98 MiB 6.46 MiB 1.49 MiB
3ce5254+dirty 3.38 MiB 4.76 MiB 1.38 MiB
9474ead+dirty 5.15 MiB 6.71 MiB 1.55 MiB
a2585ce+dirty 4.98 MiB 6.55 MiB 1.57 MiB
7c6200e+dirty 5.08 MiB 6.68 MiB 1.60 MiB
04207c4+dirty 3.38 MiB 4.76 MiB 1.38 MiB
606fb09+dirty 5.15 MiB 6.95 MiB 1.80 MiB

Previous results on branch: fix/feedback-form-over-ios-native-sheet

Startup times

Revision Plain With Sentry Diff
942bc55+dirty 3851.53 ms 1235.09 ms -2616.44 ms

App size

Revision Plain With Sentry Diff
942bc55+dirty 5.15 MiB 6.95 MiB 1.80 MiB

…rlay docs

Address review feedback on the experimental `presentOverNativeModals` option:

- Declare `react-native-screens` as an optional peer dependency (matching the
  existing `@react-navigation/native` pattern) so the optional `require` resolves
  under strict / Yarn PnP resolvers instead of silently falling back to `Modal`.
- Extend the documented limitation: over a presented native-stack sheet, both
  screenshot attachment flows are limited — the library picker ("Add a
  screenshot") is behind the overlay, and "Take a screenshot" reveals its capture
  button in the root tree behind the sheet.

Signed-off-by: Antonis Lilis <antonis.lilis@sentry.io>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feedback form doesn't open on iOS while a native-stack sheet is presented

1 participant