mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-12 17:08:14 +00:00
feat: 支持节点拖拽时被放入容器的视觉反馈, 通过 enableReactiveContainer 配置项
This commit is contained in:
parent
2c05bd3a78
commit
6a308ba81d
@ -0,0 +1,119 @@
|
||||
import * as React from 'react';
|
||||
import { Component, Fragment, ReactElement, PureComponent } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { computed, observer, Title, globalLocale } from '@ali/lowcode-editor-core';
|
||||
import { I18nData, isI18nData, TitleContent } from '@ali/lowcode-types';
|
||||
import { DropLocation } from '../../designer';
|
||||
import { BuiltinSimulatorHost } from '../../builtin-simulator/host';
|
||||
import { ParentalNode } from '../../document/node';
|
||||
|
||||
export class BorderContainerInstance extends PureComponent<{
|
||||
title: TitleContent;
|
||||
rect: DOMRect | null;
|
||||
scale: number;
|
||||
scrollX: number;
|
||||
scrollY: number;
|
||||
}> {
|
||||
render() {
|
||||
const { title, rect, scale, scrollX, scrollY } = this.props;
|
||||
if (!rect) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const style = {
|
||||
width: rect.width * scale,
|
||||
height: rect.height * scale,
|
||||
transform: `translate(${(scrollX + rect.left) * scale}px, ${(scrollY + rect.top) * scale}px)`,
|
||||
};
|
||||
|
||||
const className = classNames('lc-borders lc-borders-detecting');
|
||||
|
||||
return (
|
||||
<div className={className} style={style}>
|
||||
<Title title={title} className="lc-borders-title" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getTitle(title: string | I18nData | ReactElement) {
|
||||
if (typeof title === 'string') return title;
|
||||
if (isI18nData(title)) {
|
||||
const locale = globalLocale.getLocale() || 'zh-CN';
|
||||
return `将放入到此${title[locale]}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
@observer
|
||||
export class BorderContainer extends Component<{
|
||||
host: BuiltinSimulatorHost,
|
||||
}, {
|
||||
target?: ParentalNode,
|
||||
}> {
|
||||
|
||||
state = {} as any;
|
||||
|
||||
@computed get scale() {
|
||||
return this.props.host.viewport.scale;
|
||||
}
|
||||
|
||||
@computed get scrollX() {
|
||||
return this.props.host.viewport.scrollX;
|
||||
}
|
||||
|
||||
@computed get scrollY() {
|
||||
return this.props.host.viewport.scrollY;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { host } = this.props;
|
||||
|
||||
host.designer.editor.on('designer.dropLocation.change', (loc: DropLocation) => {
|
||||
let { target } = this.state;
|
||||
if (target === loc?.target) return;
|
||||
this.setState({
|
||||
target: loc?.target,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { host } = this.props;
|
||||
const { target } = this.state;
|
||||
if (target == undefined) {
|
||||
return null;
|
||||
}
|
||||
const instances = host.getComponentInstances(target!);
|
||||
if (!instances || instances.length < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (instances.length === 1) {
|
||||
return (
|
||||
<BorderContainerInstance
|
||||
key="line-h"
|
||||
title={getTitle(target.componentMeta.title)}
|
||||
scale={this.scale}
|
||||
scrollX={this.scrollX}
|
||||
scrollY={this.scrollY}
|
||||
rect={host.computeComponentInstanceRect(instances[0], target.componentMeta.rootSelector)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Fragment>
|
||||
{instances.map((inst, i) => (
|
||||
<BorderContainerInstance
|
||||
key={`line-h-${i}`}
|
||||
title={getTitle(target.componentMeta.title)}
|
||||
scale={this.scale}
|
||||
scrollX={this.scrollX}
|
||||
scrollY={this.scrollY}
|
||||
rect={host.computeComponentInstanceRect(inst, target.componentMeta.rootSelector)}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
import React, { Component } from 'react';
|
||||
import { observer } from '@ali/lowcode-editor-core';
|
||||
import { observer, engineConfig } from '@ali/lowcode-editor-core';
|
||||
import { BorderDetecting } from './border-detecting';
|
||||
import { BorderContainer } from './border-container';
|
||||
import { BuiltinSimulatorHost } from '../host';
|
||||
import { BorderSelecting } from './border-selecting';
|
||||
import BorderResizing from './border-resizing';
|
||||
@ -25,6 +26,7 @@ export class BemTools extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
<div className="lc-bem-tools" style={{ transform: `translate(${-scrollX * scale}px,${-scrollY * scale}px)` }}>
|
||||
<BorderDetecting key="hovering" host={host} />
|
||||
<BorderSelecting key="selecting" host={host} />
|
||||
{ engineConfig.get('enableReactiveContainer') && <BorderContainer key="reactive-container-border" host={host} /> }
|
||||
<InsertionView key="insertion" host={host} />
|
||||
<BorderResizing key="resizing" host={host} />
|
||||
{
|
||||
|
||||
@ -246,6 +246,7 @@ export class Designer {
|
||||
this._dropLocation.document.internalSetDropLocation(null);
|
||||
}
|
||||
this._dropLocation = loc;
|
||||
this.postEvent('dropLocation.change', loc);
|
||||
loc.document.internalSetDropLocation(loc);
|
||||
this.activeTracker.track({ node: loc.target, detail: loc.detail });
|
||||
return loc;
|
||||
@ -258,6 +259,7 @@ export class Designer {
|
||||
if (this._dropLocation) {
|
||||
this._dropLocation.document.internalSetDropLocation(null);
|
||||
}
|
||||
this.postEvent('dropLocation.change', undefined);
|
||||
this._dropLocation = undefined;
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +187,10 @@ interface EngineOptions {
|
||||
deviceMapper?: {
|
||||
transform: (originalDevice: string) => string;
|
||||
};
|
||||
/**
|
||||
* 开启拖拽组件时,即将被放入的容器是否有视觉反馈
|
||||
*/
|
||||
enableReactiveContainer?: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user