diff --git a/src/index.tsx b/src/index.tsx index 225ac89..4bd8bb4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -23,6 +23,7 @@ import TextAreaSetter from './setter/textarea-setter'; import ArraySetter from './setter/array-setter'; import ObjectSetter from './setter/object-setter'; import VariableSetter from './setter/variable-setter'; +import ResetSetter from './setter/reset-setter'; import TitleSetter from './setter/title-setter'; import EventBindDialog from './plugin/plugin-event-bind-dialog'; import VariableBindDialog from './plugin/plugin-variable-bind-dialog'; @@ -100,6 +101,11 @@ const DataVariableSetter = { recommend: true, }; +const ResetSetterWrapper = { + component: ResetSetter, + title: '重置属性', +} + const FunctionBindSetter = { component: FunctionSetter, title: '函数绑定', @@ -172,6 +178,7 @@ const engineExt = { BoolSetter, SelectSetter, VariableSetter: DataVariableSetter, + ResetSetter: ResetSetterWrapper, ExpressionSetter: DataExpressionSetter, RadioGroupSetter, TextAreaSetter, @@ -201,6 +208,7 @@ const engineExt = { BoolSetter, SelectSetter, VariableSetter: DataVariableSetter, + ResetSetter: ResetSetterWrapper, ExpressionSetter: DataExpressionSetter, RadioGroupSetter, TextAreaSetter, diff --git a/src/plugin/plugin-variable-bind-dialog/index.tsx b/src/plugin/plugin-variable-bind-dialog/index.tsx index 1340e83..31d7135 100644 --- a/src/plugin/plugin-variable-bind-dialog/index.tsx +++ b/src/plugin/plugin-variable-bind-dialog/index.tsx @@ -332,6 +332,7 @@ export default class VariableBindDialog extends Component { }; onOk = (autoSave) => { + event.emit('variableSetter.selectVariableSetter') const { field, jsCode } = this.state; const fieldValue = field.getValue(); field.setValue({ diff --git a/src/setter/mixed-setter/icons/reset.tsx b/src/setter/mixed-setter/icons/reset.tsx new file mode 100644 index 0000000..e56a33f --- /dev/null +++ b/src/setter/mixed-setter/icons/reset.tsx @@ -0,0 +1,10 @@ +import { IconProps, SVGIcon } from '@alilc/lowcode-utils'; + +export function ResetIcon(props: IconProps) { + return ( + + + + ); +} +ResetIcon.displayName = 'Reset'; \ No newline at end of file diff --git a/src/setter/mixed-setter/index.less b/src/setter/mixed-setter/index.less index 95cca5f..b4a238d 100644 --- a/src/setter/mixed-setter/index.less +++ b/src/setter/mixed-setter/index.less @@ -70,3 +70,7 @@ transform: none; } } + +.lc-setter-mixed.lc-setter-mixeds { + margin-right: 46px; +} \ No newline at end of file diff --git a/src/setter/mixed-setter/index.tsx b/src/setter/mixed-setter/index.tsx index 708f99a..3200b3c 100644 --- a/src/setter/mixed-setter/index.tsx +++ b/src/setter/mixed-setter/index.tsx @@ -1,7 +1,7 @@ import React, { Component, ComponentClass, ReactNode } from 'react'; import classNames from 'classnames'; import { Dropdown, Menu } from '@alifd/next'; -import { common, setters, SettingField } from '@alilc/lowcode-engine'; +import { common, setters, SettingField, event } from '@alilc/lowcode-engine'; import { SetterConfig, CustomView, @@ -16,6 +16,7 @@ import { intlNode } from './locale'; import './index.less'; import { IconVariable } from './icons/variable'; +import { ResetIcon } from './icons/reset'; const { editorCabin } = common; const { computed, obx, Title, createSetterContent, observer, shallowIntl } = editorCabin; @@ -183,6 +184,7 @@ export default class MixedSetter extends Component<{ firstMatched = setter; } } + this.used = (firstMatched || firstDefault || this.setters[0]).name; return firstMatched || firstDefault || this.setters[0]; } @@ -198,6 +200,8 @@ export default class MixedSetter extends Component<{ // dirty fix vision variable setter logic private hasVariableSetter = this.setters.some((item) => item.name === 'VariableSetter'); + private hasResetSetter = this.setters.some((item) => item.name === 'ResetSetter'); + private useSetter = (name: string, usedName: string) => { this.fromMixedSetterSelect = true; const { field } = this.props; @@ -285,6 +289,9 @@ export default class MixedSetter extends Component<{ componentDidMount() { this.checkIsBlockField(); + event.on('common:variableSetter.selectVariableSetter',() => { + this.used='VariableSetter' + }) } private renderCurrentSetter(currentSetter?: SetterItem, extraProps?: object) { @@ -403,6 +410,137 @@ export default class MixedSetter extends Component<{ }; } + private contentsFromPolyfill2() { + const { field } = this.props; + + const setterNum = this.setters.length; + if (setterNum < 4) { + return this.handleSettersLessThanFour(field, setterNum); + } else { + return this.handleSettersGreaterThanThree(field); + } + + } + handleSettersLessThanFour(field: SettingField, setterNum: number) { + if (setterNum === 1) { + // return { actions: this.handleResetSetterAction() } + } + if (setterNum === 2) { + return this.handleTwoSetters(field); + } + if (setterNum === 3) { + return this.handleThreeSetters(field) + } + } + + handleTwoSetters(field: SettingField) { + const otherSetter = this.setters.find((item) => item.name !== 'ResetSetter')!; + if (otherSetter.name === 'VariableSetter') { + return { + setterContent: this.renderVariableSetterContent(field), + actions: this.handleResetSetterAction(), + } + } + return { + setterContent: this.renderCurrentSetter(otherSetter, { + value: field.getMockOrValue(), + }), + actions: this.handleResetSetterAction(), + } + } + + renderVariableSetterContent(field: SettingField) { + const tipContent = field.isUseVariable() + ? intlNode('Binded: {expr}', { expr: field.getValue()?.value }) + : intlNode('Variable Binding'); + const variableSetterComponent = getSetter('VariableSetter')?.component as any; + return ( + { + variableSetterComponent.show({ prop: field }); + }} + > + {tipContent} + + ) + + } + // 最后一个放resetsetter,如果有variableSetter,则放在第二个位置,其他的放在第一个位置。如果没有variableSetter则使用swtich切换操作 + handleThreeSetters(field: SettingField) { + if (this.setters.some(setter => setter.name === 'VariableSetter') && this.setters.some(setter => setter.name === 'ResetSetter')) { + // 其他放第一个,VariableSetter放第二个,reset放到最后 + const otherSetter = this.setters.find((item) => (item.name !== 'VariableSetter') && (item.name !== 'ResetSetter')) + const otherSetterContent = this.renderCurrentSetter(otherSetter, { + value: field.getMockOrValue(), + }); + // VariableSetter + const variableSetterComponent = getSetter('VariableSetter')?.component as any; + const tipContent = field.isUseVariable() + ? intlNode('Binded: {expr}', { expr: field.getValue()?.value }) + : intlNode('Variable Binding'); + const variableSetterContent = ( + , + tip: tipContent, + }} + onClick={() => { + variableSetterComponent.show({ prop: field }); + }} + /> + ); + return { + setterContent: otherSetterContent, + actions: (<>{variableSetterContent}{this.handleResetSetterAction()}</>), + } + } else { + // switch+reset + const currentSetter = + !this.used && field.isUseVariable() + ? this.setters.find((item) => item.name === 'VariableSetter') + : this.getCurrentSetter(); + return { + setterContent: this.renderCurrentSetter(currentSetter), + actions: (<>{this.renderSwitchAction(currentSetter)}{this.handleResetSetterAction()}</>) + } + } + } + + handleSettersGreaterThanThree(field: SettingField) { + let setterContent: ReactNode; + const currentSetter = + !this.used && field.isUseVariable() + ? this.setters.find((item) => item.name === 'VariableSetter') + : this.getCurrentSetter(); + if (currentSetter?.name === 'VariableSetter') { + const variableSetterComponent = getSetter('VariableSetter')?.component as any; + setterContent = ( + <a + onClick={() => { + variableSetterComponent.show({ prop: field }); + }} + > + {intlNode('Binded: {expr}', { expr: field.getValue()?.value })} + </a> + ); + } else { + setterContent = this.renderCurrentSetter(currentSetter); + } + return { + setterContent, + actions: (<>{this.renderSwitchAction(currentSetter)}{this.handleResetSetterAction()}</>) + } + } + + private getClassName() { + const n = this.setters.length; + if (this.hasResetSetter && n > 2) { + // 通过class来修改样式 + return 'lc-setter-mixeds'; + } + } + private renderSwitchAction(currentSetter?: SetterItem) { const usedName = currentSetter?.name || this.used; const triggerNode = ( @@ -424,7 +562,7 @@ export default class MixedSetter extends Component<{ onItemClick={(name) => this.useSetter(name, usedName)} > {this.setters - .filter((setter) => setter.list || setter.name === usedName) + .filter((setter) => (setter.list || setter.name === usedName) && setter.name!== 'ResetSetter') .map((setter) => { return ( <Menu.Item key={setter.name}> @@ -437,6 +575,39 @@ export default class MixedSetter extends Component<{ ); } + private handleResetSetterAction() { + return (<Title + title={{ + icon: <ResetIcon size={24} />, + tip: intlNode('Reset Attribute'), + }} + onClick={() => this.resetClickHandler()} + />) + } + + resetClickHandler() { + const { onChange, initialValue, field } = this.props; + let newValue = initialValue; + if (field.isUseVariable() || this.used === 'VariableSetter') { + const fieldValue = field.getValue(); + const value = + Object.prototype.toString.call(fieldValue) === '[object Object]' + ? fieldValue.mock + : fieldValue; + // 清除变量绑定 + field.setValue(value); + // 清除标记 + this.used = undefined; + newValue = newValue??value; + } + // fixme 属性为children默认使用StringSetter并且不配置defaultValue时,onChange(null)画布不会更新,so做此处理。例如antd物料的button组件 + if (this.used === 'StringSetter') { + newValue = newValue?? ''; + } + this.used = undefined; + onChange(newValue) + } + render() { const { className } = this.props; let contents: @@ -446,7 +617,9 @@ export default class MixedSetter extends Component<{ } | undefined; - if (this.hasVariableSetter) { + if (this.hasResetSetter) { + contents = this.contentsFromPolyfill2(); + } else if (this.hasVariableSetter) { // polyfill vision variable setter logic const setterComponent = getSetter('VariableSetter')?.component as any; if (setterComponent && setterComponent.isPopup) { @@ -466,7 +639,7 @@ export default class MixedSetter extends Component<{ ref={(shell) => { this.shell = shell; }} - className={classNames('lc-setter-mixed', className)} + className={classNames('lc-setter-mixed', className, this.getClassName())} > {contents.setterContent} <div className="lc-setter-actions">{contents.actions}</div> diff --git a/src/setter/mixed-setter/locale/en-US.json b/src/setter/mixed-setter/locale/en-US.json index 571c555..0b5a5f2 100644 --- a/src/setter/mixed-setter/locale/en-US.json +++ b/src/setter/mixed-setter/locale/en-US.json @@ -5,5 +5,6 @@ "Multiple Value, Click to Clear": "Multiple Value, Click to Clear", "Required": "Required", "Setted Value, Click to Clear": "Setted Value, Click to Clear", - "Multiple Value": "Multiple Value" + "Multiple Value": "Multiple Value", + "Reset Attribute": "Reset Attribute" } diff --git a/src/setter/mixed-setter/locale/zh-CN.json b/src/setter/mixed-setter/locale/zh-CN.json index 0ed1610..38e43bd 100644 --- a/src/setter/mixed-setter/locale/zh-CN.json +++ b/src/setter/mixed-setter/locale/zh-CN.json @@ -5,5 +5,6 @@ "Multiple Value, Click to Clear": "多种值, 点击清除", "Required": "必填项", "Setted Value, Click to Clear": "已设置值,点击清除", - "Multiple Value": "多种值" + "Multiple Value": "多种值", + "Reset Attribute": "重置属性" } diff --git a/src/setter/reset-setter/index.tsx b/src/setter/reset-setter/index.tsx new file mode 100644 index 0000000..a9ca8de --- /dev/null +++ b/src/setter/reset-setter/index.tsx @@ -0,0 +1,12 @@ +import React, { PureComponent } from 'react'; +import { intlNode } from '../mixed-setter/locale'; + +export default class SetterReset extends PureComponent { + static displayName = 'ResetSetter'; + static isPopup = true; + + render() { + const tipContext = intlNode('Reset Attribute'); + return <a > {tipContext} </a>; + } +} \ No newline at end of file diff --git a/src/setter/reset-setter/resetIcon.tsx b/src/setter/reset-setter/resetIcon.tsx new file mode 100644 index 0000000..e56a33f --- /dev/null +++ b/src/setter/reset-setter/resetIcon.tsx @@ -0,0 +1,10 @@ +import { IconProps, SVGIcon } from '@alilc/lowcode-utils'; + +export function ResetIcon(props: IconProps) { + return ( + <SVGIcon viewBox="0 0 1024 1024" {...props}> + <path d="M193.070545 70.353455l5.422546 0.930909A34.909091 34.909091 0 0 1 226.862545 111.709091l-0.023272 0.069818-12.869818 72.541091a448.698182 448.698182 0 0 1 293.888-108.939636c246.830545 0 447.022545 197.911273 447.022545 442.181818s-200.192 442.181818-447.022545 442.181818c-160.186182 0-305.687273-84.084364-385.466182-218.158545a37.794909 37.794909 0 0 1 13.358545-51.921455 38.167273 38.167273 0 0 1 52.154182 13.288727c66.210909 111.243636 186.903273 180.992 319.953455 180.992 204.869818 0 370.850909-164.096 370.850909-366.382545S712.727273 151.179636 507.857455 151.179636c-107.287273 0-206.801455 45.265455-276.317091 121.995637h141.498181a34.909091 34.909091 0 0 1 0 69.818182h-209.454545c-2.606545 0-5.189818-0.279273-7.656727-0.837819a34.629818 34.629818 0 0 1-5.259637-0.512l-5.422545-0.930909a34.909091 34.909091 0 0 1-28.346182-40.494545L152.669091 98.629818a34.909091 34.909091 0 0 1 40.401454-28.276363z" /> + </SVGIcon> + ); +} +ResetIcon.displayName = 'Reset'; \ No newline at end of file