UNPKG

@axeptio/design-system

Version:
249 lines (232 loc) 6.01 kB
import React from 'react'; import ReactSelect, { components } from 'react-select'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { axeptio } from '../../../Presets'; const DropdownIndicator = props => { return ( <components.DropdownIndicator {...props}> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22" className="select-icon"> <path d="M7.41,8.59L12,13.17l4.59-4.58L18,10l-6,6l-6-6L7.41,8.59z" /> </svg> </components.DropdownIndicator> ); }; const RootMobile = styled.select` font-family: ${props => props.theme.fonts.text}; width: 100%; outline: none !important; appearance: none !important; background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' fill='%23acacac' width='22' height='22' viewBox='0 0 22 22'><path d='M7.41,8.59L12,13.17l4.59-4.58L18,10l-6,6l-6-6L7.41,8.59z'></path></svg>") right no-repeat; background-position: right 8px bottom 15px; font-size: 13px; font-weight: 400; line-height: 1.25; height: auto; min-height: 34px; border-radius: 6px; color: ${props => props.theme.colors.grey.v500}; background-color: ${props => props.theme.colors.white}; border: 1px solid ${props => props.theme.colors.grey.v300}; cursor: pointer; transition: all 100ms ease; &:focus { border: 1px solid ${props => props.theme.colors.primary}; box-shadow: 0 0 0 3px rgb(255 200 35 / 25%); } ${props => props.small && ` padding: 4px; `}; ${props => props.large && ` min-height: 56px; padding: 8px; `}; `; const Root = styled(ReactSelect)` font-family: ${props => props.theme.fonts.text}; .select-icon { fill: ${props => props.theme.colors.grey.v400}; } &:hover .select-icon { fill: ${props => props.theme.colors.secondary}; } ${props => props.small && ` .axeptio-select__control { padding: 2px 0; } .axeptio-select__indicators .axeptio-select__indicator{ padding: 4px; } `}; ${props => props.large && ` .axeptio-select__control { min-height: 54px; padding: 8px 0; } `}; .axeptio-select__indicator-separator { display: none; } `; const customStyles = { option: (provided, state) => ({ ...provided, cursor: 'pointer', zIndex: 2000, fontSize: '13px', fontWeight: state.isSelected ? 'bold' : 'normal', color: axeptio.colors.grey.v500, backgroundColor: state.isFocused ? axeptio.colors.grey['grey-50'] : 'transparent', ':active': { ...provided[':active'], backgroundColor: state.isSelected ? axeptio.colors.grey.v200 : axeptio.colors.primaryPalette.v50 }, borderLeft: state.isSelected ? '2px solid' + axeptio.colors.primary : 'none' }), control: (provided, state) => ({ ...provided, outline: 'none !important', appearance: 'none !important', fontFamily: axeptio.fonts.text, fontSize: '13px', fontWeight: '400', lineHeight: '1.25', height: 'auto', minHeight: '34px', borderRadius: '6px', color: axeptio.colors.grey.v500, backgroundColor: axeptio.colors.white, border: state.isFocused ? '1px solid ' + axeptio.colors.primary : '1px solid ' + axeptio.colors.grey.v300, cursor: 'pointer', transition: 'all 100ms ease', boxShadow: state.isFocused ? '0 0 0 3px rgb(255 200 35 / 25%)' : 'none', ':hover': { ...provided[':hover'], borderColor: state.isFocused ? axeptio.colors.primary : '' } }), multiValue: provided => ({ ...provided, color: axeptio.colors.grey.v500, backgroundColor: axeptio.colors.primary }), menu: provided => ({ ...provided, zIndex: 10000, fontFamily: axeptio.fonts.text }) }; const Select = props => { const { name, multi, value, options, onChange, onClear, placeholder, closeMenuOnSelect, small, large, optionsMessage, hideSelectedOptions, isSearchable, isDisabled, menuIsOpen, browser } = props; if (browser && !multi) { return ( <RootMobile name={name} value={value?.label} options={options} onChange={val => { onChange(val.target.value); }} placeholder={placeholder} small={small} large={large} isDisabled={isDisabled} > {options.map((data, index) => { return ( <option key={index} value={data.value}> {data.label} </option> ); })} </RootMobile> ); } return ( <Root styles={customStyles} classNamePrefix="axeptio-select" components={{ DropdownIndicator }} name={name} isMulti={multi} value={value} options={options} onChange={val => { onChange(val); }} clearValue={() => { onClear(); }} placeholder={placeholder} closeMenuOnSelect={closeMenuOnSelect} small={small} large={large} noOptionsMessage={() => { return <span>{optionsMessage}</span>; }} hideSelectedOptions={hideSelectedOptions} isSearchable={isSearchable} isDisabled={isDisabled} menuIsOpen={menuIsOpen} {...props} /> ); }; Select.propTypes = { name: PropTypes.string, small: PropTypes.bool, large: PropTypes.bool, multi: PropTypes.string, value: PropTypes.any, options: PropTypes.array, onChange: PropTypes.func, onClear: PropTypes.func, placeholder: PropTypes.string, closeMenuOnSelect: PropTypes.bool, optionsMessage: PropTypes.string, hideSelectedOptions: PropTypes.bool, isSearchable: PropTypes.bool, isDisabled: PropTypes.bool, menuIsOpen: PropTypes.bool, browser: PropTypes.bool }; Select.defaultProps = { name: '', small: false, large: true, multi: false, value: null, options: [], onChange: null, placeholder: '', closeMenuOnSelect: true, isSearchable: false, browser: false }; export default Select;