@mybricks/to-code-taro 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/cjs/core/utils/ComContext.js +11 -2
  2. package/dist/cjs/core/utils/hooks.js +13 -4
  3. package/dist/cjs/core/utils/index.js +9 -2
  4. package/dist/cjs/core/utils/slots.js +124 -0
  5. package/dist/cjs/core/utils/useContext.js +10 -6
  6. package/dist/cjs/core/utils/with.js +32 -5
  7. package/dist/cjs/generate/generateTaroProjectJson.js +2 -2
  8. package/dist/cjs/handleCom.d.ts +7 -30
  9. package/dist/cjs/handleCom.js +171 -61
  10. package/dist/cjs/handleSlot.d.ts +3 -0
  11. package/dist/cjs/handleSlot.js +27 -10
  12. package/dist/cjs/processors/processScene.js +34 -1
  13. package/dist/cjs/processors/processSceneLogic.js +1 -1
  14. package/dist/cjs/taro-template.json +17 -13
  15. package/dist/cjs/toCodeTaro.d.ts +2 -0
  16. package/dist/cjs/utils/logic/handleProcess.js +8 -13
  17. package/dist/cjs/utils/logic/processChildren.d.ts +1 -0
  18. package/dist/cjs/utils/logic/processChildren.js +16 -1
  19. package/dist/cjs/utils/style/converter.js +43 -15
  20. package/dist/cjs/utils/style/pxtransform.d.ts +2 -26
  21. package/dist/cjs/utils/style/pxtransform.js +27 -67
  22. package/dist/cjs/utils/templates/component.js +4 -3
  23. package/dist/cjs/utils/templates/index.d.ts +10 -0
  24. package/dist/cjs/utils/templates/index.js +31 -7
  25. package/dist/cjs/utils/templates/renderManager.d.ts +3 -11
  26. package/dist/cjs/utils/templates/renderManager.js +86 -21
  27. package/dist/cjs/utils/templates/scene.d.ts +2 -1
  28. package/dist/cjs/utils/templates/scene.js +4 -1
  29. package/dist/esm/core/utils/ComContext.js +5 -0
  30. package/dist/esm/core/utils/hooks.js +14 -5
  31. package/dist/esm/core/utils/index.js +4 -2
  32. package/dist/esm/core/utils/slots.js +108 -0
  33. package/dist/esm/core/utils/useContext.js +21 -11
  34. package/dist/esm/core/utils/with.js +50 -7
  35. package/dist/esm/generate/generateTaroProjectJson.js +2 -2
  36. package/dist/esm/handleCom.d.ts +7 -30
  37. package/dist/esm/handleCom.js +224 -81
  38. package/dist/esm/handleSlot.d.ts +3 -0
  39. package/dist/esm/handleSlot.js +34 -11
  40. package/dist/esm/processors/processScene.js +36 -1
  41. package/dist/esm/processors/processSceneLogic.js +3 -1
  42. package/dist/esm/taro-template.json +17 -13
  43. package/dist/esm/toCodeTaro.d.ts +2 -0
  44. package/dist/esm/utils/logic/handleProcess.js +12 -16
  45. package/dist/esm/utils/logic/processChildren.d.ts +1 -0
  46. package/dist/esm/utils/logic/processChildren.js +17 -1
  47. package/dist/esm/utils/style/converter.js +66 -31
  48. package/dist/esm/utils/style/pxtransform.d.ts +2 -26
  49. package/dist/esm/utils/style/pxtransform.js +31 -98
  50. package/dist/esm/utils/templates/component.js +3 -2
  51. package/dist/esm/utils/templates/index.d.ts +10 -0
  52. package/dist/esm/utils/templates/index.js +33 -9
  53. package/dist/esm/utils/templates/renderManager.d.ts +3 -11
  54. package/dist/esm/utils/templates/renderManager.js +92 -23
  55. package/dist/esm/utils/templates/scene.d.ts +2 -1
  56. package/dist/esm/utils/templates/scene.js +4 -2
  57. package/package.json +1 -1
@@ -19,84 +19,44 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/utils/style/pxtransform.ts
20
20
  var pxtransform_exports = {};
21
21
  __export(pxtransform_exports, {
22
- MIN_PX_THRESHOLD: () => MIN_PX_THRESHOLD,
23
- REM_BASE: () => REM_BASE,
24
- default: () => pxtransform_default,
25
- pxToRem: () => pxToRem,
26
- pxToRpx: () => pxToRpx
22
+ default: () => pxtransform
27
23
  });
28
24
  module.exports = __toCommonJS(pxtransform_exports);
29
- var MIN_PX_THRESHOLD = 1;
30
- var REM_BASE = 20;
31
- function isPxValue(value) {
32
- if (typeof value === "number") {
33
- return true;
34
- }
35
- if (typeof value === "string") {
36
- const regex = /^(\d*\.?\d+)px$/;
37
- return regex.test(value);
38
- }
39
- return false;
40
- }
41
25
  function pxToRpx(value) {
42
26
  if (typeof value === "number") {
43
- if (value <= MIN_PX_THRESHOLD) {
44
- return value;
45
- }
46
27
  return `${value * 2}rpx`;
47
28
  }
48
- if (typeof value === "string") {
49
- const regex = /^(\d*\.?\d+)px$/;
50
- const match = value.match(regex);
51
- if (match) {
52
- const pxValue = parseFloat(match[1]);
53
- if (pxValue <= MIN_PX_THRESHOLD) {
54
- return pxValue;
55
- }
56
- return `${pxValue * 2}rpx`;
57
- }
58
- return value;
59
- }
60
- return value;
29
+ if (typeof value !== "string")
30
+ return String(value);
31
+ return value.replace(/(\d*\.?\d+)px/g, (_, num) => {
32
+ return `${parseFloat(num) * 2}rpx`;
33
+ });
61
34
  }
62
35
  function pxToRem(value) {
63
36
  if (typeof value === "number") {
64
- if (value <= MIN_PX_THRESHOLD) {
65
- return value;
66
- }
67
- const remValue = value / REM_BASE;
68
- return `${remValue}rem`;
37
+ return `${value / 16}rem`;
38
+ }
39
+ if (typeof value !== "string")
40
+ return String(value);
41
+ return value.replace(/(\d*\.?\d+)px/g, (_, num) => {
42
+ return `${parseFloat(num) / 16}rem`;
43
+ });
44
+ }
45
+ function isPxValue(value) {
46
+ if (typeof value === "number") {
47
+ return true;
69
48
  }
70
49
  if (typeof value === "string") {
71
- const regex = /^(\d*\.?\d+)px$/;
72
- const match = value.match(regex);
73
- if (match) {
74
- const pxValue = parseFloat(match[1]);
75
- if (pxValue <= MIN_PX_THRESHOLD) {
76
- return pxValue;
77
- }
78
- const remValue = pxValue / REM_BASE;
79
- return `${remValue}rem`;
80
- }
81
- return value;
50
+ return /\d*\.?\d+px/.test(value);
82
51
  }
83
- return value;
52
+ return false;
84
53
  }
85
- var pxtransform = (value, type = "rpx") => {
86
- if (isPxValue(value)) {
87
- if (type === "rpx") {
88
- return pxToRpx(value);
89
- } else if (type === "rem") {
90
- return pxToRem(value);
91
- }
54
+ function pxtransform(value, target = "rpx") {
55
+ if (!isPxValue(value)) {
56
+ return value;
92
57
  }
93
- return value;
94
- };
95
- var pxtransform_default = pxtransform;
96
- // Annotate the CommonJS export names for ESM import in node:
97
- 0 && (module.exports = {
98
- MIN_PX_THRESHOLD,
99
- REM_BASE,
100
- pxToRem,
101
- pxToRpx
102
- });
58
+ if (target === "rem") {
59
+ return pxToRem(value);
60
+ }
61
+ return pxToRpx(value);
62
+ }
@@ -26,7 +26,7 @@ __export(component_exports, {
26
26
  wrapEventProcess: () => wrapEventProcess
27
27
  });
28
28
  module.exports = __toCommonJS(component_exports);
29
- var import__ = require("../index");
29
+ var import_index = require("./index");
30
30
  var genComponentInputsCode = (indent, providerName, comId) => {
31
31
  return `${indent}inputs['${comId}'] = useBindInputs(controllers.current.${providerName}, '${comId}');
32
32
  `;
@@ -50,8 +50,9 @@ var genSlotRenderRef = ({
50
50
  indent,
51
51
  isLast
52
52
  }) => {
53
+ const renderFunctionName = (0, import_index.toPascalCase)(`${renderId}_Render`);
53
54
  return `${indent}${slotId}: {
54
- ${indent} render: ${renderId}_Render,
55
+ ${indent} render: ${renderFunctionName},
55
56
  ${indent}}${isLast ? "" : ","}
56
57
  `;
57
58
  };
@@ -70,7 +71,7 @@ var formatSlotContent = ({
70
71
  const originalIndentMatch = line.match(/^(\s*)/);
71
72
  const originalIndent = originalIndentMatch ? originalIndentMatch[1].length : 0;
72
73
  const relativeIndentLevel = Math.floor(originalIndent / baseIndentSize);
73
- const newIndent = renderBodyIndent + (0, import__.indentation)(baseIndentSize * relativeIndentLevel);
74
+ const newIndent = renderBodyIndent + (0, import_index.indentation)(baseIndentSize * relativeIndentLevel);
74
75
  formattedLines.push(newIndent + trimmedLine);
75
76
  });
76
77
  return formattedLines.join("\n");
@@ -1,9 +1,19 @@
1
+ import { indentation } from "../index";
2
+ export { indentation };
3
+ /** 将第一个字符转大写 */
4
+ export declare const firstCharToUpperCase: (str: string) => string;
5
+ /** 格式化插槽内容缩进 */
6
+ export declare const formatSlotContent: (uiContent: string, baseIndentSize: number, renderBodyIndent: string) => string;
7
+ /** 将字符串转为大驼峰 */
8
+ export declare const toPascalCase: (str: string) => string;
1
9
  /** Taro/React UI 组件代码生成 */
2
10
  export declare const getUiComponentCode: (params: {
3
11
  componentName: string;
4
12
  meta: any;
5
13
  props: any;
6
14
  resultStyle: Record<string, Record<string, string | number>>;
15
+ /** 可选:自定义 data 的表达式代码(用于插槽动态入参等场景) */
16
+ dataCode?: string;
7
17
  componentInputs?: string[];
8
18
  componentOutputs?: string[];
9
19
  comEventCode?: string;
@@ -19,19 +19,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/utils/templates/index.ts
20
20
  var templates_exports = {};
21
21
  __export(templates_exports, {
22
- getUiComponentCode: () => getUiComponentCode
22
+ firstCharToUpperCase: () => firstCharToUpperCase,
23
+ formatSlotContent: () => formatSlotContent,
24
+ getUiComponentCode: () => getUiComponentCode,
25
+ indentation: () => import__.indentation,
26
+ toPascalCase: () => toPascalCase
23
27
  });
24
28
  module.exports = __toCommonJS(templates_exports);
25
29
  var import__ = require("../index");
30
+ var firstCharToUpperCase = (str) => {
31
+ if (!str)
32
+ return str;
33
+ return str.charAt(0).toUpperCase() + str.slice(1);
34
+ };
35
+ var formatSlotContent = (uiContent, baseIndentSize, renderBodyIndent) => {
36
+ return uiContent.split("\n").map((line) => `${renderBodyIndent}${line}`).join("\n");
37
+ };
38
+ var toPascalCase = (str) => {
39
+ return str.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
40
+ };
26
41
  var getUiComponentCode = (params, config) => {
27
42
  const {
28
43
  componentName,
29
44
  meta,
30
45
  props,
31
46
  resultStyle,
32
- componentInputs,
33
- componentOutputs,
34
- comEventCode,
47
+ dataCode,
35
48
  slotsCode,
36
49
  eventHandlers = {}
37
50
  } = params;
@@ -44,22 +57,29 @@ ${indent2}component={${componentName}}`;
44
57
  ${indent2}id='${meta.id}'`;
45
58
  ui += `
46
59
  ${indent2}className='${meta.id}'`;
60
+ if (meta.name) {
61
+ ui += `
62
+ ${indent2}name='${meta.name}'`;
63
+ }
47
64
  if (resultStyle.root && Object.keys(resultStyle.root).length > 0) {
48
65
  const styleCode = JSON.stringify(resultStyle.root);
49
66
  ui += `
50
67
  ${indent2}style={${styleCode}}`;
51
68
  }
52
- const initialData = JSON.stringify(props.data || {});
69
+ const initialDataCode = dataCode ?? JSON.stringify(props.data || {});
53
70
  ui += `
54
- ${indent2}data={${initialData}}`;
71
+ ${indent2}data={${initialDataCode}}`;
55
72
  Object.entries(eventHandlers).forEach(([eventName, handlerCode]) => {
56
73
  ui += `
57
74
  ${indent2}${eventName}={${handlerCode}}`;
58
75
  });
59
76
  if (slotsCode) {
77
+ console.log(`[getUiComponentCode] Component ${meta.id} has slotsCode, length: ${slotsCode.length}`);
60
78
  ui += `
61
79
  ${indent2}slots={{
62
80
  ${slotsCode}${indent2}}}`;
81
+ } else {
82
+ console.log(`[getUiComponentCode] Component ${meta.id} has NO slotsCode`);
63
83
  }
64
84
  ui += `
65
85
  ${indent}/>`;
@@ -67,5 +87,9 @@ ${indent}/>`;
67
87
  };
68
88
  // Annotate the CommonJS export names for ESM import in node:
69
89
  0 && (module.exports = {
70
- getUiComponentCode
90
+ firstCharToUpperCase,
91
+ formatSlotContent,
92
+ getUiComponentCode,
93
+ indentation,
94
+ toPascalCase
71
95
  });
@@ -1,22 +1,14 @@
1
1
  /** Render 函数管理器 */
2
2
  export declare class RenderManager {
3
+ /** 存储格式:renderId -> { renderCode, children?, logicCode?, slotType?, useWrap?, description? } */
3
4
  private _renders;
4
5
  /**
5
6
  * 注册一个 render 函数
6
- * @param renderId 唯一标识符,格式:组件ID_插槽ID
7
- * @param renderCode render 函数的代码内容(不包含函数声明)
8
7
  */
9
- register(renderId: string, renderCode: string): void;
8
+ register(renderId: string, renderCode: string, children?: any[], logicCode?: string, slotType?: string, useWrap?: boolean, description?: string): void;
10
9
  /**
11
- * 生成所有 render 函数的定义代码
12
- * @param indent 基础缩进
10
+ * 生成所有 render 函数的 definition 代码
13
11
  */
14
12
  toCode(indent: string): string;
15
- /**
16
- * 生成 render 对象的引用代码
17
- * @param slotId 插槽ID
18
- * @param renderId render 函数ID
19
- * @param indent 缩进
20
- */
21
13
  genRenderRef(slotId: string, renderId: string, indent: string): string;
22
14
  }
@@ -22,22 +22,20 @@ __export(renderManager_exports, {
22
22
  RenderManager: () => RenderManager
23
23
  });
24
24
  module.exports = __toCommonJS(renderManager_exports);
25
- var import__ = require("../index");
25
+ var import_index = require("./index");
26
26
  var RenderManager = class {
27
27
  constructor() {
28
+ /** 存储格式:renderId -> { renderCode, children?, logicCode?, slotType?, useWrap?, description? } */
28
29
  this._renders = /* @__PURE__ */ new Map();
29
30
  }
30
31
  /**
31
32
  * 注册一个 render 函数
32
- * @param renderId 唯一标识符,格式:组件ID_插槽ID
33
- * @param renderCode render 函数的代码内容(不包含函数声明)
34
33
  */
35
- register(renderId, renderCode) {
36
- this._renders.set(renderId, renderCode);
34
+ register(renderId, renderCode, children, logicCode, slotType, useWrap, description) {
35
+ this._renders.set(renderId, { renderCode, children, logicCode, slotType, useWrap, description });
37
36
  }
38
37
  /**
39
- * 生成所有 render 函数的定义代码
40
- * @param indent 基础缩进
38
+ * 生成所有 render 函数的 definition 代码
41
39
  */
42
40
  toCode(indent) {
43
41
  if (this._renders.size === 0) {
@@ -45,31 +43,98 @@ var RenderManager = class {
45
43
  }
46
44
  let code = "";
47
45
  const indentSize = 2;
48
- const indent2 = (0, import__.indentation)(indentSize);
49
- this._renders.forEach((renderCode, renderId) => {
50
- code += `${indent}const ${renderId}_Render = (params?: { style?: any }) => {
46
+ const indent2 = (0, import_index.indentation)(indentSize);
47
+ const indent3 = (0, import_index.indentation)(indentSize * 2);
48
+ const indent4 = (0, import_index.indentation)(indentSize * 3);
49
+ const indent5 = (0, import_index.indentation)(indentSize * 4);
50
+ const indent6 = (0, import_index.indentation)(indentSize * 5);
51
+ this._renders.forEach(({ renderCode, children, logicCode, useWrap, description }, renderId) => {
52
+ const renderFunctionName = (0, import_index.toPascalCase)(`${renderId}_Render`);
53
+ if (description) {
54
+ code += `${indent}/** ${description} */
51
55
  `;
56
+ }
57
+ code += `${indent}function ${renderFunctionName}(params: any) {
58
+ `;
59
+ code += `${indent}${indent2}const { comRefs, outputs } = useAppContext();
60
+ `;
61
+ if (logicCode) {
62
+ code += logicCode.split("\n").map((line) => `${indent}${line}`).join("\n") + "\n";
63
+ }
64
+ const comVars = {};
65
+ let modifiedRenderCode = renderCode;
66
+ if (children && children.length > 0) {
67
+ children.forEach((child) => {
68
+ if (child.type === "com") {
69
+ const varName = `${child.id}_JSX`;
70
+ const comJsx = child.ui.trim();
71
+ comVars[child.id] = varName;
72
+ code += `${indent}${indent2}const ${varName} = (
73
+ `;
74
+ code += `${indent}${indent3}${comJsx}
75
+ `;
76
+ code += `${indent}${indent2});
77
+ `;
78
+ const pattern = new RegExp(`<WithCom\\s+[^>]*id=['"]${child.id}['"][\\s\\S]*?/>|<WithCom\\s+[^>]*id=['"]${child.id}['"][\\s\\S]*?>[\\s\\S]*?</WithCom>`, "g");
79
+ modifiedRenderCode = modifiedRenderCode.replace(pattern, `{${varName}}`);
80
+ }
81
+ });
82
+ code += "\n";
83
+ }
84
+ if (useWrap && children && children.length > 0) {
85
+ code += `${indent}${indent2}const descriptors = [
86
+ `;
87
+ children.forEach((child) => {
88
+ var _a;
89
+ if (child.type === "com") {
90
+ const childStyle = JSON.stringify(child.rootStyle || ((_a = child.props) == null ? void 0 : _a.style) || {});
91
+ const varName = comVars[child.id];
92
+ code += `${indent}${indent3}{
93
+ `;
94
+ code += `${indent}${indent4}id: '${child.id}',
95
+ `;
96
+ code += `${indent}${indent4}name: ${child.name !== void 0 ? `'${child.name}'` : "undefined"},
97
+ `;
98
+ code += `${indent}${indent4}style: ${childStyle},
99
+ `;
100
+ code += `${indent}${indent4}get inputs() { return comRefs.current['${child.id}'] },
101
+ `;
102
+ code += `${indent}${indent4}get outputs() { return outputs.current['${child.id}'] },
103
+ `;
104
+ code += `${indent}${indent4}jsx: ${varName},
105
+ `;
106
+ code += `${indent}${indent3}},
107
+ `;
108
+ }
109
+ });
110
+ code += `${indent}${indent2}];
111
+
112
+ `;
113
+ }
52
114
  code += `${indent}${indent2}return (
53
115
  `;
54
- code += renderCode;
55
- code += `
56
- ${indent}${indent2});
116
+ if (useWrap) {
117
+ code += `${indent}${indent3}params?.wrap?.(descriptors)
57
118
  `;
58
- code += `${indent}};
119
+ } else {
120
+ code += `${indent}${indent3}<>
121
+ `;
122
+ code += modifiedRenderCode.split("\n").map((line) => `${indent}${indent2}${line}`).join("\n") + "\n";
123
+ code += `${indent}${indent3}</>
124
+ `;
125
+ }
126
+ code += `${indent}${indent2});
127
+ `;
128
+ code += `${indent}}
59
129
 
60
130
  `;
61
131
  });
62
132
  return code;
63
133
  }
64
- /**
65
- * 生成 render 对象的引用代码
66
- * @param slotId 插槽ID
67
- * @param renderId render 函数ID
68
- * @param indent 缩进
69
- */
70
134
  genRenderRef(slotId, renderId, indent) {
135
+ const renderFunctionName = (0, import_index.toPascalCase)(`${renderId}_Render`);
71
136
  return `${indent}${slotId}: {
72
- ${indent} render: ${renderId}_Render,
137
+ ${indent} render: ${renderFunctionName},
73
138
  ${indent}},
74
139
  `;
75
140
  }
@@ -7,9 +7,10 @@ export declare const genSlotDefineCode: (indent: string) => string;
7
7
  /** 生成控制器初始化代码 */
8
8
  export declare const genControllerInitCode: (indent: string, providerName: string) => string;
9
9
  /** 生成完整的函数组件模板 */
10
- export declare const genComponentTemplate: ({ componentName, combinedJsCode, uiResult, outputsConfig, scopeName, utilsPackageName, isPopup, hasPopups, }: {
10
+ export declare const genComponentTemplate: ({ componentName, combinedJsCode, renderDefinitions, uiResult, outputsConfig, scopeName, utilsPackageName, isPopup, hasPopups, }: {
11
11
  componentName: string;
12
12
  combinedJsCode: string;
13
+ renderDefinitions?: string;
13
14
  uiResult: string;
14
15
  outputsConfig?: Record<string, Record<string, any>>;
15
16
  scopeName?: string;
@@ -50,6 +50,8 @@ var genControllerInitCode = (indent, providerName) => {
50
50
  var genComponentTemplate = ({
51
51
  componentName,
52
52
  combinedJsCode,
53
+ renderDefinitions = "",
54
+ // 新增:外部定义的渲染函数
53
55
  uiResult,
54
56
  outputsConfig,
55
57
  scopeName,
@@ -57,7 +59,8 @@ var genComponentTemplate = ({
57
59
  isPopup = false,
58
60
  hasPopups = false
59
61
  }) => {
60
- let code = `function ${componentName}() {
62
+ let code = `${renderDefinitions}
63
+ function ${componentName}() {
61
64
  ${combinedJsCode}
62
65
  return (
63
66
  <>
@@ -1,6 +1,7 @@
1
1
  import { createContext, useContext } from 'react';
2
2
  export { pageRouter } from "./pageRouter";
3
3
  var ComContext = /*#__PURE__*/createContext(undefined);
4
+ var SlotContext = /*#__PURE__*/createContext(null);
4
5
  export function useAppContext() {
5
6
  var context = useContext(ComContext);
6
7
  if (!context) {
@@ -8,4 +9,8 @@ export function useAppContext() {
8
9
  }
9
10
  return context;
10
11
  }
12
+ export function useParentSlot() {
13
+ return useContext(SlotContext);
14
+ }
15
+ export var SlotProvider = SlotContext.Provider;
11
16
  export default ComContext;
@@ -83,11 +83,13 @@ export function useBindInputs(scope, id, initialHandlers) {
83
83
  });
84
84
 
85
85
  // 将代理对象挂载到作用域,供外部 comRefs.current.id.pin() 调用
86
- scope[id] = proxy;
86
+ if (scope && scope.current) {
87
+ scope.current[id] = proxy;
88
+ }
87
89
  return proxy;
88
90
  }, [scope, id]);
89
91
  }
90
- export function useBindEvents(props) {
92
+ export function useBindEvents(props, context) {
91
93
  return useMemo(function () {
92
94
  var _events = {};
93
95
 
@@ -95,8 +97,15 @@ export function useBindEvents(props) {
95
97
  Object.keys(props).forEach(function (key) {
96
98
  if (key.startsWith('on') && typeof props[key] === 'function') {
97
99
  var handler = props[key];
98
- var wrapped = function wrapped() {
99
- return handler.apply(void 0, arguments);
100
+ var wrapped = function wrapped(originalValue) {
101
+ // 鸿蒙/render-web 规范:如果是在插槽中触发事件,且存在父级协议,则自动封装元数据
102
+ // 这解决了 FormContainer 等组件识别子项的需求
103
+ var value = context ? {
104
+ id: context.id,
105
+ name: context.name,
106
+ value: originalValue
107
+ } : originalValue;
108
+ return handler(value);
100
109
  };
101
110
  wrapped.getConnections = function () {
102
111
  return [{
@@ -122,5 +131,5 @@ export function useBindEvents(props) {
122
131
  return target[key];
123
132
  }
124
133
  });
125
- }, [props]);
134
+ }, [props, context]);
126
135
  }
@@ -3,6 +3,8 @@ export { WithCom, WithWrapper } from "./with";
3
3
  export { PopupRenderer } from "./PopupRenderer";
4
4
  export { pageRouter, router } from "./pageRouter";
5
5
  export { popupRouter, subscribePopupRouter, closeActivePopupRouter } from "./popupRouter";
6
- export { useAppContext } from "./ComContext";
6
+ export { useAppContext, SlotProvider } from "./ComContext";
7
+ export { useAppCreateContext } from "./useContext";
7
8
  export { createVariable, createFx, merge } from "../mybricks";
8
- export { SUBJECT_SUBSCRIBE, SUBJECT_VALUE } from "../mybricks/constant";
9
+ export { SUBJECT_SUBSCRIBE, SUBJECT_VALUE } from "../mybricks/constant";
10
+ export * from "./slots";
@@ -0,0 +1,108 @@
1
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import React, { useMemo, useRef } from "react";
4
+ import ComContext, { SlotProvider, useAppContext, useParentSlot } from "./ComContext";
5
+ import { createReactiveInputHandler } from "../mybricks/createReactiveInputHandler";
6
+ function createChannelProxy(title) {
7
+ var handlersMap = {};
8
+ return new Proxy({}, {
9
+ get: function get(_t, pin) {
10
+ return function (arg) {
11
+ if (typeof arg === "function") {
12
+ handlersMap[pin] = arg;
13
+ return;
14
+ }
15
+ var handler = handlersMap[pin];
16
+ if (typeof handler === "function") {
17
+ return createReactiveInputHandler({
18
+ input: handler,
19
+ value: arg,
20
+ rels: {},
21
+ title: title
22
+ });
23
+ }
24
+ };
25
+ }
26
+ });
27
+ }
28
+
29
+ /**
30
+ * 参考鸿蒙的 createSlotsIO:
31
+ * - 确保每个 slot 都具备 inputs / outputs / _inputs 三套通道,避免 runtime 访问时报 undefined
32
+ * - render 时通过 SlotProvider 注入 parentSlot(slot 内子组件可 useParentSlot 获取)
33
+ */
34
+ export function useEnhancedSlots(rawSlots, id) {
35
+ var slotStoreRef = useRef({});
36
+ return useMemo(function () {
37
+ if (!rawSlots) return {};
38
+ var nextSlots = {};
39
+ Object.entries(rawSlots).forEach(function (_ref) {
40
+ var _ref2 = _slicedToArray(_ref, 2),
41
+ slotKey = _ref2[0],
42
+ slotDef = _ref2[1];
43
+ var state = slotStoreRef.current[slotKey] || (slotStoreRef.current[slotKey] = {
44
+ inputs: createChannelProxy("".concat(id, ".").concat(slotKey, ".inputs")),
45
+ outputs: createChannelProxy("".concat(id, ".").concat(slotKey, ".outputs")),
46
+ _inputs: createChannelProxy("".concat(id, ".").concat(slotKey, "._inputs")),
47
+ _scopedComRefs: {},
48
+ _render: undefined,
49
+ render: function render(params) {
50
+ var _ref3, _params$key, _params$inputValues, _params$inputValues2, _ref4;
51
+ var r = state._render;
52
+ // 只有存在 key 或 index 时才认为是“多实例作用域插槽”,需要实例隔离
53
+ var rawScope = (_ref3 = (_params$key = params === null || params === void 0 ? void 0 : params.key) !== null && _params$key !== void 0 ? _params$key : params === null || params === void 0 || (_params$inputValues = params.inputValues) === null || _params$inputValues === void 0 ? void 0 : _params$inputValues.index) !== null && _ref3 !== void 0 ? _ref3 : params === null || params === void 0 || (_params$inputValues2 = params.inputValues) === null || _params$inputValues2 === void 0 || (_params$inputValues2 = _params$inputValues2.itemData) === null || _params$inputValues2 === void 0 ? void 0 : _params$inputValues2.id;
54
+ var SlotComp = r;
55
+ var content = r ? /*#__PURE__*/React.createElement(SlotComp, params || {}) : null;
56
+ if (rawScope === undefined || rawScope === null) {
57
+ return /*#__PURE__*/React.createElement(SlotProvider, {
58
+ value: _objectSpread(_objectSpread({}, state), {}, {
59
+ params: params
60
+ })
61
+ }, content);
62
+ }
63
+ var scopeId = "".concat(id, ".").concat(slotKey, "::").concat(String(rawScope));
64
+ var scopedComRefs = (_ref4 = state._scopedComRefs)[scopeId] || (_ref4[scopeId] = {
65
+ current: {
66
+ $inputs: {}
67
+ }
68
+ });
69
+ return /*#__PURE__*/React.createElement(SlotProvider, {
70
+ value: _objectSpread(_objectSpread({}, state), {}, {
71
+ params: params
72
+ })
73
+ }, /*#__PURE__*/React.createElement(ScopedComContextProvider, {
74
+ comRefs: scopedComRefs,
75
+ scopeId: scopeId
76
+ }, content));
77
+ }
78
+ });
79
+ state._render = slotDef === null || slotDef === void 0 ? void 0 : slotDef.render;
80
+ nextSlots[slotKey] = _objectSpread(_objectSpread({}, slotDef || {}), {}, {
81
+ render: state.render,
82
+ inputs: state.inputs,
83
+ outputs: state.outputs,
84
+ _inputs: state._inputs
85
+ });
86
+ });
87
+ return nextSlots;
88
+ }, [rawSlots, id]);
89
+ }
90
+ export function ScopedComContextProvider(props) {
91
+ var parent = useAppContext();
92
+ var value = useMemo(function () {
93
+ // 如果没有显式传 comRefs,则沿用父级的,但依然带上新的 scopeId
94
+ return _objectSpread(_objectSpread({}, parent), {}, {
95
+ comRefs: props.comRefs || parent.comRefs,
96
+ $scopeId: props.scopeId
97
+ });
98
+ }, [parent, props.comRefs, props.scopeId]);
99
+ return /*#__PURE__*/React.createElement(ComContext.Provider, {
100
+ value: value
101
+ }, props.children);
102
+ }
103
+
104
+ /** parentSlot 解析:props 优先,其次用 SlotProvider 注入的 context */
105
+ export function useResolvedParentSlot(parentSlotProp) {
106
+ var parentSlotFromCtx = useParentSlot();
107
+ return parentSlotProp !== null && parentSlotProp !== void 0 ? parentSlotProp : parentSlotFromCtx;
108
+ }
@@ -1,8 +1,13 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2
- import { useRef, useState } from 'react';
2
+ import { useRef, useState, useMemo } from 'react';
3
3
  import { deepProxy } from "./hooks";
4
4
  export function useAppCreateContext() {
5
- var comRefs = useRef(deepProxy({}));
5
+ // 约定:场景级 inputs 统一挂载到 $inputs,避免与组件 runtime 的 inputs 命名冲突
6
+ // 同时可避免 `Cannot set property 'open' of undefined`
7
+ var comRefs = useRef(deepProxy({
8
+ $inputs: {}
9
+ }));
10
+ var outputs = useRef(deepProxy({}));
6
11
  var _useState = useState({
7
12
  visible: false,
8
13
  name: '',
@@ -12,7 +17,7 @@ export function useAppCreateContext() {
12
17
  _useState2 = _slicedToArray(_useState, 2),
13
18
  popupState = _useState2[0],
14
19
  setPopupState = _useState2[1];
15
- var appContext = {
20
+ var appContext = useRef({
16
21
  canvas: {
17
22
  id: "u_7VvVn" // 使用 data 中的 id
18
23
  },
@@ -26,12 +31,17 @@ export function useAppCreateContext() {
26
31
  isRelease: false,
27
32
  isDebug: false,
28
33
  isLocal: false,
29
- isTest: false
30
- };
31
- return {
32
- comRefs: comRefs,
33
- appContext: appContext,
34
- popupState: popupState,
35
- setPopupState: setPopupState
36
- };
34
+ isTest: false,
35
+ tabBar: [],
36
+ useTabBar: false
37
+ }).current;
38
+ return useMemo(function () {
39
+ return {
40
+ comRefs: comRefs,
41
+ outputs: outputs,
42
+ appContext: appContext,
43
+ popupState: popupState,
44
+ setPopupState: setPopupState
45
+ };
46
+ }, [popupState]);
37
47
  }