-
-
+
+
+
);
diff --git a/packages/designer/src/builtins/simulator/host/auxilary/insertion.less b/packages/designer/src/builtins/simulator/host/bem-tools/insertion.less
similarity index 100%
rename from packages/designer/src/builtins/simulator/host/auxilary/insertion.less
rename to packages/designer/src/builtins/simulator/host/bem-tools/insertion.less
diff --git a/packages/designer/src/builtins/simulator/host/auxilary/insertion.tsx b/packages/designer/src/builtins/simulator/host/bem-tools/insertion.tsx
similarity index 97%
rename from packages/designer/src/builtins/simulator/host/auxilary/insertion.tsx
rename to packages/designer/src/builtins/simulator/host/bem-tools/insertion.tsx
index a61d2fc74..f36993253 100644
--- a/packages/designer/src/builtins/simulator/host/auxilary/insertion.tsx
+++ b/packages/designer/src/builtins/simulator/host/bem-tools/insertion.tsx
@@ -1,6 +1,5 @@
import { Component } from 'react';
-import { computed } from '@recore/obx';
-import { observer } from '@recore/obx-react';
+import { computed, observer } from '../../../../../../globals';
import { SimulatorContext } from '../context';
import { SimulatorHost } from '../host';
import Location, {
diff --git a/packages/designer/src/builtins/simulator/host/host-view.tsx b/packages/designer/src/builtins/simulator/host/host-view.tsx
index 0ab951d69..22e4e8044 100644
--- a/packages/designer/src/builtins/simulator/host/host-view.tsx
+++ b/packages/designer/src/builtins/simulator/host/host-view.tsx
@@ -1,9 +1,9 @@
import { Component } from 'react';
-import { observer } from '@recore/obx-react';
+import { observer } from '../../../../../globals';
import { SimulatorHost, SimulatorProps } from './host';
import DocumentModel from '../../../designer/document/document-model';
import { SimulatorContext } from './context';
-import { AuxiliaryView } from './auxilary';
+import { BemTools } from './bem-tools';
import './host.less';
/*
@@ -65,7 +65,7 @@ class Canvas extends Component {
return (
sim.mountViewport(elmt)} className="lc-simulator-canvas-viewport">
-
+
diff --git a/packages/designer/src/builtins/simulator/host/host.ts b/packages/designer/src/builtins/simulator/host/host.ts
index 2b81ede54..d8feb15ea 100644
--- a/packages/designer/src/builtins/simulator/host/host.ts
+++ b/packages/designer/src/builtins/simulator/host/host.ts
@@ -1,4 +1,4 @@
-import { obx, autorun, computed } from '@recore/obx';
+import { obx, autorun, computed } from '../../../../../globals';
import { ISimulator, Component, NodeInstance } from '../../../designer/simulator';
import Viewport from './viewport';
import { createSimulator } from './create-simulator';
@@ -28,12 +28,11 @@ import {
Rect,
CanvasPoint,
} from '../../../designer/helper/location';
-import { isNodeSchema, NodeSchema } from '../../../designer/schema';
-import { ComponentMetadata } from '../../../designer/component-meta';
import { ReactInstance } from 'react';
import { isRootNode } from '../../../designer/document/node/root-node';
import { parseProps } from '../utils/parse-props';
import { isElement } from '../../../utils/is-element';
+import { ComponentMetadata, NodeSchema, isNodeSchema } from '../../../../../globals';
export interface LibraryItem {
package: string;
@@ -464,24 +463,17 @@ export class SimulatorHost implements ISimulator
{
return null;
}
+ let elems = elements.slice();
+ if (selector) {
+ const matched = getMatched(elems, selector);
+ if (!matched) {
+ return null;
+ }
+ elems = [matched];
+ }
let rects: DOMRect[] | undefined;
let last: { x: number; y: number; r: number; b: number } | undefined;
let computed = false;
- const elems = selector
- ? elements
- .map(elem => {
- if (isElement(elem)) {
- // TODO: if has selector use exact match
- if (elem.matches(selector)) {
- return elem;
- }
-
- return elem.querySelector(selector);
- }
- return null;
- })
- .filter(Boolean)
- : elements.slice();
while (true) {
if (!rects || rects.length < 1) {
const elem = elems.pop();
@@ -1057,3 +1049,19 @@ function isNearAfter(point: CanvasPoint, rect: Rect, inline: boolean) {
}
return Math.abs(point.canvasY - rect.top) > Math.abs(point.canvasY - rect.bottom);
}
+
+function getMatched(elements: Array, selector: string): Element | null {
+ let firstQueried: Element | null = null;
+ for (const elem of elements) {
+ if (isElement(elem)) {
+ if (elem.matches(selector)) {
+ return elem;
+ }
+
+ if (!firstQueried) {
+ firstQueried = elem.querySelector(selector);
+ }
+ }
+ }
+ return firstQueried;
+}
diff --git a/packages/designer/src/builtins/simulator/host/resource-consumer.ts b/packages/designer/src/builtins/simulator/host/resource-consumer.ts
index b68384812..8731e1afe 100644
--- a/packages/designer/src/builtins/simulator/host/resource-consumer.ts
+++ b/packages/designer/src/builtins/simulator/host/resource-consumer.ts
@@ -1,5 +1,5 @@
import { SimulatorRenderer } from '../renderer/renderer';
-import { autorun, obx } from '@recore/obx';
+import { autorun, obx } from '../../../../../globals';
import { SimulatorHost } from './host';
import { EventEmitter } from 'events';
@@ -34,7 +34,6 @@ export default class ResourceConsumer {
});
}
-
private _consuming?: () => void;
consume(consumerOrRenderer: SimulatorRenderer | ((data: T) => any)) {
if (this._consuming) {
@@ -48,7 +47,7 @@ export default class ResourceConsumer {
}
const rendererConsumer = this.consumer!;
- consumer = (data) => rendererConsumer(consumerOrRenderer, data);
+ consumer = data => rendererConsumer(consumerOrRenderer, data);
} else {
consumer = consumerOrRenderer;
}
@@ -76,14 +75,14 @@ export default class ResourceConsumer {
this.emitter.removeAllListeners();
}
- private _firstConsumed: boolean = false;
+ private _firstConsumed = false;
private resovleFirst?: () => void;
waitFirstConsume(): Promise {
if (this._firstConsumed) {
return Promise.resolve();
}
- return new Promise((resolve) => {
+ return new Promise(resolve => {
this.resovleFirst = resolve;
});
}
diff --git a/packages/designer/src/builtins/simulator/host/viewport.ts b/packages/designer/src/builtins/simulator/host/viewport.ts
index a22f87704..39208be2b 100644
--- a/packages/designer/src/builtins/simulator/host/viewport.ts
+++ b/packages/designer/src/builtins/simulator/host/viewport.ts
@@ -1,4 +1,4 @@
-import { obx, computed } from '@recore/obx';
+import { obx, computed } from '../../../../../globals';
import { Point } from '../../../designer/helper/location';
import { ScrollTarget } from '../../../designer/helper/scroller';
import { AutoFit, IViewport } from '../../../designer/simulator';
diff --git a/packages/designer/src/builtins/simulator/renderer/renderer.ts b/packages/designer/src/builtins/simulator/renderer/renderer.ts
index 26c246399..818825bf2 100644
--- a/packages/designer/src/builtins/simulator/renderer/renderer.ts
+++ b/packages/designer/src/builtins/simulator/renderer/renderer.ts
@@ -3,7 +3,6 @@ import { render as reactRender } from 'react-dom';
import { host } from './host';
import SimulatorRendererView from './renderer-view';
import { computed, obx } from '@recore/obx';
-import { RootSchema, NpmInfo } from '../../../designer/schema';
import { getClientRects } from '../../../utils/get-client-rects';
import { Asset } from '../utils/asset';
import loader from '../utils/loader';
@@ -13,6 +12,7 @@ import { NodeInstance } from '../../../designer/simulator';
import { isElement } from '../../../utils/is-element';
import cursor from '../../../designer/helper/cursor';
import { setNativeSelection } from '../../../designer/helper/navtive-selection';
+import { RootSchema, NpmInfo } from '../../../../../globals/src';
export class SimulatorRenderer {
readonly isSimulatorRenderer = true;
diff --git a/packages/designer/src/builtins/simulator/utils/parse-props.ts b/packages/designer/src/builtins/simulator/utils/parse-props.ts
index 5d314c8d1..90c0ddf06 100644
--- a/packages/designer/src/builtins/simulator/utils/parse-props.ts
+++ b/packages/designer/src/builtins/simulator/utils/parse-props.ts
@@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import { isValidElement } from 'react';
import { isElement } from '../../../utils/is-element';
-import { PropType, PropConfig } from '../../../designer/prop-config';
+import { PropConfig } from '../../../../../globals';
export const primitiveTypes = [
'string',
diff --git a/packages/designer/src/designer/component-meta.ts b/packages/designer/src/designer/component-meta.ts
index 0ec9329f5..b2b86f1dc 100644
--- a/packages/designer/src/designer/component-meta.ts
+++ b/packages/designer/src/designer/component-meta.ts
@@ -1,96 +1,24 @@
-import { ReactNode, ReactElement, ComponentType, createElement } from 'react';
import Node, { NodeParent } from './document/node/node';
-import { NodeData, NodeSchema } from './schema';
-import { PropConfig } from './prop-config';
import Designer from './designer';
-import { Remove, Clone } from '../../../globals';
-import { computed } from '@recore/obx';
+import {
+ IconRemove,
+ IconClone,
+ IconPage,
+ IconContainer,
+ IconComponent,
+ ComponentMetadata,
+ NpmInfo,
+ NodeData,
+ NodeSchema,
+ ComponentAction,
+ TitleContent,
+ TransformedComponentMetadata,
+ getRegisteredMetadataTransducers,
+ registerMetadataTransducer,
+ computed,
+} from '../../../globals';
import { intl } from '../locale';
-export interface NestingRule {
- childWhitelist?: string[];
- parentWhitelist?: string[];
-}
-
-export interface Configure {
- props?: any[];
- styles?: object;
- events?: object;
- component?: {
- isContainer?: boolean;
- isModal?: boolean;
- descriptor?: string;
- nestingRule?: NestingRule;
- rectSelector?: string;
- // copy,move,delete
- disableBehaviors?: string[];
- actions?: ComponentAction[];
- };
-}
-
-export interface ContentObject {
- // 图标
- icon?: string | ComponentType | ReactElement;
- // 描述
- description?: string;
- // 执行动作
- action?: (node: Node) => void;
-}
-
-export interface ComponentAction {
- // behaviorName
- name: string;
- // 菜单名称
- content: string | ReactNode | ContentObject;
- // 子集
- items?: ComponentAction[];
- // 不显示
- condition?: boolean | ((node: Node) => boolean);
- // 显示在工具条上
- important?: boolean;
-}
-
-export function isContentObject(obj: any): obj is ContentObject {
- return obj && typeof obj === 'object';
-}
-
-export interface ComponentMetadata {
- componentName: string;
- /**
- * unique id
- */
- uri?: string;
- /**
- * title or description
- */
- title?: string;
- /**
- * svg icon for component
- */
- icon?: string | ReactNode;
- tags?: string[];
- description?: string;
- docUrl?: string;
- screenshot?: string;
- devMode?: 'procode' | 'lowcode';
- npm?: {
- package: string;
- exportName: string;
- subName: string;
- main: string;
- destructuring: boolean;
- version: string;
- };
- props?: PropConfig[];
- configure?: any[] | Configure;
-}
-
-interface TransformedComponentMetadata extends ComponentMetadata {
- configure: Configure & {
- combined?: any[];
- };
-}
-
function ensureAList(list?: string | string[]): string[] | null {
if (!list) {
return null;
@@ -136,22 +64,16 @@ function npmToURI(npm: {
return uri;
}
-export type MetadataTransducer = (prev: TransformedComponentMetadata) => TransformedComponentMetadata;
-const metadataTransducers: MetadataTransducer[] = [];
-
-// propsParser
-//
-
-export function registerMetadataTransducer(transducer: MetadataTransducer) {
- metadataTransducers.push(transducer);
-}
-
export class ComponentMeta {
readonly isComponentMeta = true;
private _uri?: string;
get uri(): string {
return this._uri!;
}
+ private _npm?: NpmInfo;
+ get npm() {
+ return this._npm;
+ }
private _componentName?: string;
get componentName(): string {
return this._componentName!;
@@ -172,10 +94,6 @@ export class ComponentMeta {
get rectSelector(): string | undefined {
return this._rectSelector;
}
- private _acceptable?: boolean;
- get acceptable(): boolean {
- return this._acceptable!;
- }
private _transformedMetadata?: TransformedComponentMetadata;
get configure() {
const config = this._transformedMetadata?.configure;
@@ -185,20 +103,30 @@ export class ComponentMeta {
private parentWhitelist?: string[] | null;
private childWhitelist?: string[] | null;
+ private _title?: TitleContent;
get title() {
- return this._metadata.title || this.componentName;
+ return this._title || this.componentName;
}
get icon() {
- return this._metadata.icon;
+ return (
+ this._transformedMetadata?.icon ||
+ (this.componentName === 'Page' ? IconPage : this.isContainer ? IconContainer : IconComponent)
+ );
}
- constructor(readonly designer: Designer, private _metadata: ComponentMetadata) {
- this.parseMetadata(_metadata);
+ private _acceptable?: boolean;
+ get acceptable(): boolean {
+ return this._acceptable!;
+ }
+
+ constructor(readonly designer: Designer, metadata: ComponentMetadata) {
+ this.parseMetadata(metadata);
}
private parseMetadata(metadta: ComponentMetadata) {
- const { componentName, uri, npm, props } = metadta;
+ const { componentName, uri, npm } = metadta;
+ this._npm = npm;
this._uri = uri || (npm ? npmToURI(npm) : componentName);
this._componentName = componentName;
@@ -206,6 +134,15 @@ export class ComponentMeta {
// 额外转换逻辑
this._transformedMetadata = this.transformMetadata(metadta);
+ const title = this._transformedMetadata.title;
+ if (title && typeof title === 'string') {
+ this._title = {
+ type: 'i18n',
+ 'en-US': this.componentName,
+ 'zh-CN': title,
+ };
+ }
+
const { configure = {} } = this._transformedMetadata;
this._acceptable = false;
@@ -227,7 +164,7 @@ export class ComponentMeta {
}
private transformMetadata(metadta: ComponentMetadata): TransformedComponentMetadata {
- const result = metadataTransducers.reduce((prevMetadata, current) => {
+ const result = getRegisteredMetadataTransducers().reduce((prevMetadata, current) => {
return current(prevMetadata);
}, preprocessMetadata(metadta));
@@ -253,13 +190,12 @@ export class ComponentMeta {
return actions;
}
- set metadata(metadata: ComponentMetadata) {
- this._metadata = metadata;
+ setMetadata(metadata: ComponentMetadata) {
this.parseMetadata(metadata);
}
- get metadata(): ComponentMetadata {
- return this._metadata;
+ getMetadata(): TransformedComponentMetadata {
+ return this._transformedMetadata!;
}
checkNestingUp(my: Node | NodeData, parent: NodeParent) {
@@ -340,7 +276,7 @@ const builtinComponentActions: ComponentAction[] = [
{
name: 'remove',
content: {
- icon: Remove,
+ icon: IconRemove,
description: intl('remove'),
action(node: Node) {
node.remove();
@@ -351,7 +287,7 @@ const builtinComponentActions: ComponentAction[] = [
{
name: 'copy',
content: {
- icon: Clone,
+ icon: IconClone,
description: intl('copy'),
action(node: Node) {
// node.remove();
diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts
index 732b48fe2..34eeeaca7 100644
--- a/packages/designer/src/designer/designer.ts
+++ b/packages/designer/src/designer/designer.ts
@@ -1,8 +1,6 @@
-import { ComponentType as ReactComponentType } from 'react';
-import { obx, computed, autorun } from '@recore/obx';
+import { ComponentType } from 'react';
import BuiltinSimulatorView from '../builtins/simulator';
import Project from './project';
-import { ProjectSchema, NpmInfo } from './schema';
import Dragon, { isDragNodeObject, isDragNodeDataObject, LocateEvent, DragObject } from './helper/dragon';
import ActiveTracker from './helper/active-tracker';
import Hovering from './helper/hovering';
@@ -10,11 +8,12 @@ import Location, { LocationData, isLocationChildrenDetail } from './helper/locat
import DocumentModel from './document/document-model';
import Node, { insertChildren } from './document/node/node';
import { isRootNode } from './document/node/root-node';
-import { ComponentMetadata, ComponentMeta, ComponentAction } from './component-meta';
+import { ComponentMeta } from './component-meta';
import Scroller, { IScrollable } from './helper/scroller';
import { INodeSelector } from './simulator';
import OffsetObserver, { createOffsetObserver } from './helper/offset-observer';
import { EventEmitter } from 'events';
+import { ProjectSchema, ComponentMetadata, ComponentAction, NpmInfo, obx, computed, autorun } from '../../../globals';
export interface DesignerProps {
className?: string;
@@ -22,8 +21,8 @@ export interface DesignerProps {
defaultSchema?: ProjectSchema;
hotkeys?: object;
simulatorProps?: object | ((document: DocumentModel) => object);
- simulatorComponent?: ReactComponentType;
- dragGhostComponent?: ReactComponentType;
+ simulatorComponent?: ComponentType;
+ dragGhostComponent?: ComponentType;
suspensed?: boolean;
componentMetadatas?: ComponentMetadata[];
eventPipe?: EventEmitter;
@@ -165,6 +164,9 @@ export default class Designer {
*/
createLocation(locationData: LocationData): Location {
const loc = new Location(locationData);
+ if (this._dropLocation && this._dropLocation.document !== loc.document) {
+ this._dropLocation.document.internalSetDropLocation(null);
+ }
this._dropLocation = loc;
loc.document.internalSetDropLocation(loc);
this.activeTracker.track({ node: loc.target, detail: loc.detail });
@@ -258,9 +260,9 @@ export default class Designer {
return this.props ? this.props[key] : null;
}
- @obx.ref private _simulatorComponent?: ReactComponentType;
+ @obx.ref private _simulatorComponent?: ComponentType;
- @computed get simulatorComponent(): ReactComponentType {
+ @computed get simulatorComponent(): ComponentType {
return this._simulatorComponent || BuiltinSimulatorView;
}
@@ -300,12 +302,12 @@ export default class Designer {
const key = data.componentName;
let meta = this._componentMetasMap.get(key);
if (meta) {
- meta.metadata = data;
+ meta.setMetadata(data);
} else {
meta = this._lostComponentMetasMap.get(key);
if (meta) {
- meta.metadata = data;
+ meta.setMetadata(data);
this._lostComponentMetasMap.delete(key);
} else {
meta = new ComponentMeta(this, data);
@@ -342,7 +344,9 @@ export default class Designer {
@computed get componentsMap(): { [key: string]: NpmInfo } {
const maps: any = {};
this._componentMetasMap.forEach((config, key) => {
- maps[key] = config.metadata.npm;
+ if (config.npm) {
+ maps[key] = config.npm;
+ }
});
return maps;
}
diff --git a/packages/designer/src/designer/document/document-model.ts b/packages/designer/src/designer/document/document-model.ts
index ca0726b76..7a244bd54 100644
--- a/packages/designer/src/designer/document/document-model.ts
+++ b/packages/designer/src/designer/document/document-model.ts
@@ -1,14 +1,22 @@
import Project from '../project';
-import { RootSchema, NodeData, isDOMText, isJSExpression, NodeSchema } from '../schema';
import Node, { isNodeParent, insertChildren, insertChild, NodeParent } from './node/node';
import { Selection } from './selection';
import RootNode from './node/root-node';
-import { ISimulator, Component } from '../simulator';
-import { computed, obx, autorun } from '@recore/obx';
+import { ISimulator } from '../simulator';
import Location from '../helper/location';
import { ComponentMeta } from '../component-meta';
import History from '../helper/history';
import Prop from './node/props/prop';
+import {
+ RootSchema,
+ NodeData,
+ isJSExpression,
+ isDOMText,
+ NodeSchema,
+ computed,
+ obx,
+ autorun,
+} from '../../../../globals';
export default class DocumentModel {
/**
diff --git a/packages/designer/src/designer/document/document-view.tsx b/packages/designer/src/designer/document/document-view.tsx
index f4fab1e7c..859d00186 100644
--- a/packages/designer/src/designer/document/document-view.tsx
+++ b/packages/designer/src/designer/document/document-view.tsx
@@ -1,6 +1,6 @@
import { Component } from 'react';
import DocumentModel from './document-model';
-import { observer } from '@recore/obx-react';
+import { observer } from '../../../../globals';
import classNames from 'classnames';
@observer
diff --git a/packages/designer/src/designer/document/node/node-children.ts b/packages/designer/src/designer/document/node/node-children.ts
index 7ae7b9d7b..232ef10fe 100644
--- a/packages/designer/src/designer/document/node/node-children.ts
+++ b/packages/designer/src/designer/document/node/node-children.ts
@@ -1,6 +1,5 @@
import Node, { NodeParent } from './node';
-import { NodeData, isNodeSchema } from '../../schema';
-import { obx, computed } from '@recore/obx';
+import { NodeData, isNodeSchema, obx, computed } from '../../../../../globals';
export default class NodeChildren {
@obx.val private children: Node[];
@@ -20,7 +19,7 @@ export default class NodeChildren {
return this.children.map(node => node.export(serialize));
}
- import(data?: NodeData | NodeData[], checkId: boolean = false) {
+ import(data?: NodeData | NodeData[], checkId = false) {
data = data ? (Array.isArray(data) ? data : [data]) : [];
const originChildren = this.children.slice();
@@ -59,10 +58,14 @@ export default class NodeChildren {
return this.size < 1;
}
+ @computed notEmpty() {
+ return this.size > 0;
+ }
+
/**
* 删除一个节点
*/
- delete(node: Node, purge: boolean = false): boolean {
+ delete(node: Node, purge = false): boolean {
const i = this.children.indexOf(node);
if (i < 0) {
return false;
diff --git a/packages/designer/src/designer/document/node/node.ts b/packages/designer/src/designer/document/node/node.ts
index 1c46e1f2e..035e68d77 100644
--- a/packages/designer/src/designer/document/node/node.ts
+++ b/packages/designer/src/designer/document/node/node.ts
@@ -1,10 +1,19 @@
-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 { ComponentMeta } from '../../component-meta';
+import {
+ isDOMText,
+ isJSExpression,
+ NodeSchema,
+ PropsMap,
+ PropsList,
+ NodeData,
+ TitleContent,
+ obx,
+ computed,
+} from '../../../../../globals';
/**
* 基础节点
@@ -74,7 +83,7 @@ export default class Node {
return -1;
}
- @computed get title(): string {
+ @computed get title(): TitleContent {
let t = this.getExtraProp('title');
if (!t && this.componentMeta.descriptor) {
t = this.getProp(this.componentMeta.descriptor, false);
@@ -181,6 +190,30 @@ export default class Node {
return this.props.export(true).props || null;
}
+ isContainer() {
+ return this.isNodeParent && this.componentMeta.isContainer;
+ }
+
+ @computed isSlotContainer() {
+ for (const item of this.props) {
+ if (item.type === 'slot') {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @computed get slots() {
+ // TODO: optimize recore/obx, array maked every time, donot as changed
+ const slots: Node[] = [];
+ this.props.forEach(item => {
+ if (item.type === 'slot') {
+ slots.push(item.slotNode!);
+ }
+ });
+ return slots;
+ }
+
private _conditionGroup: string | null = null;
/**
* 条件组
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 84f0f8759..d7b63347f 100644
--- a/packages/designer/src/designer/document/node/props/prop-stash.ts
+++ b/packages/designer/src/designer/document/node/props/prop-stash.ts
@@ -1,4 +1,4 @@
-import { obx, autorun, untracked, computed } from '@recore/obx';
+import { obx, autorun, untracked, computed } from '../../../../../../globals';
import Prop, { IPropParent, UNSET } from './prop';
import Props from './props';
diff --git a/packages/designer/src/designer/document/node/props/prop.ts b/packages/designer/src/designer/document/node/props/prop.ts
index a8b941339..c8463c6cc 100644
--- a/packages/designer/src/designer/document/node/props/prop.ts
+++ b/packages/designer/src/designer/document/node/props/prop.ts
@@ -1,12 +1,20 @@
-import { untracked, computed, obx } from '@recore/obx';
import { valueToSource } from '../../../../utils/value-to-source';
-import { CompositeValue, isJSExpression, isJSSlot, NodeSchema, NodeData, isNodeSchema } from '../../../schema';
import PropStash from './prop-stash';
import { uniqueId } from '../../../../../../utils/unique-id';
import { isPlainObject } from '../../../../../../utils/is-plain-object';
import { hasOwnProperty } from '../../../../utils/has-own-property';
import Props from './props';
import Node from '../node';
+import {
+ CompositeValue,
+ isJSExpression,
+ isJSSlot,
+ NodeData,
+ isNodeSchema,
+ untracked,
+ computed,
+ obx,
+} from '../../../../../../globals';
export const UNSET = Symbol.for('unset');
export type UNSET = typeof UNSET;
@@ -197,6 +205,9 @@ export default class Prop implements IPropParent {
}
private _slotNode?: Node;
+ get slotNode() {
+ return this._slotNode;
+ }
setAsSlot(data: NodeData) {
this._type = 'slot';
if (
diff --git a/packages/designer/src/designer/document/node/props/props.ts b/packages/designer/src/designer/document/node/props/props.ts
index 328d1315b..d46b86789 100644
--- a/packages/designer/src/designer/document/node/props/props.ts
+++ b/packages/designer/src/designer/document/node/props/props.ts
@@ -1,9 +1,8 @@
-import { computed, obx } from '@recore/obx';
import { uniqueId } from '../../../../../../utils/unique-id';
-import { CompositeValue, PropsList, PropsMap } from '../../../schema';
import PropStash from './prop-stash';
import Prop, { IPropParent, UNSET } from './prop';
import Node from '../node';
+import { PropsMap, PropsList, CompositeValue, computed, obx } from '../../../../../../globals';
export const EXTRA_KEY_PREFIX = '__';
@@ -279,6 +278,12 @@ export default class Props implements IPropParent {
});
}
+ filter(fn: (item: Prop, key: number | string | undefined) => boolean) {
+ return this.items.filter(item => {
+ return fn(item, item.key);
+ });
+ }
+
private purged = false;
/**
* 回收销毁
diff --git a/packages/designer/src/designer/document/node/root-node.ts b/packages/designer/src/designer/document/node/root-node.ts
index 0bb809f33..042ecf821 100644
--- a/packages/designer/src/designer/document/node/root-node.ts
+++ b/packages/designer/src/designer/document/node/root-node.ts
@@ -1,8 +1,7 @@
import Node, { NodeParent } from './node';
-import { RootSchema } from '../../schema';
import DocumentModel from '../document-model';
import NodeChildren from './node-children';
-import Props from './props/props';
+import { RootSchema } from '../../../../../globals';
/**
* 根容器节点
diff --git a/packages/designer/src/designer/document/selection.ts b/packages/designer/src/designer/document/selection.ts
index c481b1bce..3ff2bc604 100644
--- a/packages/designer/src/designer/document/selection.ts
+++ b/packages/designer/src/designer/document/selection.ts
@@ -1,5 +1,5 @@
import Node, { comparePosition, PositionNO } from './node/node';
-import { obx } from '@recore/obx';
+import { obx } from '../../../../globals';
import DocumentModel from './document-model';
import { EventEmitter } from 'events';
diff --git a/packages/designer/src/designer/helper/dragon.ts b/packages/designer/src/designer/helper/dragon.ts
index 232fb66f4..ca748caee 100644
--- a/packages/designer/src/designer/helper/dragon.ts
+++ b/packages/designer/src/designer/helper/dragon.ts
@@ -1,13 +1,12 @@
import { EventEmitter } from 'events';
-import { obx } from '@recore/obx';
import Location from './location';
import DocumentModel from '../document/document-model';
-import { NodeSchema } from '../schema';
import { ISimulator, isSimulator, ComponentInstance } from '../simulator';
import Node from '../document/node/node';
import Designer from '../designer';
import { setNativeSelection } from './navtive-selection';
import cursor from './cursor';
+import { NodeSchema, obx } from '../../../../globals';
export interface LocateEvent {
readonly type: 'LocateEvent';
diff --git a/packages/designer/src/designer/helper/history.ts b/packages/designer/src/designer/helper/history.ts
index 8ab0fb624..f0a3a27d9 100644
--- a/packages/designer/src/designer/helper/history.ts
+++ b/packages/designer/src/designer/helper/history.ts
@@ -1,7 +1,5 @@
import { EventEmitter } from 'events';
-import Session from './session';
-import { autorun, Reaction, untracked } from '@recore/obx';
-import { NodeSchema } from '../schema';
+import { NodeSchema, autorun, Reaction, untracked } from '../../../../globals';
// TODO: cache to localStorage
@@ -176,3 +174,48 @@ export default class History {
this.records = [];
}
}
+
+class Session {
+ private _data: any;
+ private activedTimer: any;
+
+ get data() {
+ return this._data;
+ }
+
+ constructor(readonly cursor: number, data: any, private timeGap: number = 1000) {
+ this.setTimer();
+ this.log(data);
+ }
+
+ log(data: any) {
+ if (!this.isActive()) {
+ return;
+ }
+ this._data = data;
+ this.setTimer();
+ }
+
+ isActive() {
+ return this.activedTimer != null;
+ }
+
+ end() {
+ if (this.isActive()) {
+ this.clearTimer();
+ console.info('session end');
+ }
+ }
+
+ private setTimer() {
+ this.clearTimer();
+ this.activedTimer = setTimeout(() => this.end(), this.timeGap);
+ }
+
+ private clearTimer() {
+ if (this.activedTimer) {
+ clearTimeout(this.activedTimer);
+ }
+ this.activedTimer = null;
+ }
+}
diff --git a/packages/designer/src/designer/helper/hovering.ts b/packages/designer/src/designer/helper/hovering.ts
index a4f62abda..56e1efde8 100644
--- a/packages/designer/src/designer/helper/hovering.ts
+++ b/packages/designer/src/designer/helper/hovering.ts
@@ -1,9 +1,9 @@
-import { obx } from '@recore/obx';
import Node from '../document/node/node';
import DocumentModel from '../document/document-model';
+import { obx } from '../../../../globals';
export default class Hovering {
- @obx.ref private _enable: boolean = true;
+ @obx.ref private _enable = true;
get enable() {
return this._enable;
}
@@ -13,7 +13,7 @@ export default class Hovering {
this._current = null;
}
}
- @obx.ref xRayMode: boolean = false;
+ @obx.ref xRayMode = false;
@obx.ref private _current: Node | null = null;
get current() {
diff --git a/packages/designer/src/designer/helper/offset-observer.ts b/packages/designer/src/designer/helper/offset-observer.ts
index 798ec43a8..39f3c4e23 100644
--- a/packages/designer/src/designer/helper/offset-observer.ts
+++ b/packages/designer/src/designer/helper/offset-observer.ts
@@ -1,4 +1,4 @@
-import { obx, computed } from '@recore/obx';
+import { obx, computed } from '../../../../globals';
import { INodeSelector, IViewport } from '../simulator';
import { uniqueId } from '../../../../utils/unique-id';
import { isRootNode } from '../document/node/root-node';
diff --git a/packages/designer/src/designer/helper/session.ts b/packages/designer/src/designer/helper/session.ts
deleted file mode 100644
index 8095d525d..000000000
--- a/packages/designer/src/designer/helper/session.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-export default class Session {
- private _data: any;
- private activedTimer: any;
-
- get data() {
- return this._data;
- }
-
- constructor(readonly cursor: number, data: any, private timeGap: number = 1000) {
- this.setTimer();
- this.log(data);
- }
-
- log(data: any) {
- if (!this.isActive()) {
- return;
- }
- this._data = data;
- this.setTimer();
- }
-
- isActive() {
- return this.activedTimer != null;
- }
-
- end() {
- if (this.isActive()) {
- this.clearTimer();
- console.info('session end');
- }
- }
-
- private setTimer() {
- this.clearTimer();
- this.activedTimer = setTimeout(() => this.end(), this.timeGap);
- }
-
- private clearTimer() {
- if (this.activedTimer) {
- clearTimeout(this.activedTimer);
- }
- this.activedTimer = null;
- }
-}
diff --git a/packages/designer/src/designer/project-view.tsx b/packages/designer/src/designer/project-view.tsx
index 52e11ee3b..284d9c0dc 100644
--- a/packages/designer/src/designer/project-view.tsx
+++ b/packages/designer/src/designer/project-view.tsx
@@ -1,7 +1,7 @@
import { Component } from 'react';
-import { observer } from '@recore/obx-react';
import Designer from './designer';
import DocumentView from './document/document-view';
+import { observer } from '../../../globals';
@observer
export default class ProjectView extends Component<{ designer: Designer }> {
diff --git a/packages/designer/src/designer/project.ts b/packages/designer/src/designer/project.ts
index 5b5ecde9e..e64610e2f 100644
--- a/packages/designer/src/designer/project.ts
+++ b/packages/designer/src/designer/project.ts
@@ -1,8 +1,7 @@
-import { obx, computed } from '@recore/obx';
-import { ProjectSchema, RootSchema } from './schema';
import { EventEmitter } from 'events';
import Designer from './designer';
import DocumentModel, { isDocumentModel } from './document/document-model';
+import { ProjectSchema, RootSchema, obx, computed } from '../../../globals';
export default class Project {
private emitter = new EventEmitter();
@@ -21,10 +20,12 @@ export default class Project {
componentsTree: [],
...schema,
};
- this.open(this.data.componentsTree[0] || {
- componentName: 'Page',
- fileName: '',
- });
+ this.open(
+ this.data.componentsTree[0] || {
+ componentName: 'Page',
+ fileName: '',
+ },
+ );
}
@computed get currentDocument() {
@@ -106,7 +107,7 @@ export default class Project {
}
checkExclusive(actived: DocumentModel) {
- this.documents.forEach((doc) => {
+ this.documents.forEach(doc => {
if (doc !== actived) {
doc.suspense();
}
@@ -115,7 +116,7 @@ export default class Project {
}
closeOthers(opened: DocumentModel) {
- this.documents.forEach((doc) => {
+ this.documents.forEach(doc => {
if (doc !== opened) {
doc.close();
}
@@ -131,5 +132,4 @@ export default class Project {
// 通知标记删除,需要告知服务端
// 项目角度编辑不是全量打开所有文档,是按需加载,哪个更新就通知更新谁,
// 哪个删除就
-
}
diff --git a/packages/designer/src/designer/schema.ts b/packages/designer/src/designer/schema.ts
deleted file mode 100644
index 1dab9fe82..000000000
--- a/packages/designer/src/designer/schema.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-// 表达式
-export interface JSExpression {
- type: 'JSExpression';
- /**
- * 表达式字符串
- */
- value: string;
- /**
- * 模拟值
- */
- mock?: any;
-}
-
-export interface JSSlot {
- type: 'JSSlot';
- value: NodeSchema;
-}
-
-// JSON 基本类型
-export type JSONValue = boolean | string | number | null | JSONArray | JSONObject;
-export type JSONArray = JSONValue[];
-export interface JSONObject {
- [key: string]: JSONValue;
-}
-
-// 复合类型
-export type CompositeValue = JSONValue | JSExpression | JSSlot | CompositeArray | CompositeObject;
-export type CompositeArray = CompositeValue[];
-export interface CompositeObject {
- [key: string]: CompositeValue;
-}
-
-export interface NpmInfo {
- componentName?: string;
- package: string;
- version: string;
- destructuring?: boolean;
- exportName?: string;
- subName?: string;
- main?: string;
-}
-
-export type ComponentsMap = NpmInfo[];
-
-export type UtilsMap = Array<
-| {
- name: string;
- type: 'npm';
- content: NpmInfo;
-}
-| {
- name: string;
- type: '';
-}
->;
-
-// lang "en-US" | "zh-CN" | "zh-TW" | ...
-export interface I18nMap {
- [lang: string]: { [key: string]: string };
-}
-
-export interface DataSourceConfig {
- id: string;
- isInit: boolean;
- type: string;
- options: {
- uri: string;
- [option: string]: CompositeValue;
- };
- [otherKey: string]: CompositeValue;
-}
-
-export interface NodeSchema {
- id?: string;
- componentName: string;
- props?: PropsMap | PropsList;
- leadingComponents?: string;
- condition?: CompositeValue;
- loop?: CompositeValue;
- loopArgs?: [string, string];
- children?: NodeData | NodeData[];
-}
-
-export type PropsMap = CompositeObject;
-export type PropsList = Array<{
- spread?: boolean;
- name?: string;
- value: CompositeValue;
-}>;
-
-export type NodeData = NodeSchema | JSExpression | DOMText;
-
-export function isJSExpression(data: any): data is JSExpression {
- return data && data.type === 'JSExpression';
-}
-
-export function isJSSlot(data: any): data is JSSlot {
- return data && data.type === 'JSSlot';
-}
-
-export function isDOMText(data: any): data is DOMText {
- return typeof data === 'string';
-}
-
-export type DOMText = string;
-
-export interface RootSchema extends NodeSchema {
- componentName: string; // 'Block' | 'Page' | 'Component';
- fileName: string;
- meta?: object;
- state?: {
- [key: string]: CompositeValue;
- };
- methods?: {
- [key: string]: JSExpression;
- };
- lifeCycles?: {
- [key: string]: JSExpression;
- };
- css?: string;
- dataSource?: {
- items: DataSourceConfig[];
- } | any;
- defaultProps?: CompositeObject;
-}
-
-export interface BlockSchema extends RootSchema {
- componentName: 'Block';
-}
-
-export interface PageSchema extends RootSchema {
- componentName: 'Page';
-}
-
-export interface ComponentSchema extends RootSchema {
- componentName: 'Component';
-}
-
-export interface ProjectSchema {
- version: string;
- componentsMap: ComponentsMap;
- componentsTree: RootSchema[];
- i18n?: I18nMap;
- utils?: UtilsMap;
- constants?: JSONObject;
- css?: string;
- dataSource?: {
- items: DataSourceConfig[];
- };
-}
-
-export function isNodeSchema(data: any): data is NodeSchema {
- return data && data.componentName;
-}
-
-export function isProjectSchema(data: any): data is ProjectSchema {
- return data && data.componentsTree;
-}
diff --git a/packages/designer/src/designer/simulator.ts b/packages/designer/src/designer/simulator.ts
index 99c73ad47..de27ceb7c 100644
--- a/packages/designer/src/designer/simulator.ts
+++ b/packages/designer/src/designer/simulator.ts
@@ -1,9 +1,9 @@
import { Component as ReactComponent, ComponentType } from 'react';
-import { LocateEvent, ISensor } from './helper/dragon';
+import { ISensor } from './helper/dragon';
import { Point } from './helper/location';
import Node from './document/node/node';
import { ScrollTarget, IScrollable } from './helper/scroller';
-import { ComponentMetadata } from './component-meta';
+import { ComponentMetadata } from '../../../globals';
export type AutoFit = '100%';
export const AutoFit = '100%';
diff --git a/packages/editor/src/index.tsx b/packages/editor/src/index.tsx
index 22e76df35..a16cd4b4e 100644
--- a/packages/editor/src/index.tsx
+++ b/packages/editor/src/index.tsx
@@ -8,7 +8,7 @@ import components from './config/components';
import utils from './config/utils';
import constants from './config/constants';
import './config/locale';
-import './config/setters';
+import '../../plugin-setters';
import './global.scss';
import './config/theme.scss';
diff --git a/packages/globals/README.md b/packages/globals/README.md
index 070f5ca3b..30c3e7d7d 100644
--- a/packages/globals/README.md
+++ b/packages/globals/README.md
@@ -1 +1,3 @@
shared globals
+
+ 发 CDN
diff --git a/packages/globals/package.json b/packages/globals/package.json
index 26761d9ba..cfedbc382 100644
--- a/packages/globals/package.json
+++ b/packages/globals/package.json
@@ -13,6 +13,8 @@
},
"dependencies": {
"@alifd/next": "^1.19.16",
+ "@recore/obx": "^1.0.8",
+ "@recore/obx-react": "^1.0.7",
"classnames": "^2.2.6",
"react": "^16",
"react-dom": "^16.7.0"
diff --git a/packages/globals/src/components/tip/embed-tip.tsx b/packages/globals/src/components/tip/embed-tip.tsx
index fd8b3d4f8..203c8acd0 100644
--- a/packages/globals/src/components/tip/embed-tip.tsx
+++ b/packages/globals/src/components/tip/embed-tip.tsx
@@ -1,13 +1,7 @@
import { uniqueId } from '../../../../utils/unique-id';
-import { Component, ReactNode } from 'react';
+import { Component } from 'react';
import { saveTips } from './tip-handler';
-
-export interface TipConfig {
- className?: string;
- children?: ReactNode;
- theme?: string;
- direction?: string; // 'n|s|w|e|top|bottom|left|right';
-}
+import { TipConfig } from '../../types';
export default class EmbedTip extends Component {
private id = uniqueId('tips$');
diff --git a/packages/globals/src/components/tip/tip-handler.ts b/packages/globals/src/components/tip/tip-handler.ts
index 2f71d2ab3..ed1cb908a 100644
--- a/packages/globals/src/components/tip/tip-handler.ts
+++ b/packages/globals/src/components/tip/tip-handler.ts
@@ -1,5 +1,5 @@
-import { TipConfig } from './embed-tip';
import { EventEmitter } from 'events';
+import { TipConfig } from '../../types';
export interface TipOptions extends TipConfig {
target: HTMLElement;
diff --git a/packages/globals/src/components/tip/tip.tsx b/packages/globals/src/components/tip/tip.tsx
index 6c91e1e97..20d6c7928 100644
--- a/packages/globals/src/components/tip/tip.tsx
+++ b/packages/globals/src/components/tip/tip.tsx
@@ -1,7 +1,8 @@
import { Component } from 'react';
import classNames from 'classnames';
import { resolvePosition } from './utils';
-import tipHandler from './tip-handler';
+import tipHandler, { TipOptions } from './tip-handler';
+import { intl } from '../../intl';
export default class Tip extends Component {
private dispose?: () => void;
@@ -100,7 +101,7 @@ export default class Tip extends Component {
}
render() {
- const tip: any = tipHandler.tip || {};
+ const tip: TipOptions = tipHandler.tip || ({} as any);
const className = classNames('lc-tip', tip.className, tip && tip.theme ? `lc-theme-${tip.theme}` : null);
this.originClassName = className;
@@ -113,7 +114,7 @@ export default class Tip extends Component {
}}
>
- {tip.children}
+ {intl(tip.children)}
);
}
diff --git a/packages/globals/src/components/title/index.tsx b/packages/globals/src/components/title/index.tsx
index 226a5f15e..526b0ce23 100644
--- a/packages/globals/src/components/title/index.tsx
+++ b/packages/globals/src/components/title/index.tsx
@@ -1,27 +1,19 @@
-import { Component, isValidElement, ReactElement, ReactNode } from 'react';
-import { Icon } from '@alifd/next';
+import { Component, isValidElement } from 'react';
import classNames from 'classnames';
-import EmbedTip, { TipConfig } from '../tip/embed-tip';
+import EmbedTip from '../tip/embed-tip';
import './title.less';
-import { IconConfig, createIcon } from '../../utils';
+import { createIcon } from '../../utils';
+import { TitleContent, isI18nData } from '../../types';
+import { intl } from '../../intl';
-export interface TitleConfig {
- label?: ReactNode;
- tip?: string | ReactElement | TipConfig;
- icon?: string | ReactElement | IconConfig;
- className?: string;
-}
-
-export type TitleContent = string | ReactElement | TitleConfig;
-
-export class Title extends Component<{ title: TitleContent; onClick?: () => void }> {
+export class Title extends Component<{ title: TitleContent; className?: string; onClick?: () => void }> {
render() {
- let { title } = this.props;
+ let { title, className, onClick } = this.props;
if (isValidElement(title)) {
return title;
}
- if (typeof title === 'string') {
- title = { label: title }; // tslint:disable-line
+ if (typeof title === 'string' || isI18nData(title)) {
+ title = { label: title };
}
const icon = title.icon ? createIcon(title.icon) : null;
@@ -32,22 +24,24 @@ export class Title extends Component<{ title: TitleContent; onClick?: () => void
tip = title.tip;
} else {
const tipProps =
- typeof title.tip === 'object' && !isValidElement(title.tip) ? title.tip : { children: title.tip };
+ typeof title.tip === 'object' && !(isValidElement(title.tip) || isI18nData(title.tip))
+ ? title.tip
+ : { children: title.tip };
tip =