Browse Source

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 fail
pull/4072/head
Li Kui 2 years ago
committed by GitHub
parent
commit
1d38fb647e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      packages/@core/base/shared/build.config.ts
  2. 10
      packages/@core/base/shared/package.json
  3. 20
      packages/@core/base/shared/src/color/convert.test.ts
  4. 38
      packages/@core/base/shared/src/color/convert.ts
  5. 5
      packages/@core/base/shared/src/color/generator.ts
  6. 0
      packages/@core/base/shared/src/color/index.ts
  7. 73
      packages/@core/base/shared/src/colorful/convert.ts
  8. 2
      packages/@core/base/shared/src/index.ts
  9. 6
      packages/@core/ui-kit/shadcn-ui/src/components/menu-badge/menu-badge.vue
  10. 8
      packages/effects/hooks/src/use-design-tokens.ts
  11. 12
      packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue
  12. 2
      packages/utils/src/index.ts
  13. 1787
      pnpm-lock.yaml

2
packages/@core/base/shared/build.config.ts

@ -7,7 +7,7 @@ export default defineBuildConfig({
'src/index',
'src/constants/index',
'src/utils/index',
'src/colorful/index',
'src/color/index',
'src/cache/index',
],
});

10
packages/@core/base/shared/package.json

@ -35,10 +35,10 @@
"development": "./src/utils/index.ts",
"default": "./dist/utils/index.mjs"
},
"./colorful": {
"types": "./src/colorful/index.ts",
"development": "./src/colorful/index.ts",
"default": "./dist/colorful/index.mjs"
"./color": {
"types": "./src/color/index.ts",
"development": "./src/color/index.ts",
"default": "./dist/color/index.mjs"
},
"./cache": {
"types": "./src/cache/index.ts",
@ -55,7 +55,7 @@
}
},
"dependencies": {
"@ctrl/tinycolor": "^4.1.0",
"@ant-design/fast-color": "^2.0.5",
"@vue/shared": "^3.4.35",
"clsx": "^2.1.1",
"defu": "^6.1.4",

20
packages/@core/base/shared/src/colorful/convert.test.ts → packages/@core/base/shared/src/color/convert.test.ts

@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest';
import { convertToHsl, convertToHslCssVar, isValidColor } from './convert';
import { convertToHsl, convertToHslCssVar, convertToRgb } from './convert';
describe('color conversion functions', () => {
it('should correctly convert color to HSL format', () => {
@ -26,16 +26,16 @@ describe('color conversion functions', () => {
const expectedHsl = '0 100% 50% / 0.5';
expect(convertToHslCssVar(color)).toEqual(expectedHsl);
});
});
describe('isValidColor', () => {
it('isValidColor function', () => {
// 测试有效颜色
expect(isValidColor('blue')).toBe(true);
expect(isValidColor('#000000')).toBe(true);
it('should correctly convert color to RGB CSS variable format', () => {
const color = 'hsl(284, 100%, 50%)';
const expectedRgb = 'rgb(187,0,255)';
expect(convertToRgb(color)).toEqual(expectedRgb);
});
// 测试无效颜色
expect(isValidColor('invalid color')).toBe(false);
expect(isValidColor()).toBe(false);
it('should correctly convert color with alpha to RGBA CSS variable format', () => {
const color = 'hsla(284, 100%, 50%, 0.92)';
const expectedRgba = 'rgba(187,0,255,0.92)';
expect(convertToRgb(color)).toEqual(expectedRgba);
});
});

38
packages/@core/base/shared/src/color/convert.ts

@ -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 };

5
packages/@core/base/shared/src/colorful/generator.ts → packages/@core/base/shared/src/color/generator.ts

@ -1,7 +1,6 @@
import { TinyColor } from '@ctrl/tinycolor';
import { getColors } from 'theme-colors';
import { convertToHslCssVar } from './convert';
import { Color, convertToHslCssVar } from './convert';
interface ColorItem {
alias?: string;
@ -14,7 +13,7 @@ function generatorColorVariables(colorItems: ColorItem[]) {
colorItems.forEach(({ alias, color, name }) => {
if (color) {
const colorsMap = getColors(new TinyColor(color).toHexString());
const colorsMap = getColors(new Color(color).toHexString());
let mainColor = colorsMap['500'];
const colorKeys = Object.keys(colorsMap);

0
packages/@core/base/shared/src/colorful/index.ts → packages/@core/base/shared/src/color/index.ts

73
packages/@core/base/shared/src/colorful/convert.ts

@ -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 -
* truefalse
*/
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,
};

2
packages/@core/base/shared/src/index.ts

@ -1,4 +1,4 @@
export * from './cache';
export * from './colorful';
export * from './color';
export * from './constants';
export * from './utils';

6
packages/@core/ui-kit/shadcn-ui/src/components/menu-badge/menu-badge.vue

@ -3,7 +3,7 @@ import type { MenuRecordBadgeRaw } from '@vben-core/typings';
import { computed } from 'vue';
import { isValidColor } from '@vben-core/shared';
import { convertToRgb } from '@vben-core/shared';
import BadgeDot from './menu-badge-dot.vue';
@ -34,9 +34,9 @@ const badgeClass = computed(() => {
});
const badgeStyle = computed(() => {
if (badgeClass.value && isValidColor(badgeClass.value)) {
if (badgeClass.value) {
return {
backgroundColor: badgeClass.value,
backgroundColor: convertToRgb(badgeClass.value),
};
}
return {};

8
packages/effects/hooks/src/use-design-tokens.ts

@ -1,7 +1,7 @@
import { reactive, watch } from 'vue';
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 value = rootStyles.getPropertyValue(variable);
return isColor ? hlsStringToRGBString(value) : value;
return isColor ? convertToRgb(`hsl(${value})`) : value;
};
watch(
@ -145,8 +145,6 @@ export function useNaiveDesignTokens() {
commonTokens.invertedColor = getCssVariableValue('--background-deep');
commonTokens.borderRadius = getCssVariableValue('--radius', false);
// antDesignTokens.colorBgMask = getCssVariableValue('--overlay');
},
{ immediate: true },
);
@ -160,7 +158,7 @@ export function useElementPlusDesignTokens() {
const getCssVariableValue = (variable: string, isColor: boolean = true) => {
const value = rootStyles.getPropertyValue(variable);
return isColor ? `hsl(${value})` : value;
return isColor ? convertToRgb(`hsl(${value})`) : value;
};
watch(
() => preferences.theme,

12
packages/effects/layouts/src/widgets/preferences/blocks/theme/builtin.vue

@ -9,7 +9,7 @@ import {
BUILT_IN_THEME_PRESETS,
type BuiltinThemePreset,
} from '@vben/preferences';
import { convertToHsl, TinyColor } from '@vben/utils';
import { Color, convertToHsl } from '@vben/utils';
defineOptions({
name: 'PreferenceBuiltinTheme',
@ -22,17 +22,11 @@ const modelValue = defineModel<BuiltinThemeType>({ default: 'default' });
const themeColorPrimary = defineModel<string>('themeColorPrimary');
const inputValue = computed(() => {
return new TinyColor(themeColorPrimary.value).toHexString();
return new Color(themeColorPrimary.value || '').toHexString();
});
const builtinThemePresets = computed(() => {
return [
// {
// color: 'hsl(231 98% 65%)',
// type: 'default',
// },
...BUILT_IN_THEME_PRESETS,
];
return [...BUILT_IN_THEME_PRESETS];
});
function typeView(name: BuiltinThemeType) {

2
packages/utils/src/index.ts

@ -1,3 +1,3 @@
export * from './helpers';
export * from '@vben-core/shared/colorful';
export * from '@vben-core/shared/color';
export * from '@vben-core/shared/utils';

1787
pnpm-lock.yaml

File diff suppressed because it is too large
Loading…
Cancel
Save