Skip to content

Commit

Permalink
feat: remove colortranslator (#4310)
Browse files Browse the repository at this point in the history
  • Loading branch information
m0ksem committed Jul 23, 2024
1 parent 4aac12a commit e91f248
Show file tree
Hide file tree
Showing 26 changed files with 405 additions and 129 deletions.
1 change: 0 additions & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"@floating-ui/vue": "^1.0.1",
"@types/lodash": "^4.14.161",
"cleave.js": "^1.6.0",
"colortranslator": "^1.9.2",
"lodash": "^4.17.21"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-affix/VaAffix-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { throttle } from "../../utils/throttle";
import { throttle } from '../../utils/throttle'

export type State = {
isTopAffixed: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-badge/VaBadge.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
} from '../../composables'
import { useFloatingPosition, useFloatingPositionProps } from './hooks/useFloatingPositionStyles'
import { pick } from '../../utils/pick';
import { pick } from '../../utils/pick'
defineOptions({
name: 'VaBadge',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const computedButtonIcons = computed(() => {
})
const buttonPropsFiltered = computed(() => {
let ignoredProps = ['to', 'href', 'loading', 'icon'] as const
const ignoredProps = ['to', 'href', 'loading', 'icon'] as const
const presetProps = [
'plain',
'textOpacity', 'backgroundOpacity',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-card/VaCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
useRouterLink,
useRouterLinkProps,
} from '../../composables'
import { pick } from '../../utils/pick';
import { pick } from '../../utils/pick'
defineOptions({
name: 'VaCard',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<script lang="ts" setup>
import { useBem, useComponentPresetProp, useAlignProps, useAlign } from '../../../../composables'
import { pick } from '../../../../utils/pick';
import { pick } from '../../../../utils/pick'
defineOptions({
name: 'VaCardActions',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-chip/VaChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import {
} from '../../composables'
import { VaIcon } from '../va-icon'
import { pick } from '../../utils/pick';
import { pick } from '../../utils/pick'
defineOptions({
name: 'VaChip',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-icon/VaIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
useSize, useSizeProps,
useIcon,
} from '../../composables'
import { omit } from '../../utils/omit';
import { omit } from '../../utils/omit'
defineOptions({
name: 'VaIcon',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

<script lang="ts" setup>
import { computed, ComputedRef, PropType, ref, shallowRef, watch } from 'vue'
import { debounce } from '../../utils/debounce'
import { debounce as debounceFn } from '../../utils/debounce'
import { sleep } from '../../utils/sleep'
import { useColors, useComponentPresetProp, useNumericProp } from '../../composables'
Expand Down Expand Up @@ -190,7 +190,7 @@ const onError = () => {
}
watch(() => debounceComputed.value, (value) => {
debouncedLoad.value = debounce(onLoad, value)
debouncedLoad.value = debounceFn(onLoad, value)
}, { immediate: true })
watch(() => props.disabled, (value) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-input/VaInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ const computedChildAttributes = computed(() => (({
const computedInputAttributes = computed(() => (({
...computedChildAttributes.value,
...pick(props, ['type', 'disabled', 'readonly', 'placeholder', 'pattern', 'inputmode', 'name']),
...pick(attrs, ['minlength', 'minlength'])
...pick(attrs, ['minlength', 'minlength']),
}) as InputHTMLAttributes))
const valueLengthComputed = computed(() =>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/va-list/VaListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
useComponentPresetProp,
useRouterLink, useRouterLinkProps,
} from '../../composables'
import { pick } from '../../utils/pick';
import { pick } from '../../utils/pick'
defineOptions({
name: 'VaListItem',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<script lang="ts" setup>
import { useComponentPresetProp } from '../../composables/useComponentPreset'
import { computed, PropType, StyleValue } from 'vue'
import { clamp } from '../../utils/clamp';
import { clamp } from '../../utils/clamp'
import { useColors, useTextColor, useTranslation, useTranslationProp } from '../../composables'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { ref, computed, watch, PropType, ComputedRef } from 'vue'
import { useEvent, useBem, useTrackBy, useTrackByProps, useNumericProp } from '../../composables'
import { useVirtualScrollerSizes, useVirtualScrollerSizesProps } from './useVirtualScrollerSizes'
import { pick } from '../../utils/pick';
import { pick } from '../../utils/pick'
defineOptions({
name: 'VaVirtualScroller',
Expand Down
13 changes: 3 additions & 10 deletions packages/ui/src/services/color/tests/color-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ describe('useColors', () => {
['rgb(0, 0, 0)', 'rgba(0,0,0,0.4)'],
['rgba(0, 0, 0, 1)', 'rgba(0,0,0,0.4)'],
[{ h: 0, s: 0, l: 0 }, 'rgba(0,0,0,0.4)'],
[{ c: 0, m: 0, y: 0, k: 0 }, 'rgba(255,255,255,0.4)'],
])(
'getBoxShadowColorArg %s should return %s',
(getBoxShadowColorArg, expected) => {
Expand All @@ -94,7 +93,6 @@ describe('useColors', () => {
['rgb(0, 0, 0)', 'rgba(0,0,0,0.2)'],
['rgba(0, 0, 0, 1)', 'rgba(0,0,0,0.2)'],
[{ h: 0, s: 0, l: 0 }, 'rgba(0,0,0,0.2)'],
[{ c: 0, m: 0, y: 0, k: 0 }, 'rgba(255,255,255,0.2)'],
])(
'getHoverColor %s should return %s',
(getHoverColorArg, expected) => {
Expand All @@ -107,7 +105,6 @@ describe('useColors', () => {
['rgb(0, 0, 0)', 'rgba(0,0,0,0.3)'],
['rgba(0, 0, 0, 1)', 'rgba(0,0,0,0.3)'],
[{ h: 0, s: 0, l: 0 }, 'rgba(0,0,0,0.3)'],
[{ c: 0, m: 0, y: 0, k: 0 }, 'rgba(255,255,255,0.3)'],
])(
'getFocusColorArg %s should return %s',
(getFocusColorArg, expected) => {
Expand All @@ -116,11 +113,10 @@ describe('useColors', () => {
)

it.each([
['#000000', 'linear-gradient(to right, hsla(2,5%,10%,1), hsla(0,0%,0%,1))'],
['rgb(0, 0, 0)', 'linear-gradient(to right, hsla(2,5%,10%,1), hsla(0,0%,0%,1))'],
['rgba(0, 0, 0, 1)', 'linear-gradient(to right, hsla(2,5%,10%,1), hsla(0,0%,0%,1))'],
['#000000', 'linear-gradient(to right, hsla(2,5%,10%,1), #000000)'],
['rgb(0, 0, 0)', 'linear-gradient(to right, hsla(2,5%,10%,1), rgb(0, 0, 0))'],
['rgba(0, 0, 0, 1)', 'linear-gradient(to right, hsla(2,5%,10%,1), rgba(0, 0, 0, 1))'],
[{ h: 0, s: 0, l: 0 }, 'linear-gradient(to right, hsla(2,5%,10%,1), hsla(0,0%,0%,1))'],
[{ c: 0, m: 0, y: 0, k: 0 }, 'linear-gradient(to right, hsla(2,5%,100%,1), hsla(0,0%,100%,1))'],
])(
'getGradientBackgroundArg %s should return %s',
(getGradientBackgroundArg, expected) => {
Expand All @@ -132,7 +128,6 @@ describe('useColors', () => {
[['#000000', '#cccccc', '#ffffff'], '#ffffff'],
[['rgb(255, 255, 255)'], 'textPrimary'],
[[{ h: 0, s: 100, l: 27 }], 'textInverted'],
[[{ c: 0, m: 0, y: 0, k: 0 }], 'textPrimary'],
])(
'getTextColorArgs %s should return %s',
(getTextColorArgs, expected) => {
Expand All @@ -144,7 +139,6 @@ describe('useColors', () => {
[['#000000', {}], 'hsla(0,0%,0%,1)'],
[['rgb(255, 255, 255)', { h: 1, s: 2 }], 'hsla(1,2%,100%,1)'],
[[{ h: 0, s: 100, l: 27 }, { h: 1, s: 2, l: 3, a: 4 }], 'hsla(1,100%,30%,1)'],
[[{ c: 0, m: 0, y: 0, k: 0 }, { l: 3 }], 'hsla(0,0%,100%,1)'],
])(
'shiftHSLAColorArgs %s should return %s',
(shiftHSLAColorArgs, expected) => {
Expand All @@ -156,7 +150,6 @@ describe('useColors', () => {
[['#000000', {}], 'hsla(0,0%,0%,1)'],
[['rgb(255, 255, 255)', { h: 1, s: 2 }], 'hsla(1,2%,100%,1)'],
[[{ h: 0, s: 100, l: 27 }, { h: 1, s: 2, l: 3, a: 4 }], 'hsla(1,2%,3%,1)'],
[[{ c: 0, m: 0, y: 0, k: 0 }, { l: 3 }], 'hsla(0,0%,3%,1)'],
])(
'setHSLAColorArgs %s should return %s',
(setHSLAColorArgs, expected) => {
Expand Down
126 changes: 44 additions & 82 deletions packages/ui/src/services/color/utils.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,46 @@
import { camelCaseToKebabCase, kebabCaseToCamelCase } from '../../utils/text-case'
import { ColorTranslator } from 'colortranslator'
import type { HSLObject, HEXObject, RGBObject } from 'colortranslator'
import { warn } from 'vue'

export type ColorInput = string | HEXObject | HSLObject | RGBObject

const makeColor = (color: ColorInput) => {
try {
return new ColorTranslator(color)
} catch (e) {
throw new Error(`Color ${color} is not valid. Please, provide valid color.`, {
cause: e,
})
}
}

import { setHSLA, shiftHSLA, parseColorToRGB, parseColorToHSL, rgbToString, hslToString, colorToString, type RGBObject, type HSLObject } from '../../utils/color'

export const isCSSVariable = (strColor: string): boolean => /var\(--.+\)/.test(strColor)
export const cssVariableName = (colorName: string) => `--va-${camelCaseToKebabCase(colorName)}`
export const normalizeColorName = (colorName: string) => kebabCaseToCamelCase(colorName)

export const colorToRgba = (color: ColorInput, opacity: number) => {
return makeColor(color).setA(opacity).RGBA
export type ColorInput = string | RGBObject | HSLObject

export const colorToRgba = (color: string, opacity: number) => {
const { r, g, b } = parseColorToRGB(color)

return rgbToString({ r, g, b, a: opacity })
}

export const getColorLightness = (color: ColorInput) => {
const { R, G, B } = makeColor(color)
return Math.sqrt(R * R * 0.241 + G * G * 0.691 + B * B * 0.068)
const { r, g, b } = parseColorToRGB(color)
return Math.sqrt(r * r * 0.241 + g * g * 0.691 + b * b * 0.068)
}

export const getBoxShadowColor = (color: ColorInput, opacity = 0.4) => {
return makeColor(color).setA(opacity).RGBA
export const getBoxShadowColor = (color: string, opacity = 0.4) => {
return colorToRgba(color, opacity)
}

export const getBoxShadowColorFromBg = (background: ColorInput, opacity = 0.4) => {
return makeColor(background).setA(opacity).RGBA
export const getBoxShadowColorFromBg = (background: string, opacity = 0.4) => {
return colorToRgba(background, opacity)
}

export const getHoverColor = (color: ColorInput, opacity = 0.2) => {
return makeColor(color).setA(opacity).RGBA
export const getHoverColor = (color: string, opacity = 0.2) => {
return colorToRgba(color, opacity)
}

export const getFocusColor = (color: ColorInput, opacity = 0.3) => {
return makeColor(color).setA(opacity).RGBA
export const getFocusColor = (color: string, opacity = 0.3) => {
return colorToRgba(color, opacity)
}

export const shiftHSLAColor = (color: ColorInput, offset: { h?: number; s?: number; l?: number; a?: number }) => {
const result = makeColor(color)

if (offset.h) { result.setH(result.H + offset.h) }

if (offset.s) { result.setS(result.S + offset.s) }

if (offset.l) { result.setL(result.L + offset.l) }

if (offset.a) { result.setA(result.A + offset.a) }

return result.HSLA
export const shiftHSLAColor = (color: string | RGBObject | HSLObject, shift: { h?: number; s?: number; l?: number; a?: number }) => {
return hslToString(shiftHSLA(parseColorToHSL(color), shift))
}

export const setHSLAColor = (color: ColorInput, newColor: { h?: number; s?: number; l?: number; a?: number }) => {
const result = makeColor(color)

if (newColor.h !== undefined) { result.setH(newColor.h) }

if (newColor.s !== undefined) { result.setS(newColor.s) }

if (newColor.l !== undefined) { result.setL(newColor.l) }

if (newColor.a !== undefined) { result.setA(newColor.a) }

return result.HSLA
export const setHSLAColor = (color: string | RGBObject | HSLObject, shift: { h?: number; s?: number; l?: number; a?: number }) => {
return hslToString(setHSLA(parseColorToHSL(color), shift))
}

/**
Expand All @@ -79,8 +50,8 @@ export const setHSLAColor = (color: ColorInput, newColor: { h?: number; s?: numb
*
* @param color
*/
export const shiftGradientColor = (color: ColorInput): string => {
const newColor = ColorTranslator.toHSLA(color, false) as HSLObject
export const shiftGradientColor = (color: string): string => {
const newColor = parseColorToHSL(color)

// Gray
if (newColor.s < 10) {
Expand Down Expand Up @@ -113,9 +84,8 @@ export const shiftGradientColor = (color: ColorInput): string => {

export const getGradientBackground = (color: string) => {
const colorLeft = shiftGradientColor(color)
const colorRight = ColorTranslator.toHSLA(color)

return `linear-gradient(to right, ${colorLeft}, ${colorRight})`
return `linear-gradient(to right, ${colorLeft}, ${colorToString(color)})`
}

export const getStateMaskGradientBackground = (color: string, maskColor: string, maskOpacity: number) => {
Expand All @@ -124,38 +94,30 @@ export const getStateMaskGradientBackground = (color: string, maskColor: string,
return `linear-gradient(0deg, ${mask}, ${mask}), ${color}`
}

/**
* Check if color is valid hsl, hsla, rga, rgba or hex color
* Taken from https://www.regextester.com/103656
* Check options <or> isCSSVariable(prop) <or> CSS.supports('color', prop) deleted due to problems with SSR and opacity
* Details are in the discussion: https://github.com/epicmaxco/vuestic-ui/pull/1589
* @param strColor
*/
export const isColor = (strColor: string): boolean => {
// Need to use Regex instead of DOM methods because we support SSR
const cssColorRegex = /^#([\da-f]{3}){1,2}$|^#([\da-f]{4}){1,2}$|(rgb|hsl)a?\((\s*-?\d+%?\s*,){2}(\s*-?\d+%?\s*,?\s*\)?)(,\s*(0?\.\d+)?|1)?\)/

return cssColorRegex.test(strColor.toLocaleLowerCase())
}

export const applyColors = (color1: ColorInput, color2: ColorInput) => {
const c1 = makeColor(color1)
const c2 = makeColor(color2)
const weight = c2.A

if (weight === 1) { return c2.RGBA }
if (weight === 0) { return c1.RGBA }
export const applyColors = (color1: string, color2: string) => {
const c1 = parseColorToRGB(color1)
const c2 = parseColorToRGB(color2)
const weight = c2.a

c1.setR(Math.round((c1.R) * (1 - weight) + (c2.R) * weight))
c1.setG(Math.round((c1.G) * (1 - weight) + (c2.G) * weight))
c1.setB(Math.round((c1.B) * (1 - weight) + (c2.B) * weight))
if (weight === 1) { return rgbToString(c2) }
if (weight === 0) { return rgbToString(c1) }

return c1.RGBA
return rgbToString({
r: Math.round((c1.r) * (1 - weight) + (c2.r) * weight),
g: Math.round((c1.g) * (1 - weight) + (c2.g) * weight),
b: Math.round((c1.b) * (1 - weight) + (c2.b) * weight),
a: c1.a,
})
}

export const isColorTransparent = (color: ColorInput) => {
/**
* Returns `true` if color is FULLY transparent
*/
export const isColorTransparent = (color: string) => {
if (!color) { return false }
if (color === 'transparent') { return true }

return makeColor(color).A <= 0.1
return parseColorToRGB(color).a <= 0.1
}

export { isColor } from './../../utils/color'
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { camelCaseToKebabCase } from './../../utils/text-case';
import { camelCaseToKebabCase } from './../../utils/text-case'
import { defineCustomElement } from 'vue'
import { type VuesticComponent } from '../vue-plugin/types/index'

Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/utils/clone-deep.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { mergeDeep } from "./merge-deep"
import { mergeDeep } from './merge-deep'

// Notice: structureClone can not copy DOM nodes and functions.
/** Deeply merge object into new object, cloning DOM nodes and functions */
Expand All @@ -7,5 +7,5 @@ export const cloneDeep = <T>(value: T) => {
return value
}

return mergeDeep({}, value)
return mergeDeep({}, value) as T
}
Loading

0 comments on commit e91f248

Please sign in to comment.