feat: 复选框支持新版外观配置 (#11066)

Co-authored-by: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com>
This commit is contained in:
qkiroc 2024-10-17 16:53:48 +08:00 committed by GitHub
parent 0e2d2de60d
commit 1e5b057988
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 309 additions and 119 deletions

View File

@ -417,7 +417,7 @@ export function insertEditCustomStyle(params: {
} else if (key === 'root') {
const res = map(
styles[key],
(value, key) =>
(value: any, key) =>
`${key}: ${
resolveVariableAndFilter(
value.replace(/['|"]/g, ''),
@ -430,7 +430,7 @@ export function insertEditCustomStyle(params: {
} else if (/^root:/.test(key)) {
const res = map(
styles[key],
(value, key) =>
(value: any, key) =>
`${key}: ${
resolveVariableAndFilter(
value.replace(/['|"]/g, ''),
@ -444,7 +444,7 @@ export function insertEditCustomStyle(params: {
} else {
const res = map(
styles[key],
(value, key) =>
(value: any, key) =>
`${key}: ${
resolveVariableAndFilter(
value.replace(/['|"]/g, ''),

View File

@ -219,7 +219,7 @@ export class ChainedSelectControlPlugin extends BasePlugin {
body: [
...inputStateTpl(
'themeCss.chainedSelectControlClassName',
'--chained-select'
'--select-base'
)
]
},
@ -228,9 +228,13 @@ export class ChainedSelectControlPlugin extends BasePlugin {
body: [
...inputStateTpl(
'themeCss.chainedSelectPopoverClassName',
'--chained-select',
'--select-base-${state}-option',
{
state: ['default', 'hover', 'focused']
state: [
{label: '常规', value: 'default'},
{label: '悬浮', value: 'hover'},
{label: '选中', value: 'focused'}
]
}
)
]

View File

@ -25,6 +25,7 @@ import {
resolveOptionEventDataSchame,
resolveOptionType
} from '../../util';
import {inputStateTpl} from '../../renderer/style-control/helper';
export class CheckboxesControlPlugin extends BasePlugin {
static id = 'CheckboxesControlPlugin';
@ -230,7 +231,70 @@ export class CheckboxesControlPlugin extends BasePlugin {
title: '外观',
body: [
getSchemaTpl('collapseGroup', [
getSchemaTpl('style:formItem', {renderer}),
getSchemaTpl('theme:formItem', {hidSize: true}),
getSchemaTpl('theme:form-label'),
getSchemaTpl('theme:form-description'),
{
title: '勾选框样式',
body: [
...inputStateTpl('themeCss.checkboxesClassName', '--checkbox', {
hideFont: true,
hideMargin: true,
hidePadding: true,
state: [
{
label: '常规',
value: 'checkbox-default'
},
{
label: '悬浮',
value: 'checkbox-hover'
},
{
label: '禁用',
value: 'checkbox-disabled'
},
{
label: '选中',
value: 'checked-default'
},
{
label: '选中态悬浮',
value: 'checked-hover'
},
{
label: '选中禁用',
value: 'checked-disabled'
}
]
})
]
},
{
title: '选项说明样式',
body: [
...inputStateTpl('themeCss.checkboxesLabelClassName', '', {
hidePadding: true,
hideRadius: true,
hideBorder: true,
state: [
{
label: '常规',
value: 'default'
},
{
label: '悬浮',
value: 'hover'
},
{
label: '禁用',
value: 'disabled'
}
]
})
]
},
getSchemaTpl('theme:cssCode'),
getSchemaTpl('style:classNames')
])
]

View File

@ -3,7 +3,6 @@ import {registerEditorPlugin} from 'amis-editor-core';
import {BasePlugin, BaseEventContext} from 'amis-editor-core';
import {RendererPluginAction, RendererPluginEvent} from 'amis-editor-core';
import {getEventControlConfig} from '../../renderer/event-control/helper';
import {inputStateTpl} from '../../renderer/style-control/helper';
import {ValidatorTag} from '../../validator';
export class LocationControlPlugin extends BasePlugin {

View File

@ -353,7 +353,7 @@ export class NestedSelectControlPlugin extends BasePlugin {
body: [
...inputStateTpl(
'themeCss.nestedSelectControlClassName',
'--nested-select'
'--select-base'
)
]
},
@ -362,9 +362,13 @@ export class NestedSelectControlPlugin extends BasePlugin {
body: [
...inputStateTpl(
'themeCss.nestedSelectPopoverClassName',
'--nested-select',
'--select-base-${state}-option',
{
state: ['default', 'hover', 'focused']
state: [
{label: '常规', value: 'default'},
{label: '悬浮', value: 'hover'},
{label: '选中', value: 'focused'}
]
}
)
]

View File

@ -309,7 +309,10 @@ export class SelectControlPlugin extends BasePlugin {
{
title: '选择框样式',
body: [
...inputStateTpl('themeCss.selectControlClassName', '--select')
...inputStateTpl(
'themeCss.selectControlClassName',
'--select-base'
)
]
},
{
@ -317,9 +320,13 @@ export class SelectControlPlugin extends BasePlugin {
body: [
...inputStateTpl(
'themeCss.selectPopoverClassName',
'--select',
'--select-base-${state}-option',
{
state: ['default', 'hover', 'focused']
state: [
{label: '常规', value: 'default'},
{label: '悬浮', value: 'hover'},
{label: '选中', value: 'focused'}
]
}
)
]

View File

@ -3,110 +3,120 @@ import {getSchemaTpl} from 'amis-editor-core';
export const inputStateTpl = (
className: string,
token: string = '',
options: {
state: string[];
} = {
state: ['default', 'hover', 'focused', 'disabled']
options?: {
state?: {
label: string;
value: string;
token?: string;
}[];
hideFont?: boolean;
hidePadding?: boolean;
hideMargin?: boolean;
hideRadius?: boolean;
hideBackground?: boolean;
hideBorder?: boolean;
}
) => {
return [
const stateOptions = options?.state || [
{
label: '常规',
value: 'default'
},
{
label: '悬浮',
value: 'hover'
},
{
label: '选中',
value: 'focused'
},
{
label: '禁用',
value: 'disabled'
}
];
const res: any = [
{
type: 'select',
name: `__editorState${className}`,
label: '状态',
selectFirst: true,
options: [
{
label: '常规',
value: 'default'
},
{
label: '悬浮',
value: 'hover'
},
{
label: '选中',
value: 'focused'
},
{
label: '禁用',
value: 'disabled'
}
].filter(item => options.state.includes(item.value))
options: stateOptions
},
...inputStateFunc(
`\${__editorState${className} == 'default' || !__editorState${className}}`,
'default',
className,
token
),
...inputStateFunc(
`\${__editorState${className} == 'hover'}`,
'hover',
className,
token
),
...inputStateFunc(
`\${__editorState${className} == 'focused'}`,
'focused',
className,
token
),
...inputStateFunc(
`\${__editorState${className} == 'disabled'}`,
'disabled',
className,
token
)
...stateOptions.map((item: any) => {
return {
type: 'container',
visibleOn:
`\${__editorState${className} == '${item.value}'` +
(item.value === 'default' ? ` || !__editorState${className}` : '') +
`}`,
body: inputStateFunc(
item.value,
className,
item.token || token,
options
)
};
})
];
return res;
};
export const inputStateFunc = (
visibleOn: string,
state: string,
className: string,
token: string,
options: any = []
options: any
) => {
const cssToken = state === 'focused' ? 'active' : state;
const cssTokenState = state === 'focused' ? 'active' : state;
if (token.includes('${state}')) {
token = token.replace(/\${state}/g, cssTokenState);
} else {
token = `${token}-${cssTokenState}`;
}
return [
getSchemaTpl('theme:font', {
label: '文字',
name: `${className}.font:${state}`,
visibleOn: visibleOn,
editorValueToken: `${token}-${cssToken}`,
state
}),
getSchemaTpl('theme:colorPicker', {
label: '背景',
name: `${className}.background:${state}`,
labelMode: 'input',
needGradient: true,
needImage: true,
visibleOn: visibleOn,
editorValueToken: `${token}-${cssToken}-bg-color`,
state
}),
getSchemaTpl('theme:border', {
name: `${className}.border:${state}`,
visibleOn: visibleOn,
editorValueToken: `${token}-${cssToken}`,
state
}),
getSchemaTpl('theme:paddingAndMargin', {
name: `${className}.padding-and-margin:${state}`,
visibleOn: visibleOn,
editorValueToken: `${token}-${cssToken}`,
state
}),
getSchemaTpl('theme:radius', {
name: `${className}.radius:${state}`,
visibleOn: visibleOn,
editorValueToken: `${token}-${cssToken}`,
state
}),
...options
];
!options?.hideFont &&
getSchemaTpl('theme:font', {
label: '文字',
name: `${className}.font:${state}`,
editorValueToken: token,
state
}),
!options?.hideBackground &&
getSchemaTpl('theme:colorPicker', {
label: '背景',
name: `${className}.background:${state}`,
labelMode: 'input',
needGradient: true,
needImage: true,
editorValueToken: `${token}-bg-color`,
state
}),
!options?.hideBorder &&
getSchemaTpl('theme:border', {
name: `${className}.border:${state}`,
editorValueToken: token,
state
}),
!options?.hidePadding &&
!options?.hideMargin &&
getSchemaTpl('theme:paddingAndMargin', {
name: `${className}.padding-and-margin:${state}`,
editorValueToken: token,
state,
hidePadding: options?.hidePadding,
hideMargin: options?.hideMargin
}),
!options?.hideRadius &&
getSchemaTpl('theme:radius', {
name: `${className}.radius:${state}`,
editorValueToken: token,
state
}),
...(options?.schema || [])
].filter(Boolean);
};
export const buttonStateFunc = (visibleOn: string, state: string) => {

View File

@ -16,18 +16,20 @@ setSchemaTpl('style:formItem', ({renderer, schema}: any) => {
};
});
setSchemaTpl('theme:formItem', ({schema}: any = {}) => {
setSchemaTpl('theme:formItem', ({schema, hidSize}: any = {hidSize: false}) => {
return {
title: '表单项',
key: 'formItem',
body: [
getSchemaTpl('theme:labelHide'),
{
!hidSize && {
type: 'col-size',
name: '__size',
label: '宽度'
}
].concat(schema)
]
.filter(Boolean)
.concat(schema)
};
});

View File

@ -131,7 +131,6 @@
&:before {
width: var(--Checkbox-inner-size);
height: var(--Checkbox-inner-size);
background: var(--Checkbox-onHover-color);
}
}
@ -140,7 +139,6 @@
cursor: not-allowed;
background-color: var(--checkbox-checkbox-disabled-bg-color);
&:before {
background-color: var(--Checkbox-onDisabled-color);
border-width: 0;
}
}
@ -243,10 +241,6 @@
input:checked + i {
background: var(--button-primary-hover-bg-color);
border-color: transparent;
&:before {
background: var(--checkbox-checked-hover-bg-color);
}
}
& > i:before {
@ -264,9 +258,6 @@
&:checked + i {
border-color: var(--Checkbox-onHover-color);
background: var(--Checkbox-onHover-color);
&:hover {
background: var(--checkbox-checked-hover-bg-color);
}
&:before {
width: var(--Checkbox--full-inner-size);
@ -283,14 +274,12 @@
&[disabled]:checked + i {
&:before {
border-color: var(--Checkbox-onDisabled-color);
background: var(--Checkbox-onDisabled-bg);
border-width: 0 0 px2rem(1px) px2rem(1px);
}
}
&:checked[disabled] + i {
border-color: var(--Checkbox-color);
background: var(--Checkbox-onDisabled-bg);
}
}
@ -325,7 +314,6 @@
&:before {
width: var(--Checkbox-inner-size);
height: var(--Checkbox-inner-size);
background: var(--Checkbox-onHover-color);
}
}

View File

@ -7,7 +7,9 @@ import {
hasAbility,
columnsSplit,
flattenTreeWithLeafNodes,
getVariable
getVariable,
CustomStyle,
setThemeClassName
} from 'amis-core';
import type {ActionObject, Api, OptionsControlProps, Option} from 'amis-core';
import {Checkbox, Icon, Spinner} from 'amis-ui';
@ -337,6 +339,29 @@ export default class CheckboxesControl extends React.Component<
return result;
}
formateThemeCss(themeCss: any) {
if (!themeCss) {
return {};
}
const {checkboxesClassName} = themeCss;
const defaultThemeCss: any = {};
const checkedThemeCss: any = {};
Object.keys(checkboxesClassName).forEach(key => {
if (key.includes('checked-')) {
const newKey = key.replace('checked-', '');
checkedThemeCss[newKey] = checkboxesClassName[key];
} else if (key.includes('checkbox-')) {
const newKey = key.replace('checkbox-', '');
defaultThemeCss[newKey] = checkboxesClassName[key];
}
});
return {
...themeCss,
checkboxesClassName: defaultThemeCss,
checkboxesCheckedClassName: checkedThemeCss
};
}
@supportStatic()
render() {
const {
@ -361,7 +386,11 @@ export default class CheckboxesControl extends React.Component<
translate: __,
optionType,
loading,
loadingConfig
loadingConfig,
themeCss,
id,
env,
classPrefix: ns
} = this.props;
let body: Array<React.ReactNode> = [];
@ -393,8 +422,34 @@ export default class CheckboxesControl extends React.Component<
body = this.columnsSplit(body);
const css = this.formateThemeCss(themeCss);
return (
<div className={cx(`CheckboxesControl`, className)} ref="checkboxRef">
<div
className={cx(
`CheckboxesControl`,
className,
setThemeClassName({
...this.props,
name: 'checkboxesClassName',
id,
themeCss: css
}),
setThemeClassName({
...this.props,
name: 'checkboxesCheckedClassName',
id,
themeCss: css
}),
setThemeClassName({
...this.props,
name: 'checkboxesLabelClassName',
id,
themeCss: css
})
)}
ref="checkboxRef"
>
{body && body.length ? (
body
) : loading ? null : (
@ -417,6 +472,63 @@ export default class CheckboxesControl extends React.Component<
{__(createBtnLabel)}
</a>
) : null}
<CustomStyle
{...this.props}
config={{
themeCss: this.formateThemeCss(themeCss),
classNames: [
{
key: 'checkboxesClassName',
weights: {
default: {
suf: ' label',
inner: 'i'
},
hover: {
suf: ' label',
inner: 'i'
},
disabled: {
inner: `.${ns}Checkbox--checkbox input[disabled] + i`
}
}
},
{
key: 'checkboxesCheckedClassName',
weights: {
default: {
inner: `.${ns}Checkbox--checkbox input:checked + i`
},
hover: {
suf: ` .${ns}Checkbox--checkbox`,
inner: 'input:checked + i'
},
disabled: {
inner: `.${ns}Checkbox--checkbox input:checked[disabled] + i`
}
}
},
{
key: 'checkboxesLabelClassName',
weights: {
default: {
suf: ' label',
inner: 'span'
},
hover: {
suf: ' label',
inner: 'span'
},
disabled: {
inner: `.${ns}Checkbox--checkbox input[disabled] + i + span`
}
}
}
],
id: id
}}
env={env}
/>
</div>
);
}