Last active
June 7, 2019 16:08
-
-
Save benjaminreid/94b177c649ee7a9a5a8b04ed35f53ba0 to your computer and use it in GitHub Desktop.
React Native Modal Select
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import * as React from "react"; | |
function useSelect( | |
initialValue: string | number, | |
items: Array<{ label: string, value: string | number }>, | |
) { | |
const [value, setValue] = React.useState(initialValue); | |
function onChangeValue(value: string) { | |
setValue(value); | |
} | |
return { | |
initialValue, | |
value, | |
items, | |
onChangeValue, | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Screen() { | |
const frequency = useSelect( | |
3, | |
Array.from("123456").map(label => ({ label, value: parseInt(label) })), | |
); | |
return ( | |
<> | |
<Select {...frequency} /> | |
</> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import * as React from "react"; | |
import { Modal, TouchableWithoutFeedback } from "react-native"; | |
import { Container, Picker, Header, Input, Close } from "./styles"; | |
type Props = { | |
items: Array<{ | |
label: string, | |
value: string | number, | |
}>, | |
initialValue: string, | |
onChangeValue?: (value: string) => void, | |
}; | |
function Select({ items, initialValue, onChangeValue }: Props) { | |
const [visible, setVisible] = React.useState(false); | |
const [value, setValue] = React.useState(initialValue); | |
const displayValue = items.find(item => item.value === value).label; | |
function updateValue(value) { | |
setValue(value); | |
if (onChangeValue) { | |
onChangeValue(value); | |
} | |
} | |
function openModal() { | |
setVisible(true); | |
} | |
function closeModal() { | |
setVisible(false); | |
} | |
return ( | |
<> | |
<TouchableWithoutFeedback onPress={openModal}> | |
<Input>{displayValue}</Input> | |
</TouchableWithoutFeedback> | |
<Modal | |
visible={visible} | |
transparent={true} | |
animationType="slide" | |
onRequestClose={closeModal} | |
> | |
<Container> | |
<Header> | |
<Close onPress={closeModal}>Done</Close> | |
</Header> | |
<Picker selectedValue={value} onValueChange={updateValue}> | |
{items.map(({ label, value }, index) => ( | |
<Picker.Item key={index} label={label} value={value} /> | |
))} | |
</Picker> | |
</Container> | |
</Modal> | |
</> | |
); | |
} | |
export default Select; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import styled from "styled-components"; | |
import { SafeAreaView } from "react-navigation"; | |
export const Picker = styled.Picker` | |
width: 100%; | |
height: 200px; | |
`; | |
export const Container = styled(SafeAreaView)` | |
background-color: white; | |
margin-top: auto; | |
`; | |
export const Header = styled.View` | |
height: 44px; | |
background-color: #f8f8f8; | |
border-top-width: 1px; | |
border-color: #d8d8d8; | |
padding: 0 ${props => props.theme.spacing}px; | |
align-items: flex-end; | |
`; | |
export const Close = styled.Text` | |
height: 44px; | |
color: #007aff; | |
font-weight: bold; | |
line-height: 43px; | |
`; | |
export const Input = styled.Text` | |
height: 44px; | |
border-width: 1px; | |
border-color: ${props => props.theme.colors.bluegrey(20)}; | |
border-radius: ${props => props.theme.radius.normal}px; | |
padding: 0 ${props => props.theme.spacing}px; | |
font-family: ${props => props.theme.font.family.default}; | |
font-size: ${props => props.theme.font.size.normal}; | |
line-height: 43px; | |
`; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment