zmp-react
Version:
Build full featured iOS & Android apps using ZMP & React
474 lines (403 loc) • 17.5 kB
JavaScript
"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;