mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 14:39:25 +08:00
* fix(filter-form): fix operator not valid in block templates * test: add e2e test * test: clear data templates * chore: fix e2e tests * chore: stash * chore: change import path to fix unit tests * chore: change import path to fix unit tests * chore: fix build
96 lines
2.8 KiB
TypeScript
96 lines
2.8 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, useMemo } from 'react';
|
|
import { useDesignable } from '../schema-component';
|
|
|
|
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;
|
|
};
|
|
|
|
export function useDynamicComponentProps(useComponentPropsStr?: string, props?: any) {
|
|
const scope = useExpressionScope();
|
|
|
|
const useDynamicProps = useMemo(() => {
|
|
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;
|
|
}, [useComponentPropsStr]);
|
|
|
|
const res = useDynamicProps(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 <Component {...memoProps}>{props.children}</Component>;
|
|
};
|
|
|
|
Component.displayName = displayName;
|
|
ComponentWithProps.displayName = `withSchemaProps(${displayName})`;
|
|
|
|
return ComponentWithProps;
|
|
}
|