mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 14:31:41 +08:00
fix(modal): height calc error #161
This commit is contained in:
@@ -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) {
|
||||
|
@@ -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)}`;
|
||||
};
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
};
|
||||
}
|
||||
|
@@ -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';
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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();
|
||||
};
|
||||
}
|
||||
|
@@ -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];
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
};
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user