3

I am having difficulty in placing any UI element with fixed position(float) over a react native modal where modal content exceeds the screen hight. A similar issue happens with flash message/snack bar etc. They are rendered at the top/bottom of the modal content(not visible if you have scrolled) instead of them showing up at the top/bottom of the page. I created an example using FAB of react-native-paper to demonstrate this. Link here - https://snack.expo.io/PnX5RCE1_?

Sample code:

import * as React from 'react';
import { StyleSheet, View, Modal } from 'react-native';
import { FAB } from 'react-native-paper';
import { Container, Header, Body, Title, Content, ListItem, Text, Icon, Right } from 'native-base';

const renderModal = () : React.ReactElement<any> => {
    return(
      <Modal
        animationType="fade"
        visible={true}>
        <Container>
            <Header>
                <Body>
                    <Title>Alert</Title>
                </Body>
                <Right>
                  <Icon name="closecircleo" type="AntDesign"></Icon>
                </Right>
            </Header>
            <Content style={{padding: 10}}>
              <Text>Adding a lot of text to make the modal content go out of screen height</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text><Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text><Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text><Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <Text>Some Text Here</Text>
              <FAB
                style={styles.fab}
                small
                icon="plus"
                onPress={() => console.log('Pressed')}
              />
            </Content>
        </Container>
      </Modal>
    );
  }

const MyComponent = () => (
  <View>
    {renderModal()}
  </View>
);

const styles = StyleSheet.create({
  fab: {
    position: 'absolute',
    margin: 16,
    right: 0,
    bottom: 0,
  },
})

export default MyComponent;
int-i
  • 661
  • 1
  • 12
  • 28

1 Answers1

2

As you noted yourself, Content exceeds screen height. Since FAB is it's child, it is positioned relative to the total size of Content, not the size of the screen. You should move the FAB up in your view hierarchy:

{...}
            <Text>Some Text Here</Text>
          </Content>
          <FAB
            style={styles.fab}
            small
            icon="plus"
            onPress={() => console.log('Pressed')}
          />
        </Container>
{...}
Marek Lisik
  • 2,003
  • 1
  • 8
  • 17
  • Thought of that idea. Unfortunately, I structured the `````` to have another Functional Component loading in it, thus forcing me to pass down ref to FAB down to the Functional Component. – int-i Mar 28 '21 at 21:16
  • See a case I created here showing nesting of components in a real app: https://snack.expo.io/7s8ZavQ8r – int-i Mar 28 '21 at 21:36
  • In the snack, I do not see where the FAB is used (there is no source for CustomComponent) (also - FYI, the snack does not compile). – Marek Lisik Mar 29 '21 at 10:15
  • I think you should still strive to have the FAB top level, since this better reflects the view hierarchy. If it is hidden in a subview somewhere, it might, for example, be obscured by another view you add at some point, which is not something you want. That said, if you feel that you absolutely have to render it under a child of Content somewhere, you still can calculate the position for it by using the Dimensions module (`const { height } = Dimensions.get('window');` and then in your style `top: height - {calculate FAB height}` – Marek Lisik Mar 29 '21 at 10:19
  • Thanks for the suggestion. Eventually, I ended up doing that- Along with Moving react-native Modal's whole content(including header, etc) into the child component. Appreciate your help. – int-i Mar 29 '21 at 14:23