feat: panel\collapse支持新版外观 (#11124)

* feat: panel支持新版外观

* 折叠面板支持新版外观配置

* 折叠器支持新版外观
This commit is contained in:
qkiroc 2024-11-01 10:43:23 +08:00 committed by GitHub
parent cd1093f38b
commit fed1441fc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 405 additions and 141 deletions

View File

@ -194,6 +194,31 @@ export class CollapsePlugin extends BasePlugin {
{
title: '外观',
body: getSchemaTpl('collapseGroup', [
...getSchemaTpl('theme:common', {
exclude: ['layout'],
hideAnimation: true,
classname: 'baseControlClassName',
needState: false,
baseTitle: '基本样式',
extra: [
getSchemaTpl('theme:base', {
classname: 'headerControlClassName',
title: '标题区样式',
state: ['default', 'hover'],
extra: [
getSchemaTpl('theme:font', {
label: '文字',
name: 'themeCss.headerControlClassName.font'
})
]
}),
getSchemaTpl('theme:base', {
classname: 'bodyControlClassName',
needState: false,
title: '内容区样式'
})
]
}),
getSchemaTpl('style:classNames', {
isFormItem: false,
schema: [

View File

@ -269,6 +269,17 @@ export class CollapseGroupPlugin extends BasePlugin {
{
title: '外观',
body: getSchemaTpl('collapseGroup', [
{
title: '基本样式',
body: [
getSchemaTpl('theme:paddingAndMargin', {
name: `themeCss.className.padding-and-margin`,
hidePadding: true
})
]
},
getSchemaTpl('theme:cssCode'),
getSchemaTpl('animation'),
getSchemaTpl('style:classNames', {
isFormItem: false
})

View File

@ -129,37 +129,71 @@ export class PanelPlugin extends BasePlugin {
title: '外观',
body: [
getSchemaTpl('collapseGroup', [
{
className: 'p-none',
title: '基本',
body: [
getSchemaTpl('switch', {
name: 'affixFooter',
label: '固定底部',
value: false
...getSchemaTpl('theme:common', {
exclude: ['layout'],
classname: 'baseControlClassName',
needState: false,
baseTitle: '基本样式',
extra: [
getSchemaTpl('theme:base', {
classname: 'headerControlClassName',
needState: false,
title: '标题区样式',
extra: [
getSchemaTpl('theme:font', {
label: '文字',
name: 'themeCss.titleControlClassName.font'
})
]
}),
getSchemaTpl('horizontal', {
visibleOn:
'(data.mode || data.$$formMode) == "horizontal" && data.$$mode == "form"'
getSchemaTpl('theme:base', {
classname: 'bodyControlClassName',
needState: false,
title: '内容区样式',
extra: [
getSchemaTpl('subFormItemMode', {label: '表单展示模式'}),
getSchemaTpl('subFormHorizontalMode', {
label: '表单水平占比'
}),
getSchemaTpl('subFormHorizontal')
]
}),
getSchemaTpl('theme:base', {
classname: 'footerControlClassName',
needState: false,
title: '底部区样式',
extra: [
getSchemaTpl('switch', {
name: 'affixFooter',
label: '固定底部',
value: false
})
]
})
]
},
{
className: 'p-none',
title: '内容区域展示',
body: [
getSchemaTpl('subFormItemMode', {label: '表单展示模式'}),
getSchemaTpl('subFormHorizontalMode', {
label: '表单水平占比'
}),
getSchemaTpl('style:classNames', {
isFormItem: false,
schema: [
getSchemaTpl('className', {
name: 'headerClassName',
label: '头部区域'
}),
getSchemaTpl('className', {
name: 'bodyClassName',
label: '内容区域'
}),
getSchemaTpl('className', {
name: 'footerClassName',
label: '底部区域'
}),
getSchemaTpl('className', {
name: 'actionsClassName',
label: '按钮外层'
}),
getSchemaTpl('subFormHorizontal')
]
},
{
className: 'p-none',
title: 'CSS 类名',
body: [
{
name: isForm ? 'panelClassName' : 'className',
label: '主题',
@ -205,34 +239,9 @@ export class PanelPlugin extends BasePlugin {
value: 'Panel--danger'
}
]
},
getSchemaTpl('className', {
label: '外层',
name: isForm ? 'panelClassName' : 'className',
pipeIn: defaultValue('Panel--default')
}),
getSchemaTpl('className', {
name: 'headerClassName',
label: '头部区域'
}),
getSchemaTpl('className', {
name: 'bodyClassName',
label: '内容区域'
}),
getSchemaTpl('className', {
name: 'footerClassName',
label: '底部区域'
}),
getSchemaTpl('className', {
name: 'actionsClassName',
label: '按钮外层'
})
}
]
}
})
])
]
}

View File

@ -1093,21 +1093,23 @@ setSchemaTpl(
!hideBorder &&
getSchemaTpl('theme:border', {
visibleOn: visibleOn,
name: `themeCss.${classname}.border:${state}`,
name: `themeCss.${classname}.border${needState ? ':' + state : ''}`,
state,
editorValueToken
}),
!hideRadius &&
getSchemaTpl('theme:radius', {
visibleOn: visibleOn,
name: `themeCss.${classname}.radius:${state}`,
name: `themeCss.${classname}.radius${needState ? ':' + state : ''}`,
state,
editorValueToken
}),
!hidePaddingAndMargin &&
getSchemaTpl('theme:paddingAndMargin', {
visibleOn: visibleOn,
name: `themeCss.${classname}.padding-and-margin:${state}`,
name: `themeCss.${classname}.padding-and-margin${
needState ? ':' + state : ''
}`,
hideMargin,
hidePadding,
state,
@ -1116,7 +1118,9 @@ setSchemaTpl(
!hideBackground &&
getSchemaTpl('theme:colorPicker', {
visibleOn: visibleOn,
name: `themeCss.${classname}.background:${state}`,
name: `themeCss.${classname}.background${
needState ? ':' + state : ''
}`,
label: '背景',
needCustom: true,
needGradient: true,
@ -1130,7 +1134,9 @@ setSchemaTpl(
!hideShadow &&
getSchemaTpl('theme:shadow', {
visibleOn: visibleOn,
name: `themeCss.${classname}.boxShadow:${state}`,
name: `themeCss.${classname}.boxShadow${
needState ? ':' + state : ''
}`,
state,
editorValueToken
})
@ -1141,7 +1147,7 @@ setSchemaTpl(
return {
...item,
visibleOn: visibleOn,
name: `${item.name}:${state}`,
name: `${item.name}${needState ? ':' + state : ''}`,
state
};
})
@ -1201,6 +1207,8 @@ setSchemaTpl(
classname?: string;
baseTitle?: string;
hidePaddingAndMargin?: boolean;
hideAnimation?: boolean;
needState?: boolean;
}) => {
let {
exclude,
@ -1210,7 +1218,9 @@ setSchemaTpl(
layoutExtra,
classname,
baseTitle,
hidePaddingAndMargin
hidePaddingAndMargin,
hideAnimation,
needState = true
} = option || {};
const curCollapsed = collapsed ?? false; // 默认都展开
@ -1239,6 +1249,7 @@ setSchemaTpl(
extra: baseExtra,
classname,
title: baseTitle,
needState,
hidePaddingAndMargin
}),
...extra,
@ -1252,7 +1263,7 @@ setSchemaTpl(
}
]
},
getSchemaTpl('animation')
!hideAnimation && getSchemaTpl('animation')
].filter(item => !~exclude.indexOf(item.key || ''));
}
);

View File

@ -10,7 +10,26 @@
}
}
.#{$ns}Collapse:last-child {
.#{$ns}Collapse:not(.#{$ns}Collapse--title-bottom):last-child {
border-radius: 0 0 4px 4px;
& > .#{$ns}Collapse-header {
border-radius: 0 0 4px 4px;
}
&
> .#{$ns}Collapse-contentWrapper
> .#{$ns}Collapse-body
> .#{$ns}Collapse-content {
border-radius: 0 0 4px 4px;
}
}
.#{$ns}Collapse.is-active:not(.#{$ns}Collapse--title-bottom):last-child {
& > .#{$ns}Collapse-header {
border-radius: 0px;
}
}
.#{$ns}Collapse--title-bottom:last-child {
border-radius: 0 0 4px 4px;
& > .#{$ns}Collapse-header {
border-radius: 0 0 4px 4px;

View File

@ -8,10 +8,13 @@ import {
autobind,
resolveEventData,
isPureVariable,
resolveVariableAndFilter
resolveVariableAndFilter,
setThemeClassName,
CustomStyle
} from 'amis-core';
import {Collapse as BasicCollapse, Icon} from 'amis-ui';
import {BaseSchema, SchemaCollection, SchemaTpl, SchemaObject} from '../Schema';
import classNames from 'classnames';
/**
* Collapse
@ -208,66 +211,125 @@ export default class Collapse extends React.Component<CollapseProps, {}> {
propsUpdate,
mobileUI,
divideLine,
enableFieldSetStyle
enableFieldSetStyle,
themeCss,
wrapperCustomStyle
} = this.props;
const heading = title || header || '';
return (
<BasicCollapse
id={id}
ref={this.basicCollapse}
classnames={cx}
classPrefix={ns}
mountOnEnter={mountOnEnter}
unmountOnExit={unmountOnExit}
size={size}
wrapperComponent={wrapperComponent}
headingComponent={headingComponent}
className={className}
style={style}
headingClassName={headingClassName}
bodyClassName={bodyClassName}
headerPosition={titlePosition || headerPosition}
collapsable={collapsable}
collapsed={collapsed}
showArrow={showArrow}
disabled={disabled}
propsUpdate={propsUpdate}
expandIcon={
expandIcon ? (
typeof (expandIcon as any).icon === 'object' ? (
<Icon
cx={cx}
icon={(expandIcon as any).icon}
className={cx('Collapse-icon-tranform')}
/>
) : (
render('arrow-icon', expandIcon || '', {
className: cx('Collapse-icon-tranform')
})
)
) : null
}
collapseHeader={
collapseTitle || collapseHeader
? render('heading', collapseTitle || collapseHeader)
: null
}
header={heading ? render('heading', heading) : null}
body={
children
? typeof children === 'function'
? children(this.props)
: children
: body
? render('body', body)
: null
}
mobileUI={mobileUI}
onCollapse={this.handleCollapseChange}
divideLine={divideLine}
enableFieldSetStyle={enableFieldSetStyle}
></BasicCollapse>
<>
<BasicCollapse
id={id}
ref={this.basicCollapse}
classnames={cx}
classPrefix={ns}
mountOnEnter={mountOnEnter}
unmountOnExit={unmountOnExit}
size={size}
wrapperComponent={wrapperComponent}
headingComponent={headingComponent}
className={classNames(
className,
setThemeClassName({
...this.props,
name: 'baseControlClassName',
id,
themeCss
}),
setThemeClassName({
...this.props,
name: 'wrapperCustomStyle',
id,
themeCss: wrapperCustomStyle
})
)}
style={style}
headingClassName={classNames(
headingClassName,
setThemeClassName({
...this.props,
name: 'headerControlClassName',
id,
themeCss
})
)}
bodyClassName={classNames(
bodyClassName,
setThemeClassName({
...this.props,
name: 'bodyControlClassName',
id,
themeCss
})
)}
headerPosition={titlePosition || headerPosition}
collapsable={collapsable}
collapsed={collapsed}
showArrow={showArrow}
disabled={disabled}
propsUpdate={propsUpdate}
expandIcon={
expandIcon ? (
typeof (expandIcon as any).icon === 'object' ? (
<Icon
cx={cx}
icon={(expandIcon as any).icon}
className={cx('Collapse-icon-tranform')}
/>
) : (
render('arrow-icon', expandIcon || '', {
className: cx('Collapse-icon-tranform')
})
)
) : null
}
collapseHeader={
collapseTitle || collapseHeader
? render('heading', collapseTitle || collapseHeader)
: null
}
header={heading ? render('heading', heading) : null}
body={
children
? typeof children === 'function'
? children(this.props)
: children
: body
? render('body', body)
: null
}
mobileUI={mobileUI}
onCollapse={this.handleCollapseChange}
divideLine={divideLine}
enableFieldSetStyle={enableFieldSetStyle}
></BasicCollapse>
<CustomStyle
{...this.props}
config={{
wrapperCustomStyle,
id,
themeCss,
classNames: [
{
key: 'baseControlClassName'
},
{
key: 'bodyControlClassName',
weights: {
default: {
inner: `.${ns}Collapse-content`
}
}
},
{
key: 'headerControlClassName'
}
]
}}
env={this.props.env}
/>
</>
);
}
}

View File

@ -5,10 +5,13 @@ import {
autobind,
resolveEventData,
isPureVariable,
resolveVariableAndFilter
resolveVariableAndFilter,
setThemeClassName,
CustomStyle
} from 'amis-core';
import {BaseSchema, SchemaCollection, SchemaObject} from '../Schema';
import {CollapseGroup} from 'amis-ui';
import cx from 'classnames';
/**
* CollapseGroup
@ -101,7 +104,11 @@ export class CollapseGroupRender extends React.Component<
style,
render,
mobileUI,
data
data,
id,
themeCss,
wrapperCustomStyle,
env
} = this.props;
let enableFieldSetStyle = this.props.enableFieldSetStyle;
@ -114,18 +121,48 @@ export class CollapseGroupRender extends React.Component<
}
return (
<CollapseGroup
defaultActiveKey={defaultActiveKey}
accordion={accordion}
expandIcon={expandIcon}
expandIconPosition={expandIconPosition}
className={className}
style={style}
mobileUI={mobileUI}
onCollapseChange={this.handleCollapseChange}
>
{render('body', body || '', {enableFieldSetStyle})}
</CollapseGroup>
<>
<CollapseGroup
defaultActiveKey={defaultActiveKey}
accordion={accordion}
expandIcon={expandIcon}
expandIconPosition={expandIconPosition}
className={cx(
className,
setThemeClassName({
...this.props,
name: 'className',
id,
themeCss
}),
setThemeClassName({
...this.props,
name: 'wrapperCustomStyle',
id,
themeCss: wrapperCustomStyle
})
)}
style={style}
mobileUI={mobileUI}
onCollapseChange={this.handleCollapseChange}
>
{render('body', body || '', {enableFieldSetStyle})}
</CollapseGroup>
<CustomStyle
{...this.props}
config={{
wrapperCustomStyle,
id,
themeCss,
classNames: [
{
key: 'className'
}
]
}}
env={env}
/>
</>
);
}
}

View File

@ -3,7 +3,8 @@ import {
CustomStyle,
RENDERER_TRANSMISSION_OMIT_PROPS,
Renderer,
RendererProps
RendererProps,
setThemeClassName
} from 'amis-core';
import {
BaseSchema,
@ -161,6 +162,8 @@ export default class Panel extends React.Component<PanelProps> {
subFormMode,
subFormHorizontal,
id,
themeCss,
wrapperCustomStyle,
...rest
} = this.props;
@ -221,6 +224,8 @@ export default class Panel extends React.Component<PanelProps> {
classnames: cx,
id,
collapsible,
themeCss,
wrapperCustomStyle,
...rest
} = this.props;
@ -267,7 +272,13 @@ export default class Panel extends React.Component<PanelProps> {
className={cx(
'Panel-footerWrap',
footerWrapClassName,
affixFooter ? 'Panel-fixedBottom' : ''
affixFooter ? 'Panel-fixedBottom' : '',
setThemeClassName({
...this.props,
name: 'footerControlClassName',
id,
themeCss
})
)}
>
{footerDoms}
@ -277,14 +288,35 @@ export default class Panel extends React.Component<PanelProps> {
return (
<div
data-id={id}
className={cx(`Panel`, className || `Panel--default`)}
className={cx(
`Panel`,
className || `Panel--default`,
setThemeClassName({
...this.props,
name: 'baseControlClassName',
id,
themeCss
}),
setThemeClassName({
...this.props,
name: 'wrapperCustomStyle',
id,
themeCss: wrapperCustomStyle
})
)}
style={style}
>
{header ? (
<div
className={cx(
headerClassName || `Panel-heading`,
headerControlClassName
headerControlClassName,
setThemeClassName({
...this.props,
name: 'headerControlClassName',
id,
themeCss
})
)}
>
{render('header', header, subProps)}
@ -296,10 +328,27 @@ export default class Panel extends React.Component<PanelProps> {
headerControlClassName,
{
'is-collapsible': collapsible
}
},
setThemeClassName({
...this.props,
name: 'headerControlClassName',
id,
themeCss
})
)}
>
<h3 className={cx(`Panel-title`, headerTitleControlClassName)}>
<h3
className={cx(
`Panel-title`,
headerTitleControlClassName,
setThemeClassName({
...this.props,
name: 'titleControlClassName',
id,
themeCss
})
)}
>
{render('title', title, subProps)}
</h3>
{collapsible ? (
@ -324,13 +373,54 @@ export default class Panel extends React.Component<PanelProps> {
{!collapsed ? (
<div
className={cx(bodyClassName || `Panel-body`, bodyControlClassName)}
className={cx(
bodyClassName || `Panel-body`,
bodyControlClassName,
setThemeClassName({
...this.props,
name: 'bodyControlClassName',
id,
themeCss
})
)}
>
{this.renderBody()}
</div>
) : null}
{footerDom}
<CustomStyle
{...this.props}
config={{
wrapperCustomStyle,
id,
themeCss,
classNames: [
{
key: 'baseControlClassName'
},
{
key: 'bodyControlClassName'
},
{
key: 'headerControlClassName',
weights: {
default: {
suf: `.${ns}Panel-heading`
}
}
},
{
key: 'titleControlClassName'
},
{
key: 'footerControlClassName'
}
]
}}
env={this.props.env}
/>
</div>
);
}