diff --git a/packages/designer/src/designer/builtin-hotkey.ts b/packages/designer/src/designer/builtin-hotkey.ts index 8e01bbfff..3f1fbc2c4 100644 --- a/packages/designer/src/designer/builtin-hotkey.ts +++ b/packages/designer/src/designer/builtin-hotkey.ts @@ -108,6 +108,8 @@ hotkey.bind(['command+c', 'ctrl+c', 'command+x', 'ctrl+x'], (e, action) => { const componentsMap = {}; const componentsTree = selected.map((item) => item.export(TransformStage.Save)); + // FIXME: clear node.id + const data = { type: 'nodeSchema', componentsMap, componentsTree }; clipboard.setData(data); diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index fe7908500..b1c72b44d 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -483,7 +483,7 @@ export class DocumentModel { // add toData toData() { - const node = this.project?.currentDocument?.export(TransformStage.Serilize); + const node = this.project?.currentDocument?.export(TransformStage.Save); return { componentsTree: [node] }; } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index e5c18d33d..d743b0bd1 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -487,9 +487,9 @@ export class Node { componentName: this.componentName, }; - if (stage !== TransformStage.Save) { + // if (stage !== TransformStage.Save) { baseSchema.id = this.id; - } + // } if (this.isLeaf()) { baseSchema.children = this.props.get('children')?.export(stage); diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx index 44a8df171..6bdfb1570 100644 --- a/packages/editor-skeleton/src/layouts/left-float-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -31,6 +31,15 @@ export default class LeftFloatPane extends Component<{ area: Area }> if (this.shell?.contains(target)) { return true; } + // 点击了 iframe 内容,算失焦 + if (document.querySelector('.lc-simulator-content-frame') + .contentWindow.document.documentElement.contains(target)) { + return false; + } + // 防止点击 popup / dialog 等触发失焦 + if (!document.querySelector('.lc-workbench-center')?.contains(target)) { + return true; + } const docks = area.current?.getAssocDocks(); if (docks && docks?.length) { return docks.some(dock => dock.getDOMNode()?.contains(target)); @@ -41,6 +50,7 @@ export default class LeftFloatPane extends Component<{ area: Area }> this.props.area.setVisible(false); }, onBlur: () => { + // debugger this.props.area.setVisible(false); }, }); diff --git a/packages/types/src/metadata.ts b/packages/types/src/metadata.ts index b3b11aed0..ac3bee227 100644 --- a/packages/types/src/metadata.ts +++ b/packages/types/src/metadata.ts @@ -45,6 +45,10 @@ export interface InitialItem { name: string; initial: (target: SettingTarget, currentValue: any) => any; } +export interface FilterItem { + name: string; + filter: (target: SettingTarget, currentValue: any) => any; +} export interface Experimental { context?: { [contextInfoName: string]: any }; @@ -52,6 +56,7 @@ export interface Experimental { view?: ComponentType; transducers?: any; // ? should support initials?: InitialItem[]; + filters?: FilterItem[]; callbacks?: Callbacks; // TODO: thinkof function initialChildren?: NodeData[] | ((target: SettingTarget) => NodeData[]); diff --git a/packages/vision-preset/src/bundle/prototype.ts b/packages/vision-preset/src/bundle/prototype.ts index 4ea036ffc..815dab4bf 100644 --- a/packages/vision-preset/src/bundle/prototype.ts +++ b/packages/vision-preset/src/bundle/prototype.ts @@ -1,5 +1,5 @@ import { ComponentType, ReactElement } from 'react'; -import { ComponentMetadata, FieldConfig, InitialItem } from '@ali/lowcode-types'; +import { ComponentMetadata, FieldConfig, InitialItem, FilterItem } from '@ali/lowcode-types'; import { ComponentMeta, addBuiltinComponentAction, @@ -18,22 +18,35 @@ import { import { designer } from '../editor'; import { uniqueId } from '@ali/lowcode-utils'; -const GlobalPropsConfigure: Array<{ position: string; initials?: InitialItem[]; config: FieldConfig }> = []; +const GlobalPropsConfigure: Array<{ + position: string; + initials?: InitialItem[]; + filters?: FilterItem[]; + config: FieldConfig +}> = []; const Overrides: { [componentName: string]: { initials?: InitialItem[]; + filters?: FilterItem[]; override: any; }; } = {}; function addGlobalPropsConfigure(config: OldGlobalPropConfig) { const initials: InitialItem[] = []; + const filters: FilterItem[] = []; GlobalPropsConfigure.push({ position: config.position || 'bottom', initials, - config: upgradePropConfig(config, (item) => { - initials.push(item); - }), + filters, + config: upgradePropConfig(config, { + addInitial: (item) => { + initials.push(item); + }, + addFilter: (item) => { + filters.push(item); + }, + }) }); } function removeGlobalPropsConfigure(name: string) { @@ -46,20 +59,25 @@ function removeGlobalPropsConfigure(name: string) { } function overridePropsConfigure(componentName: string, config: { [name: string]: OldPropConfig } | OldPropConfig[]) { const initials: InitialItem[] = []; + const filters: FilterItem[] = []; const addInitial = (item: InitialItem) => { initials.push(item); }; + const addFilter = (item: FilterItem) => { + filters.push(item); + }; let override: any; if (Array.isArray(config)) { - override = upgradeConfigure(config, addInitial); + override = upgradeConfigure(config, { addInitial, addFilter }); } else { override = {}; Object.keys(config).forEach(key => { - override[key] = upgradePropConfig(config[key], addInitial); + override[key] = upgradePropConfig(config[key], { addInitial, addFilter }); }); } Overrides[componentName] = { initials, + filters, override, }; } diff --git a/packages/vision-preset/src/bundle/upgrade-metadata.ts b/packages/vision-preset/src/bundle/upgrade-metadata.ts index cf10a6cd5..cad503a57 100644 --- a/packages/vision-preset/src/bundle/upgrade-metadata.ts +++ b/packages/vision-preset/src/bundle/upgrade-metadata.ts @@ -1,6 +1,6 @@ import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react'; import { isPlainObject } from '@ali/lowcode-utils'; -import { isI18nData, SettingTarget, InitialItem, isJSSlot, isJSExpression } from '@ali/lowcode-types'; +import { isI18nData, SettingTarget, InitialItem, FilterItem, isJSSlot, isJSExpression } from '@ali/lowcode-types'; type Field = SettingTarget; @@ -178,7 +178,7 @@ type SetterGetter = (this: Field, value: any) => ComponentClass; type ReturnBooleanFunction = (this: Field, value: any) => boolean; -export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) { +export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollector) { const { type, name, @@ -261,22 +261,9 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) } else if (hidden != null || disabled != null) { extraProps.condition = (field: Field) => !(isHidden(field) || isDisabled(field)); } - if (ignore != null || disabled != null) { - // FIXME! addFilter - extraProps.virtual = (field: Field) => { - if (isDisabled(field)) { - return true; - } - - if (typeof ignore === 'function') { - return ignore.call(field, field.getValue()) === true; - } - return ignore === true; - }; - } if (type === 'group') { - newConfig.items = items ? upgradeConfigure(items, addInitial) : []; + newConfig.items = items ? upgradeConfigure(items, collector) : []; return newConfig; } @@ -314,7 +301,7 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) const setterInitial = getInitialFromSetter(setter); - addInitial({ + collector.addInitial({ name: slotName || name, initial: (field: Field, currentValue: any) => { // FIXME! read from prototype.defaultProps @@ -334,6 +321,28 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) }, }); + if (ignore != null || disabled != null) { + collector.addFilter({ + name: slotName || name, + filter: (field: Field, currentValue: any) => { + let disabledValue: boolean; + if (typeof disabled === 'function') { + disabledValue = disabled.call(field, currentValue) === true; + } + else { + disabledValue = disabled === true; + } + if (disabledValue) { + return false; + } + if (typeof ignore === 'function') { + return ignore.call(field, currentValue) !== true; + } + return ignore !== true; + } + }); + } + if (sync) { extraProps.autorun = (field: Field) => { const value = sync.call(field, field.getValue()); @@ -385,10 +394,18 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) let primarySetter: any; if (type === 'composite') { const initials: InitialItem[] = []; + const filters: FilterItem[] = []; const objItems = items - ? upgradeConfigure(items, (item) => { - initials.push(item); - }) + ? upgradeConfigure(items, + { + addInitial: (item) => { + initials.push(item); + }, + addFilter: (item) => { + filters.push(item); + } + } + ) : []; const initial = (target: SettingTarget, value?: any) => { // TODO: @@ -400,7 +417,7 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) }); return data; }; - addInitial({ + collector.addInitial({ name, initial, }); @@ -460,7 +477,13 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) return newConfig; } -type AddIntial = (initialItem: InitialItem) => void; +type AddInitial = (initialItem: InitialItem) => void; +type AddFilter = (filterItem: FilterItem) => void; + +type ConfigCollector = { + addInitial: AddInitial, + addFilter: AddFilter, +} function getInitialFromSetter(setter: any) { return setter && ( @@ -474,7 +497,7 @@ function defaultInitial(value: any, defaultValue: any) { } -export function upgradeConfigure(items: OldPropConfig[], addInitial: AddIntial) { +export function upgradeConfigure(items: OldPropConfig[], collector: ConfigCollector) { const configure: any[] = []; let ignoreSlotName: any = null; items.forEach((config) => { @@ -487,7 +510,7 @@ export function upgradeConfigure(items: OldPropConfig[], addInitial: AddIntial) } ignoreSlotName = null; } - configure.push(upgradePropConfig(config, addInitial)); + configure.push(upgradePropConfig(config, collector)); }); return configure; } @@ -724,10 +747,19 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { experimental.callbacks = callbacks; const initials: InitialItem[] = []; - const props = upgradeConfigure(configure || [], (item) => { - initials.push(item); - }); + const filters: FilterItem[] = []; + const props = upgradeConfigure(configure || [], + { + addInitial: (item) => { + initials.push(item); + }, + addFilter: (item) => { + filters.push(item); + }, + } + ); experimental.initials = initials; + experimental.filters = filters; const supports: any = {}; if (canUseCondition != null) { diff --git a/packages/vision-preset/src/editor.ts b/packages/vision-preset/src/editor.ts index 954235f6c..5735a946b 100644 --- a/packages/vision-preset/src/editor.ts +++ b/packages/vision-preset/src/editor.ts @@ -1,7 +1,7 @@ import { isJSBlock, isJSExpression, isJSSlot } from '@ali/lowcode-types'; import { isPlainObject } from '@ali/lowcode-utils'; import { globalContext, Editor } from '@ali/lowcode-editor-core'; -import { Designer, LiveEditing, TransformStage, addBuiltinComponentAction } from '@ali/lowcode-designer'; +import { Designer, LiveEditing, TransformStage, addBuiltinComponentAction, Node } from '@ali/lowcode-designer'; import Outline, { OutlineBackupPane, getTreeMaster } from '@ali/lowcode-plugin-outline-pane'; import { toCss } from '@ali/vu-css-style'; @@ -44,6 +44,23 @@ designer.addPropsReducer((props, node) => { // 国际化渲染时处理 designer.addPropsReducer(i18nReducer, TransformStage.Render); +function filterReducer(props: any, node: Node): any { + const filters = node.componentMeta.getMetadata().experimental?.filters; + if (filters && filters.length) { + const newProps = { ...props }; + filters.forEach((item) => { + const v = item.filter(node as any, props[item.name]); + if (!v) { + delete newProps[item.name]; + } + }); + return newProps; + } + return props; +} +designer.addPropsReducer(filterReducer, TransformStage.Save); +designer.addPropsReducer(filterReducer, TransformStage.Render); + function upgradePropsReducer(props: any) { if (!isPlainObject(props)) { return props;