@s-ui/react-molecule-select

1.74.0 • Public • Published

MoleculeSelect

MoleculeSelect is a customized select created from a combination of AtomInput, MoleculeInputTags, MoleculeDropdownList and MoleculeDropdownOption

It allows Single and Multiple Selection

documentation issue npm

Issues open NPM

Installation

$ npm install @s-ui/react-molecule-select --save

Usage

import MoleculeSelect, {
  moleculeSelectDropdownListSizes
} from '@s-ui/react-molecule-select'
import MoleculeSelectOption from '@s-ui/react-molecule-dropdown-option'

const IconCloseTag = () => <span>x</span>
const IconArrowDown = () => <span></span>

const options = ['John', 'Paul', 'George', 'Ringo']

Single Selection

Basic usage

<MoleculeSelect
  placeholder="Select a Country..."
  onChange={(_, {value}) => console.log(value)}
  iconArrowDown={<IconArrowDown />}
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

With default value

<MoleculeSelect
  placeholder="Select a Country..."
  onChange={(_, {value}) => console.log(value)}
  iconArrowDown={<IconArrowDown />}
  value="John"
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

Large List

<MoleculeSelect
  placeholder="Select a Country..."
  onChange={(_, {value}) => console.log(value)}
  iconArrowDown={<IconArrowDown />}
  size={moleculeSelectDropdownListSizes.LARGE}
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

With a search input

<MoleculeSelect
  placeholder="Select a Country..."
  onChange={(_, {value}) => console.log(value)}
  iconArrowDown={<IconArrowDown />}
  hasSearch
  onSearch={({value}) => console.log(value)}
  searchPlaceholder="Search a country..."
  noResults={
    <div>
      No results found...
    </div>
  }
  size={moleculeSelectDropdownListSizes.LARGE}
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

With state highlight

Can be success, error or alert.

<MoleculeSelect
  placeholder="Select a Country..."
  onChange={(_, {value}) => console.log(value)}
  iconArrowDown={<IconArrowDown />}
  state="success"
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

Multiple Selection

Basic usage

<MoleculeSelect
  iconCloseTag={<IconCloseTag />}
  iconArrowDown={<IconArrowDown />}
  multiselection
  value={['John', 'Paul']}
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

With selected items limit

<MoleculeSelect
  iconCloseTag={<IconCloseTag />}
  iconArrowDown={<IconArrowDown />}
  multiselection
  value={['John', 'Paul']}
  max={2}
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelect>

Managing State

Custom component from MoleculeSelect that handle State

MoleculeSelect is a stateless component, so to manage dynamic options we need to create a wrapper component that manages this and pass proper props and proper children (MoleculeSelectOption) to MoleculeSelect

Example:

import React, {Component} from 'react'

import MoleculeSelect from '@s-ui/react-molecule-select'
import MoleculeSelectOption from '@s-ui/react-molecule-dropdown-option'

const options = ['John', 'Paul', 'George', 'Ringo']

export default class SelectSingleWithAsyncOptions extends Component {
  state = {value: ''}

  onChange = async (e, {value}) => {
    this.setState({value})
  }

  render() {
    const {value} = this.state
    const {onChange, props} = this

    return (
      <MoleculeSelect {...props} value={value} onChange={onChange}>
        {options.map((option, i) => (
          <MoleculeSelectOption key={i} value={option}>
            {option}
          </MoleculeSelectOption>
        ))}
      </MoleculeSelect>
    )
  }
}

so then, the SelectSingleWithAsyncOptions can used in this way...

<SelectSingleWithAsyncOptions iconClear={<IconClear />} />

Using the hoc withStateValue

There's a hoc called withStateValue available at @s-ui/hoc that can be used to simplify the use of this component with internal state

import MoleculeSelect from '@s-ui/react-molecule-select'
import MoleculeSelectOption from '@s-ui/react-molecule-dropdown-option'

import withDynamicOptions from './hoc/withDynamicOptions'
import {withStateValue} from '@s-ui/hoc'

const MoleculeSelectWithState = withStateValue(MoleculeSelect)
const options = ['John', 'Paul', 'George', 'Ringo']

so then, the MoleculeSelectWithState can be used in this way...

<MoleculeSelectWithState
  placeholder="Type a Country name..."
  onChange={(_, {value}) => console.log(value)}
  iconClear={<IconClear />}
>
  {options.map((option, i) => (
    <MoleculeSelectOption key={i} value={option}>
      {option}
    </MoleculeSelectOption>
  ))}
</MoleculeSelectWithState>

Create custom option compatible w/ MoleculeSelect

If you need an option that cannot be customized from MoleculeDropdownOption you can create your own option compatible w/ MoleculeSelect y MoleculeSelect by using the handlersFactory method available in MoleculeDropdownOption that you can use to create proper handlers needed to work properly along w/ MoleculeSelect y MoleculeSelect

import React from 'react'
import {handlersFactory} from '@s-ui/react-molecule-dropdown-option'

const BASE_CLASS = 'AlternativeOption'

const AlternativeOption = ({children, onSelect, innerRef, value}) => {
  const {handleClick, handleKeyDown, handleFocus} = handlersFactory({
    value,
    onSelect
  })

  return (
    <div
      className={BASE_CLASS}
      ref={innerRef}
      tabIndex="0"
      onFocus={handleFocus}
      onClick={handleClick}
      onKeyDown={handleKeyDown}
    >
      {children}
    </div>
  )
}

AlternativeOption.displayName = 'AlternativeOption'

AlternativeOption.defaultProps = {
  onSelect: () => {},
  innerRef: React.createRef()
}

export default AlternativeOption

so then you can do something like...

<MoleculeSelect
  placeholder="Select an Option..."
  onChange={(_, {value}) => console.log(value)}
  iconArrowDown={<IconArrowDown />}
>
  {options.map((option, i) => (
    <AlternativeOption key={i} value={option}>
      {option}
    </AlternativeOption>
  ))}
</MoleculeSelect>

Find full description and more examples in the demo page.

Package Sidebar

Install

npm i @s-ui/react-molecule-select

Weekly Downloads

7,892

Version

1.74.0

License

MIT

Unpacked Size

37.2 kB

Total Files

13

Last publish

Collaborators

  • sergi.martinez.adevinta
  • arnau.guell
  • miriam-gil
  • andresin87.adevinta
  • alfredo.narvaez
  • sendami.luque.ext
  • sebastian.badea.adevinta
  • thomas.page.ext
  • victoria.pasichnyk.ext
  • daniel.perez.ext
  • albert.peiro
  • frandelacasa-adevinta
  • mariapaula.forero.ext
  • hpintos_adevinta
  • sziauberyte
  • victor.perez.adevinta
  • oscar-raig-adevinta
  • carlos.gonzalezl
  • carolina.mallo.ext
  • david.nieto
  • ferran.simon
  • sergi.quintela
  • jamile.radloff
  • xavi_ballestar
  • luz_adv
  • ignacio.rodriguez
  • carlosvillu-adevinta
  • diegomr
  • arturo.vicente
  • adria.velardos
  • emiliovz
  • dann41
  • ruben-martin
  • pol.valls
  • cristina.rodriguez.duque
  • sergio.escano
  • marc.benito
  • azahara
  • patricio.sartore
  • giovanny.sayas.ext
  • david.cuadrado.ext
  • alex.castells
  • beatrizip
  • pablo.rey-adevinta
  • sergiocollado
  • cristhianb
  • alisa_bayanova
  • davidmartin2108
  • ferrangbtw
  • estefania_garcia
  • belen.santos
  • alfredo.arronte
  • joanleon-adv
  • luis-garrido
  • aitor.rodriguez
  • jordi.munoz
  • oscar_ramirez
  • ignacio_navarro
  • a.ferrer
  • gfabregoadv
  • izeller
  • salvador.juan
  • ivanmlaborda
  • alejandro.ferrante
  • pa.chruscinski.ext
  • isabelgomez87
  • jenifer.lopez
  • pablogs
  • javier.miguel
  • oscar.gomez
  • marian.lucaci
  • alverd004
  • oriol.puig
  • nacho_torrella
  • xavi.murcia
  • javiauso
  • alfredo.zimperz
  • francisco.ruiz.lloret
  • andresadv
  • schibstedspain