-
Notifications
You must be signed in to change notification settings - Fork 213
/
Copy pathgetVariantsFromClassName.ts
71 lines (54 loc) · 1.75 KB
/
getVariantsFromClassName.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
import type { State } from './state'
import * as jit from './jit'
import { segment } from './segment'
export function getVariantsFromClassName(
state: State,
className: string,
): { variants: string[]; offset: number } {
let allVariants = state.variants.flatMap((variant) => {
if (variant.values.length) {
return variant.values.map((value) =>
value === 'DEFAULT' ? variant.name : `${variant.name}${variant.hasDash ? '-' : ''}${value}`,
)
}
return [variant.name]
})
let parts = segment(className, state.separator)
if (parts.length < 2) {
return { variants: [], offset: 0 }
}
parts = parts.filter(Boolean)
function isValidVariant(part: string) {
if (allVariants.includes(part)) {
return true
}
let className = `${part}${state.separator}[color:red]`
if (state.v4) {
// NOTE: This should never happen
if (!state.designSystem) return false
let prefix = state.designSystem.theme.prefix ?? ''
if (prefix !== '') {
className = `${prefix}:${className}`
}
// We don't use `compile()` so there's no overhead from PostCSS
let compiled = state.designSystem.candidatesToCss([className])
// NOTE: This should never happen
if (compiled.length !== 1) return false
return compiled[0] !== null
}
if (state.jit) {
if ((part.includes('[') && part.endsWith(']')) || part.includes('/')) {
return jit.generateRules(state, [className]).rules.length > 0
}
}
return false
}
let offset = 0
let variants = new Set<string>()
for (let part of parts) {
if (!isValidVariant(part)) break
variants.add(part)
offset += part.length + state.separator!.length
}
return { variants: Array.from(variants), offset }
}