diff --git a/components/Dropdown.js b/components/Dropdown.js index 352e05d..a342c89 100644 --- a/components/Dropdown.js +++ b/components/Dropdown.js @@ -1,134 +1,155 @@ import React from 'react' -import enhanceWithClickOutside from 'react-click-outside' +import Downshift from 'downshift' import ArrowDown from './svg/Arrowdown' -import Checkmark from './svg/Checkmark' +import CheckMark from './svg/Checkmark' import { COLORS } from '../lib/constants' -class Dropdown extends React.Component { - constructor(props) { - super(props) - this.state = { - isVisible: false - } - this.select = this.select.bind(this) - this.toggle = this.toggle.bind(this) - } - - select(item) { - if (this.props.selected !== item) { - this.props.onChange(item) - } - } - - toggle() { - this.setState({ isVisible: !this.state.isVisible }) - } +const Dropdown = ({ list, selected, onChange }) => { + return ( + it === selected)} + itemToString={item => item.name} + onChange={onChange} + stateReducer={reduceState(list)} + /> + ) +} - handleClickOutside() { - this.setState({ isVisible: false }) +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 } +} - renderListItems() { - return this.props.list.map((item, i) => ( -
- {item.name} - {this.props.selected === item ? : null} - +
+ ) +} - .dropdown-list-item:last-of-type { - border-bottom: none; - border-radius: 0px 0px 2px 2px; - } - `} +const SelectedItem = ({ children, isOpen, ...rest }) => { + return ( + + {children} +
+
- )) - } - - render() { - // find longest list value in number of characters - const MIN_WIDTH = this.props.list.reduce( - (max, { name }) => (name && name.length > max ? name.length : max), - 0 - ) - - return ( -
-
- {this.props.selected ? this.props.selected.name : ''} -
- -
-
-
{this.renderListItems()}
- + + ) +} - .dropdown-display:hover { - background: ${COLORS.HOVER}; - } +const ListItems = ({ children }) => { + return ( +
    + {children} + +
+ ) +} - .is-visible + .dropdown-list { - display: block; - } +const ListItem = ({ children, isHighlighted, isSelected, ...rest }) => { + return ( +
  • + {children} + {isSelected ? : null} + +
  • + ) +} - .dropdown-list { - display: none; - margin-top: -1px; - border: 1px solid ${COLORS.SECONDARY}; - border-radius: 0px 0px 3px 3px; - max-height: 350px; - overflow-y: scroll; - } - `} -
    - ) - } +function minWidth(list) { + return list.reduce((max, { name }) => { + const wordSize = name.length * 12 + return wordSize > max ? wordSize : max + }, 0) } -export default enhanceWithClickOutside(Dropdown) +export default Dropdown diff --git a/package.json b/package.json index 3f146d0..7af0133 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "codemirror-graphql": "^0.6.12", "codemirror-mode-elixir": "^1.1.1", "dom-to-image": "^2.5.2", + "downshift": "^1.28.0", "dropperx": "^0.1.0", "express": "^4.16.2", "form-data": "^2.2.0",