import React from 'react' ; import Select , { ValueType } from 'react-select' ; import Chevron from 'src/components/assets/chevron' ; import { Language , t } from 'src/i18n' ; import { Filter , UpdateFilter } from 'src/state' ; import styled from '../styling' ; import { AppContext } from './context' ; type OptionType = { value : string | undefined ; label : string ; } ; param className param translationKey param filterScreenField param dropDownValues param isMulti param placeholder param updateFilter interface DropDownProps < IsMulti extends boolean > { className ? : string ; translationKey : string ; filterScreenField : keyof Filter ; dropDownValues : readonly string [ ] ; isMulti ? : IsMulti ; placeholder ? : string ; updateFilter : UpdateFilter ; } interface DropDownState { selectedValues : string | string [ ] | undefined ; } class DropDown < IsMulti extends boolean > extends React . Component < DropDownProps < IsMulti > , DropDownState > { constructor ( props ) { super ( props ) ; this . state = { selectedValues : props . isMulti ? ( [ ] as string [ ] ) : undefined , } ; } private onChangeHandler = ( fieldName , selected ) : void => { const { updateFilter , isMulti } = this . props ; let newVal ; if ( selected ) { newVal = isMulti ? ( selected as OptionType [ ] ) . map ( selectedOption => selectedOption . value as string ) : ( selected as OptionType ) . value ; } this . setState ( { selectedValues : newVal } ) ; if ( newVal && typeof newVal !== 'string' ) { newVal = new Set ( newVal ) ; } updateFilter ( fieldName , newVal ) ; } ; param translationObject param propKey param valueKey return private lookUpValue = ( translationObject , propKey , valueKey ) : string | undefined => { let val = translationObject ; const keys = propKey . split ( '.' ) ; keys . forEach ( key => { val = val [ key ] ; } ) ; return val [ valueKey ] ; } ; private getLabel = ( lang , translationKey , value ) => t ( lang , translationObject => this . lookUpValue ( translationObject , translationKey , value ) as string ) ; private SelectComponent = ( lang ) => { const { className , dropDownValues , translationKey , filterScreenField , isMulti , placeholder , } = this . props ; const { selectedValues } = this . state ; const optionsMap = new Map ( dropDownValues . map ( value => [ value , { value , label : this . getLabel ( lang , translationKey , value ) , } , ] ) ) ; const any = { value : undefined , label : t ( lang , translationObject => this . lookUpValue ( translationObject , translationKey , 'any' ) ? ( this . lookUpValue ( translationObject , translationKey , 'any' ) as string ) : translationObject . services . any ) , } ; const options = isMulti ? [ ... optionsMap . values ( ) ] : [ any , ... optionsMap . values ( ) ] ; const value = isMulti ? ( selectedValues as string [ ] ) . map ( val => optionsMap . get ( val ) as OptionType ) : selectedValues ? optionsMap . get ( selectedValues as string ) : any ; return ( < Select menuPosition = "fixed" className = { className } isMulti = { isMulti } classNamePrefix = "select" value = { value } defaultValue = { isMulti ? undefined : any } noOptionsMessage = { ( ) => t ( lang , translationObject => translationObject . noOptions ) } onChange = { selected => this . onChangeHandler ( filterScreenField , selected ) } placeholder = { placeholder } options = { options } isSearchable = { false } components = { { DropdownIndicator : ( ) => < Chevron className = "chevron" / > , IndicatorSeparator : ( ) => null , } } />); } ; public render ( ) { return ( < AppContext . Consumer > { ( { lang } ) => this . SelectComponent ( lang ) } < /AppContext.Consumer>); } } export default styled ( DropDown ) `
  .select__control {
    border: 1px solid ${ p => p . theme . colors . borderBase };
    box-shadow: none;
    cursor: pointer;
    background: none;
    border-radius: 4px;
    justify-content: center;
    align-items: middle;
    min-height: initial;
    padding: 6px 8px;
    font-size: 14px;
    line-height: 20px;
    color: ${ p => p . theme . colors . brand . primaryDark1 };

    .chevron {
      color: ${ p => p . theme . colors . brand . primaryDark1 };
      opacity: 0.6;
      margin: 0 2px;
    }

    .select__value-container {
      margin: 0;
      padding: 0;
      min-height: 22px;
    }

    &.select__control--menu-is-open {
      .chevron {
        transform: rotate(180deg);
      }
    }

    .select__placeholder {
      color: ${ p => p . theme . colors . gray };
      opacity: 0.75;
    }

    &:hover,
    &.select__control--is-focused {
      border-color: ${ p => p . theme . colors . brand . primaryDark };
      .single-value,
      .chevron {
        color: ${ p => p . theme . colors . brand . primaryDark };
      }
    }
  }
  .select__menu {
    width: initial;
    min-width: 100%;
    font-size: 14px;
  }
  .select__option {
    cursor: pointer;
    white-space: nowrap;
  }
  .select__option--is-focused {
    background: ${ p => p . theme . colors . brand . primaryLight1 };
  }
  .select__option--is-selected {
    background: ${ p => p . theme . colors . brand . primary };
  }
` ;