oneframe-react
Version:
Oneframe React ## Components, Hooks, Helper Functions & State Management
206 lines (205 loc) • 11.2 kB
JavaScript
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const lodash_1 = require("lodash");
const lab_1 = require("@material-ui/lab");
const core_1 = require("@material-ui/core");
const use_debounce_1 = require("use-debounce");
const fast_memoize_1 = __importDefault(require("fast-memoize"));
const utility_1 = require("../../../utility");
const withValidate_1 = require("../../Form/withValidate");
const prop_types_1 = __importDefault(require("prop-types"));
const AutocompleteComponent = (props) => {
const { id, name, options, multiple, freeWriting, disabled, setValidate, validate, errorText, variant = 'outlined', caption, placeholder, captionActive, autoFocus = false, readOnly, required, helperText, fullWidth = true, className, disableUnderline = false, onChange, onRef, onKeyPress, onKeyDown, onKeyUp, validateMessages, closeOnSelect, groupPath, group, loading, open, onOpen, onClose, noOptionsDataText, loadingText, closeIcon, popupIcon, } = props;
const { data, selected, displayValue, displayField } = options;
const input = react_1.useRef();
react_1.useEffect(() => {
onRef && onRef(input);
});
const getSelected = () => {
if (multiple) {
const selectedData = [];
selected &&
lodash_1.isArray(selected) &&
data &&
data.length &&
selected.length &&
selected.forEach((item) => {
const count = data.filter((a) => a[displayValue] === item);
if (count.length) {
selectedData.push(count[0]);
}
else {
selectedData.push({
[displayField]: item,
[displayValue]: item,
});
}
});
return selectedData;
}
const selectedSingleData = selected ? data.filter((a) => a[displayValue] === selected) : [];
return selected && selectedSingleData.length ? selectedSingleData[0] : selected;
};
const initialSelect = () => getSelected();
const [inputFieldValue, setValue] = react_1.useState(initialSelect());
const [optionsData, setOptionsData] = react_1.useState([]);
const [fieldId, setFieldId] = react_1.useState(id);
const setValidateData = fast_memoize_1.default((value) => {
let resultValue = null;
let resultValueObject = null;
if (multiple) {
resultValue = value.length ? value.map((valueItem) => valueItem[displayValue]) : [];
resultValueObject = value;
}
else {
resultValue = value ? (typeof value !== 'string' ? value[displayValue] : value) : '';
resultValueObject = value
? typeof value !== 'string'
? value
: { [displayValue]: value, [displayField]: value }
: '';
}
data && onChange && onChange(utility_1.getTargetSelectValue(id, name, resultValue, resultValueObject));
fieldId && !disabled && validate && setValidate && setValidate(fieldId, value, validate, errorText);
});
const [debounceFunc] = use_debounce_1.useDebouncedCallback((value) => setValidateData(value), 250);
react_1.useEffect(() => {
setValue(getSelected());
// eslint-disable-next-line
}, [selected, setValue]);
react_1.useEffect(() => {
debounceFunc(inputFieldValue);
}, [inputFieldValue, debounceFunc, disabled]);
react_1.useEffect(() => {
const dataGroup = data && data.length
? data.map((option) => {
const firstLetter = groupPath
? lodash_1.get(option, groupPath || '')
: option[displayField][0].toUpperCase();
return Object.assign({ firstLetter: /[0-9]/.test(firstLetter) ? '0-9' : firstLetter }, option);
})
: [];
setOptionsData(dataGroup.sort((a, b) => -b.firstLetter.localeCompare(a.firstLetter)));
}, [data, displayField, groupPath]);
const handleChange = (val) => {
const tempVal = val;
if (multiple && freeWriting) {
tempVal.length &&
tempVal.forEach((item, i) => {
if (typeof item === 'string') {
tempVal[i] = {
[displayValue]: item,
[displayField]: item,
};
}
});
}
setValue(tempVal);
};
return (react_1.default.createElement(lab_1.Autocomplete, Object.assign({ multiple: multiple || false, freeSolo: freeWriting, options: optionsData }, (group
? {
groupBy: (option) => groupPath ? lodash_1.get(option, groupPath || '') : option[displayField][0].toUpperCase(),
}
: {}), { value: inputFieldValue, clearOnEscape: true, disableCloseOnSelect: closeOnSelect, getOptionLabel: (option) => (option && option[displayField]) || (!multiple ? inputFieldValue : ''), renderTags: (value, getTagProps) => value.map((option, index) => (react_1.default.createElement(core_1.Chip, Object.assign({ label: option[displayField] }, getTagProps({ index }), { key: index })))), open: open, onOpen: () => onOpen && onOpen(), onClose: () => onClose && onClose(), className: "oneframe-form-field oneframe-form-autocomplete", noOptionsText: noOptionsDataText, loadingText: loadingText, disabled: disabled, closeIcon: closeIcon, popupIcon: popupIcon, onInputChange: (_, val) => {
if (val && freeWriting && !multiple) {
setValue(val);
}
}, renderInput: (params) => {
setFieldId(params.id);
return (react_1.default.createElement(core_1.TextField, Object.assign({}, params, { inputProps: Object.assign(Object.assign({}, params.inputProps), { className: params.inputProps.className + ' oneframe-input' }), InputProps: Object.assign(Object.assign(Object.assign(Object.assign({}, params.InputProps), { className: `${params.InputProps.className} oneframe-input-base oneframe-input-autocomplete ${multiple ? 'oneframe-input-multiple' : 'oneframe-input-single'} `, readOnly }), (variant === 'filled' ? { disableUnderline } : {})), { endAdornment: (react_1.default.createElement(react_1.default.Fragment, null,
loading ? react_1.default.createElement(core_1.CircularProgress, { color: "inherit", size: 20 }) : null,
params.InputProps.endAdornment)) }), InputLabelProps: Object.assign(Object.assign({}, params.InputLabelProps), (props.hasOwnProperty('captionActive') && captionActive ? { shrink: true } : {})), label: caption, variant: variant, placeholder: placeholder, className: className, fullWidth: fullWidth, spellCheck: false, required: required, autoFocus: autoFocus, disabled: disabled, error: utility_1.getErrorStatus(validateMessages, fieldId, errorText), helperText: utility_1.getErrorMessage(validateMessages, fieldId, errorText, helperText), onKeyPress: (e) => {
e.key === 'Enter' && e.preventDefault();
onKeyPress && onKeyPress(e);
}, onKeyDown: (e) => {
e.key === 'Enter' && e.preventDefault();
onKeyDown && onKeyDown(e);
}, onKeyUp: (e) => {
e.key === 'Enter' && e.preventDefault();
onKeyUp && onKeyUp(e);
} })));
}, ref: input, onChange: (e, val) => handleChange(val) })));
};
AutocompleteComponent.propTypes = {
id: prop_types_1.default.string.isRequired,
name: prop_types_1.default.string.isRequired,
className: prop_types_1.default.string,
caption: prop_types_1.default.string,
errorText: prop_types_1.default.string,
placeholder: prop_types_1.default.string,
helperText: prop_types_1.default.string,
noOptionsDataText: prop_types_1.default.string,
groupPath: prop_types_1.default.string,
captionActive: prop_types_1.default.bool,
readOnly: prop_types_1.default.bool,
disableUnderline: prop_types_1.default.bool,
submitStatus: prop_types_1.default.bool,
autoFocus: prop_types_1.default.bool,
disabled: prop_types_1.default.bool,
required: prop_types_1.default.bool,
fullWidth: prop_types_1.default.bool,
multiple: prop_types_1.default.bool,
closeOnSelect: prop_types_1.default.bool,
freeWriting: prop_types_1.default.bool,
loading: prop_types_1.default.bool,
group: prop_types_1.default.bool,
variant: prop_types_1.default.oneOf(['standard', 'outlined', 'filled']),
onRef: prop_types_1.default.func,
onChange: prop_types_1.default.func,
onKeyPress: prop_types_1.default.func,
onKeyDown: prop_types_1.default.func,
onKeyUp: prop_types_1.default.func,
validate: prop_types_1.default.arrayOf(prop_types_1.default.shape({
required: prop_types_1.default.oneOf([
'required',
'maxSelect',
'minSelect',
'min',
'max',
'maxLength',
'minLength',
'custom',
'email',
'pattern',
'url',
'creditcard',
'number',
]),
message: prop_types_1.default.string.isRequired,
regex: prop_types_1.default.any,
validate: prop_types_1.default.oneOfType([prop_types_1.default.func, prop_types_1.default.bool]),
value: prop_types_1.default.oneOfType([prop_types_1.default.string, prop_types_1.default.number]),
})),
setValidate: prop_types_1.default.any,
validateMessages: prop_types_1.default.any,
ref: prop_types_1.default.any,
error: prop_types_1.default.any,
closeIcon: prop_types_1.default.node,
popupIcon: prop_types_1.default.node,
loadingText: prop_types_1.default.node,
options: prop_types_1.default.shape({
data: prop_types_1.default.arrayOf(prop_types_1.default.any).isRequired,
displayValue: prop_types_1.default.string.isRequired,
displayField: prop_types_1.default.string.isRequired,
selected: prop_types_1.default.any,
disabled: prop_types_1.default.any,
}),
};
exports.AutocompleteTmp = AutocompleteComponent;
const MemoComponent = react_1.default.memo(AutocompleteComponent, (p, n) => lodash_1.isEqual(p.options, n.options) &&
lodash_1.isEqual(p.validateMessages, n.validateMessages) &&
lodash_1.isEqual(p.disabled, n.disabled) &&
lodash_1.isEqual(p.loading, n.loading) &&
lodash_1.isEqual(p.caption, n.caption));
exports.default = withValidate_1.withValidate(MemoComponent);
;