UNPKG

1.72 kBTypeScriptView Raw
1import * as React from 'react';
2import { StyleSheet, View, ViewProps } from 'react-native';
3
4type Props = ViewProps & {
5 enabled: boolean;
6 layout: { width: number; height: number };
7 children: React.ReactNode;
8};
9
10export type CardSheetRef = {
11 setPointerEvents: React.Dispatch<ViewProps['pointerEvents']>;
12};
13
14// This component will render a page which overflows the screen
15// if the container fills the body by comparing the size
16// This lets the document.body handle scrolling of the content
17// It's necessary for mobile browsers to be able to hide address bar on scroll
18export default React.forwardRef<CardSheetRef, Props>(function CardSheet(
19 { enabled, layout, style, ...rest },
20 ref
21) {
22 const [fill, setFill] = React.useState(false);
23 // To avoid triggering a rerender in Card during animation we had to move
24 // the state to CardSheet. The `setPointerEvents` is then hoisted back to the Card.
25 const [pointerEvents, setPointerEvents] =
26 React.useState<ViewProps['pointerEvents']>('auto');
27
28 React.useImperativeHandle(ref, () => {
29 return { setPointerEvents };
30 });
31
32 React.useEffect(() => {
33 if (typeof document === 'undefined' || !document.body) {
34 // Only run when DOM is available
35 return;
36 }
37
38 const width = document.body.clientWidth;
39 const height = document.body.clientHeight;
40
41 setFill(width === layout.width && height === layout.height);
42 }, [layout.height, layout.width]);
43
44 return (
45 <View
46 {...rest}
47 pointerEvents={pointerEvents}
48 style={[enabled && fill ? styles.page : styles.card, style]}
49 />
50 );
51});
52
53const styles = StyleSheet.create({
54 page: {
55 minHeight: '100%',
56 },
57 card: {
58 flex: 1,
59 overflow: 'hidden',
60 },
61});