React-native-ui-kitten: Modal doesn't work properly

Created on 2 Jul 2019  Â·  8Comments  Â·  Source: akveo/react-native-ui-kitten

Issue type

I'm submitting a ... (check one with "x")

  • [x] bug report
  • [ ] feature request

Issue description

Current behavior:
Modal won't show up unless set isBackDropAllowed to true

Expected behavior:
Modal should show up.

Steps to reproduce:
Set up Modal to be like.. ApplicationProvider > Layout > Modal but it's not showing. Found out adding isBackDropAllowed will display it.

Related code:

export class HomeScreen extends React.Component {
  // ... incomplete code snippet
  styles = StyleSheet.create({
    container: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      padding: 20
    },
    text: {
      marginVertical: 16,
    },
    modalBackdrop: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: '#000000AA',
      padding: 20,
      alignSelf: 'stretch'
    },
    modalInner: {
      backgroundColor: 'white',
      padding: 40,
      paddingTop: 32,
      paddingBottom: 16,
      borderRadius: 10,
    }
  });

  render() {
    return (
        <ApplicationProvider mapping={mapping} theme={lightTheme}>
          <Layout style={this.styles.container} level='4'>
            <Text style={this.styles.text} category='h5'>...</Text>
            <Input label={"Type in here"} multiline height={120}/>
            <Button size={"small"} style={{"marginTop":20}}>Send!</Button>
            <Modal
                visible={this.state.modalVisible}
                isBackDropAllowed
                style={this.styles.modalBackdrop}
            >
              <Layout>
                <View style={this.styles.modalInner}>
                  <Text style={{'textAlign':'center'}}>...</Text>
                  <Button size={"small"} style={{"marginTop":20}}>...</Button>
                  <Button appearance="ghost" size={"small"} style={{"marginTop":5,"paddingBottom":0}}>...</Button>
                </View>
              </Layout>
            </Modal>
          </Layout>
        </ApplicationProvider>
    )
  }
}

Other information:

OS, device, package version

OS: MacOS
Device: Expo + xCode Emulator
Help wanted Components

All 8 comments

Hi @chenxian352! Thanks a lot for your report.
Let me explain this in a bit more detail:

  • The modal component was originally conceived to solve the internal tasks of the framework, so there may be some misunderstandings on how to use it.
  • We are going to remove ModalComponent from the list of exports in a future release.
  • At the moment you can use ModalService for this purpose. Further the code sample:
import React from 'react';
import {
  View,
  ScaledSize,
  Dimensions,
} from 'react-native';
import {
  ThemedComponentProps,
  ThemeType,
  withStyles,
} from '@kitten/theme';
import {
  Input,
  Text,
  Layout,
  Button,
} from '@kitten/ui';
import {
  ModalService,
  ModalComponentCloseProps,
} from '@kitten/theme';

export type ModalShowcaseProps = ThemedComponentProps;

class ModalShowcaseComponent extends React.Component<ModalShowcaseProps> {

  private modalId: string = '';

  private setModalVisible = (): void => {
    const modal: React.ReactElement<ModalComponentCloseProps> = this.renderModal();
    // second param if the function is param that allows or not close modal on backDrop
    this.modalId = ModalService.show(modal, true);
  };

  private setModalInvisible = (): void => {
    ModalService.hide(this.modalId);
  };

  private renderModal = (): React.ReactElement<ModalComponentCloseProps> => {
    const { themedStyle } = this.props;

    return (
      <View style={themedStyle.modal}>
        <Text style={themedStyle.modalText}>Modal Content Text</Text>
        <Button
          size='small'
          style={themedStyle.modalButton}
          onPress={this.setModalInvisible}>
          Hide Modal
        </Button>
      </View>
    );
  };

  public render(): React.ReactNode {
    const { themedStyle } = this.props;

    return (
      <Layout style={themedStyle.container} level='4'>
        <Text
          style={themedStyle.text}
          category='h5'>
          Some Text
        </Text>
        <Input
          label='Type in here'
          multiline
          style={themedStyle.input}
        />
        <Button
          size='small'
          style={themedStyle.button}
          onPress={this.setModalVisible}>
          Show Modal
        </Button>
      </Layout>
    );
  }
}

export const ModalShowcase = withStyles(ModalShowcaseComponent, (theme: ThemeType) => {
  const dimensions: ScaledSize = Dimensions.get('window');
  const contentWidth: number = dimensions.width - 24;
  const contentHeight: number = 192;

  return {
    container: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      padding: 20,
    },
    text: {
      marginVertical: 16,
    },
    input: {
      height: 120,
    },
    button: {
      marginTop: 20,
    },
    modal: {
      zIndex: 1,
      justifyContent: 'space-between',
      padding: 24,
      width: contentWidth,
      height: contentHeight,
      borderRadius: 12,
      top: (dimensions.height - contentHeight) / 2,
      left: (dimensions.width - contentWidth) / 2,
      backgroundColor: theme['background-basic-color-1'],
    },
    modalText: {
      textAlign: 'center',
    },
    modalButton: {
      marginTop: 20,
    },
  };
});

Please note that at this point you will have to manually specify the positioning of the modal window:

{
  top: (dimensions.height - contentHeight) / 2,
  left: (dimensions.width - contentWidth) / 2,
}

In future releases, we are going to add the default behavior of this method (positioning in the center of the screen).

I got the same problem from using the example code from the https://akveo.github.io/react-native-ui-kitten/docs/components/modal/overview#modal.
Did you mean I should make ModalShowcase for myself and not using the Modal component?

Hi @artiya4u 👋
I can't reproduce this issue. What version of UI Kitten do you use?
Also, it would be helpful, if you can provide the code you're trying to run. Thanks

@artyorsh I'm using expo example project from "expo init my-new-project" with tabs and added react-native-ui-kitten v4.2.0 like in Add into existing project . Code in home screen like this:

import React from 'react';
import {
  StyleSheet,
} from 'react-native';

import {Button, Modal, Text, Layout} from 'react-native-ui-kitten';

export default class HomeScreen extends React.Component {
  state = {
    modalVisible: false,
  };

  setModalVisible = () => {
    const modalVisible = !this.state.modalVisible;
    this.setState({ modalVisible });
  };

  renderModalElement = () => {
    return (
      <Layout
        level='3'
        style={styles.modalContainer}>
        <Text>This is modal</Text>
        <Button onPress={this.setModalVisible}>Hide Modal</Button>
      </Layout>
    );
  };

  render() {
    return (
      <Layout style={styles.container}>
        <Button onPress={this.setModalVisible}>Show Modal</Button>
        <Modal
          visible={this.state.modalVisible}>
          {this.renderModalElement()}
        </Modal>
      </Layout>
    );
  }
}

HomeScreen.navigationOptions = {
  header: null,
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  modalContainer: {
    width: 200,
    height: 200,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

My first attempt was a month ago (not sure the version) and it did not show at all.
Now it shows but cannot press the "Hide Modal" button on the modal and it can press the tabs under the modal. Using allowBackdrop={true} will mitigate the issue.

@artiya4u

it can press the tabs under the modal

This is standard behavior of modals in React Native. Isn't it? Use allowBackdrop={true} to prevent outside touches.

cannot press the "Hide Modal" button

Unable to reproduce. See live example on snack

"cannot press the "Hide Modal" button"
Your live example on snack won't work either.
Please check my screen record

@artiya4u @artyorsh same issue here with me also. Any solution???

@imdadturi I use allowBackdrop={true} to workaround.

Was this page helpful?
0 / 5 - 0 ratings