1
1
export type TailwindVersion = '3' | '4'
2
2
3
+ export interface TailwindStylesheet {
4
+ /**
5
+ * Whether or not this file can be used as a project root
6
+ */
7
+ root : boolean
8
+
9
+ /**
10
+ * The likely Tailwind version used by the given file
11
+ */
12
+ versions : TailwindVersion [ ]
13
+ }
14
+
15
+ // It's likely this is a v4 file if it has a v4 import:
16
+ // - `@import "tailwindcss"`
17
+ // - `@import "tailwindcss/theme"
18
+ // - etc…
19
+ const HAS_V4_IMPORT = / @ i m p o r t \s * [ ' " ] t a i l w i n d c s s (?: \/ [ ^ ' " ] + ) ? [ ' " ] /
20
+
21
+ // It's likely this is a v4 file if it has a v4-specific feature:
22
+ // - @plugin
23
+ // - @utility
24
+ // - @variant
25
+ // - @custom-variant
26
+ const HAS_V4_DIRECTIVE = / @ ( t h e m e | p l u g i n | u t i l i t y | c u s t o m - v a r i a n t | v a r i a n t | r e f e r e n c e ) \s * [ ^ ; { ] + [ ; { ] /
27
+
28
+ // It's likely this is a v4 file if it's using v4's custom functions:
29
+ // - --alpha(…)
30
+ // - --spacing(…)
31
+ // - --theme(…)
32
+ const HAS_V4_FN = / - - ( a l p h a | s p a c i n g | t h e m e ) \( /
33
+
34
+ // If the file contains older `@tailwind` directives, it's likely a v3 file
35
+ const HAS_LEGACY_TAILWIND = / @ t a i l w i n d \s * ( b a s e | p r e f l i g h t | c o m p o n e n t s | v a r i a n t s | s c r e e n s ) + ; /
36
+
37
+ // If the file contains other `@tailwind` directives it might be either
38
+ const HAS_TAILWIND_UTILITIES = / @ t a i l w i n d \s * u t i l i t i e s \s * [ ^ ; ] * ; /
39
+
40
+ // If the file contains other `@tailwind` directives it might be either
41
+ const HAS_TAILWIND = / @ t a i l w i n d \s * [ ^ ; ] + ; /
42
+
43
+ // If the file contains other `@apply` or `@config` it might be either
44
+ const HAS_COMMON_DIRECTIVE = / @ ( c o n f i g | a p p l y ) \s * [ ^ ; { ] + [ ; { ] /
45
+
46
+ // If it's got imports at all it could be either
47
+ const HAS_IMPORT = / @ i m p o r t \s * [ ' " ] /
48
+
3
49
/**
4
50
* Determine the likely Tailwind version used by the given file
5
51
*
@@ -8,46 +54,78 @@ export type TailwindVersion = '3' | '4'
8
54
*
9
55
* The order *does* matter, as the first item is the most likely version.
10
56
*/
11
- export function guessTailwindVersion ( content : string ) : TailwindVersion [ ] {
12
- // It's likely this is a v4 file if it has a v4 import:
13
- // - `@import "tailwindcss"`
14
- // - `@import "tailwindcss/theme"
15
- // - etc…
16
- let HAS_V4_IMPORT = / @ i m p o r t \s * [ ' " ] t a i l w i n d c s s (?: \/ [ ^ ' " ] + ) ? [ ' " ] /
17
- if ( HAS_V4_IMPORT . test ( content ) ) return [ '4' ]
18
-
19
- // It's likely this is a v4 file if it has a v4-specific feature:
20
- // - @theme
21
- // - @plugin
22
- // - @utility
23
- // - @variant
24
- // - @custom-variant
25
- let HAS_V4_DIRECTIVE = / @ ( t h e m e | p l u g i n | u t i l i t y | c u s t o m - v a r i a n t | v a r i a n t | r e f e r e n c e ) \s * [ ^ ; { ] + [ ; { ] /
26
- if ( HAS_V4_DIRECTIVE . test ( content ) ) return [ '4' ]
27
-
28
- // It's likely this is a v4 file if it's using v4's custom functions:
29
- // - --alpha(…)
30
- // - --spacing(…)
31
- // - --theme(…)
32
- let HAS_V4_FN = / - - ( a l p h a | s p a c i n g | t h e m e ) \( /
33
- if ( HAS_V4_FN . test ( content ) ) return [ '4' ]
34
-
35
- // If the file contains older `@tailwind` directives, it's likely a v3 file
36
- let HAS_LEGACY_TAILWIND = / @ t a i l w i n d \s * ( b a s e | p r e f l i g h t | c o m p o n e n t s | v a r i a n t s | s c r e e n s ) + ; /
37
- if ( HAS_LEGACY_TAILWIND . test ( content ) ) return [ '3' ]
38
-
39
- // If the file contains other `@tailwind` directives it might be either
40
- let HAS_TAILWIND = / @ t a i l w i n d \s * [ ^ ; ] + ; /
41
- if ( HAS_TAILWIND . test ( content ) ) return [ '4' , '3' ]
42
-
43
- // If the file contains other `@apply` or `@config` it might be either
44
- let HAS_COMMON_DIRECTIVE = / @ ( c o n f i g | a p p l y ) \s * [ ^ ; { ] + [ ; { ] /
45
- if ( HAS_COMMON_DIRECTIVE . test ( content ) ) return [ '4' , '3' ]
46
-
47
- // If it's got imports at all it could be either
48
- let HAS_IMPORT = / @ i m p o r t \s * [ ' " ] /
49
- if ( HAS_IMPORT . test ( content ) ) return [ '4' , '3' ]
50
-
51
- // There's chance this file isn't tailwind-related
52
- return [ ]
57
+ export function analyzeStylesheet ( content : string ) : TailwindStylesheet {
58
+ // An import for v4 definitely means it can be a v4 root
59
+ if ( HAS_V4_IMPORT . test ( content ) ) {
60
+ return {
61
+ root : true ,
62
+ versions : [ '4' ] ,
63
+ }
64
+ }
65
+
66
+ // Having v4-specific directives means its related but not necessarily a root
67
+ // but having `@tailwind utilities` alongside it means it could be
68
+ if ( HAS_V4_DIRECTIVE . test ( content ) ) {
69
+ // Unless it specifically has `@tailwind utilities` in it
70
+ if ( HAS_TAILWIND_UTILITIES . test ( content ) ) {
71
+ return {
72
+ root : true ,
73
+ versions : [ '4' ] ,
74
+ }
75
+ }
76
+
77
+ return {
78
+ // This file MUST be imported by another file to be a valid root
79
+ root : false ,
80
+ versions : [ '4' ] ,
81
+ }
82
+ }
83
+
84
+ // Just having v4 functions doesn't mean it's a v4 root
85
+ if ( HAS_V4_FN . test ( content ) ) {
86
+ return {
87
+ // This file MUST be imported by another file to be a valid root
88
+ root : false ,
89
+ versions : [ '4' ] ,
90
+ }
91
+ }
92
+
93
+ // Legacy tailwind directives mean it's a v3 file
94
+ if ( HAS_LEGACY_TAILWIND . test ( content ) ) {
95
+ return {
96
+ // Roots are only a valid concept in v4
97
+ root : false ,
98
+ versions : [ '3' ] ,
99
+ }
100
+ }
101
+
102
+ // Other tailwind directives could be either (though they're probably invalid)
103
+ if ( HAS_TAILWIND . test ( content ) ) {
104
+ return {
105
+ root : true ,
106
+ versions : [ '4' , '3' ] ,
107
+ }
108
+ }
109
+
110
+ // Other common directives could be either but don't signal a root file
111
+ if ( HAS_COMMON_DIRECTIVE . test ( content ) ) {
112
+ return {
113
+ root : false ,
114
+ versions : [ '4' , '3' ] ,
115
+ }
116
+ }
117
+
118
+ // Files that import other files could be either and are potentially roots
119
+ if ( HAS_IMPORT . test ( content ) ) {
120
+ return {
121
+ root : true ,
122
+ versions : [ '4' , '3' ] ,
123
+ }
124
+ }
125
+
126
+ // Pretty sure it's not related to Tailwind at all
127
+ return {
128
+ root : false ,
129
+ versions : [ ] ,
130
+ }
53
131
}
0 commit comments