@easy-editor/react-renderer 1.0.1 → 1.0.3

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.
package/LICENSE CHANGED
@@ -1,9 +1,9 @@
1
- MIT License
2
-
3
- Copyright © 2024-PRESENT JinSo <https://github.com/JinSooo>
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
-
7
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
-
9
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright © 2024-PRESENT JinSo <https://github.com/JinSooo>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
- # @easy-editor/react-renderer
2
-
3
- React renderer implementation for EasyEditor. This package provides the React-specific implementation of the renderer-core interfaces, enabling schema-driven rendering using React components.
4
-
5
- ## Features
6
-
7
- - **React Component Rendering**: Converts EasyEditor schema into React component hierarchy
8
- - **React Context Integration**: Provides schema context to all rendered components
9
- - **Lifecycle Management**: Handles React component lifecycle methods based on schema
10
- - **Error Boundaries**: React-specific error handling with fallback components
11
- - **Ref Forwarding**: Automatic reference collection for component manipulation
12
- - **Dynamic Props**: Support for dynamic props and expressions within React components
13
- - **State Management**: Integration with React's state system
14
- - **Event Handling**: React-specific event binding from schema definitions
15
-
1
+ # @easy-editor/react-renderer
2
+
3
+ React renderer implementation for EasyEditor. This package provides the React-specific implementation of the renderer-core interfaces, enabling schema-driven rendering using React components.
4
+
5
+ ## Features
6
+
7
+ - **React Component Rendering**: Converts EasyEditor schema into React component hierarchy
8
+ - **React Context Integration**: Provides schema context to all rendered components
9
+ - **Lifecycle Management**: Handles React component lifecycle methods based on schema
10
+ - **Error Boundaries**: React-specific error handling with fallback components
11
+ - **Ref Forwarding**: Automatic reference collection for component manipulation
12
+ - **Dynamic Props**: Support for dynamic props and expressions within React components
13
+ - **State Management**: Integration with React's state system
14
+ - **Event Handling**: React-specific event binding from schema definitions
15
+
package/dist/index.cjs CHANGED
@@ -673,13 +673,51 @@ const patchDidCatch = (Comp, {
673
673
  }
674
674
  };
675
675
  const cache$1 = new Map();
676
+
677
+ /** 获取数据源数据 */
678
+ const getDataSource = baseRenderer => {
679
+ // component
680
+ const componentDataSource = {};
681
+ if (baseRenderer.dataSourceMap) {
682
+ const {
683
+ dataSourceMap,
684
+ state
685
+ } = baseRenderer;
686
+ Object.keys(dataSourceMap).forEach(key => {
687
+ componentDataSource[key] = state[key];
688
+ });
689
+ }
690
+
691
+ // page
692
+ const pageDataSource = {};
693
+ if (baseRenderer.page.dataSourceMap) {
694
+ const {
695
+ dataSourceMap,
696
+ state
697
+ } = baseRenderer.page;
698
+ Object.keys(dataSourceMap).forEach(key => {
699
+ pageDataSource[key] = state[key];
700
+ });
701
+ }
702
+ if (Object.keys(componentDataSource).length > 0 || Object.keys(pageDataSource).length > 0) {
703
+ return {
704
+ component: componentDataSource,
705
+ page: pageDataSource
706
+ };
707
+ }
708
+ return undefined;
709
+ };
676
710
  const compWrapper = (Comp, info) => {
711
+ const {
712
+ baseRenderer,
713
+ schema
714
+ } = info;
677
715
  if (Comp?.prototype?.isReactComponent || Comp?.prototype instanceof react.Component) {
678
716
  patchDidCatch(Comp, info);
679
717
  return Comp;
680
718
  }
681
- if (info.schema.id && cache$1.has(info.schema.id) && cache$1.get(info.schema.id)?.Comp === Comp) {
682
- return cache$1.get(info.schema.id)?.WrapperComponent;
719
+ if (schema.id && cache$1.has(schema.id) && cache$1.get(schema.id)?.Comp === Comp) {
720
+ return cache$1.get(schema.id)?.WrapperComponent;
683
721
  }
684
722
  class Wrapper extends react.Component {
685
723
  static displayName = Comp.displayName;
@@ -688,16 +726,16 @@ const compWrapper = (Comp, info) => {
688
726
  forwardRef,
689
727
  ...rest
690
728
  } = this.props;
691
- // @ts-ignore
692
729
  return /*#__PURE__*/react.createElement(Comp, {
693
730
  ...rest,
694
- ref: forwardRef
731
+ ref: forwardRef,
732
+ __dataSource: getDataSource(baseRenderer)
695
733
  });
696
734
  }
697
735
  }
698
736
  patchDidCatch(Wrapper, info);
699
737
  const WrapperComponent = createForwardRefHocElement(Wrapper, Comp);
700
- info.schema.id && cache$1.set(info.schema.id, {
738
+ schema.id && cache$1.set(schema.id, {
701
739
  WrapperComponent,
702
740
  Comp
703
741
  });
@@ -1342,7 +1380,7 @@ function baseRendererFactory() {
1342
1380
  /**
1343
1381
  * this method is for legacy purpose only, which used _ prefix instead of __ as private for some historical reasons
1344
1382
  */
1345
- __getComponentView = () => {
1383
+ __getComponentView = schema => {
1346
1384
  const {
1347
1385
  __components,
1348
1386
  __schema
@@ -1350,6 +1388,9 @@ function baseRendererFactory() {
1350
1388
  if (!__components) {
1351
1389
  return;
1352
1390
  }
1391
+ if (schema) {
1392
+ return __components[schema.componentName];
1393
+ }
1353
1394
  return __components[__schema.componentName];
1354
1395
  };
1355
1396
  __bindCustomMethods = props => {
@@ -1577,7 +1618,7 @@ function baseRendererFactory() {
1577
1618
  if (!rendererCore.isSchema(schema)) {
1578
1619
  return null;
1579
1620
  }
1580
- let Comp = components[schema.componentName] || this.props.__container?.components?.[schema.componentName];
1621
+ let Comp = this.__getComponentView(schema);
1581
1622
 
1582
1623
  // 容器类组件的上下文通过props传递,避免context传递带来的嵌套问题
1583
1624
  const otherProps = rendererCore.isSchema(schema) ? {
@@ -1591,6 +1632,7 @@ function baseRendererFactory() {
1591
1632
  componentName: schema.componentName,
1592
1633
  componentId: schema.id,
1593
1634
  enableStrictNotFoundMode: engine.props.enableStrictNotFoundMode,
1635
+ schema,
1594
1636
  ref: ref => {
1595
1637
  ref && engine.props?.onCompGetRef?.(schema, ref);
1596
1638
  }
@@ -1614,36 +1656,6 @@ function baseRendererFactory() {
1614
1656
  if (!condition && !displayInHook) {
1615
1657
  return null;
1616
1658
  }
1617
-
1618
- // TODO: scope
1619
- // let scopeKey = ''
1620
- // // 判断组件是否需要生成scope,且只生成一次,挂在this.__compScopes上
1621
- // if (Comp.generateScope) {
1622
- // const key = this.__parseExpression(schema.props?.key, scope)
1623
- // if (key) {
1624
- // // 如果组件自己设置key则使用组件自己的key
1625
- // scopeKey = key
1626
- // } else if (schema.__ctx) {
1627
- // // 需要判断循环的情况
1628
- // scopeKey = schema.__ctx.lceKey + (idx !== undefined ? `_${idx}` : '')
1629
- // } else {
1630
- // // 在生产环境schema没有__ctx上下文,需要手动生成一个lceKey
1631
- // schema.__ctx = {
1632
- // lceKey: `lce${++scopeIdx}`,
1633
- // }
1634
- // scopeKey = schema.__ctx.lceKey
1635
- // }
1636
- // if (!this.__compScopes[scopeKey]) {
1637
- // this.__compScopes[scopeKey] = Comp.generateScope(this, schema)
1638
- // }
1639
- // }
1640
- // // 如果组件有设置scope,需要为组件生成一个新的scope上下文
1641
- // if (scopeKey && this.__compScopes[scopeKey]) {
1642
- // const compSelf = { ...this.__compScopes[scopeKey] }
1643
- // compSelf.__proto__ = scope
1644
- // scope = compSelf
1645
- // }
1646
-
1647
1659
  if (engine.props?.designMode) {
1648
1660
  otherProps.__designMode = engine.props.designMode;
1649
1661
  }
@@ -2007,9 +2019,6 @@ function componentRendererFactory() {
2007
2019
  static displayName = 'CompRenderer';
2008
2020
  __namespace = 'component';
2009
2021
  __afterInit(props, ...rest) {
2010
- this.__generateCtx({
2011
- component: this
2012
- });
2013
2022
  const schema = props.__schema || {};
2014
2023
  this.state = this.__parseData(schema.state || {});
2015
2024
  this.__initDataSource(props);
@@ -2105,19 +2114,23 @@ const FaultComponent = ({
2105
2114
  error
2106
2115
  }) => {
2107
2116
  rendererCore.logger.error(`${componentName} 组件渲染异常, 异常原因: ${error?.message || error || '未知'}`);
2108
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
2117
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
2109
2118
  role: "alert",
2110
2119
  "aria-label": `${componentName} 组件渲染异常`,
2111
2120
  style: {
2121
+ display: 'flex',
2122
+ justifyContent: 'center',
2123
+ alignItems: 'center',
2112
2124
  width: '100%',
2113
- height: '50px',
2114
- lineHeight: '50px',
2125
+ height: '100%',
2115
2126
  textAlign: 'center',
2116
2127
  fontSize: '15px',
2117
2128
  color: '#ef4444',
2118
2129
  border: '2px solid #ef4444'
2119
2130
  },
2120
- children: [componentName, " \u7EC4\u4EF6\u6E32\u67D3\u5F02\u5E38\uFF0C\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7"]
2131
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
2132
+ children: [componentName, " \u7EC4\u4EF6\u6E32\u67D3\u5F02\u5E38\uFF0C\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7"]
2133
+ })
2121
2134
  });
2122
2135
  };
2123
2136
 
@@ -2136,15 +2149,19 @@ const NotFoundComponent = ({
2136
2149
  role: "alert",
2137
2150
  "aria-label": `${componentName} component not found`,
2138
2151
  style: {
2152
+ display: 'flex',
2153
+ justifyContent: 'center',
2154
+ alignItems: 'center',
2139
2155
  width: '100%',
2140
- height: '50px',
2141
- lineHeight: '50px',
2156
+ height: '100%',
2142
2157
  textAlign: 'center',
2143
2158
  fontSize: '15px',
2144
2159
  color: '#eab308',
2145
2160
  border: '2px solid #eab308'
2146
2161
  },
2147
- children: `${componentName} Component Not Found`
2162
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
2163
+ children: `${componentName} Component Not Found`
2164
+ })
2148
2165
  });
2149
2166
  };
2150
2167
 
@@ -2252,6 +2269,63 @@ function rendererFactory() {
2252
2269
  };
2253
2270
  }
2254
2271
 
2272
+ /**
2273
+ * Setter Placeholder
2274
+ * 设置器加载占位符组件
2275
+ */
2276
+
2277
+ /**
2278
+ * 设置器加载占位符
2279
+ * 当设置器尚未加载完成时显示
2280
+ */
2281
+ const SetterPlaceholder = ({
2282
+ setterType
2283
+ }) => {
2284
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
2285
+ style: {
2286
+ display: 'flex',
2287
+ alignItems: 'center',
2288
+ gap: '8px',
2289
+ padding: '8px',
2290
+ fontSize: '12px',
2291
+ color: '#999',
2292
+ borderRadius: '4px'
2293
+ },
2294
+ children: [/*#__PURE__*/jsxRuntime.jsx(LoadingSpinner, {}), /*#__PURE__*/jsxRuntime.jsx("span", {
2295
+ children: setterType ? `加载中: ${setterType}` : '设置器加载中...'
2296
+ })]
2297
+ });
2298
+ };
2299
+
2300
+ /**
2301
+ * 简单的加载动画
2302
+ */
2303
+ const LoadingSpinner = () => {
2304
+ return /*#__PURE__*/jsxRuntime.jsxs("svg", {
2305
+ width: "14",
2306
+ height: "14",
2307
+ viewBox: "0 0 24 24",
2308
+ fill: "none",
2309
+ stroke: "currentColor",
2310
+ strokeWidth: "2",
2311
+ strokeLinecap: "round",
2312
+ strokeLinejoin: "round",
2313
+ style: {
2314
+ animation: 'spin 1s linear infinite'
2315
+ },
2316
+ children: [/*#__PURE__*/jsxRuntime.jsx("style", {
2317
+ children: `
2318
+ @keyframes spin {
2319
+ from { transform: rotate(0deg); }
2320
+ to { transform: rotate(360deg); }
2321
+ }
2322
+ `
2323
+ }), /*#__PURE__*/jsxRuntime.jsx("path", {
2324
+ d: "M21 12a9 9 0 1 1-6.219-8.56"
2325
+ })]
2326
+ });
2327
+ };
2328
+
2255
2329
  const SettingRendererContext = /*#__PURE__*/react.createContext({});
2256
2330
  const useSettingRendererContext = () => {
2257
2331
  try {
@@ -2338,6 +2412,13 @@ const SettingSetter = mobxReact.observer(({
2338
2412
  component: SetterComponent,
2339
2413
  props: mixedSetterProps
2340
2414
  } = setters.createSetterContent(setterType, setterProps);
2415
+
2416
+ // 处理设置器未加载的情况
2417
+ if (!SetterComponent) {
2418
+ return /*#__PURE__*/jsxRuntime.jsx(SetterPlaceholder, {
2419
+ setterType: setterType
2420
+ });
2421
+ }
2341
2422
  return /*#__PURE__*/jsxRuntime.jsx(SetterComponent, {
2342
2423
  field: field,
2343
2424
  selected: field.top?.getNode(),
@@ -2461,19 +2542,6 @@ const SettingRenderer = mobxReact.observer(props => {
2461
2542
  })
2462
2543
  });
2463
2544
  }
2464
-
2465
- // 当节点被锁定,且未开启锁定后容器可设置属性
2466
- if (settings.isLocked) {
2467
- return /*#__PURE__*/jsxRuntime.jsx("div", {
2468
- className: "lc-settings-main",
2469
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
2470
- className: "lc-settings-notice",
2471
- children: /*#__PURE__*/jsxRuntime.jsx("p", {
2472
- children: "Current node is locked"
2473
- })
2474
- })
2475
- });
2476
- }
2477
2545
  if (Array.isArray(settings.items) && settings.items.length === 0) {
2478
2546
  return /*#__PURE__*/jsxRuntime.jsx("div", {
2479
2547
  className: "lc-settings-main",
@@ -2505,6 +2573,8 @@ const SettingRenderer = mobxReact.observer(props => {
2505
2573
  });
2506
2574
  });
2507
2575
 
2576
+ exports.FaultComponent = FaultComponent;
2577
+ exports.NotFoundComponent = NotFoundComponent;
2508
2578
  exports.RendererContext = RendererContext;
2509
2579
  exports.SettingFieldView = SettingFieldView;
2510
2580
  exports.SettingRenderer = SettingRenderer;
package/dist/index.d.ts CHANGED
@@ -8,3 +8,5 @@ export * from './renderer';
8
8
  export * from './setting-renderer';
9
9
  export * from './types';
10
10
  export * from './utils';
11
+ export { default as NotFoundComponent } from './components/NotFoundComponent';
12
+ export { default as FaultComponent } from './components/FaultComponent';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DESIGNER_EVENT, TRANSFORM_STAGE, isJSExpression, isJSFunction, isSetterConfig } from '@easy-editor/core';
2
- import { logger, isSchema, getValue as getValue$1, parseExpression, parseData, DataHelper, isUseLoop, transformArrayToMap, transformStringToFunction, classnames, getFileCssName, checkPropTypes } from '@easy-editor/renderer-core';
2
+ import { logger, parseExpression, parseData, DataHelper, getValue as getValue$1, isSchema, isUseLoop, transformArrayToMap, transformStringToFunction, classnames, getFileCssName, checkPropTypes } from '@easy-editor/renderer-core';
3
3
  import { createContext, useContext, forwardRef, createElement, Component, PureComponent, useMemo } from 'react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { observer } from 'mobx-react';
@@ -671,13 +671,51 @@ const patchDidCatch = (Comp, {
671
671
  }
672
672
  };
673
673
  const cache$1 = new Map();
674
+
675
+ /** 获取数据源数据 */
676
+ const getDataSource = baseRenderer => {
677
+ // component
678
+ const componentDataSource = {};
679
+ if (baseRenderer.dataSourceMap) {
680
+ const {
681
+ dataSourceMap,
682
+ state
683
+ } = baseRenderer;
684
+ Object.keys(dataSourceMap).forEach(key => {
685
+ componentDataSource[key] = state[key];
686
+ });
687
+ }
688
+
689
+ // page
690
+ const pageDataSource = {};
691
+ if (baseRenderer.page.dataSourceMap) {
692
+ const {
693
+ dataSourceMap,
694
+ state
695
+ } = baseRenderer.page;
696
+ Object.keys(dataSourceMap).forEach(key => {
697
+ pageDataSource[key] = state[key];
698
+ });
699
+ }
700
+ if (Object.keys(componentDataSource).length > 0 || Object.keys(pageDataSource).length > 0) {
701
+ return {
702
+ component: componentDataSource,
703
+ page: pageDataSource
704
+ };
705
+ }
706
+ return undefined;
707
+ };
674
708
  const compWrapper = (Comp, info) => {
709
+ const {
710
+ baseRenderer,
711
+ schema
712
+ } = info;
675
713
  if (Comp?.prototype?.isReactComponent || Comp?.prototype instanceof Component) {
676
714
  patchDidCatch(Comp, info);
677
715
  return Comp;
678
716
  }
679
- if (info.schema.id && cache$1.has(info.schema.id) && cache$1.get(info.schema.id)?.Comp === Comp) {
680
- return cache$1.get(info.schema.id)?.WrapperComponent;
717
+ if (schema.id && cache$1.has(schema.id) && cache$1.get(schema.id)?.Comp === Comp) {
718
+ return cache$1.get(schema.id)?.WrapperComponent;
681
719
  }
682
720
  class Wrapper extends Component {
683
721
  static displayName = Comp.displayName;
@@ -686,16 +724,16 @@ const compWrapper = (Comp, info) => {
686
724
  forwardRef,
687
725
  ...rest
688
726
  } = this.props;
689
- // @ts-ignore
690
727
  return /*#__PURE__*/createElement(Comp, {
691
728
  ...rest,
692
- ref: forwardRef
729
+ ref: forwardRef,
730
+ __dataSource: getDataSource(baseRenderer)
693
731
  });
694
732
  }
695
733
  }
696
734
  patchDidCatch(Wrapper, info);
697
735
  const WrapperComponent = createForwardRefHocElement(Wrapper, Comp);
698
- info.schema.id && cache$1.set(info.schema.id, {
736
+ schema.id && cache$1.set(schema.id, {
699
737
  WrapperComponent,
700
738
  Comp
701
739
  });
@@ -1340,7 +1378,7 @@ function baseRendererFactory() {
1340
1378
  /**
1341
1379
  * this method is for legacy purpose only, which used _ prefix instead of __ as private for some historical reasons
1342
1380
  */
1343
- __getComponentView = () => {
1381
+ __getComponentView = schema => {
1344
1382
  const {
1345
1383
  __components,
1346
1384
  __schema
@@ -1348,6 +1386,9 @@ function baseRendererFactory() {
1348
1386
  if (!__components) {
1349
1387
  return;
1350
1388
  }
1389
+ if (schema) {
1390
+ return __components[schema.componentName];
1391
+ }
1351
1392
  return __components[__schema.componentName];
1352
1393
  };
1353
1394
  __bindCustomMethods = props => {
@@ -1575,7 +1616,7 @@ function baseRendererFactory() {
1575
1616
  if (!isSchema(schema)) {
1576
1617
  return null;
1577
1618
  }
1578
- let Comp = components[schema.componentName] || this.props.__container?.components?.[schema.componentName];
1619
+ let Comp = this.__getComponentView(schema);
1579
1620
 
1580
1621
  // 容器类组件的上下文通过props传递,避免context传递带来的嵌套问题
1581
1622
  const otherProps = isSchema(schema) ? {
@@ -1589,6 +1630,7 @@ function baseRendererFactory() {
1589
1630
  componentName: schema.componentName,
1590
1631
  componentId: schema.id,
1591
1632
  enableStrictNotFoundMode: engine.props.enableStrictNotFoundMode,
1633
+ schema,
1592
1634
  ref: ref => {
1593
1635
  ref && engine.props?.onCompGetRef?.(schema, ref);
1594
1636
  }
@@ -1612,36 +1654,6 @@ function baseRendererFactory() {
1612
1654
  if (!condition && !displayInHook) {
1613
1655
  return null;
1614
1656
  }
1615
-
1616
- // TODO: scope
1617
- // let scopeKey = ''
1618
- // // 判断组件是否需要生成scope,且只生成一次,挂在this.__compScopes上
1619
- // if (Comp.generateScope) {
1620
- // const key = this.__parseExpression(schema.props?.key, scope)
1621
- // if (key) {
1622
- // // 如果组件自己设置key则使用组件自己的key
1623
- // scopeKey = key
1624
- // } else if (schema.__ctx) {
1625
- // // 需要判断循环的情况
1626
- // scopeKey = schema.__ctx.lceKey + (idx !== undefined ? `_${idx}` : '')
1627
- // } else {
1628
- // // 在生产环境schema没有__ctx上下文,需要手动生成一个lceKey
1629
- // schema.__ctx = {
1630
- // lceKey: `lce${++scopeIdx}`,
1631
- // }
1632
- // scopeKey = schema.__ctx.lceKey
1633
- // }
1634
- // if (!this.__compScopes[scopeKey]) {
1635
- // this.__compScopes[scopeKey] = Comp.generateScope(this, schema)
1636
- // }
1637
- // }
1638
- // // 如果组件有设置scope,需要为组件生成一个新的scope上下文
1639
- // if (scopeKey && this.__compScopes[scopeKey]) {
1640
- // const compSelf = { ...this.__compScopes[scopeKey] }
1641
- // compSelf.__proto__ = scope
1642
- // scope = compSelf
1643
- // }
1644
-
1645
1657
  if (engine.props?.designMode) {
1646
1658
  otherProps.__designMode = engine.props.designMode;
1647
1659
  }
@@ -2005,9 +2017,6 @@ function componentRendererFactory() {
2005
2017
  static displayName = 'CompRenderer';
2006
2018
  __namespace = 'component';
2007
2019
  __afterInit(props, ...rest) {
2008
- this.__generateCtx({
2009
- component: this
2010
- });
2011
2020
  const schema = props.__schema || {};
2012
2021
  this.state = this.__parseData(schema.state || {});
2013
2022
  this.__initDataSource(props);
@@ -2103,19 +2112,23 @@ const FaultComponent = ({
2103
2112
  error
2104
2113
  }) => {
2105
2114
  logger.error(`${componentName} 组件渲染异常, 异常原因: ${error?.message || error || '未知'}`);
2106
- return /*#__PURE__*/jsxs("div", {
2115
+ return /*#__PURE__*/jsx("div", {
2107
2116
  role: "alert",
2108
2117
  "aria-label": `${componentName} 组件渲染异常`,
2109
2118
  style: {
2119
+ display: 'flex',
2120
+ justifyContent: 'center',
2121
+ alignItems: 'center',
2110
2122
  width: '100%',
2111
- height: '50px',
2112
- lineHeight: '50px',
2123
+ height: '100%',
2113
2124
  textAlign: 'center',
2114
2125
  fontSize: '15px',
2115
2126
  color: '#ef4444',
2116
2127
  border: '2px solid #ef4444'
2117
2128
  },
2118
- children: [componentName, " \u7EC4\u4EF6\u6E32\u67D3\u5F02\u5E38\uFF0C\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7"]
2129
+ children: /*#__PURE__*/jsxs("span", {
2130
+ children: [componentName, " \u7EC4\u4EF6\u6E32\u67D3\u5F02\u5E38\uFF0C\u8BF7\u67E5\u770B\u63A7\u5236\u53F0\u65E5\u5FD7"]
2131
+ })
2119
2132
  });
2120
2133
  };
2121
2134
 
@@ -2134,15 +2147,19 @@ const NotFoundComponent = ({
2134
2147
  role: "alert",
2135
2148
  "aria-label": `${componentName} component not found`,
2136
2149
  style: {
2150
+ display: 'flex',
2151
+ justifyContent: 'center',
2152
+ alignItems: 'center',
2137
2153
  width: '100%',
2138
- height: '50px',
2139
- lineHeight: '50px',
2154
+ height: '100%',
2140
2155
  textAlign: 'center',
2141
2156
  fontSize: '15px',
2142
2157
  color: '#eab308',
2143
2158
  border: '2px solid #eab308'
2144
2159
  },
2145
- children: `${componentName} Component Not Found`
2160
+ children: /*#__PURE__*/jsx("span", {
2161
+ children: `${componentName} Component Not Found`
2162
+ })
2146
2163
  });
2147
2164
  };
2148
2165
 
@@ -2250,6 +2267,63 @@ function rendererFactory() {
2250
2267
  };
2251
2268
  }
2252
2269
 
2270
+ /**
2271
+ * Setter Placeholder
2272
+ * 设置器加载占位符组件
2273
+ */
2274
+
2275
+ /**
2276
+ * 设置器加载占位符
2277
+ * 当设置器尚未加载完成时显示
2278
+ */
2279
+ const SetterPlaceholder = ({
2280
+ setterType
2281
+ }) => {
2282
+ return /*#__PURE__*/jsxs("div", {
2283
+ style: {
2284
+ display: 'flex',
2285
+ alignItems: 'center',
2286
+ gap: '8px',
2287
+ padding: '8px',
2288
+ fontSize: '12px',
2289
+ color: '#999',
2290
+ borderRadius: '4px'
2291
+ },
2292
+ children: [/*#__PURE__*/jsx(LoadingSpinner, {}), /*#__PURE__*/jsx("span", {
2293
+ children: setterType ? `加载中: ${setterType}` : '设置器加载中...'
2294
+ })]
2295
+ });
2296
+ };
2297
+
2298
+ /**
2299
+ * 简单的加载动画
2300
+ */
2301
+ const LoadingSpinner = () => {
2302
+ return /*#__PURE__*/jsxs("svg", {
2303
+ width: "14",
2304
+ height: "14",
2305
+ viewBox: "0 0 24 24",
2306
+ fill: "none",
2307
+ stroke: "currentColor",
2308
+ strokeWidth: "2",
2309
+ strokeLinecap: "round",
2310
+ strokeLinejoin: "round",
2311
+ style: {
2312
+ animation: 'spin 1s linear infinite'
2313
+ },
2314
+ children: [/*#__PURE__*/jsx("style", {
2315
+ children: `
2316
+ @keyframes spin {
2317
+ from { transform: rotate(0deg); }
2318
+ to { transform: rotate(360deg); }
2319
+ }
2320
+ `
2321
+ }), /*#__PURE__*/jsx("path", {
2322
+ d: "M21 12a9 9 0 1 1-6.219-8.56"
2323
+ })]
2324
+ });
2325
+ };
2326
+
2253
2327
  const SettingRendererContext = /*#__PURE__*/createContext({});
2254
2328
  const useSettingRendererContext = () => {
2255
2329
  try {
@@ -2336,6 +2410,13 @@ const SettingSetter = observer(({
2336
2410
  component: SetterComponent,
2337
2411
  props: mixedSetterProps
2338
2412
  } = setters.createSetterContent(setterType, setterProps);
2413
+
2414
+ // 处理设置器未加载的情况
2415
+ if (!SetterComponent) {
2416
+ return /*#__PURE__*/jsx(SetterPlaceholder, {
2417
+ setterType: setterType
2418
+ });
2419
+ }
2339
2420
  return /*#__PURE__*/jsx(SetterComponent, {
2340
2421
  field: field,
2341
2422
  selected: field.top?.getNode(),
@@ -2459,19 +2540,6 @@ const SettingRenderer = observer(props => {
2459
2540
  })
2460
2541
  });
2461
2542
  }
2462
-
2463
- // 当节点被锁定,且未开启锁定后容器可设置属性
2464
- if (settings.isLocked) {
2465
- return /*#__PURE__*/jsx("div", {
2466
- className: "lc-settings-main",
2467
- children: /*#__PURE__*/jsx("div", {
2468
- className: "lc-settings-notice",
2469
- children: /*#__PURE__*/jsx("p", {
2470
- children: "Current node is locked"
2471
- })
2472
- })
2473
- });
2474
- }
2475
2543
  if (Array.isArray(settings.items) && settings.items.length === 0) {
2476
2544
  return /*#__PURE__*/jsx("div", {
2477
2545
  className: "lc-settings-main",
@@ -2503,4 +2571,4 @@ const SettingRenderer = observer(props => {
2503
2571
  });
2504
2572
  });
2505
2573
 
2506
- export { RendererContext, SettingFieldView, SettingRenderer, adapter, baseRendererFactory, cloneEnumerableProperty, compWrapper, componentRendererFactory, contextFactory, createForwardRefHocElement, executeLifeCycleMethod, getSchemaChildren, isReactClass, isReactComponent, leafWrapper, pageRendererFactory, rendererFactory, useRendererContext };
2574
+ export { FaultComponent, NotFoundComponent, RendererContext, SettingFieldView, SettingRenderer, adapter, baseRendererFactory, cloneEnumerableProperty, compWrapper, componentRendererFactory, contextFactory, createForwardRefHocElement, executeLifeCycleMethod, getSchemaChildren, isReactClass, isReactComponent, leafWrapper, pageRendererFactory, rendererFactory, useRendererContext };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Setter Placeholder
3
+ * 设置器加载占位符组件
4
+ */
5
+ interface SetterPlaceholderProps {
6
+ /** 设置器类型名称 */
7
+ setterType?: string;
8
+ }
9
+ /**
10
+ * 设置器加载占位符
11
+ * 当设置器尚未加载完成时显示
12
+ */
13
+ export declare const SetterPlaceholder: ({ setterType }: SetterPlaceholderProps) => import("react").JSX.Element;
14
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-editor/react-renderer",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "React Renderer package for EasyEditor",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -48,12 +48,12 @@
48
48
  },
49
49
  "peerDependencies": {
50
50
  "mobx-react": "^9.2.0",
51
- "react": "^18 || ^19",
52
- "react-dom": "^18 || ^19",
53
- "@types/react": "^18 || ^19",
54
- "@types/react-dom": "^18 || ^19",
55
- "@easy-editor/core": "^1.0.1",
56
- "@easy-editor/renderer-core": "^1.0.1"
51
+ "react": "^19",
52
+ "react-dom": "^19",
53
+ "@types/react": "^19",
54
+ "@types/react-dom": "^19",
55
+ "@easy-editor/core": "^1.0.3",
56
+ "@easy-editor/renderer-core": "^1.0.3"
57
57
  },
58
58
  "dependencies": {
59
59
  "lodash-es": "^4.17.21"