Selaa lähdekoodia

fix(modal): height calc error #161

vben 4 vuotta sitten
vanhempi
commit
144ab577da

+ 1 - 0
CHANGELOG.zh_CN.md

@@ -13,6 +13,7 @@
 - 恢复 table 的`isTreeTable`属性
 - 修复表格内存溢出问题
 - 修复`layout` 收缩展开功能在分割模式下失效
+- 修复 modal 高度计算错误
 
 ## 2.0.0-rc.15 (2020-12-31)
 

+ 2 - 2
README.md

@@ -256,8 +256,8 @@ yarn clean:lib # 删除node_modules,兼容window系统
 
 如果这些插件对你有帮助,可以给一个 star 支持下
 
-- [vite-plugin-mock](https://github.com/anncwb/vite-plugin-mock)
-- [vite-plugin-html](https://github.com/anncwb/vite-plugin-html)
+- [vite-plugin-mock](https://github.com/vbenjs/vite-plugin-mock)
+- [vite-plugin-html](https://github.com/vbenjs/vite-plugin-html)
 
 ## 加入我们
 

+ 1 - 0
src/components/Basic/src/BasicArrow.vue

@@ -15,6 +15,7 @@
 
   export default defineComponent({
     name: 'BasicArrow',
+    inheritAttrs: false,
     components: { RightOutlined },
     props: {
       // Expand contract, expand by default

+ 1 - 0
src/components/Basic/src/BasicHelp.vue

@@ -12,6 +12,7 @@
   import { useDesign } from '/@/hooks/web/useDesign';
   export default defineComponent({
     name: 'BasicHelp',
+    inheritAttrs: false,
     components: { Tooltip },
     props: {
       // max-width

+ 1 - 0
src/components/Basic/src/BasicTitle.vue

@@ -15,6 +15,7 @@
 
   export default defineComponent({
     name: 'BasicTitle',
+    inheritAttrs: false,
     components: { BasicHelp },
     props: {
       helpMessage: {

+ 1 - 0
src/components/Container/src/LazyContainer.vue

@@ -35,6 +35,7 @@
 
   export default defineComponent({
     name: 'LazyContainer',
+    inheritAttrs: false,
     components: { Skeleton },
     props: {
       // Waiting time, if the time is specified, whether visible or not, it will be automatically loaded after the specified time

+ 1 - 0
src/components/Container/src/ScrollContainer.vue

@@ -12,6 +12,7 @@
 
   export default defineComponent({
     name: 'ScrollContainer',
+    inheritAttrs: false,
     components: { Scrollbar },
     setup() {
       const scrollbarRef = ref<Nullable<ScrollbarType>>(null);

+ 15 - 2
src/components/Markdown/src/index.vue

@@ -8,19 +8,23 @@
 
   import { propTypes } from '/@/utils/propTypes';
   import { useLocale } from '/@/hooks/web/useLocale';
+  import { useModalContext } from '../../Modal';
 
   type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined;
   export default defineComponent({
-    emits: ['change'],
+    inheritAttrs: false,
     props: {
       height: propTypes.number.def(360),
       value: propTypes.string.def(''),
     },
+    emits: ['change', 'get'],
     setup(props, { attrs, emit }) {
       const wrapRef = ref<ElRef>(null);
       const vditorRef = ref<Nullable<Vditor>>(null);
       const initedRef = ref(false);
 
+      const modalFn = useModalContext();
+
       const lang = ref<Lang>();
 
       const { getLang } = useLocale();
@@ -66,10 +70,19 @@
         initedRef.value = true;
       }
 
+      const instance = {
+        getVditor: (): Vditor => vditorRef.value!,
+      };
+
       onMounted(() => {
         nextTick(() => {
           init();
+          setTimeout(() => {
+            modalFn?.redoModalHeight?.();
+          }, 200);
         });
+
+        emit('get', instance);
       });
 
       onUnmounted(() => {
@@ -82,7 +95,7 @@
 
       return {
         wrapRef,
-        getVditor: (): Vditor => vditorRef.value!,
+        ...instance,
       };
     },
   });

+ 3 - 1
src/components/Modal/src/BasicModal.vue

@@ -27,7 +27,7 @@
       :height="getProps.height"
       :visible="visibleRef"
       :modalFooterHeight="footer !== undefined && !footer ? 0 : undefined"
-      v-bind="omit(getProps.wrapperProps, 'visible')"
+      v-bind="omit(getProps.wrapperProps, 'visible', 'height')"
       @ext-height="handleExtHeight"
       @height-change="handleHeightChange"
     >
@@ -51,6 +51,7 @@
     watchEffect,
     toRef,
     getCurrentInstance,
+    nextTick,
   } from 'vue';
 
   import Modal from './components/Modal';
@@ -67,6 +68,7 @@
   import { omit } from 'lodash-es';
   export default defineComponent({
     name: 'BasicModal',
+    inheritAttrs: false,
     components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
     props: basicProps,
     emits: ['visible-change', 'height-change', 'cancel', 'ok', 'register'],

+ 7 - 3
src/components/Modal/src/components/ModalWrapper.vue

@@ -31,6 +31,7 @@
 
   export default defineComponent({
     name: 'ModalWrapper',
+    inheritAttrs: false,
     components: { Spin, ScrollContainer },
     props: {
       loading: propTypes.bool,
@@ -51,6 +52,8 @@
       const realHeightRef = ref(0);
       const minRealHeightRef = ref(0);
 
+      let realHeight = 0;
+
       let stopElResizeFn: Fn = () => {};
 
       useWindowSizeFn(setModalHeight);
@@ -137,8 +140,9 @@
 
           if (!spinEl) return;
 
-          const realHeight = spinEl.scrollHeight;
-
+          if (!realHeight) {
+            realHeight = spinEl.scrollHeight;
+          }
           if (props.fullScreen) {
             realHeightRef.value =
               window.innerHeight - props.modalFooterHeight - props.modalHeaderHeight;
@@ -147,7 +151,7 @@
               ? props.height
               : realHeight > maxHeight
               ? maxHeight
-              : realHeight + 16 + 30;
+              : realHeight + 46;
           }
           emit('height-change', unref(realHeightRef));
         } catch (error) {

+ 10 - 3
src/components/Scrollbar/src/index.vue

@@ -33,6 +33,7 @@
 
   export default defineComponent({
     name: 'Scrollbar',
+    inheritAttrs: false,
     components: { Bar },
     props: {
       native: {
@@ -91,12 +92,18 @@
       onMounted(() => {
         if (props.native) return;
         nextTick(update);
-        !props.noresize && addResizeListener(resize.value, update);
+        if (!props.noresize) {
+          addResizeListener(resize.value, update);
+          addResizeListener(wrap.value, update);
+        }
       });
 
       onBeforeUnmount(() => {
         if (props.native) return;
-        !props.noresize && removeResizeListener(resize.value, update);
+        if (!props.noresize) {
+          removeResizeListener(resize.value, update);
+          removeResizeListener(wrap.value, update);
+        }
       });
       const style = computed(() => {
         let style: any = props.wrapStyle;
@@ -127,7 +134,7 @@
 
     &__wrap {
       height: 100%;
-      overflow: scroll;
+      overflow: auto;
 
       &--hidden-default {
         scrollbar-width: none;

+ 1 - 0
src/components/Tinymce/src/Editor.vue

@@ -31,6 +31,7 @@
 
   export default defineComponent({
     name: 'Tinymce',
+    inheritAttrs: false,
     props: basicProps,
     emits: ['change', 'update:modelValue'],
     setup(props, { emit, attrs }) {

+ 9 - 2
src/components/Tree/src/BasicTree.tsx

@@ -15,6 +15,7 @@ import { extendSlots } from '/@/utils/helper/tsxHelper';
 import { basicProps } from './props';
 import { useTree } from './useTree';
 import { useExpose } from '/@/hooks/core/useExpose';
+import { onMounted } from 'vue';
 
 interface State {
   expandedKeys: Keys;
@@ -25,7 +26,7 @@ const prefixCls = 'basic-tree';
 export default defineComponent({
   name: 'BasicTree',
   props: basicProps,
-  emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value'],
+  emits: ['update:expandedKeys', 'update:selectedKeys', 'update:value', 'get'],
   setup(props, { attrs, slots, emit }) {
     const state = reactive<State>({
       expandedKeys: props.expandedKeys || [],
@@ -182,7 +183,7 @@ export default defineComponent({
       state.checkedKeys = props.checkedKeys;
     });
 
-    useExpose<TreeActionType>({
+    const instance: TreeActionType = {
       setExpandedKeys,
       getExpandedKeys,
       setSelectedKeys,
@@ -195,6 +196,12 @@ export default defineComponent({
       filterByLevel: (level: number) => {
         state.expandedKeys = filterByLevel(level);
       },
+    };
+
+    useExpose<TreeActionType>(instance);
+
+    onMounted(() => {
+      emit('get', instance);
     });
 
     return () => {

+ 0 - 2
src/hooks/component/usePageContext.ts

@@ -1,8 +1,6 @@
 import type { InjectionKey, ComputedRef, Ref } from 'vue';
 import { createContext, useContext } from '/@/hooks/core/useContext';
 
-import {} from 'vue';
-
 export interface PageContextProps {
   contentHeight: ComputedRef<number>;
   pageHeight: Ref<number>;

+ 1 - 2
src/layouts/default/sider/MixSider.vue

@@ -113,7 +113,6 @@
       const activePath = ref('');
       const chilrenMenus = ref<Menu[]>([]);
       const openMenu = ref(false);
-      const isInit = ref(false);
       const dragBarRef = ref<ElRef>(null);
       const sideRef = ref<ElRef>(null);
       const currentRoute = ref<Nullable<RouteLocationNormalized>>(null);
@@ -251,8 +250,8 @@
       }
 
       function handleClickOutside() {
+        setActive(true);
         closeMenu();
-        setActive();
       }
 
       function getItemEvents(item: Menu) {

+ 2 - 2
src/utils/browser.ts

@@ -75,7 +75,7 @@ export function isOperaFn() {
  * set page Title
  * @param {*} title  :page Title
  */
-const setDocumentTitle = (title: string) => {
+function setDocumentTitle(title: string) {
   document.title = title;
   const ua = navigator.userAgent;
   const regex = /\bMicroMessenger\/([\d.]+)/;
@@ -91,7 +91,7 @@ const setDocumentTitle = (title: string) => {
     };
     document.body.appendChild(i);
   }
-};
+}
 
 export function setTitle(title: string, appTitle?: string) {
   if (title) {

+ 26 - 23
src/utils/color.ts

@@ -5,10 +5,10 @@
  * @param   String  color   十六进制颜色值
  * @return  Boolean
  */
-export const isHexColor = function (color: string) {
+export function isHexColor(color: string) {
   const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
   return reg.test(color);
-};
+}
 
 /**
  * RGB 颜色值转换为 十六进制颜色值.
@@ -19,18 +19,18 @@ export const isHexColor = function (color: string) {
  * @param g
  * @param b
  */
-export const rgbToHex = function (r: number, g: number, b: number) {
+export function rgbToHex(r: number, g: number, b: number) {
   // tslint:disable-next-line:no-bitwise
   const hex = ((r << 16) | (g << 8) | b).toString(16);
   return '#' + new Array(Math.abs(hex.length - 7)).join('0') + hex;
-};
+}
 
 /**
  * Transform a HEX color to its RGB representation
  * @param {string} hex The color to transform
  * @returns The RGB representation of the passed color
  */
-export const hexToRGB = function (hex: string) {
+export function hexToRGB(hex: string) {
   let sHex = hex.toLowerCase();
   if (isHexColor(hex)) {
     if (sHex.length === 4) {
@@ -47,16 +47,16 @@ export const hexToRGB = function (hex: string) {
     return 'RGB(' + sColorChange.join(',') + ')';
   }
   return sHex;
-};
+}
 
-export const colorIsDark = (color: string) => {
+export function colorIsDark(color: string) {
   if (!isHexColor(color)) return;
   const [r, g, b] = hexToRGB(color)
     .replace(/(?:\(|\)|rgb|RGB)*/g, '')
     .split(',')
     .map((item) => Number(item));
   return r * 0.299 + g * 0.578 + b * 0.114 < 192;
-};
+}
 
 /**
  * Darkens a HEX color given the passed percentage
@@ -64,14 +64,14 @@ export const colorIsDark = (color: string) => {
  * @param {number} amount The amount to change the color by
  * @returns {string} The HEX representation of the processed color
  */
-export const darken = (color: string, amount: number) => {
+export function darken(color: string, amount: number) {
   color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
   amount = Math.trunc((255 * amount) / 100);
   return `#${subtractLight(color.substring(0, 2), amount)}${subtractLight(
     color.substring(2, 4),
     amount
   )}${subtractLight(color.substring(4, 6), amount)}`;
-};
+}
 
 /**
  * Lightens a 6 char HEX color according to the passed percentage
@@ -79,14 +79,14 @@ export const darken = (color: string, amount: number) => {
  * @param {number} amount The amount to change the color by
  * @returns {string} The processed color represented as HEX
  */
-export const lighten = (color: string, amount: number) => {
+export function lighten(color: string, amount: number) {
   color = color.indexOf('#') >= 0 ? color.substring(1, color.length) : color;
   amount = Math.trunc((255 * amount) / 100);
   return `#${addLight(color.substring(0, 2), amount)}${addLight(
     color.substring(2, 4),
     amount
   )}${addLight(color.substring(4, 6), amount)}`;
-};
+}
 
 /* Suma el porcentaje indicado a un color (RR, GG o BB) hexadecimal para aclararlo */
 /**
@@ -95,11 +95,11 @@ export const lighten = (color: string, amount: number) => {
  * @param {number} amount The amount to change the color by
  * @returns {string} The processed part of the color
  */
-const addLight = (color: string, amount: number) => {
+function addLight(color: string, amount: number) {
   const cc = parseInt(color, 16) + amount;
   const c = cc > 255 ? 255 : cc;
   return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
-};
+}
 
 /**
  * Calculates luminance of an rgb color
@@ -107,33 +107,36 @@ const addLight = (color: string, amount: number) => {
  * @param {number} g green
  * @param {number} b blue
  */
-const luminanace = (r: number, g: number, b: number) => {
+function luminanace(r: number, g: number, b: number) {
   const a = [r, g, b].map((v) => {
     v /= 255;
     return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
   });
   return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
-};
+}
 
 /**
  * Calculates contrast between two rgb colors
  * @param {string} rgb1 rgb color 1
  * @param {string} rgb2 rgb color 2
  */
-const contrast = (rgb1: string[], rgb2: number[]) =>
-  (luminanace(~~rgb1[0], ~~rgb1[1], ~~rgb1[2]) + 0.05) /
-  (luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05);
+function contrast(rgb1: string[], rgb2: number[]) {
+  return (
+    (luminanace(~~rgb1[0], ~~rgb1[1], ~~rgb1[2]) + 0.05) /
+    (luminanace(rgb2[0], rgb2[1], rgb2[2]) + 0.05)
+  );
+}
 
 /**
  * Determines what the best text color is (black or white) based con the contrast with the background
  * @param hexColor - Last selected color by the user
  */
-export const calculateBestTextColor = (hexColor: string) => {
+export function calculateBestTextColor(hexColor: string) {
   const rgbColor = hexToRGB(hexColor.substring(1));
   const contrastWithBlack = contrast(rgbColor.split(','), [0, 0, 0]);
 
   return contrastWithBlack >= 12 ? '#000000' : '#FFFFFF';
-};
+}
 
 /**
  * Subtracts the indicated percentage to the R, G or B of a HEX color
@@ -141,8 +144,8 @@ export const calculateBestTextColor = (hexColor: string) => {
  * @param {number} amount The amount to change the color by
  * @returns {string} The processed part of the color
  */
-const subtractLight = (color: string, amount: number) => {
+function subtractLight(color: string, amount: number) {
   const cc = parseInt(color, 16) - amount;
   const c = cc < 0 ? 0 : cc;
   return c.toString(16).length > 1 ? c.toString(16) : `0${c.toString(16)}`;
-};
+}

+ 2 - 2
src/utils/dateUtil.ts

@@ -14,7 +14,7 @@ export function formatToDate(date: moment.MomentInput = null, format = DATE_FORM
   return moment(date).format(format);
 }
 
-export const formatAgo = (str: string | number) => {
+export function formatAgo(str: string | number) {
   if (!str) return '';
   const date = new Date(Number(str));
   const time = new Date().getTime() - date.getTime(); // 现在的时间-传入的时间 = 相差的时间(单位 = 毫秒)
@@ -35,6 +35,6 @@ export const formatAgo = (str: string | number) => {
   } else {
     return parseInt(String(time / 31536000000)) + '年前';
   }
-};
+}
 
 export const dateUtil = moment;

+ 6 - 6
src/utils/domUtils.ts

@@ -132,7 +132,7 @@ export function hackCss(attr: string, value: string) {
 }
 
 /* istanbul ignore next */
-export const on = function (
+export function on(
   element: Element | HTMLElement | Document | Window,
   event: string,
   handler: EventListenerOrEventListenerObject
@@ -140,10 +140,10 @@ export const on = function (
   if (element && event && handler) {
     element.addEventListener(event, handler, false);
   }
-};
+}
 
 /* istanbul ignore next */
-export const off = function (
+export function off(
   element: Element | HTMLElement | Document | Window,
   event: string,
   handler: Fn
@@ -151,10 +151,10 @@ export const off = function (
   if (element && event && handler) {
     element.removeEventListener(event, handler, false);
   }
-};
+}
 
 /* istanbul ignore next */
-export const once = function (el: HTMLElement, event: string, fn: EventListener): void {
+export function once(el: HTMLElement, event: string, fn: EventListener): void {
   const listener = function (this: any, ...args: unknown[]) {
     if (fn) {
       fn.apply(this, args);
@@ -162,4 +162,4 @@ export const once = function (el: HTMLElement, event: string, fn: EventListener)
     off(el, event, listener);
   };
   on(el, event, listener);
-};
+}

+ 14 - 6
src/utils/env.ts

@@ -1,9 +1,9 @@
 import type { GlobEnvConfig } from '/@/types/config';
 
-export const getGlobEnvConfig = (): GlobEnvConfig => {
+export function getGlobEnvConfig(): GlobEnvConfig {
   const env = import.meta.env;
   return (env as unknown) as GlobEnvConfig;
-};
+}
 
 /**
  * @description: 开发模式
@@ -20,25 +20,33 @@ export const prodMode = 'production';
  * @returns:
  * @example:
  */
-export const getEnv = (): string => import.meta.env.MODE;
+export function getEnv(): string {
+  return import.meta.env.MODE;
+}
 
 /**
  * @description: 是否是开发模式
  * @returns:
  * @example:
  */
-export const isDevMode = (): boolean => import.meta.env.DEV;
+export function isDevMode(): boolean {
+  return import.meta.env.DEV;
+}
 
 /**
  * @description: 是否是生产模式模式
  * @returns:
  * @example:
  */
-export const isProdMode = (): boolean => import.meta.env.PROD;
+export function isProdMode(): boolean {
+  return import.meta.env.PROD;
+}
 
 /**
  * @description: 是否开启mock
  * @returns:
  * @example:
  */
-export const isUseMock = (): boolean => import.meta.env.VITE_USE_MOCK === 'true';
+export function isUseMock(): boolean {
+  return import.meta.env.VITE_USE_MOCK === 'true';
+}

+ 6 - 6
src/utils/event/resizeEvent.ts

@@ -3,7 +3,7 @@ import ResizeObserver from 'resize-observer-polyfill';
 const isServer = typeof window === 'undefined';
 
 /* istanbul ignore next */
-const resizeHandler = function (entries: any[]) {
+function resizeHandler(entries: any[]) {
   for (const entry of entries) {
     const listeners = entry.target.__resizeListeners__ || [];
     if (listeners.length) {
@@ -12,10 +12,10 @@ const resizeHandler = function (entries: any[]) {
       });
     }
   }
-};
+}
 
 /* istanbul ignore next */
-export const addResizeListener = function (element: any, fn: () => any) {
+export function addResizeListener(element: any, fn: () => any) {
   if (isServer) return;
   if (!element.__resizeListeners__) {
     element.__resizeListeners__ = [];
@@ -23,13 +23,13 @@ export const addResizeListener = function (element: any, fn: () => any) {
     element.__ro__.observe(element);
   }
   element.__resizeListeners__.push(fn);
-};
+}
 
 /* istanbul ignore next */
-export const removeResizeListener = function (element: any, fn: () => any) {
+export function removeResizeListener(element: any, fn: () => any) {
   if (!element || !element.__resizeListeners__) return;
   element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
   if (!element.__resizeListeners__.length) {
     element.__ro__.disconnect();
   }
-};
+}

+ 1 - 1
src/utils/event/triggerWindowResizeEvent.ts

@@ -4,6 +4,6 @@
 export function triggerWindowResize() {
   const event = document.createEvent('HTMLEvents');
   event.initEvent('resize', true, true);
-  (event as ChangeEvent).eventType = 'message';
+  (event as any).eventType = 'message';
   window.dispatchEvent(event);
 }

+ 2 - 2
src/utils/helper/envHelper.ts

@@ -4,6 +4,6 @@ import pkg from '../../../package.json';
 const globSetting = useGlobSetting();
 
 // Generate cache key according to version
-export const getStorageShortName = () => {
+export function getStorageShortName() {
   return `${globSetting.shortName}__${getEnv()}${`__${pkg.version}`}__`.toUpperCase();
-};
+}

+ 14 - 0
src/utils/index.ts

@@ -85,3 +85,17 @@ export function getDynamicProps<T, U>(props: T): Partial<U> {
 
   return ret as Partial<U>;
 }
+
+export function getLastItem<T extends any>(list: T) {
+  if (Array.isArray(list)) {
+    return list.slice(-1)[0];
+  }
+
+  if (list instanceof Set) {
+    return Array.from(list).slice(-1)[0];
+  }
+
+  if (list instanceof Map) {
+    return Array.from(list.values()).slice(-1)[0];
+  }
+}

+ 35 - 17
src/utils/is.ts

@@ -4,17 +4,33 @@ export function is(val: unknown, type: string) {
   return toString.call(val) === `[object ${type}]`;
 }
 
-export const isDef = <T = unknown>(val?: T): val is T => {
+export function isDef<T = unknown>(val?: T): val is T {
   return typeof val !== 'undefined';
-};
+}
 
-export const isUnDef = <T = unknown>(val?: T): val is T => {
+export function isUnDef<T = unknown>(val?: T): val is T {
   return !isDef(val);
-};
+}
 
-export const isObject = (val: any): val is Record<any, any> => {
+export function isObject(val: any): val is Record<any, any> {
   return val !== null && is(val, 'Object');
-};
+}
+
+export function isEmpty<T = unknown>(val: T): val is T {
+  if (isArray(val) || isString(val)) {
+    return val.length === 0;
+  }
+
+  if (val instanceof Map || val instanceof Set) {
+    return val.size === 0;
+  }
+
+  if (isObject(val)) {
+    return Object.keys(val).length === 0;
+  }
+
+  return false;
+}
 
 export function isDate(val: unknown): val is Date {
   return is(val, 'Date');
@@ -40,7 +56,9 @@ export function isString(val: unknown): val is string {
   return is(val, 'String');
 }
 
-export const isFunction = (val: unknown): val is Function => typeof val === 'function';
+export function isFunction(val: unknown): val is Function {
+  return typeof val === 'function';
+}
 
 export function isBoolean(val: unknown): val is boolean {
   return is(val, 'Boolean');
@@ -54,13 +72,13 @@ export function isArray(val: any): val is Array<any> {
   return val && Array.isArray(val);
 }
 
-export const isWindow = (val: any): val is Window => {
+export function isWindow(val: any): val is Window {
   return typeof window !== 'undefined' && is(val, 'Window');
-};
+}
 
-export const isElement = (val: unknown): val is Element => {
+export function isElement(val: unknown): val is Element {
   return isObject(val) && !!val.tagName;
-};
+}
 
 export const isServer = typeof window === 'undefined';
 
@@ -70,17 +88,17 @@ export function isImageDom(o: Element) {
   return o && ['IMAGE', 'IMG'].includes(o.tagName);
 }
 
-export const isTextarea = (element: Element | null): element is HTMLTextAreaElement => {
+export function isTextarea(element: Element | null): element is HTMLTextAreaElement {
   return element !== null && element.tagName.toLowerCase() === 'textarea';
-};
+}
 
-export const isMobile = (): boolean => {
+export function isMobile(): boolean {
   return !!navigator.userAgent.match(
     /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
   );
-};
+}
 
-export const isUrl = (path: string): boolean => {
+export function isUrl(path: string): boolean {
   const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
   return reg.test(path);
-};
+}

+ 0 - 30
src/utils/scrollbarWidth.ts

@@ -1,30 +0,0 @@
-import { isWindow } from '/@/utils/is';
-
-let scrollBarWidth: number;
-
-export default function (): number {
-  if (!isWindow) return 0;
-  if (scrollBarWidth !== undefined) return scrollBarWidth;
-
-  const outer = document.createElement('div');
-  outer.className = 'scrollbar__wrap';
-  outer.style.visibility = 'hidden';
-  outer.style.width = '100px';
-  outer.style.position = 'absolute';
-  outer.style.top = '-9999px';
-  document.body.appendChild(outer);
-
-  const widthNoScroll = outer.offsetWidth;
-  outer.style.overflow = 'scroll';
-
-  const inner = document.createElement('div');
-  inner.style.width = '100%';
-  outer.appendChild(inner);
-
-  const widthWithScroll = inner.offsetWidth;
-  const parentNode = outer.parentNode;
-  parentNode && parentNode.removeChild(outer);
-  scrollBarWidth = widthNoScroll - widthWithScroll;
-
-  return scrollBarWidth;
-}