@ -1,29 +1,64 @@
import React from 'react'
import React , { Component } from 'react'
import Downshift from 'downshift'
import matchSorter from 'match-sorter'
import ArrowDown from './svg/Arrowdown'
import CheckMark from './svg/Checkmark'
import { COLORS } from '../lib/constants'
const Dropdown = ( { button , color , list , selected , onChange } ) => {
return (
< Downshift
render = { renderDropdown ( { button , color , list , selected } ) }
selectedItem = { selected }
defaultHighlightedIndex = { list . findIndex ( it => it === selected ) }
itemToString = { item => item . name }
onChange = { onChange }
stateReducer = { reduceState ( list ) }
/ >
)
}
class Dropdown extends Component {
state = {
inputValue : this . props . selected . name ,
itemsToShow : this . props . list
}
userInputtedValue = ''
onUserAction = changes => {
this . setState ( ( { inputValue , itemsToShow } ) => {
const clearUserInput = changes . hasOwnProperty ( 'isOpen' )
if ( changes . hasOwnProperty ( 'inputValue' ) ) {
if ( changes . type === Downshift . stateChangeTypes . keyDownEscape ) {
inputValue = this . userInputtedValue
} else {
inputValue = changes . inputValue
this . userInputtedValue = changes . inputValue
}
}
itemsToShow = this . userInputtedValue
? matchSorter ( this . props . list , this . userInputtedValue , { keys : [ 'name' ] } )
: this . props . list
if (
changes . hasOwnProperty ( 'highlightedIndex' ) &&
( changes . type === Downshift . stateChangeTypes . keyDownArrowUp ||
changes . type === Downshift . stateChangeTypes . keyDownArrowDown )
) {
inputValue = itemsToShow [ changes . highlightedIndex ] . name
}
if ( clearUserInput ) {
this . userInputtedValue = ''
}
return { inputValue , itemsToShow }
} )
}
const reduceState = list => ( state , changes ) => {
switch ( changes . type ) {
case Downshift . stateChangeTypes . keyDownArrowUp :
case Downshift . stateChangeTypes . keyDownArrowDown :
return { ... changes , selectedItem : list [ changes . highlightedIndex ] }
default :
return changes
render ( ) {
const { button , color , list , selected , onChange } = this . props
return (
< Downshift
inputValue = { this . state . inputValue }
render = { renderDropdown ( { button , color , list : this . state . itemsToShow , selected } ) }
selectedItem = { selected }
defaultHighlightedIndex = { list . findIndex ( it => it === selected ) }
itemToString = { item => item . name }
onChange = { onChange }
onUserAction = { this . onUserAction }
/ >
)
}
}
@ -43,7 +78,13 @@ const renderDropdown = ({ button, color, list, selected }) => ({
{ ... getRootProps ( { refKey : 'innerRef' } ) }
minWidth = { minWidth ( button , selected , list ) }
>
< SelectedItem { ... getButtonProps ( ) } { ... getInputProps ( ) } isOpen = { isOpen } color = { color } >
< SelectedItem
getButtonProps = { getButtonProps }
getInputProps = { getInputProps }
isOpen = { isOpen }
color = { color }
button = { button }
>
{ selectedItem . name }
< / S e l e c t e d I t e m >
{ isOpen ? (
@ -82,12 +123,20 @@ const DropdownContainer = ({ children, innerRef, minWidth, ...rest }) => {
)
}
const SelectedItem = ( { children, isOpen , color , ... rest } ) => {
const SelectedItem = ( { getButtonProps, getInputProps , children, isOpen , color , button } ) => {
const itemColor = color || COLORS . SECONDARY
return (
< span { ... rest } tabIndex = "0" className = { ` dropdown-display ${ isOpen ? 'is-open' : '' } ` } >
< span className = "dropdown-display-text" > { children } < / s p a n >
< span
{ ... getButtonProps ( ) }
tabIndex = "0"
className = { ` dropdown-display ${ isOpen ? 'is-open' : '' } ` }
>
{ button ? (
< span className = "dropdown-display-text" > { children } < / s p a n >
) : (
< input { ... getInputProps ( { placeholder : children } ) } className = "dropdown-display-text" / >
) }
< div role = "button" className = { ` dropdown-arrow ` } >
< ArrowDown fill = { itemColor } / >
< / d i v >
@ -112,6 +161,11 @@ const SelectedItem = ({ children, isOpen, color, ...rest }) => {
. dropdown - display - text {
flex - grow : 1 ;
color : $ { itemColor } ;
background : transparent ;
border : none ;
outline : none ;
font - size : inherit ;
font - family : inherit ;
}
. is - open > . dropdown - arrow {
transform : rotate ( 180 deg ) ;