UNPKG

@patreon/studio

Version:

Patreon Studio Design System

59 lines (58 loc) 3.27 kB
'use client'; import React from 'react'; import { useSequentialId } from '../../hooks/useSequentialId'; import { useTestIdGenerator } from '../../hooks/useTestIdGenerator'; import { isRequired } from '../../utilities/isRequired'; import { IconChevronDownAlt } from '../Icon'; import { InlineError } from '../InlineError'; import { InlineHelpText } from '../InlineHelpText'; import { InlineSuccess } from '../InlineSuccess'; import { Label } from '../Label'; import { InputWrapper, LabelWrapper, SelectWrapper, StyledSelect, IconWrapper } from './components'; export const Select = React.forwardRef(function Select({ 'aria-label': ariaLabel, 'data-tag': dataTag, disabled, error, helperText, id, loading, onChange, options, primaryLabel, required, secondaryLabel, success, width = 'default', variant = 'outlined', corners = 'rounded', ...props }, ref) { const multipleDefaults = options.filter((el) => el.defaultSelected === true).length > 1; if (multipleDefaults) { throw new Error('Multiple options are set as `defaultSelected` which will put `Select` in an indeterminate state. The `defaultSelected` prop can only be set on one option.'); } const localId = useSequentialId('Select'); const thisId = id ?? localId ?? ''; const primaryLabelId = `${thisId}-primary-label`; const secondaryLabelId = `${thisId}-secondary-label`; const errorId = InlineError.getErrorId(thisId); const successId = InlineSuccess.getSuccessId(thisId); const helpTextId = `${thisId}-help`; const getTestId = useTestIdGenerator(dataTag); const describedBy = []; if (error) { describedBy.push(errorId); } if (success) { describedBy.push(successId); } if (helperText) { describedBy.push(helpTextId); } return (<InputWrapper disabled={disabled} isFluid={width === 'fluid'}> <LabelWrapper primaryLabel={primaryLabel} secondaryLabel={secondaryLabel}> {primaryLabel && (<Label data-tag={getTestId('primaryLabel')} id={primaryLabelId} error={!!error} htmlFor={id}> {primaryLabel} {isRequired(required) && ' *'} </Label>)} {secondaryLabel && (<Label secondary data-tag={getTestId('secondaryLabel')} id={secondaryLabelId} error={!!error} htmlFor={id}> {secondaryLabel} </Label>)} </LabelWrapper> <SelectWrapper> <StyledSelect id={id} ref={ref} error={error} variant={variant} disabled={disabled} onChange={onChange} defaultValue={options.find((el) => el.defaultSelected === true)?.value} aria-describedby={describedBy.length ? describedBy.join(' ') : undefined} aria-required={isRequired(required)} aria-label={ariaLabel} data-tag={dataTag} corners={corners} {...props}> {options.map(({ value, label, disabled: optionDisabled }) => (<option value={value} key={value} disabled={optionDisabled}> {label} </option>))} </StyledSelect> <IconWrapper> <IconChevronDownAlt size="20px"/> </IconWrapper> </SelectWrapper> <InlineHelpText id={helpTextId} inputId={thisId} helpText={helperText} error={error} success={success} loading={loading} data-tag={dataTag}/> </InputWrapper>); }); //# sourceMappingURL=Select.jsx.map