fix slot title

This commit is contained in:
kangwei 2020-05-06 19:56:23 +08:00
parent 4eee69763f
commit afd47a4e83
16 changed files with 109 additions and 55 deletions

View File

@ -1,6 +1,8 @@
// all this file for polyfill vision logic
import { isValidElement } from 'react';
import { isSetterConfig } from '@ali/lowcode-types';
import { getSetter } from '@ali/lowcode-editor-core';
function getHotterFromSetter(setter) {
return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line
@ -29,9 +31,9 @@ export class Transducer {
constructor(context, config) {
let { setter } = config;
// 1. validElement
// 1. validElement
// 2. SetterConfig
// 3. SetterConfig[]
// 3. SetterConfig[]
if (Array.isArray(setter)) {
setter = setter[0];
} else if (isValidElement(setter) && setter.type.displayName === 'MixedSetter') {
@ -40,6 +42,13 @@ export class Transducer {
setter = setter.props.setters[0];
}
if (isSetterConfig(setter)) {
setter = setter.componentName;
}
if (typeof setter === 'string') {
setter = getSetter(setter);
}
this.setterTransducer = combineTransducer(
getTransducerFromSetter(setter),
getHotterFromSetter(setter),

View File

@ -160,8 +160,9 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
private transformProps(props: any): any {
// FIXME! support PropsList
return this.document.designer.transformProps(props, this, TransformStage.Init);
const x = this.document.designer.transformProps(props, this, TransformStage.Init);
return x;
// TODO: run transducers in metadata.experimental
}
@ -183,19 +184,19 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return this.isParental() && this.componentMeta.isContainer;
}
isRoot(): this is RootNode {
isRoot(): boolean {
return this.document.rootNode == (this as any);
}
isPage(): this is PageNode {
isPage(): boolean {
return this.isRoot() && this.componentName === 'Page';
}
isComponent(): this is ComponentNode {
isComponent(): boolean {
return this.isRoot() && this.componentName === 'Component';
}
isSlot(): this is SlotNode {
isSlot(): boolean {
return this._slotFor != null && this.componentName === 'Slot';
}
@ -225,8 +226,12 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return;
}
if (!this.isSlot() && this._parent) {
this._parent.children.delete(this);
if (this._parent) {
if (this.isSlot()) {
this._parent.removeSlot(this, false);
} else {
this._parent.children.delete(this);
}
}
this._parent = parent;
@ -258,8 +263,12 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
*
*/
remove() {
if (!this.isSlot() && this.parent) {
this.parent.children.delete(this, true);
if (this.parent) {
if (this.isSlot()) {
this.parent.removeSlot(this, true);
} else {
this.parent.children.delete(this, true);
}
}
}
@ -295,24 +304,13 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return this.props.export(TransformStage.Serilize).props || null;
}
@obx.val _slots: Node[] = [];
@computed hasSlots() {
for (const item of this.props) {
if (item.type === 'slot') {
return true;
}
}
return false;
return this._slots.length > 0;
}
@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;
get slots() {
return this._slots;
}
@obx.ref private _conditionGroup: ExclusiveGroup | null = null;
@ -542,6 +540,28 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
return comparePosition(this, otherNode);
}
/**
* Slot节点
*/
removeSlot(slotNode: Node, purge = false): boolean {
const i = this._slots.indexOf(slotNode);
if (i < 0) {
return false;
}
const deleted = this._slots.splice(i, 1)[0];
if (purge) {
// should set parent null
deleted.internalSetParent(null);
deleted.purge();
}
return false;
}
addSlot(slotNode: Node) {
slotNode.internalSetParent(this as ParentalNode);
this._slots.push(slotNode);
}
private purged = false;
/**
*

View File

@ -221,7 +221,7 @@ export class Prop implements IPropParent {
} else {
const owner = this.props.owner;
this._slotNode = owner.document.createNode<SlotNode>(slotSchema);
this._slotNode.internalSetParent(owner as any);
owner.addSlot(this._slotNode);
this._slotNode.internalSetSlotFor(this);
}
this.dispose();

View File

@ -37,10 +37,13 @@ function injectVars(msg: string, params: any, locale: string): string {
});*/
}
export function intl(data: any, params?: object): string {
export function intl(data: any, params?: object): ReactNode {
if (!isI18nData(data)) {
return data;
}
if (data.intl) {
return data.intl;
}
const locale = globalLocale.getLocale();
const tries = generateTryLocales(locale);
let msg: string | undefined;

View File

@ -146,5 +146,8 @@
}
}
}
>.lc-block-setter {
flex: 1;
}
}
}

View File

@ -70,13 +70,6 @@ export class SettingsMain {
this._settings = this.designer.createSettingEntry(this.editor, nodes);
}
onceOutlineVisible(fn: () => void): () => void {
this.emitter.on('outline-visible', fn);
return () => {
this.emitter.removeListener('outline-visible', fn);
};
}
purge() {
this.disposeListener();
this.emitter.removeAllListeners();

View File

@ -1,4 +1,5 @@
import { TransformedComponentMetadata, FieldConfig, SettingTarget } from '@ali/lowcode-types';
import { IconSlot } from '../icons/slot';
export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata {
const { componentName, configure = {} } = metadata;
@ -80,7 +81,21 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
});
}
// 通用设置
const propsGroup = props || [];
let propsGroup = props || [];
const basicInfo: any = {};
if (componentName === 'Slot') {
basicInfo.icon = IconSlot;
propsGroup = [{
name: '___title',
title: {
type: 'i18n',
'en-US': 'Slot Title',
'zh-CN': '插槽标题'
},
setter: 'StringSetter',
defaultValue: '插槽容器'
}]
}
/*
propsGroup.push({
name: '#generals',
@ -186,6 +201,9 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
title: { type: 'i18n', 'zh-CN': '是否渲染', 'en-US': 'Condition' },
setter: [{
componentName: 'BoolSetter',
props: {
defaultValue: true,
}
}, {
componentName: 'VariableSetter'
}],
@ -243,6 +261,7 @@ export default function(metadata: TransformedComponentMetadata): TransformedComp
return {
...metadata,
...basicInfo,
configure: {
...configure,
combined,

View File

@ -2,9 +2,9 @@ import { createIntl } from '@ali/lowcode-editor-core';
import en_US from './en-US.json';
import zh_CN from './zh-CN.json';
const { intl, getLocale, setLocale } = createIntl({
const { intl, intlNode, getLocale, setLocale } = createIntl({
'en-US': en_US,
'zh-CN': zh_CN,
});
export { intl, getLocale, setLocale };
export { intl, intlNode, getLocale, setLocale };

View File

@ -122,7 +122,7 @@ export default class TreeNode {
return title;
}
if (isI18nData(title)) {
return intl(title);
return intl(title) as string;
}
return this.node.componentName;
}

View File

@ -4,7 +4,7 @@ import { observer, Title } from '@ali/lowcode-editor-core';
import { ExclusiveGroup } from '@ali/lowcode-designer';
import TreeNode from '../tree-node';
import TreeNodeView from './tree-node';
import { intl } from '../locale';
import { intlNode } from '../locale';
@observer
export default class TreeBranches extends Component<{
@ -119,7 +119,7 @@ class TreeNodeSlots extends Component<{
data-id={treeNode.id}
>
<div className="tree-node-slots-title">
<Title title={{ type: 'i18n', intl: intl('Slots') }} />
<Title title={{ type: 'i18n', intl: intlNode('Slots') }} />
</div>
{treeNode.slots.map(tnode => (
<TreeNodeView key={tnode.id} treeNode={tnode} />

View File

@ -5,12 +5,11 @@ import { IconArrowRight } from '../icons/arrow-right';
import { IconEyeClose } from '../icons/eye-close';
import { IconLock } from '../icons/lock';
import { IconUnlock } from '../icons/unlock';
import { intl } from '../locale';
import { intl, intlNode } from '../locale';
import TreeNode from '../tree-node';
import { IconEye } from '../icons/eye';
import { IconCond } from '../icons/cond';
import { IconLoop } from '../icons/loop';
import { IconSlot } from '../icons/slot';
import { createIcon } from '@ali/lowcode-utils';
@observer
@ -104,22 +103,21 @@ export default class TreeTitle extends Component<{
{node.slotFor && (
<a className="tree-node-tag slot">
{/* todo: click redirect to prop */}
<IconSlot />
<Tip>{intl('Slot for {prop}', { prop: node.slotFor.key })}</Tip>
<Tip>{intlNode('Slot for {prop}', { prop: node.slotFor.key })}</Tip>
</a>
)}
{node.hasLoop() && (
<a className="tree-node-tag loop">
{/* todo: click todo something */}
<IconLoop />
<Tip>{intl('Loop')}</Tip>
<Tip>{intlNode('Loop')}</Tip>
</a>
)}
{node.hasCondition() && !node.conditionGroup && (
<a className="tree-node-tag cond">
{/* todo: click todo something */}
<IconCond />
<Tip>{intl('Conditional')}</Tip>
<Tip>{intlNode('Conditional')}</Tip>
</a>
)}
</Fragment>

View File

@ -4,6 +4,6 @@
"outDir": "lib"
},
"include": [
"./src/"
"./src/",
]
}

View File

@ -6,7 +6,7 @@ class Slot extends Component {
componentName: 'Slot',
configure: {
props: [{
name: '___title___',
name: '___title',
title: {
type: 'i18n',
'en-US': 'Slot Title',
@ -15,7 +15,7 @@ class Slot extends Component {
setter: 'StringSetter',
defaultValue: '插槽容器'
}, {
name: '___params___',
name: '___params',
title: {
type: 'i18n',
'en-US': 'Slot Params',

View File

@ -237,7 +237,7 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
}
}
if (collapse || collapsed || fieldCollapsed) {
if (collapse || collapsed || fieldCollapsed || extraProps.display === DISPLAY_TYPE.ENTRY) {
extraProps.defaultCollapsed = true;
}
function isDisabled(field: Field) {
@ -287,10 +287,14 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
if (slotName && initialValue === true) {
initialFn = (field: any, value: any) => {
if (isJSSlot(value)) {
return value;
return {
title: slotTitle || title,
...value,
};
}
return {
type: 'JSSlot',
title: slotTitle || title,
value: initialChildren,
};
};
@ -351,10 +355,14 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial)
componentName: 'SlotSetter',
initialValue: (field: any, value: any) => {
if (isJSSlot(value)) {
return value;
return {
title: slotTitle || title,
...value,
};
}
return {
type: 'JSSlot',
title: slotTitle || title,
value: value == null ? initialChildren : value,
};
},

View File

@ -2,11 +2,12 @@ import { Component } from 'react';
import { EventEmitter } from 'events';
import { fromJS, Iterable, Map as IMMap } from 'immutable';
import logger from '@ali/vu-logger';
import { uniqueId, cloneDeep, isDataEqual, combineInitial, Transducer } from '@ali/ve-utils';
import { cloneDeep, isDataEqual, combineInitial, Transducer } from '@ali/ve-utils';
import I18nUtil from '@ali/ve-i18n-util';
import { getSetter } from '@ali/lowcode-editor-core';
import { editor } from './editor';
import { OldPropConfig, DISPLAY_TYPE } from './bundle/upgrade-metadata';
import { uniqueId } from '@ali/lowcode-utils';
type IPropConfig = OldPropConfig;
@ -108,7 +109,7 @@ export default class Prop implements IVariableSettable {
this.parent = parent;
}
this.id = uniqueId(null as any, 'prop', 'engine-prop');
this.id = uniqueId('prop');
if (typeof config.setter === 'string') {
config.setter = getSetter(config.setter)?.component as any;