|
@@ -12,22 +12,22 @@ import { useState } from 'react';
|
|
|
// ============ React 组件实现 ============
|
|
// ============ React 组件实现 ============
|
|
|
|
|
|
|
|
// Card 组件
|
|
// Card 组件
|
|
|
-const Card = ({ title, children, className, renderChildren }: any) => (
|
|
|
|
|
|
|
+const Card = ({ title, children, className, renderChildren, emit }: any) => (
|
|
|
<div className={`bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 shadow-sm p-4 ${className || ''}`}>
|
|
<div className={`bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 shadow-sm p-4 ${className || ''}`}>
|
|
|
{title && <h3 className="text-lg font-semibold mb-3 text-gray-900 dark:text-white">{title}</h3>}
|
|
{title && <h3 className="text-lg font-semibold mb-3 text-gray-900 dark:text-white">{title}</h3>}
|
|
|
- {renderChildren ? renderChildren(children) : null}
|
|
|
|
|
|
|
+ {renderChildren ? renderChildren(children, emit) : null}
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
// Stack 组件
|
|
// Stack 组件
|
|
|
-const Stack = ({ direction = 'column', spacing = 2, align = 'start', children, className, renderChildren }: any) => {
|
|
|
|
|
|
|
+const Stack = ({ direction = 'column', spacing = 2, align = 'start', children, className, renderChildren, emit }: any) => {
|
|
|
const directionClass = direction === 'row' ? 'flex-row' : 'flex-col';
|
|
const directionClass = direction === 'row' ? 'flex-row' : 'flex-col';
|
|
|
const spacingClass = spacing > 0 ? `gap-${spacing}` : '';
|
|
const spacingClass = spacing > 0 ? `gap-${spacing}` : '';
|
|
|
const alignClass = align === 'center' ? 'items-center' : align === 'end' ? 'items-end' : align === 'stretch' ? 'items-stretch' : 'items-start';
|
|
const alignClass = align === 'center' ? 'items-center' : align === 'end' ? 'items-end' : align === 'stretch' ? 'items-stretch' : 'items-start';
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<div className={`flex ${directionClass} ${spacingClass} ${alignClass} ${className || ''}`}>
|
|
<div className={`flex ${directionClass} ${spacingClass} ${alignClass} ${className || ''}`}>
|
|
|
- {renderChildren ? renderChildren(children) : null}
|
|
|
|
|
|
|
+ {renderChildren ? renderChildren(children, emit) : null}
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
|
};
|
|
};
|
|
@@ -499,8 +499,10 @@ export const jsonRenderRegistry: Record<string, React.ComponentType<any>> = {
|
|
|
/**
|
|
/**
|
|
|
* 递归渲染子组件
|
|
* 递归渲染子组件
|
|
|
* 用于 Card 和 Stack 组件中渲染 children 数组
|
|
* 用于 Card 和 Stack 组件中渲染 children 数组
|
|
|
|
|
+ * @param children - 子组件数组
|
|
|
|
|
+ * @param emit - ActionContext emit 函数(用于组件交互)
|
|
|
*/
|
|
*/
|
|
|
-export function renderChildren(children: any): React.ReactNode {
|
|
|
|
|
|
|
+export function renderChildren(children: any, emit?: (eventName: string, payload?: any) => void): React.ReactNode {
|
|
|
if (!children) return null;
|
|
if (!children) return null;
|
|
|
if (!Array.isArray(children)) return null;
|
|
if (!Array.isArray(children)) return null;
|
|
|
|
|
|
|
@@ -512,11 +514,18 @@ export function renderChildren(children: any): React.ReactNode {
|
|
|
const Component = (jsonRenderRegistry as any)[componentType];
|
|
const Component = (jsonRenderRegistry as any)[componentType];
|
|
|
|
|
|
|
|
if (Component) {
|
|
if (Component) {
|
|
|
- // 如果组件需要渲染子组件,传入 renderChildren 函数
|
|
|
|
|
|
|
+ // 合并 props:原始 child props + emit 函数
|
|
|
|
|
+ const props: any = { ...child };
|
|
|
|
|
+ if (emit) {
|
|
|
|
|
+ props.emit = emit;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果组件需要渲染子组件,传入 renderChildren 函数(并传递 emit)
|
|
|
if (componentType === 'card' || componentType === 'stack') {
|
|
if (componentType === 'card' || componentType === 'stack') {
|
|
|
- return <Component key={idx} {...child} renderChildren={renderChildren} />;
|
|
|
|
|
|
|
+ props.renderChildren = (grandchildren: any) => renderChildren(grandchildren, emit);
|
|
|
}
|
|
}
|
|
|
- return <Component key={idx} {...child} />;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return <Component key={idx} {...props} />;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
return (
|