DEV Community

Emerson Vieira
Emerson Vieira

Posted on • Edited on

Menu PopUp/Suspenso usando React Native

Hoje vamos aprender a como criar um menu suspenso/menu popup usando React Native. Você já deve ter se deparado com aquele menu com três pontinhos no Android.

PopUpMenu

Precisei implementar esse tipo de componente em um projeto e o React Native não o possui por padrão, mas por sorte há um método em um carinha chamado UIManager.java class que nos permite criar esse componente.

O código deste tutorial segue abaixo:

PopUpMenu

import React, { Component } from "react";
import {
  View,
  UIManager,
  findNodeHandle,
  TouchableOpacity,
} from "react-native";
import Icon from "react-native-vector-icons/MaterialIcons";
import PropTypes from "prop-types";

const ICON_SIZE = 24;

export default class PopupMenu extends Component {
  static propTypes = {
    actions: PropTypes.arrayOf(PropTypes.string).isRequired,
    onPress: PropTypes.func.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      icon: null,
    };
  }

  onError() {
    console.log("Popup Error");
  }

  onPress = () => {
    if (this.state.icon) {
      UIManager.showPopupMenu(
        findNodeHandle(this.state.icon),
        this.props.actions,
        this.onError,
        this.props.onPress
      );
    }
  };
  render() {
    return (
      <View>
        <TouchableOpacity onPress={this.onPress}>
          <Icon
            name="more-vert"
            size={ICON_SIZE}
            color={"red"}
            ref={this.onRef}
          />
        </TouchableOpacity>
      </View>
    );
  }
  onRef = (icon) => {
    if (!this.state.icon) {
      this.setState({ icon });
    }
  };
}
Enter fullscreen mode Exit fullscreen mode

Tela usando o componente PopUpMenu

import React from "react";
import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  StatusBar,
} from "react-native";

import {
  Header,
  LearnMoreLinks,
  Colors,
  DebugInstructions,
  ReloadInstructions,
} from "react-native/Libraries/NewAppScreen";

import PopUp from "./src/components/PopUp/index";

const App: () => React$Node = () => {
  const onPopupEvent = (eventName, index) => {
    if (eventName !== "itemSelected") return;
    if (index === 0) console.log("PopUpMenu");
  };

  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={styles.scrollView}
        >
          <Header />
          {global.HermesInternal == null ? null : (
            <View style={styles.engine}>
              <Text style={styles.footer}>Engine: Hermes</Text>
            </View>
          )}
          <View style={styles.body}>
            <View style={styles.sectionContainer}>
              <PopUp actions={["PopUpMenu"]} onPress={onPopupEvent} />
            </View>

            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>See Your Changes</Text>
              <Text style={styles.sectionDescription}>
                <ReloadInstructions />
              </Text>
            </View>

            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Debug</Text>
              <Text style={styles.sectionDescription}>
                <DebugInstructions />
              </Text>
            </View>

            <View style={styles.sectionContainer}>
              <Text style={styles.sectionTitle}>Learn More</Text>
              <Text style={styles.sectionDescription}>
                Read the docs to discover what to do next:
              </Text>
            </View>
            <LearnMoreLinks />
          </View>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

const styles = StyleSheet.create({
  scrollView: {
    backgroundColor: Colors.lighter,
  },
  engine: {
    position: "absolute",
    right: 0,
  },
  body: {
    backgroundColor: Colors.white,
  },
  sectionContainer: {
    marginTop: 32,
    paddingHorizontal: 24,
  },
  sectionTitle: {
    fontSize: 24,
    fontWeight: "600",
    color: Colors.black,
  },

  sectionDescription: {
    marginTop: 8,
    fontSize: 18,
    fontWeight: "400",
    color: Colors.dark,
  },
  highlight: {
    fontWeight: "700",
  },
  footer: {
    color: Colors.dark,
    fontSize: 12,
    fontWeight: "600",
    padding: 4,
    paddingRight: 12,
    textAlign: "right",
  },
});

export default App;
Enter fullscreen mode Exit fullscreen mode

É isso. Até a próxima :)

Link do Projeto

Top comments (0)