import React, { createContext, FunctionComponent, PropsWithChildren, useContext, } from 'react'; import { StyleProp, StyleSheet, View, ViewStyle, ActivityIndicator, } from 'react-native'; import useModal from '../../hooks/useModal'; import useTheme from '../theme/useTheme'; import { Text } from '../../components/Text'; export type OverlayComponentProps = PropsWithChildren<{ style?: StyleProp; }>; export type LoadingComponentProps = PropsWithChildren<{ onVisible: () => void; onHidden: () => void; isOpen: boolean; }>; export type ScreenLoadingProps = { isOpen: boolean; onVisible: () => void; onHidden: () => void; OverlayComponent: FunctionComponent; LoadingComponent: FunctionComponent; }; const ScreenLoadingContext = createContext< Pick >({ isOpen: false, onVisible: () => {}, onHidden: () => {}, }); const DummyOverlay: FunctionComponent = (props) => ( ); const DummyLoadingComponent: FunctionComponent = ( props ) => { const { colors, zIndices } = useTheme(); return ( Loading... ); }; export type ScreenLoadingProviderProps = Partial< Pick > & { initialIsOpen?: boolean; }; export function ScreenLoadingProvider({ children, initialIsOpen, OverlayComponent = DummyOverlay, LoadingComponent = DummyLoadingComponent, }: PropsWithChildren) { const theme = useTheme(); const [isOpen, _, { onVisible, onHidden }] = useModal(initialIsOpen); return ( {isOpen && ( )} {children} ); } export function useScreenLoading() { return useContext(ScreenLoadingContext); } const styles = StyleSheet.create({ wrapper: { flex: 1, position: 'absolute', justifyContent: 'center', alignItems: 'center', top: 0, left: 0, }, overlay: { flex: 1, width: '100%', height: '100%', position: 'absolute', justifyContent: 'center', alignItems: 'center', top: 0, left: 0, }, content: { alignItems: 'center', gap: 10, padding: 20, borderRadius: 10, }, });