From 7b494fd44575a41cda4ea7dd182649d04fbb93b9 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 23 May 2021 22:40:42 +0800 Subject: [PATCH] fix: menu --- components/_util/isMobile.js | 110 +++++++++++++++++ components/input/Search.tsx | 2 +- components/menu/index.tsx | 5 + components/menu/src/Menu.tsx | 16 ++- components/menu/src/MenuItem.tsx | 29 ++++- components/vc-mentions/src/DropdownMenu.jsx | 4 +- examples/App.vue | 124 +++++--------------- 7 files changed, 185 insertions(+), 105 deletions(-) create mode 100644 components/_util/isMobile.js diff --git a/components/_util/isMobile.js b/components/_util/isMobile.js new file mode 100644 index 000000000..96927fd3b --- /dev/null +++ b/components/_util/isMobile.js @@ -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; diff --git a/components/input/Search.tsx b/components/input/Search.tsx index b13b741e7..77388c695 100644 --- a/components/input/Search.tsx +++ b/components/input/Search.tsx @@ -1,6 +1,6 @@ import { defineComponent, inject } from 'vue'; import classNames from '../_util/classNames'; -import isMobile from '../vc-menu/utils/isMobile'; +import isMobile from '../_util/isMobile'; import Input from './Input'; import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'; import SearchOutlined from '@ant-design/icons-vue/SearchOutlined'; diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 120eed074..fa839d6b1 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -14,6 +14,11 @@ Menu.install = function(app: App) { return app; }; +Menu.Item = MenuItem; +Menu.Divider = Divider; +Menu.SubMenu = SubMenu; +Menu.ItemGroup = ItemGroup; + export default Menu as typeof Menu & Plugin & { readonly Item: typeof MenuItem; diff --git a/components/menu/src/Menu.tsx b/components/menu/src/Menu.tsx index 6582e57d2..4f619ad38 100644 --- a/components/menu/src/Menu.tsx +++ b/components/menu/src/Menu.tsx @@ -146,10 +146,10 @@ export default defineComponent({ ...info, selectedKeys: newSelectedKeys, }; - if (!('selectedKeys' in props)) { - mergedSelectedKeys.value = newSelectedKeys; - } if (!shallowEqual(newSelectedKeys, mergedSelectedKeys.value)) { + if (!('selectedKeys' in props)) { + mergedSelectedKeys.value = newSelectedKeys; + } emit('update:selectedKeys', newSelectedKeys); if (exist && props.multiple) { emit('deselect', selectInfo); @@ -266,6 +266,10 @@ export default defineComponent({ triggerSelection(info); }; + const onInternalKeyDown = (e: KeyboardEvent) => { + console.log('onInternalKeyDown', e); + }; + const onInternalOpenChange = (eventKey: Key, open: boolean) => { const { key, childrenEventKeys } = store[eventKey]; let newOpenKeys = mergedOpenKeys.value.filter(k => k !== key); @@ -322,7 +326,11 @@ export default defineComponent({ isRootMenu: true, }); return () => { - return