Created
January 17, 2018 19:10
-
-
Save nloding/878a1564a3ecae9fe18f777e488198f2 to your computer and use it in GitHub Desktop.
formik with react-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 { compose, isNull, map, omit } from 'lodash/fp'; | |
| import React from 'react'; | |
| import styled from 'react-emotion'; | |
| import ReactSelect from 'react-select'; | |
| import { mapProps, withHandlers } from 'recompose'; | |
| import 'react-select/dist/react-select.css'; | |
| const StyledReactSelect = styled(ReactSelect)` | |
| &.is-focused .Select-control { | |
| border-color: ${props => props.theme.color.denim}; | |
| } | |
| &.is-focused:not(.is-open) > .Select-control { | |
| border-color: ${props => props.theme.color.denim}; | |
| } | |
| .Select-control { | |
| padding: 0.625rem 0; | |
| border: ${props => `1px solid ${props.theme.color.regentGray}`}; | |
| border-radius: 2px; | |
| } | |
| .Select-input { | |
| height: auto; | |
| & > input { | |
| padding-top: 0; | |
| padding-bottom: 0; | |
| } | |
| } | |
| .Select-value-label { | |
| font-size: 0.9rem; | |
| } | |
| `; | |
| const Option = styled('div')`color: inherit;`; | |
| // We have to manually handle null this way | |
| // Otherwise the option doesn't show up | |
| // as selected :( | |
| const NULL_PLACEHOLDER = 'SELECT_INPUT_NULL'; | |
| const selectOptions = compose( | |
| map(c => ({ | |
| label: c.props.children, | |
| value: isNull(c.props.value) ? NULL_PLACEHOLDER : c.props.value, | |
| })), | |
| React.Children.toArray | |
| ); | |
| const container = compose( | |
| withHandlers({ | |
| onChange: props => option => { | |
| if (!option) return props.onChange(null); | |
| return option.value === NULL_PLACEHOLDER | |
| ? props.onChange(null) | |
| : props.onChange(option.value); | |
| }, | |
| }), | |
| mapProps(props => ({ | |
| ...props, | |
| value: isNull(props.value) ? NULL_PLACEHOLDER : props.value, | |
| })) | |
| ); | |
| const omitCustomProps = omit(['children']); | |
| type Props = { | |
| children: React.Children<Option>, | |
| }; | |
| const Select = (props: Props) => ( | |
| <StyledReactSelect | |
| {...omitCustomProps(props)} | |
| options={selectOptions(props.children)} | |
| /> | |
| ); | |
| const EnhancedSelect = container(Select); | |
| EnhancedSelect.Option = Option; | |
| export default EnhancedSelect; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment