import * as React from 'react'; import { useMemo } from 'react'; import { StyleSheet, View, ViewStyle, useWindowDimensions } from 'react-native'; import { IconButton, Surface, Text } from 'react-native-paper'; import { themeStyle } from './global-style'; import Modal from './Modal'; import { _ } from '@joplin/lib/locale'; export enum DialogVariant { // Small width, auto-determined height SmallResize = 'small-resize', Small = 'small', // Ideal for panels and dialogs that should be fullscreen even on large devices Large = 'large', } interface Props { themeId: number; visible: boolean; onDismiss: ()=> void; containerStyle?: ViewStyle; children: React.ReactNode; heading?: string; scrollOverflow?: boolean; useNativeModal?: boolean; inert?: boolean; size: DialogVariant; } const useStyles = (themeId: number, containerStyle: ViewStyle, size: DialogVariant) => { const windowSize = useWindowDimensions(); return useMemo(() => { const theme = themeStyle(themeId); const maxWidth = size === DialogVariant.Large ? windowSize.width : 500; const maxHeight = size === DialogVariant.Large ? windowSize.height : 700; const dialogSizing: ViewStyle = { width: '100%', ...(size !== DialogVariant.SmallResize ? { height: '100%', } : { }), }; return StyleSheet.create({ closeButtonRow: { flexDirection: 'row', justifyContent: 'space-between', alignContent: 'center', marginBottom: 8, }, closeButtonRowWithHeading: { marginBottom: 16, }, closeButton: { margin: 0, marginRight: -8, }, // Ensure that the close button is aligned with the center of the header: // Make its container smaller and center it. closeButtonWrapper: { height: 18, flexDirection: 'column', justifyContent: 'center', alignSelf: 'center', }, heading: { // Without flexShrink/flexGrow, the heading can push the close button // outside of the dialog. flexShrink: 1, flexGrow: 1, }, modalBackground: { justifyContent: 'center', }, dialogContainer: { maxHeight, maxWidth, ...dialogSizing, // Center marginLeft: 'auto', marginRight: 'auto', paddingLeft: 6, paddingRight: 6, ...containerStyle, }, dialogSurface: { borderRadius: 24, backgroundColor: theme.backgroundColor, paddingHorizontal: theme.margin, paddingVertical: theme.margin, ...dialogSizing, }, }); }, [themeId, windowSize.width, windowSize.height, containerStyle, size]); }; const DismissibleDialog: React.FC = props => { const theme = themeStyle(props.themeId); const styles = useStyles(props.themeId, props.containerStyle, props.size); const heading = props.heading ? ( {props.heading} ) : null; const closeButtonRow = ( {heading ?? } ); return ( {closeButtonRow} {props.children} ); }; export default DismissibleDialog;