UNPKG

nornj-react

Version:

React bindings for NornJ template engine.

216 lines (178 loc) 6.08 kB
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); } import nj, { registerExtension } from 'nornj'; import React, { useRef } from 'react'; import { toJS } from 'mobx'; import extensionConfigs from '../../../mobx/extensionConfig'; import { debounce } from '../../utils'; const FORMDATA_NOT_TRIGGER = ['valueChange', 'none']; const MobxBindWrap = React.forwardRef(({ MobxBindTag, mobxBindDirectiveOptions: { tagName, context: { $this }, props: directiveProps }, _mobxBindValue: value, ...props }, ref) => { let valuePropName = 'value'; let changeEventName = 'onChange'; let componentConfig = nj.getComponentConfig(tagName) || {}; if (typeof componentConfig === 'function') { componentConfig = componentConfig(props); } const args = directiveProps && directiveProps.arguments; const debounceArg = _hasArg(args, 'debounce'); if (componentConfig.valuePropName != null) { valuePropName = componentConfig.valuePropName; } if (componentConfig.changeEventName != null) { changeEventName = componentConfig.changeEventName; } let _value = value.value; const isMultipleSelect = tagName === 'select' && props.multiple; if (componentConfig.needToJS || isMultipleSelect) { _value = toJS(_value); } const changeEvent = props[changeEventName]; let emitChangeDebounced; if (debounceArg) { const { modifiers } = debounceArg; emitChangeDebounced = useRef(debounce(args => { changeEvent && changeEvent.apply($this, args); }, modifiers && +modifiers[0] || 100)); } const compProps = {}; if (componentConfig.hasEventObject) { const targetPropName = componentConfig.targetPropName || 'value'; const isRadio = tagName === 'input' && props.type === 'radio'; const isCheckbox = tagName === 'input' && props.type === 'checkbox'; if (isRadio) { compProps.checked = props.value === _value; } else if (isCheckbox) { compProps.checked = _value != null && (nj.isArrayLike(_value) ? _value.indexOf(props.value) >= 0 : _value); } else { compProps[valuePropName] = _value; } compProps[changeEventName] = function (e) { e && e.persist && e.persist(); _setValue(e.target[targetPropName], { target: e.target, value, args: arguments, changeEventName, changeEvent, valuePropName, emitChangeDebounced, isMultipleSelect, isCheckbox }, $this); }; } else { const getValueFromEvent = componentConfig.getValueFromEvent; compProps[valuePropName] = _value; compProps[changeEventName] = function (...args) { _setValue(getValueFromEvent ? getValueFromEvent(...args) : args[0], { value, args, changeEventName, changeEvent, valuePropName, emitChangeDebounced }, $this); }; } _formDataTrigger(value, changeEventName, componentConfig, true, props, compProps, $this); return React.createElement(MobxBindTag, _extends({}, props, compProps, { ref: ref })); }); function _formDataTrigger(value, changeEventName, componentConfig, notDirect, props, compProps, $this) { const formData = value === null || value === void 0 ? void 0 : value.source; if (formData === null || formData === void 0 ? void 0 : formData._njMobxFormData) { const fieldName = value.prop; const fieldData = formData.fieldDatas.get(fieldName); const fieldDefaultRule = componentConfig === null || componentConfig === void 0 ? void 0 : componentConfig.fieldDefaultRule; if (fieldDefaultRule) { fieldData.setDefaultRule(fieldDefaultRule); } const trigger = fieldData.trigger; if (FORMDATA_NOT_TRIGGER.indexOf(trigger) > -1) { return; } if (!notDirect) { if (trigger === changeEventName) { formData.validate(fieldName).catch(nj.noop); } } else if (trigger !== changeEventName) { const triggerEvent = props[trigger]; compProps[trigger] = function (e) { e && e.persist && e.persist(); formData.validate(fieldName).catch(nj.noop); triggerEvent && triggerEvent.apply($this, arguments); }; } } } function _setValue(value, params, $this) { let _value = value; if (params.isMultipleSelect) { _value = nj.arraySlice(params.target.options).filter(option => option.selected).map(option => option.value); } else if (params.isCheckbox) { const checkboxValue = params.value.value; if (nj.isArrayLike(checkboxValue)) { if (params.target.checked) { checkboxValue.push(value); } else { checkboxValue.splice(checkboxValue.indexOf(value), 1); } _value = checkboxValue; } else { _value = params.target.checked; } } const setter = params.value.source[`set${nj.upperFirst(params.value.prop)}`]; if (setter) { setter(_value, params.args); } else { params.value.source[params.value.prop] = _value; } _formDataTrigger(params.value, params.changeEventName); if (params.emitChangeDebounced) { params.emitChangeDebounced.current(params.args); } else if (params.changeEvent) { params.changeEvent.apply($this, params.args); } } function _hasArg(args, name) { let ret; args && args.every(arg => { if (arg.name == name) { ret = arg; return false; } return true; }); return ret; } registerExtension('mobxBind', options => { const ret = options.value(); if (ret == null) { return ret; } const { tagName, setTagName, tagProps, props } = options; setTagName(MobxBindWrap); tagProps.MobxBindTag = tagName; tagProps.mobxBindDirectiveOptions = options; tagProps._mobxBindValue = ret; }, extensionConfigs.mobxBind); nj.extensions.mstBind = nj.extensions.mobxBind;