instea / react-native-popup-menu Goto Github PK
View Code? Open in Web Editor NEWPopup menu component for React Native
License: ISC License
Popup menu component for React Native
License: ISC License
Seems like the MenuTrigger is hard-coded to use TouchableHighlight. Would be great if the option was given to the developer / designer on which Touchable option to use, i.e. Highlight or Opacity. TouchableHighlight does not work for all use-cases, namely solo icons.
i am using this nav bar code i ham fix the pop up menu inside right header bar
<View style={styles.header}>
<View style={styles.leftHeader}>
<TouchableOpacity onPress={this.onBack.bind(this)}>
<Image style={styles.backIcon} source={require('image!backarrow')}/>
</TouchableOpacity>
</View>
<View style={styles.centerHeader}>
<Text style={styles.headerTitle}>X & O's</Text>
</View>
<View style={styles.rightHeader}>**# This is fix how can i fix** ?</View>
</View>
<View style={styles.line}></View>
<View style={styles.body}>
var styles = StyleSheet.create({
container:{
flex:1
},
header:{
flex: 0.1,
flexDirection:'row',
justifyContent:'center',
backgroundColor:'#013369'
},
leftHeader:{
flex:0.2,
justifyContent:'center'
},
centerHeader:{
flex:0.6,
justifyContent:'center',
alignSelf:'center'
},
rightHeader:{
flex:0.2,
justifyContent:'center',
alignSelf:'center'
},
body:{
flex:0.9,
justifyContent:'flex-start',
},
Hi there!
I have a ListView component with cards and a popup menu placed on each card. Let's say I have 10 cards visible at the moment. When I click to open menu it calls Menu's render()
method 40 times (four times on each card I suppose) and then open popup box. Of course performance is low and it looks laggy.
If I scroll to the end of the ListView and all cards become visible extra re-renders no longer occurs.
Issue
onSelect
is mandatory to pass to other wise it gives error.
Debugged Report
MenuOption have a Touchable which take onPress which calls this._onSelect(), In _onSelect definition we are doing
const { value, onSelect } = this.props;
const shouldClose = onSelect(value) !== false;
Here when we don't pass the onSelect to MenuOption second line onSelect gives error onSelect(value) is not a function
Version
Code Snapshot
<Menu onSelect={props.onSelect}>
<MenuTrigger>{props.children}</MenuTrigger>
<MenuOptions>
<MenuOption value=1>One</MenuOption>
</MenuOptions>
</Menu>
Scenario:
I have two controlled popups with a grey backdrop. The first one have some actions, which one of them is opening another popup menu.
When I tried to open the second popup right after the first popup, apparently the second popup doesn't show the grey backdrop.
However, when the second popup is opened independently (not triggered by first popup), the backdrop is appeared normally.
Version:
However, tried with recent version of react-native (0.49.5
) and react-native-popup-menu (0.9.0
) the issue happens as well
Code snippet:
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { MenuContext, Menu, MenuTrigger, MenuOption, MenuOptions, renderers } from 'react-native-popup-menu';
export const FirstPopup = ({ isOpen, closeMenu, openSecond }) => (
<Menu
renderer={renderers.SlideInMenu}
opened={isOpen}
>
<MenuTrigger style={styles.trigger} />
<MenuOptions>
<Text>This is first popup</Text>
<MenuOption onSelect={openSecond} text={'Open Second'} />
<MenuOption onSelect={closeMenu} text={'Close Popup'} />
</MenuOptions>
</Menu>
)
export const SecondPopup = ({ isOpen, closeMenu }) => (
<Menu
renderer={renderers.SlideInMenu}
opened={isOpen}
>
<MenuTrigger style={styles.trigger} />
<MenuOptions>
<Text>This is second popup</Text>
<MenuOption onSelect={closeMenu} text={'Close Popup'} />
</MenuOptions>
</Menu>
)
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
firstOpen: false,
secondOpen: false
}
}
openFirst = () => this.setState({
firstOpen: true,
secondOpen: false
})
openSecond = () => this.setState({
firstOpen: false,
secondOpen: true
})
closeMenu = () => this.setState({
firstOpen: false,
secondOpen: false
})
render() {
return (
<MenuContext customStyles={styles.menuContext}>
<View style={styles.container}>
<Button onPress={this.openFirst} title={'Open First Popup'} />
<Button onPress={this.openSecond} title={'Open Second Popup'} />
</View>
<FirstPopup isOpen={this.state.firstOpen} closeMenu={this.closeMenu} openSecond={this.openSecond} />
<SecondPopup isOpen={this.state.secondOpen} closeMenu={this.closeMenu} />
</MenuContext>
);
}
}
const styles = {
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
menuContext: {
backdrop: {
backgroundColor: '#000',
opacity: 0.6
}
},
trigger: {
height: 0,
width: 0
}
};
Sometimes you can see that menu options jump after they are opened to correct position (ie. towards trigger). Test case:
Hello,
I'm using a map to cycle through an array of menu items, and within this map exists another nested map. Because of this setup, I'm having to enclose the MenuOption elements in a view, and makes calling onSelect fail (undefined). Looking at the source it seems this is because onSelect is passing to the view, not the menu options.
Any nice way to fix this without specifying onSelect manually for each MenuOption?
Here's my code:
<Menu onSelect={(value) => this.setState({ category: value })}>
<MenuTrigger text={ this.state.category.name }/>
<MenuOptions renderOptionsContainer={optionsRenderer}>
{categories['null'].map((cat) => (
<View key={cat.id}>
<MenuOption value={cat.id}>
<CategoryIcon icon={cat.icon}/>
<Text>{cat.name}</Text>
</MenuOption>
{
_.map(categories[cat.id] === undefined ? [] : categories[cat.id], (child) => (
<MenuOption value={child.id} key={child.id}>
<Text> </Text>
<CategoryIcon icon={child.icon}/>
<Text>{child.name}</Text>
</MenuOption>
))}
</View>
))}
</MenuOptions>
</Menu>
//optionsRenderer
const optionsRenderer = (options) => (
<FlatList data={options.props.children} renderItem={({ item }) => React.cloneElement(item, {onSelect: options.props.onSelect})} style={{ height: 200 }} />
);
Is it possible to pass an Icon as prop? Currently, I guess it just accepts strings.
My use-case is a top-right menu for Android, which is usually displayed when clicked on a three-dot-line icon.
I asked this question in stackoverflow
https://stackoverflow.com/questions/44079480/how-to-include-menu-options-with-custom-icons
I want to include menu options with custom icons. Your documentation gives an example with a checkmark but I want more custom icons. What is the best way to go about it? Based on the answer in stackoverflow, I tried the following:
const IconOption = (props) => (
<MenuOption {...props}>
<Icon color={ICON_COLOR} name={props.iconName} size={ICON_SIZE} />
{props.children}
</MenuOption>
);
<MenuOptions customStyles={MenuOptionStyles}>
<IconOption
iconName='md-bookmark'
onSelect={this.onSelectSave.bind(this)}
text={MenuOptionStrings.Save}
/>
</MenuOptions>
But I still see only text in my menu options, don't see the icon. I also tried getting the unicode values for the icons that I need and setting the same way as the CheckedOption in your examples, but the icons don't render, maybe it is some font issue?
For the default renderer and slide renderer, the menu will scale / slide into place when the menu is opened. However, when the menu is closed, the menu will immediately disappear which causes a jarring flash and is not to spec with material design behavior / motion principles.
I'm thinking that these menus need reverse animations, i.e. they should animate out the exact reverse of how they animate in.
Initially my menu item text is black in color.
However, on menu item press, I want the underlayColor to be blue, and text color to be white.
I could achieve the underlayColor to be blue by setting the property in "optionTouchable" in the customStyles for MenuOptions.
How should I change the text color of the menu items on press?
Basic Menu Example doesn't work on Android, giving only the following warning when the Menu Trigger text is pressed:
Probably the same as #41, but I decided to create a new issue since it might not be the same.
Basic menu example works after simple copy-paste.
//...
import { MenuContext } from 'react-native-popup-menu';
//...
class App extends Component {
//...
render() {
//...
return (
<Provider store={store}>
<MenuContext style={{ flex: 1 }}>
<Router />
</MenuContext>
</Provider>
);
}
}
AppRegistry.registerComponent('scDocsMobile', () => App);
export default App;
This component is the initial component on the Router, so it's the first to render when the App boots up.
//...
import {
Menu,
MenuOptions,
MenuOption,
MenuTrigger,
} from 'react-native-popup-menu';
export default class Testing extends Component {
render() {
return (
<View style={styles.container}>
<Text>Hello world!</Text>
<Menu onSelect={value => console.log(`Selected number: ${value}`)}>
<MenuTrigger text='Select option' />
<MenuOptions>
<MenuOption value={1} text='One' />
<MenuOption value={2}>
<Text style={{ color: 'red' }}>Two</Text>
</MenuOption>
<MenuOption value={3} disabled text='Three' />
</MenuOptions>
</Menu>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
MenuTrigger has an outer view but the style is passed to the inner view. This makes the trigger not properly styleable, e.g. using flex properties on the box.
When rotate the screen android, the popup not open, how resolve this?
when i clicked menu trigger,
how can i control the menu default position in the screen?
thanks
Hi guys,
I am facing an issue with popup menu.. everything works fine in iOS but in Android , I don't see the menu pops up . I am sure this is a problem with the layout but I cannot figure out how to fix it. here is some screenshots:
Android while the menu is closed:
This is when I click on location field. I am expecting to see the menu
but as you can see it is not showing up. but the same code works fine in iOS
attached is my render method
code.docx
Hi, with iOs the popup menu overlays any components but I can't seem to create the same effect on android. Is there any additional property for the MenuContext overlay?
Thanks
Hello,
The triggerTouchable
prop from MenuTrigger
doesn't seem to update TouchableHighliht's props (as stated in the docs).
When I try
<MenuTrigger style={{paddingLeft: 10, paddingRight: 5, height: '100%', justifyContent: 'center'}} triggerTouchable={{hitSlop: {right: 5}} >
The hitSlop doesn't seem to change. tried also underlayColor: 'red'
, but still no results.
RN: 0.47.2
react-native-popup-menu: 0.8.0
Many thanks!
I am using a popup menu to pick a country from a list of 196 countries. I am rendering custom ListItem
elements for each country for minor styling (country flag + name) but the result is each item is a medium sized component of nested View
, styles, etc. Multiply that times 196 ListItem
s and the popup menu takes 5 seconds to open - it's not necessarily trivial to compute in one shot. The big problem is that the delay is causing users to tap it multiple times because they think they mis-tapped due to no visual feedback due to the lag, which causes the menu to close before it opens. Really suffering on the UX-front.
My guess here is that this library is rendering all items in one shot, so in my case React has to render this massive tree when the user taps to open the menu. Can we render list items in batch? FlatList
has an initialNumToRender
prop: https://facebook.github.io/react-native/docs/flatlist.html#initialnumtorender
This is a great package!
I want to keep the menu open while selecting an option. Unfortunately the menu options text is not updated immediately but only after reopening the menu.
export default class _Menu extends Component {
state = {selected: 0};
onSelect(value) {
this.setState({selected: value});
return false;
}
render() {
return (
<Menu
onSelect={ this.onSelect.bind(this) }
>
<MenuTrigger>
<Text>
trigger
</Text>
</MenuTrigger>
<MenuOptions>
<MenuOption
value={ 0 }
text={ (this.state.selected === 0 ? ' selected ' : '') + ' one ' }
>
</MenuOption>
<MenuOption
value={ 1 }
text={ (this.state.selected === 1 ? ' selected ' : '') + ' two ' }
>
</MenuOption>
</MenuOptions>
</Menu>
);
}
};
Would like to be able to customize the styles of the backdrop, i.e. backgroundColor and opacity.
Hello,
I'm trying to use your module in React Native 0.26.3, but just when I import anything from react-native-popup-menu
, I get this:
transformed 714/715 (100%)[node-haste] Encountered an error while persisting cache:
> ReferenceError: __DEV__ is not defined
> at Object.<anonymous> (/home/dimon/projects/go/src/cesanta.com/mud/node_modules/react-native/Libraries/react-native/react-native.js:15:5)
> at Module._compile (module.js:435:26)
> at Object.Module._extensions..js (module.js:442:10)
> at Module.load (module.js:356:32)
> at Function.Module._load (module.js:311:12)
> at Module.require (module.js:366:17)
> at require (module.js:385:17)
> at /home/dimon/projects/go/src/cesanta.com/mud/node_modules/react-native/node_modules/babel-core/lib/transformation/file/options/option-manager.js:391:22
> at Array.map (native)
> TransformError: /home/dimon/projects/go/src/cesanta.com/mud/node_modules/react-native-popup-menu/src/index.js: __DEV__ is not defined
Could you please give some clue?
Hey there,
Can some one help me with this problem. I'm using flatlist to preview my data results from API, and in each component I want to add a pop up menu. The popup menu is work, but the position is not correct.
when i select bed type, and popup appear far from the triger component
Thank you
React Native 0.44 fires this:
Warning: View.propTypes has been deprecated and will be removed in a future version of ReactNative. Use ViewPropTypes instead.
at MenuOptions.js:22
Disclaimer... I am pretty sure this is my mistake, and really more me just asking for help
Hi guys,
Love the popup menu! I was just trying to give the menu a slight offset from where it appeared when it opened up. I tried to trace through the source code to do this and add to popoverOrigin point. Was this the wrong way to do it? Dosen't seem to be making a difference...
Thanks!
On android, before the menu is opened, there is a black point in the center of the menu scope.how to remove it?
I'm seeing a warning when I open the popup.
ExceptionsManager.js:73 Warning: Failed prop type: Invalid prop `style` of type `array` supplied to `ContextMenu`, expected `object`.
in ContextMenu (created by MenuPlaceholder)
in MenuPlaceholder (at MenuContext.js:190)
in RCTView (at View.js:113)
in View (at MenuContext.js:186)
in MenuContext (at Main.js:40)
in Provider (at Main.js:39)
in main (at App.js:6)
in App (at index.android.js:8)
in verbmaster (at renderApplication.js:35)
in RCTView (at View.js:113)
in View (at AppContainer.js:102)
in RCTView (at View.js:113)
in View (at AppContainer.js:122)
in AppContainer (at renderApplication.js:34)
I see style being set here:
https://github.com/instea/react-native-popup-menu/blob/master/src/MenuContext.js#L250
Thanks for maintaining this project!
Hi!
If you add 1 line of code to the Platform.Select code on line say 31 of helpers.js to also consider windows UWP such as "windows:TouchableHighlight", it seems to work great in UWP. At least so far for me.
A whole other platform simply by considering it as an option. Not a bad deal. :-)
thx!
MG
Is there a simple way of closing my PopUpMenu by clicking out of it? Like on blur with text input?
Thanks,
Just like react-native-menu, this doesn't work inside a Modal. It shows up behind the modal I think.
Any suggestions?
It's currently not possible to have a MenuOption be null. This sucks because you can then not let menu options depend on component functions that may return null if the menuoption should not be rendered
I can't see the menu on android device,while iOS can.
Beautiful and this popup menu is working like a charm. I was only wondering if we can implement the option where MenuOptions list can be displayed as a horizontal list instead of the current vertical one.
Please and thanks. And good work again.
for example this work fine
<MenuOptions>
<MenuOption
value={0}
text={'Daily '}
/>
<MenuOption
value={1}
text={'Live'}
/>
</MenuOptions>
but this does not work
var options = [{
val: 0,
text: 'Daily'
}, {
val: 0,
text: 'Daily'
}];
<MenuOptions>
{options.map(({val, text}) => (
<MenuOption
key={val}
value={val}
text={text}
/>
))}
</MenuOptions>
when using this with react-native-web, it errors as menuName is not a valid prop.
"warning.js:9 Warning: Unknown prop menuName
on
Changing menuName to name inside menu.js, and menuTrigger.js fixes the issue.
This is my render code for a menu within my application:
<View style={{ alignItems: 'flex-end', flex: 1, justifyContent: "center" }}>
<Menu onSelect={this.handleMenuSelection.bind(this) }>
<MenuTrigger>
<View ref="menuButton" style={{ padding: 10, paddingRight: 15 }}>
<Icon name="bars" style={{ color: "white" }} size={20} />
</View>
</MenuTrigger>
<MenuOptions>
<MenuOption value={0}>
<Text>Settings</Text>
</MenuOption>
<MenuOption value={1}>
<Text>Send Feedback</Text>
</MenuOption>
</MenuOptions>
</Menu>
</View>
This code worked before I migrated to React Native 0.26 and when I was using the react-native-menu component. After upgrading to RN 0.26, react-native-menu no longer works due to an issue with shape. It was suggested to move to react-native-popup-menu. However, now the app crashes with the following error: undefined is not an object(this.context.menuActions._notify).
Any help would be greatly appreciated.
Thanks
First of all, thanks for your library it's been very useful!
So, I understand why MenuContext needs to be at the top of the component hierarchy but in my app I'm mapping cards, like so:
Code mapping:
return filteredSortedArray.map(post =>
<ExamCardDetail
key={post["Date, time"]}
dateTime={post["Date, time"]}
type={post["type"]}
body={post["body"]}
keyId={post["key"]}
caseId={post["caseId"]}
/>
)
The component ExamCardDetail contains the rest of the popupmenu code, like so:
<Menu>
<MenuTrigger>
<Icon
name="ios-arrow-down"
size={25}
color="grey"
/>
</MenuTrigger>
<MenuOptions>
<MenuOption style={optionsStyle}>
<Icon.Button
name="md-create"
size={25}
onPress={() => this._editExam()}
color="red"
backgroundColor="white"
/>
<Text style={textStyle}>Edit</Text>
</MenuOption>
<MenuOption style={optionsStyle}>
<Icon.Button
name="ios-trash"
size={25}
onPress={() => this._deleteExam()}
color="red"
backgroundColor="white"
/>
<Text style={textStyle}>Delete</Text>
</MenuOption>
</MenuOptions>
</Menu>
My popup menu on each of these cards contains the delete function, and so I pass down the unique id of the card so it can be deleted from Firebase. However because I am not mapping MenuContext (as it needs to be at the top of the hierarchy) it is unable to receive the ids of the different cards. It only receives the last one that was mapped. Therefore when I try to delete a specific card it is only able to delete the latest one.
If I try to map MenuContext as a wrapper around the card, this happens:
Code mapping:
return filteredSortedArray.map(post =>
<MenuContext>
<ExamCardDetail
key={post["Date, time"]}
dateTime={post["Date, time"]}
type={post["type"]}
body={post["body"]}
keyId={post["key"]}
caseId={post["caseId"]}
/>
</MenuContext>
)
This works, but obviously looks very bad. I have tried to style MenuContext, Menu and the other Components to fix this but it does not work.
Basically my question is: is there a workaround for this? Is there a way to map MenuContext (i.e. replace it's high hierarchical position at the top of my app) and still maintain it's default positioning and styling?
Sorry for such a longwinded issue! Any help would be much appreciated
Hey there,
I'm not sure if this is expected behavior but isn't it common practice to close the react-native-popup-menu on pressing the android hardware back button?
Is this a bug or is there a special way to implement this?
It seems that controlled menu does not animate when closed via props.
Expected: it should animate same as uncontrolled menu.
version: 0.7.2
platforms: both
RN 0.30 now supports zIndex property that can be used to override default "zIndex strategy" in previous RN versions. This can lead to layout problems.
Pls add new config
property to MenuContext
that can influence zIndex of rendered backdrop and menu options. However for backward compatibility with previous RN versions there will be no default zIndex and will be activated only if user explicitly define desired zIndex.
Perhaps this is intentional but usability wise, I would prefer there to be feedback when a menu option is clicked
Hello, Thanks to open this project.
I'm using your react-native-popup-menu for logout button.
when button clicked the authentication deleted and screen will go to login .
but the menu still left.
How to close this menu when screen switched?
<Menu>
<MenuTrigger>
<Icon
name='more-vert'
color='#fff'
/>
</MenuTrigger>
<MenuOptions>
<MenuOption value={1}>
<Text onPress={ () => {
this.props.onLogout()
} }>logout</Text>
</MenuOption>
</MenuOptions>
</Menu>
I have a route that uses context to open and close a menu by name
.
this.context.menuActions.openMenu(NAME)
The associated menu itself is located in the render()
method of this route.
When I add a new route onto the stack, it seems this menu is deleted by name, I guess because it exists on a route that is no longer active. This is problematic, because when I tap the "Back" button to return to the original route by popping off the current one, this menu is no longer in the registry, so attempts to call menuActions.openMenu(NAME)
on that route results in an error:
"YellowBox.js:69 menu with name NAME does not exist"
How do we re-register menus by name? Or is it possible to prevent this menu cleanup?
Hi.I wanna dynamically add MenuOption .Here's my code:
<MenuOptions>
{params.device_room.map(menuOption => <MenuOption onSelect={this.selectRoom(menuOption.room_id,menuOption.name)} text={menuOption.name}/>)}
</MenuOptions>
And then onSelect function was called for several times as my array length.
Besides, I can't call the function with select them after then.
The MenuTrigger is the button "Language to receive notifications".
My code:
<Menu onSelect={this.onFieldChange.bind(this)}>
<MenuTrigger>
<View style={{flex:1, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<Text
style={[styles.input,{flex:1}]}
keyboardType={this.props.type ? this.props.type : 'default'}>
{this.props.placeholder}
</Text>
<Text style={styles.input} ref="dropdownTitle">
{this.state.text}
</Text>
</View>
</MenuTrigger>
<MenuOptions optionsContainerStyle={styles.dropdownOptions_}>
{this.props.options.map((item, index) => (
<MenuOption key={index} value={item.title}>
<Text style={styles.input}>{item.title}</Text>
</MenuOption>
))}
</MenuOptions>
</Menu>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.