From cca344a3d1cdca3d4e63806a9bd5f7867f8961d4 Mon Sep 17 00:00:00 2001
From: Samuel Newman <mozzius@protonmail.com>
Date: Wed, 9 Oct 2024 21:30:42 +0300
Subject: Allow nested sheets without boilerplate (#5660)

Co-authored-by: Hailey <me@haileyok.com>
---
 .../src/BottomSheetNativeComponent.tsx             | 103 +++++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 modules/bottom-sheet/src/BottomSheetNativeComponent.tsx

(limited to 'modules/bottom-sheet/src/BottomSheetNativeComponent.tsx')

diff --git a/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx b/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
new file mode 100644
index 000000000..eadd9b4a1
--- /dev/null
+++ b/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
@@ -0,0 +1,103 @@
+import * as React from 'react'
+import {
+  Dimensions,
+  NativeSyntheticEvent,
+  Platform,
+  StyleProp,
+  View,
+  ViewStyle,
+} from 'react-native'
+import {requireNativeModule, requireNativeViewManager} from 'expo-modules-core'
+
+import {BottomSheetState, BottomSheetViewProps} from './BottomSheet.types'
+import {BottomSheetPortalProvider} from './BottomSheetPortal'
+
+const screenHeight = Dimensions.get('screen').height
+
+const NativeView: React.ComponentType<
+  BottomSheetViewProps & {
+    ref: React.RefObject<any>
+    style: StyleProp<ViewStyle>
+  }
+> = requireNativeViewManager('BottomSheet')
+
+const NativeModule = requireNativeModule('BottomSheet')
+
+export class BottomSheetNativeComponent extends React.Component<
+  BottomSheetViewProps,
+  {
+    open: boolean
+  }
+> {
+  ref = React.createRef<any>()
+
+  constructor(props: BottomSheetViewProps) {
+    super(props)
+    this.state = {
+      open: false,
+    }
+  }
+
+  present() {
+    this.setState({open: true})
+  }
+
+  dismiss() {
+    this.ref.current?.dismiss()
+  }
+
+  private onStateChange = (
+    event: NativeSyntheticEvent<{state: BottomSheetState}>,
+  ) => {
+    const {state} = event.nativeEvent
+    const isOpen = state !== 'closed'
+    this.setState({open: isOpen})
+    this.props.onStateChange?.(event)
+  }
+
+  private updateLayout = () => {
+    this.ref.current?.updateLayout()
+  }
+
+  static dismissAll = async () => {
+    await NativeModule.dismissAll()
+  }
+
+  render() {
+    const {children, backgroundColor, ...rest} = this.props
+    const cornerRadius = rest.cornerRadius ?? 0
+
+    if (!this.state.open) {
+      return null
+    }
+
+    return (
+      <NativeView
+        {...rest}
+        onStateChange={this.onStateChange}
+        ref={this.ref}
+        style={{
+          position: 'absolute',
+          height: screenHeight,
+          width: '100%',
+        }}
+        containerBackgroundColor={backgroundColor}>
+        <View
+          style={[
+            {
+              flex: 1,
+              backgroundColor,
+            },
+            Platform.OS === 'android' && {
+              borderTopLeftRadius: cornerRadius,
+              borderTopRightRadius: cornerRadius,
+            },
+          ]}>
+          <View onLayout={this.updateLayout}>
+            <BottomSheetPortalProvider>{children}</BottomSheetPortalProvider>
+          </View>
+        </View>
+      </NativeView>
+    )
+  }
+}
-- 
cgit 1.4.1

