create transparentifyColor function
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
import {jest} from '@jest/globals'
|
||||||
|
|
||||||
|
import {logger} from '#/logger'
|
||||||
|
import {transparentifyColor} from '../colorGeneration'
|
||||||
|
|
||||||
|
jest.mock('#/logger', () => ({
|
||||||
|
logger: {warn: jest.fn()},
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('transparentifyColor', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('converts hsl() to hsla()', () => {
|
||||||
|
const result = transparentifyColor('hsl(120 100% 50%)', 0.5)
|
||||||
|
expect(result).toBe('hsla(120 100% 50%, 0.5)')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('converts hsl() to hsla() - fully transparent', () => {
|
||||||
|
const result = transparentifyColor('hsl(120 100% 50%)', 0)
|
||||||
|
expect(result).toBe('hsla(120 100% 50%, 0)')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('converts rgb() to rgba()', () => {
|
||||||
|
const result = transparentifyColor('rgb(255 0 0)', 0.75)
|
||||||
|
expect(result).toBe('rgba(255 0 0, 0.75)')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('expands 3-digit hex and appends alpha channel', () => {
|
||||||
|
const result = transparentifyColor('#abc', 0.4)
|
||||||
|
expect(result).toBe('#aabbcc66')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('appends alpha to 6-digit hex', () => {
|
||||||
|
const result = transparentifyColor('#aabbcc', 0.4)
|
||||||
|
expect(result).toBe('#aabbcc66')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns the original string and warns for unsupported formats', () => {
|
||||||
|
const unsupported = 'blue'
|
||||||
|
const result = transparentifyColor(unsupported, 0.5)
|
||||||
|
expect(result).toBe(unsupported)
|
||||||
|
expect(logger.warn).toHaveBeenCalledWith(
|
||||||
|
`Could not make '${unsupported}' transparent`,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import {logger} from '#/logger'
|
||||||
|
|
||||||
export const BLUE_HUE = 211
|
export const BLUE_HUE = 211
|
||||||
export const RED_HUE = 346
|
export const RED_HUE = 346
|
||||||
export const GREEN_HUE = 152
|
export const GREEN_HUE = 152
|
||||||
@@ -19,3 +21,29 @@ export function generateScale(start: number, end: number) {
|
|||||||
export const defaultScale = generateScale(6, 100)
|
export const defaultScale = generateScale(6, 100)
|
||||||
// dim shifted 6% lighter
|
// dim shifted 6% lighter
|
||||||
export const dimScale = generateScale(12, 100)
|
export const dimScale = generateScale(12, 100)
|
||||||
|
|
||||||
|
export function transparentifyColor(color: string, alpha: number) {
|
||||||
|
if (color.startsWith('hsl(')) {
|
||||||
|
return 'hsla(' + color.slice('hsl('.length, -1) + `, ${alpha})`
|
||||||
|
} else if (color.startsWith('rgb(')) {
|
||||||
|
return 'rgba(' + color.slice('rgb('.length, -1) + `, ${alpha})`
|
||||||
|
} else if (color.startsWith('#')) {
|
||||||
|
if (color.length === 7) {
|
||||||
|
const alphaHex = Math.round(alpha * 255).toString(16)
|
||||||
|
// Per MDN: If there is only one number, it is duplicated: e means ee
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
|
||||||
|
return color.slice(0, 7) + alphaHex.padStart(2, alphaHex)
|
||||||
|
} else if (color.length === 4) {
|
||||||
|
// convert to 6-digit hex before adding alpha
|
||||||
|
const [r, g, b] = color.slice(1).split('')
|
||||||
|
const alphaHex = Math.round(alpha * 255).toString(16)
|
||||||
|
return `#${r.repeat(2)}${g.repeat(2)}${b.repeat(2)}${alphaHex.padStart(
|
||||||
|
2,
|
||||||
|
alphaHex,
|
||||||
|
)}`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn(`Could not make '${color}' transparent`)
|
||||||
|
}
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {useProfileQuery} from '#/state/queries/profile'
|
|||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {atoms as a, ios, native, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, ios, native, useBreakpoints, useTheme} from '#/alf'
|
||||||
|
import {transparentifyColor} from '#/alf/util/colorGeneration'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
@@ -47,12 +48,11 @@ export function PostThreadComposePrompt({
|
|||||||
]}>
|
]}>
|
||||||
{!gtMobile && (
|
{!gtMobile && (
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
|
key={t.name} // android does not update when you change the colors. sigh.
|
||||||
start={[0.5, 0]}
|
start={[0.5, 0]}
|
||||||
end={[0.5, 1]}
|
end={[0.5, 1]}
|
||||||
colors={[
|
colors={[
|
||||||
// "white transparent" - the CSS transparent keyword
|
transparentifyColor(t.atoms.bg.backgroundColor, 0),
|
||||||
// is black transparent
|
|
||||||
'rgba(255, 255, 255, 0)',
|
|
||||||
t.atoms.bg.backgroundColor,
|
t.atoms.bg.backgroundColor,
|
||||||
]}
|
]}
|
||||||
locations={[0.15, 0.4]}
|
locations={[0.15, 0.4]}
|
||||||
|
|||||||
Reference in New Issue
Block a user