@patreon/studio
Version:
Patreon Studio Design System
59 lines (58 loc) • 3.27 kB
JSX
'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