mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 22:49:26 +08:00
* fix: missing less loader while building client * fix: correct regex for .less file handling and resolve less-loader path * feat: dynamic import big react components for core plugins * chore: revert lerna.json * chore: remove global deps duplications [skip ci] * chore: optimization * feat: dynamic import for markdown vditor plugin * chore: optimization * chore: more optimization * feat: code split for plugins with some ui components * fix: incorrect submodule commit * fix: test cases failure * chore: refactor hook lazy import * chore: improve lazy component loading * chore: lazy load vditor lib's js files [skip ci] * chore: add bundle analyze option for client bundle * chore: update loading sytle * fix: add spinner when loading umi js files * chore: clean * chore: resolve develop branch confliction * chore: refactor helper function name * fix: error of lazy duplication [skip ci] * fix: replace useImported with uselazyhook * chore: rename * chore: add comments for the helper function * chore: update comment * fix: keep suspense into component level * fix: improve code --------- Co-authored-by: chenos <chenlinxh@gmail.com>
100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import { useExpressionScope } from '@formily/react';
|
|
import _ from 'lodash';
|
|
import React, { ComponentType, Suspense, useMemo } from 'react';
|
|
import { useDesignable } from '../schema-component';
|
|
import { Spin } from 'antd';
|
|
|
|
const useDefaultDynamicComponentProps = () => undefined;
|
|
|
|
const getHook = (str: string, scope: Record<string, any>, allText: string) => {
|
|
let res = undefined;
|
|
if (_.isFunction(str)) {
|
|
res = str;
|
|
} else {
|
|
res = scope[str];
|
|
if (!res) {
|
|
console.error(`${allText} is not registered`);
|
|
}
|
|
}
|
|
return res || useDefaultDynamicComponentProps;
|
|
};
|
|
|
|
const getUseDynamicProps = (useComponentPropsStr: string, scope: Record<string, any>) => {
|
|
if (!useComponentPropsStr) {
|
|
return useDefaultDynamicComponentProps;
|
|
}
|
|
|
|
if (_.isFunction(useComponentPropsStr)) {
|
|
return useComponentPropsStr;
|
|
}
|
|
|
|
const pathList = useComponentPropsStr.split('.');
|
|
let result;
|
|
|
|
for (const item of pathList) {
|
|
result = getHook(item, result || scope, useComponentPropsStr);
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
export function useDynamicComponentProps(useComponentPropsStr?: string, props?: any) {
|
|
const scope = useExpressionScope();
|
|
const res = getUseDynamicProps(useComponentPropsStr, scope)(props);
|
|
|
|
return res;
|
|
}
|
|
|
|
interface WithSchemaHookOptions {
|
|
displayName?: string;
|
|
}
|
|
|
|
export function withDynamicSchemaProps<T = any>(
|
|
Component: React.ComponentType<T>,
|
|
options: WithSchemaHookOptions = {},
|
|
) {
|
|
const displayName = options.displayName || Component.displayName || Component.name;
|
|
const ComponentWithProps: ComponentType<T> = (props) => {
|
|
const { dn, findComponent } = useDesignable();
|
|
const useComponentPropsStr = useMemo(() => {
|
|
const xComponent = dn.getSchemaAttribute('x-component');
|
|
const xDecorator = dn.getSchemaAttribute('x-decorator');
|
|
const xUseComponentProps = dn.getSchemaAttribute('x-use-component-props');
|
|
const xUseDecoratorProps = dn.getSchemaAttribute('x-use-decorator-props');
|
|
|
|
if (xComponent && xUseComponentProps && findComponent(xComponent) === ComponentWithProps) {
|
|
return xUseComponentProps;
|
|
}
|
|
|
|
if (xDecorator && xUseDecoratorProps && findComponent(xDecorator) === ComponentWithProps) {
|
|
return xUseDecoratorProps;
|
|
}
|
|
}, [dn]);
|
|
const schemaProps = useDynamicComponentProps(useComponentPropsStr, props);
|
|
|
|
const memoProps = useMemo(() => {
|
|
return { ...props, ...schemaProps };
|
|
}, [schemaProps, props]);
|
|
|
|
return (
|
|
<Suspense fallback={<Spin />}>
|
|
<Component {...memoProps}>{props.children}</Component>
|
|
</Suspense>
|
|
);
|
|
};
|
|
|
|
Component.displayName = displayName;
|
|
ComponentWithProps.displayName = `withSchemaProps(${displayName})`;
|
|
|
|
return ComponentWithProps;
|
|
}
|