feat: update menu
parent
c7b0cb0732
commit
b85bc0e738
|
@ -1,5 +1,5 @@
|
|||
module.exports = {
|
||||
dev: {
|
||||
componentName: 'list', // dev components
|
||||
componentName: 'menu', // dev components
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8,8 +8,9 @@ export default {
|
|||
props: itemProps,
|
||||
inject: {
|
||||
getInlineCollapsed: { default: () => noop },
|
||||
layoutSiderContext: { default: () => ({}) },
|
||||
},
|
||||
isMenuItem: 1,
|
||||
isMenuItem: true,
|
||||
methods: {
|
||||
onKeyDown(e) {
|
||||
this.$refs.menuItem.onKeyDown(e);
|
||||
|
@ -20,22 +21,28 @@ export default {
|
|||
const { level, title, rootPrefixCls } = props;
|
||||
const { getInlineCollapsed, $slots, $attrs: attrs } = this;
|
||||
const inlineCollapsed = getInlineCollapsed();
|
||||
let titleNode;
|
||||
if (inlineCollapsed) {
|
||||
titleNode = title || (level === 1 ? $slots.default : '');
|
||||
const tooltipProps = {
|
||||
title: title || (level === 1 ? $slots.default : ''),
|
||||
};
|
||||
const siderCollapsed = this.layoutSiderContext.sCollapsed;
|
||||
if (!siderCollapsed && !inlineCollapsed) {
|
||||
tooltipProps.title = null;
|
||||
// Reset `visible` to fix control mode tooltip display not correct
|
||||
// ref: https://github.com/ant-design/ant-design/issues/16742
|
||||
tooltipProps.visible = false;
|
||||
}
|
||||
|
||||
const itemProps = {
|
||||
props: {
|
||||
...props,
|
||||
title: inlineCollapsed ? null : title,
|
||||
title,
|
||||
},
|
||||
attrs,
|
||||
on: getListeners(this),
|
||||
};
|
||||
const toolTipProps = {
|
||||
props: {
|
||||
title: titleNode,
|
||||
...tooltipProps,
|
||||
placement: 'right',
|
||||
overlayClassName: `${rootPrefixCls}-inline-collapsed-tooltip`,
|
||||
},
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { SubMenu as VcSubMenu } from '../vc-menu';
|
||||
import { getListeners } from '../_util/props-util';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export default {
|
||||
name: 'ASubMenu',
|
||||
isSubMenu: true,
|
||||
props: { ...VcSubMenu.props },
|
||||
inject: {
|
||||
menuPropsContext: { default: () => ({}) },
|
||||
},
|
||||
methods: {
|
||||
onKeyDown(e) {
|
||||
this.$refs.subMenu.onKeyDown(e);
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { $slots, $scopedSlots } = this;
|
||||
const { rootPrefixCls, popupClassName } = this.$props;
|
||||
const { theme: antdMenuTheme } = this.menuPropsContext;
|
||||
const props = {
|
||||
props: {
|
||||
...this.$props,
|
||||
popupClassName: classNames(`${rootPrefixCls}-${antdMenuTheme}`, popupClassName),
|
||||
},
|
||||
ref: 'subMenu',
|
||||
on: getListeners(this),
|
||||
scopedSlots: $scopedSlots,
|
||||
};
|
||||
const slotsKey = Object.keys($slots);
|
||||
return (
|
||||
<VcSubMenu {...props}>
|
||||
{slotsKey.length
|
||||
? slotsKey.map(name => {
|
||||
return <template slot={name}>{$slots[name]}</template>;
|
||||
})
|
||||
: null}
|
||||
</VcSubMenu>
|
||||
);
|
||||
},
|
||||
};
|
|
@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
|
|||
import { asyncExpect } from '@/tests/utils';
|
||||
import Menu from '..';
|
||||
import Icon from '../../icon';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
|
||||
jest.mock('mutationobserver-shim', () => {
|
||||
global.MutationObserver = function MutationObserver() {
|
||||
|
@ -15,6 +16,17 @@ function $$(className) {
|
|||
return document.body.querySelectorAll(className);
|
||||
}
|
||||
describe('Menu', () => {
|
||||
mountTest({
|
||||
render() {
|
||||
return (
|
||||
<Menu>
|
||||
<Menu.Item />
|
||||
<Menu.ItemGroup />
|
||||
<Menu.SubMenu />
|
||||
</Menu>
|
||||
);
|
||||
},
|
||||
});
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = '';
|
||||
// jest.useFakeTimers()
|
||||
|
|
|
@ -16,9 +16,13 @@ const md = {
|
|||
导航菜单是一个网站的灵魂,用户依赖导航在各个页面中进行跳转。一般分为顶部导航和侧边导航,顶部导航提供全局性的类目和功能,侧边导航提供多级结构来收纳和排列网站架构。
|
||||
## 代码演示`,
|
||||
us: `# Menu
|
||||
Menu list of Navigation.
|
||||
A versatile menu for navigation.
|
||||
|
||||
## When To Use
|
||||
Navigation menu is important for a website, it helps users jump from one site section to another quickly. Mostly, it includes top navigation and side navigation. Top navigation provides all the category and functions of the website. Side navigation provides the Multi-level structure of the website.
|
||||
|
||||
Navigation is an important part of any website, as a good navigation setup allows users to move around the site quickly and efficiently. Ant Design offers top and side navigation options. Top navigation provides all the categories and functions of the website. Side navigation provides the multi-level structure of the website.
|
||||
|
||||
More layouts with navigation: [Layout](/components/layout).
|
||||
## Examples`,
|
||||
};
|
||||
export default {
|
||||
|
|
|
@ -50,11 +50,12 @@
|
|||
|
||||
### Menu.SubMenu
|
||||
|
||||
| Param | Description | Type | Default value |
|
||||
| -------- | ----------------------------------- | ------------ | ------------- |
|
||||
| disabled | whether sub menu is disabled or not | boolean | false |
|
||||
| key | unique id of the sub menu | string | |
|
||||
| title | title of the sub menu | string\|slot | |
|
||||
| Param | Description | Type | Default value | Version |
|
||||
| -------------- | ----------------------------------- | ------------ | ------------- | ------- |
|
||||
| popupClassName | Sub-menu class name | string | | 1.5.0 |
|
||||
| disabled | whether sub menu is disabled or not | boolean | false | |
|
||||
| key | Unique ID of the sub menu | string | | |
|
||||
| title | title of the sub menu | string\|slot | | |
|
||||
|
||||
The children of Menu.SubMenu must be `MenuItem` or `SubMenu`.
|
||||
|
||||
|
@ -68,7 +69,7 @@ The children of Menu.SubMenu must be `MenuItem` or `SubMenu`.
|
|||
|
||||
| Param | Description | Type | Default value |
|
||||
| -------- | ------------------ | ------------ | ------------- |
|
||||
| children | sub menu items | MenuItem\[] | |
|
||||
| children | sub-menu items | MenuItem\[] | |
|
||||
| title | title of the group | string\|slot | |
|
||||
|
||||
The children of Menu.ItemGroup must be `MenuItem`.
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import omit from 'omit.js';
|
||||
import VcMenu, { Divider, ItemGroup, SubMenu } from '../vc-menu';
|
||||
import VcMenu, { Divider, ItemGroup } from '../vc-menu';
|
||||
import SubMenu from './SubMenu';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import animation from '../_util/openAnimation';
|
||||
import warning from '../_util/warning';
|
||||
import Item from './MenuItem';
|
||||
import { hasProp, getListeners } from '../_util/props-util';
|
||||
import { hasProp, getListeners, getOptionProps } from '../_util/props-util';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
import commonPropsType from '../vc-menu/commonPropsType';
|
||||
import { ConfigConsumerProps } from '../config-provider';
|
||||
import Base from '../base';
|
||||
// import raf from '../_util/raf';
|
||||
|
||||
export const MenuMode = PropTypes.oneOf([
|
||||
'vertical',
|
||||
|
@ -47,6 +49,7 @@ const Menu = {
|
|||
provide() {
|
||||
return {
|
||||
getInlineCollapsed: this.getInlineCollapsed,
|
||||
menuPropsContext: this.$props,
|
||||
};
|
||||
},
|
||||
mixins: [BaseMixin],
|
||||
|
@ -58,12 +61,12 @@ const Menu = {
|
|||
prop: 'selectedKeys',
|
||||
event: 'selectChange',
|
||||
},
|
||||
created() {
|
||||
this.preProps = { ...this.$props };
|
||||
},
|
||||
updated() {
|
||||
this.propsUpdating = false;
|
||||
},
|
||||
// beforeDestroy() {
|
||||
// raf.cancel(this.mountRafId);
|
||||
// },
|
||||
watch: {
|
||||
mode(val, oldVal) {
|
||||
if (oldVal === 'inline' && val !== 'inline') {
|
||||
|
@ -81,9 +84,10 @@ const Menu = {
|
|||
},
|
||||
},
|
||||
data() {
|
||||
const props = this.$props;
|
||||
const props = getOptionProps(this);
|
||||
warning(
|
||||
!(hasProp(this, 'inlineCollapsed') && props.mode !== 'inline'),
|
||||
!('inlineCollapsed' in props && props.mode !== 'inline'),
|
||||
'Menu',
|
||||
"`inlineCollapsed` should only be used when Menu's `mode` is inline.",
|
||||
);
|
||||
this.switchingModeFromInline = false;
|
||||
|
@ -91,9 +95,9 @@ const Menu = {
|
|||
this.inlineOpenKeys = [];
|
||||
let sOpenKeys;
|
||||
|
||||
if (hasProp(this, 'openKeys')) {
|
||||
if ('openKeys' in props) {
|
||||
sOpenKeys = props.openKeys;
|
||||
} else if (hasProp(this, 'defaultOpenKeys')) {
|
||||
} else if ('defaultOpenKeys' in props) {
|
||||
sOpenKeys = props.defaultOpenKeys;
|
||||
}
|
||||
return {
|
||||
|
@ -137,10 +141,20 @@ const Menu = {
|
|||
// when inlineCollapsed menu width animation finished
|
||||
// https://github.com/ant-design/ant-design/issues/12864
|
||||
const widthCollapsed = e.propertyName === 'width' && e.target === e.currentTarget;
|
||||
|
||||
// Fix SVGElement e.target.className.indexOf is not a function
|
||||
// https://github.com/ant-design/ant-design/issues/15699
|
||||
const { className } = e.target;
|
||||
// SVGAnimatedString.animVal should be identical to SVGAnimatedString.baseVal, unless during an animation.
|
||||
const classNameValue =
|
||||
Object.prototype.toString.call(className) === '[object SVGAnimatedString]'
|
||||
? className.animVal
|
||||
: className;
|
||||
|
||||
// Fix for <Menu style={{ width: '100%' }} />, the width transition won't trigger when menu is collapsed
|
||||
// https://github.com/ant-design/ant-design-pro/issues/2783
|
||||
const iconScaled =
|
||||
e.propertyName === 'font-size' && e.target.className.indexOf('anticon') >= 0;
|
||||
const iconScaled = e.propertyName === 'font-size' && classNameValue.indexOf('anticon') >= 0;
|
||||
|
||||
if (widthCollapsed || iconScaled) {
|
||||
this.restoreModeVerticalFromInline();
|
||||
}
|
||||
|
@ -254,11 +268,11 @@ const Menu = {
|
|||
}
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/8587
|
||||
if (
|
||||
const hideMenu =
|
||||
this.getInlineCollapsed() &&
|
||||
(collapsedWidth === 0 || collapsedWidth === '0' || collapsedWidth === '0px')
|
||||
) {
|
||||
return null;
|
||||
(collapsedWidth === 0 || collapsedWidth === '0' || collapsedWidth === '0px');
|
||||
if (hideMenu) {
|
||||
menuProps.props.openKeys = [];
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -49,11 +49,12 @@
|
|||
|
||||
### Menu.SubMenu
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| -------- | ---------- | ------------ | ------ |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
| key | 唯一标志 | string | |
|
||||
| title | 子菜单项值 | string\|slot | |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| -------------- | ---------- | ------------ | ------ | ----- |
|
||||
| popupClassName | 子菜单样式 | string | | 1.5.0 |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| key | 唯一标志 | string | | |
|
||||
| title | 子菜单项值 | string\|slot | | |
|
||||
|
||||
Menu.SubMenu 的子元素必须是 `MenuItem` 或者 `SubMenu`.
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ const DOMWrap = {
|
|||
this.resizeObserver.disconnect();
|
||||
}
|
||||
if (this.mutationObserver) {
|
||||
this.resizeObserver.disconnect();
|
||||
this.mutationObserver.disconnect();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -98,9 +98,9 @@ const DOMWrap = {
|
|||
}
|
||||
|
||||
// filter out all overflowed indicator placeholder
|
||||
return [].slice.call(ul.children).filter(node => {
|
||||
return node.className.split(' ').indexOf(`${prefixCls}-overflowed-submenu`) < 0;
|
||||
});
|
||||
return [].slice
|
||||
.call(ul.children)
|
||||
.filter(node => node.className.split(' ').indexOf(`${prefixCls}-overflowed-submenu`) < 0);
|
||||
},
|
||||
|
||||
getOverflowedSubMenuItem(keyPrefix, overflowedItems, renderPlaceholder) {
|
||||
|
@ -111,10 +111,11 @@ const DOMWrap = {
|
|||
// 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); // eslint-disable-line no-unused-vars
|
||||
const { title, ...rest } = getPropsData(copy); // eslint-disable-line no-unused-vars
|
||||
|
||||
let style = {};
|
||||
let key = `${keyPrefix}-overflowed-indicator`;
|
||||
let eventKey = `${keyPrefix}-overflowed-indicator`;
|
||||
|
||||
if (overflowedItems.length === 0 && renderPlaceholder !== true) {
|
||||
style = {
|
||||
|
@ -127,6 +128,7 @@ const DOMWrap = {
|
|||
position: 'absolute',
|
||||
};
|
||||
key = `${key}-placeholder`;
|
||||
eventKey = `${eventKey}-placeholder`;
|
||||
}
|
||||
|
||||
const popupClassName = theme ? `${prefixCls}-${theme}` : '';
|
||||
|
@ -141,7 +143,7 @@ const DOMWrap = {
|
|||
title: overflowedIndicator,
|
||||
popupClassName,
|
||||
...props,
|
||||
eventKey: `${keyPrefix}-overflowed-indicator`,
|
||||
eventKey,
|
||||
disabled: false,
|
||||
},
|
||||
class: `${prefixCls}-overflowed-submenu`,
|
||||
|
@ -226,7 +228,7 @@ const DOMWrap = {
|
|||
this.menuItemSizes.forEach(liWidth => {
|
||||
currentSumWidth += liWidth;
|
||||
if (currentSumWidth + this.overflowedIndicatorWidth <= width) {
|
||||
lastVisibleIndex++;
|
||||
lastVisibleIndex += 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -251,7 +253,7 @@ const DOMWrap = {
|
|||
{
|
||||
style: { display: 'none' },
|
||||
props: { eventKey: `${eventKey}-hidden` },
|
||||
class: { ...getClass(childNode), [MENUITEM_OVERFLOWED_CLASSNAME]: true },
|
||||
class: MENUITEM_OVERFLOWED_CLASSNAME,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -40,16 +40,22 @@ const MenuItem = {
|
|||
mixins: [BaseMixin],
|
||||
isMenuItem: true,
|
||||
created() {
|
||||
this.prevActive = this.active;
|
||||
// invoke customized ref to expose component to mixin
|
||||
this.callRef();
|
||||
},
|
||||
updated() {
|
||||
this.$nextTick(() => {
|
||||
if (this.active) {
|
||||
const { active, parentMenu, eventKey } = this.$props;
|
||||
if (!this.prevActive && active && (!parentMenu || !parentMenu[`scrolled-${eventKey}`])) {
|
||||
scrollIntoView(this.$el, this.parentMenu.$el, {
|
||||
onlyScrollIfNeeded: true,
|
||||
});
|
||||
parentMenu[`scrolled-${eventKey}`] = true;
|
||||
} else if (parentMenu && parentMenu[`scrolled-${eventKey}`]) {
|
||||
delete parentMenu[`scrolled-${eventKey}`];
|
||||
}
|
||||
this.prevActive = active;
|
||||
});
|
||||
this.callRef();
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import PropTypes from '../_util/vue-types';
|
||||
import { getComponentFromProp, getListeners } from '../_util/props-util';
|
||||
|
||||
// import { menuAllProps } from './util'
|
||||
|
||||
const MenuItemGroup = {
|
||||
|
|
|
@ -10,6 +10,7 @@ import { getComponentFromProp, filterEmpty, getListeners } from '../_util/props-
|
|||
import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout';
|
||||
import { noop, loopMenuItemRecursively, getMenuIdFromSubMenuEventKey } from './util';
|
||||
import getTransitionProps from '../_util/getTransitionProps';
|
||||
import { MenuItem } from './MenuItem';
|
||||
|
||||
let guid = 0;
|
||||
|
||||
|
@ -171,6 +172,7 @@ const SubMenu = {
|
|||
if (isOpen && (keyCode === KeyCode.UP || keyCode === KeyCode.DOWN)) {
|
||||
return menu.onKeyDown(e);
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
onPopupVisibleChange(visible) {
|
||||
|
@ -368,7 +370,7 @@ const SubMenu = {
|
|||
deselect,
|
||||
openChange,
|
||||
},
|
||||
id: this._menuId,
|
||||
id: this.internalMenuId,
|
||||
};
|
||||
const baseProps = subPopupMenuProps.props;
|
||||
const haveRendered = this.haveRendered;
|
||||
|
@ -429,11 +431,11 @@ const SubMenu = {
|
|||
[this.getSelectedClassName()]: this.isChildrenSelected(),
|
||||
};
|
||||
|
||||
if (!this._menuId) {
|
||||
if (!this.internalMenuId) {
|
||||
if (props.eventKey) {
|
||||
this._menuId = `${props.eventKey}$Menu`;
|
||||
this.internalMenuId = `${props.eventKey}$Menu`;
|
||||
} else {
|
||||
this._menuId = `$__$${++guid}$Menu`;
|
||||
this.internalMenuId = `$__$${++guid}$Menu`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,7 +468,7 @@ const SubMenu = {
|
|||
// since corresponding node cannot be found
|
||||
if (isOpen) {
|
||||
ariaOwns = {
|
||||
'aria-owns': this._menuId,
|
||||
'aria-owns': this.internalMenuId,
|
||||
};
|
||||
}
|
||||
const titleProps = {
|
||||
|
|
|
@ -193,6 +193,7 @@ const SubPopupMenu = {
|
|||
|
||||
return 1;
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
onItemHover(e) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// based on rc-menu 7.4.21
|
||||
// based on rc-menu 7.5.5
|
||||
import Menu from './Menu';
|
||||
import SubMenu from './SubMenu';
|
||||
import MenuItem, { menuItemProps } from './MenuItem';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const isMobile = require('ismobilejs');
|
||||
import isMobile from './utils/isMobile';
|
||||
|
||||
export function noop() {}
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
// MIT License from https://github.com/kaimallea/isMobile
|
||||
|
||||
const applePhone = /iPhone/i;
|
||||
const appleIpod = /iPod/i;
|
||||
const appleTablet = /iPad/i;
|
||||
const androidPhone = /\bAndroid(?:.+)Mobile\b/i; // Match 'Android' AND 'Mobile'
|
||||
const androidTablet = /Android/i;
|
||||
const amazonPhone = /\bAndroid(?:.+)SD4930UR\b/i;
|
||||
const amazonTablet = /\bAndroid(?:.+)(?:KF[A-Z]{2,4})\b/i;
|
||||
const windowsPhone = /Windows Phone/i;
|
||||
const windowsTablet = /\bWindows(?:.+)ARM\b/i; // Match 'Windows' AND 'ARM'
|
||||
const otherBlackberry = /BlackBerry/i;
|
||||
const otherBlackberry10 = /BB10/i;
|
||||
const otherOpera = /Opera Mini/i;
|
||||
const otherChrome = /\b(CriOS|Chrome)(?:.+)Mobile/i;
|
||||
const otherFirefox = /Mobile(?:.+)Firefox\b/i; // Match 'Mobile' AND 'Firefox'
|
||||
|
||||
function match(regex, userAgent) {
|
||||
return regex.test(userAgent);
|
||||
}
|
||||
|
||||
function isMobile(userAgent) {
|
||||
let ua = userAgent || (typeof navigator !== 'undefined' ? navigator.userAgent : '');
|
||||
|
||||
// Facebook mobile app's integrated browser adds a bunch of strings that
|
||||
// match everything. Strip it out if it exists.
|
||||
let tmp = ua.split('[FBAN');
|
||||
if (typeof tmp[1] !== 'undefined') {
|
||||
[ua] = tmp;
|
||||
}
|
||||
|
||||
// Twitter mobile app's integrated browser on iPad adds a "Twitter for
|
||||
// iPhone" string. Same probably happens on other tablet platforms.
|
||||
// This will confuse detection so strip it out if it exists.
|
||||
tmp = ua.split('Twitter');
|
||||
if (typeof tmp[1] !== 'undefined') {
|
||||
[ua] = tmp;
|
||||
}
|
||||
|
||||
const result = {
|
||||
apple: {
|
||||
phone: match(applePhone, ua) && !match(windowsPhone, ua),
|
||||
ipod: match(appleIpod, ua),
|
||||
tablet: !match(applePhone, ua) && match(appleTablet, ua) && !match(windowsPhone, ua),
|
||||
device:
|
||||
(match(applePhone, ua) || match(appleIpod, ua) || match(appleTablet, ua)) &&
|
||||
!match(windowsPhone, ua),
|
||||
},
|
||||
amazon: {
|
||||
phone: match(amazonPhone, ua),
|
||||
tablet: !match(amazonPhone, ua) && match(amazonTablet, ua),
|
||||
device: match(amazonPhone, ua) || match(amazonTablet, ua),
|
||||
},
|
||||
android: {
|
||||
phone:
|
||||
(!match(windowsPhone, ua) && match(amazonPhone, ua)) ||
|
||||
(!match(windowsPhone, ua) && match(androidPhone, ua)),
|
||||
tablet:
|
||||
!match(windowsPhone, ua) &&
|
||||
!match(amazonPhone, ua) &&
|
||||
!match(androidPhone, ua) &&
|
||||
(match(amazonTablet, ua) || match(androidTablet, ua)),
|
||||
device:
|
||||
(!match(windowsPhone, ua) &&
|
||||
(match(amazonPhone, ua) ||
|
||||
match(amazonTablet, ua) ||
|
||||
match(androidPhone, ua) ||
|
||||
match(androidTablet, ua))) ||
|
||||
match(/\bokhttp\b/i, ua),
|
||||
},
|
||||
windows: {
|
||||
phone: match(windowsPhone, ua),
|
||||
tablet: match(windowsTablet, ua),
|
||||
device: match(windowsPhone, ua) || match(windowsTablet, ua),
|
||||
},
|
||||
other: {
|
||||
blackberry: match(otherBlackberry, ua),
|
||||
blackberry10: match(otherBlackberry10, ua),
|
||||
opera: match(otherOpera, ua),
|
||||
firefox: match(otherFirefox, ua),
|
||||
chrome: match(otherChrome, ua),
|
||||
device:
|
||||
match(otherBlackberry, ua) ||
|
||||
match(otherBlackberry10, ua) ||
|
||||
match(otherOpera, ua) ||
|
||||
match(otherFirefox, ua) ||
|
||||
match(otherChrome, ua),
|
||||
},
|
||||
|
||||
// Additional
|
||||
any: null,
|
||||
phone: null,
|
||||
tablet: null,
|
||||
};
|
||||
result.any =
|
||||
result.apple.device || result.android.device || result.windows.device || result.other.device;
|
||||
|
||||
// excludes 'other' devices and ipods, targeting touchscreen phones
|
||||
result.phone = result.apple.phone || result.android.phone || result.windows.phone;
|
||||
result.tablet = result.apple.tablet || result.android.tablet || result.windows.tablet;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const defaultResult = {
|
||||
...isMobile(),
|
||||
isMobile,
|
||||
};
|
||||
|
||||
export default defaultResult;
|
|
@ -24,4 +24,6 @@ export declare class SubMenu extends AntdComponent {
|
|||
* @type string | slot
|
||||
*/
|
||||
title: any;
|
||||
|
||||
popupClassName: string;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue