diff --git a/native/components/loadable-button.react.js b/native/components/loadable-button.react.js new file mode 100644 --- /dev/null +++ b/native/components/loadable-button.react.js @@ -0,0 +1,80 @@ +// @flow + +import * as React from 'react'; +import { View, ActivityIndicator } from 'react-native'; + +import Button from './button.react.js'; +import { useStyles, useColors } from '../themes/colors.js'; + +type LoadableContentProps = { + +children: React.Node, + +isLoading: boolean, +}; + +function LoadableContent(props: LoadableContentProps): React.Node { + const { children, isLoading } = props; + + const styles = useStyles(unboundStyles); + const colors = useColors(); + + const buttonContentContainerStyles = React.useMemo(() => { + const result = [styles.container]; + + if (isLoading) { + result.push(styles.containerLoading); + } + + return result; + }, [isLoading, styles.container, styles.containerLoading]); + + const loadingSpinner = React.useMemo(() => { + if (!isLoading) { + return null; + } + + return ( + + ); + }, [colors.whiteText, isLoading, styles.loadingSpinner]); + + return ( + <> + {children} + {loadingSpinner} + + ); +} + +type Props = { + ...React.ElementConfig, + +isLoading: boolean, +}; + +function LoadableButton(props: Props): React.Node { + const { isLoading, children, ...rest } = props; + + return ( + + ); +} + +const unboundStyles = { + container: { + flexDirection: 'row', + alignItems: 'center', + }, + containerLoading: { + opacity: 0, + }, + loadingSpinner: { + position: 'absolute', + }, +}; + +export default LoadableButton;