tailwindcss 3.3.1 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -6
- package/lib/cli/build/deps.js +17 -9
- package/lib/cli/build/index.js +10 -8
- package/lib/cli/build/plugin.js +29 -27
- package/lib/cli/build/utils.js +18 -8
- package/lib/cli/build/watching.js +12 -10
- package/lib/cli/help/index.js +6 -4
- package/lib/cli/index.js +4 -4
- package/lib/cli/init/index.js +8 -6
- package/lib/cli-peer-dependencies.js +12 -4
- package/lib/cli.js +1 -1
- package/lib/corePluginList.js +3 -1
- package/lib/corePlugins.js +52 -42
- package/lib/css/preflight.css +9 -0
- package/lib/featureFlags.js +14 -9
- package/lib/index.js +1 -5
- package/lib/lib/cacheInvalidation.js +7 -5
- package/lib/lib/collapseAdjacentRules.js +3 -1
- package/lib/lib/collapseDuplicateDeclarations.js +10 -8
- package/lib/lib/content.js +18 -14
- package/lib/lib/defaultExtractor.js +6 -4
- package/lib/lib/detectNesting.js +3 -1
- package/lib/lib/evaluateTailwindFunctions.js +20 -16
- package/lib/lib/expandApplyAtRules.js +37 -40
- package/lib/lib/expandTailwindAtRules.js +19 -17
- package/lib/lib/findAtConfigPath.js +6 -4
- package/lib/lib/generateRules.js +52 -38
- package/lib/lib/getModuleDependencies.js +10 -8
- package/lib/lib/load-config.js +5 -3
- package/lib/lib/normalizeTailwindDirectives.js +5 -3
- package/lib/lib/offsets.js +7 -5
- package/lib/lib/partitionApplyAtRules.js +3 -1
- package/lib/lib/regex.js +21 -7
- package/lib/lib/remap-bitfield.js +3 -1
- package/lib/lib/resolveDefaultsAtRules.js +24 -20
- package/lib/lib/setupContextUtils.js +91 -63
- package/lib/lib/setupTrackingContext.js +27 -24
- package/lib/lib/sharedState.js +28 -24
- package/lib/lib/substituteScreenAtRules.js +5 -3
- package/lib/oxide/cli/build/deps.js +16 -8
- package/lib/oxide/cli/build/index.js +6 -4
- package/lib/oxide/cli/build/plugin.js +19 -17
- package/lib/oxide/cli/build/utils.js +18 -8
- package/lib/oxide/cli/build/watching.js +10 -8
- package/lib/oxide/cli/help/index.js +6 -4
- package/lib/oxide/cli/index.js +4 -4
- package/lib/oxide/cli/init/index.js +6 -4
- package/lib/plugin.js +9 -9
- package/lib/postcss-plugins/nesting/index.js +3 -1
- package/lib/postcss-plugins/nesting/plugin.js +8 -6
- package/lib/processTailwindFeatures.js +16 -14
- package/lib/public/colors.js +5 -3
- package/lib/public/create-plugin.js +5 -3
- package/lib/public/default-config.js +6 -4
- package/lib/public/default-theme.js +6 -4
- package/lib/public/load-config.js +5 -3
- package/lib/public/resolve-config.js +6 -4
- package/lib/util/applyImportantSelector.js +9 -10
- package/lib/util/bigSign.js +3 -1
- package/lib/util/buildMediaQuery.js +3 -1
- package/lib/util/cloneDeep.js +3 -1
- package/lib/util/cloneNodes.js +3 -1
- package/lib/util/color.js +10 -6
- package/lib/util/colorNames.js +752 -0
- package/lib/util/configurePlugins.js +3 -1
- package/lib/util/createPlugin.js +3 -1
- package/lib/util/createUtilityPlugin.js +5 -3
- package/lib/util/dataTypes.js +59 -21
- package/lib/util/defaults.js +6 -4
- package/lib/util/escapeClassName.js +7 -5
- package/lib/util/escapeCommas.js +3 -1
- package/lib/util/flattenColorPalette.js +3 -1
- package/lib/util/formatVariantSelector.js +30 -110
- package/lib/util/getAllConfigs.js +6 -4
- package/lib/util/hashConfig.js +6 -4
- package/lib/util/isKeyframeRule.js +3 -1
- package/lib/util/isPlainObject.js +3 -1
- package/lib/util/isSyntacticallyValidPropertyValue.js +3 -1
- package/lib/util/log.js +8 -4
- package/lib/util/nameClass.js +12 -6
- package/lib/util/negateValue.js +3 -1
- package/lib/util/normalizeConfig.js +7 -5
- package/lib/util/normalizeScreens.js +12 -4
- package/lib/util/parseAnimationValue.js +3 -1
- package/lib/util/parseBoxShadowValue.js +6 -2
- package/lib/util/parseDependency.js +3 -1
- package/lib/util/parseGlob.js +6 -4
- package/lib/util/parseObjectStyles.js +9 -7
- package/lib/util/pluginUtils.js +30 -18
- package/lib/util/prefixSelector.js +6 -4
- package/lib/util/pseudoElements.js +209 -0
- package/lib/util/removeAlphaVariables.js +3 -1
- package/lib/util/resolveConfig.js +10 -8
- package/lib/util/resolveConfigPath.js +9 -5
- package/lib/util/responsive.js +6 -4
- package/lib/util/splitAtTopLevelOnly.js +3 -1
- package/lib/util/tap.js +3 -1
- package/lib/util/toColorValue.js +3 -1
- package/lib/util/toPath.js +3 -1
- package/lib/util/transformThemeValue.js +6 -4
- package/lib/util/validateConfig.js +5 -3
- package/lib/util/validateFormalSyntax.js +3 -1
- package/lib/util/withAlphaVariable.js +6 -2
- package/lib/value-parser/LICENSE +22 -0
- package/lib/value-parser/README.md +3 -0
- package/lib/value-parser/index.d.js +2 -0
- package/lib/value-parser/index.js +22 -0
- package/lib/value-parser/parse.js +259 -0
- package/lib/value-parser/stringify.js +38 -0
- package/lib/value-parser/unit.js +86 -0
- package/lib/value-parser/walk.js +16 -0
- package/package.json +30 -35
- package/peers/index.js +65828 -48819
- package/src/cli/build/plugin.js +3 -3
- package/src/cli.js +1 -1
- package/src/corePlugins.js +29 -24
- package/src/css/preflight.css +9 -0
- package/src/featureFlags.js +2 -3
- package/src/index.js +1 -5
- package/src/lib/defaultExtractor.js +1 -1
- package/src/lib/evaluateTailwindFunctions.js +4 -1
- package/src/lib/expandApplyAtRules.js +2 -8
- package/src/lib/expandTailwindAtRules.js +12 -10
- package/src/lib/generateRules.js +15 -8
- package/src/lib/setupContextUtils.js +18 -5
- package/src/lib/setupTrackingContext.js +2 -4
- package/src/lib/sharedState.js +0 -15
- package/src/oxide/cli/build/plugin.ts +1 -1
- package/src/plugin.js +4 -4
- package/src/processTailwindFeatures.js +3 -2
- package/src/util/applyImportantSelector.js +2 -5
- package/src/util/color.js +1 -1
- package/src/util/colorNames.js +150 -0
- package/src/util/dataTypes.js +17 -6
- package/src/util/formatVariantSelector.js +4 -126
- package/src/util/pluginUtils.js +1 -5
- package/src/util/prefixSelector.js +1 -0
- package/src/util/pseudoElements.js +167 -0
- package/src/value-parser/LICENSE +22 -0
- package/src/value-parser/README.md +3 -0
- package/src/value-parser/index.d.ts +177 -0
- package/src/value-parser/index.js +28 -0
- package/src/value-parser/parse.js +303 -0
- package/src/value-parser/stringify.js +41 -0
- package/src/value-parser/unit.js +118 -0
- package/src/value-parser/walk.js +18 -0
- package/stubs/config.full.js +1 -0
- package/types/generated/default-theme.d.ts +1 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
aliceblue: [240, 248, 255],
|
|
3
|
+
antiquewhite: [250, 235, 215],
|
|
4
|
+
aqua: [0, 255, 255],
|
|
5
|
+
aquamarine: [127, 255, 212],
|
|
6
|
+
azure: [240, 255, 255],
|
|
7
|
+
beige: [245, 245, 220],
|
|
8
|
+
bisque: [255, 228, 196],
|
|
9
|
+
black: [0, 0, 0],
|
|
10
|
+
blanchedalmond: [255, 235, 205],
|
|
11
|
+
blue: [0, 0, 255],
|
|
12
|
+
blueviolet: [138, 43, 226],
|
|
13
|
+
brown: [165, 42, 42],
|
|
14
|
+
burlywood: [222, 184, 135],
|
|
15
|
+
cadetblue: [95, 158, 160],
|
|
16
|
+
chartreuse: [127, 255, 0],
|
|
17
|
+
chocolate: [210, 105, 30],
|
|
18
|
+
coral: [255, 127, 80],
|
|
19
|
+
cornflowerblue: [100, 149, 237],
|
|
20
|
+
cornsilk: [255, 248, 220],
|
|
21
|
+
crimson: [220, 20, 60],
|
|
22
|
+
cyan: [0, 255, 255],
|
|
23
|
+
darkblue: [0, 0, 139],
|
|
24
|
+
darkcyan: [0, 139, 139],
|
|
25
|
+
darkgoldenrod: [184, 134, 11],
|
|
26
|
+
darkgray: [169, 169, 169],
|
|
27
|
+
darkgreen: [0, 100, 0],
|
|
28
|
+
darkgrey: [169, 169, 169],
|
|
29
|
+
darkkhaki: [189, 183, 107],
|
|
30
|
+
darkmagenta: [139, 0, 139],
|
|
31
|
+
darkolivegreen: [85, 107, 47],
|
|
32
|
+
darkorange: [255, 140, 0],
|
|
33
|
+
darkorchid: [153, 50, 204],
|
|
34
|
+
darkred: [139, 0, 0],
|
|
35
|
+
darksalmon: [233, 150, 122],
|
|
36
|
+
darkseagreen: [143, 188, 143],
|
|
37
|
+
darkslateblue: [72, 61, 139],
|
|
38
|
+
darkslategray: [47, 79, 79],
|
|
39
|
+
darkslategrey: [47, 79, 79],
|
|
40
|
+
darkturquoise: [0, 206, 209],
|
|
41
|
+
darkviolet: [148, 0, 211],
|
|
42
|
+
deeppink: [255, 20, 147],
|
|
43
|
+
deepskyblue: [0, 191, 255],
|
|
44
|
+
dimgray: [105, 105, 105],
|
|
45
|
+
dimgrey: [105, 105, 105],
|
|
46
|
+
dodgerblue: [30, 144, 255],
|
|
47
|
+
firebrick: [178, 34, 34],
|
|
48
|
+
floralwhite: [255, 250, 240],
|
|
49
|
+
forestgreen: [34, 139, 34],
|
|
50
|
+
fuchsia: [255, 0, 255],
|
|
51
|
+
gainsboro: [220, 220, 220],
|
|
52
|
+
ghostwhite: [248, 248, 255],
|
|
53
|
+
gold: [255, 215, 0],
|
|
54
|
+
goldenrod: [218, 165, 32],
|
|
55
|
+
gray: [128, 128, 128],
|
|
56
|
+
green: [0, 128, 0],
|
|
57
|
+
greenyellow: [173, 255, 47],
|
|
58
|
+
grey: [128, 128, 128],
|
|
59
|
+
honeydew: [240, 255, 240],
|
|
60
|
+
hotpink: [255, 105, 180],
|
|
61
|
+
indianred: [205, 92, 92],
|
|
62
|
+
indigo: [75, 0, 130],
|
|
63
|
+
ivory: [255, 255, 240],
|
|
64
|
+
khaki: [240, 230, 140],
|
|
65
|
+
lavender: [230, 230, 250],
|
|
66
|
+
lavenderblush: [255, 240, 245],
|
|
67
|
+
lawngreen: [124, 252, 0],
|
|
68
|
+
lemonchiffon: [255, 250, 205],
|
|
69
|
+
lightblue: [173, 216, 230],
|
|
70
|
+
lightcoral: [240, 128, 128],
|
|
71
|
+
lightcyan: [224, 255, 255],
|
|
72
|
+
lightgoldenrodyellow: [250, 250, 210],
|
|
73
|
+
lightgray: [211, 211, 211],
|
|
74
|
+
lightgreen: [144, 238, 144],
|
|
75
|
+
lightgrey: [211, 211, 211],
|
|
76
|
+
lightpink: [255, 182, 193],
|
|
77
|
+
lightsalmon: [255, 160, 122],
|
|
78
|
+
lightseagreen: [32, 178, 170],
|
|
79
|
+
lightskyblue: [135, 206, 250],
|
|
80
|
+
lightslategray: [119, 136, 153],
|
|
81
|
+
lightslategrey: [119, 136, 153],
|
|
82
|
+
lightsteelblue: [176, 196, 222],
|
|
83
|
+
lightyellow: [255, 255, 224],
|
|
84
|
+
lime: [0, 255, 0],
|
|
85
|
+
limegreen: [50, 205, 50],
|
|
86
|
+
linen: [250, 240, 230],
|
|
87
|
+
magenta: [255, 0, 255],
|
|
88
|
+
maroon: [128, 0, 0],
|
|
89
|
+
mediumaquamarine: [102, 205, 170],
|
|
90
|
+
mediumblue: [0, 0, 205],
|
|
91
|
+
mediumorchid: [186, 85, 211],
|
|
92
|
+
mediumpurple: [147, 112, 219],
|
|
93
|
+
mediumseagreen: [60, 179, 113],
|
|
94
|
+
mediumslateblue: [123, 104, 238],
|
|
95
|
+
mediumspringgreen: [0, 250, 154],
|
|
96
|
+
mediumturquoise: [72, 209, 204],
|
|
97
|
+
mediumvioletred: [199, 21, 133],
|
|
98
|
+
midnightblue: [25, 25, 112],
|
|
99
|
+
mintcream: [245, 255, 250],
|
|
100
|
+
mistyrose: [255, 228, 225],
|
|
101
|
+
moccasin: [255, 228, 181],
|
|
102
|
+
navajowhite: [255, 222, 173],
|
|
103
|
+
navy: [0, 0, 128],
|
|
104
|
+
oldlace: [253, 245, 230],
|
|
105
|
+
olive: [128, 128, 0],
|
|
106
|
+
olivedrab: [107, 142, 35],
|
|
107
|
+
orange: [255, 165, 0],
|
|
108
|
+
orangered: [255, 69, 0],
|
|
109
|
+
orchid: [218, 112, 214],
|
|
110
|
+
palegoldenrod: [238, 232, 170],
|
|
111
|
+
palegreen: [152, 251, 152],
|
|
112
|
+
paleturquoise: [175, 238, 238],
|
|
113
|
+
palevioletred: [219, 112, 147],
|
|
114
|
+
papayawhip: [255, 239, 213],
|
|
115
|
+
peachpuff: [255, 218, 185],
|
|
116
|
+
peru: [205, 133, 63],
|
|
117
|
+
pink: [255, 192, 203],
|
|
118
|
+
plum: [221, 160, 221],
|
|
119
|
+
powderblue: [176, 224, 230],
|
|
120
|
+
purple: [128, 0, 128],
|
|
121
|
+
rebeccapurple: [102, 51, 153],
|
|
122
|
+
red: [255, 0, 0],
|
|
123
|
+
rosybrown: [188, 143, 143],
|
|
124
|
+
royalblue: [65, 105, 225],
|
|
125
|
+
saddlebrown: [139, 69, 19],
|
|
126
|
+
salmon: [250, 128, 114],
|
|
127
|
+
sandybrown: [244, 164, 96],
|
|
128
|
+
seagreen: [46, 139, 87],
|
|
129
|
+
seashell: [255, 245, 238],
|
|
130
|
+
sienna: [160, 82, 45],
|
|
131
|
+
silver: [192, 192, 192],
|
|
132
|
+
skyblue: [135, 206, 235],
|
|
133
|
+
slateblue: [106, 90, 205],
|
|
134
|
+
slategray: [112, 128, 144],
|
|
135
|
+
slategrey: [112, 128, 144],
|
|
136
|
+
snow: [255, 250, 250],
|
|
137
|
+
springgreen: [0, 255, 127],
|
|
138
|
+
steelblue: [70, 130, 180],
|
|
139
|
+
tan: [210, 180, 140],
|
|
140
|
+
teal: [0, 128, 128],
|
|
141
|
+
thistle: [216, 191, 216],
|
|
142
|
+
tomato: [255, 99, 71],
|
|
143
|
+
turquoise: [64, 224, 208],
|
|
144
|
+
violet: [238, 130, 238],
|
|
145
|
+
wheat: [245, 222, 179],
|
|
146
|
+
white: [255, 255, 255],
|
|
147
|
+
whitesmoke: [245, 245, 245],
|
|
148
|
+
yellow: [255, 255, 0],
|
|
149
|
+
yellowgreen: [154, 205, 50],
|
|
150
|
+
}
|
package/src/util/dataTypes.js
CHANGED
|
@@ -49,10 +49,22 @@ export function normalize(value, isRoot = true) {
|
|
|
49
49
|
value = value.trim()
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
value = normalizeMathOperatorSpacing(value)
|
|
53
|
+
|
|
54
|
+
return value
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Add spaces around operators inside math functions
|
|
59
|
+
* like calc() that do not follow an operator or '('.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} value
|
|
62
|
+
* @returns {string}
|
|
63
|
+
*/
|
|
64
|
+
function normalizeMathOperatorSpacing(value) {
|
|
65
|
+
return value.replace(/(calc|min|max|clamp)\(.+\)/g, (match) => {
|
|
55
66
|
let vars = []
|
|
67
|
+
|
|
56
68
|
return match
|
|
57
69
|
.replace(/var\((--.+?)[,)]/g, (match, g1) => {
|
|
58
70
|
vars.push(g1)
|
|
@@ -61,8 +73,6 @@ export function normalize(value, isRoot = true) {
|
|
|
61
73
|
.replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ')
|
|
62
74
|
.replace(placeholderRe, () => vars.shift())
|
|
63
75
|
})
|
|
64
|
-
|
|
65
|
-
return value
|
|
66
76
|
}
|
|
67
77
|
|
|
68
78
|
export function url(value) {
|
|
@@ -178,11 +188,12 @@ export function image(value) {
|
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
let gradientTypes = new Set([
|
|
191
|
+
'conic-gradient',
|
|
181
192
|
'linear-gradient',
|
|
182
193
|
'radial-gradient',
|
|
194
|
+
'repeating-conic-gradient',
|
|
183
195
|
'repeating-linear-gradient',
|
|
184
196
|
'repeating-radial-gradient',
|
|
185
|
-
'conic-gradient',
|
|
186
197
|
])
|
|
187
198
|
export function gradient(value) {
|
|
188
199
|
value = normalize(value)
|
|
@@ -2,13 +2,14 @@ import selectorParser from 'postcss-selector-parser'
|
|
|
2
2
|
import unescape from 'postcss-selector-parser/dist/util/unesc'
|
|
3
3
|
import escapeClassName from '../util/escapeClassName'
|
|
4
4
|
import prefixSelector from '../util/prefixSelector'
|
|
5
|
+
import { movePseudos } from './pseudoElements'
|
|
5
6
|
|
|
6
7
|
/** @typedef {import('postcss-selector-parser').Root} Root */
|
|
7
8
|
/** @typedef {import('postcss-selector-parser').Selector} Selector */
|
|
8
9
|
/** @typedef {import('postcss-selector-parser').Pseudo} Pseudo */
|
|
9
10
|
/** @typedef {import('postcss-selector-parser').Node} Node */
|
|
10
11
|
|
|
11
|
-
/** @typedef {{format: string,
|
|
12
|
+
/** @typedef {{format: string, respectPrefix: boolean}[]} RawFormats */
|
|
12
13
|
/** @typedef {import('postcss-selector-parser').Root} ParsedFormats */
|
|
13
14
|
/** @typedef {RawFormats | ParsedFormats} AcceptedFormats */
|
|
14
15
|
|
|
@@ -28,7 +29,7 @@ export function formatVariantSelector(formats, { context, candidate }) {
|
|
|
28
29
|
|
|
29
30
|
return {
|
|
30
31
|
...format,
|
|
31
|
-
ast: format.
|
|
32
|
+
ast: format.respectPrefix ? prefixSelector(prefix, ast) : ast,
|
|
32
33
|
}
|
|
33
34
|
})
|
|
34
35
|
|
|
@@ -245,12 +246,7 @@ export function finalizeSelector(current, formats, { context, candidate, base })
|
|
|
245
246
|
})
|
|
246
247
|
|
|
247
248
|
// Move pseudo elements to the end of the selector (if necessary)
|
|
248
|
-
selector.each((sel) =>
|
|
249
|
-
let [pseudoElements] = collectPseudoElements(sel)
|
|
250
|
-
if (pseudoElements.length > 0) {
|
|
251
|
-
sel.nodes.push(...pseudoElements.sort(sortSelector))
|
|
252
|
-
}
|
|
253
|
-
})
|
|
249
|
+
selector.each((sel) => movePseudos(sel))
|
|
254
250
|
|
|
255
251
|
return selector.toString()
|
|
256
252
|
}
|
|
@@ -318,121 +314,3 @@ export function handleMergePseudo(selector, format) {
|
|
|
318
314
|
|
|
319
315
|
return [selector, format]
|
|
320
316
|
}
|
|
321
|
-
|
|
322
|
-
// Note: As a rule, double colons (::) should be used instead of a single colon
|
|
323
|
-
// (:). This distinguishes pseudo-classes from pseudo-elements. However, since
|
|
324
|
-
// this distinction was not present in older versions of the W3C spec, most
|
|
325
|
-
// browsers support both syntaxes for the original pseudo-elements.
|
|
326
|
-
let pseudoElementsBC = [':before', ':after', ':first-line', ':first-letter']
|
|
327
|
-
|
|
328
|
-
// These pseudo-elements _can_ be combined with other pseudo selectors AND the order does matter.
|
|
329
|
-
let pseudoElementExceptions = [
|
|
330
|
-
'::file-selector-button',
|
|
331
|
-
|
|
332
|
-
// Webkit scroll bar pseudo elements can be combined with user-action pseudo classes
|
|
333
|
-
'::-webkit-scrollbar',
|
|
334
|
-
'::-webkit-scrollbar-button',
|
|
335
|
-
'::-webkit-scrollbar-thumb',
|
|
336
|
-
'::-webkit-scrollbar-track',
|
|
337
|
-
'::-webkit-scrollbar-track-piece',
|
|
338
|
-
'::-webkit-scrollbar-corner',
|
|
339
|
-
'::-webkit-resizer',
|
|
340
|
-
]
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* This will make sure to move pseudo's to the correct spot (the end for
|
|
344
|
-
* pseudo elements) because otherwise the selector will never work
|
|
345
|
-
* anyway.
|
|
346
|
-
*
|
|
347
|
-
* E.g.:
|
|
348
|
-
* - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
|
|
349
|
-
* - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
|
|
350
|
-
*
|
|
351
|
-
* `::before:hover` doesn't work, which means that we can make it work for you by flipping the order.
|
|
352
|
-
*
|
|
353
|
-
* @param {Selector} selector
|
|
354
|
-
* @param {boolean} force
|
|
355
|
-
**/
|
|
356
|
-
export function collectPseudoElements(selector, force = false) {
|
|
357
|
-
/** @type {Node[]} */
|
|
358
|
-
let nodes = []
|
|
359
|
-
let seenPseudoElement = null
|
|
360
|
-
|
|
361
|
-
for (let node of [...selector.nodes]) {
|
|
362
|
-
if (isPseudoElement(node, force)) {
|
|
363
|
-
nodes.push(node)
|
|
364
|
-
selector.removeChild(node)
|
|
365
|
-
seenPseudoElement = node.value
|
|
366
|
-
} else if (seenPseudoElement !== null) {
|
|
367
|
-
if (pseudoElementExceptions.includes(seenPseudoElement) && isPseudoClass(node, force)) {
|
|
368
|
-
nodes.push(node)
|
|
369
|
-
selector.removeChild(node)
|
|
370
|
-
} else {
|
|
371
|
-
seenPseudoElement = null
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (node?.nodes) {
|
|
376
|
-
let hasPseudoElementRestrictions =
|
|
377
|
-
node.type === 'pseudo' && (node.value === ':is' || node.value === ':has')
|
|
378
|
-
|
|
379
|
-
let [collected, seenPseudoElementInSelector] = collectPseudoElements(
|
|
380
|
-
node,
|
|
381
|
-
force || hasPseudoElementRestrictions
|
|
382
|
-
)
|
|
383
|
-
|
|
384
|
-
if (seenPseudoElementInSelector) {
|
|
385
|
-
seenPseudoElement = seenPseudoElementInSelector
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
nodes.push(...collected)
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return [nodes, seenPseudoElement]
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// This will make sure to move pseudo's to the correct spot (the end for
|
|
396
|
-
// pseudo elements) because otherwise the selector will never work
|
|
397
|
-
// anyway.
|
|
398
|
-
//
|
|
399
|
-
// E.g.:
|
|
400
|
-
// - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
|
|
401
|
-
// - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
|
|
402
|
-
//
|
|
403
|
-
// `::before:hover` doesn't work, which means that we can make it work
|
|
404
|
-
// for you by flipping the order.
|
|
405
|
-
export function sortSelector(a, z) {
|
|
406
|
-
// Both nodes are non-pseudo's so we can safely ignore them and keep
|
|
407
|
-
// them in the same order.
|
|
408
|
-
if (a.type !== 'pseudo' && z.type !== 'pseudo') {
|
|
409
|
-
return 0
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// If one of them is a combinator, we need to keep it in the same order
|
|
413
|
-
// because that means it will start a new "section" in the selector.
|
|
414
|
-
if ((a.type === 'combinator') ^ (z.type === 'combinator')) {
|
|
415
|
-
return 0
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// One of the items is a pseudo and the other one isn't. Let's move
|
|
419
|
-
// the pseudo to the right.
|
|
420
|
-
if ((a.type === 'pseudo') ^ (z.type === 'pseudo')) {
|
|
421
|
-
return (a.type === 'pseudo') - (z.type === 'pseudo')
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Both are pseudo's, move the pseudo elements (except for
|
|
425
|
-
// ::file-selector-button) to the right.
|
|
426
|
-
return isPseudoElement(a) - isPseudoElement(z)
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
function isPseudoElement(node, force = false) {
|
|
430
|
-
if (node.type !== 'pseudo') return false
|
|
431
|
-
if (pseudoElementExceptions.includes(node.value) && !force) return false
|
|
432
|
-
|
|
433
|
-
return node.value.startsWith('::') || pseudoElementsBC.includes(node.value)
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
function isPseudoClass(node, force) {
|
|
437
|
-
return node.type === 'pseudo' && !isPseudoElement(node, force)
|
|
438
|
-
}
|
package/src/util/pluginUtils.js
CHANGED
|
@@ -115,11 +115,7 @@ export function parseColorFormat(value) {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
function unwrapArbitraryModifier(modifier) {
|
|
118
|
-
|
|
119
|
-
if (modifier.startsWith('--')) {
|
|
120
|
-
modifier = `var(${modifier})`
|
|
121
|
-
}
|
|
122
|
-
return modifier
|
|
118
|
+
return normalize(modifier.slice(1, -1))
|
|
123
119
|
}
|
|
124
120
|
|
|
125
121
|
export function asColor(modifier, options = {}, { tailwindConfig = {} } = {}) {
|
|
@@ -17,6 +17,7 @@ export default function (prefix, selector, prependNegative = false) {
|
|
|
17
17
|
return selector
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/** @type {import('postcss-selector-parser').Root} */
|
|
20
21
|
let ast = typeof selector === 'string' ? parser().astSync(selector) : selector
|
|
21
22
|
|
|
22
23
|
ast.walkClasses((classSelector) => {
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/** @typedef {import('postcss-selector-parser').Root} Root */
|
|
2
|
+
/** @typedef {import('postcss-selector-parser').Selector} Selector */
|
|
3
|
+
/** @typedef {import('postcss-selector-parser').Pseudo} Pseudo */
|
|
4
|
+
/** @typedef {import('postcss-selector-parser').Node} Node */
|
|
5
|
+
|
|
6
|
+
// There are some pseudo-elements that may or may not be:
|
|
7
|
+
|
|
8
|
+
// **Actionable**
|
|
9
|
+
// Zero or more user-action pseudo-classes may be attached to the pseudo-element itself
|
|
10
|
+
// structural-pseudo-classes are NOT allowed but we don't make
|
|
11
|
+
// The spec is not clear on whether this is allowed or not — but in practice it is.
|
|
12
|
+
|
|
13
|
+
// **Terminal**
|
|
14
|
+
// It MUST be placed at the end of a selector
|
|
15
|
+
//
|
|
16
|
+
// This is the required in the spec. However, some pseudo elements are not "terminal" because
|
|
17
|
+
// they represent a "boundary piercing" that is compiled out by a build step.
|
|
18
|
+
|
|
19
|
+
// **Jumpable**
|
|
20
|
+
// Any terminal element may "jump" over combinators when moving to the end of the selector
|
|
21
|
+
//
|
|
22
|
+
// This is a backwards-compat quirk of pseudo element variants from earlier versions of Tailwind CSS.
|
|
23
|
+
|
|
24
|
+
/** @typedef {'terminal' | 'actionable' | 'jumpable'} PseudoProperty */
|
|
25
|
+
|
|
26
|
+
/** @type {Record<string, PseudoProperty[]>} */
|
|
27
|
+
let elementProperties = {
|
|
28
|
+
// Pseudo elements from the spec
|
|
29
|
+
'::after': ['terminal', 'jumpable'],
|
|
30
|
+
'::backdrop': ['terminal', 'jumpable'],
|
|
31
|
+
'::before': ['terminal', 'jumpable'],
|
|
32
|
+
'::cue': ['terminal'],
|
|
33
|
+
'::cue-region': ['terminal'],
|
|
34
|
+
'::first-letter': ['terminal', 'jumpable'],
|
|
35
|
+
'::first-line': ['terminal', 'jumpable'],
|
|
36
|
+
'::grammar-error': ['terminal'],
|
|
37
|
+
'::marker': ['terminal', 'jumpable'],
|
|
38
|
+
'::part': ['terminal', 'actionable'],
|
|
39
|
+
'::placeholder': ['terminal', 'jumpable'],
|
|
40
|
+
'::selection': ['terminal', 'jumpable'],
|
|
41
|
+
'::slotted': ['terminal'],
|
|
42
|
+
'::spelling-error': ['terminal'],
|
|
43
|
+
'::target-text': ['terminal'],
|
|
44
|
+
|
|
45
|
+
// Pseudo elements from the spec with special rules
|
|
46
|
+
'::file-selector-button': ['terminal', 'actionable'],
|
|
47
|
+
|
|
48
|
+
// Library-specific pseudo elements used by component libraries
|
|
49
|
+
// These are Shadow DOM-like
|
|
50
|
+
'::deep': ['actionable'],
|
|
51
|
+
'::v-deep': ['actionable'],
|
|
52
|
+
'::ng-deep': ['actionable'],
|
|
53
|
+
|
|
54
|
+
// Note: As a rule, double colons (::) should be used instead of a single colon
|
|
55
|
+
// (:). This distinguishes pseudo-classes from pseudo-elements. However, since
|
|
56
|
+
// this distinction was not present in older versions of the W3C spec, most
|
|
57
|
+
// browsers support both syntaxes for the original pseudo-elements.
|
|
58
|
+
':after': ['terminal', 'jumpable'],
|
|
59
|
+
':before': ['terminal', 'jumpable'],
|
|
60
|
+
':first-letter': ['terminal', 'jumpable'],
|
|
61
|
+
':first-line': ['terminal', 'jumpable'],
|
|
62
|
+
|
|
63
|
+
// The default value is used when the pseudo-element is not recognized
|
|
64
|
+
// Because it's not recognized, we don't know if it's terminal or not
|
|
65
|
+
// So we assume it can be moved AND can have user-action pseudo classes attached to it
|
|
66
|
+
__default__: ['terminal', 'actionable'],
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {Selector} sel
|
|
71
|
+
* @returns {Selector}
|
|
72
|
+
*/
|
|
73
|
+
export function movePseudos(sel) {
|
|
74
|
+
let [pseudos] = movablePseudos(sel)
|
|
75
|
+
|
|
76
|
+
// Remove all pseudo elements from their respective selectors
|
|
77
|
+
pseudos.forEach(([sel, pseudo]) => sel.removeChild(pseudo))
|
|
78
|
+
|
|
79
|
+
// Re-add them to the end of the selector in the correct order.
|
|
80
|
+
// This moves terminal pseudo elements to the end of the
|
|
81
|
+
// selector otherwise the selector will not be valid.
|
|
82
|
+
//
|
|
83
|
+
// Examples:
|
|
84
|
+
// - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
|
|
85
|
+
// - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
|
|
86
|
+
//
|
|
87
|
+
// The selector `::before:hover` does not work but we
|
|
88
|
+
// can make it work for you by flipping the order.
|
|
89
|
+
sel.nodes.push(...pseudos.map(([, pseudo]) => pseudo))
|
|
90
|
+
|
|
91
|
+
return sel
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** @typedef {[sel: Selector, pseudo: Pseudo, attachedTo: Pseudo | null]} MovablePseudo */
|
|
95
|
+
/** @typedef {[pseudos: MovablePseudo[], lastSeenElement: Pseudo | null]} MovablePseudosResult */
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {Selector} sel
|
|
99
|
+
* @returns {MovablePseudosResult}
|
|
100
|
+
*/
|
|
101
|
+
function movablePseudos(sel) {
|
|
102
|
+
/** @type {MovablePseudo[]} */
|
|
103
|
+
let buffer = []
|
|
104
|
+
|
|
105
|
+
/** @type {Pseudo | null} */
|
|
106
|
+
let lastSeenElement = null
|
|
107
|
+
|
|
108
|
+
for (let node of sel.nodes) {
|
|
109
|
+
if (node.type === 'combinator') {
|
|
110
|
+
buffer = buffer.filter(([, node]) => propertiesForPseudo(node).includes('jumpable'))
|
|
111
|
+
lastSeenElement = null
|
|
112
|
+
} else if (node.type === 'pseudo') {
|
|
113
|
+
if (isMovablePseudoElement(node)) {
|
|
114
|
+
lastSeenElement = node
|
|
115
|
+
buffer.push([sel, node, null])
|
|
116
|
+
} else if (lastSeenElement && isAttachablePseudoClass(node, lastSeenElement)) {
|
|
117
|
+
buffer.push([sel, node, lastSeenElement])
|
|
118
|
+
} else {
|
|
119
|
+
lastSeenElement = null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (let sub of node.nodes ?? []) {
|
|
123
|
+
let [movable, lastSeenElementInSub] = movablePseudos(sub)
|
|
124
|
+
lastSeenElement = lastSeenElementInSub || lastSeenElement
|
|
125
|
+
buffer.push(...movable)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return [buffer, lastSeenElement]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @param {Node} node
|
|
135
|
+
* @returns {boolean}
|
|
136
|
+
*/
|
|
137
|
+
function isPseudoElement(node) {
|
|
138
|
+
return node.value.startsWith('::') || elementProperties[node.value] !== undefined
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {Node} node
|
|
143
|
+
* @returns {boolean}
|
|
144
|
+
*/
|
|
145
|
+
function isMovablePseudoElement(node) {
|
|
146
|
+
return isPseudoElement(node) && propertiesForPseudo(node).includes('terminal')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @param {Node} node
|
|
151
|
+
* @param {Pseudo} pseudo
|
|
152
|
+
* @returns {boolean}
|
|
153
|
+
*/
|
|
154
|
+
function isAttachablePseudoClass(node, pseudo) {
|
|
155
|
+
if (node.type !== 'pseudo') return false
|
|
156
|
+
if (isPseudoElement(node)) return false
|
|
157
|
+
|
|
158
|
+
return propertiesForPseudo(pseudo).includes('actionable')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @param {Pseudo} pseudo
|
|
163
|
+
* @returns {PseudoProperty[]}
|
|
164
|
+
*/
|
|
165
|
+
function propertiesForPseudo(pseudo) {
|
|
166
|
+
return elementProperties[pseudo.value] ?? elementProperties.__default__
|
|
167
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) Bogdan Chadkin <trysound@yandex.ru>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
|
4
|
+
obtaining a copy of this software and associated documentation
|
|
5
|
+
files (the "Software"), to deal in the Software without
|
|
6
|
+
restriction, including without limitation the rights to use,
|
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the
|
|
9
|
+
Software is furnished to do so, subject to the following
|
|
10
|
+
conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be
|
|
13
|
+
included in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|