[Sheets] [Pt. 11] Move native code into repo (#5583)

Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
Hailey
2024-10-02 21:43:54 -07:00
committed by GitHub
parent 4466f68b81
commit 79996ac952
20 changed files with 822 additions and 12 deletions
@@ -0,0 +1,22 @@
import React from 'react'
import {ColorValue, NativeSyntheticEvent} from 'react-native'
export type BottomSheetState = 'closed' | 'closing' | 'open' | 'opening'
export interface BottomSheetViewProps {
children: React.ReactNode
cornerRadius?: number
preventDismiss?: boolean
preventExpansion?: boolean
containerBackgroundColor?: ColorValue
topInset?: number
bottomInset?: number
minHeight?: number
maxHeight?: number
onStateChange?: (
event: NativeSyntheticEvent<{state: BottomSheetState}>,
) => void
onAttemptDismiss?: (event: NativeSyntheticEvent<object>) => void
}
@@ -0,0 +1,104 @@
import * as React from 'react'
import {
ColorValue,
Dimensions,
NativeSyntheticEvent,
StyleProp,
StyleSheet,
View,
ViewStyle,
} from 'react-native'
import {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')
export class BottomSheetView 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 getBackgroundColor = (): ColorValue | undefined => {
const parent = React.Children.toArray(
this.props.children,
)[0] as React.ReactElement
if (parent?.props?.style) {
const parentStyle = StyleSheet.flatten(parent.props.style) as ViewStyle
return parentStyle.backgroundColor ?? 'transparent'
}
return undefined
}
private updateLayout = () => {
this.ref.current?.updateLayout()
}
render() {
const {children, ...rest} = this.props
const topInset = rest.topInset ?? 0
const bottomInset = rest.bottomInset ?? 0
if (!this.state.open) {
return null
}
const backgroundColor = this.getBackgroundColor()
return (
<NativeView
{...rest}
onStateChange={this.onStateChange}
ref={this.ref}
style={{
position: 'absolute',
height: screenHeight - topInset - bottomInset,
width: '100%',
}}
containerBackgroundColor={backgroundColor}>
<View
style={{
flex: 1,
backgroundColor,
paddingTop: topInset,
paddingBottom: bottomInset,
}}>
<View onLayout={this.updateLayout}>{children}</View>
</View>
</NativeView>
)
}
}
@@ -0,0 +1,5 @@
import {BottomSheetViewProps} from './BottomSheet.types'
export function BottomSheetView(_: BottomSheetViewProps) {
throw new Error('BottomSheetView is not available on web')
}