refactor: use @ant-design/fast-color instead (#4070)
* refactor: Use @ant-design/fast-color instead * fix: test failed * chore: remove isValidColor All FastColor objects are valid. So isValid is always true. FastColor("not-a-color") -> `#000000` * refactor: rename directory `colorful` to `color` * fix: ci failpull/48/MERGE
parent
861f39b519
commit
1d38fb647e
|
@ -7,7 +7,7 @@ export default defineBuildConfig({
|
||||||
'src/index',
|
'src/index',
|
||||||
'src/constants/index',
|
'src/constants/index',
|
||||||
'src/utils/index',
|
'src/utils/index',
|
||||||
'src/colorful/index',
|
'src/color/index',
|
||||||
'src/cache/index',
|
'src/cache/index',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,10 +35,10 @@
|
||||||
"development": "./src/utils/index.ts",
|
"development": "./src/utils/index.ts",
|
||||||
"default": "./dist/utils/index.mjs"
|
"default": "./dist/utils/index.mjs"
|
||||||
},
|
},
|
||||||
"./colorful": {
|
"./color": {
|
||||||
"types": "./src/colorful/index.ts",
|
"types": "./src/color/index.ts",
|
||||||
"development": "./src/colorful/index.ts",
|
"development": "./src/color/index.ts",
|
||||||
"default": "./dist/colorful/index.mjs"
|
"default": "./dist/color/index.mjs"
|
||||||
},
|
},
|
||||||
"./cache": {
|
"./cache": {
|
||||||
"types": "./src/cache/index.ts",
|
"types": "./src/cache/index.ts",
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ctrl/tinycolor": "^4.1.0",
|
"@ant-design/fast-color": "^2.0.5",
|
||||||
"@vue/shared": "^3.4.35",
|
"@vue/shared": "^3.4.35",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"defu": "^6.1.4",
|
"defu": "^6.1.4",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import { convertToHsl, convertToHslCssVar, isValidColor } from './convert';
|
import { convertToHsl, convertToHslCssVar, convertToRgb } from './convert';
|
||||||
|
|
||||||
describe('color conversion functions', () => {
|
describe('color conversion functions', () => {
|
||||||
it('should correctly convert color to HSL format', () => {
|
it('should correctly convert color to HSL format', () => {
|
||||||
|
@ -26,16 +26,16 @@ describe('color conversion functions', () => {
|
||||||
const expectedHsl = '0 100% 50% / 0.5';
|
const expectedHsl = '0 100% 50% / 0.5';
|
||||||
expect(convertToHslCssVar(color)).toEqual(expectedHsl);
|
expect(convertToHslCssVar(color)).toEqual(expectedHsl);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('isValidColor', () => {
|
it('should correctly convert color to RGB CSS variable format', () => {
|
||||||
it('isValidColor function', () => {
|
const color = 'hsl(284, 100%, 50%)';
|
||||||
// 测试有效颜色
|
const expectedRgb = 'rgb(187,0,255)';
|
||||||
expect(isValidColor('blue')).toBe(true);
|
expect(convertToRgb(color)).toEqual(expectedRgb);
|
||||||
expect(isValidColor('#000000')).toBe(true);
|
});
|
||||||
|
|
||||||
// 测试无效颜色
|
it('should correctly convert color with alpha to RGBA CSS variable format', () => {
|
||||||
expect(isValidColor('invalid color')).toBe(false);
|
const color = 'hsla(284, 100%, 50%, 0.92)';
|
||||||
expect(isValidColor()).toBe(false);
|
const expectedRgba = 'rgba(187,0,255,0.92)';
|
||||||
|
expect(convertToRgb(color)).toEqual(expectedRgba);
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { FastColor } from '@ant-design/fast-color';
|
||||||
|
|
||||||
|
const Color = FastColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将颜色转换为HSL格式。
|
||||||
|
*
|
||||||
|
* HSL是一种颜色模型,包括色相(Hue)、饱和度(Saturation)和亮度(Lightness)三个部分。
|
||||||
|
*
|
||||||
|
* @param {string} color 输入的颜色。
|
||||||
|
* @returns {string} HSL格式的颜色字符串。
|
||||||
|
*/
|
||||||
|
function convertToHsl(color: string): string {
|
||||||
|
const { a, h, l, s } = new Color(color).toHsl();
|
||||||
|
const hsl = `hsl(${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%)`;
|
||||||
|
return a < 1 ? `${hsl} ${a}` : hsl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将颜色转换为HSL CSS变量。
|
||||||
|
*
|
||||||
|
* 这个函数与convertToHsl函数类似,但是返回的字符串格式稍有不同,
|
||||||
|
* 以便可以作为CSS变量使用。
|
||||||
|
*
|
||||||
|
* @param {string} color 输入的颜色。
|
||||||
|
* @returns {string} 可以作为CSS变量使用的HSL格式的颜色字符串。
|
||||||
|
*/
|
||||||
|
function convertToHslCssVar(color: string): string {
|
||||||
|
const { a, h, l, s } = new Color(color).toHsl();
|
||||||
|
const hsl = `${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
|
||||||
|
return a < 1 ? `${hsl} / ${a}` : hsl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToRgb(color: string): string {
|
||||||
|
return new Color(color).toRgbString();
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Color, convertToHsl, convertToHslCssVar, convertToRgb };
|
|
@ -1,7 +1,6 @@
|
||||||
import { TinyColor } from '@ctrl/tinycolor';
|
|
||||||
import { getColors } from 'theme-colors';
|
import { getColors } from 'theme-colors';
|
||||||
|
|
||||||
import { convertToHslCssVar } from './convert';
|
import { Color, convertToHslCssVar } from './convert';
|
||||||
|
|
||||||
interface ColorItem {
|
interface ColorItem {
|
||||||
alias?: string;
|
alias?: string;
|
||||||
|
@ -14,7 +13,7 @@ function generatorColorVariables(colorItems: ColorItem[]) {
|
||||||
|
|
||||||
colorItems.forEach(({ alias, color, name }) => {
|
colorItems.forEach(({ alias, color, name }) => {
|
||||||
if (color) {
|
if (color) {
|
||||||
const colorsMap = getColors(new TinyColor(color).toHexString());
|
const colorsMap = getColors(new Color(color).toHexString());
|
||||||
let mainColor = colorsMap['500'];
|
let mainColor = colorsMap['500'];
|
||||||
|
|
||||||
const colorKeys = Object.keys(colorsMap);
|
const colorKeys = Object.keys(colorsMap);
|
|
@ -1,73 +0,0 @@
|
||||||
import { TinyColor } from '@ctrl/tinycolor';
|
|
||||||
/**
|
|
||||||
* 将颜色转换为HSL格式。
|
|
||||||
*
|
|
||||||
* HSL是一种颜色模型,包括色相(Hue)、饱和度(Saturation)和亮度(Lightness)三个部分。
|
|
||||||
* 这个函数使用TinyColor库将输入的颜色转换为HSL格式,并返回一个字符串。
|
|
||||||
*
|
|
||||||
* @param {string} color 输入的颜色,可以是任何TinyColor支持的颜色格式。
|
|
||||||
* @returns {string} HSL格式的颜色字符串。
|
|
||||||
*/
|
|
||||||
function convertToHsl(color: string): string {
|
|
||||||
const { a, h, l, s } = new TinyColor(color).toHsl();
|
|
||||||
const hsl = `hsl(${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%)`;
|
|
||||||
return a < 1 ? `${hsl} ${a}` : hsl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将颜色转换为HSL CSS变量。
|
|
||||||
*
|
|
||||||
* 这个函数与convertToHsl函数类似,但是返回的字符串格式稍有不同,
|
|
||||||
* 以便可以作为CSS变量使用。
|
|
||||||
*
|
|
||||||
* @param {string} color 输入的颜色,可以是任何TinyColor支持的颜色格式。
|
|
||||||
* @returns {string} 可以作为CSS变量使用的HSL格式的颜色字符串。
|
|
||||||
*/
|
|
||||||
function convertToHslCssVar(color: string): string {
|
|
||||||
const { a, h, l, s } = new TinyColor(color).toHsl();
|
|
||||||
const hsl = `${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
|
|
||||||
return a < 1 ? `${hsl} / ${a}` : hsl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查颜色是否有效
|
|
||||||
* @param {string} color - 待检查的颜色
|
|
||||||
* 如果颜色有效返回true,否则返回false
|
|
||||||
*/
|
|
||||||
function isValidColor(color?: string) {
|
|
||||||
if (!color) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return new TinyColor(color).isValid;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 将HLS字符串转换为RGB颜色字符串
|
|
||||||
*
|
|
||||||
* 本函数接收一个表示HLS值的字符串,移除其中的度量单位,
|
|
||||||
* 并将其转换为TinyColor对象,以便进行颜色处理。
|
|
||||||
* 如果转换后的颜色无效,则直接返回原始字符串;
|
|
||||||
* 否则,返回转换后的RGB颜色字符串
|
|
||||||
*
|
|
||||||
* @param str 表示HLS颜色值的字符串,可能包含度量单位如'deg'、'grad'、'rad'或'turn'
|
|
||||||
* @returns 如果颜色值有效,则返回对应的RGB颜色字符串;如果无效,则返回原始字符串
|
|
||||||
*/
|
|
||||||
function hlsStringToRGBString(str: string): string {
|
|
||||||
// 移除HLS字符串中的度量单位,以便正确解析
|
|
||||||
const color = new TinyColor(
|
|
||||||
`hsl(${str.replaceAll(/deg|grad|rad|turn/g, '')})`,
|
|
||||||
);
|
|
||||||
// 检查颜色是否有效,如果无效则直接返回原始字符串
|
|
||||||
if (!color.isValid) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
// 返回转换后的RGB颜色字符串
|
|
||||||
return color.toRgbString();
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
convertToHsl,
|
|
||||||
convertToHslCssVar,
|
|
||||||
hlsStringToRGBString,
|
|
||||||
isValidColor,
|
|
||||||
TinyColor,
|
|
||||||
};
|
|
|
@ -1,4 +1,4 @@
|
||||||
export * from './cache';
|
export * from './cache';
|
||||||
export * from './colorful';
|
export * from './color';
|
||||||
export * from './constants';
|
export * from './constants';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { MenuRecordBadgeRaw } from '@vben-core/typings';
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
|
||||||
import { isValidColor } from '@vben-core/shared';
|
import { convertToRgb } from '@vben-core/shared';
|
||||||
|
|
||||||
import BadgeDot from './menu-badge-dot.vue';
|
import BadgeDot from './menu-badge-dot.vue';
|
||||||
|
|
||||||
|
@ -34,9 +34,9 @@ const badgeClass = computed(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const badgeStyle = computed(() => {
|
const badgeStyle = computed(() => {
|
||||||
if (badgeClass.value && isValidColor(badgeClass.value)) {
|
if (badgeClass.value) {
|
||||||
return {
|
return {
|
||||||
backgroundColor: badgeClass.value,
|
backgroundColor: convertToRgb(badgeClass.value),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { reactive, watch } from 'vue';
|
import { reactive, watch } from 'vue';
|
||||||
|
|
||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
import { hlsStringToRGBString, updateCSSVariables } from '@vben/utils';
|
import { convertToRgb, updateCSSVariables } from '@vben/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于适配各个框架的设计系统
|
* 用于适配各个框架的设计系统
|
||||||
|
@ -102,7 +102,7 @@ export function useNaiveDesignTokens() {
|
||||||
|
|
||||||
const getCssVariableValue = (variable: string, isColor: boolean = true) => {
|
const getCssVariableValue = (variable: string, isColor: boolean = true) => {
|
||||||
const value = rootStyles.getPropertyValue(variable);
|
const value = rootStyles.getPropertyValue(variable);
|
||||||
return isColor ? hlsStringToRGBString(value) : value;
|
return isColor ? convertToRgb(`hsl(${value})`) : value;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -145,8 +145,6 @@ export function useNaiveDesignTokens() {
|
||||||
commonTokens.invertedColor = getCssVariableValue('--background-deep');
|
commonTokens.invertedColor = getCssVariableValue('--background-deep');
|
||||||
|
|
||||||
commonTokens.borderRadius = getCssVariableValue('--radius', false);
|
commonTokens.borderRadius = getCssVariableValue('--radius', false);
|
||||||
|
|
||||||
// antDesignTokens.colorBgMask = getCssVariableValue('--overlay');
|
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
@ -160,7 +158,7 @@ export function useElementPlusDesignTokens() {
|
||||||
|
|
||||||
const getCssVariableValue = (variable: string, isColor: boolean = true) => {
|
const getCssVariableValue = (variable: string, isColor: boolean = true) => {
|
||||||
const value = rootStyles.getPropertyValue(variable);
|
const value = rootStyles.getPropertyValue(variable);
|
||||||
return isColor ? `hsl(${value})` : value;
|
return isColor ? convertToRgb(`hsl(${value})`) : value;
|
||||||
};
|
};
|
||||||
watch(
|
watch(
|
||||||
() => preferences.theme,
|
() => preferences.theme,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
BUILT_IN_THEME_PRESETS,
|
BUILT_IN_THEME_PRESETS,
|
||||||
type BuiltinThemePreset,
|
type BuiltinThemePreset,
|
||||||
} from '@vben/preferences';
|
} from '@vben/preferences';
|
||||||
import { convertToHsl, TinyColor } from '@vben/utils';
|
import { Color, convertToHsl } from '@vben/utils';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'PreferenceBuiltinTheme',
|
name: 'PreferenceBuiltinTheme',
|
||||||
|
@ -22,17 +22,11 @@ const modelValue = defineModel<BuiltinThemeType>({ default: 'default' });
|
||||||
const themeColorPrimary = defineModel<string>('themeColorPrimary');
|
const themeColorPrimary = defineModel<string>('themeColorPrimary');
|
||||||
|
|
||||||
const inputValue = computed(() => {
|
const inputValue = computed(() => {
|
||||||
return new TinyColor(themeColorPrimary.value).toHexString();
|
return new Color(themeColorPrimary.value || '').toHexString();
|
||||||
});
|
});
|
||||||
|
|
||||||
const builtinThemePresets = computed(() => {
|
const builtinThemePresets = computed(() => {
|
||||||
return [
|
return [...BUILT_IN_THEME_PRESETS];
|
||||||
// {
|
|
||||||
// color: 'hsl(231 98% 65%)',
|
|
||||||
// type: 'default',
|
|
||||||
// },
|
|
||||||
...BUILT_IN_THEME_PRESETS,
|
|
||||||
];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function typeView(name: BuiltinThemeType) {
|
function typeView(name: BuiltinThemeType) {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
export * from './helpers';
|
export * from './helpers';
|
||||||
export * from '@vben-core/shared/colorful';
|
export * from '@vben-core/shared/color';
|
||||||
export * from '@vben-core/shared/utils';
|
export * from '@vben-core/shared/utils';
|
||||||
|
|
1773
pnpm-lock.yaml
1773
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue