/
color.test.ts
174 lines (146 loc) · 9.18 KB
/
color.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import type { RuleContext } from '@unocss/core'
import { createGenerator } from '@unocss/core'
import { colorResolver, colorToString, colorableShadows, hex2rgba, parseCssColor } from '@unocss/preset-mini/utils'
import { describe, expect, it } from 'vitest'
describe('color utils', () => {
it('convert hex to rgb', () => {
expect(hex2rgba('#fff')).eql([255, 255, 255])
expect(hex2rgba('fff')).eql(undefined)
expect(hex2rgba('#000')).eql([0, 0, 0])
expect(hex2rgba('#264512')).eql([38, 69, 18])
expect(hex2rgba('#123')).eql([17, 34, 51])
expect(hex2rgba('#abd3')).eql([170, 187, 221, 0.2])
expect(hex2rgba('#95723489')).eql([149, 114, 52, 0.54])
expect(hex2rgba('95723489')).eql(undefined)
expect(hex2rgba('#12')).eql(undefined)
expect(hex2rgba('#12123')).eql(undefined)
})
it('parses css colors', () => {
expect(parseCssColor('rgb(0,1,2)')).eql({ type: 'rgb', components: ['0', '1', '2'], alpha: undefined })
expect(parseCssColor('rgba(0,1,2,3)')).eql({ type: 'rgba', components: ['0', '1', '2'], alpha: '3' })
expect(parseCssColor('rgba(0,(1),2,3)')).eql({ type: 'rgba', components: ['0', '(1)', '2'], alpha: '3' })
expect(parseCssColor('rgb(0)')).eql({ type: 'rgb', components: ['0'], alpha: undefined })
expect(parseCssColor('rgb(0,1)')).eql(undefined)
expect(parseCssColor('rgba(0,1,2)')).eql(undefined)
expect(parseCssColor('rgba(0,1,2,3,4)')).eql(undefined)
expect(parseCssColor('rgba(0,)1(,2,3)')).eql(undefined)
expect(parseCssColor('rgba(0 1 2 / 3)')).eql({ type: 'rgba', components: ['0', '1', '2'], alpha: '3' })
expect(parseCssColor('rgba(0 1 2/ 3)')).eql({ type: 'rgba', components: ['0', '1', '2'], alpha: '3' })
expect(parseCssColor('rgba(0 1 2 /3)')).eql({ type: 'rgba', components: ['0', '1', '2'], alpha: '3' })
expect(parseCssColor('rgba(0 1 2/3)')).eql({ type: 'rgba', components: ['0', '1', '2'], alpha: '3' })
expect(parseCssColor('rgba(0 1 2//3)')).eql(undefined)
expect(parseCssColor('rgba(0 1 2/ /3)')).eql(undefined)
expect(parseCssColor('rgb(0)')).eql({ type: 'rgb', components: ['0'], alpha: undefined })
expect(parseCssColor('rgba(0 / 1)')).eql({ type: 'rgba', components: ['0'], alpha: '1' })
expect(parseCssColor('rgba(0 1)')).eql(undefined)
expect(parseCssColor('rgba(0 1 / 2)')).eql(undefined)
expect(parseCssColor('rgb(0 1 2)')).eql({ type: 'rgb', components: ['0', '1', '2'], alpha: undefined })
expect(parseCssColor('rgba(0 1 2)')).eql(undefined)
expect(parseCssColor('rgba(0 1 2 3)')).eql(undefined)
expect(parseCssColor('rgba(0 1 2 3 4)')).eql(undefined)
expect(parseCssColor('color(rgb 0 1 2)')).eql({ type: 'rgb', components: ['0', '1', '2'], alpha: undefined })
expect(parseCssColor('color(rgba 0 1 2)')).eql(undefined)
expect(parseCssColor('color(rgba 0 1 2 / 3)')).eql({ type: 'rgba', components: ['0', '1', '2'], alpha: '3' })
expect(parseCssColor('color(fancy 0 1 2 3 4 5 / 6)')).eql({ type: 'fancy', components: ['0', '1', '2', '3', '4', '5'], alpha: '6' })
expect(parseCssColor('color(fancy 0 1 2 3 4 5 /6)')).eql({ type: 'fancy', components: ['0', '1', '2', '3', '4', '5'], alpha: '6' })
expect(parseCssColor('color(fancy 0 1 2 3 4 5/ 6)')).eql({ type: 'fancy', components: ['0', '1', '2', '3', '4', '5'], alpha: '6' })
expect(parseCssColor('color(fancy 0 1 2 3 4 5/6)')).eql({ type: 'fancy', components: ['0', '1', '2', '3', '4', '5'], alpha: '6' })
expect(parseCssColor('color(fancy 0 1 2 3 4 5//6)')).eql(undefined)
expect(parseCssColor('color(over-limit 2 3 4 5 6 7 8 9 10)')).eql({ type: 'over-limit', components: ['2', '3', '4', '5', '6', '7', '8', '9', '10'], alpha: undefined })
expect(parseCssColor('color(over-limit 2 3 4 5 6 7 8 / 9)')).eql({ type: 'over-limit', components: ['2', '3', '4', '5', '6', '7', '8'], alpha: '9' })
expect(parseCssColor('color(over-limit 2 3 4 5 6 7 8 9 10 11)')).eql(undefined)
expect(parseCssColor('color(over-limit 2 3 4 5 6 7 8 9 / 10)')).eql(undefined)
expect(parseCssColor('color(lite 0)')).eql({ type: 'lite', components: ['0'], alpha: undefined })
expect(parseCssColor('color(lite 0 / 1)')).eql({ type: 'lite', components: ['0'], alpha: '1' })
expect(parseCssColor('color(lite 0 /1)')).eql({ type: 'lite', components: ['0'], alpha: '1' })
expect(parseCssColor('color(lite 0/ 1)')).eql({ type: 'lite', components: ['0'], alpha: '1' })
expect(parseCssColor('color(lite 0/1)')).eql({ type: 'lite', components: ['0'], alpha: '1' })
expect(parseCssColor('color(lite)')).eql(undefined)
expect(parseCssColor('color(lite 0//1)')).eql(undefined)
expect(parseCssColor('color(vary calc(0.1 / 5) calc(0.2 / 5) / calc(0.3 / 5))')).eql({ type: 'vary', components: ['calc(0.1 / 5)', 'calc(0.2 / 5)'], alpha: 'calc(0.3 / 5)' })
expect(parseCssColor('color(vary calc(0.1 / 5) calc(0.2 / 5) /calc(0.3 / 5))')).eql({ type: 'vary', components: ['calc(0.1 / 5)', 'calc(0.2 / 5)'], alpha: 'calc(0.3 / 5)' })
expect(parseCssColor('color(vary calc(0.1 / 5) calc(0.2 / 5)/ calc(0.3 / 5))')).eql({ type: 'vary', components: ['calc(0.1 / 5)', 'calc(0.2 / 5)'], alpha: 'calc(0.3 / 5)' })
expect(parseCssColor('color(vary calc(0.1 / 5) calc(0.2 / 5)/calc(0.3 / 5))')).eql({ type: 'vary', components: ['calc(0.1 / 5)', 'calc(0.2 / 5)'], alpha: 'calc(0.3 / 5)' })
expect(parseCssColor('color(vary calc(0.1 / 5) calc(0.2 / 5)//calc(0.3 / 5))')).eql(undefined)
})
it('generate css color string', () => {
const fn = (x: string) => colorToString(parseCssColor(x)!)
expect(fn('rgb(0,1,2)')).eql('rgba(0,1,2)')
expect(fn('rgba(0,1,2,3)')).eql('rgba(0,1,2,3)')
expect(fn('rgba(0,(1),2,3)')).eql('rgba(0,(1),2,3)')
expect(fn('rgba(0 1 2 / 3)')).eql('rgba(0,1,2,3)')
expect(fn('rgba(0 1 2/ 3)')).eql('rgba(0,1,2,3)')
expect(fn('rgba(0 1 2 /3)')).eql('rgba(0,1,2,3)')
expect(fn('rgba(0 1 2/3)')).eql('rgba(0,1,2,3)')
expect(fn('color(rgba 0 1 2 / 3)')).eql('rgba(0,1,2,3)')
expect(fn('color(fancy 0 1 2 3 4 5 / 6)')).eql('color(fancy 0 1 2 3 4 5 / 6)')
expect(fn('color(fancy 0 1 2 3 4 5 /6)')).eql('color(fancy 0 1 2 3 4 5 / 6)')
expect(fn('color(fancy 0 1 2 3 4 5/ 6)')).eql('color(fancy 0 1 2 3 4 5 / 6)')
expect(fn('color(fancy 0 1 2 3 4 5/6)')).eql('color(fancy 0 1 2 3 4 5 / 6)')
expect(fn('color(lite 0)')).eql('color(lite 0)')
expect(fn('color(lite 0 / 1)')).eql('color(lite 0 / 1)')
expect(fn('color(lite 0 /1)')).eql('color(lite 0 / 1)')
expect(fn('color(lite 0/ 1)')).eql('color(lite 0 / 1)')
expect(fn('color(lite 0/1)')).eql('color(lite 0 / 1)')
expect(fn('color(vary calc(0.1 / 5) calc(0.2 / 5) / calc(0.3 / 5))')).eql('color(vary calc(0.1 / 5) calc(0.2 / 5) / calc(0.3 / 5))')
expect(fn('color(vary calc(0.1 / 5) calc(0.2 / 5) /calc(0.3 / 5))')).eql('color(vary calc(0.1 / 5) calc(0.2 / 5) / calc(0.3 / 5))')
expect(fn('color(vary calc(0.1 / 5) calc(0.2 / 5)/ calc(0.3 / 5))')).eql('color(vary calc(0.1 / 5) calc(0.2 / 5) / calc(0.3 / 5))')
expect(fn('color(vary calc(0.1 / 5) calc(0.2 / 5)/calc(0.3 / 5))')).eql('color(vary calc(0.1 / 5) calc(0.2 / 5) / calc(0.3 / 5))')
})
it('parses shadow color values', () => {
// default 'none'
expect(colorableShadows('0 0 #0000', '--v')).eql(['0 0 var(--v, rgba(0,0,0,0))'])
// with spaces
expect(colorableShadows('0 1px 3px 0 rgba(0, 0, 0, 0.2)', '--v')).eql(['0 1px 3px 0 var(--v, rgba(0,0,0,0.2))'])
// full box-shadow
expect(colorableShadows('var(--un-shadow-inset) 0 1px 3px 0 #0000', '--v')).eql(['var(--un-shadow-inset) 0 1px 3px 0 var(--v, rgba(0,0,0,0))'])
// no color
expect(colorableShadows('0', '--v')).eql(['0'])
expect(colorableShadows('1px 2px', '--v')).eql(['1px 2px'])
// text shadow alternative syntax (color first, unsupported/not parsed)
expect(colorableShadows('#0000 0 0', '--v')).eql(['#0000 0 0'])
// component length
expect(colorableShadows('1px #200', '--v')).eql(['1px #200'])
expect(colorableShadows('inset 2px 3px 4px 5px #600', '--v')).eql(['inset 2px 3px 4px 5px var(--v, rgba(102,0,0))'])
expect(colorableShadows('inset 2px 3px 4px 5px 6px #700', '--v')).eql(['inset 2px 3px 4px 5px 6px #700'])
})
it('parses color token', () => {
const context: RuleContext = {
theme: {
colors: {
info: 'hsl(200.1,100%,54.3%)',
warning: 'hsl(42.4 100% 50%)',
danger: 'hsl(var(--danger))',
},
},
rawSelector: '',
currentSelector: '',
generator: createGenerator(),
variantHandlers: [],
variantMatch: ['', '', [], new Set()],
constructCSS: () => '',
}
const fn = (body: string) => colorResolver('prop', 'v')(['', body], context)
expect(fn('info')).eql({
'--un-v-opacity': 1,
'prop': 'hsla(200.1,100%,54.3%,var(--un-v-opacity))',
})
expect(fn('info/10')).eql({
prop: 'hsla(200.1,100%,54.3%,0.1)',
})
expect(fn('warning')).eql({
'--un-v-opacity': 1,
'prop': 'hsla(42.4,100%,50%,var(--un-v-opacity))',
})
expect(fn('warning/[20%]')).eql({
prop: 'hsla(42.4,100%,50%,20%)',
})
expect(fn('danger')).eql({
'--un-v-opacity': 1,
'prop': 'hsla(var(--danger),var(--un-v-opacity))',
})
expect(fn('danger/$o3')).eql({
prop: 'hsla(var(--danger),var(--o3))',
})
})
})