- 本仓库最初代码 for 自 react-native-modal-dropdown, 感谢原作者的启发.
- 为了兼容 React-Native-Web, 需要将 react-native-modal 添加至依赖中, 如果将来 React-Native-Web 支持 React Native 的原生 Modal 组件, 我将会保持现有的 Api, 并移除 react-native-modal
- 🙏 If you have a question, please start a new discussion instead of opening a new issue.
请先花五分钟看完这段话, 这对于使用和对该组件二次开发是很有帮助的, 首先必须要了解两个概念 Trigger
和 Overlay
, Dropdown
组件由
This library is rewritten(fork) from react-native-modal-dropdown,感谢原作者。
这个库重写自react-native-modal-dropdown,原有库长期未维护,并且使用了 React Native 的废弃组件 ListView,导致无法兼容 React Native For Web,考虑除了兼容 Web 之外,本人还要新增一些功能,改动性比较大,索性不发 PR ,直接重写。
This library is rewritten from react-native-modal-dropdown, the original library has not been maintained for a long time,and it use React Native deprecated component ListView, so it can not be compatibility with React Native For Web, Considering that in addition to Web compatibility, I have to add some new feature, which will be changed a lot, so i will directly rewrite it without PR.
react-native dropdown/picker/selector 组件,支持 Android、IOS、Web.
A react-native dropdown/picker/selector component for Android & iOS & Web.
react-native-modal-dropdown 以下简称为 RNMD
我认为大多数前端开发流程中开发者往往需要使用基础组件来封装符合 UI 风格与业务逻辑的组件,RNMD 就是这么一个非常基础的组件,它仅仅用于定位以及弹出 DropDown,所以使用前你可能需要先进行封装。
I think most Frontend Development process developers often need to use base component encapsulate component that conform to UI style and business logic. RNMD is a very basic component that is only used to locate and popup dorpdown, so before using it that you may need to encapsulate it.
如果你在寻求一个开箱即用的组件,我已经封装了一些案例,你可以直接将源代码复制进你的项目,在线预览:
If you are looking for an out of the box component, I have encapsulated a few cases, you can copy the source code into your project directly, online preview.
https://expo.io/@912305043/monchilin-react-native-dropdown-example
(源代码)(https://github.com/MonchiLin/react-native-dropdown/blob/master/example/src/App.tsx)
- 100% Typescript 编写提供类型安全 ( compile to JS )
- 100% Typescript writting provider type safety ( compile to JS )
- 交互动画支持
- Interactive animation support
- 兼容 Android & IOS & Web (欢迎贡献 Windows 与 macOS 代码)
- compatible Android & IOS & Web (welcome to contribute Windows & macOS code)
- 自动调整位置,无需担心 dropdown 在屏幕边缘
- Automatically position, without fear of Dorpdown at the edge of the screen
- 一目了然的语义化 API
- A clear semantic API
- 自定义99% 样式与属性
- Customize 99% of styles and attributes
- 命令式 Api 支持 (Show/Hide/Select)
- Imperative Api support (Show/Hide/Select)
你可以在 这里 找到更多的用例。
You can be here Find more usecase.
npm i @monchilin/react-native-dropdown -save
// yarn add @monchilin/react-native-dropdown
如果你想要在 React Native Web 中使用,你还需要安装 resize-observer-polyfill,因为 Dropdown 位置计算依赖于 onLayout 事件,但是在 React Native Web 中 onLayout 事件依赖于 ResizeObserver,但是在一些 webkit 内核的浏览器并没有实现( qq浏览器:谁在说我?)
npm install resize-observer-polyfill --save-dev
// yarn add resize-observer-polyfill -D
导入模块
import ModalDropdown from '@monchilin/react-native-dropdown';
<ModalDropdown options={['option 1', 'option 2']}/>
<ModalDropdown options={['option 1', 'option 2']}>
I'm Label
</ModalDropdown>
Prop | Type | Optional | Default | Description |
---|---|---|---|---|
disabled |
bool | Yes | false | disable / enable the component. |
defaultIndex |
number | Yes | -1 | Init selected index. -1 : None is selected. This only change the highlight of the dropdown row, you have to give a defaultValue to change the init text. |
index |
number | Yes | -1 | Init selected index. -1 : None is selected. |
defaultLabel |
string | Yes | Please select... | Init label text. Invalid in custom label. |
dataSource |
array | No | dataSource for renderItem. | |
animated |
bool | Yes | true | Disable / enable animation. |
transitionShow |
string | Yee | flipUp | Expand animation ['flipUp', 'scaleIn', 'fadeIn', 'slideUp'] |
transitionHide |
string | Yee | flipDown | Expand animation ['flipDown', 'scaleOut', 'fadeOut', 'slideDown'] |
loading |
bool | Yes | false | Enable loading Indicator |
scrollEnabled |
bool | Yes | true | When false, the content does not scroll. The default value is true |
keyExtractor |
func | Yes | (_, index) => index.toString() | Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks item.key , then falls back to using the index, like React does. |
adjustFrame |
func | Yes | This is a callback after the frame of the dropdown have been calculated and before showing. You will receive a style object as argument with some of the props like width height top left and right . Change them to appropriate values that accord with your requirement and make the new style as the return value of this function. |
|
renderItem |
func | Yes | Customize render dataSource item: function(option,index,isActive) Will render a default row if null /undefined . |
|
renderSeparator |
func | Yes | Customize render dropdown list separators. Will render a default thin gray line if null /undefined . |
|
showSeparator |
bool | yes | true | Show split line or not |
renderLabel |
func | Yes | Use this to extract and return text from dataSource object. This text will show on label after dataSource selected. Invalid in wrapper mode. | |
onDropdownWillShow |
func | Yes | Trigger when dropdown will show by touching the button. Return false can cancel the event. |
|
onDropdownWillHide |
func | Yes | Trigger when dropdown will hide by touching the button. Return false can cancel the event. |
|
onSelect |
func | Yes | Trigger when item touched with selected index and value . Return false can cancel the event. |
见 自定义任何样式与属性
章节
Prop | Type | Optional |
---|---|---|
rootContainerStyle |
StyleProp<ViewStyle> |
Yes |
rootContainerProps |
Omit<ViewProps, 'style'> |
Yes |
labelContainerDisabledStyle |
StyleProp<ViewStyle> |
Yes |
labelContainerStyle |
StyleProp<ViewStyle> |
Yes |
labelContainerProps |
Omit<TouchableOpacityProps, 'ref'> |
Yes |
labelStyle |
StyleProp<TextStyle> |
Yes |
labelDisabledStyle |
StyleProp<TextStyle> |
Yes |
labelProps |
Omit<TextProps, 'style'> |
Yes |
modalProps |
Omit<ModalProps, 'visible'> |
Yes |
dropdownStyle |
StyleProp<ViewStyle> |
Yes |
dropdownProps |
Omit<FlatListProps<ItemT>, 'data'> |
Yes |
itemTouchableProps |
Omit<TouchableOpacityProps,'onPress'> |
Yes |
itemLabelStyle |
StyleProp<TextStyle> |
Yes |
itemLabelProps |
Omit<TextProps, 'style'> |
Yes |
itemHighlightStyle |
StyleProp<ViewStyle> |
Yes |
itemLabelHighlightStyle |
StyleProp<TextStyle> |
Yes |
Method | Description |
---|---|
show() |
Show the dropdown. Won't trigger onDropdownWillShow . |
hide() |
Hide the dropdown. Won't trigger onDropdownWillHide . |
select(index) |
Select the specified dataSource of the index . Select -1 will reset it to display defaultValue . Won't trigger onSelect . |
正如开头所说,RNMD 是一个非常基础的组件,它提供了自定义任何样式与属性的能力,但是在 RN 中我们无法像在浏览器中一样直观的看到 DOM 结构,所以看到 someStyle, someProp
api 时会感到很困惑,为此,我做了两张图来表示结构。
RN 的 Animated 模块提供了 useNativeDriver
选项以提升动画性能,但是它只能与 opacity
和 transform
一起使用,slideUp 与 slideDown 是使用 height
实现的,在开发模式下更为明显,所以,如果对流畅度有要求建议使用其他动画效果。