about summary refs log tree commit diff
path: root/modules/bottom-sheet/src
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-10-04 13:24:12 -0700
committerGitHub <noreply@github.com>2024-10-04 13:24:12 -0700
commit00486e94991f344353ffb083dd631283a84c3ad3 (patch)
treea5dc4da5e5e71912d73a099e84761517fa8c62a9 /modules/bottom-sheet/src
parent9802ebe20d32dc1867a069dc377b3d4c43ce45f0 (diff)
downloadvoidsky-00486e94991f344353ffb083dd631283a84c3ad3.tar.zst
[Sheets] [Pt. 1] Root PR (#5557)
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: dan <dan.abramov@gmail.com>
Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'modules/bottom-sheet/src')
-rw-r--r--modules/bottom-sheet/src/BottomSheet.tsx100
-rw-r--r--modules/bottom-sheet/src/BottomSheet.types.ts35
-rw-r--r--modules/bottom-sheet/src/BottomSheet.web.tsx5
3 files changed, 140 insertions, 0 deletions
diff --git a/modules/bottom-sheet/src/BottomSheet.tsx b/modules/bottom-sheet/src/BottomSheet.tsx
new file mode 100644
index 000000000..9e7d0c209
--- /dev/null
+++ b/modules/bottom-sheet/src/BottomSheet.tsx
@@ -0,0 +1,100 @@
+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'
+
+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 BottomSheet 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}>{children}</View>
+        </View>
+      </NativeView>
+    )
+  }
+}
diff --git a/modules/bottom-sheet/src/BottomSheet.types.ts b/modules/bottom-sheet/src/BottomSheet.types.ts
new file mode 100644
index 000000000..150932d42
--- /dev/null
+++ b/modules/bottom-sheet/src/BottomSheet.types.ts
@@ -0,0 +1,35 @@
+import React from 'react'
+import {ColorValue, NativeSyntheticEvent} from 'react-native'
+
+export type BottomSheetState = 'closed' | 'closing' | 'open' | 'opening'
+
+export enum BottomSheetSnapPoint {
+  Hidden,
+  Partial,
+  Full,
+}
+
+export type BottomSheetAttemptDismissEvent = NativeSyntheticEvent<object>
+export type BottomSheetSnapPointChangeEvent = NativeSyntheticEvent<{
+  snapPoint: BottomSheetSnapPoint
+}>
+export type BottomSheetStateChangeEvent = NativeSyntheticEvent<{
+  state: BottomSheetState
+}>
+
+export interface BottomSheetViewProps {
+  children: React.ReactNode
+  cornerRadius?: number
+  preventDismiss?: boolean
+  preventExpansion?: boolean
+  backgroundColor?: ColorValue
+  containerBackgroundColor?: ColorValue
+  disableDrag?: boolean
+
+  minHeight?: number
+  maxHeight?: number
+
+  onAttemptDismiss?: (event: BottomSheetAttemptDismissEvent) => void
+  onSnapPointChange?: (event: BottomSheetSnapPointChangeEvent) => void
+  onStateChange?: (event: BottomSheetStateChangeEvent) => void
+}
diff --git a/modules/bottom-sheet/src/BottomSheet.web.tsx b/modules/bottom-sheet/src/BottomSheet.web.tsx
new file mode 100644
index 000000000..4573604eb
--- /dev/null
+++ b/modules/bottom-sheet/src/BottomSheet.web.tsx
@@ -0,0 +1,5 @@
+import {BottomSheetViewProps} from './BottomSheet.types'
+
+export function BottomSheet(_: BottomSheetViewProps) {
+  throw new Error('BottomSheetView is not available on web')
+}