From 9bcc9799f35ecfb502c83f67300b29eec3c5919d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Boro=C5=84?= Date: Fri, 24 Apr 2026 10:42:18 +0200 Subject: [PATCH 01/82] Prepare JS component and native spec --- .../gamma/form-sheet/ModalFormSheet.tsx | 29 +++++++++++++++++++ .../gamma/form-sheet/ModalFormSheet.types.ts | 20 +++++++++++++ src/components/gamma/form-sheet/index.ts | 3 ++ src/experimental/index.ts | 1 + .../ModalFormSheetNativeComponent.ts | 17 +++++++++++ 5 files changed, 70 insertions(+) create mode 100644 src/components/gamma/form-sheet/ModalFormSheet.tsx create mode 100644 src/components/gamma/form-sheet/ModalFormSheet.types.ts create mode 100644 src/components/gamma/form-sheet/index.ts create mode 100644 src/fabric/gamma/form-sheet/ModalFormSheetNativeComponent.ts diff --git a/src/components/gamma/form-sheet/ModalFormSheet.tsx b/src/components/gamma/form-sheet/ModalFormSheet.tsx new file mode 100644 index 0000000000..5d454d4a64 --- /dev/null +++ b/src/components/gamma/form-sheet/ModalFormSheet.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { StyleSheet } from 'react-native'; +import ModalFormSheetNativeComponent from '../../../fabric/gamma/form-sheet/ModalFormSheetNativeComponent'; +import type { ModalFormSheetProps } from './ModalFormSheet.types'; + +export function ModalFormSheet(props: ModalFormSheetProps) { + const { isOpen, detents, onDismiss, children, style, ...rest } = props; + + return ( + + {children} + + ); +} + +const styles = StyleSheet.create({ + host: { + position: 'absolute', + top: 0, + left: 0, + width: 0, + height: 0, + }, +}); diff --git a/src/components/gamma/form-sheet/ModalFormSheet.types.ts b/src/components/gamma/form-sheet/ModalFormSheet.types.ts new file mode 100644 index 0000000000..88355779b4 --- /dev/null +++ b/src/components/gamma/form-sheet/ModalFormSheet.types.ts @@ -0,0 +1,20 @@ +import type { ViewProps } from 'react-native'; + +export interface ModalFormSheetProps extends ViewProps { + /** + * Controls whether the sheet is currently presented or dismissed. + */ + isOpen: boolean; + + /** + * Array of fractional heights [0..1] that map to `UISheetPresentationController` detents. + * For example, `[0.5, 1.0]` creates a medium and a large detent. + */ + detents?: number[] | undefined; + + /** + * Called when the user interactively dismisses the sheet (e.g., by swiping it down). + * Use this to sync your local state (`isOpen = false`). + */ + onDismiss?: (() => void) | undefined; +} diff --git a/src/components/gamma/form-sheet/index.ts b/src/components/gamma/form-sheet/index.ts new file mode 100644 index 0000000000..d11819ce68 --- /dev/null +++ b/src/components/gamma/form-sheet/index.ts @@ -0,0 +1,3 @@ +export type { ModalFormSheetProps } from './ModalFormSheet.types'; + +export { ModalFormSheet } from './ModalFormSheet'; diff --git a/src/experimental/index.ts b/src/experimental/index.ts index 90718b377f..e8dd94b153 100644 --- a/src/experimental/index.ts +++ b/src/experimental/index.ts @@ -9,3 +9,4 @@ export * from '../components/gamma/stack'; export * from '../components/gamma/split'; export * from '../components/safe-area'; export * from '../components/gamma/scroll-view-marker'; +export * from '../components/gamma/form-sheet'; diff --git a/src/fabric/gamma/form-sheet/ModalFormSheetNativeComponent.ts b/src/fabric/gamma/form-sheet/ModalFormSheetNativeComponent.ts new file mode 100644 index 0000000000..48e973c775 --- /dev/null +++ b/src/fabric/gamma/form-sheet/ModalFormSheetNativeComponent.ts @@ -0,0 +1,17 @@ +'use client'; + +import type { CodegenTypes as CT, ViewProps } from 'react-native'; +import { codegenNativeComponent } from 'react-native'; + +// eslint-disable-next-line @typescript-eslint/ban-types +type GenericEmptyEvent = Readonly<{}>; + +interface NativeProps extends ViewProps { + isOpen?: CT.WithDefault; + detents?: readonly CT.Double[] | undefined; + onDismiss?: CT.DirectEventHandler | undefined; +} + +export default codegenNativeComponent('RNSModalFormSheet', { + excludedPlatforms: ['android'], +}); From 95e871114a4f8290095a7517739e7b4e350a8798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Boro=C5=84?= Date: Fri, 24 Apr 2026 10:54:21 +0200 Subject: [PATCH 02/82] Temporarly update app --- FabricExample/App.tsx | 63 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/FabricExample/App.tsx b/FabricExample/App.tsx index e5d153146f..4ee63259be 100644 --- a/FabricExample/App.tsx +++ b/FabricExample/App.tsx @@ -1,14 +1,53 @@ -import App from '../apps'; -import { featureFlags } from 'react-native-screens'; +import React, { useState } from 'react'; +import { View, Text, Button, StyleSheet } from 'react-native'; +import { + ModalFormSheet, + SafeAreaView, +} from 'react-native-screens/experimental'; -featureFlags.experiment.synchronousScreenUpdatesEnabled = false; -featureFlags.experiment.synchronousHeaderConfigUpdatesEnabled = false; -featureFlags.experiment.synchronousHeaderSubviewUpdatesEnabled = false; -featureFlags.experiment.androidResetScreenShadowStateOnOrientationChangeEnabled = - true; -featureFlags.experiment.iosPreventReattachmentOfDismissedScreens = true; -featureFlags.experiment.iosPreventReattachmentOfDismissedModals = true; -featureFlags.experiment.ios26AllowInteractionsDuringTransition = true; -featureFlags.stable.debugLogging = true; +export default function TestModalFormSheet() { + const [isOpen, setIsOpen] = useState(false); -export default App; + return ( + + ModalFormSheet Test +