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 aa464b50c..9e98c1d5c 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: '按钮', @@ -164,7 +202,15 @@ export default { name: 'children', propType: 'node' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + childWhitelist: 'Button' + } + } + } }, Input: { componentName: 'Input', @@ -446,7 +492,12 @@ export default { propType: 'bool', description: '是否开启预览态' } - ] + ], + configure: { + component: { + isContainer: true, + } + } }, 'Form.Item': { componentName: 'Form.Item', @@ -743,7 +794,15 @@ export default { propType: 'func', description: '预览态模式下渲染的内容\n@param {any} value 根据包裹的组件的 value 类型而决定' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + parentWhitelist: 'Form' + } + } + } }, NumberPicker: { componentName: 'NumberPicker', @@ -1131,7 +1190,15 @@ export default { name: 'locale', propType: 'object' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + childWhitelist: 'Select.Option' + } + } + } }, 'Select.Option': { componentName: 'Select.Option', @@ -1162,7 +1229,15 @@ export default { name: 'children', propType: 'any' } - ] + ], + configure: { + component: { + isContainer: true, + nestingRule: { + parentWhitelist: 'Select' + } + } + } } }, componentList: [ diff --git a/packages/editor/src/config/setters.ts b/packages/editor/src/config/setters.ts index 46f762ff0..32a404a41 100644 --- a/packages/editor/src/config/setters.ts +++ b/packages/editor/src/config/setters.ts @@ -1,8 +1,7 @@ -import { DatePicker, Input, Radio, Select, Switch } from '@alifd/next'; -import NumberSetter from '../../../plugin-setters/src/number-setter'; +import { DatePicker, Input, Radio, Select, Switch, NumberPicker } from '@alifd/next'; import ExpressionSetter from '../../../plugin-setters/src/expression-setter'; import MixinSetter from '../../../plugin-setters/src/mixin-setter'; -import EventsSetter from '../../../plugin-settings/src/builtin-setters/events-setter' +import EventsSetter from '../../../plugin-setters/src/events-setter'; import { registerSetter } from '../../../plugin-settings/src'; import { createElement } from 'react'; @@ -17,17 +16,20 @@ registerSetter('ClassNameSetter', () => { }); registerSetter('EventsSetter', EventsSetter); - -registerSetter('StringSetter', { component: Input, props: { placeholder: '请输入' } }); - -registerSetter('NumberSetter', NumberSetter as any); - -registerSetter('StringSetter', { component: Input, props: { placeholder: '请输入' } }); +registerSetter('StringSetter', { component: Input, defaultProps: { placeholder: '请输入' } }); +registerSetter('NumberSetter', NumberPicker); registerSetter('ExpressionSetter', ExpressionSetter); registerSetter('MixinSetter', MixinSetter); registerSetter('BoolSetter', Switch); -registerSetter('RadioGroupSetter', Radio.RadioGroup); +registerSetter('RadioGroupSetter', { + component: Radio.Group, + defaultProps: { + shape: 'button' + } +}); registerSetter('SelectSetter', Select); + +// suggest: 做成 StringSetter 的一个参数, registerSetter('TextAreaSetter', Input.TextArea); registerSetter('DateSetter', DatePicker); registerSetter('DateYearSetter', DatePicker.YearPicker); diff --git a/packages/plugin-settings/src/builtin-setters/events-setter/event-dialog.tsx b/packages/plugin-setters/src/events-setter/event-dialog.tsx similarity index 100% rename from packages/plugin-settings/src/builtin-setters/events-setter/event-dialog.tsx rename to packages/plugin-setters/src/events-setter/event-dialog.tsx diff --git a/packages/plugin-settings/src/builtin-setters/events-setter/index.tsx b/packages/plugin-setters/src/events-setter/index.tsx similarity index 100% rename from packages/plugin-settings/src/builtin-setters/events-setter/index.tsx rename to packages/plugin-setters/src/events-setter/index.tsx diff --git a/packages/plugin-settings/src/builtin-setters/events-setter/native-events.ts b/packages/plugin-setters/src/events-setter/native-events.ts similarity index 100% rename from packages/plugin-settings/src/builtin-setters/events-setter/native-events.ts rename to packages/plugin-setters/src/events-setter/native-events.ts diff --git a/packages/plugin-settings/src/builtin-setters/events-setter/style.less b/packages/plugin-setters/src/events-setter/style.less similarity index 100% rename from packages/plugin-settings/src/builtin-setters/events-setter/style.less rename to packages/plugin-setters/src/events-setter/style.less diff --git a/packages/plugin-setters/src/mixin-setter.tsx b/packages/plugin-setters/src/mixin-setter.tsx index 476e4fb35..d1e6b23e1 100644 --- a/packages/plugin-setters/src/mixin-setter.tsx +++ b/packages/plugin-setters/src/mixin-setter.tsx @@ -34,7 +34,8 @@ export default class Mixin extends PureComponent { }; static defaultProps = { locale: 'zh-CN', - messages: zhCN + messages: zhCN, + types: ['StringSetter', 'ExpressionSetter', 'NumberSetter', 'BoolSetter', 'SelectSetter', 'RadioGroupSetter'], }; constructor(props) { super(props); diff --git a/packages/plugin-settings/src/index.tsx b/packages/plugin-settings/src/index.tsx index c7ebbf33a..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; @@ -42,10 +43,10 @@ export default class SettingsMainView extends Component { let node: Node | null = this.main.nodes[0]!; const items = []; - let l = 4; + let l = 3; while (l-- > 0 && node) { const props = - l === 3 + l === 2 ? {} : { onMouseOver: hoverNode.bind(null, node, true), @@ -101,6 +102,7 @@ export default class SettingsMainView extends Component { return (
+ 4 ? 'SelectSetter' : 'RadioSetter'; + const componentName = dataSource.length > 4 ? 'SelectSetter' : 'RadioGroupSetter'; return { componentName, props: { dataSource }, @@ -135,7 +141,8 @@ export function propTypeToSetter(propType: PropType): SetterType { return { componentName: 'MixinSetter', props: { - setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)), + // TODO: + // setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)), }, isRequired, }; @@ -163,21 +170,23 @@ registerMetadataTransducer(metadata => { 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 +198,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; } @@ -279,11 +291,12 @@ registerMetadataTransducer(metadata => { setter: { componentName: 'MixinSetter', props: { + // TODO: setters: [ { componentName: 'StringSetter', props: { - // todo: + // TODO: textarea mode multiline: true, }, initialValue: '', @@ -304,44 +317,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 +411,7 @@ registerMetadataTransducer(metadata => { }); } - if (eventsDefinition) { + if (eventsDefinition.length > 0) { combined.push({ name: '#events', title: '事件', @@ -416,15 +425,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 +440,6 @@ registerMetadataTransducer(metadata => { } if (isRoot) { - // todo... combined.push({ name: '#advanced', title: '高级', @@ -458,6 +465,7 @@ registerMetadataTransducer(metadata => { setter: { componentName: 'MixinSetter', props: { + // TODO: setters: [ { componentName: 'JSONSetter', 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 {