@navinc/base-react-components
Version:
Nav's Pattern Library
79 lines (72 loc) • 2.44 kB
JavaScript
import React from 'react'
import styled from 'styled-components'
import Copy from './copy.js'
import { moz } from './helpers/target-vendor.js'
import { Chevron, Label, Input, Field, Errors, Err, FieldWrapper, Helper } from './form-elements/shared.js'
import isRebrand from './is-rebrand.js'
const SelectField = styled(Input).attrs(() => ({ as: 'select' }))`
width: 100%;
appearance: none;
color: inherit;
cursor: pointer;
font-size: 16px;
padding-right: 3em;
outline: 0;
${moz`
// Selects in firefox have extra, unstylable, 3px of whitespace around the text.
padding-left: 10px;
// Focusable elements in firefox have a focus ring around sub-elements.
&:-moz-focusring {
color: transparent;
text-shadow:0 0 0 ${({ theme }) => (isRebrand(theme) ? theme.navNeutral500 : theme.neutral500)};
}
&:-moz-focusring * {
color: ${({ theme }) => (isRebrand(theme) ? theme.navNeutral500 : theme.neutral500)};
text-shadow:none;
}
`}
& > * {
/** for firefox. also note that you cant style for safari **/
font-family: ${({ theme }) => theme.fontPrimary};
font-weight: normal;
}
`
const defaultValue = { label: '...', value: '' }
const Select = ({
className,
label,
hasSpaceForErrors,
helperText,
isInvalid,
options = [],
value = defaultValue,
required,
errors = [],
lede = '',
onChange = (event) => event.target.value,
...props
}) => (
<FieldWrapper className={className}>
{lede && <Copy bold>{lede}</Copy>}
<Field isInvalid={isInvalid} isVisited required={required}>
<Chevron isInvalid={isInvalid} />
<SelectField onChange={onChange} required={required} value={value} isInvalid={isInvalid} {...props}>
{[defaultValue, ...options].map((option) => {
const { label = option.label || option, value = option.value || option } = option
return (
<option key={`${label}:${value}`} value={value} hidden={!value}>
{label}
</option>
)
})}
</SelectField>
<Label required={required}>{label}</Label>
</Field>
{helperText && <Helper hasSpaceForHelper={hasSpaceForErrors} helperText={helperText} />}
<Errors hasSpaceForErrors={hasSpaceForErrors}>
{!!errors.length && errors.map((err, i) => <Err key={`err-${i}`}>{err}</Err>)}
</Errors>
</FieldWrapper>
)
Select.displayName = 'Select'
export default styled(Select)``