feat: DropDownButton支持分组,菜单CSS类名,添加下拉菜单max-width (#3302)

This commit is contained in:
RUNZE LU 2021-12-30 22:42:43 +08:00 committed by GitHub
parent 1aa45a631f
commit 548f3cccfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 319 additions and 78 deletions

View File

@ -18,10 +18,10 @@ exports[`Renderer:dropdown-button 1`] = `
</span>
</button>
<ul
class="cxd-DropDown-menu"
class="cxd-DropDown-menu-root cxd-DropDown-menu"
>
<li
class=""
class="cxd-DropDown-button"
>
<a
class=""
@ -32,7 +32,7 @@ exports[`Renderer:dropdown-button 1`] = `
</a>
</li>
<li
class=""
class="cxd-DropDown-button"
>
<a
class=""

View File

@ -0,0 +1,124 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Renderer:timeline 1`] = `
<div>
<div
class="cxd-Timeline cxd-Timeline-vertical cxd-Timeline-right"
>
<div
class="cxd-TimelineItem"
>
<div
class="cxd-TimelineItem-axle"
>
<div
class="cxd-TimelineItem-line"
/>
<div
class="cxd-TimelineItem-round"
style="background-color: rgb(255, 178, 0);"
/>
</div>
<div
class="cxd-TimelineItem-content"
>
<div
class="cxd-TimelineItem-time"
>
2019-02-07
</div>
<div
class="cxd-TimelineItem-title"
>
节点数据
</div>
</div>
</div>
<div
class="cxd-TimelineItem"
>
<div
class="cxd-TimelineItem-axle"
>
<div
class="cxd-TimelineItem-line"
/>
<div
class="cxd-TimelineItem-round"
style="background-color: rgb(79, 134, 244);"
/>
</div>
<div
class="cxd-TimelineItem-content"
>
<div
class="cxd-TimelineItem-time"
>
2019-02-08
</div>
<div
class="cxd-TimelineItem-title"
>
节点数据
</div>
</div>
</div>
<div
class="cxd-TimelineItem"
>
<div
class="cxd-TimelineItem-axle"
>
<div
class="cxd-TimelineItem-line"
/>
<div
class="cxd-TimelineItem-round cxd-TimelineItem-round--success"
/>
</div>
<div
class="cxd-TimelineItem-content"
>
<div
class="cxd-TimelineItem-time"
>
2019-02-09
</div>
<div
class="cxd-TimelineItem-title"
>
节点数据
</div>
</div>
</div>
<div
class="cxd-TimelineItem"
>
<div
class="cxd-TimelineItem-axle"
>
<div
class="cxd-TimelineItem-line"
/>
<div
class="cxd-TimelineItem-round cxd-TimelineItem-round--warning"
/>
</div>
<div
class="cxd-TimelineItem-content"
>
<div
class="cxd-TimelineItem-time"
>
2019-02-09
</div>
<div
class="cxd-TimelineItem-title"
>
节点数据
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -35,6 +35,68 @@ order: 44
}
```
## 分组展示模式
配置`children`可以实现分组展示,分组标题支持配置`icon`。
> 1.5.7 及以上版本
```schema: scope="body"
{
"type": "dropdown-button",
"label": "下拉菜单",
"buttons": [
{
"label": "RD",
"icon": "fa fa-user",
"children": [
{
"type": "button",
"label": "前端FE"
},
{
"type": "button",
"label": "后端RD"
}
]
},
{
"label": "QA",
"icon": "fa fa-user",
"children": [
{
"type": "button",
"label": "测试QA",
},
{
"type": "button",
"label": "交付测试DQA",
"disabled": true
},
{
"type": "divider"
}
]
},
{
"label": "Manager",
"icon": "fa fa-user",
"children": [
{
"type": "button",
"label": "项目经理PM"
},
{
"type": "button",
"label": "项目管理中心PMO",
"visible": false
}
]
}
]
}
```
## 关闭下拉菜单
配置`"closeOnClick": true`可以实现点击按钮后自动关闭下拉菜单。
@ -197,18 +259,20 @@ order: 44
## 属性表
| 属性名 | 类型 | 默认值 | 说明 |
| --------------- | ------------------ | ----------------- | ----------------------------------------- |
| type | `string` | `dropdown-button` | 类型 |
| label | `string` | | 按钮文本 |
| className | `string` | | 外层 CSS 类名 |
| block | `boolean` | | 块状样式 |
| size | `string` | | 尺寸,支持`'xs'`、`'sm'`、`'md'` 、`'lg'` |
| align | `string` | | 位置,可选`'left'`或`'right'` |
| buttons | `Array<action>` | | 配置下拉按钮 |
| iconOnly | `boolean` | | 只显示 icon |
| defaultIsOpened | `boolean` | | 默认是否打开 |
| closeOnOutside | `boolean` | `true` | 点击外侧区域是否收起 |
| closeOnClick | `boolean` | `false` | 点击按钮后自动关闭下拉菜单 |
| trigger | `click``hover` | `click` | 触发方式 |
| hideCaret | `boolean` | false | 隐藏下拉图标 |
| 属性名 | 类型 | 默认值 | 说明 |
| --------------- | ----------------------- | ----------------- | ----------------------------------------- |
| type | `string` | `dropdown-button` | 类型 |
| label | `string` | | 按钮文本 |
| className | `string` | | 外层 CSS 类名 |
| btnClassName | `string` | | 按钮 CSS 类名 |
| menuClassName | `string` | | 下拉菜单 CSS 类名 |
| block | `boolean` | | 块状样式 |
| size | `string` | | 尺寸,支持`'xs'`、`'sm'`、`'md'` 、`'lg'` |
| align | `string` | | 位置,可选`'left'`或`'right'` |
| buttons | `Array<DropdownButton>` | | 配置下拉按钮 |
| iconOnly | `boolean` | | 只显示 icon |
| defaultIsOpened | `boolean` | | 默认是否打开 |
| closeOnOutside | `boolean` | `true` | 点击外侧区域是否收起 |
| closeOnClick | `boolean` | `false` | 点击按钮后自动关闭下拉菜单 |
| trigger | `click``hover` | `click` | 触发方式 |
| hideCaret | `boolean` | false | 隐藏下拉图标 |

View File

@ -626,10 +626,11 @@
--DropDown-menu-paddingX: 0;
--DropDown-menu-paddingY: var(--gap-xs);
--DropDown-menuItem-onHover-bg: var(--ListMenu-item--onHover-bg);
--DropDown-menuItem-color: var(--text-color);
--DropDown-group-color: #848b99;
--DropDown-menuItem-color: #151a26;
--DropDown-menuItem-onHover-color: var(--primary);
--DropDown-menuItem-onActive-color: var(--primary);
--DropDown-menuItem-onDisabled-color: var(--text--muted-color);
--DropDown-menuItem-onDisabled-color: #b4b6ba;
--DropDown-menuItem-paddingX: var(--gap-sm);
--DropDown-menuItem-paddingY: calc(
(var(--DropDown-menu-height) - var(--fontSizeBase) * var(--lineHeightBase)) /

View File

@ -34,20 +34,28 @@
}
&-menu {
position: absolute;
z-index: $zindex-dropdown;
top: 100%;
left: 0;
margin: px2rem(1px) 0 0;
background: var(--DropDown-menu-bg);
list-style: none;
padding: var(--DropDown-menu-paddingY) var(--DropDown-menu-paddingX);
border: var(--DropDown-menu-borderWidth) solid
var(--DropDown-menu-borderColor);
border-radius: var(--DropDown-menu-borderRadius);
box-shadow: var(--DropDown-menu-boxShadow);
min-width: var(--DropDown-menu-minWidth);
text-align: left;
border: none;
user-select: none;
&-root {
position: absolute;
z-index: $zindex-dropdown;
top: 100%;
left: 0;
margin: px2rem(1px) 0 0;
border: none;
border-radius: var(--DropDown-menu-borderRadius);
box-shadow: var(--DropDown-menu-boxShadow);
min-width: var(--DropDown-menu-minWidth);
overflow-y: auto;
overflow-x: hidden;
max-height: px2rem(300px);
}
}
&--alignRight &-menu {
@ -95,6 +103,28 @@
background: var(--DropDown-menu-borderColor);
padding: 0;
}
&.#{$ns}DropDown-groupTitle {
height: inherit;
font-size: var(--fontSizeSm);
padding: var(--gap-xs) var(--gap-xs);
padding-left: var(--gap-sm);
color: var(--DropDown-group-color);
flex-grow: 1;
cursor: default;
&:hover {
background: none;
}
span {
white-space: nowrap;
}
& ~ .#{$ns}DropDown-button {
padding-left: var(--gap-lg);
}
}
}
&-menu > li a {

View File

@ -639,7 +639,8 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
--TimelineItem--round-radius: #{$R8};
--TimelineItem--content-radius: #{$R2};
--TimelineItem-detail-visible-shadow: 0 #{px2rem(1px)} #{px2rem(10px)} 0 rgba(0 0 0 / 10%);
--TimelineItem-detail-visible-shadow: 0 #{px2rem(1px)} #{px2rem(10px)} 0
rgba(0 0 0 / 10%);
--TimelineItem--font-size: #{$T2};
@ -655,7 +656,6 @@ $L1: 0px 4px 6px 0px rgba(8, 14, 26, 0.06),
--Timeline--warning-bg: var(--warning);
--Timeline--danger-bg: var(--danger);
// Formula
--Formula-header-bgColor: #{$G10};
--Formula-funcItem-bgColor-onActive: #{$light};

View File

@ -96,18 +96,6 @@
}
}
.#{$ns}DropDown {
.#{$ns}DropDown-menu {
border: none;
> li {
color: #{$G2};
}
> li.is-disabled {
color: #{$G6};
}
}
}
.#{$ns}Toast {
.#{$ns}Toast-icon {
margin-right: #{px2rem(8px)};

View File

@ -13,6 +13,13 @@ import {DividerSchema} from './Divider';
import {RootClose} from '../utils/RootClose';
import {generateIcon} from '../utils/icon';
import type {Option} from '../components/Select';
export type DropdownButton =
| (ActionSchema & {children?: Array<DropdownButton>})
| DividerSchema
| 'divider';
/**
*
* https://baidu.gitee.io/amis/docs/components/dropdown-button
@ -34,9 +41,9 @@ export interface DropdownButtonSchema extends BaseSchema {
btnClassName?: SchemaClassName;
/**
*
*
*/
buttons?: Array<ActionSchema | DividerSchema | 'divider'>;
buttons?: Array<DropdownButton>;
/**
*
@ -92,6 +99,11 @@ export interface DropdownButtonSchema extends BaseSchema {
*
*/
hideCaret?: boolean;
/**
* CSS
*/
menuClassName?: string;
}
export interface DropDownButtonProps
@ -110,6 +122,7 @@ export interface DropDownButtonProps
label?: any;
// 激活状态
isActived?: boolean;
menuClassName?: string;
}
export interface DropDownButtonState {
@ -175,6 +188,49 @@ export default class DropDownButton extends React.Component<
});
}
renderButton(
button: DropdownButton,
index: number | string
): React.ReactNode {
const {render, classnames: cx, data} = this.props;
index = typeof index === 'number' ? index.toString() : index;
if (typeof button !== 'string' && Array.isArray(button?.children)) {
return (
<div key={index} className={cx('DropDown-menu')}>
<li key={`${index}/0`} className={cx('DropDown-groupTitle')}>
{button.icon ? generateIcon(cx, button.icon, 'm-r-xs') : null}
<span>{button.label}</span>
</li>
{button.children.map((child, childIndex) =>
this.renderButton(child, `${index}/${childIndex + 1}`)
)}
</div>
);
}
if (typeof button !== 'string' && !isVisible(button, data)) {
return null;
} else if (button === 'divider' || button.type === 'divider') {
return <li key={index} className={cx('DropDown-divider')} />;
} else {
return (
<li
key={index}
className={cx('DropDown-button', {
['is-disabled']: isDisabled(button, data)
})}
>
{render(`button/${index}`, {
type: 'button',
...(button as any),
isMenuItem: true
})}
</li>
);
}
}
renderOuter() {
const {
render,
@ -186,7 +242,8 @@ export default class DropDownButton extends React.Component<
children,
align,
closeOnClick,
closeOnOutside
closeOnOutside,
menuClassName
} = this.props;
let body = (
@ -197,43 +254,20 @@ export default class DropDownButton extends React.Component<
{(ref: any) => {
return (
<ul
className={cx('DropDown-menu')}
className={cx(
'DropDown-menu-root',
'DropDown-menu',
menuClassName
)}
onClick={closeOnClick ? this.close : noop}
ref={ref}
>
{children
? children
: Array.isArray(buttons)
? buttons.map((button, index) => {
if (
typeof button !== 'string' &&
!isVisible(button, data)
) {
return null;
} else if (
button === 'divider' ||
button.type === 'divider'
) {
return (
<li key={index} className={cx('DropDown-divider')} />
);
}
return (
<li
key={index}
className={
isDisabled(button, data) ? 'is-disabled' : ''
}
>
{render(`button/${index}`, {
type: 'button',
...(button as any),
isMenuItem: true
})}
</li>
);
})
? buttons.map((button, index) =>
this.renderButton(button, index)
)
: null}
</ul>
);
@ -248,7 +282,7 @@ export default class DropDownButton extends React.Component<
overlay
onHide={this.close}
classPrefix={ns}
className={cx('DropDown-popover')}
className={cx('DropDown-popover', menuClassName)}
style={{minWidth: this.target?.offsetWidth}}
>
{body}