diff --git a/packages/designer/src/builtins/simulator/renderer/renderer.ts b/packages/designer/src/builtins/simulator/renderer/renderer.ts index 08298fc08..40cb6647d 100644 --- a/packages/designer/src/builtins/simulator/renderer/renderer.ts +++ b/packages/designer/src/builtins/simulator/renderer/renderer.ts @@ -314,7 +314,10 @@ export interface LibraryMap { function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo }) { const components: any = {}; Object.keys(componentsMap).forEach(componentName => { - components[componentName] = findComponent(libraryMap, componentName, componentsMap[componentName]); + const component = findComponent(libraryMap, componentName, componentsMap[componentName]); + if (component) { + components[componentName] = component; + } }); return components; } diff --git a/packages/editor/src/config/assets.js b/packages/editor/src/config/assets.js index 4a6193df6..02a2d80e3 100644 --- a/packages/editor/src/config/assets.js +++ b/packages/editor/src/config/assets.js @@ -13,6 +13,44 @@ export default { } }, components: { + Page: { + componentName: 'Page', + title: '页面', + configure: { + events: { + supportedLifecycles: [ + { + description: '初始化时', + name: 'constructor', + }, + { + description: '装载后', + name: 'componentDidMount', + }, + { + description: '更新时', + name: 'componentDidMount', + }, + { + description: '卸载时', + name: 'componentWillUnmount', + }, + ] + }, + component: { + isContainer: true, + } + } + }, + Div: { + componentName: 'Div', + title: '容器', + configure: { + component: { + isContainer: true, + } + } + }, Button: { componentName: 'Button', title: '按钮', @@ -165,7 +203,15 @@ export default { name: 'children', propType: 'node' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + childWhitelist: 'Button' + } + } + } }, Input: { componentName: 'Input', @@ -450,7 +496,12 @@ export default { propType: 'bool', description: '是否开启预览态' } - ] + ], + configure: { + component: { + isContainer: true, + } + } }, 'Form.Item': { componentName: 'Form.Item', @@ -747,7 +798,15 @@ export default { propType: 'func', description: '预览态模式下渲染的内容\n@param {any} value 根据包裹的组件的 value 类型而决定' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + parentWhitelist: 'Form' + } + } + } }, NumberPicker: { componentName: 'NumberPicker', @@ -1142,7 +1201,15 @@ export default { propType: 'object', defaultValue: 'zhCN.Select' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + childWhitelist: 'Select.Option' + } + } + } }, 'Select.Option': { componentName: 'Select.Option', @@ -1173,7 +1240,15 @@ export default { name: 'children', propType: 'any' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + parentWhitelist: 'Select' + } + } + } } }, componentList: [ diff --git a/packages/plugin-settings/src/index.tsx b/packages/plugin-settings/src/index.tsx index d1edcc926..36f6fc754 100644 --- a/packages/plugin-settings/src/index.tsx +++ b/packages/plugin-settings/src/index.tsx @@ -8,6 +8,7 @@ import Node from '../../designer/src/designer/document/node/node'; import ArraySetter from './builtin-setters/array-setter'; import ObjectSetter from './builtin-setters/object-setter'; import './register-transducer'; +import { TipContainer } from './tip'; export default class SettingsMainView extends Component { private main: SettingsMain; @@ -101,6 +102,7 @@ export default class SettingsMainView extends Component { return (
+ { return metadata as any; } } + + const { configure = {} } = metadata; + if (!metadata.props) { return { ...metadata, configure: { - props: metadata.configure && Array.isArray(metadata.configure) ? metadata.configure : [], + ...configure, + props: [], }, }; } - - const { configure = {} } = metadata; const { props = [], component = {}, events = {}, styles = {} } = configure; - const supportEvents: string[] | null = (events as any).supportEvents ? null : []; + const supportedEvents: any[] | null = (events as any).supportedEvents ? null : []; metadata.props.forEach(prop => { - const { name, propType } = prop; + const { name, propType, description } = prop; if ( name === 'children' && (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any') @@ -189,9 +197,12 @@ registerMetadataTransducer(metadata => { } if (EVENT_RE.test(name) && (propType === 'func' || propType === 'any')) { - if (supportEvents) { - supportEvents.push(name); - (events as any).supportEvents = supportEvents; + if (supportedEvents) { + supportedEvents.push({ + name, + description, + }); + (events as any).supportedEvents = supportedEvents; } return; } @@ -304,44 +315,40 @@ registerMetadataTransducer(metadata => { }; } - const { props, events, styles } = configure as any; - let eventsDefinition: any; - let isRoot: boolean = false; - if (componentName === 'Page' || componentName === 'Component') { - isRoot = true; - // 平台配置的,一般只有根节点才会配置 - eventsDefinition = [ - { - type: 'lifeCycleEvent', - title: '生命周期', - list: [ - { - description: '初始化时', - name: 'constructor', - }, - { - description: '装载后', - name: 'componentDidMount', - }, - { - description: '更新时', - name: 'componentDidMount', - }, - { - description: '卸载时', - name: 'componentWillUnmount', - }, - ], - }, - ]; - } else { - eventsDefinition = [ - { - type: 'events', - title: '事件', - list: (events?.supportEvents || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)), - }, - ]; + const { props, events = {}, styles } = configure as any; + const isRoot: boolean = componentName === 'Page' || componentName === 'Component'; + const eventsDefinition: any[] = []; + const supportedLifecycles = events.supportedLifecycles || (isRoot ? [ + { + description: '初始化时', + name: 'constructor', + }, + { + description: '装载后', + name: 'componentDidMount', + }, + { + description: '更新时', + name: 'componentDidMount', + }, + { + description: '卸载时', + name: 'componentWillUnmount', + }, + ] : null); + if (supportedLifecycles) { + eventsDefinition.push({ + type: 'lifeCycleEvent', + title: '生命周期', + list: supportedLifecycles.map((event: any) => (typeof event === 'string' ? { name: event } : event)), + }); + } + if (events.supportedEvents) { + eventsDefinition.push({ + type: 'events', + title: '事件', + list: (events.supportedEvents || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)), + }); } // 通用设置 const propsGroup = props || []; @@ -402,7 +409,7 @@ registerMetadataTransducer(metadata => { }); } - if (eventsDefinition) { + if (eventsDefinition.length > 0) { combined.push({ name: '#events', title: '事件', @@ -416,15 +423,14 @@ registerMetadataTransducer(metadata => { definition: eventsDefinition, }, }, - - getValue(field: SettingField, val?:any[]) { + getValue(field: SettingField, val?: any[]) { + // todo: return val; }, setValue(field: SettingField, eventDataList: any[]) { + // todo: return; - // console.info(eventDataList); - // field.parent.setPropValue('eventDataList', eventDataList); }, }, ], @@ -432,7 +438,6 @@ registerMetadataTransducer(metadata => { } if (isRoot) { - // todo... combined.push({ name: '#advanced', title: '高级', diff --git a/packages/plugin-settings/src/title/index.tsx b/packages/plugin-settings/src/title/index.tsx index 00963ec46..266a947de 100644 --- a/packages/plugin-settings/src/title/index.tsx +++ b/packages/plugin-settings/src/title/index.tsx @@ -6,7 +6,7 @@ import './title.less'; export interface IconConfig { type: string; - size?: number | "small" | "xxs" | "xs" | "medium" | "large" | "xl" | "xxl" | "xxxl" | "inherit"; + size?: number | 'small' | 'xxs' | 'xs' | 'medium' | 'large' | 'xl' | 'xxl' | 'xxxl' | 'inherit'; className?: string; } @@ -51,7 +51,12 @@ export default class Title extends Component<{ title: TitleContent; onClick?: () } return ( -
+
{icon ?
{icon}
: null} {title.label ? {title.label} : null} {tip} diff --git a/packages/plugin-settings/src/title/title.less b/packages/plugin-settings/src/title/title.less index 3563331df..049626e6c 100644 --- a/packages/plugin-settings/src/title/title.less +++ b/packages/plugin-settings/src/title/title.less @@ -7,6 +7,13 @@ align-items: center; margin-right: 4px; } + &.has-tip { + cursor: help; + text-decoration-line: underline; + text-decoration-style: dashed; + text-decoration-color: rgba(31, 56, 88, .3); + } + padding: 2px 0; } .actived .lc-title {