Merge branch 'polyfill/vision' of gitlab.alibaba-inc.com:ali-lowcode/ali-lowcode-engine into polyfill/vision

This commit is contained in:
mario.gk 2020-05-05 14:54:30 +08:00
commit 5b38959f89
8 changed files with 229 additions and 17 deletions

View File

@ -7,6 +7,8 @@ import {
TitleContent,
TransformedComponentMetadata,
NestingFilter,
isTitleConfig,
I18nData,
} from '@ali/lowcode-types';
import { computed } from '@ali/lowcode-editor-core';
import { Node, ParentalNode } from './document';
@ -17,6 +19,7 @@ import { IconPage } from './icons/page';
import { IconComponent } from './icons/component';
import { IconRemove } from './icons/remove';
import { IconClone } from './icons/clone';
import { ReactElement } from 'react';
function ensureAList(list?: string | string[]): string[] | null {
if (!list) {
@ -91,12 +94,20 @@ export class ComponentMeta {
private childWhitelist?: NestingFilter | null;
private _title?: TitleContent;
get title() {
get title(): string | I18nData | ReactElement {
// TODO: 标记下。这块需要康师傅加一下API页面正常渲染。
// string | i18nData | ReactElement
// TitleConfig title.label
if (isTitleConfig(this._title)) {
return (this._title.label as any) || this.componentName;
}
return this._title || this.componentName;
}
@computed get icon() {
// TODO: 标记下。这块需要康师傅加一下API页面正常渲染。
// give Slot default icon
// if _title is TitleConfig get _title.icon
return (
this._transformedMetadata?.icon ||
(this.componentName === 'Page' ? IconPage : this.isContainer ? IconContainer : IconComponent)
@ -131,10 +142,10 @@ export class ComponentMeta {
this._title =
typeof title === 'string'
? {
type: 'i18n',
'en-US': this.componentName,
'zh-CN': title,
}
type: 'i18n',
'en-US': this.componentName,
'zh-CN': title,
}
: title;
}

View File

@ -180,6 +180,11 @@ export class SettingPropEntry implements SettingEntry {
return this.top;
}
// add settingfield props
get props() {
return this.top;
}
onValueChange(func: () => any) {
this.emitter.on('valuechange', func);

View File

@ -7,6 +7,7 @@ import {
PropsList,
NodeData,
TitleContent,
I18nData,
SlotSchema,
PageSchema,
ComponentSchema,
@ -19,6 +20,7 @@ import { Prop } from './props/prop';
import { ComponentMeta } from '../../component-meta';
import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group';
import { TransformStage } from './transform-stage';
import { ReactElement } from 'react';
/**
*
@ -122,7 +124,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return 0;
}
@computed get title(): TitleContent {
@computed get title(): string | I18nData | ReactElement {
let t = this.getExtraProp('title');
if (!t && this.componentMeta.descriptor) {
t = this.getProp(this.componentMeta.descriptor, false);
@ -136,6 +138,10 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return this.componentMeta.title;
}
get icon() {
return this.componentMeta.icon;
}
constructor(readonly document: DocumentModel, nodeSchema: Schema) {
const { componentName, id, children, props, ...extras } = nodeSchema;
this.id = id || `node$${document.nextId()}`;

View File

@ -7,7 +7,7 @@ import './renderer.less';
// patch cloneElement avoid lost keyProps
const originCloneElement = window.React.cloneElement;
(window as any).React.cloneElement = (child: any, { _leaf, ...props}: any = {}) => {
(window as any).React.cloneElement = (child: any, { _leaf, ...props }: any = {}) => {
if (child.ref && props.ref) {
const dRef = props.ref;
const cRef = child.ref;
@ -18,7 +18,7 @@ const originCloneElement = window.React.cloneElement;
} else {
try {
cRef.current = x;
} catch (e) { }
} catch (e) {}
}
}
if (dRef) {
@ -27,13 +27,13 @@ const originCloneElement = window.React.cloneElement;
} else {
try {
dRef.current = x;
} catch (e) { }
} catch (e) {}
}
}
}
};
};
}
return originCloneElement(child, props);
}
};
export default class SimulatorRendererView extends Component<{ renderer: SimulatorRenderer }> {
render() {
@ -87,7 +87,7 @@ class Renderer extends Component<{ renderer: SimulatorRenderer }> {
return createElement(
Component,
viewProps,
children == null ? null : Array.isArray(children) ? children : [children],
children == null ? [] : Array.isArray(children) ? children : [children],
);
}}
onCompGetRef={(schema: any, ref: ReactInstance | null) => {

View File

@ -13,3 +13,6 @@ export interface TitleConfig {
export type TitleContent = string | I18nData | ReactElement | TitleConfig;
export function isTitleConfig(obj: any): obj is TitleConfig {
return obj && (obj.label || obj.tip || obj.icon);
}

View File

@ -0,0 +1,82 @@
@import '~@ali/ve-less-variables/index.less';
// 样式直接沿用之前的样式,优化了下命名
.instance-node-selector {
position: relative;
margin-right: 2px;
color: var(--color-icon-white, @title-bgcolor);
border-radius: @global-border-radius;
margin-right: 2px;
pointer-events: auto;
flex-grow: 0;
flex-shrink: 0;
svg {
width: 16px;
height: 16px;
margin-right: 5px;
flex-grow: 0;
flex-shrink: 0;
max-width: inherit;
path {
fill: var(--color-icon-white, @title-bgcolor);
}
}
&-current {
background: var(--color-brand, @brand-color-1);
padding: 0 6px;
display: flex;
align-items: center;
height: 20px;
cursor: pointer;
color: var(--color-icon-white, @title-bgcolor);
border-radius: 3px;
&-title {
padding-right: 6px;
color: var(--color-icon-white, @title-bgcolor);
}
}
&-list {
position: absolute;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
}
&-node {
margin: 2px 0;
&-content {
padding-left: 6px;
background: #78869a;
display: inline-flex;
border-radius: 3px;
align-items: center;
height: 20px;
color: var(--color-icon-white, @title-bgcolor);
cursor: pointer;
overflow: visible;
}
&-title {
padding-right: 6px;
// margin-left: 5px;
color: var(--color-icon-white, @title-bgcolor);
cursor: pointer;
overflow: visible;
}
&:hover {
opacity: 0.8;
}
}
}
&:hover {
.instance-node-selector-current {
color: ar(--color-text-reverse, @white-alpha-2);
}
.instance-node-selector-popup {
visibility: visible;
opacity: 1;
transition: 0.2s all ease-in;
}
}

View File

@ -0,0 +1,95 @@
import { Overlay } from '@alifd/next';
import React from 'react';
import './index.less';
import { Title } from '@ali/lowcode-editor-core';
import { Node, ParentalNode } from '@ali/lowcode-designer';
const { Popup } = Overlay;
export interface IProps {
node: Node;
}
export interface IState {
parentNodes: Node[];
}
type UnionNode = Node | ParentalNode | null;
export class InstanceNodeSelector extends React.Component<IProps, IState> {
state: IState = {
parentNodes: [],
};
componentDidMount() {
const parentNodes = this.getParentNodes(this.props.node);
this.setState({
parentNodes,
});
}
// 获取节点的父级节点最多获取5层
getParentNodes = (node: Node) => {
const parentNodes = [];
let currentNode: UnionNode = node;
while (currentNode && parentNodes.length < 5) {
currentNode = currentNode.getParent();
if (currentNode) {
parentNodes.push(currentNode);
}
}
return parentNodes;
};
onSelect = (node: Node) => () => {
if (node && typeof node.select === 'function') {
node.select();
}
};
renderNodes = (node: Node) => {
const nodes = this.state.parentNodes || [];
const children = nodes.map((node, key) => {
return (
<div key={key} onClick={this.onSelect(node)} className="instance-node-selector-node">
<div className="instance-node-selector-node-content">
<Title
className="instance-node-selector-node-title"
title={{
label: node.title,
icon: node.icon,
}}
/>
</div>
</div>
);
});
return children;
};
render() {
const { node } = this.props;
return (
<div className="instance-node-selector">
<Popup
trigger={
<div className="instance-node-selector-current">
<Title
className="instance-node-selector-node-title"
title={{
label: node.title,
icon: node.icon,
}}
/>
</div>
}
triggerType="hover"
>
<div className="instance-node-selector">{this.renderNodes(node)}</div>
</Popup>
</div>
);
}
}

View File

@ -1,15 +1,18 @@
import { isJSBlock, isJSSlot } from '@ali/lowcode-types';
import { isPlainObject } from '@ali/lowcode-utils';
import { globalContext, Editor, registerSetter } from '@ali/lowcode-editor-core';
import { Designer, TransformStage } from '@ali/lowcode-designer';
// import { registerSetters } from '@ali/lowcode-setters';
import Outline from '@ali/lowcode-plugin-outline-pane';
import { globalContext, Editor } from '@ali/lowcode-editor-core';
import { Designer, TransformStage, addBuiltinComponentAction } from '@ali/lowcode-designer';
import { registerSetters } from '@ali/lowcode-setters';
// import Outline from '@ali/lowcode-plugin-outline-pane';
import DesignerPlugin from '@ali/lowcode-plugin-designer';
import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton';
import Preview from '@ali/lowcode-plugin-sample-preview';
// import SourceEditor from '@ali/lowcode-plugin-source-editor';
import { i18nReducer } from './i18n-reducer';
import { InstanceNodeSelector } from './components';
import { Divider } from '@alifd/next';
export const editor = new Editor();
globalContext.register(editor, Editor);
@ -112,3 +115,10 @@ skeleton.add({
// },
// content: SourceEditor,
// });
// 实例节点选择器,线框高亮
addBuiltinComponentAction({
name: 'instance-node-selector',
content: InstanceNodeSelector,
important: true,
});