react-native-paper
react-native-paper copied to clipboard
feat: added dropdown component
I have previously created this PR https://github.com/callstack/react-native-paper/pull/2893. This was a long time ago and the branch fell behind very far from the current main branch. Also material m3 has been released so I thought it's a better idea to redo the work from scratch to better align with the new guidelines and the new code version.
Dropdown menus are very commonly used. From a design perspective, dropdown menu is referred to as Menu in material design guidelines, but it's a pain having to create this component with the expected functionality from a developer point of view. At least this is the impression I got from the comments in the previous PR.
The dropdown component in this PR is just a combination of a TextInput and a Menu component with an out-of-the-box functionality to select a specific item in the menu.
If you think this is a good idea, I'd like to kindly ask for your help to fix any mistakes and enrich this PR with tests/docs (or anything that I missed) so it can hopefully be merged in the repo.
Thanks!
Hey @omneimneh, thank you for your pull request 🤗. The documentation from this branch can be viewed here.
@omneimneh : It will also support this model:
https://m2.material.io/components/menus#exposed-dropdown-menu
@omneimneh : It will also support this model:
https://m2.material.io/components/menus#exposed-dropdown-menu
Thanks for providing this link. I think it behaves in the way described, although there might be minor changes (like the arrow icon). Please point out if you see anything else missing or contradicting the behavior or design that is intended.
@omneimneh : Could you provide an example of everything on snack.expo so we can try it?
How does multiple item selection work?
@omneimneh : Could you provide an example of everything on snack.expo so we can try it?
How does multiple item selection work?
How do I use this version of react-native-paper in snack.expo?
I did not support multiple item selection since I never seen it in native android or in material design guidelines. I think for that it's better to use radio buttons or switches. What do you think? https://m2.material.io/components/selection-controls
@omneimneh : Shouldn't you be looking at v3?
https://m3.material.io/components
Will it support grouped items?
Take a look here for the various types of dropdowns, although I don't know if it has much to do with Android's material design: https://mui.com/material-ui/react-autocomplete/#grouped
Hey @omneimneh, I've run your example, however when pressing the any of anchors there's nothing going on. Could you please check it?
Hey @omneimneh, I've run your example, however when pressing the any of anchors there's nothing going on. Could you please check it?
It's weird that I didn't notice this issue before, it seems like I have to click twice in order to open the menu, I will check this issue. But I also think there's also another bug in the Menu component when the anchor is at the bottom of the screen.
https://github.com/callstack/react-native-paper/assets/49276638/36c08ffb-5e25-4686-b509-b4ef2396dd71
@omneimneh : Shouldn't you be looking at v3?
https://m3.material.io/components
Will it support grouped items?
Take a look here for the various types of dropdowns, although I don't know if it has much to do with Android's material design: https://mui.com/material-ui/react-autocomplete/#grouped
I think it's easy to add this once we have a working component. I see this more as a compound component and there's an example of it in m3 figma file, but I didn't see any specific requirements. Please note that I'm not very familiar with design systems in general but I'm trying my best to follow the documentation.
I'm happy to change it depending on the requirements if you have them. Otherwise my suggestion is let's start by identifying the different use cases, we can check examples of usage in some google apps. Then we can comply with the naming as well (whether it's Dropdown, ComboBox, Autocomplete, Exposed Menu...) And I'll do my best to finish & fix the implementation.
@omneimneh : I can't find it in the figma file, can you take a screenshot?
@omneimneh : I can't find it in the figma file, can you take a screenshot?
https://www.figma.com/community/file/1035203688168086460/material-3-design-kit
@omneimneh :
see this more as a compound component and there's an example of it in m3 figma file.
I looked at the figma file but I can't find this example you mention.
@omneimneh :
see this more as a compound component and there's an example of it in m3 figma file.
I looked at the figma file but I can't find this example you mention.
I see this more as a compound component and there's an example of it in m3 figma file
I had seen this too, I thought you were referring to something there that allowed you to select multiple elements.
I was thinking of something like this:
@omneimneh : Is there any news?
Is there an update on this? Would be very cool to use. I was tinkering with this code and found that
useEffect(() => { menu?.measureInWindow((_x, _y, width, _height) => { setWidth(width); }); }, [open, menu]);
Doesn't really work, width is undefined so the width can't be really calculated. Couldn't this be simplified by using the onLayout Event of the view? Or are there circumstances where this won't fire? It would uncomplicate the some code.
Any version milestone on this? Many devs have been waiting for this component for months or years, and this is the closest we've ever been.
useEffect(() => { menu?.measureInWindow((_x, _y, width, _height) => { setWidth(width); }); }, [open, menu]);
Doesn't really work, width is undefined so the width can't be really calculated. Couldn't this be simplified by using the onLayout Event of the view? Or are there circumstances where this won't fire? It would uncomplicate the some code.
yes. the onLayout event resolves the issue. there's an ugly shadow in outlined mode that can be fixed by setting the ripple color to transparent.
@omneimneh i propose the following changes:
- const [menu, setMenu] = useState<View | null>(null);
- ...
- useEffect(() => {
- menu?.measureInWindow((_x, _y, width, _height) => {
- setWidth(width);
- });
- }, [open, menu]);
- ...
- <View ref={setMenu}>
- <TouchableRipple onPress={() => setOpen(true)}>
+ <View onLayout={x => setWidth(x.nativeEvent.layout.width) }>
+ <TouchableRipple onPress={() => setOpen(true)} rippleColor={'transparent'}>
I can help finishing this, but I'm new to open source contribution if anyone can guide me how to change this code
and we need to map the menu items inside some kind of scroll view, so on large items number we can scroll inside the menu..