From d4fd34811453e3c2a805cb86e22a924366a5dde6 Mon Sep 17 00:00:00 2001 From: Wei Zhu Date: Thu, 15 Jun 2017 16:36:09 +0800 Subject: [PATCH 01/17] Uprgade rc-table --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9174e5e350..b34e17449a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "rc-slider": "~8.1.2", "rc-steps": "~2.5.1", "rc-switch": "~1.5.1", - "rc-table": "~5.3.3", + "rc-table": "~5.4.0", "rc-tabs": "~8.0.0", "rc-time-picker": "~2.4.1", "rc-tooltip": "~3.4.6", From 51f84e82e280282e034956ea9666ce5a9e74910c Mon Sep 17 00:00:00 2001 From: Wei Zhu Date: Thu, 15 Jun 2017 16:45:46 +0800 Subject: [PATCH 02/17] 2.12.0-beta1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b34e17449a..7a8a72ba30 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd", - "version": "2.11.0", + "version": "2.12.0-beta1", "title": "Ant Design", "description": "An enterprise-class UI design language and React-based implementation", "homepage": "http://ant.design/", From a4a26797ec650f587b20cf0bd99581f9ba23c8a4 Mon Sep 17 00:00:00 2001 From: Benjy Cui Date: Wed, 28 Jun 2017 16:02:38 +0800 Subject: [PATCH 03/17] fix: mention should support `.focus`, close: #6135 --- components/badge/ScrollNumber.tsx | 2 +- components/mention/demo/controllder-simple.md | 4 ++++ components/mention/index.en-US.md | 6 ++++++ components/mention/index.tsx | 8 ++++++++ components/mention/index.zh-CN.md | 6 ++++++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/components/badge/ScrollNumber.tsx b/components/badge/ScrollNumber.tsx index 5664cb2970..b5a8eb5bc8 100644 --- a/components/badge/ScrollNumber.tsx +++ b/components/badge/ScrollNumber.tsx @@ -135,7 +135,7 @@ export default class ScrollNumber extends Component { props.style.boxShadow = `0 0 0 1px ${props.style.borderColor} inset`; } return createElement( - this.props.component || 'sup', + (this.props.component || 'sup') as any, props, this.renderNumberElement(), ); diff --git a/components/mention/demo/controllder-simple.md b/components/mention/demo/controllder-simple.md index 4cf0c1b997..3d27563ba0 100644 --- a/components/mention/demo/controllder-simple.md +++ b/components/mention/demo/controllder-simple.md @@ -21,6 +21,9 @@ class App extends React.Component { state = { value: toContentState('@afc163'), } + componentDidMount() { + this.mention.focus(); + } handleChange = (editorState) => { this.setState({ value: editorState, @@ -29,6 +32,7 @@ class App extends React.Component { render() { return ( this.mention = ele} suggestions={['afc163', 'benjycui', 'yiminghe', 'RaoHai', '中文', 'にほんご']} value={this.state.value} onChange={this.handleChange} diff --git a/components/mention/index.en-US.md b/components/mention/index.en-US.md index 47c9544357..e5bb9914f6 100644 --- a/components/mention/index.en-US.md +++ b/components/mention/index.en-US.md @@ -51,6 +51,12 @@ When need to mention someone or something. | readOnly | Tell if the input is readonly. | boolean | false | | disabled | Tell if the input is disabled. | boolean | false | +### Mention methods + +| Property | Description | Type | Default | +|----------|---------------|----------|--------------| +| focus | Force focus back onto the editor node. | - | - | + ### Nav | Property | Description | Type | Default | diff --git a/components/mention/index.tsx b/components/mention/index.tsx index ce56231edd..cdbd98bbe9 100644 --- a/components/mention/index.tsx +++ b/components/mention/index.tsx @@ -46,6 +46,7 @@ export default class Mention extends React.Component console.warn('Mention.toEditorState is deprecated. Use toContentState instead.'); return toEditorState(text); } + private mentionEle: any; constructor(props) { super(props); this.state = { @@ -102,6 +103,12 @@ export default class Mention extends React.Component this.props.onBlur(ev); } } + focus = () => { + this.mentionEle._editor.focus(); + } + mentionRef = ele => { + this.mentionEle = ele; + } render() { const { className = '', prefixCls, loading } = this.props; const { suggestions, focus } = this.state; @@ -117,6 +124,7 @@ export default class Mention extends React.Component Date: Fri, 30 Jun 2017 17:22:01 +0800 Subject: [PATCH 04/17] feat: support `autoAdjustOverflow` prop (#6661) --- .../tooltip/demo/auto-adjust-overflow.md | 44 +++++++++++++ components/tooltip/index.en-US.md | 1 + components/tooltip/index.tsx | 7 +- components/tooltip/index.zh-CN.md | 1 + components/tooltip/placements.tsx | 65 ++++++++++--------- 5 files changed, 85 insertions(+), 33 deletions(-) create mode 100644 components/tooltip/demo/auto-adjust-overflow.md diff --git a/components/tooltip/demo/auto-adjust-overflow.md b/components/tooltip/demo/auto-adjust-overflow.md new file mode 100644 index 0000000000..776d5d46c5 --- /dev/null +++ b/components/tooltip/demo/auto-adjust-overflow.md @@ -0,0 +1,44 @@ +--- +order: 3 +title: + zh-CN: 自动调整位置 + en-US: Adjust placement automatically +--- + +## zh-CN + +气泡框不可见时自动调整位置 + +## en-US + +Adjust popup placement automatically when popup is invisible + +````jsx +import { Tooltip, Button } from 'antd'; + +const wrapStyles = { + overflow: 'hidden', + position: 'relative', + padding: '24px', + border: '1px solid #e9e9e9', +}; + +ReactDOM.render( +
+ trigger.parentElement}> + + +
+ trigger.parentElement} autoAdjustOverflow={false}> + + +
+, mountNode); +```` + + diff --git a/components/tooltip/index.en-US.md b/components/tooltip/index.en-US.md index 2399c4637b..1448af6846 100644 --- a/components/tooltip/index.en-US.md +++ b/components/tooltip/index.en-US.md @@ -26,6 +26,7 @@ The following APIs are shared by Tooltip, Popconfirm, Popover. | placement | to set the position, which can be one of `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom` | string | top | | getPopupContainer | to set the container of the tip, while the default is to create a `div` element in `body`. Use `getTooltipContainer` if you are using `antd@<2.5.2` | Function(triggerNode) | () => document.body | | arrowPointAtCenter | whether arrow pointed at the center of target, supported after `antd@1.11+` | boolean | `false` | +| autoAdjustOverflow | whether adjust popup placement automatically when popup is invisible | boolean | `true` | | visible | make the float card visible or not | boolean | false | | onVisibleChange | callback of the visible attribute changed | (visible) => void | none | | mouseEnterDelay | delay time to show when mouse enter.unit: s | number | 0 | diff --git a/components/tooltip/index.tsx b/components/tooltip/index.tsx index 80312cf934..672a360e6c 100644 --- a/components/tooltip/index.tsx +++ b/components/tooltip/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { cloneElement } from 'react'; import RcTooltip from 'rc-tooltip'; import classNames from 'classnames'; -import getPlacements from './placements'; +import getPlacements, { AdjustOverflow } from './placements'; export type TooltipPlacement = 'top' | 'left' | 'right' | 'bottom' | @@ -24,6 +24,7 @@ export interface AbstractTooltipProps { trigger?: 'hover' | 'focus' | 'click'; openClassName?: string; arrowPointAtCenter?: boolean; + autoAdjustOverflow?: boolean | AdjustOverflow; // getTooltipContainer had been rename to getPopupContainer getTooltipContainer?: (triggerNode: Element) => HTMLElement; getPopupContainer?: (triggerNode: Element) => HTMLElement; @@ -55,6 +56,7 @@ export default class Tooltip extends React.Component { mouseEnterDelay: 0.1, mouseLeaveDelay: 0.1, arrowPointAtCenter: false, + autoAdjustOverflow: true, }; refs: { @@ -90,10 +92,11 @@ export default class Tooltip extends React.Component { } getPlacements() { - const { builtinPlacements, arrowPointAtCenter } = this.props; + const { builtinPlacements, arrowPointAtCenter, autoAdjustOverflow } = this.props; return builtinPlacements || getPlacements({ arrowPointAtCenter, verticalArrowShift: 8, + autoAdjustOverflow, }); } diff --git a/components/tooltip/index.zh-CN.md b/components/tooltip/index.zh-CN.md index 29a2f2f067..6d73c095fe 100644 --- a/components/tooltip/index.zh-CN.md +++ b/components/tooltip/index.zh-CN.md @@ -28,6 +28,7 @@ title: Tooltip | placement | 气泡框位置,可选 `top` `left` `right` `bottom` `topLeft` `topRight` `bottomLeft` `bottomRight` `leftTop` `leftBottom` `rightTop` `rightBottom` | string | top | | getPopupContainer | 浮层渲染父节点,默认渲染到 body 上。`2.5.2` 之前请使用 `getTooltipContainer` | Function(triggerNode) | () => document.body | | arrowPointAtCenter | 箭头是否指向目标元素中心,`antd@1.11+` 支持 | boolean | `false` | +| autoAdjustOverflow | 气泡被遮挡时自动调整位置 | boolean | `true` | | visible | 用于手动控制浮层显隐 | boolean | false | | onVisibleChange | 显示隐藏的回调 | (visible) => void | 无 | | mouseEnterDelay | 鼠标移入后延时多少才显示 Tooltip,单位:秒 | number | 0 | diff --git a/components/tooltip/placements.tsx b/components/tooltip/placements.tsx index 543283d9f3..ccf2a95633 100644 --- a/components/tooltip/placements.tsx +++ b/components/tooltip/placements.tsx @@ -1,96 +1,99 @@ -import { placements } from 'rc-tooltip/lib/placements'; +import { placements as rcPlacements } from 'rc-tooltip/lib/placements'; -const autoAdjustOverflow = { +const autoAdjustOverflowEnabled = { adjustX: 1, adjustY: 1, }; +const autoAdjustOverflowDisabled = { + adjustX: 0, + adjustY: 0, +}; + const targetOffset = [0, 0]; +export interface AdjustOverflow { + adjustX?: 0 | 1; + adjustY?: 0 | 1; +} + export interface PlacementsConfig { arrowWidth?: number; horizontalArrowShift?: number; verticalArrowShift?: number; arrowPointAtCenter?: boolean; + autoAdjustOverflow?: any; +} + +export function getOverflowOptions(autoAdjustOverflow: any) { + if (typeof autoAdjustOverflow === 'boolean') { + return autoAdjustOverflow ? autoAdjustOverflowEnabled : autoAdjustOverflowDisabled; + } + return { + ...autoAdjustOverflowDisabled, + ...autoAdjustOverflow, + }; } export default function getPlacements(config: PlacementsConfig = {}) { - if (!config.arrowPointAtCenter) { - return placements; - } - const { arrowWidth = 5, horizontalArrowShift = 16, verticalArrowShift = 12 } = config; - return { + const { arrowWidth = 5, horizontalArrowShift = 16, verticalArrowShift = 12, autoAdjustOverflow = true } = config; + const placementMap = { left: { points: ['cr', 'cl'], - overflow: autoAdjustOverflow, offset: [-4, 0], - targetOffset, }, right: { points: ['cl', 'cr'], - overflow: autoAdjustOverflow, offset: [4, 0], - targetOffset, }, top: { points: ['bc', 'tc'], - overflow: autoAdjustOverflow, offset: [0, -4], - targetOffset, }, bottom: { points: ['tc', 'bc'], - overflow: autoAdjustOverflow, offset: [0, 4], - targetOffset, }, topLeft: { points: ['bl', 'tc'], - overflow: autoAdjustOverflow, offset: [-(horizontalArrowShift + arrowWidth), -4], - targetOffset, }, leftTop: { points: ['tr', 'cl'], - overflow: autoAdjustOverflow, offset: [-4, -(verticalArrowShift + arrowWidth)], - targetOffset, }, topRight: { points: ['br', 'tc'], - overflow: autoAdjustOverflow, offset: [horizontalArrowShift + arrowWidth, -4], - targetOffset, }, rightTop: { points: ['tl', 'cr'], - overflow: autoAdjustOverflow, offset: [4, -(verticalArrowShift + arrowWidth)], - targetOffset, }, bottomRight: { points: ['tr', 'bc'], - overflow: autoAdjustOverflow, offset: [horizontalArrowShift + arrowWidth, 4], - targetOffset, }, rightBottom: { points: ['bl', 'cr'], - overflow: autoAdjustOverflow, offset: [4, verticalArrowShift + arrowWidth], - targetOffset, }, bottomLeft: { points: ['tl', 'bc'], - overflow: autoAdjustOverflow, offset: [-(horizontalArrowShift + arrowWidth), 4], - targetOffset, }, leftBottom: { points: ['br', 'cl'], - overflow: autoAdjustOverflow, offset: [-4, verticalArrowShift + arrowWidth], - targetOffset, }, }; + Object.keys(placementMap).forEach(key => { + placementMap[key] = { + ...placementMap[key], + overflow: getOverflowOptions(autoAdjustOverflow), + offset: (config.arrowPointAtCenter ? rcPlacements[key] : placementMap[key]).offset, + targetOffset, + }; + }); + return placementMap; } From 63daf8d0a3387fee3e3c1d730f98c35146483da7 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 18:08:30 +0800 Subject: [PATCH 05/17] Add Menu[inlineCollapsed] prop --- components/menu/demo/inline-collapsed.md | 75 ++++++++++++++++++++ components/menu/demo/{sider.md => inline.md} | 2 +- components/menu/index.tsx | 74 ++++++++++++------- components/menu/style/index.less | 30 ++++++++ 4 files changed, 156 insertions(+), 25 deletions(-) create mode 100644 components/menu/demo/inline-collapsed.md rename components/menu/demo/{sider.md => inline.md} (97%) diff --git a/components/menu/demo/inline-collapsed.md b/components/menu/demo/inline-collapsed.md new file mode 100644 index 0000000000..b3fa954104 --- /dev/null +++ b/components/menu/demo/inline-collapsed.md @@ -0,0 +1,75 @@ +--- +order: 2 +title: + zh-CN: 缩起内嵌菜单 + en-US: Collapsed inline menu +--- + +## zh-CN + +内嵌菜单可以被缩起/展开。 + +## en-US + +Inline menu could be collapsed. + +````jsx +import { Menu, Icon, Button } from 'antd'; +const SubMenu = Menu.SubMenu; + +class App extends React.Component { + state = { + collapsed: false, + } + toggleCollapsed = () => { + this.setState({ + collapsed: !this.state.collapsed, + }); + } + render() { + return ( +
+ + + + + Option 1 + + + + Option 2 + + + + Option 3 + + Navigation One}> + Option 5 + Option 6 + Option 7 + Option 8 + + Navigation Two}> + Option 9 + Option 10 + + Option 11 + Option 12 + + + +
+ ); + } +} + +ReactDOM.render(, mountNode); +```` diff --git a/components/menu/demo/sider.md b/components/menu/demo/inline.md similarity index 97% rename from components/menu/demo/sider.md rename to components/menu/demo/inline.md index 7294441fff..d66ad98f5f 100755 --- a/components/menu/demo/sider.md +++ b/components/menu/demo/inline.md @@ -2,7 +2,7 @@ order: 1 title: zh-CN: 内嵌菜单 - en-US: Vertical menu with inline children + en-US: Inline menu --- ## zh-CN diff --git a/components/menu/index.tsx b/components/menu/index.tsx index c3c7c0c47b..63722f84a6 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -1,5 +1,6 @@ import React from 'react'; import RcMenu, { Item, Divider, SubMenu, ItemGroup } from 'rc-menu'; +import classNames from 'classnames'; import animation from '../_util/openAnimation'; import warning from '../_util/warning'; @@ -39,6 +40,7 @@ export interface MenuProps { prefixCls?: string; multiple?: boolean; inlineIndent?: number; + inlineCollapsed?: boolean; } export default class Menu extends React.Component { @@ -52,6 +54,7 @@ export default class Menu extends React.Component { theme: 'light', // or dark }; switchModeFromInline: boolean; + inlineOpenKeys = []; constructor(props) { super(props); @@ -77,6 +80,15 @@ export default class Menu extends React.Component { nextProps.mode !== 'inline') { this.switchModeFromInline = true; } + if (nextProps.inlineCollapsed && !this.props.inlineCollapsed) { + this.switchModeFromInline = true; + this.inlineOpenKeys = this.state.openKeys; + this.setState({ openKeys: [] }); + } + if (!nextProps.inlineCollapsed && this.props.inlineCollapsed) { + this.setState({ openKeys: this.inlineOpenKeys }); + this.inlineOpenKeys = []; + } if ('openKeys' in nextProps) { this.setState({ openKeys: nextProps.openKeys }); } @@ -102,48 +114,62 @@ export default class Menu extends React.Component { this.setState({ openKeys }); } } - render() { - let openAnimation = this.props.openAnimation || this.props.openTransitionName; - if (this.props.openAnimation === undefined && this.props.openTransitionName === undefined) { - switch (this.props.mode) { + getRealMenuMode() { + const { mode, inlineCollapsed } = this.props; + return inlineCollapsed ? 'vertical' : mode; + } + getMenuOpenAnimation() { + const { openAnimation, openTransitionName } = this.props; + const menuMode = this.getRealMenuMode(); + let menuOpenAnimation = openAnimation || openTransitionName; + if (openAnimation === undefined && openTransitionName === undefined) { + switch (menuMode) { case 'horizontal': - openAnimation = 'slide-up'; + menuOpenAnimation = 'slide-up'; break; case 'vertical': // When mode switch from inline // submenu should hide without animation if (this.switchModeFromInline) { - openAnimation = ''; + menuOpenAnimation = ''; this.switchModeFromInline = false; } else { - openAnimation = 'zoom-big'; + menuOpenAnimation = 'zoom-big'; } break; case 'inline': - openAnimation = animation; + menuOpenAnimation = animation; break; default: } } + return menuOpenAnimation; + } + render() { + const { inlineCollapsed, prefixCls, className, theme } = this.props; + const menuMode = this.getRealMenuMode(); + const menuOpenAnimation = this.getMenuOpenAnimation(); - let props = {}; - const className = `${this.props.className} ${this.props.prefixCls}-${this.props.theme}`; - if (this.props.mode !== 'inline') { - // There is this.state.openKeys for + const menuClassName = classNames(className, `${prefixCls}-${theme}`, { + [`${prefixCls}-inline-collapsed`]: inlineCollapsed, + }); + + const menuProps: MenuProps = { + openKeys: this.state.openKeys, + onClick: this.handleClick, + onOpenChange: this.handleOpenChange, + className: menuClassName, + mode: menuMode, + }; + + if (menuMode !== 'inline') { // closing vertical popup submenu after click it - props = { - openKeys: this.state.openKeys, - onClick: this.handleClick, - onOpenChange: this.handleOpenChange, - openTransitionName: openAnimation, - className, - }; + menuProps.onClick = this.handleClick; + menuProps.openTransitionName = menuOpenAnimation; } else { - props = { - openAnimation, - className, - }; + menuProps.openAnimation = menuOpenAnimation; } - return ; + + return ; } } diff --git a/components/menu/style/index.less b/components/menu/style/index.less index b9c6234006..63015524e8 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -158,6 +158,11 @@ } &-inline { + width: 100%; + &, + .@{iconfont-css-prefix} { + transition: all .1s; + } .@{menu-prefix-cls}-selected, .@{menu-prefix-cls}-item-selected { &:after { @@ -166,6 +171,31 @@ } } + &-inline-collapsed { + width: 64px; + > .@{menu-prefix-cls}-item, + > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { + text-align: center; + margin-left: 0; + left: 0; + &:after { + display: none; + } + } + .@{menu-prefix-cls}-item, + .@{menu-prefix-cls}-submenu-title { + padding: 0; + .@{iconfont-css-prefix} { + font-size: 16px; + line-height: 42px; + margin: 0; + + span { + display: none; + } + } + } + } + &-submenu-horizontal > & { top: 100%; left: 0; From 115749e06f958c5aee572f9e29f5b25036afa7cf Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 20:27:39 +0800 Subject: [PATCH 06/17] inline menu should not trigger handleClick --- components/menu/index.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 63722f84a6..81c37f08c0 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -64,6 +64,12 @@ export default class Menu extends React.Component { 'see: http://u.ant.design/menu-on-open-change.', ); + warning( + !('inlineCollapsed' in props && props.mode !== 'inline'), + '`onOpen` and `onClose` are removed, please use `onOpenChange` instead, ' + + 'see: http://u.ant.design/menu-on-open-change.', + ); + let openKeys; if ('defaultOpenKeys' in props) { openKeys = props.defaultOpenKeys; @@ -83,10 +89,10 @@ export default class Menu extends React.Component { if (nextProps.inlineCollapsed && !this.props.inlineCollapsed) { this.switchModeFromInline = true; this.inlineOpenKeys = this.state.openKeys; - this.setState({ openKeys: [] }); + this.setOpenKeys([]); } if (!nextProps.inlineCollapsed && this.props.inlineCollapsed) { - this.setState({ openKeys: this.inlineOpenKeys }); + this.setOpenKeys(this.inlineOpenKeys); this.inlineOpenKeys = []; } if ('openKeys' in nextProps) { @@ -156,7 +162,6 @@ export default class Menu extends React.Component { const menuProps: MenuProps = { openKeys: this.state.openKeys, - onClick: this.handleClick, onOpenChange: this.handleOpenChange, className: menuClassName, mode: menuMode, From 6e145bfad3d13df05e59ff26b4c481e61d4bebf2 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 21:07:01 +0800 Subject: [PATCH 07/17] Add tooltip for collapsed menu item --- components/menu/MenuItem.tsx | 22 ++++++++++++++++++++++ components/menu/index.tsx | 12 +++++++++++- components/menu/style/index.less | 24 ++++++++++++++++++------ components/menu/style/index.tsx | 3 +++ 4 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 components/menu/MenuItem.tsx diff --git a/components/menu/MenuItem.tsx b/components/menu/MenuItem.tsx new file mode 100644 index 0000000000..9d57ae8b16 --- /dev/null +++ b/components/menu/MenuItem.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Item } from 'rc-menu'; +import PropTypes from 'prop-types'; +import Tooltip from '../tooltip'; + +const MenuItem: any = (props, { inlineCollapsed }) => { + return ( + + + + ); +}; + +MenuItem.contextTypes = { + inlineCollapsed: PropTypes.bool, +}; + +export default MenuItem; diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 81c37f08c0..3a15e6761f 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -1,8 +1,10 @@ import React from 'react'; -import RcMenu, { Item, Divider, SubMenu, ItemGroup } from 'rc-menu'; +import RcMenu, { Divider, SubMenu, ItemGroup } from 'rc-menu'; +import PropTypes from 'prop-types'; import classNames from 'classnames'; import animation from '../_util/openAnimation'; import warning from '../_util/warning'; +import Item from './MenuItem'; export interface SelectParam { key: string; @@ -53,6 +55,9 @@ export default class Menu extends React.Component { className: '', theme: 'light', // or dark }; + static childContextTypes = { + inlineCollapsed: PropTypes.bool, + }; switchModeFromInline: boolean; inlineOpenKeys = []; constructor(props) { @@ -81,6 +86,11 @@ export default class Menu extends React.Component { openKeys: openKeys || [], }; } + getChildContext() { + return { + inlineCollapsed: this.props.inlineCollapsed, + }; + } componentWillReceiveProps(nextProps) { if (this.props.mode === 'inline' && nextProps.mode !== 'inline') { diff --git a/components/menu/style/index.less b/components/menu/style/index.less index 63015524e8..8cc678d938 100644 --- a/components/menu/style/index.less +++ b/components/menu/style/index.less @@ -159,10 +159,7 @@ &-inline { width: 100%; - &, - .@{iconfont-css-prefix} { - transition: all .1s; - } + transition: width .24s; .@{menu-prefix-cls}-selected, .@{menu-prefix-cls}-item-selected { &:after { @@ -173,10 +170,10 @@ &-inline-collapsed { width: 64px; + transition: all .3s; > .@{menu-prefix-cls}-item, > .@{menu-prefix-cls}-submenu > .@{menu-prefix-cls}-submenu-title { text-align: center; - margin-left: 0; left: 0; &:after { display: none; @@ -190,10 +187,16 @@ line-height: 42px; margin: 0; + span { - display: none; + max-width: 0; + visibility: hidden; } } } + &-tooltip { + .@{iconfont-css-prefix} { + display: none; + } + } } &-submenu-horizontal > & { @@ -229,6 +232,15 @@ .@{iconfont-css-prefix} { min-width: 14px; margin-right: 8px; + transition: all .3s; + vertical-align: middle; + + span { + max-width: 100%; + display: inline-block; + overflow: hidden; + transition: all .3s; + vertical-align: middle; + } } } diff --git a/components/menu/style/index.tsx b/components/menu/style/index.tsx index 3a3ab0de59..7bd39f61bf 100644 --- a/components/menu/style/index.tsx +++ b/components/menu/style/index.tsx @@ -1,2 +1,5 @@ import '../../style/index.less'; import './index.less'; + +// style dependencies +import '../../tooltip/style'; From 2eb3d55743e0cd6b449af557aaa9ca19692ac91d Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 21:09:34 +0800 Subject: [PATCH 08/17] Add documentation for inlineCollapsed --- components/menu/index.en-US.md | 1 + components/menu/index.zh-CN.md | 1 + 2 files changed, 2 insertions(+) diff --git a/components/menu/index.en-US.md b/components/menu/index.en-US.md index 69e60fb504..1e89bf0c00 100644 --- a/components/menu/index.en-US.md +++ b/components/menu/index.en-US.md @@ -42,6 +42,7 @@ More layout and samples: [layout](/docs/spec/layout). | style | style of the root node | object | | | inlineIndent | indent px of inline menu item on each level | number | 24 | | multiple | Allow select multiple item | boolean | false | +| inlineCollapsed | specified the collapsed status when menu is inline mode | boolean | - | > More options in [rc-menu](https://github.com/react-component/menu#api) diff --git a/components/menu/index.zh-CN.md b/components/menu/index.zh-CN.md index 002aa62f03..3947293fe4 100644 --- a/components/menu/index.zh-CN.md +++ b/components/menu/index.zh-CN.md @@ -42,6 +42,7 @@ subtitle: 导航菜单 | style | 根节点样式 | object | | | inlineIndent | inline 模式的菜单缩进宽度 | number | 24 | | multiple | 是否允许多选 | boolean | false | +| inlineCollapsed | inline 时菜单是否收起状态 | boolean | - | > More options in [rc-menu](https://github.com/react-component/menu#api) From 89a37da77f483fb06822e7f0a5597566477abbc0 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 21:36:23 +0800 Subject: [PATCH 09/17] Menu will get collapsed status from Layout.Sider --- components/layout/Sider.tsx | 11 +++++ components/layout/demo/custom-trigger.md | 14 ++----- components/layout/demo/side.md | 51 ++++++++++-------------- components/menu/index.tsx | 20 +++++++--- 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/components/layout/Sider.tsx b/components/layout/Sider.tsx index b08f5188fb..b81e6eb339 100644 --- a/components/layout/Sider.tsx +++ b/components/layout/Sider.tsx @@ -17,6 +17,7 @@ if (typeof window !== 'undefined') { import React from 'react'; import classNames from 'classnames'; import omit from 'omit.js'; +import PropTypes from 'prop-types'; import Icon from '../icon'; const dimensionMap = { @@ -55,6 +56,10 @@ export default class Sider extends React.Component { style: {}, }; + static childContextTypes = { + siderCollapsed: PropTypes.bool, + }; + private mql: any; constructor(props) { @@ -78,6 +83,12 @@ export default class Sider extends React.Component { }; } + getChildContext() { + return { + siderCollapsed: this.props.collapsed, + }; + } + componentWillReceiveProps(nextProps) { if ('collapsed' in nextProps) { this.setState({ diff --git a/components/layout/demo/custom-trigger.md b/components/layout/demo/custom-trigger.md index f30a6b3a49..e059ed7f31 100644 --- a/components/layout/demo/custom-trigger.md +++ b/components/layout/demo/custom-trigger.md @@ -38,15 +38,15 @@ class SiderDemo extends React.Component { - nav 1 + nav 1 - nav 2 + nav 2 - nav 3 + nav 3 @@ -89,12 +89,4 @@ ReactDOM.render(, mountNode); border-radius: 6px; margin: 16px; } - -#components-layout-demo-custom-trigger .ant-layout-sider-collapsed .anticon { - font-size: 16px; -} - -#components-layout-demo-custom-trigger .ant-layout-sider-collapsed .nav-text { - display: none; -} ```` diff --git a/components/layout/demo/side.md b/components/layout/demo/side.md index b57aa02871..b714531b08 100644 --- a/components/layout/demo/side.md +++ b/components/layout/demo/side.md @@ -27,14 +27,10 @@ const SubMenu = Menu.SubMenu; class SiderDemo extends React.Component { state = { collapsed: false, - mode: 'inline', }; onCollapse = (collapsed) => { console.log(collapsed); - this.setState({ - collapsed, - mode: collapsed ? 'vertical' : 'inline', - }); + this.setState({ collapsed }); } render() { return ( @@ -45,27 +41,33 @@ class SiderDemo extends React.Component { onCollapse={this.onCollapse} >
- + + + + Option 1 + + + + Option 2 + User} + title={User} > - Tom - Bill - Alex + Tom + Bill + Alex Team} + title={Team} > - Team 1 - Team 2 + Team 1 + Team 2 - - - - File - + + + File @@ -99,17 +101,4 @@ ReactDOM.render(, mountNode); border-radius: 6px; margin: 16px; } - -#components-layout-demo-side .ant-layout-sider-collapsed .anticon { - font-size: 16px; - margin-left: 8px; -} - -#components-layout-demo-side .ant-layout-sider-collapsed .nav-text { - display: none; -} - -#components-layout-demo-side .ant-layout-sider-collapsed .ant-menu-submenu-vertical > .ant-menu-submenu-title:after { - display: none; -} ```` diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 3a15e6761f..1e72c176fc 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -58,6 +58,9 @@ export default class Menu extends React.Component { static childContextTypes = { inlineCollapsed: PropTypes.bool, }; + static contextTypes = { + siderCollapsed: PropTypes.bool, + }; switchModeFromInline: boolean; inlineOpenKeys = []; constructor(props) { @@ -88,7 +91,7 @@ export default class Menu extends React.Component { } getChildContext() { return { - inlineCollapsed: this.props.inlineCollapsed, + inlineCollapsed: this.getInlineCollapsed(), }; } componentWillReceiveProps(nextProps) { @@ -131,8 +134,15 @@ export default class Menu extends React.Component { } } getRealMenuMode() { - const { mode, inlineCollapsed } = this.props; - return inlineCollapsed ? 'vertical' : mode; + const { mode } = this.props; + return this.getInlineCollapsed() ? 'vertical' : mode; + } + getInlineCollapsed() { + const { inlineCollapsed } = this.props; + if ('siderCollapsed' in this.context) { + return this.context.siderCollapsed; + } + return inlineCollapsed; } getMenuOpenAnimation() { const { openAnimation, openTransitionName } = this.props; @@ -162,12 +172,12 @@ export default class Menu extends React.Component { return menuOpenAnimation; } render() { - const { inlineCollapsed, prefixCls, className, theme } = this.props; + const { prefixCls, className, theme } = this.props; const menuMode = this.getRealMenuMode(); const menuOpenAnimation = this.getMenuOpenAnimation(); const menuClassName = classNames(className, `${prefixCls}-${theme}`, { - [`${prefixCls}-inline-collapsed`]: inlineCollapsed, + [`${prefixCls}-inline-collapsed`]: this.getInlineCollapsed(), }); const menuProps: MenuProps = { From 82afb368c0ca4cdbe2782d1fa19f7b20af5b8371 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 22:00:04 +0800 Subject: [PATCH 10/17] Fix context change logic --- components/menu/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 1e72c176fc..48fb373aef 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -94,17 +94,19 @@ export default class Menu extends React.Component { inlineCollapsed: this.getInlineCollapsed(), }; } - componentWillReceiveProps(nextProps) { + componentWillReceiveProps(nextProps, nextContext) { if (this.props.mode === 'inline' && nextProps.mode !== 'inline') { this.switchModeFromInline = true; } - if (nextProps.inlineCollapsed && !this.props.inlineCollapsed) { + if ((nextProps.inlineCollapsed && !this.props.inlineCollapsed) || + (nextContext.siderCollapsed && !this.context.siderCollapsed)) { this.switchModeFromInline = true; this.inlineOpenKeys = this.state.openKeys; this.setOpenKeys([]); } - if (!nextProps.inlineCollapsed && this.props.inlineCollapsed) { + if ((!nextProps.inlineCollapsed && this.props.inlineCollapsed) || + (!nextContext.siderCollapsed && this.context.siderCollapsed)) { this.setOpenKeys(this.inlineOpenKeys); this.inlineOpenKeys = []; } From 7d3bc4ebd431888ab71757f205f5d055e0813828 Mon Sep 17 00:00:00 2001 From: afc163 Date: Fri, 30 Jun 2017 22:02:19 +0800 Subject: [PATCH 11/17] update snapshots --- .../__tests__/__snapshots__/demo.test.js.snap | 86 ++++++---- .../__tests__/__snapshots__/demo.test.js.snap | 161 ++++++++++++++++-- 2 files changed, 200 insertions(+), 47 deletions(-) diff --git a/components/layout/__tests__/__snapshots__/demo.test.js.snap b/components/layout/__tests__/__snapshots__/demo.test.js.snap index 09746263f5..b2e4e75bf8 100644 --- a/components/layout/__tests__/__snapshots__/demo.test.js.snap +++ b/components/layout/__tests__/__snapshots__/demo.test.js.snap @@ -139,7 +139,7 @@ exports[`renders ./components/layout/demo/custom-trigger.md correctly 1`] = ` />
@@ -847,7 +859,7 @@ exports[`renders ./components/layout/demo/top.md correctly 1`] = ` />