[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:
@@ -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')
|
||||
}
|
||||
Reference in New Issue
Block a user