mirror of
https://gitee.com/baidu/amis.git
synced 2024-11-29 18:48:45 +08:00
feat: Divider支持带文字配置 (#8358)
* feat:divider支持带文字配置 * feat: divider支持带文字配置 * feat: divider支持带文字配置 --------- Co-authored-by: zhaowenli <zhaowenli@baidu.com>
This commit is contained in:
parent
034d18e36c
commit
0ba4f50f70
@ -21,22 +21,51 @@ order: 42
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "divider"
|
||||
"type": "divider",
|
||||
"lineStyle": "solid"
|
||||
},
|
||||
{
|
||||
"type": "divider",
|
||||
"lineStyle": "solid"
|
||||
"lineStyle": "dashed"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 带标题的分割线
|
||||
|
||||
> `3.5.0`及以上版本
|
||||
|
||||
```schema: scope="body"
|
||||
[
|
||||
{
|
||||
"type": "divider",
|
||||
"title": "Text",
|
||||
"titlePosition": "left"
|
||||
},
|
||||
{
|
||||
"type": "divider",
|
||||
"title": "Text",
|
||||
"titlePosition": "center"
|
||||
},
|
||||
{
|
||||
"type": "divider",
|
||||
"title": "Text",
|
||||
"titlePosition": "right"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 属性表
|
||||
|
||||
| 属性名 | 类型 | 默认值 | 说明 |
|
||||
| --------- | -------- | ------------ | ------------------------------------------ |
|
||||
| 属性名 | 类型 | 默认值 | 说明 | 版本 |
|
||||
| --------- | -------- | ------------ | --------------------------------------- |---------- |
|
||||
| type | `string` | | `"divider"` 指定为 分割线 渲染器 |
|
||||
| className | `string` | | 外层 Dom 的类名 |
|
||||
| lineStyle | `string` | `solid` | 分割线的样式,支持`dashed`和`solid` |
|
||||
| direction | `string` | `horizontal` | 分割线的方向,支持`horizontal`和`vertical` |
|
||||
| color | `string` | | 分割线的颜色 |
|
||||
| rotate | `number` | | 分割线的旋转角度 |
|
||||
| direction | `string` | `horizontal` | 分割线的方向,支持`horizontal`和`vertical` | `3.5.0` |
|
||||
| color | `string` | | 分割线的颜色 | `3.5.0` |
|
||||
| rotate | `number` | | 分割线的旋转角度 | `3.5.0` |
|
||||
| title | [SchemaNode](../../docs/types/schemanode) | | 分割线的标题 | `3.5.0` |
|
||||
| titleClassName | `string` | | 分割线的标题类名 | `3.5.0` |
|
||||
| titlePosition | `string` | `center`| 分割线的标题位置,支持`left`、`center`和`right` | `3.5.0` |
|
||||
|
||||
|
@ -1,6 +1,13 @@
|
||||
import {registerEditorPlugin} from 'amis-editor-core';
|
||||
import {BasePlugin} from 'amis-editor-core';
|
||||
import {getSchemaTpl} from 'amis-editor-core';
|
||||
import {
|
||||
BasePlugin,
|
||||
BaseEventContext,
|
||||
defaultValue,
|
||||
getI18nEnabled,
|
||||
getSchemaTpl,
|
||||
registerEditorPlugin,
|
||||
tipedLabel,
|
||||
valuePipeOut
|
||||
} from 'amis-editor-core';
|
||||
|
||||
export class DividerPlugin extends BasePlugin {
|
||||
static id = 'DividerPlugin';
|
||||
@ -27,103 +34,203 @@ export class DividerPlugin extends BasePlugin {
|
||||
panelJustify = true;
|
||||
tags = ['展示'];
|
||||
|
||||
panelBody = getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本样式',
|
||||
body: [
|
||||
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
|
||||
getSchemaTpl('layout:width:v2', {
|
||||
visibleOn:
|
||||
'data.style && data.style.position && (data.style.position === "fixed" || data.style.position === "absolute")'
|
||||
}),
|
||||
{
|
||||
mode: 'horizontal',
|
||||
type: 'button-group-select',
|
||||
label: '类型',
|
||||
name: 'lineStyle',
|
||||
value: 'dashed',
|
||||
options: [
|
||||
{
|
||||
value: 'dashed',
|
||||
label: '虚线'
|
||||
},
|
||||
{
|
||||
value: 'solid',
|
||||
label: '实线'
|
||||
panelBodyCreator = (context: BaseEventContext) => {
|
||||
const i18nEnabled = getI18nEnabled();
|
||||
return getSchemaTpl('tabs', [
|
||||
{
|
||||
title: '属性',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本',
|
||||
body: [
|
||||
i18nEnabled
|
||||
? {
|
||||
type: 'input-text-i18n',
|
||||
name: 'title',
|
||||
label: '标题',
|
||||
placeholder: '请输入标题'
|
||||
}
|
||||
: getSchemaTpl('valueFormula', {
|
||||
name: 'title',
|
||||
label: '标题',
|
||||
placeholder: '请输入标题',
|
||||
rendererSchema: {
|
||||
type: 'input-text'
|
||||
}
|
||||
})
|
||||
]
|
||||
},
|
||||
getSchemaTpl('status')
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '外观',
|
||||
body: getSchemaTpl('collapseGroup', [
|
||||
{
|
||||
title: '基本样式',
|
||||
body: [
|
||||
getSchemaTpl('layout:originPosition', {value: 'left-top'}),
|
||||
getSchemaTpl('layout:width:v2', {
|
||||
visibleOn:
|
||||
'data.style && data.style.position && (data.style.position === "fixed" || data.style.position === "absolute")'
|
||||
}),
|
||||
{
|
||||
mode: 'horizontal',
|
||||
type: 'select',
|
||||
label: '类型',
|
||||
name: 'lineStyle',
|
||||
value: 'solid',
|
||||
options: [
|
||||
{
|
||||
value: 'solid',
|
||||
label: '实线'
|
||||
},
|
||||
{
|
||||
value: 'dashed',
|
||||
label: '虚线'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
mode: 'horizontal',
|
||||
type: 'select',
|
||||
label: '方向',
|
||||
name: 'direction',
|
||||
value: 'horizontal',
|
||||
options: [
|
||||
{
|
||||
value: 'horizontal',
|
||||
label: '水平'
|
||||
},
|
||||
{
|
||||
value: 'vertical',
|
||||
label: '垂直'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
mode: 'horizontal',
|
||||
type: 'input-number',
|
||||
label: '角度',
|
||||
name: 'rotate',
|
||||
value: 0,
|
||||
min: -360,
|
||||
max: 360
|
||||
},
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '线长',
|
||||
name: 'style.width',
|
||||
placeholder: '100%',
|
||||
visibleOn: 'data.direction !== "vertical"',
|
||||
clearValueOnHidden: true
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '线长',
|
||||
name: 'style.height',
|
||||
placeholder: 'var(--sizes-base-15)',
|
||||
visibleOn: 'data.direction === "vertical"',
|
||||
clearValueOnHidden: true
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '线宽',
|
||||
name: 'style.borderWidth',
|
||||
placeholder: '1px',
|
||||
visibleOn: '!data.title || data.direction === "vertical"'
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '线宽',
|
||||
name: 'themeCss.titleWrapperControlClassName.border-bottom-width',
|
||||
placeholder: '1px',
|
||||
visibleOn: '!!data.title && data.direction !== "vertical"',
|
||||
clearValueOnHidden: true,
|
||||
pipeIn: (value: any, form: any) => {
|
||||
if (
|
||||
value === undefined &&
|
||||
form.data?.style?.borderWidth !== undefined
|
||||
) {
|
||||
const bwidth = form.data.style.borderWidth;
|
||||
setTimeout(() =>
|
||||
form.setValueByName(
|
||||
'themeCss.titleWrapperControlClassName.border-bottom-width',
|
||||
bwidth
|
||||
)
|
||||
);
|
||||
return bwidth;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
mode: 'horizontal',
|
||||
type: 'button-group-select',
|
||||
label: '方向',
|
||||
name: 'direction',
|
||||
value: 'horizontal',
|
||||
options: [
|
||||
{
|
||||
value: 'horizontal',
|
||||
label: '水平'
|
||||
},
|
||||
{
|
||||
value: 'vertical',
|
||||
label: '垂直'
|
||||
}
|
||||
]
|
||||
},
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '长度',
|
||||
name: 'style.width',
|
||||
placeholder: '100%',
|
||||
visibleOn: 'direction !== "vertical"',
|
||||
clearValueOnHidden: true
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '长度',
|
||||
name: 'style.height',
|
||||
placeholder: 'var(--sizes-base-15)',
|
||||
visibleOn: 'direction === "vertical"',
|
||||
clearValueOnHidden: true
|
||||
}),
|
||||
getSchemaTpl('theme:select', {
|
||||
mode: 'horizontal',
|
||||
label: '宽度',
|
||||
name: 'style.borderWidth',
|
||||
placeholder: '1px'
|
||||
}),
|
||||
|
||||
getSchemaTpl('theme:colorPicker', {
|
||||
mode: 'horizontal',
|
||||
label: '颜色',
|
||||
name: 'color',
|
||||
placeholder: 'var(--colors-neutral-line-8)',
|
||||
labelMode: 'input',
|
||||
needGradient: true
|
||||
}),
|
||||
getSchemaTpl('theme:paddingAndMargin', {
|
||||
name: 'style',
|
||||
hidePadding: true
|
||||
}),
|
||||
{
|
||||
mode: 'horizontal',
|
||||
type: 'input-number',
|
||||
label: '角度',
|
||||
name: 'rotate',
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
},
|
||||
{
|
||||
title: '显隐',
|
||||
body: [getSchemaTpl('ref'), getSchemaTpl('visible')]
|
||||
}
|
||||
]);
|
||||
}),
|
||||
getSchemaTpl('theme:colorPicker', {
|
||||
mode: 'horizontal',
|
||||
label: '颜色',
|
||||
name: 'color',
|
||||
placeholder: 'var(--colors-neutral-line-8)',
|
||||
labelMode: 'input',
|
||||
needGradient: true
|
||||
}),
|
||||
getSchemaTpl('theme:paddingAndMargin', {
|
||||
name: 'style',
|
||||
hidePadding: true
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '标题样式',
|
||||
visibleOn: '!!data.title && data.direction !== "vertical"',
|
||||
body: [
|
||||
{
|
||||
type: 'select',
|
||||
name: 'titlePosition',
|
||||
label: '位置',
|
||||
pipeIn: defaultValue('center'),
|
||||
options: [
|
||||
{
|
||||
value: 'left',
|
||||
label: '居左'
|
||||
},
|
||||
{
|
||||
value: 'center',
|
||||
label: '居中'
|
||||
},
|
||||
{
|
||||
value: 'right',
|
||||
label: '居右'
|
||||
}
|
||||
],
|
||||
clearValueOnHidden: true
|
||||
},
|
||||
getSchemaTpl('theme:select', {
|
||||
label: tipedLabel(
|
||||
'距离',
|
||||
'标题和最近左、右边框之间的距离,默认值5%'
|
||||
),
|
||||
name: 'themeCss.titleWrapperControlClassName.flex-basis',
|
||||
placeholder: '5%',
|
||||
visibleOn:
|
||||
'data.titlePosition === "left" || data.titlePosition === "right"',
|
||||
clearValueOnHidden: true
|
||||
}),
|
||||
getSchemaTpl('theme:font', {
|
||||
title: '文字',
|
||||
name: 'themeCss.titleControlClassName.font',
|
||||
textAlign: false,
|
||||
clearValueOnHidden: true
|
||||
}),
|
||||
getSchemaTpl('theme:paddingAndMargin', {
|
||||
name: 'themeCss.titleControlClassName.padding-and-margin',
|
||||
hidePadding: true,
|
||||
clearValueOnHidden: true
|
||||
})
|
||||
]
|
||||
}
|
||||
])
|
||||
}
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
||||
registerEditorPlugin(DividerPlugin);
|
||||
|
@ -2545,6 +2545,14 @@
|
||||
--Divider-marginLeft: var(--sizes-size-0);
|
||||
--Divider-marginRight: var(--sizes-size-0);
|
||||
--Divider-marginBottom: var(--sizes-size-7);
|
||||
--Divider-text-width: 5%;
|
||||
--Divider-text-fontSize: var(--fonts-size-7);
|
||||
--Divider-text-fontWeight: var(--fonts-weight-6);
|
||||
--Divider-text-color: var(--colors-neutral-text-2);
|
||||
--Divider-text-marginTop: var(--sizes-size-0);
|
||||
--Divider-text-marginLeft: var(--sizes-size-9);
|
||||
--Divider-text-marginRight: var(--sizes-size-9);
|
||||
--Divider-text-marginBottom: var(--sizes-size-0);
|
||||
|
||||
--inputFile-base-des-color: var(--colors-neutral-text-2);
|
||||
--inputFile-base-des-fontSize: var(--fonts-size-7);
|
||||
|
@ -23,18 +23,53 @@
|
||||
}
|
||||
|
||||
&--horizontal {
|
||||
border-bottom: var(--Divider-width) var(--Divider-style)
|
||||
var(--Divider-color);
|
||||
position: relative;
|
||||
height: px2rem(2px);
|
||||
border-bottom: var(--Divider-width) var(--Divider-style) var(--Divider-color);
|
||||
transform-origin: 0 center;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
&--vertical {
|
||||
border-left: var(--Divider-width) var(--Divider-style) var(--Divider-color);
|
||||
height: var(--sizes-base-15);
|
||||
transform-origin: center bottom;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$ns}Divider--with-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: unset;
|
||||
border-bottom-width: 0 !important;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
height: 0;
|
||||
flex: 1;
|
||||
border-bottom: inherit;
|
||||
border-bottom-width: var(--Divider-width);
|
||||
}
|
||||
|
||||
&.#{$ns}Divider--with-text-left:before,
|
||||
&.#{$ns}Divider--with-text-right:after {
|
||||
flex-basis: var(--Divider-text-width);
|
||||
flex-grow: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$ns}Divider-text {
|
||||
margin: var(--Divider-text-marginTop) var(--Divider-text-marginRight)
|
||||
var(--Divider-text-marginBottom) var(--Divider-text-marginLeft);
|
||||
font-size: var(--Divider-text-fontSize);
|
||||
font-weight: var(--Divider-text-fontWeight);
|
||||
line-height: 1;
|
||||
color: var(--Divider-text-color);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 移动端样式调整 */
|
||||
@include media-breakpoint-down(sm) {
|
||||
.#{$ns}Divider {
|
||||
|
@ -1,6 +1,13 @@
|
||||
import React from 'react';
|
||||
import {Renderer, RendererProps} from 'amis-core';
|
||||
import {BaseSchema} from '../Schema';
|
||||
import {
|
||||
Renderer,
|
||||
RendererProps,
|
||||
CustomStyle,
|
||||
setThemeClassName,
|
||||
isPureVariable,
|
||||
resolveVariableAndFilter
|
||||
} from 'amis-core';
|
||||
import {BaseSchema, SchemaCollection} from '../Schema';
|
||||
|
||||
/**
|
||||
* Divider 分割线渲染器。
|
||||
@ -12,6 +19,9 @@ export interface DividerSchema extends BaseSchema {
|
||||
direction?: 'horizontal' | 'vertical';
|
||||
color?: string;
|
||||
rotate?: number;
|
||||
title?: SchemaCollection;
|
||||
titleClassName?: string;
|
||||
titlePosition?: 'left' | 'center' | 'right';
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
@ -20,20 +30,33 @@ export interface DividerProps
|
||||
Omit<DividerSchema, 'type' | 'className'> {}
|
||||
|
||||
export default class Divider extends React.Component<DividerProps, object> {
|
||||
static defaultProps: Pick<DividerProps, 'className' | 'lineStyle'> = {
|
||||
static defaultProps: Pick<
|
||||
DividerProps,
|
||||
'className' | 'lineStyle' | 'titleClassName' | 'titlePosition'
|
||||
> = {
|
||||
className: '',
|
||||
lineStyle: 'solid'
|
||||
lineStyle: 'solid',
|
||||
titleClassName: '',
|
||||
titlePosition: 'center'
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
let {
|
||||
render,
|
||||
classnames: cx,
|
||||
className,
|
||||
style = {},
|
||||
lineStyle,
|
||||
direction,
|
||||
color,
|
||||
rotate
|
||||
rotate,
|
||||
title,
|
||||
titleClassName,
|
||||
titlePosition,
|
||||
id,
|
||||
themeCss,
|
||||
env,
|
||||
data
|
||||
} = this.props;
|
||||
|
||||
const borderColor: any = {};
|
||||
@ -46,22 +69,77 @@ export default class Divider extends React.Component<DividerProps, object> {
|
||||
}
|
||||
}
|
||||
|
||||
let transform;
|
||||
let transform = style?.transform || '';
|
||||
if (rotate) {
|
||||
transform = `${style?.transform || ''} rotate(${rotate}deg)`;
|
||||
transform += ` rotate(${rotate}deg)`;
|
||||
}
|
||||
|
||||
if (isPureVariable(title)) {
|
||||
title = resolveVariableAndFilter(title, data);
|
||||
}
|
||||
|
||||
const classNames = cx(
|
||||
'Divider',
|
||||
lineStyle ? `Divider--${lineStyle}` : '',
|
||||
direction === 'vertical' ? 'Divider--vertical' : 'Divider--horizontal',
|
||||
title && direction !== 'vertical' ? 'Divider--with-text' : '',
|
||||
title && direction !== 'vertical' && titlePosition
|
||||
? `Divider--with-text-${titlePosition}`
|
||||
: '',
|
||||
title && direction !== 'vertical'
|
||||
? setThemeClassName('titleWrapperControlClassName', id, themeCss)
|
||||
: '',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
'Divider',
|
||||
lineStyle ? `Divider--${lineStyle}` : '',
|
||||
direction === 'vertical'
|
||||
? 'Divider--vertical'
|
||||
: 'Divider--horizontal',
|
||||
className
|
||||
)}
|
||||
style={{...style, ...borderColor, transform}}
|
||||
/>
|
||||
<div className={classNames} style={{...style, ...borderColor, transform}}>
|
||||
{title && direction !== 'vertical' ? (
|
||||
<span
|
||||
className={cx(
|
||||
`Divider-text Divider-text-${titlePosition} ${titleClassName}`,
|
||||
setThemeClassName('titleControlClassName', id, themeCss)
|
||||
)}
|
||||
>
|
||||
{render('title', title)}
|
||||
</span>
|
||||
) : null}
|
||||
<CustomStyle
|
||||
config={{
|
||||
themeCss: themeCss,
|
||||
classNames: [
|
||||
{
|
||||
key: 'titleWrapperControlClassName',
|
||||
weights: {
|
||||
default: {
|
||||
suf: '::before',
|
||||
important: true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'titleWrapperControlClassName',
|
||||
weights: {
|
||||
default: {
|
||||
suf: '::after',
|
||||
important: true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'titleControlClassName',
|
||||
weights: {
|
||||
default: {
|
||||
important: true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
id
|
||||
}}
|
||||
env={env}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user