mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-06 16:06:28 +08:00
Update dependendies (#8150)
* deps: upgrade rc-menu, and close: #2837 * test: update snapshots * Update rc-calendar * Update rc-cascader * Update rc-dialog * Update dropdown * Update rc-select@7.1.0 * Update rc-slider * Update rc-time-picker * Update rc-tooltip * Update rc-tree-select * Mock rc-trigger and Portal * Fix animation warning when inlineCollapsed changes * fix: should use SubMenu[popupClassName] * Fix typescript error * Fix lint * fix: style for menu * Mock rc-trigger for React 15 * Remvoe allow_failures
This commit is contained in:
parent
fe7386746c
commit
55c85f77a1
@ -19,8 +19,6 @@ matrix:
|
||||
- env: REACT=15 TEST_TYPE=test:es
|
||||
- env: REACT=15 TEST_TYPE=test:dom
|
||||
- env: REACT=15 TEST_TYPE=test:node
|
||||
allow_failures:
|
||||
- env: REACT=16 TEST_TYPE=test:dist
|
||||
|
||||
before_script:
|
||||
- scripts/install-react.sh
|
||||
|
@ -17,6 +17,15 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 3.0.0
|
||||
|
||||
- Select
|
||||
- 单选和多选模式 Option 支持 number。
|
||||
- 新增 `maxTagCount` 和 `maxTagPlaceholder`。
|
||||
- 新增 `showAction`。
|
||||
- 新增 `onMouseEnter` 和 `onMouseLeave`。
|
||||
- 新增 `focus()`、`blur()` 和 `autoFocus`。
|
||||
|
||||
## 2.13.9
|
||||
|
||||
`2017-11-06`
|
||||
|
@ -234,7 +234,7 @@ exports[`RangePicker show month panel according to value 1`] = `
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-selected-day"
|
||||
class="ant-calendar-cell ant-calendar-selected-start-date ant-calendar-selected-end-date ant-calendar-selected-day"
|
||||
role="gridcell"
|
||||
title="2000年1月1日"
|
||||
>
|
||||
@ -1739,7 +1739,7 @@ exports[`RangePicker switch to corresponding month panel when click presetted ra
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-calendar-cell ant-calendar-selected-day"
|
||||
class="ant-calendar-cell ant-calendar-selected-start-date ant-calendar-selected-end-date ant-calendar-selected-day"
|
||||
role="gridcell"
|
||||
title="2000年1月1日"
|
||||
>
|
||||
|
@ -139,13 +139,13 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@ -219,7 +219,7 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-horizontal ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
@ -233,7 +233,7 @@ exports[`renders ./components/layout/demo/fixed.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
@ -323,7 +323,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -374,7 +374,7 @@ exports[`renders ./components/layout/demo/fixed-sider.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@ -588,7 +588,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -639,7 +639,7 @@ exports[`renders ./components/layout/demo/responsive.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@ -699,13 +699,13 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@ -730,7 +730,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -753,7 +753,7 @@ exports[`renders ./components/layout/demo/side.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -867,7 +867,7 @@ exports[`renders ./components/layout/demo/top.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-horizontal ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
@ -881,7 +881,7 @@ exports[`renders ./components/layout/demo/top.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
@ -967,7 +967,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-horizontal ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
@ -981,7 +981,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
@ -1053,13 +1053,13 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="height:100%"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -1080,13 +1080,13 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
>
|
||||
@ -1119,7 +1119,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -1140,7 +1140,7 @@ exports[`renders ./components/layout/demo/top-side.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -1192,7 +1192,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
/>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-horizontal ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
style="line-height:64px"
|
||||
tabindex="0"
|
||||
@ -1206,7 +1206,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
</li>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
nav 2
|
||||
@ -1232,13 +1232,13 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="height:100%;border-right:0"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -1259,13 +1259,13 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
>
|
||||
@ -1298,7 +1298,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -1319,7 +1319,7 @@ exports[`renders ./components/layout/demo/top-side-2.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
|
File diff suppressed because it is too large
Load Diff
22
components/menu/SubMenu.tsx
Normal file
22
components/menu/SubMenu.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { SubMenu as RcSubMenu } from 'rc-menu';
|
||||
import classNames from 'classnames';
|
||||
|
||||
class SubMenu extends React.Component<any, any> {
|
||||
static contextTypes = {
|
||||
antdMenuTheme: PropTypes.string,
|
||||
};
|
||||
render() {
|
||||
const { rootPrefixCls, className } = this.props;
|
||||
const theme = this.context.antdMenuTheme;
|
||||
return (
|
||||
<RcSubMenu
|
||||
{...this.props}
|
||||
popupClassName={classNames(`${rootPrefixCls}-${theme}`, className)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SubMenu;
|
@ -3,13 +3,13 @@
|
||||
exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-horizontal ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-horizontal"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
>
|
||||
<i
|
||||
@ -20,7 +20,7 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
<li
|
||||
aria-disabled="true"
|
||||
aria-selected="false"
|
||||
class="ant-menu-item-disabled ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-disabled"
|
||||
role="menuitem"
|
||||
>
|
||||
<i
|
||||
@ -29,7 +29,7 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
Navigation Two
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-horizontal ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-horizontal"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -67,13 +67,13 @@ exports[`renders ./components/menu/demo/horizontal.md correctly 1`] = `
|
||||
exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -96,7 +96,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@ -114,7 +114,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
>
|
||||
@ -163,7 +163,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -186,7 +186,7 @@ exports[`renders ./components/menu/demo/inline.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -226,13 +226,13 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</button>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@ -270,7 +270,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -293,7 +293,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@ -332,7 +332,7 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -361,13 +361,13 @@ exports[`renders ./components/menu/demo/inline-collapsed.md correctly 1`] = `
|
||||
exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -390,7 +390,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@ -429,7 +429,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -452,7 +452,7 @@ exports[`renders ./components/menu/demo/sider-current.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -505,14 +505,14 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
<br />
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:24px"
|
||||
>
|
||||
@ -533,7 +533,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
Navigation Two
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -556,7 +556,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
@ -577,7 +577,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
Option 4
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -596,7 +596,7 @@ exports[`renders ./components/menu/demo/switch-mode.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -639,13 +639,13 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
<br />
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-dark ant-menu-root"
|
||||
class="ant-menu ant-menu-dark ant-menu-root ant-menu-inline"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline ant-menu-submenu-open ant-menu-submenu-selected"
|
||||
>
|
||||
<div
|
||||
aria-expanded="true"
|
||||
@ -668,13 +668,13 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
</div>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-inline ant-menu-sub"
|
||||
class="ant-menu ant-menu-sub ant-menu-inline"
|
||||
id="sub1$Menu"
|
||||
role="menu"
|
||||
>
|
||||
<li
|
||||
aria-selected="true"
|
||||
class="ant-menu-item-selected ant-menu-item"
|
||||
class="ant-menu-item ant-menu-item-selected"
|
||||
role="menuitem"
|
||||
style="padding-left:48px"
|
||||
>
|
||||
@ -707,7 +707,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
</ul>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -730,7 +730,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-inline ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-inline"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -759,13 +759,13 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-menu ant-menu-vertical ant-menu-light ant-menu-root"
|
||||
class="ant-menu ant-menu-light ant-menu-root ant-menu-vertical"
|
||||
role="menu"
|
||||
style="width:256px"
|
||||
tabindex="0"
|
||||
>
|
||||
<li
|
||||
class="ant-menu-submenu-vertical ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -787,7 +787,7 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-vertical ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -809,7 +809,7 @@ exports[`renders ./components/menu/demo/vertical.md correctly 1`] = `
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
class="ant-menu-submenu-vertical ant-menu-submenu"
|
||||
class="ant-menu-submenu ant-menu-submenu-vertical"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
|
@ -4,7 +4,6 @@ import Menu from '..';
|
||||
import Icon from '../../icon';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
|
||||
|
||||
describe('Menu', () => {
|
||||
it('should accept defaultOpenKeys in mode horizontal', () => {
|
||||
@ -46,7 +45,7 @@ describe('Menu', () => {
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
});
|
||||
|
||||
it('should accept openKeys in mode horizontal', () => {
|
||||
it('horizontal', () => {
|
||||
const wrapper = mount(
|
||||
<Menu openKeys={['1']} mode="horizontal" openTransitionName="">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
@ -64,7 +63,7 @@ describe('Menu', () => {
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
});
|
||||
|
||||
it('should accept openKeys in mode inline', () => {
|
||||
it('inline', () => {
|
||||
const wrapper = mount(
|
||||
<Menu openKeys={['1']} mode="inline" openAnimation="">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
@ -82,7 +81,7 @@ describe('Menu', () => {
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
});
|
||||
|
||||
it('should accept openKeys in mode vertical', () => {
|
||||
it('vertical', () => {
|
||||
const wrapper = mount(
|
||||
<Menu openKeys={['1']} mode="vertical" openTransitionName="">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
@ -133,7 +132,9 @@ describe('Menu', () => {
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
});
|
||||
|
||||
it('should always follow openKeys when mode is switched', () => {
|
||||
it('should always follow openKeys when mode is switched', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
const wrapper = mount(
|
||||
<Menu defaultOpenKeys={['1']} mode="inline">
|
||||
<Menu.Item key="menu1">
|
||||
@ -150,76 +151,97 @@ describe('Menu', () => {
|
||||
</SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
|
||||
wrapper.setProps({ inlineCollapsed: true });
|
||||
setTimeout(() => {
|
||||
// 动画结束后套样式;
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
wrapper.setProps({ inlineCollapsed: false });
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
}, 300);
|
||||
// 动画结束后套样式;
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('.ant-menu').at(0).hasClass('ant-menu-vertical')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
|
||||
wrapper.setProps({ inlineCollapsed: false });
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-inline')).toBe(true);
|
||||
expect(wrapper.find('.ant-menu-sub').at(0).hasClass('ant-menu-hidden')).toBe(false);
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should open submenu when click submenu title (inline)', async () => {
|
||||
const wrapper = mount(
|
||||
<Menu mode="inline">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
wrapper.find('.ant-menu-submenu-title').simulate('click');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().length).toBe(1);
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
wrapper.find('.ant-menu-submenu-title').simulate('click');
|
||||
await delay(300);
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
});
|
||||
describe('open submenu when click submenu title', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
it('should open submenu when hover submenu title (vertical)', async () => {
|
||||
const wrapper = mount(
|
||||
<Menu mode="vertical">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
wrapper.find('.ant-menu-submenu-title').simulate('mouseenter');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().length).toBe(1);
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
wrapper.find('.ant-menu-submenu').simulate('mouseleave');
|
||||
await delay(300);
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('should open submenu when hover submenu title (horizontal)', async () => {
|
||||
const wrapper = mount(
|
||||
<Menu mode="horizontal">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
wrapper.find('.ant-menu-submenu-title').simulate('mouseenter');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().length).toBe(1);
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
wrapper.find('.ant-menu-submenu').simulate('mouseleave');
|
||||
await delay(300);
|
||||
wrapper.update();
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
const toggleMenu = (wrapper, index, event) => {
|
||||
wrapper.find('.ant-menu-submenu-title').at(index).simulate(event);
|
||||
jest.runAllTimers();
|
||||
wrapper.update();
|
||||
};
|
||||
|
||||
it('inline', () => {
|
||||
const wrapper = mount(
|
||||
<Menu mode="inline">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
toggleMenu(wrapper, 0, 'click');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().length).toBe(1);
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
toggleMenu(wrapper, 0, 'click');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('vertical', () => {
|
||||
const wrapper = mount(
|
||||
<Menu mode="vertical">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
toggleMenu(wrapper, 0, 'mouseenter');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().length).toBe(1);
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
toggleMenu(wrapper, 0, 'mouseleave');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
});
|
||||
|
||||
it('horizontal', () => {
|
||||
jest.useFakeTimers();
|
||||
const wrapper = mount(
|
||||
<Menu mode="horizontal">
|
||||
<SubMenu key="1" title="submenu1">
|
||||
<Menu.Item key="submenu1">Option 1</Menu.Item>
|
||||
<Menu.Item key="submenu2">Option 2</Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item key="2">menu2</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
expect(wrapper.find('.ant-menu-sub').length).toBe(0);
|
||||
toggleMenu(wrapper, 0, 'mouseenter');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().length).toBe(1);
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).not.toBe(true);
|
||||
toggleMenu(wrapper, 0, 'mouseleave');
|
||||
expect(wrapper.find('.ant-menu-sub').hostNodes().at(0).hasClass('ant-menu-hidden')).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -32,7 +32,7 @@ More layouts with navigation: [layout](/components/layout).
|
||||
| defaultSelectedKeys | array with the keys of default selected menu items | string\[] | |
|
||||
| inlineCollapsed | specifies the collapsed status when menu is inline mode | boolean | - |
|
||||
| inlineIndent | indent px of inline menu item on each level | number | 24 |
|
||||
| mode | type of the menu; `vertical`, `horizontal`, and `inline` modes are supported | string: `vertical` \| `horizontal` \| `inline` | `vertical` |
|
||||
| mode | type of the menu; `vertical`, `horizontal`, and `inline` modes are supported | string: `vertical` \| `vertical-right` \| `horizontal` \| `inline` | `vertical` |
|
||||
| multiple | Allow selection of multiple items | boolean | false |
|
||||
| openKeys | array with the keys of currently opened sub menus | string\[] | |
|
||||
| selectable | Allow to be selected | boolean | true |
|
||||
@ -44,6 +44,8 @@ More layouts with navigation: [layout](/components/layout).
|
||||
| onDeselect | callback executed when a menu item is deselected, only supported for multiple mode | function({ item, key, selectedKeys }) | - |
|
||||
| onOpenChange | called when open/close sub menu | function(openKeys: string\[]) | noop |
|
||||
| onSelect | callback executed when a menu item is selected | function({ item, key, selectedKeys }) | none |
|
||||
| subMenuOpenDelay | delay time to show submenu when mouse enter, unit: second | number | 0 |
|
||||
| subMenuCloseDelay | delay time to hide submenu when mouse leave, unit: second | number | 0.1 |
|
||||
|
||||
> More options in [rc-menu](https://github.com/react-component/menu#api)
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import RcMenu, { Divider, SubMenu, ItemGroup } from 'rc-menu';
|
||||
import RcMenu, { Divider, ItemGroup } from 'rc-menu';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import animation from '../_util/openAnimation';
|
||||
import warning from '../_util/warning';
|
||||
import SubMenu from './SubMenu';
|
||||
import Item from './MenuItem';
|
||||
|
||||
export interface SelectParam {
|
||||
@ -23,10 +24,8 @@ export interface ClickParam {
|
||||
|
||||
export interface MenuProps {
|
||||
id?: string;
|
||||
/** `light` `dark` */
|
||||
theme?: 'light' | 'dark';
|
||||
/** enum: `vertical` `horizontal` `inline` */
|
||||
mode?: 'vertical' | 'horizontal' | 'inline';
|
||||
mode?: 'vertical' | 'vertical-left' | 'vertical-right' | 'horizontal' | 'inline';
|
||||
selectable?: boolean;
|
||||
selectedKeys?: Array<string>;
|
||||
defaultSelectedKeys?: Array<string>;
|
||||
@ -58,6 +57,7 @@ export default class Menu extends React.Component<MenuProps, any> {
|
||||
};
|
||||
static childContextTypes = {
|
||||
inlineCollapsed: PropTypes.bool,
|
||||
antdMenuTheme: PropTypes.string,
|
||||
};
|
||||
static contextTypes = {
|
||||
siderCollapsed: PropTypes.bool,
|
||||
@ -92,6 +92,7 @@ export default class Menu extends React.Component<MenuProps, any> {
|
||||
getChildContext() {
|
||||
return {
|
||||
inlineCollapsed: this.getInlineCollapsed(),
|
||||
antdMenuTheme: this.props.theme,
|
||||
};
|
||||
}
|
||||
componentWillReceiveProps(nextProps, nextContext) {
|
||||
@ -160,6 +161,8 @@ export default class Menu extends React.Component<MenuProps, any> {
|
||||
menuOpenAnimation = 'slide-up';
|
||||
break;
|
||||
case 'vertical':
|
||||
case 'vertical-left':
|
||||
case 'vertical-right':
|
||||
// When mode switch from inline
|
||||
// submenu should hide without animation
|
||||
if (this.switchModeFromInline) {
|
||||
@ -176,6 +179,11 @@ export default class Menu extends React.Component<MenuProps, any> {
|
||||
// Make sure inline menu leave animation finished before mode is switched
|
||||
this.switchModeFromInline = false;
|
||||
this.setState({});
|
||||
// when inlineCollapsed change false to true, all submenu will be unmounted,
|
||||
// so that we don't need handle animation leaving.
|
||||
if (this.getRealMenuMode() === 'vertical') {
|
||||
return;
|
||||
}
|
||||
done();
|
||||
}),
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ subtitle: 导航菜单
|
||||
| defaultSelectedKeys | 初始选中的菜单项 key 数组 | string\[] | |
|
||||
| inlineCollapsed | inline 时菜单是否收起状态 | boolean | - |
|
||||
| inlineIndent | inline 模式的菜单缩进宽度 | number | 24 |
|
||||
| mode | 菜单类型,现在支持垂直、水平、和内嵌模式三种 | string: `vertical` `horizontal` `inline` | `vertical` |
|
||||
| mode | 菜单类型,现在支持垂直、水平、和内嵌模式三种 | string: `vertical` `vertical-right` `horizontal` `inline` | `vertical` |
|
||||
| multiple | 是否允许多选 | boolean | false |
|
||||
| openKeys | 当前展开的 SubMenu 菜单项 key 数组 | string\[] | |
|
||||
| selectable | 是否允许选中 | boolean | true |
|
||||
@ -44,6 +44,8 @@ subtitle: 导航菜单
|
||||
| onDeselect | 取消选中时调用,仅在 multiple 生效 | function({ item, key, selectedKeys }) | - |
|
||||
| onOpenChange | SubMenu 展开/关闭的回调 | function(openKeys: string\[]) | noop |
|
||||
| onSelect | 被选中时调用 | function({ item, key, selectedKeys }) | 无 |
|
||||
| subMenuOpenDelay | 用户鼠标进入子菜单后开启延时,单位:秒 | number | 0 |
|
||||
| subMenuCloseDelay | 用户鼠标离开子菜单后关闭延时,单位:秒 | number | 0.1 |
|
||||
|
||||
> More options in [rc-menu](https://github.com/react-component/menu#api)
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
margin-bottom: 0;
|
||||
padding-left: 0; // Override default ul/ol
|
||||
list-style: none;
|
||||
z-index: @zindex-dropdown;
|
||||
box-shadow: @box-shadow-base;
|
||||
background: @component-background;
|
||||
line-height: 0; // Fix display inline-block gap
|
||||
@ -102,10 +101,6 @@
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
&:not(&-inline) &-submenu-open {
|
||||
z-index: @zindex-dropdown;
|
||||
}
|
||||
|
||||
&-horizontal &-item,
|
||||
&-horizontal &-submenu {
|
||||
margin-top: -1px;
|
||||
@ -129,18 +124,12 @@
|
||||
background-color: @item-active-bg;
|
||||
}
|
||||
|
||||
&-horizontal,
|
||||
&-inline,
|
||||
&-vertical {
|
||||
z-index: auto;
|
||||
}
|
||||
|
||||
&-inline,
|
||||
&-vertical {
|
||||
border-right: @border-width-base @border-style-base @border-color-split;
|
||||
&-vertical,
|
||||
&-vertical-left,
|
||||
&-vertical-right {
|
||||
.@{menu-prefix-cls}-item {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@ -155,7 +144,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical&-sub {
|
||||
&-inline,
|
||||
&-vertical,
|
||||
&-vertical-left {
|
||||
border-right: @border-width-base @border-style-base @border-color-split;
|
||||
}
|
||||
&-vertical-right {
|
||||
border-left: @border-width-base @border-style-base @border-color-split;
|
||||
}
|
||||
|
||||
&-vertical&-sub,
|
||||
&-vertical-left&-sub,
|
||||
&-vertical-right&-sub {
|
||||
border-right: 0;
|
||||
.@{menu-prefix-cls}-item {
|
||||
border-right: 0;
|
||||
@ -167,26 +167,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-submenu-horizontal > & {
|
||||
top: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
min-width: 100%;
|
||||
margin-top: 7px;
|
||||
z-index: @zindex-dropdown;
|
||||
}
|
||||
|
||||
&-submenu-vertical {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&-submenu-vertical > & {
|
||||
top: 0;
|
||||
left: 100%;
|
||||
position: absolute;
|
||||
&-horizontal&-sub,
|
||||
&-vertical&-sub,
|
||||
&-vertical-left&-sub,
|
||||
&-vertical-right&-sub {
|
||||
min-width: 160px;
|
||||
margin-left: 4px;
|
||||
z-index: @zindex-dropdown;
|
||||
}
|
||||
|
||||
&-item,
|
||||
@ -217,7 +202,9 @@
|
||||
}
|
||||
|
||||
&-submenu {
|
||||
position: relative;
|
||||
&-popup {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
> .@{menu-prefix-cls} {
|
||||
background-color: @component-background;
|
||||
@ -227,9 +214,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical > .@{menu-prefix-cls}-submenu-title,
|
||||
&-inline > .@{menu-prefix-cls}-submenu-title {
|
||||
.@{menu-prefix-cls}-submenu-arrow {
|
||||
&-vertical,
|
||||
&-vertical-left,
|
||||
&-vertical-right,
|
||||
&-inline {
|
||||
> .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow {
|
||||
transition: transform .3s @ease-in-out;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
@ -251,11 +240,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow:before {
|
||||
transform: rotate(-45deg) translateY(2px);
|
||||
&-vertical,
|
||||
&-vertical-left,
|
||||
&-vertical-right {
|
||||
> .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow:before {
|
||||
transform: rotate(-45deg) translateY(2px);
|
||||
}
|
||||
}
|
||||
&-vertical > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow:after {
|
||||
transform: rotate(45deg) translateY(-2px);
|
||||
&-vertical,
|
||||
&-vertical-left,
|
||||
&-vertical-right {
|
||||
> .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow:after {
|
||||
transform: rotate(45deg) translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
&-inline > .@{menu-prefix-cls}-submenu-title .@{menu-prefix-cls}-submenu-arrow:after {
|
||||
@ -265,9 +262,11 @@
|
||||
transform: rotate(-45deg) translateX(2px);
|
||||
}
|
||||
|
||||
&-vertical > .@{menu-prefix-cls}-submenu-title:hover,
|
||||
&-inline > .@{menu-prefix-cls}-submenu-title:hover {
|
||||
.@{menu-prefix-cls}-submenu-arrow {
|
||||
&-vertical,
|
||||
&-vertical-left,
|
||||
&-vertical-right,
|
||||
&-inline {
|
||||
> .@{menu-prefix-cls}-submenu-title:hover .@{menu-prefix-cls}-submenu-arrow {
|
||||
&:after,
|
||||
&:before {
|
||||
background: linear-gradient(to right, @primary-color, @primary-color);
|
||||
@ -288,7 +287,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical &-submenu-selected {
|
||||
&-vertical &-submenu-selected,
|
||||
&-vertical-left &-submenu-selected,
|
||||
&-vertical-right &-submenu-selected {
|
||||
color: @primary-color;
|
||||
> a {
|
||||
color: @primary-color;
|
||||
@ -299,7 +300,6 @@
|
||||
border: 0;
|
||||
border-bottom: @border-width-base @border-style-base @border-color-split;
|
||||
box-shadow: none;
|
||||
z-index: 0;
|
||||
line-height: 46px;
|
||||
|
||||
> .@{menu-prefix-cls}-item,
|
||||
@ -335,6 +335,8 @@
|
||||
}
|
||||
|
||||
&-vertical,
|
||||
&-vertical-left,
|
||||
&-vertical-right,
|
||||
&-inline {
|
||||
.@{menu-prefix-cls}-item,
|
||||
.@{menu-prefix-cls}-submenu-title {
|
||||
@ -344,7 +346,6 @@
|
||||
height: @menu-item-height;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@ -423,7 +424,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
&-vertical&-sub {
|
||||
&-vertical&-sub,
|
||||
&-vertical-left&-sub,
|
||||
&-vertical-right&-sub {
|
||||
padding: 0;
|
||||
transform-origin: 0 0;
|
||||
& > .@{menu-prefix-cls}-item,
|
||||
@ -433,6 +436,8 @@
|
||||
}
|
||||
|
||||
&-root&-vertical,
|
||||
&-root&-vertical-left,
|
||||
&-root&-vertical-right,
|
||||
&-root&-inline {
|
||||
box-shadow: none;
|
||||
}
|
||||
@ -511,12 +516,16 @@
|
||||
}
|
||||
|
||||
&-dark&-inline,
|
||||
&-dark&-vertical {
|
||||
&-dark&-vertical,
|
||||
&-dark&-vertical-left,
|
||||
&-dark&-vertical-right {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
&-dark&-inline &-item,
|
||||
&-dark&-vertical &-item {
|
||||
&-dark&-vertical &-item,
|
||||
&-dark&-vertical-left &-item,
|
||||
&-dark&-vertical-right &-item {
|
||||
border-right: 0;
|
||||
margin-left: 0;
|
||||
left: 0;
|
||||
|
@ -2,6 +2,8 @@ import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import Modal from '..';
|
||||
|
||||
jest.mock('rc-util/lib/Portal');
|
||||
|
||||
class ModalTester extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -2,67 +2,66 @@
|
||||
|
||||
exports[`Modal render correctly 1`] = `
|
||||
<div>
|
||||
<div />
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
>
|
||||
<div
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
class="ant-modal-content"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-content"
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-modal-body"
|
||||
>
|
||||
Here is content of Modal
|
||||
</div>
|
||||
<div
|
||||
class="ant-modal-footer"
|
||||
>
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
OK
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-modal-body"
|
||||
>
|
||||
Here is content of Modal
|
||||
</div>
|
||||
<div
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
class="ant-modal-footer"
|
||||
>
|
||||
sentinel
|
||||
<div>
|
||||
<button
|
||||
class="ant-btn"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Cancel
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
OK
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
>
|
||||
sentinel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -71,45 +70,44 @@ exports[`Modal render correctly 1`] = `
|
||||
|
||||
exports[`Modal render without footer 1`] = `
|
||||
<div>
|
||||
<div />
|
||||
<div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-mask fade-appear"
|
||||
/>
|
||||
<div
|
||||
class="ant-modal-wrap "
|
||||
role="dialog"
|
||||
tabindex="-1"
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
>
|
||||
<div
|
||||
class="ant-modal zoom-appear"
|
||||
role="document"
|
||||
style="width: 520px;"
|
||||
class="ant-modal-content"
|
||||
>
|
||||
<div
|
||||
class="ant-modal-content"
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
>
|
||||
<button
|
||||
aria-label="Close"
|
||||
class="ant-modal-close"
|
||||
>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
class="ant-modal-body"
|
||||
>
|
||||
Here is content of Modal
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="ant-modal-close-x"
|
||||
/>
|
||||
</button>
|
||||
<div
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
class="ant-modal-body"
|
||||
>
|
||||
sentinel
|
||||
Here is content of Modal
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width: 0px; height: 0px; overflow: hidden;"
|
||||
tabindex="0"
|
||||
>
|
||||
sentinel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,6 +7,7 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
||||
|
||||
afterEach(() => {
|
||||
errorSpy.mockReset();
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
@ -46,7 +47,7 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
||||
onOk,
|
||||
});
|
||||
// second Modal
|
||||
$$('.ant-btn-primary')[1].click();
|
||||
$$('.ant-btn-primary')[0].click();
|
||||
expect(onCancel.mock.calls.length).toBe(0);
|
||||
expect(onOk.mock.calls.length).toBe(1);
|
||||
});
|
||||
@ -54,14 +55,14 @@ describe('Modal.confirm triggers callbacks correctly', () => {
|
||||
it('should allow Modal.comfirm without onCancel been set', () => {
|
||||
open();
|
||||
// Third Modal
|
||||
$$('.ant-btn')[4].click();
|
||||
$$('.ant-btn')[0].click();
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should allow Modal.comfirm without onOk been set', () => {
|
||||
open();
|
||||
// Fourth Modal
|
||||
$$('.ant-btn-primary')[3].click();
|
||||
$$('.ant-btn-primary')[0].click();
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ describe('Popconfirm', () => {
|
||||
const triggerNode = wrapper.find('span').at(0);
|
||||
triggerNode.simulate('click');
|
||||
expect(onVisibleChange).toBeCalledWith(true);
|
||||
expect(document.querySelectorAll('.popconfirm-test').length).toBe(1);
|
||||
expect(wrapper.find('.popconfirm-test').length).toBe(1);
|
||||
|
||||
triggerNode.simulate('click');
|
||||
expect(onVisibleChange).toBeCalledWith(false);
|
||||
|
@ -102,7 +102,7 @@ exports[`renders ./components/select/demo/basic.md correctly 1`] = `
|
||||
</div>
|
||||
<span
|
||||
class="ant-select-selection__clear"
|
||||
style="user-select:none;-webkit-user-select:none;display:block"
|
||||
style="user-select:none;-webkit-user-select:none"
|
||||
unselectable="unselectable"
|
||||
/>
|
||||
<span
|
||||
|
@ -24,6 +24,7 @@ Select component to select value from options.
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| allowClear | Show clear button. | boolean | false |
|
||||
| autoFocus | Get focus by default | boolean | false |
|
||||
| combobox | Enable combobox mode (can not set multiple at the same time). (Deprecated after 2.9, use `mode` instead) | boolean | false |
|
||||
| defaultActiveFirstOption | Whether active first option by default | boolean | true |
|
||||
| defaultValue | Initial selected option. | string\|string\[] | - |
|
||||
@ -35,6 +36,8 @@ Select component to select value from options.
|
||||
| firstActiveValue | Value of action option by default | string\|string\[] | - |
|
||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative.[example](http://codepen.io/anon/pen/xVBOVQ?editors=001) | function(triggerNode) | () => document.body |
|
||||
| labelInValue | whether to embed label in value, turn the format of value from `string` to `{key: string, label: ReactNode}` | boolean | false |
|
||||
| maxTagCount | Max tag count to show | number | - |
|
||||
| maxTagPlaceholder | Placeholder for not showing tags | ReactNode | - |
|
||||
| mode | Set mode of Select (Support after 2.9) | 'multiple' \| 'tags' \| 'combobox' | - |
|
||||
| multiple | Allow multiple select (Deprecated after 2.9, use `mode` instead) | boolean | false |
|
||||
| notFoundContent | Specify content to show when no result matches.. | string | 'Not Found' |
|
||||
@ -50,9 +53,18 @@ Select component to select value from options.
|
||||
| onChange | Called when select an option or input value change, or value of input is changed in combobox mode | function(value, label) | - |
|
||||
| onDeselect | Called when a option is deselected, the params are option's value (or key) . only called for multiple or tags, effective in multiple or tags mode only. | function(value) | - |
|
||||
| onFocus | Called when focus | function | - |
|
||||
| onMouseEnter | Called when mouse enter | function | - |
|
||||
| onMouseLeave | Called when mouse leave | function | - |
|
||||
| onSearch | Callback function that is fired when input changed. | function(value: string) | |
|
||||
| onSelect | Called when a option is selected, the params are option's value (or key) and option instance. | function(value, option) | - |
|
||||
|
||||
### Select Methods
|
||||
|
||||
| Name | Description |
|
||||
| --- | --- |
|
||||
| blur() | Remove focus |
|
||||
| focus() | Get focus |
|
||||
|
||||
### Option props
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
|
@ -52,6 +52,7 @@ export interface SelectProps extends AbstractSelectProps {
|
||||
getPopupContainer?: (triggerNode: Element) => HTMLElement;
|
||||
tokenSeparators?: string[];
|
||||
getInputElement?: () => React.ReactElement<any>;
|
||||
autoFocus?: boolean;
|
||||
}
|
||||
|
||||
export interface OptionProps {
|
||||
@ -93,6 +94,20 @@ export default class Select extends React.Component<SelectProps, any> {
|
||||
|
||||
static propTypes = SelectPropTypes;
|
||||
|
||||
private rcSelect: any;
|
||||
|
||||
focus() {
|
||||
this.rcSelect.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.rcSelect.blur();
|
||||
}
|
||||
|
||||
saveSelect = (node) => {
|
||||
this.rcSelect = node;
|
||||
}
|
||||
|
||||
renderSelect = (locale) => {
|
||||
const {
|
||||
prefixCls,
|
||||
@ -133,6 +148,7 @@ export default class Select extends React.Component<SelectProps, any> {
|
||||
className={cls}
|
||||
optionLabelProp={optionLabelProp || 'children'}
|
||||
notFoundContent={notFoundContentLocale}
|
||||
ref={this.saveSelect}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ title: Select
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| allowClear | 支持清除 | boolean | false |
|
||||
| autoFocus | 默认获取焦点 | boolean | false |
|
||||
| combobox | 输入框自动提示模式(2.9 之后废弃,请使用 `mode`) | boolean | false |
|
||||
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true |
|
||||
| defaultValue | 指定默认选中的条目 | string\|string\[] | - |
|
||||
@ -36,6 +37,8 @@ title: Select
|
||||
| firstActiveValue | 默认高亮的选项 | string\|string\[] | - |
|
||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | () => document.body |
|
||||
| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 `string` 变为 `{key: string, label: ReactNode}` 的格式 | boolean | false |
|
||||
| maxTagCount | 最多显示多少个 tag | number | - |
|
||||
| maxTagPlaceholder | 隐藏 tag 时显示的内容 | ReactNode | - |
|
||||
| mode | 设置 Select 的模式(2.9 之后支持) | 'multiple' \| 'tags' \| 'combobox' | - |
|
||||
| multiple | 支持多选(2.9 之后废弃,请使用 `mode`) | boolean | false |
|
||||
| notFoundContent | 当下拉列表为空时显示的内容 | string | 'Not Found' |
|
||||
@ -51,11 +54,20 @@ title: Select
|
||||
| onChange | 选中 option,或 input 的 value 变化(combobox 模式下)时,调用此函数 | function(value) | - |
|
||||
| onDeselect | 取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效 | function(value) | - |
|
||||
| onFocus | 获得焦点时回调 | function | - |
|
||||
| onMouseEnter | 鼠标移入时回调 | function | - |
|
||||
| onMouseLeave | 鼠标移出时回调 | function | - |
|
||||
| onSearch | 文本框值变化时回调 | function(value: string) | |
|
||||
| onSelect | 被选中时调用,参数为选中项的 value (或 key) 值 | function(value, option) | - |
|
||||
|
||||
> 注意,如果发现下拉菜单跟随页面滚动,或者需要在其他弹层中触发 Select,请尝试使用 `getPopupContainer={triggerNode => triggerNode.parentNode}` 将下拉弹层渲染节点固定在触发器的父元素中。
|
||||
|
||||
### Select Methods
|
||||
|
||||
| 名称 | 说明 |
|
||||
| --- | --- |
|
||||
| blur() | 取消焦点 |
|
||||
| focus() | 获取焦点 |
|
||||
|
||||
### Option props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|
@ -115,7 +115,7 @@ describe('Table.filter', () => {
|
||||
}],
|
||||
}));
|
||||
|
||||
wrapper.find('Dropdown').first().simulate('click');
|
||||
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
|
||||
|
||||
expect(handleChange).toBeCalledWith(true);
|
||||
});
|
||||
|
@ -133,7 +133,7 @@ exports[`Table.filter renders menu correctly 1`] = `
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-dropdown-menu ant-dropdown-menu-vertical ant-dropdown-menu-root"
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -186,7 +186,7 @@ exports[`Table.filter renders menu correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="ant-dropdown-menu-submenu-vertical ant-dropdown-menu-submenu"
|
||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
@ -231,7 +231,7 @@ exports[`Table.filter renders radio filter correctly 1`] = `
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-dropdown-menu ant-dropdown-menu-vertical ant-dropdown-menu-root"
|
||||
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
@ -284,7 +284,7 @@ exports[`Table.filter renders radio filter correctly 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
class="ant-dropdown-menu-submenu-vertical ant-dropdown-menu-submenu"
|
||||
class="ant-dropdown-menu-submenu ant-dropdown-menu-submenu-vertical"
|
||||
>
|
||||
<div
|
||||
aria-expanded="false"
|
||||
|
@ -7,7 +7,7 @@ exports[`Table.rowSelection render with default selection correctly 1`] = `
|
||||
>
|
||||
<ul
|
||||
aria-activedescendant=""
|
||||
class="ant-dropdown-menu ant-dropdown-menu-vertical ant-table-selection-menu ant-dropdown-menu-light ant-dropdown-menu-root"
|
||||
class="ant-dropdown-menu ant-table-selection-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"
|
||||
role="menu"
|
||||
tabindex="0"
|
||||
>
|
||||
|
@ -0,0 +1,18 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Tooltip should hide when mouse leave antd disabled Button 1`] = `
|
||||
<span
|
||||
style="display: inline-block; cursor: not-allowed;"
|
||||
>
|
||||
<button
|
||||
class="ant-btn"
|
||||
disabled=""
|
||||
style="pointer-events: none;"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Hello world!
|
||||
</span>
|
||||
</button>
|
||||
</span>
|
||||
`;
|
@ -14,12 +14,12 @@ describe('Tooltip', () => {
|
||||
mouseLeaveDelay={0}
|
||||
onVisibleChange={onVisibleChange}
|
||||
>
|
||||
<div>Hello world!</div>
|
||||
<div id="hello">Hello world!</div>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
// `title` is empty.
|
||||
const div = wrapper.find('div').at(0);
|
||||
const div = wrapper.find('#hello').at(0);
|
||||
div.simulate('mouseenter');
|
||||
expect(onVisibleChange).not.toHaveBeenCalled();
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
@ -30,17 +30,17 @@ describe('Tooltip', () => {
|
||||
|
||||
// update `title` value.
|
||||
wrapper.setProps({ title: 'Have a nice day!' });
|
||||
wrapper.simulate('mouseenter');
|
||||
wrapper.find('#hello').simulate('mouseenter');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(true);
|
||||
|
||||
wrapper.simulate('mouseleave');
|
||||
wrapper.find('#hello').simulate('mouseleave');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(false);
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
|
||||
// add `visible` props.
|
||||
wrapper.setProps({ visible: false });
|
||||
wrapper.simulate('mouseenter');
|
||||
wrapper.find('#hello').simulate('mouseenter');
|
||||
expect(onVisibleChange).toHaveBeenLastCalledWith(true);
|
||||
const lastCount = onVisibleChange.mock.calls.length;
|
||||
expect(wrapper.instance().tooltip.props.visible).toBe(false);
|
||||
@ -88,7 +88,7 @@ describe('Tooltip', () => {
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
expect(wrapper.getDOMNode().tagName).toBe('SPAN');
|
||||
expect(wrapper.render()).toMatchSnapshot();
|
||||
const button = wrapper.find('span').at(0);
|
||||
button.simulate('mouseenter');
|
||||
expect(onVisibleChange).toBeCalledWith(true);
|
||||
@ -110,8 +110,8 @@ describe('Tooltip', () => {
|
||||
<Button disabled style={{ display: 'block' }}>Hello world!</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
expect(wrapper1.getDOMNode().style.display).toBe('inline-block');
|
||||
expect(wrapper2.getDOMNode().style.display).toBe('block');
|
||||
expect(wrapper1.find('span').first().getDOMNode().style.display).toBe('inline-block');
|
||||
expect(wrapper2.find('span').first().getDOMNode().style.display).toBe('block');
|
||||
});
|
||||
|
||||
it('should not wrap span when trigger is not hover', () => {
|
||||
@ -134,38 +134,42 @@ describe('Tooltip', () => {
|
||||
const horizontalArrowShift = 16;
|
||||
const triggerWidth = 200;
|
||||
|
||||
const wrapper = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
trigger="click"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
placement="bottomLeft"
|
||||
>
|
||||
<button style={{ width: triggerWidth }}>
|
||||
Hello world!
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
wrapper.find('button').at(0).simulate('click');
|
||||
const popupLeftDefault = parseInt(wrapper.instance().getPopupDomNode().style.left, 10);
|
||||
const suit = () => {
|
||||
const wrapper = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
trigger="click"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
placement="bottomLeft"
|
||||
>
|
||||
<button style={{ width: triggerWidth }}>
|
||||
Hello world!
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
wrapper.find('button').at(0).simulate('click');
|
||||
const popupLeftDefault = parseInt(wrapper.instance().getPopupDomNode().style.left, 10);
|
||||
|
||||
const wrapper2 = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
trigger="click"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
placement="bottomLeft"
|
||||
arrowPointAtCenter
|
||||
>
|
||||
<button style={{ width: triggerWidth }}>
|
||||
Hello world!
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
wrapper2.find('button').at(0).simulate('click');
|
||||
const popupLeftArrowPointAtCenter = parseInt(wrapper2.instance().getPopupDomNode().style.left, 10);
|
||||
expect(popupLeftArrowPointAtCenter - popupLeftDefault).toBe((triggerWidth / 2) - horizontalArrowShift - arrowWidth);
|
||||
const wrapper2 = mount(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
trigger="click"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
placement="bottomLeft"
|
||||
arrowPointAtCenter
|
||||
>
|
||||
<button style={{ width: triggerWidth }}>
|
||||
Hello world!
|
||||
</button>
|
||||
</Tooltip>
|
||||
);
|
||||
wrapper2.find('button').at(0).simulate('click');
|
||||
const popupLeftArrowPointAtCenter = parseInt(wrapper2.instance().getPopupDomNode().style.left, 10);
|
||||
expect(popupLeftArrowPointAtCenter - popupLeftDefault).toBe((triggerWidth / 2) - horizontalArrowShift - arrowWidth);
|
||||
};
|
||||
|
||||
jest.dontMock('rc-trigger', suit);
|
||||
});
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ A simple text popup tip.
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| title | The text shown in the tooltip | string\|React.Element | - |
|
||||
| title | The text shown in the tooltip | string\|ReactNode\|() => ReactNode | - |
|
||||
|
||||
### Common API
|
||||
|
||||
|
@ -33,9 +33,11 @@ export interface AbstractTooltipProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export type RenderFunction = () => React.ReactNode;
|
||||
|
||||
export interface TooltipProps extends AbstractTooltipProps {
|
||||
title?: React.ReactNode;
|
||||
overlay?: React.ReactNode;
|
||||
title?: React.ReactNode | RenderFunction;
|
||||
overlay?: React.ReactNode | RenderFunction;
|
||||
}
|
||||
|
||||
const splitObject = (obj, keys) => {
|
||||
|
@ -17,7 +17,7 @@ title: Tooltip
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| title | 提示文字 | React.ReactNode | 无 |
|
||||
| title | 提示文字 | string\|ReactNode\|() => ReactNode | 无 |
|
||||
|
||||
### 共同的 API
|
||||
|
||||
|
20
package.json
20
package.json
@ -50,30 +50,30 @@
|
||||
"omit.js": "^1.0.0",
|
||||
"prop-types": "^15.5.7",
|
||||
"rc-animate": "^2.4.1",
|
||||
"rc-calendar": "~9.1.0",
|
||||
"rc-cascader": "~0.11.3",
|
||||
"rc-calendar": "~9.2.0",
|
||||
"rc-cascader": "~0.12.0",
|
||||
"rc-checkbox": "~2.0.3",
|
||||
"rc-collapse": "~1.7.5",
|
||||
"rc-dialog": "~6.5.10",
|
||||
"rc-dropdown": "~1.5.0",
|
||||
"rc-dialog": "~7.0.0",
|
||||
"rc-dropdown": "~2.1.0",
|
||||
"rc-editor-mention": "^1.0.2",
|
||||
"rc-form": "~1.5.0",
|
||||
"rc-input-number": "~3.6.0",
|
||||
"rc-menu": "~5.1.0",
|
||||
"rc-menu": "~6.1.0",
|
||||
"rc-notification": "~3.0.0",
|
||||
"rc-pagination": "~1.12.4",
|
||||
"rc-progress": "~2.2.2",
|
||||
"rc-rate": "~2.1.1",
|
||||
"rc-select": "~6.9.0",
|
||||
"rc-slider": "~8.3.0",
|
||||
"rc-select": "~7.1.0",
|
||||
"rc-slider": "~8.4.0",
|
||||
"rc-steps": "~3.0.0",
|
||||
"rc-switch": "~1.5.1",
|
||||
"rc-table": "~5.6.9",
|
||||
"rc-tabs": "~9.1.2",
|
||||
"rc-time-picker": "~3.0.0",
|
||||
"rc-tooltip": "~3.4.6",
|
||||
"rc-time-picker": "~3.1.0",
|
||||
"rc-tooltip": "~3.7.0",
|
||||
"rc-tree": "~1.7.0",
|
||||
"rc-tree-select": "~1.10.2",
|
||||
"rc-tree-select": "~1.11.0",
|
||||
"rc-upload": "~2.4.0",
|
||||
"rc-util": "^4.0.4",
|
||||
"react-lazy-load": "^3.0.12",
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
&:target {
|
||||
border: 1px solid @primary-color;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&-expand-trigger {
|
||||
|
31
tests/__mocks__/rc-trigger.js
Normal file
31
tests/__mocks__/rc-trigger.js
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
|
||||
let Trigger; // eslint-disable-line
|
||||
|
||||
if (process.env.REACT === '15') {
|
||||
const ActualTrigger = require.requireActual('rc-trigger');
|
||||
const render = ActualTrigger.prototype.render;
|
||||
|
||||
ActualTrigger.prototype.render = function () {
|
||||
const { popupVisible } = this.state;
|
||||
let component;
|
||||
|
||||
if (popupVisible || this._component) { // eslint-disable-line
|
||||
component = this.getComponent();
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="TriggerContainer">
|
||||
{render.call(this)}
|
||||
{component}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Trigger = ActualTrigger;
|
||||
} else {
|
||||
const TriggerMock = require('rc-trigger/lib/mock'); // eslint-disable-line
|
||||
Trigger = TriggerMock;
|
||||
}
|
||||
|
||||
|
||||
export default Trigger;
|
19
tests/__mocks__/rc-util/lib/Portal.js
Normal file
19
tests/__mocks__/rc-util/lib/Portal.js
Normal file
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class Portal extends React.Component {
|
||||
componentDidMount() {
|
||||
this.createContainer();
|
||||
}
|
||||
|
||||
createContainer() {
|
||||
this.container = true;
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.container) {
|
||||
return this.props.children;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user