diff --git a/packages/designer/src/builtins/simulator/host/auxilary/outline-selecting.tsx b/packages/designer/src/builtins/simulator/host/auxilary/outline-selecting.tsx
index 0273daf07..8b148cbfa 100644
--- a/packages/designer/src/builtins/simulator/host/auxilary/outline-selecting.tsx
+++ b/packages/designer/src/builtins/simulator/host/auxilary/outline-selecting.tsx
@@ -8,17 +8,17 @@ import OffsetObserver from '../../../../designer/helper/offset-observer';
import Node from '../../../../designer/document/node/node';
@observer
-export class OutlineSelectingInstance extends Component<{ observed: OffsetObserver; highlight?: boolean }> {
- shouldComponentUpdate() {
- return false;
- }
-
+export class OutlineSelectingInstance extends Component<{
+ observed: OffsetObserver;
+ highlight?: boolean;
+ dragging?: boolean;
+}> {
componentWillUnmount() {
this.props.observed.purge();
}
render() {
- const { observed, highlight } = this.props;
+ const { observed, highlight, dragging } = this.props;
if (!observed.hasOffset) {
return null;
}
@@ -33,6 +33,7 @@ export class OutlineSelectingInstance extends Component<{ observed: OffsetObserv
const className = classNames('lc-outlines lc-outlines-selecting', {
highlight,
+ dragging,
});
return (
@@ -51,6 +52,10 @@ export class OutlineSelectingForNode extends Component<{ node: Node }> {
return this.context;
}
+ get dragging(): boolean {
+ return this.host.designer.dragon.dragging;
+ }
+
@computed get instances() {
return this.host.getComponentInstances(this.props.node);
}
@@ -77,7 +82,7 @@ export class OutlineSelectingForNode extends Component<{ node: Node }> {
if (!observed) {
return null;
}
- return ;
+ return ;
})}
);
@@ -92,12 +97,17 @@ export class OutlineSelecting extends Component {
return this.context;
}
+ get dragging(): boolean {
+ return this.host.designer.dragon.dragging;
+ }
+
@computed get selecting() {
const doc = this.host.document;
if (doc.suspensed) {
return null;
}
- return doc.selection.getNodes();
+ const selection = doc.selection;
+ return this.dragging ? selection.getTopNodes() : selection.getNodes();
}
shouldComponentUpdate() {
diff --git a/packages/designer/src/builtins/simulator/host/auxilary/outlines.less b/packages/designer/src/builtins/simulator/host/auxilary/outlines.less
index fc3e1042e..6a1ba2111 100644
--- a/packages/designer/src/builtins/simulator/host/auxilary/outlines.less
+++ b/packages/designer/src/builtins/simulator/host/auxilary/outlines.less
@@ -22,7 +22,7 @@
&&-hovering {
z-index: 1;
border-style: dashed;
- background: rgba(95, 240, 114, 0.04);
+ background: rgba(0,121,242,.04);
&.x-loop {
border-color: rgba(138, 93, 226, 0.8);
@@ -44,6 +44,7 @@
&&-selecting {
z-index: 2;
+ border-width: 2px;
&.x-loop {
border-color: rgba(147, 112, 219, 1.0);
@@ -67,7 +68,6 @@
&.dragging {
background: rgba(182, 178, 178, 0.8);
border: none;
- pointer-events: all;
}
}
}
diff --git a/packages/designer/src/builtins/simulator/host/host.ts b/packages/designer/src/builtins/simulator/host/host.ts
index ab64b23c9..9fab87841 100644
--- a/packages/designer/src/builtins/simulator/host/host.ts
+++ b/packages/designer/src/builtins/simulator/host/host.ts
@@ -145,9 +145,6 @@ export class SimulatorHost implements ISimulator {
readonly scroller = this.designer.createScroller(this.viewport);
mountViewport(viewport: Element | null) {
- if (!viewport) {
- return;
- }
this.viewport.mount(viewport);
}
@@ -174,10 +171,12 @@ export class SimulatorHost implements ISimulator {
readonly libraryMap: { [key: string]: string } = {};
+ private _iframe?: HTMLIFrameElement;
async mountContentFrame(iframe: HTMLIFrameElement | null) {
- if (!iframe) {
+ if (!iframe || this._iframe === iframe) {
return;
}
+ this._iframe = iframe;
this._contentWindow = iframe.contentWindow!;
@@ -234,63 +233,88 @@ export class SimulatorHost implements ISimulator {
// TODO: think of lock when edit a node
// 事件路由
- doc.addEventListener('mousedown', (downEvent: MouseEvent) => {
- const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
- const node = nodeInst?.node || this.document.rootNode;
- const isMulti = downEvent.metaKey || downEvent.ctrlKey;
- const isLeftButton = downEvent.which === 1 || downEvent.button === 0;
- const checkSelect = (e: MouseEvent) => {
- doc.removeEventListener('mouseup', checkSelect, true);
- if (!isShaken(downEvent, e)) {
- const id = node.id;
- designer.activeTracker.track(node);
- if (isMulti && !isRootNode(node) && selection.has(id)) {
- selection.remove(id);
- } else {
- selection.select(id);
- }
- }
- };
+ doc.addEventListener(
+ 'mousedown',
+ (downEvent: MouseEvent) => {
+ // stop response document focus event
+ downEvent.stopPropagation();
+ downEvent.preventDefault();
- if (isLeftButton && !isRootNode(node)) {
- let nodes: Node[] = [node];
- let ignoreUpSelected = false;
- // 排除根节点拖拽
- selection.remove(this.document.rootNode.id);
- if (isMulti) {
- // multi select mode, directily add
- if (!selection.has(node.id)) {
+ const nodeInst = this.getNodeInstanceFromElement(downEvent.target as Element);
+ const node = nodeInst?.node || this.document.rootNode;
+ const isMulti = downEvent.metaKey || downEvent.ctrlKey;
+ const isLeftButton = downEvent.which === 1 || downEvent.button === 0;
+ const checkSelect = (e: MouseEvent) => {
+ doc.removeEventListener('mouseup', checkSelect, true);
+ if (!isShaken(downEvent, e)) {
+ const id = node.id;
designer.activeTracker.track(node);
- selection.add(node.id);
- ignoreUpSelected = true;
+ if (isMulti && !isRootNode(node) && selection.has(id)) {
+ selection.remove(id);
+ } else {
+ selection.select(id);
+ }
}
- // 获得顶层 nodes
- nodes = selection.getTopNodes();
- } else if (selection.containsNode(node)) {
- nodes = selection.getTopNodes();
- } else {
- // will clear current selection & select dragment in dragstart
- }
- designer.dragon.boost(
- {
- type: DragObjectType.Node,
- nodes,
- },
- downEvent,
- );
- if (ignoreUpSelected) {
- // multi select mode has add selected, should return
- return;
- }
- }
+ };
- doc.addEventListener('mouseup', checkSelect, true);
- });
+ if (isLeftButton && !isRootNode(node)) {
+ let nodes: Node[] = [node];
+ let ignoreUpSelected = false;
+ if (isMulti) {
+ // multi select mode, directily add
+ if (!selection.has(node.id)) {
+ designer.activeTracker.track(node);
+ selection.add(node.id);
+ ignoreUpSelected = true;
+ }
+ selection.remove(this.document.rootNode.id);
+ // 获得顶层 nodes
+ nodes = selection.getTopNodes();
+ } else if (selection.containsNode(node, true)) {
+ nodes = selection.getTopNodes();
+ } else {
+ // will clear current selection & select dragment in dragstart
+ }
+ designer.dragon.boost(
+ {
+ type: DragObjectType.Node,
+ nodes,
+ },
+ downEvent,
+ );
+ if (ignoreUpSelected) {
+ // multi select mode has add selected, should return
+ return;
+ }
+ }
+
+ doc.addEventListener('mouseup', checkSelect, true);
+ },
+ true,
+ );
+
+ doc.addEventListener(
+ 'click',
+ e => {
+ // stop response document click event
+ e.preventDefault();
+ e.stopPropagation();
+ // todo: catch link redirect
+ },
+ true,
+ );
// cause edit
- doc.addEventListener('dblclick', (e: MouseEvent) => {
- // TODO:
- });
+ doc.addEventListener(
+ 'dblclick',
+ (e: MouseEvent) => {
+ // stop response document dblclick event
+ e.stopPropagation();
+ e.preventDefault();
+ // todo: quick editing
+ },
+ true,
+ );
}
private disableHovering?: () => void;
@@ -443,18 +467,28 @@ export class SimulatorHost implements ISimulator {
let last: { x: number; y: number; r: number; b: number } | undefined;
let computed = false;
const elems = elements.slice();
+ const commonParent: Element | null = null;
while (true) {
if (!rects || rects.length < 1) {
const elem = elems.pop();
if (!elem) {
break;
}
+ /*
+ if (!commonParent) {
+ commonParent = elem.parentElement;
+ } else if (elem.parentElement !== commonParent) {
+ continue;
+ }*/
rects = renderer.getClientRects(elem);
}
const rect = rects.pop();
if (!rect) {
break;
}
+ if (rect.width === 0 && rect.height === 0) {
+ continue;
+ }
if (!last) {
last = {
x: rect.left,
@@ -677,8 +711,10 @@ export class SimulatorHost implements ISimulator {
}
const target = dropTarget;
- const targetInstance = e.targetInstance as ReactInstance;
+ // FIXME: e.target is #document, etc., does not has e.targetInstance
+
+ const targetInstance = e.targetInstance as ReactInstance;
const parentInstance = this.getClosestNodeInstance(targetInstance, target.id);
const edge = this.computeComponentInstanceRect(parentInstance?.instance as any);
diff --git a/packages/designer/src/builtins/simulator/host/viewport.ts b/packages/designer/src/builtins/simulator/host/viewport.ts
index 3ae3d41df..a22f87704 100644
--- a/packages/designer/src/builtins/simulator/host/viewport.ts
+++ b/packages/designer/src/builtins/simulator/host/viewport.ts
@@ -25,7 +25,7 @@ export default class Viewport implements IViewport {
private viewportElement?: Element;
mount(viewportElement: Element | null) {
- if (!viewportElement) {
+ if (!viewportElement || this.viewportElement === viewportElement) {
return;
}
this.viewportElement = viewportElement;
@@ -54,7 +54,7 @@ export default class Viewport implements IViewport {
/**
* 缩放比例
*/
- get scale(): number {
+ @computed get scale(): number {
if (!this.rect || this.contentWidth === AutoFit) {
return 1;
}
@@ -63,14 +63,14 @@ export default class Viewport implements IViewport {
@obx.ref private _contentWidth: number | AutoFit = AutoFit;
- get contentHeight(): number | AutoFit {
+ @computed get contentHeight(): number | AutoFit {
if (!this.rect || this.scale === 1) {
return AutoFit;
}
return this.height / this.scale;
}
- get contentWidth(): number | AutoFit {
+ @computed get contentWidth(): number | AutoFit {
if (!this.rect || (this._contentWidth !== AutoFit && this._contentWidth <= this.width)) {
return AutoFit;
}
@@ -98,7 +98,7 @@ export default class Viewport implements IViewport {
return this._scrollTarget;
}
- @obx private _scrolling: boolean = false;
+ @obx private _scrolling = false;
get scrolling(): boolean {
return this._scrolling;
}
@@ -120,6 +120,7 @@ export default class Viewport implements IViewport {
this._scrolling = false;
}, 80);
});
+ target.addEventListener('resize', () => this.touch());
this._scrollTarget = scrollTarget;
}
diff --git a/packages/designer/src/designer/designer.less b/packages/designer/src/designer/designer.less
index 7f73d92b1..9c3a7dfa9 100644
--- a/packages/designer/src/designer/designer.less
+++ b/packages/designer/src/designer/designer.less
@@ -8,7 +8,9 @@
--font-size-btn-medium: @fontSize-4;
--font-size-btn-small: @fontSize-5;
- --color-brand-light: rgb(102, 188, 92);
+ --color-brand: #006cff;
+ --color-brand-light: #197aff;
+ --color-brand-dark: #0060e5;
--color-icon: rgba(255, 255, 255, 0.8);
--color-visited: rgba(179, 182, 201, 0.4);
--color-actived: #498ee6;
diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts
index 10b802d98..73c479f26 100644
--- a/packages/designer/src/designer/designer.ts
+++ b/packages/designer/src/designer/designer.ts
@@ -61,9 +61,13 @@ export default class Designer {
this.dragon.onDragstart(e => {
this.hovering.enable = false;
const { dragObject } = e;
- if (isDragNodeObject(dragObject) && dragObject.nodes.length === 1) {
- // ensure current selecting
- dragObject.nodes[0].select();
+ if (isDragNodeObject(dragObject)) {
+ if (dragObject.nodes.length === 1) {
+ // ensure current selecting
+ dragObject.nodes[0].select();
+ }
+ } else {
+ this.currentSelection?.clear();
}
if (this.props?.onDragstart) {
this.props.onDragstart(e);
diff --git a/packages/designer/src/designer/document/node/node.ts b/packages/designer/src/designer/document/node/node.ts
index 2bdc4106e..1c46e1f2e 100644
--- a/packages/designer/src/designer/document/node/node.ts
+++ b/packages/designer/src/designer/document/node/node.ts
@@ -374,7 +374,7 @@ export default class Node {
* 2 thisNode before or after otherNode
* 0 thisNode same as otherNode
*/
- comparePosition(otherNode: Node): number {
+ comparePosition(otherNode: Node): PositionNO {
return comparePosition(this, otherNode);
}
@@ -455,31 +455,37 @@ export function contains(node1: Node, node2: Node): boolean {
// 8 node1 contained_by node2
// 2 node1 before or after node2
// 0 node1 same as node2
-export function comparePosition(node1: Node, node2: Node): number {
+export enum PositionNO {
+ Contains = 16,
+ ContainedBy = 8,
+ BeforeOrAfter = 2,
+ TheSame = 0,
+}
+export function comparePosition(node1: Node, node2: Node): PositionNO {
if (node1 === node2) {
- return 0;
+ return PositionNO.TheSame;
}
const l1 = node1.zLevel;
const l2 = node2.zLevel;
if (l1 === l2) {
- return 2;
+ return PositionNO.BeforeOrAfter;
}
let p: any;
- if (l1 > l2) {
+ if (l1 < l2) {
p = getZLevelTop(node2, l1);
if (p && p === node1) {
- return 16;
+ return PositionNO.Contains;
}
- return 2;
+ return PositionNO.BeforeOrAfter;
}
p = getZLevelTop(node1, l2);
if (p && p === node2) {
- return 8;
+ return PositionNO.ContainedBy;
}
- return 2;
+ return PositionNO.BeforeOrAfter;
}
export function insertChild(container: NodeParent, thing: Node | NodeData, at?: number | null, copy?: boolean): Node {
diff --git a/packages/designer/src/designer/document/node/props/prop-stash.ts b/packages/designer/src/designer/document/node/props/prop-stash.ts
index 2618cd804..84f0f8759 100644
--- a/packages/designer/src/designer/document/node/props/prop-stash.ts
+++ b/packages/designer/src/designer/document/node/props/prop-stash.ts
@@ -23,7 +23,7 @@ export default class PropStash implements IPropParent {
}
const pending: Prop[] = [];
for (const prop of this.space) {
- if (!prop.isUnset()) {
+ if (!prop.isUnset() && !prop.isVirtual()) {
this.space.delete(prop);
pending.push(prop);
}
diff --git a/packages/designer/src/designer/document/node/props/prop.ts b/packages/designer/src/designer/document/node/props/prop.ts
index a657216f0..2162cd3ea 100644
--- a/packages/designer/src/designer/document/node/props/prop.ts
+++ b/packages/designer/src/designer/document/node/props/prop.ts
@@ -225,6 +225,10 @@ export default class Prop implements IPropParent {
return this._type === 'unset';
}
+ isVirtual() {
+ return typeof this.key === 'string' && this.key.charAt(0) === '!';
+ }
+
// TODO: improve this logic
compare(other: Prop | null): number {
if (!other || other.isUnset()) {
diff --git a/packages/designer/src/designer/document/selection.ts b/packages/designer/src/designer/document/selection.ts
index 117351ebf..c481b1bce 100644
--- a/packages/designer/src/designer/document/selection.ts
+++ b/packages/designer/src/designer/document/selection.ts
@@ -1,4 +1,4 @@
-import Node, { comparePosition } from './node/node';
+import Node, { comparePosition, PositionNO } from './node/node';
import { obx } from '@recore/obx';
import DocumentModel from './document-model';
import { EventEmitter } from 'events';
@@ -97,9 +97,12 @@ export class Selection {
/**
* 选区是否包含节点
*/
- containsNode(node: Node) {
+ containsNode(node: Node, excludeRoot = false) {
for (const id of this._selected) {
const parent = this.doc.getNode(id);
+ if (excludeRoot && parent === this.doc.rootNode) {
+ continue;
+ }
if (parent?.contains(node)) {
return true;
}
@@ -124,11 +127,12 @@ export class Selection {
/**
* 获取顶层选区节点, 场景:拖拽时,建立蒙层,只蒙在最上层
*/
- getTopNodes() {
+ getTopNodes(includeRoot = false) {
const nodes = [];
for (const id of this._selected) {
const node = this.doc.getNode(id);
- if (!node) {
+ // 排除根节点
+ if (!node || (!includeRoot && node === this.doc.rootNode)) {
continue;
}
let i = nodes.length;
@@ -136,12 +140,12 @@ export class Selection {
while (i-- > 0) {
const n = comparePosition(nodes[i], node);
// nodes[i] contains node
- if (n === 16 || n === 0) {
+ if (n === PositionNO.Contains || n === PositionNO.TheSame) {
isTop = false;
break;
}
// node contains nodes[i], delete nodes[i]
- if (n === 8) {
+ if (n === PositionNO.ContainedBy) {
nodes.splice(i, 1);
}
}
diff --git a/packages/editor/src/config/assets.js b/packages/editor/src/config/assets.js
index b4fa7e612..954ac79e6 100644
--- a/packages/editor/src/config/assets.js
+++ b/packages/editor/src/config/assets.js
@@ -28,6 +28,10 @@ export default {
name: 'type',
propType: 'string'
},
+ {
+ name: 'onClick',
+ propType: 'func'
+ },
{
name: 'children',
propType: 'string'
@@ -66,6 +70,22 @@ export default {
{
name: 'placeholder',
propType: 'string'
+ },
+ {
+ name: 'onChange',
+ propType: 'func'
+ },
+ {
+ name: 'onKeyDown',
+ propType: 'func'
+ },
+ {
+ name: 'onFocus',
+ propType: 'func'
+ },
+ {
+ name: 'onBlur',
+ propType: 'func'
}
],
},
@@ -83,7 +103,11 @@ export default {
{
name: 'device',
propType: 'string'
- }
+ },
+ {
+ name: 'onChange',
+ propType: 'func'
+ },
],
},
'Form.Item': {
@@ -126,6 +150,26 @@ export default {
{
name: 'defaultValue',
propType: 'number'
+ },
+ {
+ name: 'onChange',
+ propType: 'func'
+ },
+ {
+ name: 'onKeyDown',
+ propType: 'func'
+ },
+ {
+ name: 'onFocus',
+ propType: 'func'
+ },
+ {
+ name: 'onBlur',
+ propType: 'func'
+ },
+ {
+ name: 'onCorrect',
+ propType: 'func'
}
],
},
@@ -151,6 +195,38 @@ export default {
{
name: 'placeholder',
propType: 'string'
+ },
+ {
+ name: 'onChange',
+ propType: 'func'
+ },
+ {
+ name: 'onVisibleChange',
+ propType: 'func'
+ },
+ {
+ name: 'onToggleHighlightItem',
+ propType: 'func'
+ },
+ {
+ name: 'onSearch',
+ propType: 'func'
+ },
+ {
+ name: 'onSearchClear',
+ propType: 'func'
+ },
+ {
+ name: 'onRemove',
+ propType: 'func'
+ },
+ {
+ name: 'onFocus',
+ propType: 'func'
+ },
+ {
+ name: 'onBlur',
+ propType: 'func'
}
],
}
diff --git a/packages/plugin-settings/src/builtin-setters/events-setter/index.tsx b/packages/plugin-settings/src/builtin-setters/events-setter/index.tsx
index 34e7f482d..6de0defb7 100644
--- a/packages/plugin-settings/src/builtin-setters/events-setter/index.tsx
+++ b/packages/plugin-settings/src/builtin-setters/events-setter/index.tsx
@@ -1,5 +1,6 @@
import { Component, isValidElement, ReactElement, ReactNode } from 'react';
import { Radio, Menu, Table, Icon, Dialog } from '@alifd/next';
+import {SettingField} from './main';
import nativeEvents from './native-events';
import './style.less';
@@ -19,7 +20,10 @@ const DEFINITION_EVENT_TYPE = {
LIFE_CYCLE_EVENT: 'lifeCycleEvent',
};
-export default class EventsSetter extends Component<{}> {
+export default class EventsSetter extends Component<{
+ value: any[];
+ onChange: (eventList: any[]) => void;
+}> {
state = {
showEventList: false,
eventBtns: [],
@@ -34,6 +38,7 @@ export default class EventsSetter extends Component<{}> {
};
componentWillMount() {
+ console.log(this.props);
this.initEventBtns();
this.initEventList();
}
@@ -42,8 +47,7 @@ export default class EventsSetter extends Component<{}> {
* 初始化事件按钮
*/
initEventBtns() {
- const { prop } = this.props;
- const { definition } = prop.extraProps;
+ const { definition } = this.props;
let isRoot = false;
definition.map(item => {
if (item.type === DEFINITION_EVENT_TYPE.LIFE_CYCLE_EVENT) {
@@ -73,7 +77,7 @@ export default class EventsSetter extends Component<{}> {
}
initEventList() {
- const { definition } = this.props.prop.extraProps;
+ const { definition } = this.props;
let nativeEventList = [];
definition.map(item => {
if (item.type === DEFINITION_EVENT_TYPE.EVENTS) {
@@ -229,14 +233,18 @@ export default class EventsSetter extends Component<{}> {
};
submitDialog = (relatedEventName: String) => {
- const { bindEventName } = this.state;
- const { eventDataList } = this.state;
+ const { bindEventName,eventDataList} = this.state;
eventDataList.map(item => {
if (item.name === bindEventName) {
item.relatedEventName = relatedEventName;
}
});
+ debugger;
+ this.props.onChange(eventDataList);
+ // field.setValue(eventDataList);
+
+
this.closeDialog();
};
@@ -270,7 +278,7 @@ export default class EventsSetter extends Component<{}> {
{selectType && selectType != EVENT_CONTENTS.NATIVE_EVENT && (