[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>
This commit is contained in:
Hailey
2024-10-04 13:24:12 -07:00
committed by GitHub
parent 9802ebe20d
commit 00486e9499
86 changed files with 2509 additions and 1577 deletions
+100
View File
@@ -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>
)
}
}
@@ -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
}
@@ -0,0 +1,5 @@
import {BottomSheetViewProps} from './BottomSheet.types'
export function BottomSheet(_: BottomSheetViewProps) {
throw new Error('BottomSheetView is not available on web')
}