UNPKG

@innoways/hooks

Version:

drip-form通用hooks

1,307 lines (1,160 loc) 44.7 kB
import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import { useState, useCallback, useRef, useEffect, createContext, useContext, useMemo } from 'react'; import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray'; import _useDebounceFn2 from 'ahooks/es/useDebounceFn'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import produce, { produce as produce$1 } from 'immer'; import _typeof from '@babel/runtime/helpers/typeof'; import moment from 'moment'; import { isEmpty, typeCheck, generateReg, fetchFnJsonKey } from '@innoways/utils'; import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator'; import _regeneratorRuntime from '@babel/runtime/regenerator'; var useModal = function useModal(defaultStatus) { var _useState = useState(defaultStatus), _useState2 = _slicedToArray(_useState, 2), visible = _useState2[0], setVisible = _useState2[1]; var showModal = useCallback(function () { setVisible(true); }, []); var hideModal = useCallback(function () { setVisible(false); }, []); return [visible, showModal, hideModal]; }; /* * @Author: jiangxiaowei * @Date: 2020-05-14 11:08:36 * @Last Modified by: jiangxiaowei * @Last Modified time: 2020-06-23 16:25:02 */ var useRefProp = function useRefProp(props) { var ref = useRef(null); useEffect(function () { ref.current = props; }); return ref; }; /* * @Author: jiangxiaowei * @Date: 2020-05-14 11:08:53 * @Last Modified by: jiangxiaowei * @Last Modified time: 2020-06-23 16:24:55 */ var usePrevious = function usePrevious(value) { var ref = useRef(); useEffect(function () { ref.current = value; }); return ref.current; }; /** * 重写useCallback(保证函数即使dependencies依赖改变。也不会重新生成) * 解决因为useCallback的依赖频繁变化导致useCallback缓存效果很差甚至影响性能的问题 * fn 函数 * dependencies 依赖数组 */ var useEventCallback = function useEventCallback(fn, dependencies) { var ref = useRef(function () { throw new Error('Cannot call an event handler while rendering.'); }); useEffect(function () { ref.current = fn; // eslint-disable-next-line react-hooks/exhaustive-deps }, [fn].concat(_toConsumableArray(dependencies))); return useCallback(function () { var fn = ref.current; return fn.apply(void 0, arguments); }, [ref]); }; /* * 按钮只可以点击一次 * @Author: jiangxiaowei * @Date: 2020-05-14 16:54:56 * @Last Modified by: jiangxiaowei * @Last Modified time: 2020-06-21 18:40:08 */ var useClickOne = function useClickOne() { var ref = useRef(true); var startClick = useCallback(function () { ref.current = false; }, []); var stopClick = useCallback(function () { ref.current = true; }, []); return [ref.current, startClick, stopClick]; }; function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$4(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /** * * @param {json} schema 校验数据的json schema * @param {object} formData 校验数据 * @param {Ajv} ajv 校验器 * @param visibleFieldKey * return { * pass {bol} 是否校验通过 * error {} 校验错误信息 * } */ var validate = function validate(_ref) { var schema = _ref.schema, formData = _ref.formData, ajv = _ref.ajv, visibleFieldKey = _ref.visibleFieldKey, customProps = _ref.customProps; try { var ignoreKeywords = (customProps === null || customProps === void 0 ? void 0 : customProps.filter(function (item) { return !ajv.RULES.keywords[item]; })) || []; if ((ignoreKeywords === null || ignoreKeywords === void 0 ? void 0 : ignoreKeywords.length) > 0) { ajv.addVocabulary(ignoreKeywords); } // 编译ajv var validateFuc = ajv.compile(schema); // 校验是否通过 var pass = false; // 因为ajv会改动formData数据。而formData是不可变的,我们通过immer生成新的数据 var newFormData = produce(formData, function (draft) { if (schema && schema.properties && schema.properties && Object.keys(schema.properties).length) { for (var i in schema.properties) { if (schema.properties[i].dateChecking && schema.properties[i].dateChecking.earlierDateChecking && schema.properties[i].dateChecking.authModeDateChecking) { draft = _objectSpread$4(_objectSpread$4({}, draft), {}, _defineProperty({}, i, _defineProperty({ self: formData[i] }, schema.properties[i].dateChecking.earlierDateChecking, formData[schema.properties[i].dateChecking.earlierDateChecking]))); } } } pass = validateFuc(draft); }); // 未通过校验的数据,结构如下 // [{ // instancePath: '/e/0/1', // 这是一个嵌套表单,数据结构为 { e: [[]] } // schemaPath: '#/properties/e/items/items/1/errorMessage', // keyword: 'errorMessage', // params: { errors: [Array] }, // message: '类型错误!应为number', // schema: { type: '类型错误!应为number' }, // parentSchema: { type: 'number', title: '手机', minimum: 1, errorMessage: [Object] }, // data: '231' // }, ...] var errors = (validateFuc === null || validateFuc === void 0 ? void 0 : validateFuc.errors) || []; // 当前数据错误映射 var errorsMap = {}; // 只处理 dataSchema 中 errorMessage 给出具体错误内容的错误 errors = errors.filter(function (err) { return err.keyword === 'errorMessage'; }); // 解析错误信息 errors.forEach(function (error) { // 由于获取的instancePath前面会带有/,此处移除首项的 var key = error === null || error === void 0 ? void 0 : error.instancePath.replace(/^\//, '').replace(/\//g, '.'); // TODO 错误兜底逻辑优化,过滤error.message上不存在的错误 if (key) { // 数组嵌套对象必填校验 只区instacePath不行,还需加上 error.params.errors[0].params.missingProperty errorsMap["".concat(String(key)).concat(error.params.errors[0].params.missingProperty ? '.' + error.params.errors[0].params.missingProperty : '')] = error.message || '未知错误'; } else { // 根目录required错误 errorsMap[error.params.errors[0].params.missingProperty] = error.message || '未知错误'; } }); // 如果该字段不展示在界面上,比如通过开关控制显隐的一些必填项 // 则从校验中移除这些错误 Object.keys(errorsMap).map(function (key) { if (visibleFieldKey && !(visibleFieldKey !== null && visibleFieldKey !== void 0 && visibleFieldKey.includes(key))) { delete errorsMap[key]; } }); return { pass: pass, errors: errors, errorsMap: errorsMap, formData: newFormData }; } catch (error) { console.error(error); return { pass: false, errors: [], formData: formData, errorsMap: {} }; } }; /** * * @param delay 校验防抖,延迟多少ms校验 * @returns */ var useValidate = function useValidate() { var delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var _useDebounceFn = _useDebounceFn2(function (_ref2) { var dataSchema = _ref2.dataSchema, formData = _ref2.formData, dispatch = _ref2.dispatch, visibleFieldKey = _ref2.visibleFieldKey, ajv = _ref2.ajv; /* 因为ajv中有option配置可以改变formData(useDefaults:true)修改默认值 或者类似ajv-keywords的自定义关键字transform等情况会修改formData。 所以需要在在validate中使用immer,并重新返回新的formData。在此需要对formData重新dispatch设置 */ var _validate = validate({ schema: dataSchema, formData: formData, ajv: ajv, visibleFieldKey: visibleFieldKey }), errorsMap = _validate.errorsMap, newFormData = _validate.formData; dispatch({ type: 'setAjvErr', action: { errors: errorsMap } }); dispatch({ type: 'setData', action: { formData: newFormData } }); dispatch({ type: 'setChecking', checking: false }); }, { wait: delay }), run = _useDebounceFn.run; return run; }; /* * @Author: jiangxiaowei * @Date: 2022-03-08 17:48:49 * @Last Modified by: jiangxiaowei * @Last Modified time: 2022-03-09 17:10:13 */ var RequiredModeContext = /*#__PURE__*/createContext('default'); // 返回上一次的value值 var useRequiredModeContext = function useRequiredModeContext() { var requiredMode = useContext(RequiredModeContext); return requiredMode; }; function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$3(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /** * 格式化Moment类型数据 * @param {array|string} value * @param {string} format 格式化模板 * @returns {string|array} */ function formatMomentData(_ref) { var value = _ref.value, format = _ref.format; if (value) { if (Array.isArray(value)) { return [value[0].format(format), value[1].format(format)]; } else { return moment(value).format(format); } } return value; } /** * 格式化颜色选择器数据 * @param {object|string} value 颜色选择器表单值 */ function formatColor(_ref2) { var _value$rgb, _value$rgb2, _value$rgb3, _value$rgb4; var value = _ref2.value; if (_typeof(value) === 'object') { switch (value.source) { case 'rgb': return "rgba(".concat((value === null || value === void 0 ? void 0 : (_value$rgb = value.rgb) === null || _value$rgb === void 0 ? void 0 : _value$rgb.r) || 0, ",").concat((value === null || value === void 0 ? void 0 : (_value$rgb2 = value.rgb) === null || _value$rgb2 === void 0 ? void 0 : _value$rgb2.g) || 0, ",").concat((value === null || value === void 0 ? void 0 : (_value$rgb3 = value.rgb) === null || _value$rgb3 === void 0 ? void 0 : _value$rgb3.b) || 0, ",").concat((value === null || value === void 0 ? void 0 : (_value$rgb4 = value.rgb) === null || _value$rgb4 === void 0 ? void 0 : _value$rgb4.a) || 1, ")"); default: return (value === null || value === void 0 ? void 0 : value.hex) || '#ffffff'; } } return value; } /** * 格式化uploader数据 */ // function formatUploader({ value }: { value: { fileList?: any } }) { // if (typeCheck(value) === 'Object') { // return value?.fileList || value // } // return value // } /** * 扁平化treeselect结构 * @param options treeselect的options 非treeDataSimpleMode(简单)模式 */ function loop(options) { return options.reduce(function (prev, cur) { if (cur.children) { var childrenArr = loop(cur.children); return prev.concat(childrenArr).concat(cur); } return prev.concat(cur); }, []); } /** * treeselect默认只保存当前选中的id。使用此方法将treeselect改成使用withPidDelimiter分隔符拼接的包括父级id的格式 类似 ‘0#1#2’ * @param param0 { * value 需要更改的初始值 * options treeselect非treeDataSimpleMode格式的数据 * withPidDelimiter 分隔符 * } */ function formatWithPid(_ref3) { var value = _ref3.value, options = _ref3.options, withPidDelimiter = _ref3.withPidDelimiter; var newOptions = loop(options); /** * 循环获取父元素id并合并当前id值 * @param val 当前选择的id值 * @param withPidValue 带父元素id的值 默认为空 */ var newValue = value.map(function (curVal) { var loops = function loops(val, withPidValue) { var index = newOptions.findIndex(function (item) { return item.value === val; }); if (index != -1) { var parentValue = newOptions[index].parentValue; withPidValue = "".concat(parentValue).concat(withPidDelimiter).concat(withPidValue || val); return loops(parentValue, withPidValue); } else { return withPidValue; } }; var withPidValue = loops(curVal); return withPidValue; }); return newValue; } /** * value格式化 * @param param0 { * value 表单值 * disabled_input 禁止输入的值 * } */ function formatValue(_ref4) { var value = _ref4.value, disabled_input = _ref4.disabled_input; if (disabled_input) { var regStr = disabled_input.join('|'); var regExp = new RegExp(regStr, 'g'); if (regExp.test(value)) { return value.replace(regExp, ''); } } return value; } /** * 针对select+text表单项的format * @param value * @param subFieldKey * @param prevFieldData */ function formatSelectText(_ref5) { var value = _ref5.value, subFieldKey = _ref5.subFieldKey, prevFieldData = _ref5.prevFieldData; return Object.assign({ select: [], text: '' }, typeCheck(prevFieldData) === 'Object' ? prevFieldData : {}, _defineProperty({}, subFieldKey, value)); } var formatMap = { isMoment: formatMomentData, isColor: formatColor, // 移除uploader组件的格式化处理,因为入参需要为 {file, fileList} 格式 // isUploader: formatUploader, isWithPid: formatWithPid, isFormat: formatValue, isSelectText: formatSelectText }; /* 例子 import { useField } from 'hooks' const myComponent = ({fieldKey,onChange})=>{ const onchange = useField(fieldKey,onChange) <Input onChange={_onChange} /> } */ var useField = function useField(_ref6, dispatch) { var fieldKey = _ref6.fieldKey, onChange = _ref6.onChange, _ref6$options = _ref6.options, options = _ref6$options === void 0 ? {} : _ref6$options, asyncValidate = _ref6.asyncValidate, prevFieldData = _ref6.prevFieldData, fieldData = _ref6.fieldData, getKey = _ref6.getKey; var requiredMode = useRequiredModeContext(); // onChange 回调 debounce var _useDebounceFn = _useDebounceFn2(function (val, dispatch) { if (onChange) { try { // 如果为函数,则直接执行 if (typeof onChange === 'function') { onChange({ val: val, dispatch: dispatch, fieldKey: fieldKey, prevFieldData: prevFieldData, fieldData: fieldData, getKey: getKey }); } else { var onChangeFuc = new Function('props', onChange); onChangeFuc && onChangeFuc({ val: val, dispatch: dispatch, fieldKey: fieldKey, prevFieldData: prevFieldData, fieldData: fieldData, getKey: getKey }); } } catch (error) { console.error('onChange函数体错误'); console.error(error); } } if (asyncValidate && asyncValidate.type === 'change') { var asyncValidateResult = asyncValidate.fn(val); if (asyncValidateResult !== null && asyncValidateResult !== void 0 && asyncValidateResult.then) { asyncValidateResult.then(function (res) { if (res) { dispatch({ type: 'setErr', action: { set: _defineProperty({}, fieldKey, res) } }); } else { dispatch({ type: 'setErr', action: { deleteKeys: fieldKey } }); } }); } else { if (asyncValidateResult) { dispatch({ type: 'setErr', action: { set: _defineProperty({}, fieldKey, asyncValidateResult) } }); } else { dispatch({ type: 'setErr', action: { deleteKeys: fieldKey } }); } } } // onChange && onChange(val,dispatch) }, { wait: 300 }), run = _useDebounceFn.run; return useEventCallback(function (e) { var _e$target; // 针对 babel-ui中的radio的checkbox模式和所有主题包的switch,由于获取不到正确的e.target,需要通过自身的fieldData进行修改 // switch返回的e为true、false,因此在传入onChange时直接将fieldData取反 var value = isEmpty(fieldData) ? e !== null && e !== void 0 && e.target ? e === null || e === void 0 ? void 0 : (_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.value : e : fieldData; //uploader内部修改不可变数据特殊处理 if (options.draft) { value = produce$1(value, function (draft) { return draft; }); } // 判断当前传的options配置项是否需要特殊format处理 var formatKeys = Object.keys(formatMap); var specialFormatKeys = Object.keys(options).filter(function (item) { return options[item] === true && formatKeys.includes(item); }); if (specialFormatKeys.length === 1 && formatMap[specialFormatKeys[0]]) { value = formatMap[specialFormatKeys[0]](_objectSpread$3({ value: value }, options)); } /** * 数组容器中子项为空不删除 */ if ((options.isDelete || isEmpty(value)) && getKey(fieldKey, 'dataSchema').split('.').pop() !== 'items') { // 使用JSON Schema规范的required关键字校验必填 if (requiredMode === 'default') { // 删除formData中相应表单字段(fix:表单为空之后必填校验失效) dispatch({ type: 'setData', action: { deleteKeys: fieldKey } }); } else { // 通过minLength、minItems控制必填 dispatch({ type: 'setData', action: { set: _defineProperty({}, fieldKey, value) } }); } // 删除dataSchema中相应default(fix: text默认值后续删除不自动添加) dispatch({ type: 'setValidate', action: { deleteKeys: "".concat(getKey(fieldKey, 'dataSchema'), ".default") } }); } else { dispatch({ type: 'setData', action: { set: _defineProperty({}, fieldKey, value) } }); } dispatch({ type: 'setChecking', checking: true }); run(value, dispatch); }, [dispatch, onChange, fieldKey]); }; var useQuery = function useQuery(_ref, dispatch) { var options = _ref.options, queryFunc = _ref.queryFunc, _ref$requestCache = _ref.requestCache, requestCache = _ref$requestCache === void 0 ? true : _ref$requestCache, fieldKey = _ref.fieldKey, getKey = _ref.getKey; return useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var data, _args = arguments; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!((options.length === 0 || !requestCache) && queryFunc)) { _context.next = 5; break; } _context.next = 3; return queryFunc.apply(void 0, _args); case 3: data = _context.sent; dispatch({ type: 'setUi', action: { set: _defineProperty({}, "".concat(getKey(fieldKey, 'uiSchema'), ".options"), data) } }); case 5: case "end": return _context.stop(); } } }, _callee); })), [dispatch, fieldKey, getKey, options.length, queryFunc, requestCache]); }; var useArray = function useArray(_ref) { var fieldKey = _ref.fieldKey, dispatch = _ref.dispatch, fieldData = _ref.fieldData; // 新增一项 var addItem = useCallback(function (order, item) { dispatch({ type: 'setArrayKey', action: { fieldKey: fieldKey, order: order } }); dispatch({ type: 'setData', action: { set: _defineProperty({}, fieldKey, produce(fieldData || [], function (draft) { draft.splice(order, 0, item); })) } }); }, [dispatch, fieldData, fieldKey]); // 删除一项 var deltItem = useCallback(function (order) { dispatch({ type: 'setArrayKey', action: { fieldKey: fieldKey, order: order, isDelete: true } }); // 删除自定义错误 dispatch({ type: 'setErr', action: { deleteKeys: "".concat(fieldKey, ".").concat(order) } }); dispatch({ type: 'setData', action: { deleteKeys: "".concat(fieldKey, ".").concat(order) } }); }, [dispatch, fieldKey]); // 切换顺序 var arrayMove = useCallback(function (oldIndex, newIndex) { dispatch({ type: 'setData', action: { set: _defineProperty({}, fieldKey, produce(fieldData || [], function (draft) { draft.splice(newIndex, 0, draft.splice(oldIndex, 1)[0]); })) } }); dispatch({ type: 'setArrayKey', action: { fieldKey: fieldKey, move: [oldIndex, newIndex] } }); }, [dispatch, fieldData, fieldKey]); return { addItem: addItem, deltItem: deltItem, arrayMove: arrayMove }; }; /* * container容器通用逻辑 * @Author: jiangxiaowei * @Date: 2021-08-05 11:18:43 * @Last Modified by: jiangxiaowei * @Last Modified time: 2022-01-26 17:58:40 */ var useContainer = function useContainer(_ref) { var fieldKey = _ref.fieldKey, dispatch = _ref.dispatch; //container容器加载的时候将当前表单fieldKey加入到visibleFieldKey中 useEffect(function () { dispatch({ type: 'setVisibleKey', action: { fieldKey: fieldKey } }); return function () { dispatch({ type: 'setVisibleKey', action: { deleteKeys: fieldKey } }); }; }, [dispatch, fieldKey]); }; /* * 获取fieldKey相对uiSchema、dataSchema、typeMap路径 * @Author: jiangxiaowei * @Date: 2021-08-11 11:39:48 * @Last Modified by: jiangxiaowei * @Last Modified time: 2022-08-12 12:46:46 */ var useGetKey = function useGetKey(typeMap) { // 获取fieldKey相对typeMap的路径 var getTypeKey = useCallback(function (fieldKey) { var fieldKeyToTypeMap = Object.keys(typeMap).find(function (item) { return generateReg(fieldKey.split('.')).test(item); }); if (!fieldKeyToTypeMap) { console.error(fieldKey, typeMap); throw "\u65E0\u6CD5\u5728typeMap\u4E2D\u627E\u5230\u4E0E".concat(fieldKey, "\u5BF9\u5E94\u7684key,"); } return fieldKeyToTypeMap; }, [typeMap]); // 获取fieldKey相对uiSchema、dataSchema路径 var getKey = useCallback(function (fieldKey, type) { if (type === 'data') return fieldKey; if (type === 'unitedSchema') return typeMap[getTypeKey(fieldKey)].unitedSchemaKey; return getTypeKey(fieldKey).split('.').reduce(function (prev, cur, index, arr) { switch (index === 0 ? 'object' : typeMap[arr.slice(0, index).join('.')].type) { case 'array': if (cur === '$container') { // 普通数组 return type === 'uiSchema' ? "".concat(prev ? "".concat(prev, ".") : '', "properties.").concat(cur) : "".concat(prev ? "".concat(prev, ".") : '', "items"); } else { // 元祖 return type === 'uiSchema' ? "".concat(prev ? "".concat(prev, ".") : '', "properties.").concat(cur) : "".concat(prev ? "".concat(prev, ".") : '', "items.").concat(cur); } case 'object': // 对象 return "".concat(prev ? "".concat(prev, ".") : '', "properties.").concat(cur); default: return "".concat(prev ? "".concat(prev, ".") : '', "properties.").concat(cur); } }, ''); }, [getTypeKey, typeMap]); return { getTypeKey: getTypeKey, getKey: getKey }; }; function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$2(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } var useSchema = function useSchema(_ref) { var uiSchema = _ref.uiSchema, dataSchema = _ref.dataSchema, typeMap = _ref.typeMap, formData = _ref.formData, dispatch = _ref.dispatch, prevFormData = _ref.prevFormData, prevUiSchema = _ref.prevUiSchema, prevDataSchema = _ref.prevDataSchema, prevTypeMap = _ref.prevTypeMap; var _useGetKey = useGetKey(typeMap), getTypeKey = _useGetKey.getTypeKey, getKey = _useGetKey.getKey; var get = useCallback(function (fieldKey) { var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { isPrev: false }; var isPrev = option === null || option === void 0 ? void 0 : option.isPrev; var newFormData = isPrev ? prevFormData : formData; var newTypeMap = isPrev ? prevTypeMap : typeMap; var newUiSchema = isPrev ? prevUiSchema : uiSchema; var newDataSchema = isPrev ? prevDataSchema : dataSchema; try { // 找不到则获取根目录 if (!fieldKey) { return { uiSchema: newUiSchema, dataSchema: newDataSchema, data: newFormData }; } else { var fieldKeyMap = fieldKey.split('.'); var arr = getTypeKey(fieldKey).split('.'); return arr.reduce(function (prev, cur, index, arr) { if (cur === '') { // 返回根目录的dataSchema、uiSchema、formData return prev; } else if (index === 0 || newTypeMap[arr.slice(0, index).join('.')].type === 'object') { // 对象类型 return { uiSchema: prev.uiSchema.properties[cur], dataSchema: prev.dataSchema.properties[cur], data: prev.data ? prev.data[cur] : undefined }; } else if (newTypeMap[arr.slice(0, index).join('.')].type === 'array') { // 数组类型 if (cur === '$container') { // 普通数组 return { uiSchema: prev.uiSchema.properties.$container, dataSchema: prev.dataSchema[index === 0 ? 'properties' : 'items'], data: prev.data ? prev.data[fieldKeyMap[index]] : undefined }; } else { // 元祖 return { uiSchema: prev.uiSchema.properties[cur], dataSchema: prev.dataSchema[index === 0 ? 'properties' : 'items'][cur], data: prev.data ? prev.data[cur] : undefined }; } } else { return { uiSchema: prev.uiSchema, dataSchema: prev.dataSchema, data: prev.data }; } }, { data: newFormData, uiSchema: newUiSchema, dataSchema: newDataSchema }); } } catch (error) { return { data: undefined, uiSchema: undefined, dataSchema: undefined }; } }, [dataSchema, formData, getTypeKey, prevDataSchema, prevFormData, prevTypeMap, prevUiSchema, typeMap, uiSchema]); /** * 获取当前value值 * @param fieldKey 表单项路径,a.b.c * @param value 待替换值 * @param type 类型 */ var handleFn = useCallback(function (fieldKey, value, type) { var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'set'; var typeMap = { data: formData, uiSchema: uiSchema, dataSchema: dataSchema }; // 根据FieldKey和type,获取在schema中的真实位置,如在ui中的a.properties.b.properties.c // 生成解析映射树 ''在set中代表根路径,所以直接返回 var oldData; if (fieldKey === '') { oldData = typeMap[type]; } else { var key = getKey(fieldKey, type); oldData = key.split('.').reduce(function (prev, cur) { return prev[cur]; }, typeMap[type]); } switch (typeCheck(value)) { case 'Function': return produce(oldData, value); case 'Object': if (mode === 'set') { return value; } else { var recursionFn = function recursionFn(oldData, value) { return produce(oldData, function (draft) { for (var i in value) { if (typeCheck(value[i]) === 'Object') { // 如果存在,继续递归遍历设置对象的每个属性类似webpack-merge方式 if (draft[i]) { draft[i] = recursionFn(draft[i], value[i]); } else { // 不存在直接设置 draft[i] = value[i]; } } else { draft[i] = value[i]; } } }); }; return recursionFn(oldData, value); } default: return value; } }, [dataSchema, formData, getKey, uiSchema]); // TODO 多个set合并 var set = useCallback(function (key, type, value) { switch (type) { case 'data': dispatch({ type: 'setData', action: _objectSpread$2(_objectSpread$2({}, key === '' && { formData: handleFn(key, value, 'data') }), key !== '' && { set: _defineProperty({}, key, handleFn(key, value, 'data')) }) }); break; case 'uiSchema': dispatch({ type: 'setUi', action: _objectSpread$2(_objectSpread$2({}, key === '' && { uiSchema: handleFn(key, value, 'uiSchema') }), key !== '' && { set: _defineProperty({}, getKey(key, 'uiSchema'), handleFn(key, value, 'uiSchema')) }) }); break; case 'dataSchema': dispatch({ type: 'setValidate', action: _objectSpread$2(_objectSpread$2({}, key === '' && { dataSchema: handleFn(key, value, 'dataSchema') }), key !== '' && { set: _defineProperty({}, getKey(key, 'dataSchema'), handleFn(key, value, 'dataSchema')) }) }); break; } }, [dispatch, getKey, handleFn]); // 支持深度merge,类似webpack-merge方式 var merge = useCallback(function (key, type, value) { switch (type) { case 'data': dispatch({ type: 'setData', action: _objectSpread$2(_objectSpread$2({}, key === '' && { formData: handleFn(key, value, 'data', 'merge') }), key !== '' && { set: _defineProperty({}, key, handleFn(key, value, 'data', 'merge')) }) }); break; case 'uiSchema': dispatch({ type: 'setUi', action: _objectSpread$2(_objectSpread$2({}, key === '' && { uiSchema: handleFn(key, value, 'uiSchema', 'merge') }), key !== '' && { set: _defineProperty({}, getKey(key, 'uiSchema'), handleFn(key, value, 'uiSchema', 'merge')) }) }); break; case 'dataSchema': dispatch({ type: 'setValidate', action: _objectSpread$2(_objectSpread$2({}, key === '' && { dataSchema: handleFn(key, value, 'dataSchema', 'merge') }), key !== '' && { set: _defineProperty({}, getKey(key, 'dataSchema'), handleFn(key, value, 'dataSchema', 'merge')) }) }); break; } }, [dispatch, getKey, handleFn]); /** * 删除一个表单项(同步删除uiSchema、dataSchema中的配置) */ var deleteField = useCallback(function (key, cb) { dispatch({ type: 'deleteField', action: { fieldKey: key, get: get, getKey: getKey, getTypeKey: getTypeKey } }); cb && cb(); }, [dispatch, get, getKey, getTypeKey]); /** * 添加一个表单项 */ var addField = useCallback(function (_ref2) { var fieldKey = _ref2.fieldKey, closestEdge = _ref2.closestEdge, unitedSchema = _ref2.unitedSchema, overFieldKey = _ref2.overFieldKey, cb = _ref2.cb, shouldDelete = _ref2.shouldDelete; dispatch({ type: 'addField', action: { fieldKey: fieldKey, closestEdge: closestEdge, unitedSchema: unitedSchema, overFieldKey: overFieldKey, get: get, getKey: getKey, getTypeKey: getTypeKey, shouldDelete: shouldDelete } }); cb && cb(); }, [dispatch, get, getKey, getTypeKey]); return { get: get, set: set, deleteField: deleteField, addField: addField, merge: merge }; }; function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$1(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /** * title margin的基础数值,分别对应title在不同方位的布局 */ var baseTitleMargin = { top: ['0', '0', '5px', '0'], right: ['0', '0', '0', '10px'], bottom: ['5px', '0', '0', '0'], left: ['0', '10px', '0', '0'] }; /** * margin中index对应margin方向的映射 */ var indexToMarginP = ['marginTop', 'marginRight', 'marginBottom', 'marginLeft']; function calcTitleMargin(titleUi, titlePlacement) { // 根据title布局确认基础margin,默认使用 var marginRes = baseTitleMargin[titlePlacement || 'left']; if (Object.hasOwnProperty.call(titleUi, 'margin')) { var _titleUi$margin; // 解析margin,并映射到数组对应字段,数组顺序与margin原书写顺序一致 var tmpMargin = (titleUi === null || titleUi === void 0 ? void 0 : (_titleUi$margin = titleUi.margin) === null || _titleUi$margin === void 0 ? void 0 : _titleUi$margin.split(' ')) || []; tmpMargin = tmpMargin.filter(function (item) { return !!item; }); if (tmpMargin.length === 1) { marginRes = marginRes.map(function () { return tmpMargin[0]; }); } else if (tmpMargin.length === 2) { marginRes = marginRes.map(function (item, idx) { return idx % 2 === 0 ? tmpMargin[0] : tmpMargin[1]; }); } else if (tmpMargin.length === 3) { marginRes = marginRes.map(function (item, idx) { return idx === 3 ? tmpMargin[1] : tmpMargin[idx]; }); } else { marginRes = tmpMargin; } } // 如果配置了marginRight等字段,则优先级更高,可覆盖base配置 marginRes = marginRes.map(function (item, idx) { var part = indexToMarginP[idx]; var hasPartMargin = Object.hasOwnProperty.call(titleUi, part); var value = hasPartMargin && titleUi !== null ? Object.hasOwnProperty.call(titleUi, part) && titleUi[part] !== undefined ? titleUi[part] : item : item; return Number.isNaN(Number(value)) ? "".concat(value) : "".concat(value, "px"); }); return { // 用于覆写style style: marginRes.join(' '), // 用于计算其他元素的宽度或padding stringArr: marginRes }; } /** * * @param titleUi ui中的title字段 * @param type ui的type类型 * @returns */ var useTitle = function useTitle(titleUi, type) { // title的margin样式 var _useState = useState(function () { return calcTitleMargin(titleUi, titleUi === null || titleUi === void 0 ? void 0 : titleUi.placement); }), _useState2 = _slicedToArray(_useState, 2), titleMargin = _useState2[0], onChangeTitleMargin = _useState2[1]; useEffect(function () { onChangeTitleMargin(calcTitleMargin(titleUi, titleUi === null || titleUi === void 0 ? void 0 : titleUi.placement)); }, [titleUi]); // 标题宽度 var titleWidth = useMemo(function () { if (type === 'object') return '100%'; return typeCheck((titleUi === null || titleUi === void 0 ? void 0 : titleUi.width) || 82) === 'Number' ? "".concat((titleUi === null || titleUi === void 0 ? void 0 : titleUi.width) || 82, "px") : (titleUi === null || titleUi === void 0 ? void 0 : titleUi.width) || '82px'; }, [titleUi === null || titleUi === void 0 ? void 0 : titleUi.width, type]); return _objectSpread$1(_objectSpread$1({}, titleUi), {}, { margin: titleMargin.style, width: titleWidth, marginTop: titleMargin.stringArr[0], marginRight: titleMargin.stringArr[1], marginBottom: titleMargin.stringArr[2], marginLeft: titleMargin.stringArr[3] }); }; /* * drip form全局配置 * @Author: jiangxiaowei * @Date: 2022-09-21 16:41:46 * @Last Modified by: jiangxiaowei * @Last Modified time: 2022-09-29 17:33:39 */ // 默认全局配置 var defaultGlobalOptions = { reload: true, ajvValidateDelay: 0, undefinedComponent: { type: 'tips', value: function value(_ref) { var theme = _ref.theme, type = _ref.type, fieldKey = _ref.fieldKey; if (theme && type) { return "Unable to find ".concat(type, " component in theme ").concat(theme, ", please confirm whether to import it"); } else { return "Unable to find custom component ".concat(fieldKey, ", please confirm whether to import it"); } } }, fieldTitleEditable: false, selectedFieldKey: null, setFieldTitleChange: function setFieldTitleChange() {}, showTitleWithIcon: null, getDeletedColumnsIndex: null }; var globalOptionsContext = /*#__PURE__*/createContext(defaultGlobalOptions); // 返回上一次的value值 var useGlobalOptions = function useGlobalOptions() { return useContext(globalOptionsContext); }; /* * 全局状态 * @Author: linjunchen5 */ // 默认全局状态 var defaultGlobalState = { stageErrors: {}, apiJson: {}, webModalForPlaceAutoCompleteField: null, setGlobalState: function setGlobalState() {} }; var globalStateContext = /*#__PURE__*/createContext(defaultGlobalState); // 返回上一次的value值 var useGlobalState = function useGlobalState() { return useContext(globalStateContext); }; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } var useCountryStateCityOptions = function useCountryStateCityOptions(selectedOptions, countryConfig, stateConfig, cityConfig) { var _useState = useState([]), _useState2 = _slicedToArray(_useState, 2), countryOption = _useState2[0], setCountryOption = _useState2[1]; var _useState3 = useState([]), _useState4 = _slicedToArray(_useState3, 2), stateOption = _useState4[0], setStateOption = _useState4[1]; var _useState5 = useState([]), _useState6 = _slicedToArray(_useState5, 2), cityOption = _useState6[0], setCityOption = _useState6[1]; useEffect(function () { if (countryConfig) { fetchFnJsonKey({ config: _objectSpread({}, countryConfig), dataHandler: setCountryOption }); } }, [JSON.stringify(countryConfig)]); useEffect(function () { if (selectedOptions.country && stateConfig) { var temp = _objectSpread({}, stateConfig); temp.url = temp.url.replace(':countryCode', selectedOptions.country); fetchFnJsonKey({ config: temp, dataHandler: setStateOption }); } }, [selectedOptions.country, JSON.stringify(stateConfig)]); useEffect(function () { if (selectedOptions.state && stateConfig && cityConfig) { var temp = _objectSpread({}, cityConfig); temp.url = temp.url.replace(':stateCode', selectedOptions.state); fetchFnJsonKey({ config: temp, dataHandler: setCityOption }); } else if (selectedOptions.country && countryConfig && cityConfig && !stateConfig) { var _temp = _objectSpread({}, cityConfig); _temp.url = _temp.url.replace(':countryCode', selectedOptions.country); fetchFnJsonKey({ config: _temp, dataHandler: setCityOption }); } }, [selectedOptions.country, JSON.stringify(countryConfig), selectedOptions.state, JSON.stringify(stateConfig), JSON.stringify(cityConfig)]); return { countryOption: countryOption, stateOption: stateOption, cityOption: cityOption, setCountryOption: setCountryOption, setStateOption: setStateOption, setCityOption: setCityOption }; }; var useScreenSize = function useScreenSize() { var _useState = useState(window.innerWidth), _useState2 = _slicedToArray(_useState, 2), screenSize = _useState2[0], setScreenSize = _useState2[1]; useEffect(function () { var handleResize = function handleResize() { return setScreenSize(window.innerWidth); }; window.addEventListener('resize', handleResize); return function () { return window.removeEventListener('resize', handleResize); }; }, []); return screenSize; }; export { RequiredModeContext, defaultGlobalOptions, defaultGlobalState, globalOptionsContext, globalStateContext, useArray, useClickOne, useContainer, useCountryStateCityOptions, useEventCallback, useField, useGetKey, useGlobalOptions, useGlobalState, useModal, usePrevious, useQuery, useRefProp, useRequiredModeContext, useSchema, useScreenSize, useTitle, useValidate, validate };