Skip to content

Commit 379e54d

Browse files
authored
feat(typings): type of colors object being more specific (#174)
1 parent c2b5a6b commit 379e54d

File tree

2 files changed

+114
-16
lines changed

2 files changed

+114
-16
lines changed

packages/system/src/theme.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { generateHexAlphaVariants } from './theme'
2+
3+
describe('#theme', () => {
4+
describe('#generateHexAlphaVariants', () => {
5+
it('generates colors with default alpha', () => {
6+
const colors = generateHexAlphaVariants({
7+
white: '#ffffff',
8+
9+
'blue-gray-500': '#64748b',
10+
})
11+
12+
expect(colors).toEqual({
13+
white: '#ffffff',
14+
'white-a0': '#ffffff0',
15+
'white-a5': '#ffffffd',
16+
'white-a10': '#ffffff1a',
17+
'white-a20': '#ffffff33',
18+
'white-a25': '#ffffff40',
19+
'white-a30': '#ffffff4d',
20+
'white-a40': '#ffffff66',
21+
'white-a50': '#ffffff80',
22+
'white-a60': '#ffffff99',
23+
'white-a70': '#ffffffb3',
24+
'white-a75': '#ffffffbf',
25+
'white-a80': '#ffffffcc',
26+
'white-a90': '#ffffffe6',
27+
'white-a95': '#fffffff2',
28+
'white-a100': '#ffffffff',
29+
30+
'blue-gray-500': '#64748b',
31+
'blue-gray-500-a0': '#64748b0',
32+
'blue-gray-500-a5': '#64748bd',
33+
'blue-gray-500-a10': '#64748b1a',
34+
'blue-gray-500-a20': '#64748b33',
35+
'blue-gray-500-a25': '#64748b40',
36+
'blue-gray-500-a30': '#64748b4d',
37+
'blue-gray-500-a40': '#64748b66',
38+
'blue-gray-500-a50': '#64748b80',
39+
'blue-gray-500-a60': '#64748b99',
40+
'blue-gray-500-a70': '#64748bb3',
41+
'blue-gray-500-a75': '#64748bbf',
42+
'blue-gray-500-a80': '#64748bcc',
43+
'blue-gray-500-a90': '#64748be6',
44+
'blue-gray-500-a95': '#64748bf2',
45+
'blue-gray-500-a100': '#64748bff',
46+
})
47+
})
48+
49+
it('generates colors with custom alpha', () => {
50+
const colors = generateHexAlphaVariants(
51+
{
52+
white: '#ffffff',
53+
'blue-gray-500': '#64748b',
54+
},
55+
[1, 2, 3],
56+
)
57+
58+
expect(colors).toEqual({
59+
white: '#ffffff',
60+
'white-a1': '#ffffff3',
61+
'white-a2': '#ffffff5',
62+
'white-a3': '#ffffff8',
63+
64+
'blue-gray-500': '#64748b',
65+
'blue-gray-500-a1': '#64748b3',
66+
'blue-gray-500-a2': '#64748b5',
67+
'blue-gray-500-a3': '#64748b8',
68+
})
69+
})
70+
})
71+
})

packages/system/src/theme.ts

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { IProps } from './types'
22
import { th } from './th'
33

4+
type ColorsGuard = Record<string, string>
5+
type AlphaVariants = number[]
6+
47
const defaultAlphaVariants = [
58
0,
69
5,
@@ -17,29 +20,53 @@ const defaultAlphaVariants = [
1720
90,
1821
95,
1922
100,
20-
]
23+
] as const
24+
25+
type DefaultAlphaVariants = typeof defaultAlphaVariants
2126

22-
function generateAlphaVariants<T>(
23-
colors: Record<string, T>,
24-
transform: (value: T, key: string, variant: number) => T = (x) => x,
25-
variants: number[] = defaultAlphaVariants,
26-
): Record<string, T> {
27-
return Object.keys(colors).reduce(
28-
(obj, key) => {
29-
variants.forEach((i) => {
27+
function generateAlphaVariants<
28+
T extends ColorsGuard,
29+
U extends AlphaVariants | DefaultAlphaVariants = DefaultAlphaVariants
30+
>(
31+
colors: T,
32+
transform: (value: string, key: string, variant: number) => string = (x) => x,
33+
variants: U = defaultAlphaVariants as U,
34+
) {
35+
const alphaColors = Object.keys(colors).reduce(
36+
(obj, key: string) => {
37+
variants.forEach((i: number) => {
3038
obj[`${key}-a${i}`] = transform(colors[key], key, i)
3139
})
40+
3241
return obj
3342
},
34-
{ ...colors },
43+
44+
{ ...colors } as ColorsGuard,
3545
)
46+
47+
type ColorKeys = keyof T
48+
49+
type Colors = {
50+
[key in ColorKeys]: string
51+
}
52+
53+
type AlphaVariantKeys = `${Extract<
54+
ColorKeys,
55+
string
56+
>}-a${typeof variants[number]}`
57+
58+
type AlphaVariants = {
59+
[key in AlphaVariantKeys]: string
60+
}
61+
62+
return alphaColors as Colors & AlphaVariants
3663
}
3764

38-
export function generateHexAlphaVariants(
39-
colors: Record<string, string>,
40-
variants: number[] = defaultAlphaVariants,
41-
): Record<string, string> {
42-
return generateAlphaVariants<string>(
65+
export function generateHexAlphaVariants<
66+
T extends ColorsGuard,
67+
U extends AlphaVariants | DefaultAlphaVariants = DefaultAlphaVariants
68+
>(colors: T, variants: U = defaultAlphaVariants as U) {
69+
return generateAlphaVariants(
4370
colors,
4471
(value, _, variant) =>
4572
`${value}${Math.round((variant / 100) * 255).toString(16)}`,
@@ -53,7 +80,7 @@ export function aliasColor(
5380
alias: string,
5481
color: string,
5582
tones: number[] = defaultTones,
56-
variants: number[] = defaultAlphaVariants,
83+
variants: number[] = (defaultAlphaVariants as unknown) as number[],
5784
): Record<string, (props: IProps) => unknown> {
5885
return tones.reduce((obj, tone) => {
5986
obj[`${alias}-${tone}`] = th.color(`${color}-${tone}`)

0 commit comments

Comments
 (0)