这是基于vue-vben-admin 模板适用于abp Vnext的前端管理项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

119 lines
3.3 KiB

import color from "color";
import { themeTokens } from "../theme/type";
/**
* @example
* const rgb = rgbAlpha("#000000", 0.24);
* console.log(rgb); // "rgba(0, 0, 0, 0.24)"
*
* const rgb = rgbAlpha("var(--colors-palette-primary-main)", 0.24);
* console.log(rgb); // "rgba(var(--colors-palette-primary-main), 0.24)"
*
* const rgb = rgbAlpha("rgb(var(--colors-palette-primary-main))", 0.24);
* console.log(rgb); // "rgba(rgb(var(--colors-palette-primary-main)), 0.24)"
*
* const rgb = rgbAlpha([200, 250, 214], 0.24);
* console.log(rgb); // "rgba(200, 250, 214, 0.24)"
*/
export function rgbAlpha(color: string | string[] | number[], alpha: number): string {
// ensure alpha value is between 0-1
const safeAlpha = Math.max(0, Math.min(1, alpha));
// if color is CSS variable
if (typeof color === "string") {
if (color.startsWith("#")) {
return `rgba(${hexToRgbChannel(color)}, ${safeAlpha})`;
}
if (color.includes("var(")) {
return `rgba(${color}, ${safeAlpha})`;
}
if (color.startsWith("--")) {
return `rgba(var(${color}), ${safeAlpha})`;
}
// handle "200, 250, 214" or "200 250 214" format
if (color.includes(",") || color.includes(" ")) {
const rgb = color.split(/[,\s]+/).map((n) => n.trim());
return `rgba(${rgb.join(", ")}, ${safeAlpha})`;
}
}
// handle array format [200, 250, 214]
if (Array.isArray(color)) {
return `rgba(${color.join(", ")}, ${safeAlpha})`;
}
throw new Error("Invalid color format");
}
/**
* @example
* const rgbChannel = hexToRgbChannel("#000000");
* console.log(rgbChannel); // "0, 0, 0"
*/
export const hexToRgbChannel = (hex: string) => {
const rgb = color(hex).rgb().array();
return rgb.join(",");
};
/**
* convert to CSS vars
* @param propertyPath example: `colors.palette.primary`
* @returns example: `--colors-palette-primary`
*/
export const toCssVar = (propertyPath: string) => {
return `--${propertyPath.split(".").join("-")}`;
};
/**
* convert to CSS vars
* @param propertyPath example: `colors.palette.primary`
* @returns
* ```js
* {
* lighter: "var(--colors-palette-primary-lighter)",
* light: "var(--colors-palette-primary-light)",
* main: "rgb(var(--colors-palette-primary-main))",
* dark: "rgb(var(--colors-palette-primary-dark))",
* darker: "rgb(var(--colors-palette-primary-darker))"
* }
* ```
*/
export const toCssVars = (propertyPath: string) => {
const variants = getThemeTokenVariants(propertyPath);
const result = variants.reduce(
(acc, variant) => {
const variantKey = variant === "default" ? "DEFAULT" : variant;
acc[variantKey] = `var(${toCssVar(`${propertyPath}-${variant}`)})`;
return acc;
},
{} as Record<string, string>,
);
return result;
};
/**
* get variants in {@link themeTokens}
* @param propertyPath example: `colors.palette.primary`
* @returns example: `["lighter", "light", "main", "dark", "darker"]`
*/
export const getThemeTokenVariants = (propertyPath: string) => {
const keys = propertyPath.split(".");
const val = keys.reduce((obj: any, key) => {
if (obj && typeof obj === "object") {
return obj[key];
}
return;
}, themeTokens);
return val ? Object.keys(val) : [];
};
/**
* remove px unit
* @param value example: "16px"
* @returns example: 16
*/
export const removePx = (value: string) => {
return Number(value.replace("px", ""));
};