Skip to content

Commit

Permalink
feat(typings): type of colors object being more specific (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
marceloadsj committed Jan 18, 2021
1 parent c2b5a6b commit 379e54d
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 16 deletions.
71 changes: 71 additions & 0 deletions packages/system/src/theme.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { generateHexAlphaVariants } from './theme'

describe('#theme', () => {
describe('#generateHexAlphaVariants', () => {
it('generates colors with default alpha', () => {
const colors = generateHexAlphaVariants({
white: '#ffffff',

'blue-gray-500': '#64748b',
})

expect(colors).toEqual({
white: '#ffffff',
'white-a0': '#ffffff0',
'white-a5': '#ffffffd',
'white-a10': '#ffffff1a',
'white-a20': '#ffffff33',
'white-a25': '#ffffff40',
'white-a30': '#ffffff4d',
'white-a40': '#ffffff66',
'white-a50': '#ffffff80',
'white-a60': '#ffffff99',
'white-a70': '#ffffffb3',
'white-a75': '#ffffffbf',
'white-a80': '#ffffffcc',
'white-a90': '#ffffffe6',
'white-a95': '#fffffff2',
'white-a100': '#ffffffff',

'blue-gray-500': '#64748b',
'blue-gray-500-a0': '#64748b0',
'blue-gray-500-a5': '#64748bd',
'blue-gray-500-a10': '#64748b1a',
'blue-gray-500-a20': '#64748b33',
'blue-gray-500-a25': '#64748b40',
'blue-gray-500-a30': '#64748b4d',
'blue-gray-500-a40': '#64748b66',
'blue-gray-500-a50': '#64748b80',
'blue-gray-500-a60': '#64748b99',
'blue-gray-500-a70': '#64748bb3',
'blue-gray-500-a75': '#64748bbf',
'blue-gray-500-a80': '#64748bcc',
'blue-gray-500-a90': '#64748be6',
'blue-gray-500-a95': '#64748bf2',
'blue-gray-500-a100': '#64748bff',
})
})

it('generates colors with custom alpha', () => {
const colors = generateHexAlphaVariants(
{
white: '#ffffff',
'blue-gray-500': '#64748b',
},
[1, 2, 3],
)

expect(colors).toEqual({
white: '#ffffff',
'white-a1': '#ffffff3',
'white-a2': '#ffffff5',
'white-a3': '#ffffff8',

'blue-gray-500': '#64748b',
'blue-gray-500-a1': '#64748b3',
'blue-gray-500-a2': '#64748b5',
'blue-gray-500-a3': '#64748b8',
})
})
})
})
59 changes: 43 additions & 16 deletions packages/system/src/theme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { IProps } from './types'
import { th } from './th'

type ColorsGuard = Record<string, string>
type AlphaVariants = number[]

const defaultAlphaVariants = [
0,
5,
Expand All @@ -17,29 +20,53 @@ const defaultAlphaVariants = [
90,
95,
100,
]
] as const

type DefaultAlphaVariants = typeof defaultAlphaVariants

function generateAlphaVariants<T>(
colors: Record<string, T>,
transform: (value: T, key: string, variant: number) => T = (x) => x,
variants: number[] = defaultAlphaVariants,
): Record<string, T> {
return Object.keys(colors).reduce(
(obj, key) => {
variants.forEach((i) => {
function generateAlphaVariants<
T extends ColorsGuard,
U extends AlphaVariants | DefaultAlphaVariants = DefaultAlphaVariants
>(
colors: T,
transform: (value: string, key: string, variant: number) => string = (x) => x,
variants: U = defaultAlphaVariants as U,
) {
const alphaColors = Object.keys(colors).reduce(
(obj, key: string) => {
variants.forEach((i: number) => {
obj[`${key}-a${i}`] = transform(colors[key], key, i)
})

return obj
},
{ ...colors },

{ ...colors } as ColorsGuard,
)

type ColorKeys = keyof T

type Colors = {
[key in ColorKeys]: string
}

type AlphaVariantKeys = `${Extract<
ColorKeys,
string
>}-a${typeof variants[number]}`

type AlphaVariants = {
[key in AlphaVariantKeys]: string
}

return alphaColors as Colors & AlphaVariants
}

export function generateHexAlphaVariants(
colors: Record<string, string>,
variants: number[] = defaultAlphaVariants,
): Record<string, string> {
return generateAlphaVariants<string>(
export function generateHexAlphaVariants<
T extends ColorsGuard,
U extends AlphaVariants | DefaultAlphaVariants = DefaultAlphaVariants
>(colors: T, variants: U = defaultAlphaVariants as U) {
return generateAlphaVariants(
colors,
(value, _, variant) =>
`${value}${Math.round((variant / 100) * 255).toString(16)}`,
Expand All @@ -53,7 +80,7 @@ export function aliasColor(
alias: string,
color: string,
tones: number[] = defaultTones,
variants: number[] = defaultAlphaVariants,
variants: number[] = (defaultAlphaVariants as unknown) as number[],
): Record<string, (props: IProps) => unknown> {
return tones.reduce((obj, tone) => {
obj[`${alias}-${tone}`] = th.color(`${color}-${tone}`)
Expand Down

0 comments on commit 379e54d

Please sign in to comment.