tailwindcss 0.0.0-insiders.ea10bb9 → 0.0.0-insiders.ea4e1cd
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/README.md +1 -1
- package/lib/cli/build/deps.js +17 -9
- package/lib/cli/build/index.js +20 -10
- package/lib/cli/build/plugin.js +86 -70
- package/lib/cli/build/utils.js +18 -8
- package/lib/cli/build/watching.js +16 -12
- package/lib/cli/help/index.js +6 -4
- package/lib/cli/index.js +222 -10
- package/lib/cli/init/index.js +29 -12
- package/lib/cli-peer-dependencies.js +12 -4
- package/lib/cli.js +4 -226
- package/lib/corePluginList.js +7 -1
- package/lib/corePlugins.js +348 -75
- package/lib/css/preflight.css +2 -0
- package/lib/featureFlags.js +27 -15
- package/lib/index.js +1 -47
- package/lib/lib/cacheInvalidation.js +7 -5
- package/lib/lib/collapseAdjacentRules.js +5 -3
- package/lib/lib/collapseDuplicateDeclarations.js +12 -10
- package/lib/lib/content.js +34 -30
- package/lib/lib/defaultExtractor.js +15 -8
- package/lib/lib/detectNesting.js +10 -2
- package/lib/lib/evaluateTailwindFunctions.js +22 -20
- package/lib/lib/expandApplyAtRules.js +43 -35
- package/lib/lib/expandTailwindAtRules.js +46 -19
- package/lib/lib/findAtConfigPath.js +9 -7
- package/lib/lib/generateRules.js +157 -92
- package/lib/lib/getModuleDependencies.js +85 -37
- package/lib/lib/load-config.js +42 -0
- package/lib/lib/normalizeTailwindDirectives.js +5 -3
- package/lib/lib/offsets.js +93 -4
- package/lib/lib/partitionApplyAtRules.js +3 -1
- package/lib/lib/regex.js +21 -7
- package/lib/lib/remap-bitfield.js +89 -0
- package/lib/lib/resolveDefaultsAtRules.js +28 -24
- package/lib/lib/setupContextUtils.js +190 -131
- package/lib/lib/setupTrackingContext.js +49 -26
- package/lib/lib/sharedState.js +37 -10
- package/lib/lib/substituteScreenAtRules.js +5 -3
- package/lib/oxide/cli/build/deps.js +89 -0
- package/lib/oxide/cli/build/index.js +53 -0
- package/lib/oxide/cli/build/plugin.js +375 -0
- package/lib/oxide/cli/build/utils.js +87 -0
- package/lib/oxide/cli/build/watching.js +179 -0
- package/lib/oxide/cli/help/index.js +72 -0
- package/lib/oxide/cli/index.js +214 -0
- package/lib/oxide/cli/init/index.js +52 -0
- package/lib/oxide/cli.js +5 -0
- package/lib/oxide/postcss-plugin.js +2 -0
- package/lib/plugin.js +98 -0
- package/lib/postcss-plugins/nesting/index.js +3 -1
- package/lib/postcss-plugins/nesting/plugin.js +10 -8
- package/lib/processTailwindFeatures.js +14 -12
- package/lib/public/colors.js +49 -25
- 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 +12 -0
- package/lib/public/resolve-config.js +6 -4
- package/lib/util/applyImportantSelector.js +36 -0
- 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 +5 -3
- package/lib/util/color.js +30 -12
- 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 +7 -5
- package/lib/util/dataTypes.js +74 -17
- package/lib/util/defaults.js +9 -7
- package/lib/util/escapeClassName.js +10 -8
- package/lib/util/escapeCommas.js +3 -1
- package/lib/util/flattenColorPalette.js +3 -1
- package/lib/util/formatVariantSelector.js +138 -160
- package/lib/util/getAllConfigs.js +8 -6
- 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 +4 -2
- package/lib/util/normalizeConfig.js +28 -27
- 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 +54 -54
- package/lib/util/prefixSelector.js +27 -11
- package/lib/util/pseudoElements.js +229 -0
- package/lib/util/removeAlphaVariables.js +3 -1
- package/lib/util/resolveConfig.js +17 -15
- package/lib/util/resolveConfigPath.js +26 -10
- package/lib/util/responsive.js +6 -4
- package/lib/util/splitAtTopLevelOnly.js +10 -2
- 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 +16 -3
- package/lib/util/validateFormalSyntax.js +3 -1
- package/lib/util/withAlphaVariable.js +6 -2
- package/loadConfig.d.ts +4 -0
- package/loadConfig.js +2 -0
- package/package.json +45 -37
- package/peers/index.js +63324 -46417
- package/resolveConfig.d.ts +11 -2
- package/scripts/swap-engines.js +40 -0
- package/src/cli/build/index.js +13 -9
- package/src/cli/build/plugin.js +42 -32
- package/src/cli/build/watching.js +4 -2
- package/src/cli/index.js +216 -3
- package/src/cli/init/index.js +37 -8
- package/src/cli.js +4 -220
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +207 -32
- package/src/css/preflight.css +2 -0
- package/src/featureFlags.js +6 -0
- package/src/index.js +1 -47
- package/src/lib/content.js +12 -17
- package/src/lib/defaultExtractor.js +9 -3
- package/src/lib/detectNesting.js +9 -1
- package/src/lib/expandApplyAtRules.js +8 -1
- package/src/lib/expandTailwindAtRules.js +36 -7
- package/src/lib/generateRules.js +124 -42
- package/src/lib/getModuleDependencies.js +70 -30
- package/src/lib/load-config.ts +31 -0
- package/src/lib/offsets.js +104 -1
- package/src/lib/remap-bitfield.js +82 -0
- package/src/lib/setupContextUtils.js +103 -54
- package/src/lib/setupTrackingContext.js +36 -11
- package/src/lib/sharedState.js +15 -4
- package/src/oxide/cli/build/deps.ts +91 -0
- package/src/oxide/cli/build/index.ts +47 -0
- package/src/oxide/cli/build/plugin.ts +442 -0
- package/src/oxide/cli/build/utils.ts +74 -0
- package/src/oxide/cli/build/watching.ts +225 -0
- package/src/oxide/cli/help/index.ts +69 -0
- package/src/oxide/cli/index.ts +204 -0
- package/src/oxide/cli/init/index.ts +59 -0
- package/src/oxide/cli.ts +1 -0
- package/src/oxide/postcss-plugin.ts +1 -0
- package/src/plugin.js +107 -0
- package/src/public/colors.js +22 -0
- package/src/public/default-config.js +1 -1
- package/src/public/default-theme.js +2 -2
- package/src/public/load-config.js +2 -0
- package/src/util/applyImportantSelector.js +27 -0
- package/src/util/color.js +18 -3
- package/src/util/colorNames.js +150 -0
- package/src/util/dataTypes.js +33 -4
- package/src/util/formatVariantSelector.js +160 -163
- package/src/util/getAllConfigs.js +2 -2
- package/src/util/negateValue.js +1 -1
- package/src/util/normalizeConfig.js +2 -1
- package/src/util/pluginUtils.js +16 -31
- package/src/util/prefixSelector.js +28 -10
- package/src/util/pseudoElements.js +170 -0
- package/src/util/resolveConfigPath.js +12 -1
- package/src/util/splitAtTopLevelOnly.js +8 -1
- package/src/util/validateConfig.js +13 -0
- package/stubs/.gitignore +1 -0
- package/stubs/.prettierrc.json +6 -0
- package/stubs/{defaultConfig.stub.js → config.full.js} +183 -146
- package/stubs/{simpleConfig.stub.js → config.simple.js} +0 -1
- package/stubs/postcss.config.js +6 -0
- package/stubs/tailwind.config.cjs +2 -0
- package/stubs/tailwind.config.js +2 -0
- package/stubs/tailwind.config.ts +3 -0
- package/types/config.d.ts +15 -9
- package/types/generated/colors.d.ts +22 -0
- package/types/generated/corePluginList.d.ts +1 -1
- package/types/generated/default-theme.d.ts +108 -79
- package/CHANGELOG.md +0 -2336
- package/lib/cli/shared.js +0 -12
- package/lib/constants.js +0 -44
- package/scripts/install-integrations.js +0 -27
- package/scripts/rebuildFixtures.js +0 -68
- package/src/cli/shared.js +0 -5
- package/src/constants.js +0 -17
- /package/stubs/{defaultPostCssConfig.stub.js → postcss.config.cjs} +0 -0
package/lib/util/createPlugin.js
CHANGED
|
@@ -4,10 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
Object.defineProperty(exports, "default", {
|
|
6
6
|
enumerable: true,
|
|
7
|
-
get: ()
|
|
7
|
+
get: function() {
|
|
8
|
+
return createUtilityPlugin;
|
|
9
|
+
}
|
|
8
10
|
});
|
|
9
|
-
const _transformThemeValue = /*#__PURE__*/
|
|
10
|
-
function
|
|
11
|
+
const _transformThemeValue = /*#__PURE__*/ _interop_require_default(require("./transformThemeValue"));
|
|
12
|
+
function _interop_require_default(obj) {
|
|
11
13
|
return obj && obj.__esModule ? obj : {
|
|
12
14
|
default: obj
|
|
13
15
|
};
|
|
@@ -26,7 +28,7 @@ function createUtilityPlugin(themeKey, utilityVariations = [
|
|
|
26
28
|
let group = Array.isArray(utilityVariation[0]) ? utilityVariation : [
|
|
27
29
|
utilityVariation
|
|
28
30
|
];
|
|
29
|
-
var
|
|
31
|
+
var _theme;
|
|
30
32
|
matchUtilities(group.reduce((obj, [classPrefix, properties])=>{
|
|
31
33
|
return Object.assign(obj, {
|
|
32
34
|
[classPrefix]: (value)=>{
|
|
@@ -44,7 +46,7 @@ function createUtilityPlugin(themeKey, utilityVariations = [
|
|
|
44
46
|
});
|
|
45
47
|
}, {}), {
|
|
46
48
|
...options,
|
|
47
|
-
values: filterDefault ? Object.fromEntries(Object.entries((
|
|
49
|
+
values: filterDefault ? Object.fromEntries(Object.entries((_theme = theme(themeKey)) !== null && _theme !== void 0 ? _theme : {}).filter(([modifier])=>modifier !== "DEFAULT")) : theme(themeKey)
|
|
48
50
|
});
|
|
49
51
|
}
|
|
50
52
|
};
|
package/lib/util/dataTypes.js
CHANGED
|
@@ -9,21 +9,51 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
-
normalize: ()
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
12
|
+
normalize: function() {
|
|
13
|
+
return normalize;
|
|
14
|
+
},
|
|
15
|
+
url: function() {
|
|
16
|
+
return url;
|
|
17
|
+
},
|
|
18
|
+
number: function() {
|
|
19
|
+
return number;
|
|
20
|
+
},
|
|
21
|
+
percentage: function() {
|
|
22
|
+
return percentage;
|
|
23
|
+
},
|
|
24
|
+
length: function() {
|
|
25
|
+
return length;
|
|
26
|
+
},
|
|
27
|
+
lineWidth: function() {
|
|
28
|
+
return lineWidth;
|
|
29
|
+
},
|
|
30
|
+
shadow: function() {
|
|
31
|
+
return shadow;
|
|
32
|
+
},
|
|
33
|
+
color: function() {
|
|
34
|
+
return color;
|
|
35
|
+
},
|
|
36
|
+
image: function() {
|
|
37
|
+
return image;
|
|
38
|
+
},
|
|
39
|
+
gradient: function() {
|
|
40
|
+
return gradient;
|
|
41
|
+
},
|
|
42
|
+
position: function() {
|
|
43
|
+
return position;
|
|
44
|
+
},
|
|
45
|
+
familyName: function() {
|
|
46
|
+
return familyName;
|
|
47
|
+
},
|
|
48
|
+
genericName: function() {
|
|
49
|
+
return genericName;
|
|
50
|
+
},
|
|
51
|
+
absoluteSize: function() {
|
|
52
|
+
return absoluteSize;
|
|
53
|
+
},
|
|
54
|
+
relativeSize: function() {
|
|
55
|
+
return relativeSize;
|
|
56
|
+
}
|
|
27
57
|
});
|
|
28
58
|
const _color = require("./color");
|
|
29
59
|
const _parseBoxShadowValue = require("./parseBoxShadowValue");
|
|
@@ -38,7 +68,12 @@ let cssFunctions = [
|
|
|
38
68
|
function isCSSFunction(value) {
|
|
39
69
|
return cssFunctions.some((fn)=>new RegExp(`^${fn}\\(.*\\)`).test(value));
|
|
40
70
|
}
|
|
71
|
+
const placeholder = "--tw-placeholder";
|
|
72
|
+
const placeholderRe = new RegExp(placeholder, "g");
|
|
41
73
|
function normalize(value, isRoot = true) {
|
|
74
|
+
if (value.startsWith("--")) {
|
|
75
|
+
return `var(${value})`;
|
|
76
|
+
}
|
|
42
77
|
// Keep raw strings if it starts with `url(`
|
|
43
78
|
if (value.includes("url(")) {
|
|
44
79
|
return value.split(/(url\(.*?\))/g).filter(Boolean).map((part)=>{
|
|
@@ -57,7 +92,11 @@ function normalize(value, isRoot = true) {
|
|
|
57
92
|
// Add spaces around operators inside math functions like calc() that do not follow an operator
|
|
58
93
|
// or '('.
|
|
59
94
|
value = value.replace(/(calc|min|max|clamp)\(.+\)/g, (match)=>{
|
|
60
|
-
|
|
95
|
+
let vars = [];
|
|
96
|
+
return match.replace(/var\((--.+?)[,)]/g, (match, g1)=>{
|
|
97
|
+
vars.push(g1);
|
|
98
|
+
return match.replace(g1, placeholder);
|
|
99
|
+
}).replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, "$1 $2 ").replace(placeholderRe, ()=>vars.shift());
|
|
61
100
|
});
|
|
62
101
|
return value;
|
|
63
102
|
}
|
|
@@ -70,6 +109,9 @@ function number(value) {
|
|
|
70
109
|
function percentage(value) {
|
|
71
110
|
return value.endsWith("%") && number(value.slice(0, -1)) || isCSSFunction(value);
|
|
72
111
|
}
|
|
112
|
+
// Please refer to MDN when updating this list:
|
|
113
|
+
// https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units
|
|
114
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries#container_query_length_units
|
|
73
115
|
let lengthUnits = [
|
|
74
116
|
"cm",
|
|
75
117
|
"mm",
|
|
@@ -83,10 +125,25 @@ let lengthUnits = [
|
|
|
83
125
|
"ch",
|
|
84
126
|
"rem",
|
|
85
127
|
"lh",
|
|
128
|
+
"rlh",
|
|
86
129
|
"vw",
|
|
87
130
|
"vh",
|
|
88
131
|
"vmin",
|
|
89
|
-
"vmax"
|
|
132
|
+
"vmax",
|
|
133
|
+
"vb",
|
|
134
|
+
"vi",
|
|
135
|
+
"svw",
|
|
136
|
+
"svh",
|
|
137
|
+
"lvw",
|
|
138
|
+
"lvh",
|
|
139
|
+
"dvw",
|
|
140
|
+
"dvh",
|
|
141
|
+
"cqw",
|
|
142
|
+
"cqh",
|
|
143
|
+
"cqi",
|
|
144
|
+
"cqb",
|
|
145
|
+
"cqmin",
|
|
146
|
+
"cqmax"
|
|
90
147
|
];
|
|
91
148
|
let lengthUnitsPattern = `(?:${lengthUnits.join("|")})`;
|
|
92
149
|
function length(value) {
|
package/lib/util/defaults.js
CHANGED
|
@@ -4,20 +4,22 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
Object.defineProperty(exports, "defaults", {
|
|
6
6
|
enumerable: true,
|
|
7
|
-
get: ()
|
|
7
|
+
get: function() {
|
|
8
|
+
return defaults;
|
|
9
|
+
}
|
|
8
10
|
});
|
|
9
11
|
function defaults(target, ...sources) {
|
|
10
12
|
for (let source of sources){
|
|
11
13
|
for(let k in source){
|
|
12
|
-
var
|
|
13
|
-
if (!(target === null || target === void 0 ? void 0 : (
|
|
14
|
+
var _target_hasOwnProperty;
|
|
15
|
+
if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty = target.hasOwnProperty) === null || _target_hasOwnProperty === void 0 ? void 0 : _target_hasOwnProperty.call(target, k))) {
|
|
14
16
|
target[k] = source[k];
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
|
-
for (let
|
|
18
|
-
var
|
|
19
|
-
if (!(target === null || target === void 0 ? void 0 : (
|
|
20
|
-
target[
|
|
19
|
+
for (let k of Object.getOwnPropertySymbols(source)){
|
|
20
|
+
var _target_hasOwnProperty1;
|
|
21
|
+
if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty1 = target.hasOwnProperty) === null || _target_hasOwnProperty1 === void 0 ? void 0 : _target_hasOwnProperty1.call(target, k))) {
|
|
22
|
+
target[k] = source[k];
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
}
|
|
@@ -4,19 +4,21 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
Object.defineProperty(exports, "default", {
|
|
6
6
|
enumerable: true,
|
|
7
|
-
get: ()
|
|
7
|
+
get: function() {
|
|
8
|
+
return escapeClassName;
|
|
9
|
+
}
|
|
8
10
|
});
|
|
9
|
-
const
|
|
10
|
-
const _escapeCommas = /*#__PURE__*/
|
|
11
|
-
function
|
|
11
|
+
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser"));
|
|
12
|
+
const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas"));
|
|
13
|
+
function _interop_require_default(obj) {
|
|
12
14
|
return obj && obj.__esModule ? obj : {
|
|
13
15
|
default: obj
|
|
14
16
|
};
|
|
15
17
|
}
|
|
16
18
|
function escapeClassName(className) {
|
|
17
|
-
var
|
|
18
|
-
let node =
|
|
19
|
+
var _node_raws;
|
|
20
|
+
let node = _postcssselectorparser.default.className();
|
|
19
21
|
node.value = className;
|
|
20
|
-
var
|
|
21
|
-
return (0, _escapeCommas.default)((
|
|
22
|
+
var _node_raws_value;
|
|
23
|
+
return (0, _escapeCommas.default)((_node_raws_value = node === null || node === void 0 ? void 0 : (_node_raws = node.raws) === null || _node_raws === void 0 ? void 0 : _node_raws.value) !== null && _node_raws_value !== void 0 ? _node_raws_value : node.value);
|
|
22
24
|
}
|
package/lib/util/escapeCommas.js
CHANGED
|
@@ -4,7 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
Object.defineProperty(exports, "default", {
|
|
6
6
|
enumerable: true,
|
|
7
|
-
get: ()
|
|
7
|
+
get: function() {
|
|
8
|
+
return escapeCommas;
|
|
9
|
+
}
|
|
8
10
|
});
|
|
9
11
|
function escapeCommas(className) {
|
|
10
12
|
return className.replace(/\\,/g, "\\2c ");
|
|
@@ -4,7 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
Object.defineProperty(exports, "default", {
|
|
6
6
|
enumerable: true,
|
|
7
|
-
get: ()
|
|
7
|
+
get: function() {
|
|
8
|
+
return _default;
|
|
9
|
+
}
|
|
8
10
|
});
|
|
9
11
|
const flattenColorPalette = (colors)=>Object.assign({}, ...Object.entries(colors !== null && colors !== void 0 ? colors : {}).flatMap(([color, values])=>typeof values == "object" ? Object.entries(flattenColorPalette(values)).map(([number, hex])=>({
|
|
10
12
|
[color + (number === "DEFAULT" ? "" : `-${number}`)]: hex
|
|
@@ -9,41 +9,62 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
formatVariantSelector: function() {
|
|
13
|
+
return formatVariantSelector;
|
|
14
|
+
},
|
|
15
|
+
eliminateIrrelevantSelectors: function() {
|
|
16
|
+
return eliminateIrrelevantSelectors;
|
|
17
|
+
},
|
|
18
|
+
finalizeSelector: function() {
|
|
19
|
+
return finalizeSelector;
|
|
20
|
+
},
|
|
21
|
+
handleMergePseudo: function() {
|
|
22
|
+
return handleMergePseudo;
|
|
23
|
+
}
|
|
15
24
|
});
|
|
16
|
-
const
|
|
17
|
-
const _unesc = /*#__PURE__*/
|
|
18
|
-
const _escapeClassName = /*#__PURE__*/
|
|
19
|
-
const _prefixSelector = /*#__PURE__*/
|
|
20
|
-
|
|
25
|
+
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser"));
|
|
26
|
+
const _unesc = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser/dist/util/unesc"));
|
|
27
|
+
const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("../util/escapeClassName"));
|
|
28
|
+
const _prefixSelector = /*#__PURE__*/ _interop_require_default(require("../util/prefixSelector"));
|
|
29
|
+
const _pseudoElements = require("./pseudoElements");
|
|
30
|
+
function _interop_require_default(obj) {
|
|
21
31
|
return obj && obj.__esModule ? obj : {
|
|
22
32
|
default: obj
|
|
23
33
|
};
|
|
24
34
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
/** @typedef {import('postcss-selector-parser').Root} Root */ /** @typedef {import('postcss-selector-parser').Selector} Selector */ /** @typedef {import('postcss-selector-parser').Pseudo} Pseudo */ /** @typedef {import('postcss-selector-parser').Node} Node */ /** @typedef {{format: string, isArbitraryVariant: boolean}[]} RawFormats */ /** @typedef {import('postcss-selector-parser').Root} ParsedFormats */ /** @typedef {RawFormats | ParsedFormats} AcceptedFormats */ let MERGE = ":merge";
|
|
36
|
+
function formatVariantSelector(formats, { context , candidate }) {
|
|
37
|
+
var _context_tailwindConfig_prefix;
|
|
38
|
+
let prefix = (_context_tailwindConfig_prefix = context === null || context === void 0 ? void 0 : context.tailwindConfig.prefix) !== null && _context_tailwindConfig_prefix !== void 0 ? _context_tailwindConfig_prefix : "";
|
|
39
|
+
// Parse the format selector into an AST
|
|
40
|
+
let parsedFormats = formats.map((format)=>{
|
|
41
|
+
let ast = (0, _postcssselectorparser.default)().astSync(format.format);
|
|
42
|
+
return {
|
|
43
|
+
...format,
|
|
44
|
+
ast: format.isArbitraryVariant ? ast : (0, _prefixSelector.default)(prefix, ast)
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
// We start with the candidate selector
|
|
48
|
+
let formatAst = _postcssselectorparser.default.root({
|
|
49
|
+
nodes: [
|
|
50
|
+
_postcssselectorparser.default.selector({
|
|
51
|
+
nodes: [
|
|
52
|
+
_postcssselectorparser.default.className({
|
|
53
|
+
value: (0, _escapeClassName.default)(candidate)
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
// And iteratively merge each format selector into the candidate selector
|
|
60
|
+
for (let { ast } of parsedFormats){
|
|
61
|
+
[formatAst, ast] = handleMergePseudo(formatAst, ast);
|
|
62
|
+
// 2. Merge the format selector into the current selector AST
|
|
63
|
+
ast.walkNesting((nesting)=>nesting.replaceWith(...formatAst.nodes[0].nodes));
|
|
64
|
+
// 3. Keep going!
|
|
65
|
+
formatAst = ast;
|
|
45
66
|
}
|
|
46
|
-
return
|
|
67
|
+
return formatAst;
|
|
47
68
|
}
|
|
48
69
|
/**
|
|
49
70
|
* Given any node in a selector this gets the "simple" selector it's a part of
|
|
@@ -51,10 +72,10 @@ function formatVariantSelector(current, ...others) {
|
|
|
51
72
|
* Technically :is(), :not(), :has(), etc… can have combinators but those are nested
|
|
52
73
|
* inside the relevant node and won't be picked up so they're fine to ignore
|
|
53
74
|
*
|
|
54
|
-
* @param {
|
|
55
|
-
* @returns {
|
|
75
|
+
* @param {Node} node
|
|
76
|
+
* @returns {Node[]}
|
|
56
77
|
**/ function simpleSelectorForNode(node) {
|
|
57
|
-
/** @type {
|
|
78
|
+
/** @type {Node[]} */ let nodes = [];
|
|
58
79
|
// Walk backwards until we hit a combinator node (or the start)
|
|
59
80
|
while(node.prev() && node.prev().type !== "combinator"){
|
|
60
81
|
node = node.prev();
|
|
@@ -70,8 +91,8 @@ function formatVariantSelector(current, ...others) {
|
|
|
70
91
|
* Resorts the nodes in a selector to ensure they're in the correct order
|
|
71
92
|
* Tags go before classes, and pseudo classes go after classes
|
|
72
93
|
*
|
|
73
|
-
* @param {
|
|
74
|
-
* @returns {
|
|
94
|
+
* @param {Selector} sel
|
|
95
|
+
* @returns {Selector}
|
|
75
96
|
**/ function resortSelector(sel) {
|
|
76
97
|
sel.sort((a, b)=>{
|
|
77
98
|
if (a.type === "tag" && b.type === "class") {
|
|
@@ -106,27 +127,20 @@ function eliminateIrrelevantSelectors(sel, base) {
|
|
|
106
127
|
// meaning of the selector.
|
|
107
128
|
// TODO: Can we do this for :matches, :is, and :where?
|
|
108
129
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
format = format.replace(PARENT, `.${(0, _escapeClassName.default)(candidate)}`);
|
|
125
|
-
let formatAst = (0, _postcssSelectorParser.default)().astSync(format);
|
|
126
|
-
// Remove extraneous selectors that do not include the base class/candidate being matched against
|
|
127
|
-
// For example if we have a utility defined `.a, .b { color: red}`
|
|
128
|
-
// And the formatted variant is sm:b then we want the final selector to be `.sm\:b` and not `.a, .sm\:b`
|
|
129
|
-
ast.each((sel)=>eliminateIrrelevantSelectors(sel, base));
|
|
130
|
+
function finalizeSelector(current, formats, { context , candidate , base }) {
|
|
131
|
+
var _context_tailwindConfig;
|
|
132
|
+
var _context_tailwindConfig_separator;
|
|
133
|
+
let separator = (_context_tailwindConfig_separator = context === null || context === void 0 ? void 0 : (_context_tailwindConfig = context.tailwindConfig) === null || _context_tailwindConfig === void 0 ? void 0 : _context_tailwindConfig.separator) !== null && _context_tailwindConfig_separator !== void 0 ? _context_tailwindConfig_separator : ":";
|
|
134
|
+
// Split by the separator, but ignore the separator inside square brackets:
|
|
135
|
+
//
|
|
136
|
+
// E.g.: dark:lg:hover:[paint-order:markers]
|
|
137
|
+
// ┬ ┬ ┬ ┬
|
|
138
|
+
// │ │ │ ╰── We will not split here
|
|
139
|
+
// ╰──┴─────┴─────────────── We will split here
|
|
140
|
+
//
|
|
141
|
+
base = base !== null && base !== void 0 ? base : candidate.split(new RegExp(`\\${separator}(?![^[]*\\])`)).pop();
|
|
142
|
+
// Parse the selector into an AST
|
|
143
|
+
let selector = (0, _postcssselectorparser.default)().astSync(current);
|
|
130
144
|
// Normalize escaped classes, e.g.:
|
|
131
145
|
//
|
|
132
146
|
// The idea would be to replace the escaped `base` in the selector with the
|
|
@@ -138,20 +152,31 @@ base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === vo
|
|
|
138
152
|
// base in selector: bg-\\[rgb\\(255\\,0\\,0\\)\\]
|
|
139
153
|
// escaped base: bg-\\[rgb\\(255\\2c 0\\2c 0\\)\\]
|
|
140
154
|
//
|
|
141
|
-
|
|
155
|
+
selector.walkClasses((node)=>{
|
|
142
156
|
if (node.raws && node.value.includes(base)) {
|
|
143
157
|
node.raws.value = (0, _escapeClassName.default)((0, _unesc.default)(node.raws.value));
|
|
144
158
|
}
|
|
145
159
|
});
|
|
146
|
-
|
|
160
|
+
// Remove extraneous selectors that do not include the base candidate
|
|
161
|
+
selector.each((sel)=>eliminateIrrelevantSelectors(sel, base));
|
|
162
|
+
// If there are no formats that means there were no variants added to the candidate
|
|
163
|
+
// so we can just return the selector as-is
|
|
164
|
+
let formatAst = Array.isArray(formats) ? formatVariantSelector(formats, {
|
|
165
|
+
context,
|
|
166
|
+
candidate
|
|
167
|
+
}) : formats;
|
|
168
|
+
if (formatAst === null) {
|
|
169
|
+
return selector.toString();
|
|
170
|
+
}
|
|
171
|
+
let simpleStart = _postcssselectorparser.default.comment({
|
|
147
172
|
value: "/*__simple__*/"
|
|
148
173
|
});
|
|
149
|
-
let simpleEnd =
|
|
174
|
+
let simpleEnd = _postcssselectorparser.default.comment({
|
|
150
175
|
value: "/*__simple__*/"
|
|
151
176
|
});
|
|
152
177
|
// We can safely replace the escaped base now, since the `base` section is
|
|
153
178
|
// now in a normalized escaped value.
|
|
154
|
-
|
|
179
|
+
selector.walkClasses((node)=>{
|
|
155
180
|
if (node.value !== base) {
|
|
156
181
|
return;
|
|
157
182
|
}
|
|
@@ -166,120 +191,73 @@ base =candidate.split(new RegExp(`\\${(ref1 = context === null || context === vo
|
|
|
166
191
|
parent.insertBefore(simpleSelector[0], simpleStart);
|
|
167
192
|
parent.insertAfter(simpleSelector[simpleSelector.length - 1], simpleEnd);
|
|
168
193
|
for (let child of formatNodes){
|
|
169
|
-
parent.insertBefore(simpleSelector[0], child);
|
|
194
|
+
parent.insertBefore(simpleSelector[0], child.clone());
|
|
170
195
|
}
|
|
171
196
|
node.remove();
|
|
172
197
|
// Re-sort the simple selector to ensure it's in the correct order
|
|
173
198
|
simpleSelector = simpleSelectorForNode(simpleStart);
|
|
174
199
|
let firstNode = parent.index(simpleStart);
|
|
175
|
-
parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(
|
|
200
|
+
parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(_postcssselectorparser.default.selector({
|
|
176
201
|
nodes: simpleSelector
|
|
177
202
|
})).nodes);
|
|
178
203
|
simpleStart.remove();
|
|
179
204
|
simpleEnd.remove();
|
|
180
205
|
});
|
|
181
|
-
// This will make sure to move pseudo's to the correct spot (the end for
|
|
182
|
-
// pseudo elements) because otherwise the selector will never work
|
|
183
|
-
// anyway.
|
|
184
|
-
//
|
|
185
|
-
// E.g.:
|
|
186
|
-
// - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
|
|
187
|
-
// - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
|
|
188
|
-
//
|
|
189
|
-
// `::before:hover` doesn't work, which means that we can make it work for you by flipping the order.
|
|
190
|
-
function collectPseudoElements(selector) {
|
|
191
|
-
let nodes = [];
|
|
192
|
-
for (let node of selector.nodes){
|
|
193
|
-
if (isPseudoElement(node)) {
|
|
194
|
-
nodes.push(node);
|
|
195
|
-
selector.removeChild(node);
|
|
196
|
-
}
|
|
197
|
-
if (node === null || node === void 0 ? void 0 : node.nodes) {
|
|
198
|
-
nodes.push(...collectPseudoElements(node));
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return nodes;
|
|
202
|
-
}
|
|
203
206
|
// Remove unnecessary pseudo selectors that we used as placeholders
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
p.replaceWith(p.nodes);
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
let pseudoElements = collectPseudoElements(selector);
|
|
211
|
-
if (pseudoElements.length > 0) {
|
|
212
|
-
selector.nodes.push(pseudoElements.sort(sortSelector));
|
|
207
|
+
selector.walkPseudos((p)=>{
|
|
208
|
+
if (p.value === MERGE) {
|
|
209
|
+
p.replaceWith(p.nodes);
|
|
213
210
|
}
|
|
214
211
|
});
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// (:). This distinguishes pseudo-classes from pseudo-elements. However, since
|
|
219
|
-
// this distinction was not present in older versions of the W3C spec, most
|
|
220
|
-
// browsers support both syntaxes for the original pseudo-elements.
|
|
221
|
-
let pseudoElementsBC = [
|
|
222
|
-
":before",
|
|
223
|
-
":after",
|
|
224
|
-
":first-line",
|
|
225
|
-
":first-letter"
|
|
226
|
-
];
|
|
227
|
-
// These pseudo-elements _can_ be combined with other pseudo selectors AND the order does matter.
|
|
228
|
-
let pseudoElementExceptions = [
|
|
229
|
-
"::file-selector-button"
|
|
230
|
-
];
|
|
231
|
-
// This will make sure to move pseudo's to the correct spot (the end for
|
|
232
|
-
// pseudo elements) because otherwise the selector will never work
|
|
233
|
-
// anyway.
|
|
234
|
-
//
|
|
235
|
-
// E.g.:
|
|
236
|
-
// - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before`
|
|
237
|
-
// - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before`
|
|
238
|
-
//
|
|
239
|
-
// `::before:hover` doesn't work, which means that we can make it work
|
|
240
|
-
// for you by flipping the order.
|
|
241
|
-
function sortSelector(a, z) {
|
|
242
|
-
// Both nodes are non-pseudo's so we can safely ignore them and keep
|
|
243
|
-
// them in the same order.
|
|
244
|
-
if (a.type !== "pseudo" && z.type !== "pseudo") {
|
|
245
|
-
return 0;
|
|
246
|
-
}
|
|
247
|
-
// If one of them is a combinator, we need to keep it in the same order
|
|
248
|
-
// because that means it will start a new "section" in the selector.
|
|
249
|
-
if (a.type === "combinator" ^ z.type === "combinator") {
|
|
250
|
-
return 0;
|
|
251
|
-
}
|
|
252
|
-
// One of the items is a pseudo and the other one isn't. Let's move
|
|
253
|
-
// the pseudo to the right.
|
|
254
|
-
if (a.type === "pseudo" ^ z.type === "pseudo") {
|
|
255
|
-
return (a.type === "pseudo") - (z.type === "pseudo");
|
|
256
|
-
}
|
|
257
|
-
// Both are pseudo's, move the pseudo elements (except for
|
|
258
|
-
// ::file-selector-button) to the right.
|
|
259
|
-
return isPseudoElement(a) - isPseudoElement(z);
|
|
260
|
-
}
|
|
261
|
-
function isPseudoElement(node) {
|
|
262
|
-
if (node.type !== "pseudo") return false;
|
|
263
|
-
if (pseudoElementExceptions.includes(node.value)) return false;
|
|
264
|
-
return node.value.startsWith("::") || pseudoElementsBC.includes(node.value);
|
|
212
|
+
// Move pseudo elements to the end of the selector (if necessary)
|
|
213
|
+
selector.each((sel)=>(0, _pseudoElements.movePseudos)(sel));
|
|
214
|
+
return selector.toString();
|
|
265
215
|
}
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
target += char;
|
|
276
|
-
} else if (char === "(") {
|
|
277
|
-
target += char;
|
|
278
|
-
count++;
|
|
279
|
-
} else if (char === ")") {
|
|
280
|
-
if (--count < 0) break; // unbalanced
|
|
281
|
-
target += char;
|
|
216
|
+
function handleMergePseudo(selector, format) {
|
|
217
|
+
/** @type {{pseudo: Pseudo, value: string}[]} */ let merges = [];
|
|
218
|
+
// Find all :merge() pseudo-classes in `selector`
|
|
219
|
+
selector.walkPseudos((pseudo)=>{
|
|
220
|
+
if (pseudo.value === MERGE) {
|
|
221
|
+
merges.push({
|
|
222
|
+
pseudo,
|
|
223
|
+
value: pseudo.nodes[0].toString()
|
|
224
|
+
});
|
|
282
225
|
}
|
|
283
|
-
}
|
|
284
|
-
|
|
226
|
+
});
|
|
227
|
+
// Find all :merge() "attachments" in `format` and attach them to the matching selector in `selector`
|
|
228
|
+
format.walkPseudos((pseudo)=>{
|
|
229
|
+
if (pseudo.value !== MERGE) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
let value = pseudo.nodes[0].toString();
|
|
233
|
+
// Does `selector` contain a :merge() pseudo-class with the same value?
|
|
234
|
+
let existing = merges.find((merge)=>merge.value === value);
|
|
235
|
+
// Nope so there's nothing to do
|
|
236
|
+
if (!existing) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// Everything after `:merge()` up to the next combinator is what is attached to the merged selector
|
|
240
|
+
let attachments = [];
|
|
241
|
+
let next = pseudo.next();
|
|
242
|
+
while(next && next.type !== "combinator"){
|
|
243
|
+
attachments.push(next);
|
|
244
|
+
next = next.next();
|
|
245
|
+
}
|
|
246
|
+
let combinator = next;
|
|
247
|
+
existing.pseudo.parent.insertAfter(existing.pseudo, _postcssselectorparser.default.selector({
|
|
248
|
+
nodes: attachments.map((node)=>node.clone())
|
|
249
|
+
}));
|
|
250
|
+
pseudo.remove();
|
|
251
|
+
attachments.forEach((node)=>node.remove());
|
|
252
|
+
// What about this case:
|
|
253
|
+
// :merge(.group):focus > &
|
|
254
|
+
// :merge(.group):hover &
|
|
255
|
+
if (combinator && combinator.type === "combinator") {
|
|
256
|
+
combinator.remove();
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
return [
|
|
260
|
+
selector,
|
|
261
|
+
format
|
|
262
|
+
];
|
|
285
263
|
}
|