diff --git a/components/Dropdown.js b/components/Dropdown.js index ad03d45..e4b2aa5 100644 --- a/components/Dropdown.js +++ b/components/Dropdown.js @@ -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 ( - 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 ( + 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.name} {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 ( - - {children} + + {button ? ( + {children} + ) : ( + + )}
@@ -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(180deg); diff --git a/package.json b/package.json index c966d4d..9b0b857 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "highlight.js": "^9.12.0", "history": "^4.7.2", "lodash.debounce": "^4.0.8", + "match-sorter": "^2.2.0", "morgan": "^1.8.2", "morphmorph": "^0.0.2", "ms": "^2.0.0", diff --git a/yarn.lock b/yarn.lock index 0c8bdf8..8bdf774 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1688,6 +1688,10 @@ detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" +diacritic@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/diacritic/-/diacritic-0.0.2.tgz#fc2a887b5a5bc0a0a854fb614c7c2f209061ee04" + diffie-hellman@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" @@ -3265,6 +3269,12 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" +match-sorter@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-2.2.0.tgz#3e88661aab7b8320836f67731cf7f9d3cb889761" + dependencies: + diacritic "0.0.2" + material-colors@^1.2.1: version "1.2.5" resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.5.tgz#5292593e6754cb1bcc2b98030e4e0d6a3afc9ea1"