Skip to content

Instantly share code, notes, and snippets.

@benjaminreid
Last active June 7, 2019 16:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjaminreid/94b177c649ee7a9a5a8b04ed35f53ba0 to your computer and use it in GitHub Desktop.
Save benjaminreid/94b177c649ee7a9a5a8b04ed35f53ba0 to your computer and use it in GitHub Desktop.
React Native Modal Select
// @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,
};
}
function Screen() {
const frequency = useSelect(
3,
Array.from("123456").map(label => ({ label, value: parseInt(label) })),
);
return (
<>
<Select {...frequency} />
</>
);
}
// @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;
// @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