import React, { useRef } from 'react' import { ActivityIndicator } from '../ActivityIndicator' import { View } from '../View' import { useAnimatedVariantStyles } from '../../utils' import { LoadingOverlayProps } from './types' import { MobileStyleRegistry } from '../../Registry' import { AnyRecord, useNestedStylesByKey, IJSX, StyledComponentProps } from '@codeleap/styles' import { useStylesFor } from '../../hooks' export * from './styles' export * from './types' /** * Renders in-place (not in a portal) — it does NOT block touch events on sibling content * outside its own subtree. Position it as a full-screen absolute layer in the style variant * if you need to cover the screen. The visibility transition is driven by Reanimated worklets * via `useAnimatedVariantStyles`; the transition config is snapshotted into a ref on first * render because mutating `styles.transition` after mount has no effect. */ export const LoadingOverlay = (props: LoadingOverlayProps) => { const { children, visible, style, } = { ...LoadingOverlay.defaultProps, ...props } const transition = useRef(null) const styles = useStylesFor(LoadingOverlay.styleRegistryName, style) const loaderStyles = useNestedStylesByKey('loader', styles) const wrapperAnimation = useAnimatedVariantStyles({ variantStyles: styles, animatedProperties: ['wrapper:visible', 'wrapper:hidden'], updater: (s) => { 'worklet' return visible ? s['wrapper:visible'] : s['wrapper:hidden'] }, transition: styles.transition, dependencies: [visible], }) if (!transition.current) { transition.current = JSON.parse(JSON.stringify(styles['wrapper:transition'])) } return ( {children} ) } LoadingOverlay.styleRegistryName = 'LoadingOverlay' LoadingOverlay.elements = ['wrapper', 'loader', 'transition'] LoadingOverlay.rootElement = 'wrapper' LoadingOverlay.defaultProps = {} as Partial LoadingOverlay.withVariantTypes = (styles: S) => { return LoadingOverlay as (props: StyledComponentProps) => IJSX } MobileStyleRegistry.registerComponent(LoadingOverlay)