feat: update vc-menu to 7.4.19

pull/309/head
tangjinzhou 2018-11-05 21:03:25 +08:00
parent 2bf65a4828
commit 2cce6a5f55
11 changed files with 438 additions and 139 deletions

View File

@ -88,19 +88,19 @@ const getOptionProps = (instance) => {
return filterProps($props, $options.propsData)
}
const getComponentFromProp = (instance, prop) => {
const getComponentFromProp = (instance, prop, options) => {
if (instance.$createElement) {
const h = instance.$createElement
const temp = instance[prop]
if (temp !== undefined) {
return typeof temp === 'function' ? temp(h) : temp
return typeof temp === 'function' ? temp(h, options) : temp
}
return instance.$slots[prop]
return instance.$slots[prop] || (instance.$scopedSlots[prop] && instance.$scopedSlots[prop](options)) || undefined
} else {
const h = instance.context.$createElement
const temp = getPropsData(instance)[prop]
if (temp !== undefined) {
return typeof temp === 'function' ? temp(h) : temp
return typeof temp === 'function' ? temp(h, options) : temp
}
const slotsProp = []
const componentOptions = instance.componentOptions || {};

View File

@ -1,41 +1,304 @@
import PropTypes from '../_util/vue-types'
import ResizeObserver from 'resize-observer-polyfill'
import SubMenu from './SubMenu'
import BaseMixin from '../_util/BaseMixin'
import { getWidth, setStyle, menuAllProps } from './util'
import { cloneElement } from '../_util/vnode'
import { getClass, getPropsData, filterEmpty } from '../_util/props-util'
import omit from 'omit.js'
export default {
const canUseDOM = !!(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
)
const MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed'
// Fix ssr
if (canUseDOM) {
require('mutationobserver-shim')
}
const DOMWrap = {
name: 'DOMWrap',
props: {
visible: {
type: Boolean,
default: false,
},
tag: {
type: String,
default: 'div',
},
hiddenClassName: {
type: String,
default: '',
},
},
computed: {
class () {
const { visible, hiddenClassName } = this.$props
mixins: [BaseMixin],
data () {
this.resizeObserver = null
this.mutationObserver = null
// original scroll size of the list
this.originalTotalWidth = 0
// copy of overflowed items
this.overflowedItems = []
// cache item of the original items (so we can track the size and order)
this.menuItemSizes = []
return {
// [hiddenClassName]: !visible,
lastVisibleIndex: undefined,
}
},
mounted () {
this.$nextTick(() => {
this.setChildrenWidthAndResize()
if (this.level === 1 && this.mode === 'horizontal') {
const menuUl = this.$el
if (!menuUl) {
return
}
this.resizeObserver = new ResizeObserver(entries => {
entries.forEach(this.setChildrenWidthAndResize)
});
[].slice.call(menuUl.children).concat(menuUl).forEach(el => {
this.resizeObserver.observe(el)
})
if (typeof MutationObserver !== 'undefined') {
this.mutationObserver = new MutationObserver(() => {
this.resizeObserver.disconnect();
[].slice.call(menuUl.children).concat(menuUl).forEach(el => {
this.resizeObserver.observe(el)
})
this.setChildrenWidthAndResize()
})
this.mutationObserver.observe(
menuUl,
{ attributes: false, childList: true, subTree: false }
)
}
}
})
},
beforeDestroy () {
if (this.resizeObserver) {
this.resizeObserver.disconnect()
}
if (this.mutationObserver) {
this.resizeObserver.disconnect()
}
},
methods: {
// get all valid menuItem nodes
getMenuItemNodes () {
const { prefixCls } = this.$props
const ul = this.$el
if (!ul) {
return []
}
// filter out all overflowed indicator placeholder
return [].slice.call(ul.children)
.filter(node => {
return node.className.split(' ').indexOf(`${prefixCls}-overflowed-submenu`) < 0
})
},
getOverflowedSubMenuItem (keyPrefix, overflowedItems, renderPlaceholder) {
const { overflowedIndicator, level, mode, prefixCls, theme } = this.$props
if (level !== 1 || mode !== 'horizontal') {
return null
}
// put all the overflowed item inside a submenu
// with a title of overflow indicator ('...')
const copy = this.$slots.default[0]
const { title, eventKey, ...rest } = getPropsData(copy)
let style = {}
let key = `${keyPrefix}-overflowed-indicator`
if (overflowedItems.length === 0 && renderPlaceholder !== true) {
style = {
display: 'none',
}
} else if (renderPlaceholder) {
style = {
visibility: 'hidden',
// prevent from taking normal dom space
position: 'absolute',
}
key = `${key}-placeholder`
}
const popupClassName = theme ? `${prefixCls}-${theme}` : ''
const subMenuProps = {
props: {
title,
overflowedIndicator,
popupClassName,
eventKey: `${keyPrefix}-overflowed-indicator`,
disabled: false,
},
class: `${prefixCls}-overflowed-submenu`,
key,
style,
on: copy.$listeners,
}
menuAllProps.props.forEach(k => {
if (rest[k] !== undefined) {
subMenuProps.props[k] = rest[k]
}
})
return (
<SubMenu
{...subMenuProps}
>
{overflowedItems}
</SubMenu>
)
},
// memorize rendered menuSize
setChildrenWidthAndResize () {
if (this.mode !== 'horizontal') {
return
}
const ul = this.$el
if (!ul) {
return
}
const ulChildrenNodes = ul.children
if (!ulChildrenNodes || ulChildrenNodes.length === 0) {
return
}
const lastOverflowedIndicatorPlaceholder = ul.children[ulChildrenNodes.length - 1]
// need last overflowed indicator for calculating length;
setStyle(lastOverflowedIndicatorPlaceholder, 'display', 'inline-block')
const menuItemNodes = this.getMenuItemNodes()
// reset display attribute for all hidden elements caused by overflow to calculate updated width
// and then reset to original state after width calculation
const overflowedItems = menuItemNodes
.filter(c => c.className.split(' ').indexOf(MENUITEM_OVERFLOWED_CLASSNAME) >= 0)
overflowedItems.forEach(c => {
setStyle(c, 'display', 'inline-block')
})
this.menuItemSizes = menuItemNodes.map(c => getWidth(c))
overflowedItems.forEach(c => {
setStyle(c, 'display', 'none')
})
this.overflowedIndicatorWidth = getWidth(ul.children[ul.children.length - 1])
this.originalTotalWidth = this.menuItemSizes.reduce((acc, cur) => acc + cur, 0)
this.handleResize()
// prevent the overflowed indicator from taking space;
setStyle(lastOverflowedIndicatorPlaceholder, 'display', 'none')
},
handleResize () {
if (this.mode !== 'horizontal') {
return
}
const ul = this.$el
if (!ul) {
return
}
const width = getWidth(ul)
this.overflowedItems = []
let currentSumWidth = 0
// index for last visible child in horizontal mode
let lastVisibleIndex
if (this.originalTotalWidth > width) {
lastVisibleIndex = -1
this.menuItemSizes.forEach(liWidth => {
currentSumWidth += liWidth
if (currentSumWidth + this.overflowedIndicatorWidth <= width) {
lastVisibleIndex++
}
})
}
this.setState({ lastVisibleIndex })
},
renderChildren (children) {
// need to take care of overflowed items in horizontal mode
const { lastVisibleIndex } = this.$data
const className = getClass(this)
return (children || []).reduce((acc, childNode, index) => {
let item = childNode
const eventKey = getPropsData(childNode).eventKey
if (this.mode === 'horizontal') {
let overflowed = this.getOverflowedSubMenuItem(eventKey, [])
if (lastVisibleIndex !== undefined &&
className[`${this.prefixCls}-root`]
) {
if (index > lastVisibleIndex) {
item = cloneElement(
childNode,
// eventKey openkeys
{
style: { display: 'none' },
props: { eventKey: `${eventKey}-hidden` },
class: { ...getClass(childNode), [MENUITEM_OVERFLOWED_CLASSNAME]: true },
},
)
}
if (index === lastVisibleIndex + 1) {
this.overflowedItems = children.slice(lastVisibleIndex + 1).map(c => {
return cloneElement(
c,
// children[index].key will become '.$key' in clone by default,
// we have to overwrite with the correct key explicitly
{ key: getPropsData(c).eventKey, props: { mode: 'vertical-left' }},
)
})
overflowed = this.getOverflowedSubMenuItem(
eventKey,
this.overflowedItems,
)
}
}
const ret = [...acc, overflowed, item]
if (index === children.length - 1) {
// need a placeholder for calculating overflowed indicator width
ret.push(this.getOverflowedSubMenuItem(eventKey, [], true))
}
return ret
}
return [...acc, item]
}, [])
},
},
render () {
const otherProps = omit(this.$props, [
'tag',
'hiddenClassName',
'visible',
])
const Tag = this.$props.tag
const tagProps = {
attr: { ...otherProps, ...this.$attrs },
on: this.$listeners,
}
return <Tag {...tagProps} class={this.class}>{this.$slots.default}</Tag>
return <Tag {...tagProps}>{this.renderChildren(filterEmpty(this.$slots.default))}</Tag>
},
}
DOMWrap.props = {
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']),
prefixCls: PropTypes.string,
level: PropTypes.number,
theme: PropTypes.string,
overflowedIndicator: PropTypes.node,
visible: PropTypes.bool,
hiddenClassName: PropTypes.string,
tag: PropTypes.string.def('div'),
}
export default DOMWrap

View File

@ -2,7 +2,7 @@ import PropTypes from '../_util/vue-types'
import { Provider, create } from '../_util/store'
import { default as SubPopupMenu, getActiveKey } from './SubPopupMenu'
import BaseMixin from '../_util/BaseMixin'
import hasProp, { getOptionProps } from '../_util/props-util'
import hasProp, { getOptionProps, getComponentFromProp } from '../_util/props-util'
import commonPropsType from './commonPropsType'
const Menu = {
@ -33,47 +33,13 @@ const Menu = {
// this.isRootMenu = true // props
return {}
},
watch: {
selectedKeys (val) {
this.store.setState({
selectedKeys: val || [],
})
mounted () {
this.updateMiniStore()
},
openKeys (val) {
this.store.setState({
openKeys: val || [],
})
},
// '$props': {
// handler: function (nextProps) {
// if (hasProp(this, 'selectedKeys')) {
// this.setState({
// sSelectedKeys: nextProps.selectedKeys || [],
// })
// }
// if (hasProp(this, 'openKeys')) {
// this.setState({
// sOpenKeys: nextProps.openKeys || [],
// })
// }
// },
// deep: true,
// },
updated () {
this.updateMiniStore()
},
methods: {
// onDestroy (key) {
// const state = this.$data
// const sSelectedKeys = state.sSelectedKeys
// const sOpenKeys = state.sOpenKeys
// let index = sSelectedKeys.indexOf(key)
// if (!hasProp(this, 'selectedKeys') && index !== -1) {
// sSelectedKeys.splice(index, 1)
// }
// index = sOpenKeys.indexOf(key)
// if (!hasProp(this, 'openKeys') && index !== -1) {
// sOpenKeys.splice(index, 1)
// }
// },
onSelect (selectInfo) {
const props = this.$props
@ -170,35 +136,19 @@ const Menu = {
}
return transitionName
},
// isInlineMode () {
// return this.$props.mode === 'inline'
// },
// lastOpenSubMenu () {
// let lastOpen = []
// const { sOpenKeys } = this.$data
// if (sOpenKeys.length) {
// lastOpen = this.getFlatInstanceArray().filter((c) => {
// return c && sOpenKeys.indexOf(c.eventKey) !== -1
// })
// }
// return lastOpen[0]
// },
// renderMenuItem (c, i, subIndex) {
// if (!c) {
// return null
// }
// const state = this.$data
// const extraProps = {
// openKeys: state.sOpenKeys,
// selectedKeys: state.sSelectedKeys,
// triggerSubMenuAction: this.$props.triggerSubMenuAction,
// isRootMenu: this.isRootMenu,
// }
// return this.renderCommonMenuItem(c, i, subIndex, extraProps)
// },
updateMiniStore () {
const props = getOptionProps(this)
if ('selectedKeys' in props) {
this.store.setState({
selectedKeys: props.selectedKeys || [],
})
}
if ('openKeys' in props) {
this.store.setState({
openKeys: props.openKeys || [],
})
}
},
},
render () {
@ -206,6 +156,9 @@ const Menu = {
const subPopupMenuProps = {
props: {
...props,
itemIcon: getComponentFromProp(this, 'itemIcon', props),
expandIcon: getComponentFromProp(this, 'expandIcon', props),
overflowedIndicator: getComponentFromProp(this, 'overflowedIndicator', props),
openTransitionName: this.getOpenTransitionName(),
parentMenu: this,
children: this.$slots.default || [],

View File

@ -5,6 +5,7 @@ import BaseMixin from '../_util/BaseMixin'
import scrollIntoView from 'dom-scroll-into-view'
import { connect } from '../_util/store'
import { noop, menuAllProps } from './util'
import { getComponentFromProp } from '../_util/props-util'
const props = {
attribute: PropTypes.object,
@ -25,6 +26,7 @@ const props = {
manualRef: PropTypes.func.def(noop),
role: PropTypes.any,
subMenuKey: PropTypes.string,
itemIcon: PropTypes.any,
// clearSubMenuTimers: PropTypes.func.def(noop),
}
const MenuItem = {
@ -138,7 +140,7 @@ const MenuItem = {
let attrs = {
...props.attribute,
title: props.title,
role: 'menuitem',
role: props.role || 'menuitem',
'aria-disabled': props.disabled,
}
if (props.role === 'option') {
@ -148,10 +150,13 @@ const MenuItem = {
role: 'option',
'aria-selected': props.isSelected,
}
} else if (props.role === null) {
} else if (props.role === null || props.role === 'none') {
// sometimes we want to specify role inside <li/> element
// <li><a role='menuitem'>Link</a></li> would be a good example
delete attrs.role
// in this case the role on <li/> should be "none" to
// remove the implied listitem role.
// https://www.w3.org/TR/wai-aria-practices-1.1/examples/menubar/menubar-1/menubar-1.html
attrs.role = 'none'
}
// In case that onClick/onMouseLeave/onMouseEnter is passed down from owner
const mouseEvent = {
@ -184,6 +189,7 @@ const MenuItem = {
class={className}
>
{this.$slots.default}
{getComponentFromProp(this, 'itemIcon', props)}
</li>
)
},

View File

@ -66,6 +66,9 @@ const SubMenu = {
store: PropTypes.object,
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']).def('vertical'),
manualRef: PropTypes.func.def(noop),
builtinPlacements: PropTypes.object.def({}),
itemIcon: PropTypes.any,
expandIcon: PropTypes.any,
},
mixins: [BaseMixin],
isSubMenu: true,
@ -350,11 +353,14 @@ const SubMenu = {
subMenuCloseDelay: props.subMenuCloseDelay,
forceSubMenuRender: props.forceSubMenuRender,
triggerSubMenuAction: props.triggerSubMenuAction,
builtinPlacements: props.builtinPlacements,
defaultActiveFirst: props.store.getState()
.defaultActiveFirst[getMenuIdFromSubMenuEventKey(props.eventKey)],
multiple: props.multiple,
prefixCls: props.rootPrefixCls,
manualRef: this.saveMenuInstance,
itemIcon: getComponentFromProp(this, 'itemIcon'),
expandIcon: getComponentFromProp(this, 'expandIcon'),
children,
__propsSymbol__: Symbol(),
},
@ -475,10 +481,15 @@ const SubMenu = {
class: `${prefixCls}-title`,
ref: 'subMenuTitle',
}
// expand custom icon should NOT be displayed in menu with horizontal mode.
let icon = null
if (props.mode !== 'horizontal') {
icon = getComponentFromProp(this, 'expandIcon', props)
}
const title = (
<div {...titleProps}>
{getComponentFromProp(this, 'title')}
<i class={`${prefixCls}-arrow`} />
{icon || <i class={`${prefixCls}-arrow`} />}
</div>
)
const children = this.renderChildren(this.$slots.default)
@ -503,6 +514,7 @@ const SubMenu = {
popupClassName={`${prefixCls}-popup ${rootPrefixCls}-${parentMenu.theme} ${popupClassName || ''}`}
getPopupContainer={getPopupContainer}
builtinPlacements={placements}
builtinPlacements={Object.assign({}, placements, props.builtinPlacements)}
popupPlacement={popupPlacement}
popupVisible={isOpen}
popupAlign={popupAlign}

View File

@ -7,7 +7,7 @@ import classNames from 'classnames'
import { getKeyFromChildrenIndex, loopMenuItem, noop } from './util'
import DOMWrap from './DOMWrap'
import { cloneElement } from '../_util/vnode'
import { initDefaultProps, getOptionProps, getEvents } from '../_util/props-util'
import { initDefaultProps, getOptionProps, getPropsData, getEvents, getComponentFromProp } from '../_util/props-util'
function allDisabled (arr) {
if (!arr.length) {
@ -28,6 +28,11 @@ function updateActiveKey (store, menuId, activeKey) {
})
}
function getEventKey (props) {
// when eventKey not available ,it's menu and return menu id '0-menu-'
return props.eventKey || '0-menu-'
}
export function saveRef (key, c) {
if (c) {
const index = this.instanceArrayKeyIndexMap[key]
@ -100,6 +105,8 @@ const SubPopupMenu = {
triggerSubMenuAction: PropTypes.oneOf(['click', 'hover']),
inlineIndent: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
manualRef: PropTypes.func,
itemIcon: PropTypes.any,
expandIcon: PropTypes.any,
children: PropTypes.any.def([]),
__propsSymbol__: PropTypes.any, // mock componentWillReceiveProps
}, {
@ -129,18 +136,27 @@ const SubPopupMenu = {
this.manualRef(this)
}
},
watch: {
__propsSymbol__ () {
updated () {
const props = getOptionProps(this)
const storeActiveKey = this.getStore().getState().activeKey[this.getEventKey()]
const originalActiveKey = 'activeKey' in props ? props.activeKey
: storeActiveKey
: props.store.getState().activeKey[getEventKey(props)]
const activeKey = getActiveKey(props, originalActiveKey)
if (activeKey !== originalActiveKey || storeActiveKey !== activeKey) {
updateActiveKey(this.getStore(), this.getEventKey(), activeKey)
if (activeKey !== originalActiveKey) {
updateActiveKey(props.store, getEventKey(props), activeKey)
}
},
},
// watch: {
// __propsSymbol__ () {
// const props = getOptionProps(this)
// const storeActiveKey = this.getStore().getState().activeKey[this.getEventKey()]
// const originalActiveKey = 'activeKey' in props ? props.activeKey
// : storeActiveKey
// const activeKey = getActiveKey(props, originalActiveKey)
// if (activeKey !== originalActiveKey || storeActiveKey !== activeKey) {
// updateActiveKey(this.getStore(), this.getEventKey(), activeKey)
// }
// },
// },
methods: {
// all keyboard events callbacks run from here at first
onKeyDown (e, callback) {
@ -160,7 +176,7 @@ const SubPopupMenu = {
}
if (activeItem) {
e.preventDefault()
updateActiveKey(this.getStore(), this.getEventKey(), activeItem.eventKey)
updateActiveKey(this.$props.store, getEventKey(this.$props), activeItem.eventKey)
if (typeof callback === 'function') {
callback(activeItem)
@ -172,7 +188,7 @@ const SubPopupMenu = {
onItemHover (e) {
const { key, hover } = e
updateActiveKey(this.getStore(), this.getEventKey(), hover ? key : null)
updateActiveKey(this.$props.store, getEventKey(this.$props), hover ? key : null)
},
onDeselect (selectInfo) {
@ -199,22 +215,13 @@ const SubPopupMenu = {
return this.instanceArray
},
getStore () {
return this.store
},
getEventKey () {
// when eventKey not available ,it's menu and return menu id '0-menu-'
return this.eventKey !== undefined ? this.eventKey : '0-menu-'
},
getOpenTransitionName () {
return this.$props.openTransitionName
},
step (direction) {
let children = this.getFlatInstanceArray()
const activeKey = this.getStore().getState().activeKey[this.getEventKey()]
const activeKey = this.$props.store.getState().activeKey[this.getEventKey(this.$props)]
const len = children.length
if (!len) {
return null
@ -251,14 +258,39 @@ const SubPopupMenu = {
return null
},
getIcon (instance, name) {
if (instance.$createElement) {
const temp = instance[name]
if (temp !== undefined) {
return temp
}
return instance.$slots[name] || instance.$scopedSlots[name]
} else {
const temp = getPropsData(instance)[name]
if (temp !== undefined) {
return temp
}
const slotsProp = []
const componentOptions = instance.componentOptions || {};
(componentOptions.children || []).forEach((child) => {
if (child.data && child.data.slot === name) {
if (child.tag === 'template') {
slotsProp.push(child.children)
} else {
slotsProp.push(child)
}
}
})
return slotsProp.length ? slotsProp : undefined
}
},
renderCommonMenuItem (child, i, extraProps) {
if (child.tag === undefined) { return child }
const state = this.getStore().getState()
const state = this.$props.store.getState()
const props = this.$props
const key = getKeyFromChildrenIndex(child, props.eventKey, i)
const childProps = child.componentOptions.propsData || {}
const isActive = key === state.activeKey[this.getEventKey()]
const isActive = key === state.activeKey
if (!childProps.disabled) {
// manualRef使keyrefthis.instanceArray
this.instanceArrayKeyIndexMap[key] = Object.keys(this.instanceArrayKeyIndexMap).length
@ -266,7 +298,7 @@ const SubPopupMenu = {
const childListeners = getEvents(child)
const newChildProps = {
props: {
mode: props.mode,
mode: childProps.mode || props.mode,
level: props.level,
inlineIndent: props.inlineIndent,
renderMenuItem: this.renderMenuItem,
@ -283,6 +315,9 @@ const SubPopupMenu = {
subMenuOpenDelay: props.subMenuOpenDelay,
subMenuCloseDelay: props.subMenuCloseDelay,
forceSubMenuRender: props.forceSubMenuRender,
builtinPlacements: props.builtinPlacements,
itemIcon: this.getIcon(child, 'itemIcon') || this.getIcon(this, 'itemIcon'),
expandIcon: this.getIcon(child, 'expandIcon') || this.getIcon(this, 'expandIcon'),
...extraProps,
},
on: {
@ -307,7 +342,7 @@ const SubPopupMenu = {
if (!c) {
return null
}
const state = this.getStore().getState()
const state = this.$props.store.getState()
const extraProps = {
openKeys: state.openKeys,
selectedKeys: state.selectedKeys,
@ -320,7 +355,7 @@ const SubPopupMenu = {
},
render () {
const { ...props } = this.$props
const { eventKey, visible } = props
const { eventKey, visible, level, mode, theme } = props
this.instanceArray = []
this.instanceArrayKeyIndexMap = {}
const className = classNames(
@ -332,6 +367,8 @@ const SubPopupMenu = {
tag: 'ul',
// hiddenClassName: `${prefixCls}-hidden`,
visible,
level, mode, theme,
overflowedIndicator: getComponentFromProp(this, 'overflowedIndicator'),
},
attrs: {
role: props.role || 'menu',

View File

@ -2,8 +2,8 @@
@font-face {
font-family: 'FontAwesome';
src: url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?v=4.2.0');
src: url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('https://cdn.bootcss.com/font-awesome/4.2.0/fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
src: url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/fonts/fontawesome-webfont.eot');
src: url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/fonts/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/fonts/fontawesome-webfont.woff') format('woff'), url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/fonts/fontawesome-webfont.ttf') format('truetype'), url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/fonts/fontawesome-webfont.svg?#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
@ -92,6 +92,10 @@
&-submenu {
&-popup {
position: absolute;
.submenu-title-wrapper {
padding-right: 20px;
}
}
> .@{menuPrefixCls} {
background-color: #fff;
@ -110,17 +114,19 @@
&-horizontal {
background-color: #F3F5F7;
border: none;
border-bottom: 1px solid transparent;
border-bottom: 1px solid #d9d9d9;
box-shadow: none;
white-space: nowrap;
overflow: hidden;
& > .@{menuPrefixCls}-item, & > .@{menuPrefixCls}-submenu > .@{menuPrefixCls}-submenu-title {
padding: 15px 20px;
}
& > .@{menuPrefixCls}-submenu, & > .@{menuPrefixCls}-item {
float: left;
border-bottom: 2px solid transparent;
display: inline-block;
vertical-align: bottom;
&-active {
border-bottom: 2px solid #2db7f5;

View File

@ -23,4 +23,8 @@ export default {
forceSubMenuRender: PropTypes.bool,
selectable: PropTypes.bool,
isRootMenu: PropTypes.bool.def(true),
builtinPlacements: PropTypes.object.def({}),
itemIcon: PropTypes.any,
expandIcon: PropTypes.any,
overflowedIndicator: PropTypes.any,
}

View File

@ -1,4 +1,4 @@
// based on rc-menu 7.0.5
// based on rc-menu 7.4.19
import Menu from './Menu'
import SubMenu from './SubMenu'
import MenuItem, { menuItemProps } from './MenuItem'

View File

@ -77,6 +77,7 @@ export const menuAllProps = {
'rootPrefixCls',
'eventKey',
'active',
'popupAlign',
'popupOffset',
'isOpen',
'renderMenuItem',
@ -87,6 +88,8 @@ export const menuAllProps = {
'isSelected',
'store',
'activeKey',
'builtinPlacements',
'overflowedIndicator',
// the following keys found need to be removed from test regression
'attribute',
@ -95,6 +98,8 @@ export const menuAllProps = {
'inlineCollapsed',
'menu',
'theme',
'itemIcon',
'expandIcon',
],
on: [
'select',
@ -107,3 +112,15 @@ export const menuAllProps = {
'titleClick',
],
}
export const getWidth = (elem) => (
elem &&
typeof elem.getBoundingClientRect === 'function' &&
elem.getBoundingClientRect().width
) || 0
export const setStyle = (elem, styleProperty, value) => {
if (elem && typeof elem.style === 'object') {
elem.style[styleProperty] = value
}
}

View File

@ -172,6 +172,7 @@
"json2mq": "^0.2.0",
"lodash": "^4.17.5",
"moment": "^2.21.0",
"mutationobserver-shim": "^0.3.2",
"omit.js": "^1.0.0",
"raf": "^3.4.0",
"resize-observer-polyfill": "^1.5.0",