import { JSSlot, isJSSlot, NodeData } from '@alilc/lowcode-types'; import { CodeGeneratorError, NodeGenerator, IScope } from '../types'; import { unwrapJsExprQuoteInJsx } from './jsxHelpers'; function generateSingleLineComment(commentText: string): string { return `/* ${commentText.split('\n').join(' ').replace(/\*\//g, '*-/')}*/`; } export function generateJsSlot(slot: any, scope: IScope, generator: NodeGenerator): string { if (isJSSlot(slot)) { const { title, params, value } = slot as JSSlot; // slot 也是分有参数和无参数的 // - 有参数的 slot 就是类似一个 render 函数,需要创建子作用域 // - 无参数的 slot 就是类似一个 JSX 节点,不需要创建子作用域 const slotScope = params ? scope.createSubScope(params || []) : scope; const contentExpr = !value ? 'null' : generateNodeDataOrArrayForJsSlot(value, generator, slotScope); if (params) { return [ title && generateSingleLineComment(title), '(', (params || []).join(', '), ') => ((__$$context) => (', contentExpr, '))(', ` __$$createChildContext(__$$context, { ${(params || []).join(', ')} }`, '))', ] .filter(Boolean) .join(''); } return contentExpr || '[]'; } throw new CodeGeneratorError('Not a JSSlot'); } function generateNodeDataOrArrayForJsSlot( value: NodeData | NodeData[], generator: NodeGenerator, scope: IScope, ) { if (Array.isArray(value)) { if (value.length === 0) { return '[]'; } if (value.length === 1) { return unwrapJsExprQuoteInJsx(generator(value, scope)) || 'null'; } return `[\n${ value .map((v) => { if (typeof v === 'string') { return JSON.stringify(v); } return unwrapJsExprQuoteInJsx(generator(v, scope)) || 'null'; }) .join(',\n') || 'null' }\n]`; } return unwrapJsExprQuoteInJsx(generator(value, scope)) || 'null'; }