@schema-render/core-react
Version:
Through a set of simple JSON Schema, efficiently build a set of forms.
102 lines (101 loc) • 3.33 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { forwardRef, useMemo, useRef } from "react";
import ErrorBoundary from "./components/ErrorBoundary";
import useCoreValue from "./hooks/useCoreValue";
import useLayoutStyle, { LAYOUT_MIN_MAX } from "./hooks/useLayoutStyle";
import useOpenApi from "./hooks/useOpenApi";
import zhCN from "./locale/zh_CN";
import RootContext from "./RootContext";
import RendererIterator from "./services/RendererIterator";
import assert from "./utils/assert";
import { classNamesWithPrefix } from "./utils/base";
import classNames from "./utils/classnames";
import { mapKeys, pick } from "./utils/tinyLodash";
const DEFAULT_CONFIG = {
prefixCls: 'schema-render',
layout: 'normal',
layoutColumnGap: 10,
layoutRowGap: 15,
layoutMinMax: LAYOUT_MIN_MAX,
disabled: false,
readonly: false,
validators: {},
userCtx: {}
};
const InnerCore = /*#__PURE__*/ forwardRef((coreProps, ref)=>{
assert.falsy(coreProps.schema, 'missing schema.');
assert.falsy(coreProps.itemLayout, 'missing itemLayout.');
const props = {
...DEFAULT_CONFIG,
...coreProps
};
const rootElementRef = useRef(null);
const rootContextRef = useRef({});
// 表单数据 value 控制
const { value, onChange, getValue, setValue, resetValue } = useCoreValue(props);
// 合并语言
const locale = useMemo(()=>({
...zhCN,
...props.locale
}), [
props.locale
]);
// 处理渲染器与其名称
const renderers = useMemo(()=>mapKeys(props.renderers, (_, key)=>key.toLowerCase()), [
props.renderers
]);
// 计算布局样式
const layoutStyle = useLayoutStyle(props);
// root context value
const rootCtxVal = rootContextRef.current = {
...pick(props, 'disabled', 'readonly', 'prefixCls', 'layout', 'itemLayout', 'userCtx', 'validators', 'catchErrorTips'),
objectStyle: layoutStyle,
renderers,
rootSchema: props.schema,
rootValue: value,
locale,
rendererStorage: {},
// 事件
onChange,
// 方法
prefixClassNames: (...args)=>classNamesWithPrefix(props.prefixCls, ...args)
};
// 开放 API
useOpenApi({
ref,
rootElementRef,
rootContextRef,
getValue,
setValue,
resetValue
});
return /*#__PURE__*/ _jsx(RootContext.Provider, {
value: rootCtxVal,
children: /*#__PURE__*/ _jsx("div", {
className: classNames(rootCtxVal.prefixCls, props.className, {
'is-disabled': rootCtxVal.disabled,
'is-readonly': rootCtxVal.readonly
}),
ref: rootElementRef,
style: {
position: 'relative',
...layoutStyle,
...props.style
},
children: /*#__PURE__*/ _jsx(RendererIterator, {
schema: rootCtxVal.rootSchema,
path: []
})
})
});
});
const Core = /*#__PURE__*/ forwardRef((props, ref)=>{
return /*#__PURE__*/ _jsx(ErrorBoundary, {
catchErrorTips: props.catchErrorTips,
children: /*#__PURE__*/ _jsx(InnerCore, {
...props,
ref: ref
})
});
});
export default Core;