UNPKG

mui-rff

Version:

Set of modern wrapper components to facilitate using Material UI with React Final Form

745 lines (653 loc) 28.5 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var React = require('react'); var React__default = _interopDefault(React); var reactFinalForm = require('react-final-form'); var TextField$1 = _interopDefault(require('@material-ui/core/TextField')); var MuiAutocomplete = _interopDefault(require('@material-ui/lab/Autocomplete')); var core = require('@material-ui/core'); var pickers = require('@material-ui/pickers'); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var Autocomplete = function Autocomplete(props) { var name = props.name, fieldProps = props.fieldProps, rest = _objectWithoutPropertiesLoose(props, ["name", "fieldProps"]); return React__default.createElement(reactFinalForm.Field, Object.assign({ name: name, render: function render(fieldRenderProps) { return React__default.createElement(AutocompleteWrapper, Object.assign({}, fieldRenderProps, rest)); } }, fieldProps)); }; var AutocompleteWrapper = function AutocompleteWrapper(props) { var _props$input = props.input, onChange = _props$input.onChange, value = _props$input.value, restInput = _objectWithoutPropertiesLoose(_props$input, ["name", "onChange", "value"]), meta = props.meta, options = props.options, label = props.label, required = props.required, multiple = props.multiple, textFieldProps = props.textFieldProps, getOptionValue = props.getOptionValue, rest = _objectWithoutPropertiesLoose(props, ["input", "meta", "options", "label", "required", "multiple", "textFieldProps", "getOptionValue"]); function getValue(values) { if (!getOptionValue) { return values; } // ternary hell... return multiple ? values ? values.map(getOptionValue) : null : values ? getOptionValue(values) : null; } var helperText = rest.helperText, lessrest = _objectWithoutPropertiesLoose(rest, ["helperText"]); var showError = (meta.submitError && !meta.dirtySinceLastSubmit || meta.error) && meta.touched; var _ref = textFieldProps || {}, variant = _ref.variant, restTextFieldProps = _objectWithoutPropertiesLoose(_ref, ["variant"]); // yuck... var defaultValue = null; if (!getOptionValue) { defaultValue = value; } else if (value !== null) { options.forEach(function (option) { var optionValue = getOptionValue(option); if (multiple) { if (!defaultValue) defaultValue = []; value.forEach(function (v) { if (v === optionValue) { defaultValue.push(option); } }); } else { if (value === optionValue) { defaultValue = option; } } }); } var onChangeFunc = function onChangeFunc(_e, values) { return onChange(getValue(values)); }; return React__default.createElement(MuiAutocomplete, Object.assign({ multiple: multiple, onChange: onChangeFunc, options: options, value: defaultValue, renderInput: function renderInput(params) { return React__default.createElement(TextField$1, Object.assign({ label: label, required: required, fullWidth: true, error: showError, helperText: showError ? meta.error || meta.submitError : helperText, variant: variant }, params, restInput, restTextFieldProps)); } }, lessrest)); }; function Checkboxes(props) { var required = props.required, label = props.label, data = props.data, name = props.name, helperText = props.helperText, fieldProps = props.fieldProps, formControlProps = props.formControlProps, formGroupProps = props.formGroupProps, formLabelProps = props.formLabelProps, formControlLabelProps = props.formControlLabelProps, formHelperTextProps = props.formHelperTextProps, restCheckboxes = _objectWithoutPropertiesLoose(props, ["required", "label", "data", "name", "helperText", "fieldProps", "formControlProps", "formGroupProps", "formLabelProps", "formControlLabelProps", "formHelperTextProps"]); var formState = reactFinalForm.useFormState(); var errors = formState.errors, submitErrors = formState.submitErrors, submitFailed = formState.submitFailed, modified = formState.modified; var _useState = React.useState(null), errorState = _useState[0], setErrorState = _useState[1]; React.useEffect(function () { var showError = (!!errors[name] || !!submitErrors) && (submitFailed || modified && modified[name]); setErrorState(showError ? errors[name] || submitErrors[name] : null); }, [errors, submitErrors, submitFailed, modified, name]); var itemsData = !Array.isArray(data) ? [data] : data; var single = itemsData.length === 1; return React__default.createElement(core.FormControl, Object.assign({ required: required, error: !!errorState }, formControlProps), label ? React__default.createElement(core.FormLabel, Object.assign({}, formLabelProps), label) : React__default.createElement(React__default.Fragment, null), React__default.createElement(core.FormGroup, Object.assign({}, formGroupProps), itemsData.map(function (item, idx) { return React__default.createElement(core.FormControlLabel, Object.assign({ key: idx, name: name, label: item.label, value: single ? undefined : item.value, disabled: item.disabled, control: React__default.createElement(reactFinalForm.Field, Object.assign({ type: "checkbox", name: name }, fieldProps), function (_ref) { var _ref$input = _ref.input, name = _ref$input.name, value = _ref$input.value, onChange = _ref$input.onChange, checked = _ref$input.checked, restInput = _objectWithoutPropertiesLoose(_ref$input, ["name", "value", "onChange", "checked"]); return React__default.createElement(core.Checkbox, Object.assign({ name: name, value: value, onChange: onChange, checked: checked, inputProps: _extends({ required: required }, restInput) }, restCheckboxes)); }) }, formControlLabelProps)); })), !!errorState ? React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), errorState) : !!helperText && React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), helperText)); } function Switches(props) { var name = props.name, data = props.data, label = props.label, required = props.required, helperText = props.helperText, fieldProps = props.fieldProps, formControlProps = props.formControlProps, formGroupProps = props.formGroupProps, formLabelProps = props.formLabelProps, formControlLabelProps = props.formControlLabelProps, formHelperTextProps = props.formHelperTextProps, restSwitches = _objectWithoutPropertiesLoose(props, ["name", "data", "label", "required", "helperText", "fieldProps", "formControlProps", "formGroupProps", "formLabelProps", "formControlLabelProps", "formHelperTextProps"]); var formState = reactFinalForm.useFormState(); var errors = formState.errors, submitErrors = formState.submitErrors, submitFailed = formState.submitFailed, modified = formState.modified; var _useState = React.useState(null), errorState = _useState[0], setErrorState = _useState[1]; React.useEffect(function () { var showError = (!!errors[name] || !!submitErrors) && (submitFailed || modified && modified[name]); setErrorState(showError ? errors[name] || submitErrors[name] : null); }, [errors, submitErrors, submitFailed, modified, name]); var itemsData = !Array.isArray(data) ? [data] : data; var single = itemsData.length === 1; return React__default.createElement(core.FormControl, Object.assign({ required: required, error: !!errorState }, formControlProps), label ? React__default.createElement(core.FormLabel, Object.assign({}, formLabelProps), label) : React__default.createElement(React__default.Fragment, null), React__default.createElement(core.FormGroup, Object.assign({}, formGroupProps), itemsData.map(function (item, idx) { return React__default.createElement(core.FormControlLabel, Object.assign({ key: idx, name: name, label: item.label, value: single ? undefined : item.value, disabled: item.disabled, control: React__default.createElement(reactFinalForm.Field, Object.assign({ type: "checkbox", name: name }, fieldProps), function (_ref) { var _ref$input = _ref.input, name = _ref$input.name, value = _ref$input.value, onChange = _ref$input.onChange, checked = _ref$input.checked, restInput = _objectWithoutPropertiesLoose(_ref$input, ["name", "value", "onChange", "checked"]); return React__default.createElement(core.Switch, Object.assign({ name: name, value: value, onChange: onChange, checked: checked, inputProps: _extends({ required: required }, restInput) }, restSwitches)); }) }, formControlLabelProps)); })), !!errorState ? React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), errorState) : !!helperText && React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), helperText)); } function Radios(props) { var name = props.name, data = props.data, label = props.label, required = props.required, helperText = props.helperText, formLabelProps = props.formLabelProps, formControlLabelProps = props.formControlLabelProps, fieldProps = props.fieldProps, formControlProps = props.formControlProps, radioGroupProps = props.radioGroupProps, formHelperTextProps = props.formHelperTextProps, restRadios = _objectWithoutPropertiesLoose(props, ["name", "data", "label", "required", "helperText", "formLabelProps", "formControlLabelProps", "fieldProps", "formControlProps", "radioGroupProps", "formHelperTextProps"]); var formState = reactFinalForm.useFormState(); var errors = formState.errors, submitErrors = formState.submitErrors, submitFailed = formState.submitFailed, modified = formState.modified; var _useState = React.useState(null), errorState = _useState[0], setErrorState = _useState[1]; React.useEffect(function () { var showError = (!!errors[name] || !!submitErrors) && (submitFailed || modified && modified[name]); setErrorState(showError ? errors[name] || submitErrors[name] : null); }, [errors, submitErrors, submitFailed, modified, name]); return React__default.createElement(core.FormControl, Object.assign({ required: required, error: !!errorState }, formControlProps), !!label && React__default.createElement(core.FormLabel, Object.assign({}, formLabelProps), label), React__default.createElement(core.RadioGroup, Object.assign({}, radioGroupProps), data.map(function (item, idx) { return React__default.createElement(core.FormControlLabel, Object.assign({ key: idx, name: name, label: item.label, value: item.value, disabled: item.disabled, control: React__default.createElement(reactFinalForm.Field, Object.assign({ type: "radio", name: name }, fieldProps), function (_ref) { var _ref$input = _ref.input, name = _ref$input.name, value = _ref$input.value, onChange = _ref$input.onChange, checked = _ref$input.checked, restInput = _objectWithoutPropertiesLoose(_ref$input, ["name", "value", "onChange", "checked"]); return React__default.createElement(core.Radio, Object.assign({ name: name, value: value, onChange: onChange, checked: checked, inputProps: _extends({ required: required }, restInput) }, restRadios)); }) }, formControlLabelProps)); })), !!errorState ? React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), errorState) : !!helperText && React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), helperText)); } function Select(props) { var name = props.name, label = props.label, data = props.data, children = props.children, required = props.required, multiple = props.multiple, helperText = props.helperText, fieldProps = props.fieldProps, inputLabelProps = props.inputLabelProps, formControlProps = props.formControlProps, formHelperTextProps = props.formHelperTextProps, menuItemProps = props.menuItemProps, labelWidth = props.labelWidth, restSelectProps = _objectWithoutPropertiesLoose(props, ["name", "label", "data", "children", "required", "multiple", "helperText", "fieldProps", "inputLabelProps", "formControlProps", "formHelperTextProps", "menuItemProps", "labelWidth"]); if (!data && !children) { throw new Error('Please specify either children or data as an attribute.'); } var formState = reactFinalForm.useFormState(); var errors = formState.errors, submitErrors = formState.submitErrors, submitFailed = formState.submitFailed, modified = formState.modified; var _useState = React.useState(null), errorState = _useState[0], setErrorState = _useState[1]; React.useEffect(function () { var showError = (!!errors[name] || !!submitErrors) && (submitFailed || modified && modified[name]); setErrorState(showError ? errors[name] || submitErrors[name] : null); }, [errors, submitErrors, submitFailed, modified, name]); // This is for supporting the special case of variant="outlined" // Fixes: https://github.com/lookfirst/mui-rff/issues/91 var variant = restSelectProps.variant; var inputLabel = React__default.useRef(null); var _React$useState = React__default.useState(0), labelWidthState = _React$useState[0], setLabelWidthState = _React$useState[1]; React__default.useEffect(function () { if (label) { setLabelWidthState(inputLabel.current.offsetWidth); } }, [label]); return React__default.createElement(core.FormControl, Object.assign({ required: required, error: !!errorState, fullWidth: true, variant: variant }, formControlProps), !!label && React__default.createElement(core.InputLabel, Object.assign({ ref: inputLabel, htmlFor: name }, inputLabelProps), label), React__default.createElement(reactFinalForm.Field, Object.assign({ name: name }, fieldProps), function (_ref) { var _ref$input = _ref.input, name = _ref$input.name, value = _ref$input.value, onChange = _ref$input.onChange, restInput = _objectWithoutPropertiesLoose(_ref$input, ["name", "value", "onChange"]); return React__default.createElement(core.Select, Object.assign({ name: name, value: value, onChange: onChange, multiple: multiple, label: label, labelWidth: variant === 'outlined' && !!label ? labelWidthState : labelWidth, inputProps: _extends({ required: required }, restInput) }, restSelectProps), data ? data.map(function (item) { return React__default.createElement(core.MenuItem, Object.assign({ value: item.value, key: item.value, disabled: item.disabled }, menuItemProps), item.label); }) : children); }), !!errorState ? React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), errorState) : !!helperText && React__default.createElement(core.FormHelperText, Object.assign({}, formHelperTextProps), helperText)); } function pickerProviderWrapper(dateFunsUtils, component) { return dateFunsUtils ? React__default.createElement(pickers.MuiPickersUtilsProvider, { utils: dateFunsUtils }, component) : component; } function KeyboardDatePicker(props) { var name = props.name, fieldProps = props.fieldProps, rest = _objectWithoutPropertiesLoose(props, ["name", "fieldProps"]); return React__default.createElement(reactFinalForm.Field, Object.assign({ name: name, render: function render(fieldRenderProps) { return React__default.createElement(KeyboardDatePickerWrapper, Object.assign({}, fieldRenderProps, rest)); } }, fieldProps)); } function KeyboardDatePickerWrapper(props) { var _props$input = props.input, name = _props$input.name, onChange = _props$input.onChange, value = _props$input.value, restInput = _objectWithoutPropertiesLoose(_props$input, ["name", "onChange", "value"]), meta = props.meta, dateFunsUtils = props.dateFunsUtils, rest = _objectWithoutPropertiesLoose(props, ["input", "meta", "dateFunsUtils"]); var helperText = rest.helperText, lessrest = _objectWithoutPropertiesLoose(rest, ["helperText"]); var showError = (meta.submitError && !meta.dirtySinceLastSubmit || meta.error) && meta.touched; return pickerProviderWrapper(dateFunsUtils, React__default.createElement(pickers.KeyboardDatePicker, Object.assign({ disableToolbar: true, fullWidth: true, autoOk: true, helperText: showError ? meta.error || meta.submitError : helperText, error: showError, onChange: onChange, name: name, value: value === '' ? null : value, inputProps: restInput }, lessrest))); } function DatePicker(props) { var name = props.name, fieldProps = props.fieldProps, rest = _objectWithoutPropertiesLoose(props, ["name", "fieldProps"]); return React__default.createElement(reactFinalForm.Field, Object.assign({ name: name, render: function render(fieldRenderProps) { return React__default.createElement(DatePickerWrapper, Object.assign({}, fieldRenderProps, rest)); } }, fieldProps)); } function DatePickerWrapper(props) { var _props$input = props.input, name = _props$input.name, onChange = _props$input.onChange, value = _props$input.value, restInput = _objectWithoutPropertiesLoose(_props$input, ["name", "onChange", "value"]), meta = props.meta, dateFunsUtils = props.dateFunsUtils, rest = _objectWithoutPropertiesLoose(props, ["input", "meta", "dateFunsUtils"]); var helperText = rest.helperText, lessrest = _objectWithoutPropertiesLoose(rest, ["helperText"]); var showError = (meta.submitError && !meta.dirtySinceLastSubmit || meta.error) && meta.touched; return pickerProviderWrapper(dateFunsUtils, React__default.createElement(pickers.DatePicker, Object.assign({ fullWidth: true, autoOk: true, helperText: showError ? meta.error || meta.submitError : helperText, error: showError, onChange: onChange, name: name, value: value === '' ? null : value }, lessrest, { inputProps: restInput }))); } function KeyboardTimePicker(props) { var name = props.name, fieldProps = props.fieldProps, rest = _objectWithoutPropertiesLoose(props, ["name", "fieldProps"]); return React__default.createElement(reactFinalForm.Field, Object.assign({ name: name, render: function render(fieldRenderProps) { return React__default.createElement(KeyboardTimePickerWrapper, Object.assign({}, fieldRenderProps, rest)); } }, fieldProps)); } function KeyboardTimePickerWrapper(props) { var _props$input = props.input, name = _props$input.name, onChange = _props$input.onChange, value = _props$input.value, restInput = _objectWithoutPropertiesLoose(_props$input, ["name", "onChange", "value"]), meta = props.meta, dateFunsUtils = props.dateFunsUtils, rest = _objectWithoutPropertiesLoose(props, ["input", "meta", "dateFunsUtils"]); var helperText = rest.helperText, lessrest = _objectWithoutPropertiesLoose(rest, ["helperText"]); var showError = (meta.submitError && !meta.dirtySinceLastSubmit || meta.error) && meta.touched; return pickerProviderWrapper(dateFunsUtils, React__default.createElement(pickers.KeyboardTimePicker, Object.assign({ fullWidth: true, autoOk: true, helperText: showError ? meta.error || meta.submitError : helperText, error: showError, onChange: onChange, name: name, value: value === '' ? null : value }, lessrest, { inputProps: restInput }))); } function TimePicker(props) { var name = props.name, fieldProps = props.fieldProps, rest = _objectWithoutPropertiesLoose(props, ["name", "fieldProps"]); return React__default.createElement(reactFinalForm.Field, Object.assign({ name: name, render: function render(fieldRenderProps) { return React__default.createElement(TimePickerWrapper, Object.assign({}, fieldRenderProps, rest)); } }, fieldProps)); } function TimePickerWrapper(props) { var _props$input = props.input, name = _props$input.name, onChange = _props$input.onChange, value = _props$input.value, restInput = _objectWithoutPropertiesLoose(_props$input, ["name", "onChange", "value"]), meta = props.meta, dateFunsUtils = props.dateFunsUtils, rest = _objectWithoutPropertiesLoose(props, ["input", "meta", "dateFunsUtils"]); var helperText = rest.helperText, lessrest = _objectWithoutPropertiesLoose(rest, ["helperText"]); var showError = (meta.submitError && !meta.dirtySinceLastSubmit || meta.error) && meta.touched; return pickerProviderWrapper(dateFunsUtils, React__default.createElement(pickers.TimePicker, Object.assign({ fullWidth: true, autoOk: true, helperText: showError ? meta.error || meta.submitError : helperText, error: showError, onChange: onChange, name: name, value: value === '' ? null : value }, lessrest, { inputProps: restInput }))); } var TYPE_TEXT = 'text'; function TextField(props) { var name = props.name, _props$type = props.type, type = _props$type === void 0 ? TYPE_TEXT : _props$type, fieldProps = props.fieldProps, helperText = props.helperText, _props$fullWidth = props.fullWidth, fullWidth = _props$fullWidth === void 0 ? true : _props$fullWidth, rest = _objectWithoutPropertiesLoose(props, ["name", "type", "fieldProps", "helperText", "fullWidth"]); var formState = reactFinalForm.useFormState(); var errors = formState.errors, submitErrors = formState.submitErrors, submitFailed = formState.submitFailed, modified = formState.modified; var _useState = React.useState(null), errorState = _useState[0], setErrorState = _useState[1]; React.useEffect(function () { var showError = (!!errors[name] || !!submitErrors) && (submitFailed || modified && modified[name]); setErrorState(showError ? errors[name] || submitErrors[name] : null); }, [errors, submitErrors, submitFailed, modified, name]); return React__default.createElement(reactFinalForm.Field, Object.assign({ name: name }, fieldProps), function (_ref) { var _ref$input = _ref.input, name = _ref$input.name, value = _ref$input.value, onChange = _ref$input.onChange, restInput = _objectWithoutPropertiesLoose(_ref$input, ["name", "value", "onChange", "checked"]); return React__default.createElement(core.TextField, Object.assign({ fullWidth: fullWidth, helperText: !!errorState ? errorState : helperText, error: !!errorState, onChange: onChange, name: name, value: value, type: type, inputProps: _extends({}, restInput) }, rest)); }); } // A type of promise-like that resolves synchronously and supports only one observer const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator"; const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator"; // Asynchronously call a function and send errors to recovery continuation function _catch(body, recover) { try { var result = body(); } catch(e) { return recover(e); } if (result && result.then) { return result.then(void 0, recover); } return result; } // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_get function get(obj, path, defaultValue) { var result = String.prototype.split.call(path, /[,[\].]+?/).filter(Boolean).reduce(function (res, key) { return res !== null && res !== undefined ? res[key] : res; }, obj); return result === undefined || result === obj ? defaultValue : result; } // https://stackoverflow.com/questions/54733539/javascript-implementation-of-lodash-set-method function set(obj, path, value) { if (Object(obj) !== obj) return obj; // When obj is not an object // If not yet an array, get the keys from the string-path if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || []; path.slice(0, -1).reduce(function (a, c, i // Iterate all of them except the last one ) { return Object(a[c]) === a[c] // Does the key exist and is its value an object? ? // Yes: then follow that path a[c] : // No: create the key. Is the next key a potential array-index? a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] // Yes: assign a new array object : {}; }, // No: assign a new plain object obj)[path[path.length - 1]] = value; // Finally assign the value to the last key return obj; // Return the top-level object to allow chaining } /** * Wraps the execution of a Yup schema to return an object * where the key is the form field and the value is the error string. */ function makeValidate(validator) { return function (values) { try { return Promise.resolve(_catch(function () { return Promise.resolve(validator.validate(values, { abortEarly: false })).then(function () {}); }, function (err) { return err.inner.reduce(function (errors, _ref) { var path = _ref.path, message = _ref.message; if (errors.hasOwnProperty(path)) { set(errors, path, get(errors, path) + ' ' + message); } else { set(errors, path, message); } return errors; }, {}); })); } catch (e) { return Promise.reject(e); } }; } /** * Uses the private _exclusive field in the schema to get whether or not * the field is marked as required or not. */ function makeRequired(schema) { var fields = schema.fields; return Object.keys(fields).reduce(function (accu, field) { accu[field] = fields[field]._exclusive.required; return accu; }, {}); } function Debug() { return React__default.createElement(reactFinalForm.FormSpy, { subscription: { values: true } }, function (_ref) { var values = _ref.values; return React__default.createElement("pre", null, JSON.stringify(values, undefined, 2)); }); } exports.Autocomplete = Autocomplete; exports.Checkboxes = Checkboxes; exports.DatePicker = DatePicker; exports.Debug = Debug; exports.KeyboardDatePicker = KeyboardDatePicker; exports.KeyboardTimePicker = KeyboardTimePicker; exports.Radios = Radios; exports.Select = Select; exports.Switches = Switches; exports.TextField = TextField; exports.TimePicker = TimePicker; exports.makeRequired = makeRequired; exports.makeValidate = makeValidate; //# sourceMappingURL=mui-rff.cjs.development.js.map