UNPKG

oneframe-react

Version:

Oneframe React ## Components, Hooks, Helper Functions & State Management

206 lines (205 loc) 11.2 kB
"use strict"; 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);