From d8003720a275493a216e4e2987ab58ab4167e7b2 Mon Sep 17 00:00:00 2001 From: kangwei Date: Sun, 15 Mar 2020 18:09:46 +0800 Subject: [PATCH] complete parse props --- .../src/builtins/simulator/host/host.ts | 23 +- .../builtins/simulator/renderer/renderer.ts | 24 ++- .../builtins/simulator/utils/parse-props.ts | 200 ++++++++++++++++++ .../builtins/simulator/utils/vision-types.js | 198 ----------------- .../src/designer/document/document-model.ts | 3 +- .../designer/document/node/node-content.ts | 90 -------- .../src/designer/document/node/node.ts | 92 ++++---- .../src/designer/document/node/props/prop.ts | 44 +++- .../src/designer/document/node/props/props.ts | 6 +- .../src/designer/document/node/root-node.ts | 3 - packages/designer/src/designer/simulator.ts | 2 +- .../builtin-setters/array-setter/index.tsx | 7 +- .../builtin-setters/object-setter/index.tsx | 6 +- packages/plugin-settings/src/main.ts | 2 + .../src/register-transducer.ts | 32 +-- 15 files changed, 358 insertions(+), 374 deletions(-) create mode 100644 packages/designer/src/builtins/simulator/utils/parse-props.ts delete mode 100644 packages/designer/src/builtins/simulator/utils/vision-types.js delete mode 100644 packages/designer/src/designer/document/node/node-content.ts diff --git a/packages/designer/src/builtins/simulator/host/host.ts b/packages/designer/src/builtins/simulator/host/host.ts index 313fec373..6e8176928 100644 --- a/packages/designer/src/builtins/simulator/host/host.ts +++ b/packages/designer/src/builtins/simulator/host/host.ts @@ -31,9 +31,8 @@ import { import { isNodeSchema, NodeSchema } from '../../../designer/schema'; import { ComponentMetadata } from '../../../designer/component-meta'; import { ReactInstance } from 'react'; -import { setNativeSelection } from '../../../designer/helper/navtive-selection'; -import cursor from '../../../designer/helper/cursor'; import { isRootNode } from '../../../designer/document/node/root-node'; +import { parseProps } from '../utils/parse-props'; export interface SimulatorProps { // 从 documentModel 上获取 @@ -333,12 +332,26 @@ export class SimulatorHost implements ISimulator { * @see ISimulator */ generateComponentMetadata(componentName: string): ComponentMetadata { + // if html tags + if (isHTMLTag(componentName)) { + return { + componentName, + // TODO: read builtins html metadata + }; + } + const component = this.getComponent(componentName); + + if (component) { + parseProps(component as any); + } + // TODO: // 1. generate builtin div/p/h1/h2 // 2. read propTypes return { componentName, + props: parseProps(this.getComponent(componentName)), }; } @@ -346,7 +359,7 @@ export class SimulatorHost implements ISimulator { * @see ISimulator */ getComponent(componentName: string): Component | null { - return null; + return this.renderer?.getComponent(componentName) || null; } @obx.val private instancesMap = new Map(); @@ -933,6 +946,10 @@ export class SimulatorHost implements ISimulator { // #endregion } +function isHTMLTag(name: string) { + return /^[a-z]\w*$/.test(name); +} + function isPointInRect(point: CanvasPoint, rect: Rect) { return ( point.canvasY >= rect.top && diff --git a/packages/designer/src/builtins/simulator/renderer/renderer.ts b/packages/designer/src/builtins/simulator/renderer/renderer.ts index 7573c7adb..ea7eeeaf9 100644 --- a/packages/designer/src/builtins/simulator/renderer/renderer.ts +++ b/packages/designer/src/builtins/simulator/renderer/renderer.ts @@ -7,7 +7,6 @@ import { RootSchema, NpmInfo } from '../../../designer/schema'; import { getClientRects } from '../../../utils/get-client-rects'; import { Asset } from '../utils/asset'; import loader from '../utils/loader'; -import { ComponentMetadata } from '../../../designer/component-meta'; import { reactFindDOMNodes, FIBER_KEY } from '../utils/react-find-dom-nodes'; import { isESModule } from '../../../../../utils/is-es-module'; import { NodeInstance } from '../../../designer/simulator'; @@ -68,7 +67,7 @@ export class SimulatorRenderer { private buildComponents() { this._components = buildComponents(this._componentsMap); } - @obx.ref private _components = {}; + @obx.ref private _components: any = {}; @computed get components(): object { // 根据 device 选择不同组件,进行响应式 // 更好的做法是,根据 device 选择加载不同的组件资源,甚至是 simulatorUrl @@ -175,6 +174,27 @@ export class SimulatorRenderer { this.ctxMap.set(id, ctx); } + getComponent(componentName: string) { + const paths = componentName.split('.'); + const subs: string[] = []; + + while (true) { + const component = this._components[componentName]; + if (component) { + return getSubComponent(component, subs); + } + + const sub = paths.pop(); + if (!sub) { + return null; + } + subs.unshift(sub); + componentName = paths.join('.'); + } + + return null; + } + getComponentInstances(id: string): ReactInstance[] | null { return this.instancesMap.get(id) || null; } diff --git a/packages/designer/src/builtins/simulator/utils/parse-props.ts b/packages/designer/src/builtins/simulator/utils/parse-props.ts new file mode 100644 index 000000000..5d314c8d1 --- /dev/null +++ b/packages/designer/src/builtins/simulator/utils/parse-props.ts @@ -0,0 +1,200 @@ +import PropTypes from 'prop-types'; +import { isValidElement } from 'react'; +import { isElement } from '../../../utils/is-element'; +import { PropType, PropConfig } from '../../../designer/prop-config'; + +export const primitiveTypes = [ + 'string', + 'number', + 'array', + 'bool', + 'func', + 'object', + 'node', + 'element', + 'symbol', + 'any', +]; + +function makeRequired(propType: any, lowcodeType: string | object) { + function lowcodeCheckTypeIsRequired(...rest: any[]) { + return propType.isRequired(...rest); + } + if (typeof lowcodeType === 'string') { + lowcodeType = { + type: lowcodeType, + }; + } + lowcodeCheckTypeIsRequired.lowcodeType = { + ...lowcodeType, + isRequired: true, + }; + return lowcodeCheckTypeIsRequired; +} + +function define(propType: any = PropTypes.any, lowcodeType: string | object = {}) { + if (!propType._inner && propType.name !== 'lowcodeCheckType') { + propType.lowcodeType = lowcodeType; + } + function lowcodeCheckType(...rest: any[]) { + return propType(...rest); + } + lowcodeCheckType.lowcodeType = lowcodeType; + lowcodeCheckType.isRequired = makeRequired(propType, lowcodeType); + return lowcodeCheckType; +} + +const LowcodeTypes: any = { + ...PropTypes, + define, +}; + +(window as any).PropTypes = LowcodeTypes; +(window as any).React.PropTypes = LowcodeTypes; + +// override primitive type chechers +primitiveTypes.forEach(type => { + const propType = (PropTypes as any)[type]; + if (!propType) { + return; + } + propType._inner = true; + LowcodeTypes[type] = define(propType, type); +}); + +// You can ensure that your prop is limited to specific values by treating +// it as an enum. +LowcodeTypes.oneOf = (list: any[]) => { + return define(PropTypes.oneOf(list), { + type: 'oneOf', + value: list, + }); +}; + +// An array of a certain type +LowcodeTypes.arrayOf = (type: any) => { + return define(PropTypes.arrayOf(type), { + type: 'arrayOf', + value: type.lowcodeType || 'any', + }); +}; + +// An object with property values of a certain type +LowcodeTypes.objectOf = (type: any) => { + return define(PropTypes.objectOf(type), { + type: 'objectOf', + value: type.lowcodeType || 'any', + }); +}; + +// An object that could be one of many types +LowcodeTypes.oneOfType = (types: any[]) => { + const itemTypes = types.map(type => type.lowcodeType || 'any'); + return define(PropTypes.oneOfType(types), { + type: 'oneOfType', + value: itemTypes, + }); +}; + +// An object with warnings on extra properties +LowcodeTypes.exact = (typesMap: any) => { + const configs = Object.keys(typesMap).map(key => { + return { + name: key, + propType: typesMap[key].lowcodeType || 'any', + }; + }); + return define(PropTypes.exact(typesMap), { + type: 'exact', + value: configs, + }); +}; + +// An object taking on a particular shape +LowcodeTypes.shape = (typesMap: any) => { + const configs = Object.keys(typesMap).map(key => { + return { + name: key, + propType: typesMap[key].lowcodeType || 'any', + }; + }); + return define(PropTypes.shape(typesMap), { + type: 'shape', + value: configs, + }); +}; + +const BasicTypes = ['string', 'number', 'object']; +export function parseProps(component: any): PropConfig[] { + if (!component) { + return []; + } + const propTypes = component.propTypes || ({} as any); + const defaultProps = component.defaultProps || ({} as any); + const result: any = {}; + if (!propTypes) return []; + Object.keys(propTypes).forEach(key => { + const propTypeItem = propTypes[key]; + const defaultValue = defaultProps[key]; + const lowcodeType = propTypeItem.lowcodeType; + if (lowcodeType) { + result[key] = { + name: key, + propType: lowcodeType, + }; + if (defaultValue != null) { + result[key].defaultValue = defaultValue; + } + return; + } + + let i = primitiveTypes.length; + while (i-- > 0) { + const k = primitiveTypes[i]; + if ((LowcodeTypes as any)[k] === propTypeItem) { + result[key] = { + name: key, + propType: k, + }; + if (defaultValue != null) { + result[key].defaultValue = defaultValue; + } + return; + } + } + result[key] = { + name: key, + propType: 'any', + }; + if (defaultValue != null) { + result[key].defaultValue = defaultValue; + } + }); + + Object.keys(defaultProps).forEach(key => { + if (result[key]) return; + const defaultValue = defaultProps[key]; + let type: string = typeof defaultValue; + if (type === 'boolean') { + type = 'bool'; + } else if (type === 'function') { + type = 'func'; + } else if (type === 'object' && Array.isArray(defaultValue)) { + type = 'array'; + } else if (defaultValue && isValidElement(defaultValue)) { + type = 'node'; + } else if (defaultValue && isElement(defaultValue)) { + type = 'element'; + } else if (!BasicTypes.includes(type)) { + type = 'any'; + } + + result[key] = { + name: key, + propType: type || 'any', + defaultValue, + }; + }); + + return Object.keys(result).map(key => result[key]); +} diff --git a/packages/designer/src/builtins/simulator/utils/vision-types.js b/packages/designer/src/builtins/simulator/utils/vision-types.js deleted file mode 100644 index 86a8a42b5..000000000 --- a/packages/designer/src/builtins/simulator/utils/vision-types.js +++ /dev/null @@ -1,198 +0,0 @@ -import PropTypes from 'prop-types'; - -export const primitiveTypeMaps = { - string: { - defaultValue: '', - display: 'inline', - setter: 'TextSetter', - }, - number: { - display: 'inline', - setter: 'NumberSetter' // extends TextSetter - }, - array: { - defaultValue: [], - display: 'inline', - // itemType: any - setter: 'ArraySetter' // extends ExpressionSetter - }, - bool: { - defaultValue: false, - display: 'inline', - setter: 'BoolSetter' - }, - func: { - defaultValue: () => {}, - display: 'inline', - setter: 'FunctionSetter' // extends ExpressionSetter - }, - object: { - defaultValue: {}, - display: 'inline', - // itemType: any - setter: 'ObjectSetter' // extends ExpressionSetter - }, - // Anything that can be rendered: numbers, strings, elements or an array - // (or fragment) containing these types. - node: { - defaultValue: '', - display: 'inline', - setter: 'FragmentSetter', - }, - // A React element. - element: { - display: 'inline', - setter: 'JSXSetter', // extends ExpressionSetter - }, - symbol: { - display: 'inline', - setter: 'ExpressionSetter', - }, - any: { - display: 'inline', - setter: 'ExpressionSetter', - } -}; - -function makeRequired(propType, visionType) { - function visionCheckTypeIsRequired(...rest) { - return propType.isRequired(...rest); - } - visionCheckTypeIsRequired.visionType = { - ...visionType, - required: true, - }; - return visionCheckTypeIsRequired; -} - -function define(propType = PropTypes.any, visionType = {}) { - if (!propType._inner && propType.name !== 'visionCheckType') { - propType.visionType = visionType; - } - function visionCheckType(...rest) { - return propType(...rest); - } - visionCheckType.visionType = visionType; - visionCheckType.isRequired = makeRequired(propType, visionType); - return visionCheckType; -} - -const VisionTypes = { - ...PropTypes, - define, -}; - -export default VisionTypes; - -// override primitive type chechers -Object.keys(primitiveTypeMaps).forEach((type) => { - const propType = PropTypes[type]; - if (!propType) { - return; - } - propType._inner = true; - VisionTypes[type] = define(propType, primitiveTypeMaps[type]); -}); - -// You can ensure that your prop is limited to specific values by treating -// it as an enum. -VisionTypes.oneOf = (list) => { - return define(PropTypes.oneOf(list), { - defaultValue: list && list[0], - display: 'inline', - setter: { - type: 'SelectSetter', - options: list, - }, - }); -}; - -// An array of a certain type -VisionTypes.arrayOf = (type) => { - return define(PropTypes.arrayOf(type), { - defaultValue: [], - display: 'inline', - setter: { - type: 'ArraySetter', // list - itemType: type.visionType || primitiveTypeMaps.any, // addable type - } - }); -}; - -// An object with property values of a certain type -VisionTypes.objectOf = (type) => { - return define(PropTypes.objectOf(type), { - defaultValue: {}, - display: 'inline', - setter: { - type: 'ObjectSetter', // all itemType - itemType: type.visionType || primitiveTypeMaps.any, // addable type - } - }); -}; - -// An object that could be one of many types -VisionTypes.oneOfType = (types) => { - const itemType = types.map(type => type.visionType || primitiveTypeMaps.any); - return define(PropTypes.oneOfType(types), { - defaultValue: itemType[0] && itemType[0].defaultValue, - display: 'inline', - setter: { - type: 'OneOfTypeSetter', - itemType, // addable type - }, - }); -}; - - -// You can also declare that a prop is an instance of a class. This uses -// JS's instanceof operator. -VisionTypes.instanceOf = (classType) => { - return define(PropTypes.instanceOf(classType), { - display: 'inline', - setter: 'ExpressionSetter', - }); -}; - -// An object with warnings on extra properties -VisionTypes.exact = (typesMap) => { - const exactTypes = {}; - const defaultValue = {}; - Object.keys(typesMap).forEach(key => { - exactTypes[key] = typesMap[key].visionType || primitiveTypeMaps.any; - defaultValue[key] = exactTypes[key].defaultValue; - }); - return define(PropTypes.exact(typesMap), { - defaultValue, - display: 'inline', - setter: { - type: 'ObjectSetter', // all itemType - exactTypes, - }, - }); -} - -// An object taking on a particular shape -VisionTypes.shape = (typesMap) => { - const exactTypes = {}; - const defaultValue = {}; - Object.keys(typesMap).forEach(key => { - exactTypes[key] = typesMap[key].visionType || primitiveTypeMaps.any; - defaultValue[key] = exactTypes[key].defaultValue; - }); - return define(PropTypes.shape(typesMap), { - defaultValue, - display: 'inline', - setter: { - type: 'ObjectSetter', // all itemType - exactTypes, - itemType: primitiveTypeMaps.any, // addable type - }, - }); -}; - - -// color -// time -// date -// range diff --git a/packages/designer/src/designer/document/document-model.ts b/packages/designer/src/designer/document/document-model.ts index f20256db0..ca0726b76 100644 --- a/packages/designer/src/designer/document/document-model.ts +++ b/packages/designer/src/designer/document/document-model.ts @@ -102,7 +102,7 @@ export default class DocumentModel { let schema: any; if (isDOMText(data) || isJSExpression(data)) { schema = { - componentName: '#frag', + componentName: 'Leaf', children: data, }; } else { @@ -281,6 +281,7 @@ export default class DocumentModel { // TODO: emit simulator mounted } + // FIXME: does needed? getComponent(componentName: string): any { return this.simulator!.getComponent(componentName); } diff --git a/packages/designer/src/designer/document/node/node-content.ts b/packages/designer/src/designer/document/node/node-content.ts deleted file mode 100644 index b7e5caeb5..000000000 --- a/packages/designer/src/designer/document/node/node-content.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { obx, computed } from '@recore/obx'; -import { JSExpression, isJSExpression } from '../../schema'; - -export default class NodeContent { - @obx.ref private _value: string | JSExpression = ''; - - @computed get value(): string | JSExpression { - return this._value; - } - - set value(val: string | JSExpression) { - this._value = val; - } - - /** - * 获得表达式值 - */ - @computed get code() { - if (isJSExpression(this._value)) { - return this._value.value; - } - return JSON.stringify(this.value); - } - - /** - * 设置表达式值 - */ - set code(code: string) { - if (isJSExpression(this._value)) { - this._value = { - ...this._value, - value: code, - }; - } else { - let useCode: boolean = true; - try { - const v = JSON.parse(code); - const t = typeof v; - if (v == null) { - this._value = ''; - useCode = false; - } else if (t === 'string' || t === 'number' || t === 'boolean') { - this._value = String(v); - useCode = false; - } - } catch (e) { - // ignore - } - if (useCode) { - this._value = { - type: 'JSExpression', - value: code, - mock: this._value, - }; - } - } - } - - constructor(value: any) { - this.import(value); - } - - import(value: any) { - const type = typeof value; - if (value == null) { - this._value = ''; - } else if (type === 'string' || type === 'number' || type === 'boolean') { - this._value = String(value); - } else if (isJSExpression(value)) { - this._value = value; - } - } - - /** - * 是否表达式 - */ - @computed isJSExpression(): boolean { - return isJSExpression(this._value); - } - - /** - * 是否空值 - */ - @computed isEmpty() { - if (isJSExpression(this._value)) { - return this._value.value === ''; - } - return this._value === ''; - } -} diff --git a/packages/designer/src/designer/document/node/node.ts b/packages/designer/src/designer/document/node/node.ts index c4dcbdf45..c94101e16 100644 --- a/packages/designer/src/designer/document/node/node.ts +++ b/packages/designer/src/designer/document/node/node.ts @@ -1,11 +1,9 @@ -import { obx, computed, untracked } from '@recore/obx'; -import { NodeSchema, NodeData, PropsMap, PropsList } from '../../schema'; +import { obx, computed } from '@recore/obx'; +import { NodeSchema, NodeData, PropsMap, PropsList, isDOMText, isJSExpression } from '../../schema'; import Props, { EXTRA_KEY_PREFIX } from './props/props'; import DocumentModel from '../document-model'; import NodeChildren from './node-children'; import Prop from './props/prop'; -import NodeContent from './node-content'; -import { Component } from '../../simulator'; import { ComponentMeta } from '../../component-meta'; /** @@ -48,12 +46,12 @@ export default class Node { * * Component 组件/元件 */ readonly componentName: string; - protected _props?: Props; - protected _children: NodeChildren | NodeContent; + /** + * 属性抽象 + */ + readonly props: Props; + protected _children?: NodeChildren; @obx.ref private _parent: NodeParent | null = null; - get props(): Props | undefined { - return this._props; - } /** * 父级节点 */ @@ -63,8 +61,8 @@ export default class Node { /** * 当前节点子集 */ - get children(): NodeChildren | NodeContent { - return this._children; + get children(): NodeChildren | null { + return this._children || null; } /** * 当前节点深度 @@ -99,19 +97,23 @@ export default class Node { this.id = id || `node$${document.nextId()}`; this.componentName = componentName; this._slotFor = slotFor; + let _props: Props; if (isNodeParent(this)) { - this._props = new Props(this, props, extras); + _props = new Props(this, props, extras); this._children = new NodeChildren(this as NodeParent, children || []); } else { - this._children = new NodeContent(children); + _props = new Props(this, { + children: isDOMText(children) || isJSExpression(children) ? children : '', + }); } + this.props = _props; } /** * 是否一个父亲类节点 */ get isNodeParent(): boolean { - return this.componentName.charAt(0) !== '#'; + return this.componentName !== 'Leaf'; } /** @@ -165,16 +167,6 @@ export default class Node { } } - /** - * 节点组件类 - */ - @obx.ref get component(): Component { - if (this.isNodeParent) { - return this.document.getComponent(this.componentName) || this.componentName; - } - return this.componentName; - } - /** * 节点组件描述 */ @@ -186,7 +178,7 @@ export default class Node { if (!this.isNodeParent || this.componentName === 'Fragment') { return null; } - return this.props?.export(true).props || null; + return this.props.export(true).props || null; } private _conditionGroup: string | null = null; @@ -231,12 +223,12 @@ export default class Node { // } - getProp(path: string, useStash = true): Prop | null { - return this.props?.query(path, useStash as any) || null; + getProp(path: string, stash = true): Prop | null { + return this.props.query(path, stash as any) || null; } - getExtraProp(key: string, useStash = true): Prop | null { - return this.props?.get(EXTRA_KEY_PREFIX + key, useStash) || null; + getExtraProp(key: string, stash = true): Prop | null { + return this.props.get(EXTRA_KEY_PREFIX + key, stash) || null; } /** @@ -257,14 +249,14 @@ export default class Node { * 设置多个属性值,和原有值合并 */ mergeProps(props: PropsMap) { - this.props?.merge(props); + this.props.merge(props); } /** * 设置多个属性值,替换原有值 */ setProps(props?: PropsMap | PropsList | null) { - this.props?.import(props); + this.props.import(props); } /** @@ -320,10 +312,10 @@ export default class Node { const { componentName, id, children, props, ...extras } = data; if (isNodeParent(this)) { - this._props!.import(props, extras); - this._children.import(children, checkId); + this.props.import(props, extras); + (this._children as NodeChildren).import(children, checkId); } else { - this._children.import(children); + this.props.get('children', true)!.setValue(isDOMText(children) || isJSExpression(children) ? children : ''); } } @@ -332,22 +324,30 @@ export default class Node { * @param serialize 序列化,加 id 标识符,用于储存为操作记录 */ export(serialize = false): NodeSchema { - const { props, extras } = this.props?.export(serialize) || {}; - const schema: any = { + const baseSchema: any = { componentName: this.componentName, + }; + + if (serialize) { + baseSchema.id = this.id; + } + + if (!isNodeParent(this)) { + baseSchema.children = this.props.get('children')?.export(serialize); + return baseSchema; + } + + const { props, extras } = this.props.export(serialize) || {}; + const schema: any = { + ...baseSchema, props, ...extras, }; - if (serialize) { - schema.id = this.id; - } - if (isNodeParent(this)) { - if (this.children.size > 0) { - schema.children = this.children.export(serialize); - } - } else { - schema.children = (this.children as NodeContent).value; + + if (this.children.size > 0) { + schema.children = this.children.export(serialize); } + return schema; } @@ -400,7 +400,7 @@ export default class Node { if (isNodeParent(this)) { this.children.purge(); } - this.props?.purge(); + this.props.purge(); this.document.internalRemoveAndPurgeNode(this); } } diff --git a/packages/designer/src/designer/document/node/props/prop.ts b/packages/designer/src/designer/document/node/props/prop.ts index 5a9680541..a657216f0 100644 --- a/packages/designer/src/designer/document/node/props/prop.ts +++ b/packages/designer/src/designer/document/node/props/prop.ts @@ -16,16 +16,18 @@ export interface IPropParent { readonly props: Props; } +export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot'; + export default class Prop implements IPropParent { readonly isProp = true; readonly id = uniqueId('prop$'); - @obx.ref private _type: 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot' = 'unset'; + @obx.ref private _type: ValueTypes = 'unset'; /** * 属性类型 */ - get type(): 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot' { + get type(): ValueTypes { return this._type; } @@ -83,6 +85,7 @@ export default class Prop implements IPropParent { return null; } + private _code: string | null = null; /** * 获得表达式值 */ @@ -90,13 +93,41 @@ export default class Prop implements IPropParent { if (isJSExpression(this.value)) { return this.value.value; } + // todo: JSFunction ... if (this.type === 'slot') { return JSON.stringify(this._slotNode!.export(false)); } - return JSON.stringify(this.value); + return this._code != null ? this._code : JSON.stringify(this.value); } - set code(val) { - // todo + + /** + * 设置表达式值 + */ + set code(code: string) { + if (isJSExpression(this._value)) { + this.setValue({ + ...this._value, + value: code, + }); + this._code = code; + return; + } + + try { + const v = JSON.parse(code); + this.setValue(v); + this._code = code; + return; + } catch (e) { + // ignore + } + + this.setValue({ + type: 'JSExpression', + value: code, + mock: this._value, + }); + this._code = code; } @computed getAsString(): string { @@ -111,6 +142,7 @@ export default class Prop implements IPropParent { */ setValue(val: CompositeValue) { this._value = val; + this._code = null; const t = typeof val; if (val == null) { this._value = null; @@ -174,7 +206,7 @@ export default class Prop implements IPropParent { this._slotNode?.internalSetParent(null); const owner = this.props.owner; this._slotNode = owner.document.createNode(data, this); - this._slotNode.internalSetParent(owner); + this._slotNode.internalSetParent(owner as any); } this.dispose(); } diff --git a/packages/designer/src/designer/document/node/props/props.ts b/packages/designer/src/designer/document/node/props/props.ts index 3d655c7bb..328d1315b 100644 --- a/packages/designer/src/designer/document/node/props/props.ts +++ b/packages/designer/src/designer/document/node/props/props.ts @@ -1,9 +1,9 @@ import { computed, obx } from '@recore/obx'; import { uniqueId } from '../../../../../../utils/unique-id'; -import { CompositeValue, PropsList, PropsMap, CompositeObject } from '../../../schema'; +import { CompositeValue, PropsList, PropsMap } from '../../../schema'; import PropStash from './prop-stash'; import Prop, { IPropParent, UNSET } from './prop'; -import { NodeParent } from '../node'; +import Node from '../node'; export const EXTRA_KEY_PREFIX = '__'; @@ -40,7 +40,7 @@ export default class Props implements IPropParent { @obx type: 'map' | 'list' = 'map'; - constructor(readonly owner: NodeParent, value?: PropsMap | PropsList | null, extras?: object) { + constructor(readonly owner: Node, value?: PropsMap | PropsList | null, extras?: object) { if (Array.isArray(value)) { this.type = 'list'; this.items = value.map(item => new Prop(this, item.value, item.name, item.spread)); diff --git a/packages/designer/src/designer/document/node/root-node.ts b/packages/designer/src/designer/document/node/root-node.ts index aa8b629cc..0bb809f33 100644 --- a/packages/designer/src/designer/document/node/root-node.ts +++ b/packages/designer/src/designer/document/node/root-node.ts @@ -56,9 +56,6 @@ export default class RootNode extends Node implements NodeParent { get children(): NodeChildren { return this._children as NodeChildren; } - get props(): Props { - return this._props as any; - } internalSetParent(parent: null) { // empty } diff --git a/packages/designer/src/designer/simulator.ts b/packages/designer/src/designer/simulator.ts index 8212354fc..e21b5e8c9 100644 --- a/packages/designer/src/designer/simulator.ts +++ b/packages/designer/src/designer/simulator.ts @@ -157,7 +157,7 @@ export interface NodeInstance { /** * 组件类定义 */ -export type Component = ComponentType | object | string; +export type Component = ComponentType | object; /** * 组件实例定义 diff --git a/packages/plugin-settings/src/builtin-setters/array-setter/index.tsx b/packages/plugin-settings/src/builtin-setters/array-setter/index.tsx index 71c521bfc..8d050d849 100644 --- a/packages/plugin-settings/src/builtin-setters/array-setter/index.tsx +++ b/packages/plugin-settings/src/builtin-setters/array-setter/index.tsx @@ -237,7 +237,7 @@ export default class ArraySetter extends Component<{ if (setter?.componentName === 'ObjectSetter') { const items: FieldConfig[] = setter.props?.config?.items; if (items && Array.isArray(items)) { - columns = items.filter(item => item.isRequired || item.important); + columns = items.filter(item => item.isRequired || item.important || (item.setter as any)?.isRequired); if (columns.length === 3) { columns = columns.slice(0, 3); } else if (columns.length > 3) { @@ -264,10 +264,7 @@ export default class ArraySetter extends Component<{ } this.pipe = (this.context as PopupPipe).create({ width }); } - this.pipe.send( - , - title, - ); + this.pipe.send(, title); return (