tailwindcss 0.0.0-insiders.d87bdb2 → 0.0.0-insiders.db475be
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 +33 -1
- package/lib/corePlugins.js +34 -4
- package/lib/lib/defaultExtractor.js +2 -0
- package/lib/lib/expandApplyAtRules.js +7 -4
- package/lib/lib/generateRules.js +48 -4
- package/lib/lib/setupContextUtils.js +55 -2
- package/lib/util/prefixSelector.js +4 -5
- package/package.json +6 -5
- package/peers/index.js +56 -47
- package/src/corePlugins.js +37 -4
- package/src/lib/defaultExtractor.js +2 -0
- package/src/lib/expandApplyAtRules.js +5 -5
- package/src/lib/generateRules.js +57 -5
- package/src/lib/setupContextUtils.js +57 -4
- package/src/util/prefixSelector.js +7 -5
package/CHANGELOG.md
CHANGED
|
@@ -9,9 +9,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Fixed
|
|
11
11
|
|
|
12
|
+
- Remove opacity variables from `:visited` pseudo class ([#7458](https://github.com/tailwindlabs/tailwindcss/pull/7458))
|
|
13
|
+
- Support arbitrary values + calc + theme with quotes ([#7462](https://github.com/tailwindlabs/tailwindcss/pull/7462))
|
|
14
|
+
|
|
15
|
+
## [3.0.22] - 2022-02-11
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Temporarily move postcss to dependencies ([#7424](https://github.com/tailwindlabs/tailwindcss/pull/7424))
|
|
20
|
+
|
|
21
|
+
## [3.0.21] - 2022-02-10
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Move prettier plugin to dev dependencies ([#7418](https://github.com/tailwindlabs/tailwindcss/pull/7418))
|
|
26
|
+
|
|
27
|
+
## [3.0.20] - 2022-02-10
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Expose `context.sortClassList(classes)` ([#7412](https://github.com/tailwindlabs/tailwindcss/pull/7412))
|
|
32
|
+
|
|
33
|
+
## [3.0.19] - 2022-02-07
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
12
37
|
- Fix preflight border color fallback ([#7288](https://github.com/tailwindlabs/tailwindcss/pull/7288))
|
|
13
38
|
- Correctly parse shadow lengths without a leading zero ([#7289](https://github.com/tailwindlabs/tailwindcss/pull/7289))
|
|
14
39
|
- Don't crash when scanning extremely long class candidates ([#7331](https://github.com/tailwindlabs/tailwindcss/pull/7331))
|
|
40
|
+
- Use less hacky fix for URLs detected as custom properties ([#7275](https://github.com/tailwindlabs/tailwindcss/pull/7275))
|
|
41
|
+
- Correctly generate negative utilities when dash is before the prefix ([#7295](https://github.com/tailwindlabs/tailwindcss/pull/7295))
|
|
42
|
+
- Detect prefixed negative utilities in the safelist ([#7295](https://github.com/tailwindlabs/tailwindcss/pull/7295))
|
|
15
43
|
|
|
16
44
|
## [3.0.18] - 2022-01-28
|
|
17
45
|
|
|
@@ -1840,7 +1868,11 @@ No release notes
|
|
|
1840
1868
|
|
|
1841
1869
|
- Everything!
|
|
1842
1870
|
|
|
1843
|
-
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.
|
|
1871
|
+
[unreleased]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.22...HEAD
|
|
1872
|
+
[3.0.22]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.21...v3.0.22
|
|
1873
|
+
[3.0.21]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.20...v3.0.21
|
|
1874
|
+
[3.0.20]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.19...v3.0.20
|
|
1875
|
+
[3.0.19]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.18...v3.0.19
|
|
1844
1876
|
[3.0.18]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.17...v3.0.18
|
|
1845
1877
|
[3.0.17]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.16...v3.0.17
|
|
1846
1878
|
[3.0.16]: https://github.com/tailwindlabs/tailwindcss/compare/v3.0.15...v3.0.16
|
package/lib/corePlugins.js
CHANGED
|
@@ -116,7 +116,28 @@ let variantPlugins = {
|
|
|
116
116
|
'last-of-type',
|
|
117
117
|
'only-of-type',
|
|
118
118
|
// State
|
|
119
|
-
|
|
119
|
+
[
|
|
120
|
+
'visited',
|
|
121
|
+
({ container })=>{
|
|
122
|
+
let toRemove = [
|
|
123
|
+
'--tw-text-opacity',
|
|
124
|
+
'--tw-border-opacity',
|
|
125
|
+
'--tw-bg-opacity'
|
|
126
|
+
];
|
|
127
|
+
container.walkDecls((decl)=>{
|
|
128
|
+
if (toRemove.includes(decl.prop)) {
|
|
129
|
+
decl.remove();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
for (const varName of toRemove){
|
|
133
|
+
if (decl.value.includes(`/ var(${varName})`)) {
|
|
134
|
+
decl.value = decl.value.replace(`/ var(${varName})`, '');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return ':visited';
|
|
139
|
+
},
|
|
140
|
+
],
|
|
120
141
|
'target',
|
|
121
142
|
[
|
|
122
143
|
'open',
|
|
@@ -149,13 +170,22 @@ let variantPlugins = {
|
|
|
149
170
|
]
|
|
150
171
|
);
|
|
151
172
|
for (let [variantName, state] of pseudoVariants){
|
|
152
|
-
addVariant(variantName,
|
|
173
|
+
addVariant(variantName, (ctx)=>{
|
|
174
|
+
let result = typeof state === 'function' ? state(ctx) : state;
|
|
175
|
+
return `&${result}`;
|
|
176
|
+
});
|
|
153
177
|
}
|
|
154
178
|
for (let [variantName1, state1] of pseudoVariants){
|
|
155
|
-
addVariant(`group-${variantName1}`,
|
|
179
|
+
addVariant(`group-${variantName1}`, (ctx)=>{
|
|
180
|
+
let result = typeof state1 === 'function' ? state1(ctx) : state1;
|
|
181
|
+
return `:merge(.group)${result} &`;
|
|
182
|
+
});
|
|
156
183
|
}
|
|
157
184
|
for (let [variantName2, state2] of pseudoVariants){
|
|
158
|
-
addVariant(`peer-${variantName2}`,
|
|
185
|
+
addVariant(`peer-${variantName2}`, (ctx)=>{
|
|
186
|
+
let result = typeof state2 === 'function' ? state2(ctx) : state2;
|
|
187
|
+
return `:merge(.peer)${result} ~ &`;
|
|
188
|
+
});
|
|
159
189
|
}
|
|
160
190
|
},
|
|
161
191
|
directionVariants: ({ addVariant })=>{
|
|
@@ -13,6 +13,8 @@ const PATTERNS = [
|
|
|
13
13
|
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source,
|
|
14
14
|
/([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source,
|
|
15
15
|
/([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source,
|
|
16
|
+
/([^<>"'`\s]*\[[^<>"'`\s]*\('[^"`\s]*'\)+\])/.source,
|
|
17
|
+
/([^<>"'`\s]*\[[^<>"'`\s]*\("[^'`\s]*"\)+\])/.source,
|
|
16
18
|
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source,
|
|
17
19
|
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source,
|
|
18
20
|
/([^<>"'`\s]*\[[^<>"'`\s]*:[^\]\s]*\])/.source,
|
|
@@ -140,11 +140,14 @@ function processApply(root, context) {
|
|
|
140
140
|
throw apply.error(`@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`);
|
|
141
141
|
}
|
|
142
142
|
for (let applyCandidate of applyCandidates){
|
|
143
|
+
if ([
|
|
144
|
+
prefix(context, 'group'),
|
|
145
|
+
prefix(context, 'peer')
|
|
146
|
+
].includes(applyCandidate)) {
|
|
147
|
+
// TODO: Link to specific documentation page with error code.
|
|
148
|
+
throw apply.error(`@apply should not be used with the '${applyCandidate}' utility`);
|
|
149
|
+
}
|
|
143
150
|
if (!applyClassCache.has(applyCandidate)) {
|
|
144
|
-
if (applyCandidate === prefix(context, 'group')) {
|
|
145
|
-
// TODO: Link to specific documentation page with error code.
|
|
146
|
-
throw apply.error(`@apply should not be used with the '${applyCandidate}' utility`);
|
|
147
|
-
}
|
|
148
151
|
throw apply.error(`The \`${applyCandidate}\` class does not exist. If \`${applyCandidate}\` is a custom class, make sure it is defined within a \`@layer\` directive.`);
|
|
149
152
|
}
|
|
150
153
|
let rules = applyClassCache.get(applyCandidate);
|
package/lib/lib/generateRules.js
CHANGED
|
@@ -72,8 +72,14 @@ function applyPrefix(matches, context) {
|
|
|
72
72
|
match[1].clone()
|
|
73
73
|
]
|
|
74
74
|
});
|
|
75
|
+
let classCandidate = match[1].raws.tailwind.classCandidate;
|
|
75
76
|
container.walkRules((r)=>{
|
|
76
|
-
|
|
77
|
+
// If this is a negative utility with a dash *before* the prefix we
|
|
78
|
+
// have to ensure that the generated selector matches the candidate
|
|
79
|
+
// Not doing this will cause `-tw-top-1` to generate the class `.tw--top-1`
|
|
80
|
+
// The disconnect between candidate <-> class can cause @apply to hard crash.
|
|
81
|
+
let shouldPrependNegative = classCandidate.startsWith('-');
|
|
82
|
+
r.selector = (0, _prefixSelector).default(context.tailwindConfig.prefix, r.selector, shouldPrependNegative);
|
|
77
83
|
});
|
|
78
84
|
match[1] = container.nodes[0];
|
|
79
85
|
}
|
|
@@ -222,6 +228,7 @@ function applyVariant(variant, matches, context) {
|
|
|
222
228
|
// .sm:underline {} is a variant of something in the utilities layer
|
|
223
229
|
// .sm:container {} is a variant of the container component
|
|
224
230
|
clone.nodes[0].raws.tailwind = {
|
|
231
|
+
...clone.nodes[0].raws.tailwind,
|
|
225
232
|
parentLayer: meta.layer
|
|
226
233
|
};
|
|
227
234
|
var _collectedFormats;
|
|
@@ -265,10 +272,32 @@ function parseRules(rule, cache, options = {}) {
|
|
|
265
272
|
}
|
|
266
273
|
const IS_VALID_PROPERTY_NAME = /^[a-z_-]/;
|
|
267
274
|
function isValidPropName(name) {
|
|
268
|
-
|
|
269
|
-
|
|
275
|
+
return IS_VALID_PROPERTY_NAME.test(name);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* @param {string} declaration
|
|
279
|
+
* @returns {boolean}
|
|
280
|
+
*/ function looksLikeUri(declaration) {
|
|
281
|
+
// Quick bailout for obvious non-urls
|
|
282
|
+
// This doesn't support schemes that don't use a leading // but that's unlikely to be a problem
|
|
283
|
+
if (!declaration.includes('://')) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
const url = new URL(declaration);
|
|
288
|
+
return url.scheme !== '' && url.host !== '';
|
|
289
|
+
} catch (err) {
|
|
290
|
+
// Definitely not a valid url
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
270
293
|
}
|
|
271
294
|
function isParsableCssValue(property, value) {
|
|
295
|
+
// We don't want to to treat [https://example.com] as a custom property
|
|
296
|
+
// Even though, according to the CSS grammar, it's a totally valid CSS declaration
|
|
297
|
+
// So we short-circuit here by checking if the custom property looks like a url
|
|
298
|
+
if (looksLikeUri(`${property}:${value}`)) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
272
301
|
try {
|
|
273
302
|
_postcss.default.parse(`a{${property}:${value}}`).toResult();
|
|
274
303
|
return true;
|
|
@@ -348,6 +377,15 @@ function* resolveMatchedPlugins(classCandidate, context) {
|
|
|
348
377
|
function splitWithSeparator(input, separator) {
|
|
349
378
|
return input.split(new RegExp(`\\${separator}(?![^[]*\\])`, 'g'));
|
|
350
379
|
}
|
|
380
|
+
function* recordCandidates(matches, classCandidate) {
|
|
381
|
+
for (const match of matches){
|
|
382
|
+
match[1].raws.tailwind = {
|
|
383
|
+
...match[1].raws.tailwind,
|
|
384
|
+
classCandidate
|
|
385
|
+
};
|
|
386
|
+
yield match;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
351
389
|
function* resolveMatches(candidate, context) {
|
|
352
390
|
let separator = context.tailwindConfig.separator;
|
|
353
391
|
let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse();
|
|
@@ -457,7 +495,9 @@ function* resolveMatches(candidate, context) {
|
|
|
457
495
|
]);
|
|
458
496
|
continue;
|
|
459
497
|
}
|
|
460
|
-
matches =
|
|
498
|
+
matches = matches.flat();
|
|
499
|
+
matches = Array.from(recordCandidates(matches, classCandidate));
|
|
500
|
+
matches = applyPrefix(matches, context);
|
|
461
501
|
if (important) {
|
|
462
502
|
matches = applyImportant(matches, context);
|
|
463
503
|
}
|
|
@@ -465,6 +505,10 @@ function* resolveMatches(candidate, context) {
|
|
|
465
505
|
matches = applyVariant(variant, matches, context);
|
|
466
506
|
}
|
|
467
507
|
for (let match1 of matches){
|
|
508
|
+
match1[1].raws.tailwind = {
|
|
509
|
+
...match1[1].raws.tailwind,
|
|
510
|
+
candidate
|
|
511
|
+
};
|
|
468
512
|
// Apply final format selector
|
|
469
513
|
if (match1[0].collectedFormats) {
|
|
470
514
|
let finalFormat = (0, _formatVariantSelector).formatVariantSelector('&', ...match1[0].collectedFormats);
|
|
@@ -24,6 +24,7 @@ var _toPath = require("../util/toPath");
|
|
|
24
24
|
var _log = _interopRequireDefault(require("../util/log"));
|
|
25
25
|
var _negateValue = _interopRequireDefault(require("../util/negateValue"));
|
|
26
26
|
var _isValidArbitraryValue = _interopRequireDefault(require("../util/isValidArbitraryValue"));
|
|
27
|
+
var _generateRules = require("./generateRules");
|
|
27
28
|
function _interopRequireDefault(obj) {
|
|
28
29
|
return obj && obj.__esModule ? obj : {
|
|
29
30
|
default: obj
|
|
@@ -50,6 +51,10 @@ function _interopRequireWildcard(obj) {
|
|
|
50
51
|
return newObj;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
54
|
+
function prefix(context, selector) {
|
|
55
|
+
let prefix1 = context.tailwindConfig.prefix;
|
|
56
|
+
return typeof prefix1 === 'function' ? prefix1(selector) : prefix1 + selector;
|
|
57
|
+
}
|
|
53
58
|
function parseVariantFormatString(input) {
|
|
54
59
|
if (input.includes('{')) {
|
|
55
60
|
if (!isBalanced(input)) throw new Error(`Your { and } are unbalanced.`);
|
|
@@ -673,18 +678,31 @@ function registerPlugins(plugins, context) {
|
|
|
673
678
|
}
|
|
674
679
|
if (checks.length > 0) {
|
|
675
680
|
let patternMatchingCount = new Map();
|
|
681
|
+
let prefixLength = context.tailwindConfig.prefix.length;
|
|
676
682
|
for (let util of classList){
|
|
677
683
|
let utils = Array.isArray(util) ? (()=>{
|
|
678
684
|
let [utilName, options] = util;
|
|
679
685
|
var ref;
|
|
680
|
-
let
|
|
686
|
+
let values = Object.keys((ref = options === null || options === void 0 ? void 0 : options.values) !== null && ref !== void 0 ? ref : {});
|
|
687
|
+
let classes = values.map((value)=>(0, _nameClass).formatClass(utilName, value)
|
|
681
688
|
);
|
|
682
689
|
if (options === null || options === void 0 ? void 0 : options.supportsNegativeValues) {
|
|
690
|
+
// This is the normal negated version
|
|
691
|
+
// e.g. `-inset-1` or `-tw-inset-1`
|
|
683
692
|
classes = [
|
|
684
693
|
...classes,
|
|
685
694
|
...classes.map((cls)=>'-' + cls
|
|
686
695
|
)
|
|
687
696
|
];
|
|
697
|
+
// This is the negated version *after* the prefix
|
|
698
|
+
// e.g. `tw--inset-1`
|
|
699
|
+
// The prefix is already attached to util name
|
|
700
|
+
// So we add the negative after the prefix
|
|
701
|
+
classes = [
|
|
702
|
+
...classes,
|
|
703
|
+
...classes.map((cls)=>cls.slice(0, prefixLength) + '-' + cls.slice(prefixLength)
|
|
704
|
+
),
|
|
705
|
+
];
|
|
688
706
|
}
|
|
689
707
|
return classes;
|
|
690
708
|
})() : [
|
|
@@ -723,9 +741,44 @@ function registerPlugins(plugins, context) {
|
|
|
723
741
|
}
|
|
724
742
|
}
|
|
725
743
|
}
|
|
744
|
+
// A list of utilities that are used by certain Tailwind CSS utilities but
|
|
745
|
+
// that don't exist on their own. This will result in them "not existing" and
|
|
746
|
+
// sorting could be weird since you still require them in order to make the
|
|
747
|
+
// host utitlies work properly. (Thanks Biology)
|
|
748
|
+
let parasiteUtilities = new Set([
|
|
749
|
+
prefix(context, 'group'),
|
|
750
|
+
prefix(context, 'peer')
|
|
751
|
+
]);
|
|
752
|
+
context.sortClassList = function sortClassList(classes) {
|
|
753
|
+
let sortedClassNames = new Map();
|
|
754
|
+
for (let [sort, rule] of (0, _generateRules).generateRules(new Set(classes), context)){
|
|
755
|
+
if (sortedClassNames.has(rule.raws.tailwind.candidate)) continue;
|
|
756
|
+
sortedClassNames.set(rule.raws.tailwind.candidate, sort);
|
|
757
|
+
}
|
|
758
|
+
return classes.map((className)=>{
|
|
759
|
+
var ref;
|
|
760
|
+
let order = (ref = sortedClassNames.get(className)) !== null && ref !== void 0 ? ref : null;
|
|
761
|
+
if (order === null && parasiteUtilities.has(className)) {
|
|
762
|
+
// This will make sure that it is at the very beginning of the
|
|
763
|
+
// `components` layer which technically means 'before any
|
|
764
|
+
// components'.
|
|
765
|
+
order = context.layerOrder.components;
|
|
766
|
+
}
|
|
767
|
+
return [
|
|
768
|
+
className,
|
|
769
|
+
order
|
|
770
|
+
];
|
|
771
|
+
}).sort(([, a], [, z])=>{
|
|
772
|
+
if (a === z) return 0;
|
|
773
|
+
if (a === null) return -1;
|
|
774
|
+
if (z === null) return 1;
|
|
775
|
+
return (0, _bigSign).default(a - z);
|
|
776
|
+
}).map(([className])=>className
|
|
777
|
+
);
|
|
778
|
+
};
|
|
726
779
|
// Generate a list of strings for autocompletion purposes, e.g.
|
|
727
780
|
// ['uppercase', 'lowercase', ...]
|
|
728
|
-
context.getClassList = function() {
|
|
781
|
+
context.getClassList = function getClassList() {
|
|
729
782
|
let output = [];
|
|
730
783
|
for (let util of classList){
|
|
731
784
|
if (Array.isArray(util)) {
|
|
@@ -4,18 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
exports.default = _default;
|
|
6
6
|
var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
|
|
7
|
-
var _tap = require("./tap");
|
|
8
7
|
function _interopRequireDefault(obj) {
|
|
9
8
|
return obj && obj.__esModule ? obj : {
|
|
10
9
|
default: obj
|
|
11
10
|
};
|
|
12
11
|
}
|
|
13
|
-
function _default(prefix, selector) {
|
|
12
|
+
function _default(prefix, selector, prependNegative = false) {
|
|
14
13
|
return (0, _postcssSelectorParser).default((selectors)=>{
|
|
15
14
|
selectors.walkClasses((classSelector)=>{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
})
|
|
15
|
+
let baseClass = classSelector.value;
|
|
16
|
+
let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-');
|
|
17
|
+
classSelector.value = shouldPlaceNegativeBeforePrefix ? `-${prefix}${baseClass.slice(1)}` : `${prefix}${baseClass}`;
|
|
19
18
|
});
|
|
20
19
|
}).processSync(selector);
|
|
21
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailwindcss",
|
|
3
|
-
"version": "0.0.0-insiders.
|
|
3
|
+
"version": "0.0.0-insiders.db475be",
|
|
4
4
|
"description": "A utility-first CSS framework for rapidly building custom user interfaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"@swc/register": "^0.1.10",
|
|
45
45
|
"autoprefixer": "^10.4.2",
|
|
46
46
|
"cssnano": "^5.0.16",
|
|
47
|
-
"esbuild": "^0.14.
|
|
47
|
+
"esbuild": "^0.14.21",
|
|
48
48
|
"eslint": "^8.8.0",
|
|
49
49
|
"eslint-config-prettier": "^8.3.0",
|
|
50
50
|
"eslint-plugin-prettier": "^4.0.0",
|
|
51
|
-
"jest": "^27.
|
|
52
|
-
"jest-diff": "^27.
|
|
53
|
-
"postcss": "^8.4.5",
|
|
51
|
+
"jest": "^27.5.1",
|
|
52
|
+
"jest-diff": "^27.5.1",
|
|
54
53
|
"prettier": "^2.5.1",
|
|
54
|
+
"prettier-plugin-tailwindcss": "^0.1.7",
|
|
55
55
|
"rimraf": "^3.0.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"is-glob": "^4.0.3",
|
|
73
73
|
"normalize-path": "^3.0.0",
|
|
74
74
|
"object-hash": "^2.2.0",
|
|
75
|
+
"postcss": "^8.4.6",
|
|
75
76
|
"postcss-js": "^4.0.0",
|
|
76
77
|
"postcss-load-config": "^3.1.0",
|
|
77
78
|
"postcss-nested": "5.0.6",
|
package/peers/index.js
CHANGED
|
@@ -22,31 +22,31 @@ var require_picocolors = __commonJS({
|
|
|
22
22
|
};
|
|
23
23
|
var createColors = (enabled = isColorSupported) => ({
|
|
24
24
|
isColorSupported: enabled,
|
|
25
|
-
reset: enabled ? (s) =>
|
|
26
|
-
bold: enabled ? formatter("
|
|
27
|
-
dim: enabled ? formatter("
|
|
28
|
-
italic: enabled ? formatter("
|
|
29
|
-
underline: enabled ? formatter("
|
|
30
|
-
inverse: enabled ? formatter("
|
|
31
|
-
hidden: enabled ? formatter("
|
|
32
|
-
strikethrough: enabled ? formatter("
|
|
33
|
-
black: enabled ? formatter("
|
|
34
|
-
red: enabled ? formatter("
|
|
35
|
-
green: enabled ? formatter("
|
|
36
|
-
yellow: enabled ? formatter("
|
|
37
|
-
blue: enabled ? formatter("
|
|
38
|
-
magenta: enabled ? formatter("
|
|
39
|
-
cyan: enabled ? formatter("
|
|
40
|
-
white: enabled ? formatter("
|
|
41
|
-
gray: enabled ? formatter("
|
|
42
|
-
bgBlack: enabled ? formatter("
|
|
43
|
-
bgRed: enabled ? formatter("
|
|
44
|
-
bgGreen: enabled ? formatter("
|
|
45
|
-
bgYellow: enabled ? formatter("
|
|
46
|
-
bgBlue: enabled ? formatter("
|
|
47
|
-
bgMagenta: enabled ? formatter("
|
|
48
|
-
bgCyan: enabled ? formatter("
|
|
49
|
-
bgWhite: enabled ? formatter("
|
|
25
|
+
reset: enabled ? (s) => `\x1B[0m${s}\x1B[0m` : String,
|
|
26
|
+
bold: enabled ? formatter("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m") : String,
|
|
27
|
+
dim: enabled ? formatter("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m") : String,
|
|
28
|
+
italic: enabled ? formatter("\x1B[3m", "\x1B[23m") : String,
|
|
29
|
+
underline: enabled ? formatter("\x1B[4m", "\x1B[24m") : String,
|
|
30
|
+
inverse: enabled ? formatter("\x1B[7m", "\x1B[27m") : String,
|
|
31
|
+
hidden: enabled ? formatter("\x1B[8m", "\x1B[28m") : String,
|
|
32
|
+
strikethrough: enabled ? formatter("\x1B[9m", "\x1B[29m") : String,
|
|
33
|
+
black: enabled ? formatter("\x1B[30m", "\x1B[39m") : String,
|
|
34
|
+
red: enabled ? formatter("\x1B[31m", "\x1B[39m") : String,
|
|
35
|
+
green: enabled ? formatter("\x1B[32m", "\x1B[39m") : String,
|
|
36
|
+
yellow: enabled ? formatter("\x1B[33m", "\x1B[39m") : String,
|
|
37
|
+
blue: enabled ? formatter("\x1B[34m", "\x1B[39m") : String,
|
|
38
|
+
magenta: enabled ? formatter("\x1B[35m", "\x1B[39m") : String,
|
|
39
|
+
cyan: enabled ? formatter("\x1B[36m", "\x1B[39m") : String,
|
|
40
|
+
white: enabled ? formatter("\x1B[37m", "\x1B[39m") : String,
|
|
41
|
+
gray: enabled ? formatter("\x1B[90m", "\x1B[39m") : String,
|
|
42
|
+
bgBlack: enabled ? formatter("\x1B[40m", "\x1B[49m") : String,
|
|
43
|
+
bgRed: enabled ? formatter("\x1B[41m", "\x1B[49m") : String,
|
|
44
|
+
bgGreen: enabled ? formatter("\x1B[42m", "\x1B[49m") : String,
|
|
45
|
+
bgYellow: enabled ? formatter("\x1B[43m", "\x1B[49m") : String,
|
|
46
|
+
bgBlue: enabled ? formatter("\x1B[44m", "\x1B[49m") : String,
|
|
47
|
+
bgMagenta: enabled ? formatter("\x1B[45m", "\x1B[49m") : String,
|
|
48
|
+
bgCyan: enabled ? formatter("\x1B[46m", "\x1B[49m") : String,
|
|
49
|
+
bgWhite: enabled ? formatter("\x1B[47m", "\x1B[49m") : String
|
|
50
50
|
});
|
|
51
51
|
module2.exports = createColors();
|
|
52
52
|
module2.exports.createColors = createColors;
|
|
@@ -4407,11 +4407,13 @@ var require_parser = __commonJS({
|
|
|
4407
4407
|
if (brackets.length > 0)
|
|
4408
4408
|
this.unclosedBracket(bracket);
|
|
4409
4409
|
if (end && colon) {
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4410
|
+
if (!customProperty) {
|
|
4411
|
+
while (tokens.length) {
|
|
4412
|
+
token = tokens[tokens.length - 1][0];
|
|
4413
|
+
if (token !== "space" && token !== "comment")
|
|
4414
|
+
break;
|
|
4415
|
+
this.tokenizer.back(tokens.pop());
|
|
4416
|
+
}
|
|
4415
4417
|
}
|
|
4416
4418
|
this.decl(tokens, customProperty);
|
|
4417
4419
|
} else {
|
|
@@ -4467,7 +4469,14 @@ var require_parser = __commonJS({
|
|
|
4467
4469
|
node.raws.before += node.prop[0];
|
|
4468
4470
|
node.prop = node.prop.slice(1);
|
|
4469
4471
|
}
|
|
4470
|
-
let firstSpaces =
|
|
4472
|
+
let firstSpaces = [];
|
|
4473
|
+
let next;
|
|
4474
|
+
while (tokens.length) {
|
|
4475
|
+
next = tokens[0][0];
|
|
4476
|
+
if (next !== "space" && next !== "comment")
|
|
4477
|
+
break;
|
|
4478
|
+
firstSpaces.push(tokens.shift());
|
|
4479
|
+
}
|
|
4471
4480
|
this.precheckMissedSemicolon(tokens);
|
|
4472
4481
|
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
4473
4482
|
token = tokens[i];
|
|
@@ -4499,12 +4508,11 @@ var require_parser = __commonJS({
|
|
|
4499
4508
|
}
|
|
4500
4509
|
}
|
|
4501
4510
|
let hasWord = tokens.some((i) => i[0] !== "space" && i[0] !== "comment");
|
|
4502
|
-
this.raw(node, "value", tokens);
|
|
4503
4511
|
if (hasWord) {
|
|
4504
|
-
node.raws.between += firstSpaces;
|
|
4505
|
-
|
|
4506
|
-
node.value = firstSpaces + node.value;
|
|
4512
|
+
node.raws.between += firstSpaces.map((i) => i[1]).join("");
|
|
4513
|
+
firstSpaces = [];
|
|
4507
4514
|
}
|
|
4515
|
+
this.raw(node, "value", firstSpaces.concat(tokens), customProperty);
|
|
4508
4516
|
if (node.value.includes(":") && !customProperty) {
|
|
4509
4517
|
this.checkMissedSemicolon(tokens);
|
|
4510
4518
|
}
|
|
@@ -4635,28 +4643,25 @@ var require_parser = __commonJS({
|
|
|
4635
4643
|
if (node.type !== "comment")
|
|
4636
4644
|
this.semicolon = false;
|
|
4637
4645
|
}
|
|
4638
|
-
raw(node, prop, tokens) {
|
|
4646
|
+
raw(node, prop, tokens, customProperty) {
|
|
4639
4647
|
let token, type;
|
|
4640
4648
|
let length = tokens.length;
|
|
4641
4649
|
let value = "";
|
|
4642
4650
|
let clean = true;
|
|
4643
4651
|
let next, prev;
|
|
4644
|
-
let pattern = /^([#.|])?(\w)+/i;
|
|
4645
4652
|
for (let i = 0; i < length; i += 1) {
|
|
4646
4653
|
token = tokens[i];
|
|
4647
4654
|
type = token[0];
|
|
4648
|
-
if (type === "
|
|
4655
|
+
if (type === "space" && i === length - 1 && !customProperty) {
|
|
4656
|
+
clean = false;
|
|
4657
|
+
} else if (type === "comment") {
|
|
4649
4658
|
prev = tokens[i - 1];
|
|
4650
4659
|
next = tokens[i + 1];
|
|
4651
|
-
if (prev[0] !== "space" && next[0] !== "space"
|
|
4660
|
+
if (prev && next && prev[0] !== "space" && next[0] !== "space") {
|
|
4652
4661
|
value += token[1];
|
|
4653
4662
|
} else {
|
|
4654
4663
|
clean = false;
|
|
4655
4664
|
}
|
|
4656
|
-
continue;
|
|
4657
|
-
}
|
|
4658
|
-
if (type === "comment" || type === "space" && i === length - 1) {
|
|
4659
|
-
clean = false;
|
|
4660
4665
|
} else {
|
|
4661
4666
|
value += token[1];
|
|
4662
4667
|
}
|
|
@@ -5356,8 +5361,12 @@ var require_no_work_result = __commonJS({
|
|
|
5356
5361
|
} catch (error) {
|
|
5357
5362
|
this.error = error;
|
|
5358
5363
|
}
|
|
5359
|
-
this.
|
|
5360
|
-
|
|
5364
|
+
if (this.error) {
|
|
5365
|
+
throw this.error;
|
|
5366
|
+
} else {
|
|
5367
|
+
this._root = root;
|
|
5368
|
+
return root;
|
|
5369
|
+
}
|
|
5361
5370
|
}
|
|
5362
5371
|
get messages() {
|
|
5363
5372
|
return [];
|
|
@@ -5408,7 +5417,7 @@ var require_processor = __commonJS({
|
|
|
5408
5417
|
var Root = require_root();
|
|
5409
5418
|
var Processor = class {
|
|
5410
5419
|
constructor(plugins = []) {
|
|
5411
|
-
this.version = "8.4.
|
|
5420
|
+
this.version = "8.4.6";
|
|
5412
5421
|
this.plugins = this.normalize(plugins);
|
|
5413
5422
|
}
|
|
5414
5423
|
use(plugin) {
|
|
@@ -19734,7 +19743,7 @@ var require_parse_cst = __commonJS({
|
|
|
19734
19743
|
str += "\b";
|
|
19735
19744
|
break;
|
|
19736
19745
|
case "e":
|
|
19737
|
-
str += "
|
|
19746
|
+
str += "\x1B";
|
|
19738
19747
|
break;
|
|
19739
19748
|
case "f":
|
|
19740
19749
|
str += "\f";
|
package/src/corePlugins.js
CHANGED
|
@@ -70,7 +70,28 @@ export let variantPlugins = {
|
|
|
70
70
|
'only-of-type',
|
|
71
71
|
|
|
72
72
|
// State
|
|
73
|
-
|
|
73
|
+
[
|
|
74
|
+
'visited',
|
|
75
|
+
({ container }) => {
|
|
76
|
+
let toRemove = ['--tw-text-opacity', '--tw-border-opacity', '--tw-bg-opacity']
|
|
77
|
+
|
|
78
|
+
container.walkDecls((decl) => {
|
|
79
|
+
if (toRemove.includes(decl.prop)) {
|
|
80
|
+
decl.remove()
|
|
81
|
+
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for (const varName of toRemove) {
|
|
86
|
+
if (decl.value.includes(`/ var(${varName})`)) {
|
|
87
|
+
decl.value = decl.value.replace(`/ var(${varName})`, '')
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
return ':visited'
|
|
93
|
+
},
|
|
94
|
+
],
|
|
74
95
|
'target',
|
|
75
96
|
['open', '[open]'],
|
|
76
97
|
|
|
@@ -100,15 +121,27 @@ export let variantPlugins = {
|
|
|
100
121
|
].map((variant) => (Array.isArray(variant) ? variant : [variant, `:${variant}`]))
|
|
101
122
|
|
|
102
123
|
for (let [variantName, state] of pseudoVariants) {
|
|
103
|
-
addVariant(variantName,
|
|
124
|
+
addVariant(variantName, (ctx) => {
|
|
125
|
+
let result = typeof state === 'function' ? state(ctx) : state
|
|
126
|
+
|
|
127
|
+
return `&${result}`
|
|
128
|
+
})
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
for (let [variantName, state] of pseudoVariants) {
|
|
107
|
-
addVariant(`group-${variantName}`,
|
|
132
|
+
addVariant(`group-${variantName}`, (ctx) => {
|
|
133
|
+
let result = typeof state === 'function' ? state(ctx) : state
|
|
134
|
+
|
|
135
|
+
return `:merge(.group)${result} &`
|
|
136
|
+
})
|
|
108
137
|
}
|
|
109
138
|
|
|
110
139
|
for (let [variantName, state] of pseudoVariants) {
|
|
111
|
-
addVariant(`peer-${variantName}`,
|
|
140
|
+
addVariant(`peer-${variantName}`, (ctx) => {
|
|
141
|
+
let result = typeof state === 'function' ? state(ctx) : state
|
|
142
|
+
|
|
143
|
+
return `:merge(.peer)${result} ~ &`
|
|
144
|
+
})
|
|
112
145
|
}
|
|
113
146
|
},
|
|
114
147
|
|
|
@@ -8,6 +8,8 @@ const PATTERNS = [
|
|
|
8
8
|
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source, // bg-[url("...")]
|
|
9
9
|
/([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source, // bg-[url('...'),url('...')]
|
|
10
10
|
/([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source, // bg-[url("..."),url("...")]
|
|
11
|
+
/([^<>"'`\s]*\[[^<>"'`\s]*\('[^"`\s]*'\)+\])/.source, // h-[calc(100%-theme('spacing.1'))]
|
|
12
|
+
/([^<>"'`\s]*\[[^<>"'`\s]*\("[^'`\s]*"\)+\])/.source, // h-[calc(100%-theme("spacing.1"))]
|
|
11
13
|
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
|
|
12
14
|
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
|
|
13
15
|
/([^<>"'`\s]*\[[^<>"'`\s]*:[^\]\s]*\])/.source, // `[attr:value]`
|
|
@@ -161,12 +161,12 @@ function processApply(root, context) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
for (let applyCandidate of applyCandidates) {
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
164
|
+
if ([prefix(context, 'group'), prefix(context, 'peer')].includes(applyCandidate)) {
|
|
165
|
+
// TODO: Link to specific documentation page with error code.
|
|
166
|
+
throw apply.error(`@apply should not be used with the '${applyCandidate}' utility`)
|
|
167
|
+
}
|
|
169
168
|
|
|
169
|
+
if (!applyClassCache.has(applyCandidate)) {
|
|
170
170
|
throw apply.error(
|
|
171
171
|
`The \`${applyCandidate}\` class does not exist. If \`${applyCandidate}\` is a custom class, make sure it is defined within a \`@layer\` directive.`
|
|
172
172
|
)
|
package/src/lib/generateRules.js
CHANGED
|
@@ -63,9 +63,23 @@ function applyPrefix(matches, context) {
|
|
|
63
63
|
let [meta] = match
|
|
64
64
|
if (meta.options.respectPrefix) {
|
|
65
65
|
let container = postcss.root({ nodes: [match[1].clone()] })
|
|
66
|
+
let classCandidate = match[1].raws.tailwind.classCandidate
|
|
67
|
+
|
|
66
68
|
container.walkRules((r) => {
|
|
67
|
-
|
|
69
|
+
// If this is a negative utility with a dash *before* the prefix we
|
|
70
|
+
// have to ensure that the generated selector matches the candidate
|
|
71
|
+
|
|
72
|
+
// Not doing this will cause `-tw-top-1` to generate the class `.tw--top-1`
|
|
73
|
+
// The disconnect between candidate <-> class can cause @apply to hard crash.
|
|
74
|
+
let shouldPrependNegative = classCandidate.startsWith('-')
|
|
75
|
+
|
|
76
|
+
r.selector = prefixSelector(
|
|
77
|
+
context.tailwindConfig.prefix,
|
|
78
|
+
r.selector,
|
|
79
|
+
shouldPrependNegative
|
|
80
|
+
)
|
|
68
81
|
})
|
|
82
|
+
|
|
69
83
|
match[1] = container.nodes[0]
|
|
70
84
|
}
|
|
71
85
|
}
|
|
@@ -220,7 +234,7 @@ function applyVariant(variant, matches, context) {
|
|
|
220
234
|
// For example:
|
|
221
235
|
// .sm:underline {} is a variant of something in the utilities layer
|
|
222
236
|
// .sm:container {} is a variant of the container component
|
|
223
|
-
clone.nodes[0].raws.tailwind = { parentLayer: meta.layer }
|
|
237
|
+
clone.nodes[0].raws.tailwind = { ...clone.nodes[0].raws.tailwind, parentLayer: meta.layer }
|
|
224
238
|
|
|
225
239
|
let withOffset = [
|
|
226
240
|
{
|
|
@@ -262,11 +276,37 @@ function parseRules(rule, cache, options = {}) {
|
|
|
262
276
|
const IS_VALID_PROPERTY_NAME = /^[a-z_-]/
|
|
263
277
|
|
|
264
278
|
function isValidPropName(name) {
|
|
265
|
-
|
|
266
|
-
|
|
279
|
+
return IS_VALID_PROPERTY_NAME.test(name)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* @param {string} declaration
|
|
284
|
+
* @returns {boolean}
|
|
285
|
+
*/
|
|
286
|
+
function looksLikeUri(declaration) {
|
|
287
|
+
// Quick bailout for obvious non-urls
|
|
288
|
+
// This doesn't support schemes that don't use a leading // but that's unlikely to be a problem
|
|
289
|
+
if (!declaration.includes('://')) {
|
|
290
|
+
return false
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
const url = new URL(declaration)
|
|
295
|
+
return url.scheme !== '' && url.host !== ''
|
|
296
|
+
} catch (err) {
|
|
297
|
+
// Definitely not a valid url
|
|
298
|
+
return false
|
|
299
|
+
}
|
|
267
300
|
}
|
|
268
301
|
|
|
269
302
|
function isParsableCssValue(property, value) {
|
|
303
|
+
// We don't want to to treat [https://example.com] as a custom property
|
|
304
|
+
// Even though, according to the CSS grammar, it's a totally valid CSS declaration
|
|
305
|
+
// So we short-circuit here by checking if the custom property looks like a url
|
|
306
|
+
if (looksLikeUri(`${property}:${value}`)) {
|
|
307
|
+
return false
|
|
308
|
+
}
|
|
309
|
+
|
|
270
310
|
try {
|
|
271
311
|
postcss.parse(`a{${property}:${value}}`).toResult()
|
|
272
312
|
return true
|
|
@@ -345,6 +385,14 @@ function splitWithSeparator(input, separator) {
|
|
|
345
385
|
return input.split(new RegExp(`\\${separator}(?![^[]*\\])`, 'g'))
|
|
346
386
|
}
|
|
347
387
|
|
|
388
|
+
function* recordCandidates(matches, classCandidate) {
|
|
389
|
+
for (const match of matches) {
|
|
390
|
+
match[1].raws.tailwind = { ...match[1].raws.tailwind, classCandidate }
|
|
391
|
+
|
|
392
|
+
yield match
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
348
396
|
function* resolveMatches(candidate, context) {
|
|
349
397
|
let separator = context.tailwindConfig.separator
|
|
350
398
|
let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse()
|
|
@@ -456,7 +504,9 @@ function* resolveMatches(candidate, context) {
|
|
|
456
504
|
continue
|
|
457
505
|
}
|
|
458
506
|
|
|
459
|
-
matches =
|
|
507
|
+
matches = matches.flat()
|
|
508
|
+
matches = Array.from(recordCandidates(matches, classCandidate))
|
|
509
|
+
matches = applyPrefix(matches, context)
|
|
460
510
|
|
|
461
511
|
if (important) {
|
|
462
512
|
matches = applyImportant(matches, context)
|
|
@@ -467,6 +517,8 @@ function* resolveMatches(candidate, context) {
|
|
|
467
517
|
}
|
|
468
518
|
|
|
469
519
|
for (let match of matches) {
|
|
520
|
+
match[1].raws.tailwind = { ...match[1].raws.tailwind, candidate }
|
|
521
|
+
|
|
470
522
|
// Apply final format selector
|
|
471
523
|
if (match[0].collectedFormats) {
|
|
472
524
|
let finalFormat = formatVariantSelector('&', ...match[0].collectedFormats)
|
|
@@ -19,6 +19,12 @@ import { toPath } from '../util/toPath'
|
|
|
19
19
|
import log from '../util/log'
|
|
20
20
|
import negateValue from '../util/negateValue'
|
|
21
21
|
import isValidArbitraryValue from '../util/isValidArbitraryValue'
|
|
22
|
+
import { generateRules } from './generateRules'
|
|
23
|
+
|
|
24
|
+
function prefix(context, selector) {
|
|
25
|
+
let prefix = context.tailwindConfig.prefix
|
|
26
|
+
return typeof prefix === 'function' ? prefix(selector) : prefix + selector
|
|
27
|
+
}
|
|
22
28
|
|
|
23
29
|
function parseVariantFormatString(input) {
|
|
24
30
|
if (input.includes('{')) {
|
|
@@ -666,17 +672,30 @@ function registerPlugins(plugins, context) {
|
|
|
666
672
|
|
|
667
673
|
if (checks.length > 0) {
|
|
668
674
|
let patternMatchingCount = new Map()
|
|
675
|
+
let prefixLength = context.tailwindConfig.prefix.length
|
|
669
676
|
|
|
670
677
|
for (let util of classList) {
|
|
671
678
|
let utils = Array.isArray(util)
|
|
672
679
|
? (() => {
|
|
673
680
|
let [utilName, options] = util
|
|
674
|
-
let
|
|
675
|
-
|
|
676
|
-
)
|
|
681
|
+
let values = Object.keys(options?.values ?? {})
|
|
682
|
+
let classes = values.map((value) => formatClass(utilName, value))
|
|
677
683
|
|
|
678
684
|
if (options?.supportsNegativeValues) {
|
|
685
|
+
// This is the normal negated version
|
|
686
|
+
// e.g. `-inset-1` or `-tw-inset-1`
|
|
679
687
|
classes = [...classes, ...classes.map((cls) => '-' + cls)]
|
|
688
|
+
|
|
689
|
+
// This is the negated version *after* the prefix
|
|
690
|
+
// e.g. `tw--inset-1`
|
|
691
|
+
// The prefix is already attached to util name
|
|
692
|
+
// So we add the negative after the prefix
|
|
693
|
+
classes = [
|
|
694
|
+
...classes,
|
|
695
|
+
...classes.map(
|
|
696
|
+
(cls) => cls.slice(0, prefixLength) + '-' + cls.slice(prefixLength)
|
|
697
|
+
),
|
|
698
|
+
]
|
|
680
699
|
}
|
|
681
700
|
|
|
682
701
|
return classes
|
|
@@ -720,9 +739,43 @@ function registerPlugins(plugins, context) {
|
|
|
720
739
|
}
|
|
721
740
|
}
|
|
722
741
|
|
|
742
|
+
// A list of utilities that are used by certain Tailwind CSS utilities but
|
|
743
|
+
// that don't exist on their own. This will result in them "not existing" and
|
|
744
|
+
// sorting could be weird since you still require them in order to make the
|
|
745
|
+
// host utitlies work properly. (Thanks Biology)
|
|
746
|
+
let parasiteUtilities = new Set([prefix(context, 'group'), prefix(context, 'peer')])
|
|
747
|
+
context.sortClassList = function sortClassList(classes) {
|
|
748
|
+
let sortedClassNames = new Map()
|
|
749
|
+
for (let [sort, rule] of generateRules(new Set(classes), context)) {
|
|
750
|
+
if (sortedClassNames.has(rule.raws.tailwind.candidate)) continue
|
|
751
|
+
sortedClassNames.set(rule.raws.tailwind.candidate, sort)
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
return classes
|
|
755
|
+
.map((className) => {
|
|
756
|
+
let order = sortedClassNames.get(className) ?? null
|
|
757
|
+
|
|
758
|
+
if (order === null && parasiteUtilities.has(className)) {
|
|
759
|
+
// This will make sure that it is at the very beginning of the
|
|
760
|
+
// `components` layer which technically means 'before any
|
|
761
|
+
// components'.
|
|
762
|
+
order = context.layerOrder.components
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
return [className, order]
|
|
766
|
+
})
|
|
767
|
+
.sort(([, a], [, z]) => {
|
|
768
|
+
if (a === z) return 0
|
|
769
|
+
if (a === null) return -1
|
|
770
|
+
if (z === null) return 1
|
|
771
|
+
return bigSign(a - z)
|
|
772
|
+
})
|
|
773
|
+
.map(([className]) => className)
|
|
774
|
+
}
|
|
775
|
+
|
|
723
776
|
// Generate a list of strings for autocompletion purposes, e.g.
|
|
724
777
|
// ['uppercase', 'lowercase', ...]
|
|
725
|
-
context.getClassList = function () {
|
|
778
|
+
context.getClassList = function getClassList() {
|
|
726
779
|
let output = []
|
|
727
780
|
|
|
728
781
|
for (let util of classList) {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import parser from 'postcss-selector-parser'
|
|
2
|
-
import { tap } from './tap'
|
|
3
2
|
|
|
4
|
-
export default function (prefix, selector) {
|
|
3
|
+
export default function (prefix, selector, prependNegative = false) {
|
|
5
4
|
return parser((selectors) => {
|
|
6
5
|
selectors.walkClasses((classSelector) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
let baseClass = classSelector.value
|
|
7
|
+
let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-')
|
|
8
|
+
|
|
9
|
+
classSelector.value = shouldPlaceNegativeBeforePrefix
|
|
10
|
+
? `-${prefix}${baseClass.slice(1)}`
|
|
11
|
+
: `${prefix}${baseClass}`
|
|
10
12
|
})
|
|
11
13
|
}).processSync(selector)
|
|
12
14
|
}
|