mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: 编辑器【链式下拉框】、【下拉按钮】支持新版外观配置 (#11026)
* feat: 编辑器链式下拉框支持新版外观配置 * feat: 下拉按钮支持外观配置 --------- Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com>
This commit is contained in:
parent
7f3aa7e39b
commit
0d5606c5b5
@ -13,6 +13,7 @@ import {getEventControlConfig} from '../renderer/event-control/helper';
|
||||
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
|
||||
import type {SchemaObject} from 'amis';
|
||||
import {getOldActionSchema} from '../renderer/event-control/helper';
|
||||
import {buttonStateFunc} from '../renderer/style-control/helper';
|
||||
|
||||
export class ButtonPlugin extends BasePlugin {
|
||||
static id = 'ButtonPlugin';
|
||||
@ -133,56 +134,6 @@ export class ButtonPlugin extends BasePlugin {
|
||||
// const isInDropdown = /(?:\/|^)dropdown-button\/.+$/.test(context.path);
|
||||
const isInDropdown = /^button-group\/.+$/.test(context.path);
|
||||
|
||||
const buttonStateFunc = (visibleOn: string, state: string) => {
|
||||
return [
|
||||
getSchemaTpl('theme:font', {
|
||||
label: '文字',
|
||||
name: `themeCss.className.font:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: {
|
||||
'color': `--button-\${level || "default"}-${state}-font-color`,
|
||||
'*': '--button-size-${size || "default"}'
|
||||
},
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:colorPicker', {
|
||||
label: '背景',
|
||||
name: `themeCss.className.background:${state}`,
|
||||
labelMode: 'input',
|
||||
needGradient: true,
|
||||
needImage: true,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: `--button-\${level || "default"}-${state}-bg-color`,
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:border', {
|
||||
name: `themeCss.className.border:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: `--button-\${level || "default"}-${state}`,
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:paddingAndMargin', {
|
||||
name: `themeCss.className.padding-and-margin:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: '--button-size-${size || "default"}',
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:radius', {
|
||||
name: `themeCss.className.radius:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: '--button-size-${size || "default"}',
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
label: '图标尺寸',
|
||||
name: `themeCss.iconClassName.iconSize:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: '--button-size-${size || "default"}-icon-size',
|
||||
state
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
return getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '属性',
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
diff
|
||||
} from 'amis-editor-core';
|
||||
import {BUTTON_DEFAULT_ACTION} from '../component/BaseControl';
|
||||
import {buttonStateFunc} from '../renderer/style-control/helper';
|
||||
export class DropDownButtonPlugin extends BasePlugin {
|
||||
static id = 'DropDownButtonPlugin';
|
||||
static scene = ['layout'];
|
||||
@ -162,6 +163,38 @@ export class DropDownButtonPlugin extends BasePlugin {
|
||||
})
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
title: '基本样式',
|
||||
body: [
|
||||
{
|
||||
type: 'select',
|
||||
name: '__editorState',
|
||||
label: '状态',
|
||||
selectFirst: true,
|
||||
options: [
|
||||
{
|
||||
label: '常规',
|
||||
value: 'default'
|
||||
},
|
||||
{
|
||||
label: '悬浮',
|
||||
value: 'hover'
|
||||
},
|
||||
{
|
||||
label: '点击',
|
||||
value: 'active'
|
||||
}
|
||||
]
|
||||
},
|
||||
...buttonStateFunc(
|
||||
"${__editorState == 'default' || !__editorState}",
|
||||
'default'
|
||||
),
|
||||
...buttonStateFunc("${__editorState == 'hover'}", 'hover'),
|
||||
...buttonStateFunc("${__editorState == 'active'}", 'active')
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '图标',
|
||||
body: [
|
||||
@ -185,6 +218,14 @@ export class DropDownButtonPlugin extends BasePlugin {
|
||||
})
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode', {
|
||||
themeClass: [
|
||||
{
|
||||
value: '',
|
||||
state: ['default', 'hover', 'active']
|
||||
}
|
||||
]
|
||||
}),
|
||||
getSchemaTpl('style:classNames', {
|
||||
isFormItem: false,
|
||||
schema: [
|
||||
|
@ -19,6 +19,7 @@ import {ValidatorTag} from '../../validator';
|
||||
import {getEventControlConfig} from '../../renderer/event-control/helper';
|
||||
import type {Schema} from 'amis';
|
||||
import {resolveOptionEventDataSchame} from '../../util';
|
||||
import {inputStateTpl} from '../../renderer/style-control/helper';
|
||||
|
||||
export class ChainedSelectControlPlugin extends BasePlugin {
|
||||
static id = 'ChainedSelectControlPlugin';
|
||||
@ -210,15 +211,32 @@ export class ChainedSelectControlPlugin extends BasePlugin {
|
||||
title: '外观',
|
||||
body: [
|
||||
getSchemaTpl('collapseGroup', [
|
||||
getSchemaTpl('style:formItem', {renderer: context.info.renderer}),
|
||||
getSchemaTpl('style:classNames', {
|
||||
schema: [
|
||||
getSchemaTpl('className', {
|
||||
name: 'descriptionClassName',
|
||||
label: '描述'
|
||||
})
|
||||
getSchemaTpl('theme:formItem'),
|
||||
getSchemaTpl('theme:form-label'),
|
||||
getSchemaTpl('theme:form-description'),
|
||||
{
|
||||
title: '选择框样式',
|
||||
body: [
|
||||
...inputStateTpl(
|
||||
'themeCss.chainedSelectControlClassName',
|
||||
'--chained-select'
|
||||
)
|
||||
]
|
||||
})
|
||||
},
|
||||
{
|
||||
title: '下拉框样式',
|
||||
body: [
|
||||
...inputStateTpl(
|
||||
'themeCss.chainedSelectPopoverClassName',
|
||||
'--chained-select',
|
||||
{
|
||||
state: ['default', 'hover', 'focused']
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:cssCode'),
|
||||
getSchemaTpl('style:classNames')
|
||||
])
|
||||
]
|
||||
},
|
||||
|
@ -108,3 +108,53 @@ export const inputStateFunc = (
|
||||
...options
|
||||
];
|
||||
};
|
||||
|
||||
export const buttonStateFunc = (visibleOn: string, state: string) => {
|
||||
return [
|
||||
getSchemaTpl('theme:font', {
|
||||
label: '文字',
|
||||
name: `themeCss.className.font:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: {
|
||||
'color': `--button-\${level || "default"}-${state}-font-color`,
|
||||
'*': '--button-size-${size || "default"}'
|
||||
},
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:colorPicker', {
|
||||
label: '背景',
|
||||
name: `themeCss.className.background:${state}`,
|
||||
labelMode: 'input',
|
||||
needGradient: true,
|
||||
needImage: true,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: `--button-\${level || "default"}-${state}-bg-color`,
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:border', {
|
||||
name: `themeCss.className.border:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: `--button-\${level || "default"}-${state}`,
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:paddingAndMargin', {
|
||||
name: `themeCss.className.padding-and-margin:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: '--button-size-${size || "default"}',
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:radius', {
|
||||
name: `themeCss.className.radius:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: '--button-size-${size || "default"}',
|
||||
state
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
label: '图标尺寸',
|
||||
name: `themeCss.iconClassName.iconSize:${state}`,
|
||||
visibleOn: visibleOn,
|
||||
editorValueToken: '--button-size-${size || "default"}-icon-size',
|
||||
state
|
||||
})
|
||||
];
|
||||
};
|
||||
|
@ -85,6 +85,7 @@ export interface OptionProps {
|
||||
virtualThreshold?: number; // 数据量多大的时候开启虚拟渲染
|
||||
hasError?: boolean;
|
||||
block?: boolean;
|
||||
controlStyle?: any;
|
||||
onAdd?: (
|
||||
idx?: number | Array<number>,
|
||||
value?: any,
|
||||
@ -1329,7 +1330,8 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
||||
mobileUI,
|
||||
hasError,
|
||||
testIdBuilder,
|
||||
loadingConfig
|
||||
loadingConfig,
|
||||
controlStyle
|
||||
} = this.props;
|
||||
|
||||
const selection = this.state.selection;
|
||||
@ -1378,6 +1380,7 @@ export class Select extends React.Component<SelectProps, SelectState> {
|
||||
className
|
||||
)}
|
||||
data-amis-name={this.props.dataName}
|
||||
style={controlStyle}
|
||||
>
|
||||
<div
|
||||
className={cx(`Select-valueWrap`, {
|
||||
|
@ -1,5 +1,11 @@
|
||||
import React from 'react';
|
||||
import {createObject, Renderer, RendererProps} from 'amis-core';
|
||||
import {
|
||||
createObject,
|
||||
CustomStyle,
|
||||
Renderer,
|
||||
RendererProps,
|
||||
setThemeClassName
|
||||
} from 'amis-core';
|
||||
import {Overlay} from 'amis-core';
|
||||
import {PopOver} from 'amis-core';
|
||||
import {TooltipWrapper} from 'amis-ui';
|
||||
@ -433,7 +439,10 @@ export default class DropDownButton extends React.Component<
|
||||
data,
|
||||
hideCaret,
|
||||
env,
|
||||
testIdBuilder
|
||||
testIdBuilder,
|
||||
id,
|
||||
wrapperCustomStyle,
|
||||
themeCss
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -478,13 +487,49 @@ export default class DropDownButton extends React.Component<
|
||||
'Button--primary': primary,
|
||||
'Button--iconOnly': iconOnly
|
||||
},
|
||||
`Button--size-${size}`
|
||||
`Button--size-${size}`,
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'wrapperCustomStyle',
|
||||
id,
|
||||
themeCss: wrapperCustomStyle
|
||||
}),
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'className',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
>
|
||||
<Icon c={cx} icon={icon} className="icon m-r-xs" />
|
||||
<Icon
|
||||
c={cx}
|
||||
icon={icon}
|
||||
className={cx(
|
||||
'icon m-r-xs',
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'iconClassName',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
/>
|
||||
{typeof label === 'string' ? filter(label, data) : label}
|
||||
{rightIcon && (
|
||||
<Icon cx={cx} icon={rightIcon} className="icon m-l-xs" />
|
||||
<Icon
|
||||
cx={cx}
|
||||
icon={rightIcon}
|
||||
className={cx(
|
||||
'icon m-l-xs',
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'iconClassName',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{!hideCaret ? (
|
||||
<span className={cx('DropDown-caret')}>
|
||||
@ -494,6 +539,43 @@ export default class DropDownButton extends React.Component<
|
||||
</button>
|
||||
</TooltipWrapper>
|
||||
{this.state.isOpened ? this.renderOuter() : null}
|
||||
|
||||
<CustomStyle
|
||||
{...this.props}
|
||||
config={{
|
||||
themeCss: themeCss,
|
||||
classNames: [
|
||||
{
|
||||
key: 'className',
|
||||
weights: {
|
||||
hover: {
|
||||
suf: ':not(:disabled):not(.is-disabled)'
|
||||
},
|
||||
active: {suf: ':not(:disabled):not(.is-disabled)'}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'iconClassName',
|
||||
weights: {
|
||||
default: {
|
||||
important: true
|
||||
},
|
||||
hover: {
|
||||
important: true,
|
||||
suf: ':not(:disabled):not(.is-disabled)'
|
||||
},
|
||||
active: {
|
||||
important: true,
|
||||
suf: ':not(:disabled):not(.is-disabled)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
wrapperCustomStyle,
|
||||
id
|
||||
}}
|
||||
env={env}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ import {
|
||||
Option,
|
||||
FormOptionsControl,
|
||||
resolveEventData,
|
||||
getVariable
|
||||
getVariable,
|
||||
setThemeClassName,
|
||||
CustomStyle
|
||||
} from 'amis-core';
|
||||
import {Select, Spinner} from 'amis-ui';
|
||||
import {Api, ApiObject} from 'amis-core';
|
||||
@ -327,6 +329,7 @@ export default class ChainedSelectControl extends React.Component<
|
||||
mobileUI,
|
||||
env,
|
||||
testIdBuilder,
|
||||
popoverClassName,
|
||||
...rest
|
||||
} = this.props;
|
||||
const arr = Array.isArray(value)
|
||||
@ -335,6 +338,8 @@ export default class ChainedSelectControl extends React.Component<
|
||||
? value.split(delimiter || ',')
|
||||
: [];
|
||||
|
||||
const {themeCss, id} = this.props;
|
||||
|
||||
const hasStackLoading = this.state.stack.find((a: StackItem) => a.loading);
|
||||
|
||||
return (
|
||||
@ -347,6 +352,24 @@ export default class ChainedSelectControl extends React.Component<
|
||||
? env?.getModalContainer
|
||||
: rest.popOverContainer || env?.getModalContainer
|
||||
}
|
||||
className={cx(
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'chainedSelectControlClassName',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
popoverClassName={cx(
|
||||
popoverClassName,
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'chainedSelectPopoverClassName',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
controlStyle={style}
|
||||
classPrefix={ns}
|
||||
key="base"
|
||||
testIdBuilder={testIdBuilder?.getChild('base')}
|
||||
@ -375,6 +398,24 @@ export default class ChainedSelectControl extends React.Component<
|
||||
value={arr[index + 1]}
|
||||
onChange={this.handleChange.bind(this, index + 1)}
|
||||
inline
|
||||
controlStyle={style}
|
||||
className={cx(
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'chainedSelectControlClassName',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
popoverClassName={cx(
|
||||
popoverClassName,
|
||||
setThemeClassName({
|
||||
...this.props,
|
||||
name: 'chainedSelectPopoverClassName',
|
||||
id,
|
||||
themeCss: themeCss
|
||||
})
|
||||
)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
@ -385,6 +426,41 @@ export default class ChainedSelectControl extends React.Component<
|
||||
className={cx(`${ns}ChainedSelectControl-spinner`)}
|
||||
/>
|
||||
)}
|
||||
<CustomStyle
|
||||
{...this.props}
|
||||
config={{
|
||||
themeCss: themeCss,
|
||||
classNames: [
|
||||
{
|
||||
key: 'chainedSelectControlClassName',
|
||||
weights: {
|
||||
focused: {
|
||||
suf: '.is-opened:not(.is-mobile)'
|
||||
},
|
||||
disabled: {
|
||||
suf: '.is-disabled'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'chainedSelectPopoverClassName',
|
||||
weights: {
|
||||
default: {
|
||||
suf: ` .${ns}Select-option`
|
||||
},
|
||||
hover: {
|
||||
suf: ` .${ns}Select-option.is-highlight`
|
||||
},
|
||||
focused: {
|
||||
inner: `.${ns}Select-option.is-active`
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
id: id
|
||||
}}
|
||||
env={env}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user