saagie-ui
Version:
Saagie UI from Saagie Design System
150 lines (133 loc) • 3.62 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { withFormsy, propTypes as formsyPropTypes } from 'formsy-react';
import { FormControlSelect } from '../../core/atoms/formControlSelect/FormControlSelect';
import { FormGroup } from '../../core/molecules/formGroup/FormGroup';
const propTypes = {
...formsyPropTypes,
children: PropTypes.node,
disabled: PropTypes.bool,
/**
* Object of props passed to the <FormGroup> component
*/
groupProps: PropTypes.object,
helper: PropTypes.node,
isMulti: PropTypes.bool,
label: PropTypes.node,
onChange: PropTypes.func,
options: PropTypes.array,
placeholder: PropTypes.string,
/**
* Object of props passed to the <FormControlSelect> component
*/
selectProps: PropTypes.object,
};
const defaultProps = {
children: null,
disabled: false,
groupProps: {},
helper: null,
isMulti: false,
label: null,
onChange: () => {},
options: [],
placeholder: null,
selectProps: {},
};
export const FieldSelectUI = ({
// Formsy props
errorMessage,
value,
isFormSubmitted,
isPristine,
isRequired,
isValid,
setValue,
// Global props
children,
disabled,
groupProps,
helper,
label,
onChange,
placeholder,
// Custom props
isMulti,
isGroupOption,
isCreatable,
options,
selectProps,
}) => {
const [isTouched, setIsTouched] = React.useState(false);
const [isFocused, setIsFocused] = React.useState(false);
const isFeedbackVisible = (isTouched && !isPristine) || isFormSubmitted;
const isError = !isValid && isFeedbackVisible;
const getDefaultValue = () => {
if (isGroupOption) {
const optionsConcat = options
.reduce((acc, cur) => (cur.options ? [...acc, ...cur.options] : [...acc]), []);
return (
Array.isArray(value)
? value.map((val) => optionsConcat.find((x) => (x.value === val)))
: optionsConcat.find((x) => (x.value === value))
);
}
return (
Array.isArray(value)
? value.map((val) => options.find((x) => x.value === val)) // Multi
: options.find((x) => (x.value === value)) // Single
);
};
const handleChange = (opt) => {
// Multi
if (Array.isArray(opt)) {
const fieldValue = !opt.length ? null : opt.map((x) => x.value);
setValue(fieldValue);
onChange(fieldValue);
return;
}
// Single
const fieldValue = opt ? opt.value : null;
setValue(fieldValue);
onChange(fieldValue);
};
const handleFocus = () => {
setIsFocused(true);
setIsTouched(true);
};
const handleBlur = () => {
setIsFocused(false);
};
return (
<FormGroup
label={label}
helper={helper}
isOptional={!isRequired}
validationState={!isFocused && isError ? 'danger' : null}
feedbackMessage={isFeedbackVisible && errorMessage}
{...groupProps}
>
<FormControlSelect
isDisabled={disabled}
placeholder={placeholder}
defaultValue={getDefaultValue()}
options={options}
onChange={handleChange}
onFocus={handleFocus}
onBlur={handleBlur}
menuPortalTarget={document.body}
isMulti={isMulti}
isDanger={!isFocused && isError}
isClearable
isCreatable={isCreatable}
isGroupOption={isGroupOption}
isValidNewOption={isCreatable ? (inputValue) => !!inputValue : undefined}
{...selectProps}
/>
{children}
</FormGroup>
);
};
FieldSelectUI.propTypes = propTypes;
FieldSelectUI.defaultProps = defaultProps;
export const FieldSelect = withFormsy(FieldSelectUI);