about summary refs log tree commit diff
path: root/modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-10-09 21:30:42 +0300
committerGitHub <noreply@github.com>2024-10-09 11:30:42 -0700
commitcca344a3d1cdca3d4e63806a9bd5f7867f8961d4 (patch)
tree999d7dffe5d53989b7e217db13f451c6d019ff57 /modules/bottom-sheet/src/BottomSheetNativeComponent.tsx
parentb3ade19bbe3da3caf07bf9561cebb11dac4b6afc (diff)
downloadvoidsky-cca344a3d1cdca3d4e63806a9bd5f7867f8961d4.tar.zst
Allow nested sheets without boilerplate (#5660)
Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'modules/bottom-sheet/src/BottomSheetNativeComponent.tsx')
-rw-r--r--modules/bottom-sheet/src/BottomSheetNativeComponent.tsx103
1 files changed, 103 insertions, 0 deletions
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>
+    )
+  }
+}