diff --git a/packages/demo/package.json b/packages/demo/package.json index 9ff3918c5..562476b97 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -40,7 +40,8 @@ "@alife/theme-lowcode-dark": "^0.1.0", "@alife/theme-lowcode-light": "^0.1.0", "react": "^16.8.1", - "react-dom": "^16.8.1" + "react-dom": "^16.8.1", + "@ali/vu-function-parser": "^2.5.0-beta.0" }, "devDependencies": { "@ali/iceluna-cli": "^0.0.16", diff --git a/packages/demo/src/vision/index.ts b/packages/demo/src/vision/index.ts index 36eac68c2..157b496a3 100644 --- a/packages/demo/src/vision/index.ts +++ b/packages/demo/src/vision/index.ts @@ -1,7 +1,7 @@ /* eslint-disable */ import { createElement } from 'react'; import { Button } from '@alifd/next'; -import Engine, { Panes } from '@ali/visualengine'; +import Engine, { Panes, Prototype } from '@ali/visualengine'; import { ActionUtil as actionUtil } from '@ali/visualengine-utils'; import getTrunkPane from '@ali/ve-trunk-pane'; import DatapoolPane from '@ali/ve-datapool-pane'; @@ -18,6 +18,9 @@ import { upgradeAssetsBundle } from './upgrade-assets'; import { isCSSUrl } from '@ali/lowcode-utils'; import { I18nSetter } from '@ali/visualengine-utils'; import VariableSetter from '@ali/vs-variable-setter'; +import { isObject, isArray } from 'lodash'; +import funcParser from '@ali/vu-function-parser'; + const { editor, skeleton, context, HOOKS, Trunk } = Engine; @@ -324,6 +327,30 @@ function initActionPane() { props, }); } +function replaceFuncProp(props?: any){ + const replaceProps = {}; + for (const name in props) { + const prop = props[name]; + if (!prop) { + continue; + } + if ((prop.compiled && prop.source) || prop.type === 'actionRef' || prop.type === 'js') { + replaceProps[name] = funcParser(prop); + } else if (isObject(prop)) { + replaceFuncProp(prop); + } else if (isArray(prop)) { + prop.map((propItem) => { + replaceFuncProp(propItem); + }); + } + } + + for (const name in replaceProps) { + props[name] = replaceProps[name]; + } + + return props; +}; // 操作历史与页面历史面板 function initHistoryPane() { @@ -388,6 +415,7 @@ async function init() { subview: true, i18nPane: true, }); + Prototype.addGlobalPropsReducer(replaceFuncProp); await loadAssets(); await loadSchema(); await initTrunkPane(); @@ -396,7 +424,6 @@ async function init() { initActionPane(); initDemoPanes(); initHistoryPane(); - Engine.init(); } init(); diff --git a/packages/demo/src/vision/module.d.ts b/packages/demo/src/vision/module.d.ts index c7fdc6942..ba843aea9 100644 --- a/packages/demo/src/vision/module.d.ts +++ b/packages/demo/src/vision/module.d.ts @@ -9,3 +9,4 @@ declare module '@ali/ve-page-history'; declare module '@ali/ve-i18n-manage-pane'; declare module '@ali/ve-action-pane'; declare module '@ali/vu-legao-design-fetch-context'; +declare module "@ali/vu-function-parser"; diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 9f19ce0eb..4cc95b4e1 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -155,6 +155,7 @@ export class Node { private transformProps(props: any): any { // FIXME! support PropsList return this.document.designer.transformProps(props, this, TransformStage.Init); + // TODO: run transducers in metadata.experimental } diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index fcb37a8a3..39436aaec 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -52,17 +52,17 @@ export class Prop implements IPropParent { if (type === 'slot') { const schema = this._slotNode!.export(stage); - if (stage === TransformStage.Save) { + if (stage === TransformStage.Render) { return { type: 'JSSlot', params: schema.params, - value: schema.children, + value: schema, }; } return { type: 'JSSlot', params: schema.params, - value: schema, + value: schema.children, }; } diff --git a/packages/editor-skeleton/src/components/mixed-setter/index.tsx b/packages/editor-skeleton/src/components/mixed-setter/index.tsx index 1adafc6eb..6f5ddeeeb 100644 --- a/packages/editor-skeleton/src/components/mixed-setter/index.tsx +++ b/packages/editor-skeleton/src/components/mixed-setter/index.tsx @@ -121,16 +121,22 @@ export default class MixedSetter extends Component<{ @computed private getCurrentSetter() { const { field } = this.props; let firstMatched: SetterItem | undefined; + let firstDefault: SetterItem | undefined; for (const setter of this.setters) { if (setter.name === this.used) { return setter; } - const matched = !setter.condition || setter.condition(field); - if (matched && !firstMatched) { + if (!setter.condition) { + if (!firstDefault) { + firstDefault = setter; + } + continue; + } + if (!firstMatched && setter.condition(field)) { firstMatched = setter; } } - return firstMatched; + return firstMatched || firstDefault || this.setters[0]; } // dirty fix vision variable setter logic @@ -151,14 +157,19 @@ export default class MixedSetter extends Component<{ const setter = this.setters.find((item) => item.name === name); this.used = name; if (setter) { - let newValue: any = setter.initialValue; - if (newValue && typeof newValue === 'function') { - newValue = newValue(field); - } - onChange && onChange(newValue); + this.handleInitial(setter); } }; + private handleInitial({ initialValue }: SetterItem) { + const { field, onChange } = this.props; + let newValue: any = initialValue; + if (newValue && typeof newValue === 'function') { + newValue = newValue(field); + } + onChange && onChange(newValue); + } + private shell: HTMLDivElement | null = null; private checkIsBlockField() { if (this.shell) { @@ -207,6 +218,9 @@ export default class MixedSetter extends Component<{ field, ...restProps, ...extraProps, + onInitial: () => { + this.handleInitial(currentSetter); + } }); } diff --git a/packages/editor-skeleton/src/components/mixed-setter/style.less b/packages/editor-skeleton/src/components/mixed-setter/style.less index d277ae322..5d6f31674 100644 --- a/packages/editor-skeleton/src/components/mixed-setter/style.less +++ b/packages/editor-skeleton/src/components/mixed-setter/style.less @@ -25,7 +25,7 @@ border-radius: 3px; } } - .next-input,.next-date-picker { + .next-input,.next-date-picker,.next-month-picker { width: 100%; } &.lc-block-setter { diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index 9b6e377a6..0ab2ce23a 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -20,6 +20,7 @@ class SettingFieldView extends Component<{ field: SettingField }> { let setterProps: any = {}; let setterType: any; + let initialValue: any = null; if (Array.isArray(setter)) { setterType = 'MixedSetter'; setterProps = { @@ -33,6 +34,9 @@ class SettingFieldView extends Component<{ field: SettingField }> { setterProps = setterProps(field); } } + if (setter.initialValue != null) { + initialValue = setter.initialValue; + } } else if (setter) { setterType = setter; } @@ -40,6 +44,9 @@ class SettingFieldView extends Component<{ field: SettingField }> { if (field.type === 'field') { if (defaultValue != null && !('defaultValue' in setterProps)) { setterProps.defaultValue = defaultValue; + if (initialValue == null) { + initialValue = defaultValue; + } } if (field.valueState > 0) { value = field.getValue(); @@ -79,6 +86,16 @@ class SettingFieldView extends Component<{ field: SettingField }> { }); field.setValue(value); }, + onInitial: () => { + if (initialValue == null) { + return; + } + const value = typeof initialValue === 'function' ? initialValue(field) : initialValue; + this.setState({ + value, + }); + field.setValue(value); + } }), extraProps.forceInline ? 'plain' : extraProps.display, ); diff --git a/packages/editor-skeleton/src/components/slot-setter/index.less b/packages/editor-skeleton/src/components/slot-setter/index.less new file mode 100644 index 000000000..230032716 --- /dev/null +++ b/packages/editor-skeleton/src/components/slot-setter/index.less @@ -0,0 +1,7 @@ +.lc-setter-slot { + display: flex; + align-items: center; + .lc-slot-params { + margin-left: 5px; + } +} diff --git a/packages/editor-skeleton/src/components/slot-setter/index.tsx b/packages/editor-skeleton/src/components/slot-setter/index.tsx new file mode 100644 index 000000000..344a2a2a3 --- /dev/null +++ b/packages/editor-skeleton/src/components/slot-setter/index.tsx @@ -0,0 +1,97 @@ +import { Component } from 'react'; +import { isJSSlot } from '@ali/lowcode-types'; +import { Button, Input, Icon } from '@alifd/next'; +import './index.less'; + +export default class SlotSetter extends Component<{ + value: any; + onChange?: (value: any) => void; + onInitial?: () => void; + // 是否支持设置入参 + supportParams?: boolean; +}> { + private handleInitial = () => { + const { value, onChange, onInitial } = this.props; + if (onInitial) { + onInitial(); + return; + } + if (!onChange) { + return; + } + onChange({ + type: 'JSSlot', + value: null, + }); + }; + render() { + const { value, onChange, supportParams } = this.props; + if (!isJSSlot(value)) { + return ( + + ); + } + const hasParams = value.params && Array.isArray(value.params); + return ( +
+ + {hasParams ? ( + { + val = val.trim(); + const params = val ? val.split(/ *, */) : []; + onChange && + onChange({ + ...value, + params, + }); + }} + addonAfter={ + + } + /> + ) : supportParams ? ( + + ) : null} +
+ ); + } +} diff --git a/packages/editor-skeleton/src/register-defaults.ts b/packages/editor-skeleton/src/register-defaults.ts index 63bf0dd90..3c114e43d 100644 --- a/packages/editor-skeleton/src/register-defaults.ts +++ b/packages/editor-skeleton/src/register-defaults.ts @@ -6,6 +6,8 @@ import MixedSetter from './components/mixed-setter'; import { isPlainObject } from '@ali/lowcode-utils'; import parseProps from './transducers/parse-props'; import addonCombine from './transducers/addon-combine'; +import SlotSetter from './components/slot-setter'; +import { isJSSlot } from '@ali/lowcode-types'; registerSetter('ArraySetter', { component: ArraySetter, @@ -30,6 +32,27 @@ registerSetter('ObjectSetter', { initialValue: {}, recommend: true, }); +registerSetter('SlotSetter', { + component: SlotSetter, + title: { + type: 'i18n', + 'zh-CN': '插槽输入', + 'en-US': 'Slot Setter' + }, + condition: (field: any) => { + return isJSSlot(field.getValue()); + }, + initialValue: (field: any, value: any) => { + if (isJSSlot(value)) { + return value; + } + return { + type: 'JSSlot', + value: value + }; + }, + recommend: true, +}); registerSetter('MixedSetter', MixedSetter); // parseProps diff --git a/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx b/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx index 5f3923042..70992e246 100644 --- a/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx +++ b/packages/material-parser/test/fixtures/fusion-next-component/src/calendar/calendar.jsx @@ -334,7 +334,7 @@ class Calendar extends Component { [CALENDAR_MODE_MONTH]: , [CALENDAR_MODE_YEAR]: , }; - + return (
{ - if (!container) { - container = document.createElement('div'); - document.body.appendChild(container); - } - container.id = 'engine'; - ReactDOM.render(, container); - }, - - /** - * VE.modules.xxx - * - * VE BuildIn Modules - */ - modules: { - // SchemaManager, 没看到使用的地方 - // VisualDesigner, 没看到使用的地方 - VisualManager // legao-designer 有用 - // VisualRender, 没看到使用的地方 - I18nUtil, // vs-list vs-rhino-widget-mapping - Prop, // vs-list vs-rhino-widget-mapping - /* 没看到使用的地方 - Node, - Props, - - Scroller, - Insertion, - */ - }, - - /** - * VE Utils - */ - utils, - /* 包抽象 */ - Bundle, - - /* pub/sub 集线器 */ - // ve-quick-search-pane, ve-section-pane vp-in-place-editing ve-action-save - // ve-page-history vs-q-chart-data ve-action-pane ve-page-lock-pane - // ve-datapool-pane ve-youshu-card-param-pane - Bus, - - /* 拖拽引擎 */ - DragEngine, // 在 ve-metadata-pane, ve-section-pane, ve-trunk-pane-simple, ve-trunk-pane 中有用 - - /* 环境变量 */ - // vu-oneapi-parser vu-events-property ve-section-pane vs-formula vu-link-property - // ve-datapool-pane vs-form-validator vs-style vs-link vs-micro-link vs-link-options vu-field-property - Env, - - /* 状态交换 */ - // - Exchange, - - /* 状态 Flags */ - // legao-design tree-pane - Flags, - - /* 快捷键 */ - // legao-design - Hotkey, - - /* 多语言文案 */ - I18nUtil, - - /* 页面管理 */ - Pages, - - /* 面板管理 */ - Panes, - - /* 应用管理 */ - Project, - - /* 包原型 */ - Prototype, - - /* 组件仓库 */ - Trunk, - - /* 事件 */ - EVENTS: VE_EVENTS, // legao-design - - /* 修饰方法 */ - HOOKS: VE_HOOKS, // legao-design vu-visualpage-rax - - /* 视图管理 */ - Viewport, - - /* Symbol 管理类 */ - Symbols, // legao-design vu-action-util - - /** - * VisualEngine Logger Tool - */ - // lg: logger, 没看到使用的地方 - // logger, - - /* 版本号 */ - // Version: VERSION, - - // Location, - // Node, - // VirtualRenderingNode -} diff --git a/packages/vision-preset/src/bundle/prototype.ts b/packages/vision-preset/src/bundle/prototype.ts index 8fa44e3cd..f7b291873 100644 --- a/packages/vision-preset/src/bundle/prototype.ts +++ b/packages/vision-preset/src/bundle/prototype.ts @@ -5,6 +5,7 @@ import { addBuiltinComponentAction, isComponentMeta, registerMetadataTransducer, + TransformStage, } from '@ali/lowcode-designer'; import { OldPropConfig, @@ -112,9 +113,10 @@ function addGlobalExtraActions(action: () => ReactElement) { upgradeActions(action)?.forEach(addBuiltinComponentAction); } -const GlobalPropsReducers: any[] = []; +// const GlobalPropsReducers: any[] = []; function addGlobalPropsReducer(reducer: () => any) { - GlobalPropsReducers.push(reducer); + // GlobalPropsReducers.push(reducer); + designer.addPropsReducer(reducer, TransformStage.Render); } export interface OldGlobalPropConfig extends OldPropConfig { diff --git a/packages/vision-preset/src/editor.ts b/packages/vision-preset/src/editor.ts index 61d3b0843..333e1a42f 100644 --- a/packages/vision-preset/src/editor.ts +++ b/packages/vision-preset/src/editor.ts @@ -1,6 +1,6 @@ -import { isJSBlock } from '@ali/lowcode-types'; +import { isJSBlock, isJSSlot } from '@ali/lowcode-types'; import { isPlainObject } from '@ali/lowcode-utils'; -import { globalContext, Editor } from '@ali/lowcode-editor-core'; +import { globalContext, Editor, registerSetter } from '@ali/lowcode-editor-core'; import { Designer, TransformStage } from '@ali/lowcode-designer'; // import { registerSetters } from '@ali/lowcode-setters'; import Outline from '@ali/lowcode-plugin-outline-pane'; @@ -11,8 +11,6 @@ import Preview from '@ali/lowcode-plugin-sample-preview'; // import SourceEditor from '@ali/lowcode-plugin-source-editor'; import { i18nReducer } from './i18n-reducer'; -// registerSetters(); - export const editor = new Editor(); globalContext.register(editor, Editor); diff --git a/packages/vision-preset/src/i18n-reducer.ts b/packages/vision-preset/src/i18n-reducer.ts index 1c8511840..693ee0cae 100644 --- a/packages/vision-preset/src/i18n-reducer.ts +++ b/packages/vision-preset/src/i18n-reducer.ts @@ -9,7 +9,6 @@ interface I18nObject { } export function i18nReducer(obj?: any): any { - console.info(obj); if (!obj) { return obj; } if (Array.isArray(obj)) { return obj.map((item) => i18nReducer(item)); diff --git a/packages/vision-preset/src/vision.less b/packages/vision-preset/src/vision.less index b87da9230..d0c17fcc0 100644 --- a/packages/vision-preset/src/vision.less +++ b/packages/vision-preset/src/vision.less @@ -85,6 +85,18 @@ html.engine-blur #engine { white-space: nowrap; } + +// dirty fix override vision reset +.engine-design-mode { + .next-input-group, + .next-checkbox-group,.next-date-picker,.next-input,.next-month-picker, + .next-number-picker,.next-radio-group,.next-range,.next-range-picker, + .next-rating,.next-select,.next-switch,.next-time-picker,.next-upload, + .next-year-picker { + pointer-events: auto !important; + } +} + .lc-left-float-pane { font-size: 14px; }