UNPKG

zmp-react

Version:

Build full featured iOS & Android apps using ZMP & React

474 lines (403 loc) 17.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = _interopRequireWildcard(require("react")); var _useIsomorphicLayoutEffect = require("../shared/use-isomorphic-layout-effect"); var _utils = require("../shared/utils"); var _mixins = require("../shared/mixins"); var _zmp = require("../shared/zmp"); var _textEditor = _interopRequireDefault(require("./text-editor")); var _watchProp = require("../shared/watch-prop"); var _listContext = require("../shared/list-context"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } var ListInput = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) { var className = props.className, id = props.id, style = props.style, sortable = props.sortable, media = props.media, _props$dropdown = props.dropdown, dropdown = _props$dropdown === void 0 ? 'auto' : _props$dropdown, _props$wrap = props.wrap, wrap = _props$wrap === void 0 ? true : _props$wrap, _props$input = props.input, renderInput = _props$input === void 0 ? true : _props$input, _props$type = props.type, type = _props$type === void 0 ? 'text' : _props$type, name = props.name, value = props.value, defaultValue = props.defaultValue, inputmode = props.inputmode, readonly = props.readonly, required = props.required, disabled = props.disabled, placeholder = props.placeholder, inputId = props.inputId, size = props.size, accept = props.accept, autocomplete = props.autocomplete, autocorrect = props.autocorrect, autocapitalize = props.autocapitalize, spellcheck = props.spellcheck, autofocus = props.autofocus, autosave = props.autosave, max = props.max, min = props.min, step = props.step, maxlength = props.maxlength, minlength = props.minlength, multiple = props.multiple, inputStyle = props.inputStyle, pattern = props.pattern, validate = props.validate, validateOnBlur = props.validateOnBlur, onValidate = props.onValidate, tabindex = props.tabindex, resizable = props.resizable, clearButton = props.clearButton, noFormStoreData = props.noFormStoreData, noStoreData = props.noStoreData, ignoreStoreData = props.ignoreStoreData, errorMessage = props.errorMessage, errorMessageForce = props.errorMessageForce, info = props.info, outline = props.outline, label = props.label, inlineLabel = props.inlineLabel, floatingLabel = props.floatingLabel, calendarParams = props.calendarParams, colorPickerParams = props.colorPickerParams, textEditorParams = props.textEditorParams, rows = props.rows; var _useState = (0, _react.useState)(false), inputInvalid = _useState[0], setInputInvalid = _useState[1]; var _useState2 = (0, _react.useState)(false), inputFocused = _useState2[0], setInputFocused = _useState2[1]; var listContext = (0, _react.useContext)(_listContext.ListContext); var _ref = listContext || {}, _ref$listIsSortable = _ref.listIsSortable, listIsSortable = _ref$listIsSortable === void 0 ? false : _ref$listIsSortable; var extraAttrs = (0, _utils.getExtraAttrs)(props); var zmpCalendar = (0, _react.useRef)(null); var zmpColorPicker = (0, _react.useRef)(null); var elRef = (0, _react.useRef)(null); var inputElRef = (0, _react.useRef)(null); var itemContentElRef = (0, _react.useRef)(null); var updateInputOnDidUpdate = (0, _react.useRef)(false); var getDomValue = function getDomValue() { if (!inputElRef.current) return undefined; return inputElRef.current.value; }; var isInputHasValue = function isInputHasValue() { if (type === 'datepicker' && Array.isArray(value) && value.length === 0) { return false; } var domValue = getDomValue(); return typeof value === 'undefined' ? domValue || domValue === 0 : value || value === 0; }; var validateInput = function validateInput() { if (!_zmp.zmp || !inputElRef.current) return; var validity = inputElRef.current.validity; if (!validity) return; if (!validity.valid) { if (onValidate) onValidate(false); if (inputInvalid !== true) { setInputInvalid(true); } } else { if (onValidate) onValidate(true); if (inputInvalid !== false) { setInputInvalid(false); } } }; var onTextareaResize = function onTextareaResize(event) { (0, _utils.emit)(props, 'textareaResize', event); }; var onInputNotEmpty = function onInputNotEmpty(event) { (0, _utils.emit)(props, 'inputNotEmpty', event); }; var onInputEmpty = function onInputEmpty(event) { (0, _utils.emit)(props, 'inputEmpty', event); }; var onInputClear = function onInputClear(event) { (0, _utils.emit)(props, 'inputClear', event); }; var onInput = function onInput() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _utils.emit.apply(void 0, [props, 'input'].concat(args)); if (!(validateOnBlur || validateOnBlur === '') && (validate || validate === '') && inputElRef.current) { validateInput(inputElRef.current); } }; var onFocus = function onFocus() { for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } _utils.emit.apply(void 0, [props, 'focus'].concat(args)); setInputFocused(true); }; var onBlur = function onBlur() { for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } _utils.emit.apply(void 0, [props, 'blur'].concat(args)); if ((validate || validate === '' || validateOnBlur || validateOnBlur === '') && inputElRef.current) { validateInput(inputElRef.current); } setInputFocused(false); }; var onChange = function onChange() { for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { args[_key4] = arguments[_key4]; } _utils.emit.apply(void 0, [props, 'change'].concat(args)); if (type === 'texteditor') { (0, _utils.emit)(props, 'textEditorChange', args[0]); } }; (0, _react.useImperativeHandle)(ref, function () { return { el: elRef.current }; }); var onMount = function onMount() { if (!elRef.current && !itemContentElRef.current) return; (0, _zmp.zmpready)(function () { if (!inputElRef.current) return; inputElRef.current.addEventListener('input:notempty', onInputNotEmpty, false); inputElRef.current.addEventListener('textarea:resize', onTextareaResize, false); inputElRef.current.addEventListener('input:empty', onInputEmpty, false); inputElRef.current.addEventListener('input:clear', onInputClear, false); if (type === 'datepicker') { zmpCalendar.current = _zmp.zmp.calendar.create((0, _extends2.default)({ inputEl: inputElRef.current, value: value, on: { change: function change(calendar, calendarValue) { (0, _utils.emit)(props, 'calendarChange', calendarValue); } } }, calendarParams || {})); } if (type === 'colorpicker') { zmpColorPicker.current = _zmp.zmp.colorPicker.create((0, _extends2.default)({ inputEl: inputElRef.current, value: value, on: { change: function change(colorPicker, colorPickerValue) { (0, _utils.emit)(props, 'colorpicker:change colorPickerChange', colorPickerValue); } } }, colorPickerParams || {})); } if (!(validateOnBlur || validateOnBlur === '') && (validate || validate === '') && (typeof value !== 'undefined' && value !== null && value !== '' || typeof defaultValue !== 'undefined' && defaultValue !== null && defaultValue !== '')) { setTimeout(function () { validateInput(); }, 0); } if (type === 'textarea' && resizable) { _zmp.zmp.input.resizeTextarea(inputElRef.current); } }); }; var onDestroy = function onDestroy() { if (inputElRef.current) { inputElRef.current.removeEventListener('input:notempty', onInputNotEmpty, false); inputElRef.current.removeEventListener('textarea:resize', onTextareaResize, false); inputElRef.current.removeEventListener('input:empty', onInputEmpty, false); inputElRef.current.removeEventListener('input:clear', onInputClear, false); } if (zmpCalendar.current && zmpCalendar.current.destroy) { zmpCalendar.current.destroy(); zmpCalendar.current = null; } if (zmpColorPicker.current && zmpColorPicker.current.destroy) { zmpColorPicker.current.destroy(); zmpColorPicker.current = null; } }; (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(function () { onMount(); return onDestroy; }, []); (0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(function () { if (!_zmp.zmp) return; if (updateInputOnDidUpdate.current) { if (!inputElRef.current) return; updateInputOnDidUpdate.current = false; if (validate && !validateOnBlur) { validateInput(); } if (type === 'textarea' && resizable) { _zmp.zmp.input.resizeTextarea(inputElRef.current); } } }); (0, _watchProp.watchProp)(colorPickerParams, function (newValue) { if (!_zmp.zmp || !zmpColorPicker.current) return; (0, _utils.extend)(zmpColorPicker.current.params, newValue || {}); }); (0, _watchProp.watchProp)(calendarParams, function (newValue) { if (!_zmp.zmp || !zmpCalendar.current) return; (0, _utils.extend)(zmpCalendar.current.params, newValue || {}); }); (0, _watchProp.watchProp)(value, function (newValue) { if (!_zmp.zmp) return; updateInputOnDidUpdate.current = true; if (zmpCalendar.current) { zmpCalendar.current.setValue(newValue); } if (zmpColorPicker.current) { zmpColorPicker.current.setValue(newValue); } }); var slots = (0, _utils.getSlots)(props); var domValue = getDomValue(); var inputHasValue = isInputHasValue(); var isSortableComputed = sortable || listIsSortable; var inputEl; var createInput = function createInput(InputTag, children) { var needsValue = type !== 'file' && type !== 'datepicker' && type !== 'colorpicker'; var needsType = InputTag === 'input'; var inputType = type; if (inputType === 'datepicker' || inputType === 'colorpicker') { inputType = 'text'; } var inputClassName = (0, _utils.classNames)({ resizable: inputType === 'textarea' && resizable, 'no-store-data': noFormStoreData || noStoreData || ignoreStoreData, 'input-invalid': errorMessage && errorMessageForce || inputInvalid, 'input-with-value': inputHasValue, 'input-focused': inputFocused }); var inputValue; if (needsValue) { if (typeof value !== 'undefined') inputValue = value;else inputValue = domValue; } var valueProps = {}; if (type !== 'datepicker' && type !== 'colorpicker') { if ('value' in props) valueProps.value = inputValue; if ('defaultValue' in props) valueProps.defaultValue = defaultValue; } return /*#__PURE__*/_react.default.createElement(InputTag, (0, _extends2.default)({ ref: inputElRef, style: inputStyle, name: name, type: needsType ? inputType : undefined, placeholder: placeholder, inputMode: inputmode, id: inputId, size: size, accept: accept, autoComplete: autocomplete, autoCorrect: autocorrect, autoCapitalize: autocapitalize, spellCheck: spellcheck, autoFocus: autofocus, autoSave: autosave, disabled: disabled, max: max, maxLength: maxlength, min: min, minLength: minlength, step: step, multiple: multiple, readOnly: readonly, required: required, pattern: pattern, validate: typeof validate === 'string' && validate.length ? validate : undefined, "data-validate": validate === true || validate === '' || validateOnBlur === true || validateOnBlur === '' ? true : undefined, "data-validate-on-blur": validateOnBlur === true || validateOnBlur === '' ? true : undefined, tabIndex: tabindex, "data-error-message": errorMessageForce ? undefined : errorMessage, className: inputClassName, onFocus: onFocus, onBlur: onBlur, onInput: onInput, onChange: onChange, rows: rows }, valueProps), children); }; if (renderInput) { if (type === 'select' || type === 'textarea' || type === 'file') { if (type === 'select') { inputEl = createInput('select', slots.default); } else if (type === 'file') { inputEl = createInput('input'); } else { inputEl = createInput('textarea'); } } else if (type === 'texteditor') { inputEl = /*#__PURE__*/_react.default.createElement(_textEditor.default, (0, _extends2.default)({ value: value, resizable: resizable, placeholder: placeholder, onTextEditorFocus: onFocus, onTextEditorBlur: onBlur, onTextEditorInput: onInput, onTextEditorChange: onChange }, textEditorParams || {})); } else { inputEl = createInput('input'); } } var hasErrorMessage = !!errorMessage || slots['error-message'] && slots['error-message'].length; var ItemContent = /*#__PURE__*/_react.default.createElement("div", { ref: itemContentElRef, className: (0, _utils.classNames)('item-content item-input', !wrap && className, !wrap && { disabled: disabled }, !wrap && (0, _mixins.colorClasses)(props), { 'inline-label': inlineLabel, 'item-input-outline': outline, 'item-input-focused': inputFocused, 'item-input-with-info': !!info || slots.info && slots.info.length, 'item-input-with-value': inputHasValue, 'item-input-with-error-message': hasErrorMessage && errorMessageForce || inputInvalid, 'item-input-invalid': hasErrorMessage && errorMessageForce || inputInvalid }) }, slots['content-start'], (media || slots.media) && /*#__PURE__*/_react.default.createElement("div", { className: "item-media" }, media && /*#__PURE__*/_react.default.createElement("img", { src: media }), slots.media), /*#__PURE__*/_react.default.createElement("div", { className: "item-inner" }, slots['inner-start'], (label || slots.label) && /*#__PURE__*/_react.default.createElement("div", { className: (0, _utils.classNames)('item-title item-label', { 'item-floating-label': floatingLabel }) }, label, slots.label), /*#__PURE__*/_react.default.createElement("div", { className: (0, _utils.classNames)('item-input-wrap', { 'input-dropdown': dropdown === 'auto' ? type === 'select' : dropdown }) }, inputEl, slots.input, hasErrorMessage && errorMessageForce && /*#__PURE__*/_react.default.createElement("div", { className: "item-input-error-message" }, errorMessage, slots['error-message']), clearButton && /*#__PURE__*/_react.default.createElement("span", { className: "input-clear-button" }), (info || slots.info) && /*#__PURE__*/_react.default.createElement("div", { className: "item-input-info" }, info, slots.info)), slots.inner, slots['inner-end']), slots.content, slots['content-end']); if (!wrap) { return ItemContent; } return /*#__PURE__*/_react.default.createElement("li", (0, _extends2.default)({ ref: elRef, id: id, style: style, className: (0, _utils.classNames)(className, { disabled: disabled }, (0, _mixins.colorClasses)(props)) }, extraAttrs), slots['root-start'], ItemContent, isSortableComputed && /*#__PURE__*/_react.default.createElement("div", { className: "sortable-handler" }), slots.root, slots['root-end']); }); ListInput.displayName = 'zmp-list-input'; var _default = ListInput; exports.default = _default;