UNPKG

@schema-render/core-react

Version:

Through a set of simple JSON Schema, efficiently build a set of forms.

88 lines (87 loc) 3.72 kB
import { useImperativeHandle } from "react"; import { EValidationStatus } from "../constants"; import { isArray, isString } from "../utils/checking"; import { positionedOffset } from "../utils/dom"; import { stringifyPath } from "../utils/misc"; import { pick } from "../utils/tinyLodash"; import { validateRootSchema } from "../utils/validator"; import useMemoizedFn from "./useMemoizedFn"; /** * 内部滚动到指定表单项位置方法 * @param formItemElement 表单项 DOM 元素 * @param coreRootElement 内核根节点元素 * @param options 参数 */ function internalScrollTo(formItemElement, coreRootElement, options = {}) { if (!formItemElement) { return; } // 解构参数,并赋予默认值 const { positionedElement, xAxis, yAxis, behavior = 'smooth', gap = 0 } = options; // 表单内部滚动,取根节点元素,否则取用户指定的 “定位元素” const scrollElement = positionedElement || coreRootElement; if (scrollElement) { // 获取指定表单项元素到滚动祖先元素的距离 const offset = positionedOffset(formItemElement, scrollElement); // 滚动到指定位置 scrollElement.scrollTo({ left: xAxis === false ? undefined : offset.left + gap, top: yAxis === false ? undefined : offset.top + gap, behavior }); } } /** * 开放 API */ export default function useOpenApi({ ref, rootElementRef, rootContextRef, getValue, setValue, resetValue }) { const validate = useMemoizedFn(()=>{ return validateRootSchema(pick(rootContextRef.current, 'rootSchema', 'rootValue', 'locale', 'disabled', 'readonly', 'renderers', 'rendererStorage', 'validators', 'userCtx')); }); /** * 查找指定表单项 */ const findItem = useMemoizedFn((paths)=>{ var _rootContextRef_current; const renderers = (_rootContextRef_current = rootContextRef.current) === null || _rootContextRef_current === void 0 ? void 0 : _rootContextRef_current.rendererStorage; if (renderers && paths) { const sPath = isArray(paths) ? stringifyPath(paths) : paths; return renderers[sPath]; } }); /** * 重置错误与警告 */ const resetError = useMemoizedFn((paths)=>{ var _rootContextRef_current; const renderers = (_rootContextRef_current = rootContextRef.current) === null || _rootContextRef_current === void 0 ? void 0 : _rootContextRef_current.rendererStorage; if (renderers) { const pathList = !paths ? Object.keys(renderers) : isString(paths) ? [ paths ] : paths; pathList.forEach((pathKey)=>{ var _renderers_pathKey; (_renderers_pathKey = renderers[pathKey]) === null || _renderers_pathKey === void 0 ? void 0 : _renderers_pathKey.setValidatorState({ status: EValidationStatus.success }); }); } }); /** * 获取 Core 根节点元素 */ const getRootElement = useMemoizedFn(()=>rootElementRef.current); /** * 滚动到指定位置 */ const scrollTo = useMemoizedFn((paths, options)=>{ var _findItem; return internalScrollTo((_findItem = findItem(paths)) === null || _findItem === void 0 ? void 0 : _findItem.getRootElement(), getRootElement(), options); }); // 暴露开放 API useImperativeHandle(ref, ()=>({ validate, resetError, setValue, resetValue, getValue, getRootElement, scrollTo, findItem }), // eslint-disable-next-line react-hooks/exhaustive-deps []); }