tailwindcss 0.0.0-insiders.fd500fc → 0.0.0-insiders.fd74f04

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.
@@ -98,6 +98,7 @@ const _default = [
98
98
  "textOverflow",
99
99
  "hyphens",
100
100
  "whitespace",
101
+ "textWrap",
101
102
  "wordBreak",
102
103
  "borderRadius",
103
104
  "borderWidth",
@@ -415,6 +415,17 @@ let variantPlugins = {
415
415
  values: (_theme = theme("supports")) !== null && _theme !== void 0 ? _theme : {}
416
416
  });
417
417
  },
418
+ hasVariants: ({ matchVariant })=>{
419
+ matchVariant("has", (value)=>`&:has(${(0, _dataTypes.normalize)(value)})`, {
420
+ values: {}
421
+ });
422
+ matchVariant("group-has", (value, { modifier })=>modifier ? `:merge(.group\\/${modifier}):has(${(0, _dataTypes.normalize)(value)}) &` : `:merge(.group):has(${(0, _dataTypes.normalize)(value)}) &`, {
423
+ values: {}
424
+ });
425
+ matchVariant("peer-has", (value, { modifier })=>modifier ? `:merge(.peer\\/${modifier}):has(${(0, _dataTypes.normalize)(value)}) ~ &` : `:merge(.peer):has(${(0, _dataTypes.normalize)(value)}) ~ &`, {
426
+ values: {}
427
+ });
428
+ },
418
429
  ariaVariants: ({ matchVariant , theme })=>{
419
430
  var _theme;
420
431
  matchVariant("aria", (value)=>`&[aria-${(0, _dataTypes.normalize)(value)}]`, {
@@ -2293,6 +2304,19 @@ let corePlugins = {
2293
2304
  }
2294
2305
  });
2295
2306
  },
2307
+ textWrap: ({ addUtilities })=>{
2308
+ addUtilities({
2309
+ ".text-wrap": {
2310
+ "text-wrap": "wrap"
2311
+ },
2312
+ ".text-nowrap": {
2313
+ "text-wrap": "nowrap"
2314
+ },
2315
+ ".text-balance": {
2316
+ "text-wrap": "balance"
2317
+ }
2318
+ });
2319
+ },
2296
2320
  wordBreak: ({ addUtilities })=>{
2297
2321
  addUtilities({
2298
2322
  ".break-normal": {
@@ -71,7 +71,12 @@ const builtInTransformers = {
71
71
  };
72
72
  function getExtractor(context, fileExtension) {
73
73
  let extractors = context.tailwindConfig.content.extract;
74
- return extractors[fileExtension] || extractors.DEFAULT || builtInExtractors[fileExtension] || builtInExtractors.DEFAULT(context);
74
+ return extractors[fileExtension] || extractors.DEFAULT || builtInExtractors[fileExtension] || // Because we call `DEFAULT(context)`, the returning function is always a new function without a
75
+ // stable identity. Marking it with `DEFAULT_EXTRACTOR` allows us to check if it is the default
76
+ // extractor without relying on the function identity.
77
+ Object.assign(builtInExtractors.DEFAULT(context), {
78
+ DEFAULT_EXTRACTOR: true
79
+ });
75
80
  }
76
81
  function getTransformer(tailwindConfig, fileExtension) {
77
82
  let transformers = tailwindConfig.content.transform;
@@ -157,15 +162,34 @@ function expandTailwindAtRules(context) {
157
162
  let seen = new Set();
158
163
  env.DEBUG && console.time("Reading changed files");
159
164
  if ((0, _featureFlags.flagEnabled)(context.tailwindConfig, "oxideParser")) {
160
- // TODO: Pass through or implement `extractor`
161
- for (let candidate of (0, _oxide.parseCandidateStringsFromFiles)(context.changedContent)){
162
- candidates.add(candidate);
165
+ let rustParserContent = [];
166
+ let regexParserContent = [];
167
+ for (let item of context.changedContent){
168
+ let transformer = getTransformer(context.tailwindConfig, item.extension);
169
+ let extractor = getExtractor(context, item.extension);
170
+ if (transformer === builtInTransformers.DEFAULT && (extractor === null || extractor === void 0 ? void 0 : extractor.DEFAULT_EXTRACTOR) === true) {
171
+ rustParserContent.push(item);
172
+ } else {
173
+ regexParserContent.push([
174
+ item,
175
+ {
176
+ transformer,
177
+ extractor
178
+ }
179
+ ]);
180
+ }
181
+ }
182
+ if (rustParserContent.length > 0) {
183
+ for (let candidate of (0, _oxide.parseCandidateStrings)(rustParserContent, _oxide.IO.Parallel | _oxide.Parsing.Parallel)){
184
+ candidates.add(candidate);
185
+ }
186
+ }
187
+ if (regexParserContent.length > 0) {
188
+ for (let [{ file , content }, { transformer , extractor }] of regexParserContent){
189
+ content = file ? _fs.default.readFileSync(file, "utf8") : content;
190
+ getClassCandidates(transformer(content), extractor, candidates, seen);
191
+ }
163
192
  }
164
- // for (let { file, content, extension } of context.changedContent) {
165
- // let transformer = getTransformer(context.tailwindConfig, extension)
166
- // let extractor = getExtractor(context, extension)
167
- // getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen)
168
- // }
169
193
  } else {
170
194
  for (let { file , content , extension } of context.changedContent){
171
195
  let transformer = getTransformer(context.tailwindConfig, extension);
@@ -180,7 +204,10 @@ function expandTailwindAtRules(context) {
180
204
  let classCacheCount = context.classCache.size;
181
205
  env.DEBUG && console.time("Generate rules");
182
206
  env.DEBUG && console.time("Sorting candidates");
183
- let sortedCandidates = (0, _featureFlags.flagEnabled)(context.tailwindConfig, "oxideParser") ? candidates : new Set([
207
+ // TODO: only sort if we are not using the oxide parser (flagEnabled(context.tailwindConfig,
208
+ // 'oxideParser')) AND if we got all the candidates form the oxideParser alone. This will not
209
+ // be the case currently if you have custom transformers / extractors.
210
+ let sortedCandidates = new Set([
184
211
  ...candidates
185
212
  ].sort((a, z)=>{
186
213
  if (a === z) return 0;
@@ -244,9 +271,20 @@ function expandTailwindAtRules(context) {
244
271
  }));
245
272
  layerNodes.variants.remove();
246
273
  } else if (variantNodes.length > 0) {
247
- root.append((0, _cloneNodes.default)(variantNodes, root.source, {
274
+ let cloned = (0, _cloneNodes.default)(variantNodes, undefined, {
248
275
  layer: "variants"
249
- }));
276
+ });
277
+ cloned.forEach((node)=>{
278
+ var _node_raws_tailwind;
279
+ var _node_raws_tailwind_parentLayer;
280
+ let parentLayer = (_node_raws_tailwind_parentLayer = (_node_raws_tailwind = node.raws.tailwind) === null || _node_raws_tailwind === void 0 ? void 0 : _node_raws_tailwind.parentLayer) !== null && _node_raws_tailwind_parentLayer !== void 0 ? _node_raws_tailwind_parentLayer : null;
281
+ node.walk((n)=>{
282
+ if (!n.source) {
283
+ n.source = layerNodes[parentLayer].source;
284
+ }
285
+ });
286
+ });
287
+ root.append(cloned);
250
288
  }
251
289
  // If we've got a utility layer and no utilities are generated there's likely something wrong
252
290
  const hasUtilityVariants = variantNodes.some((node)=>{
@@ -733,6 +733,7 @@ function resolvePlugins(context, root) {
733
733
  let beforeVariants = [
734
734
  _corePlugins.variantPlugins["pseudoElementVariants"],
735
735
  _corePlugins.variantPlugins["pseudoClassVariants"],
736
+ _corePlugins.variantPlugins["hasVariants"],
736
737
  _corePlugins.variantPlugins["ariaVariants"],
737
738
  _corePlugins.variantPlugins["dataVariants"]
738
739
  ];
package/lib/plugin.js CHANGED
@@ -43,13 +43,22 @@ module.exports = function tailwindcss(configOrPath) {
43
43
  (0, _processTailwindFeatures.default)(context)(root, result);
44
44
  },
45
45
  function lightningCssPlugin(_root, result) {
46
+ var _intermediateResult_map, _intermediateResult_map_toJSON;
47
+ var _result_map;
48
+ let map = (_result_map = result.map) !== null && _result_map !== void 0 ? _result_map : result.opts.map;
49
+ let intermediateResult = result.root.toResult({
50
+ map: map ? {
51
+ inline: true
52
+ } : false
53
+ });
54
+ var _intermediateResult_map_toJSON1;
55
+ let intermediateMap = (_intermediateResult_map_toJSON1 = (_intermediateResult_map = intermediateResult.map) === null || _intermediateResult_map === void 0 ? void 0 : (_intermediateResult_map_toJSON = _intermediateResult_map.toJSON) === null || _intermediateResult_map_toJSON === void 0 ? void 0 : _intermediateResult_map_toJSON.call(_intermediateResult_map)) !== null && _intermediateResult_map_toJSON1 !== void 0 ? _intermediateResult_map_toJSON1 : map;
46
56
  try {
47
57
  let transformed = _lightningcss.default.transform({
48
58
  filename: result.opts.from,
49
- code: Buffer.from(result.root.toString()),
59
+ code: Buffer.from(intermediateResult.css),
50
60
  minify: false,
51
- sourceMap: !!result.map,
52
- inputSourceMap: result.map ? result.map.toString() : undefined,
61
+ sourceMap: !!intermediateMap,
53
62
  targets: typeof process !== "undefined" && process.env.JEST_WORKER_ID ? {
54
63
  chrome: 111 << 16
55
64
  } : _lightningcss.default.browserslistToTargets((0, _browserslist.default)(require("../package.json").browserslist)),
@@ -58,18 +67,22 @@ module.exports = function tailwindcss(configOrPath) {
58
67
  customMedia: true
59
68
  }
60
69
  });
61
- var _result_map;
62
- result.map = Object.assign((_result_map = result.map) !== null && _result_map !== void 0 ? _result_map : {}, {
63
- toJSON () {
64
- return transformed.map.toJSON();
65
- },
66
- toString () {
67
- return transformed.map.toString();
70
+ let code = transformed.code.toString();
71
+ // https://postcss.org/api/#sourcemapoptions
72
+ if (intermediateMap && transformed.map != null) {
73
+ let prev = transformed.map.toString();
74
+ if (typeof intermediateMap === "object") {
75
+ intermediateMap.prev = prev;
76
+ } else {
77
+ code = `${code}\n/*# sourceMappingURL=data:application/json;base64,${Buffer.from(prev).toString("base64")} */`;
68
78
  }
79
+ }
80
+ result.root = _postcss.default.parse(code, {
81
+ ...result.opts,
82
+ map: intermediateMap
69
83
  });
70
- result.root = _postcss.default.parse(transformed.code.toString("utf8"));
71
84
  } catch (err) {
72
- if (typeof process !== "undefined" && process.env.JEST_WORKER_ID) {
85
+ if (err.source && typeof process !== "undefined" && process.env.JEST_WORKER_ID) {
73
86
  let lines = err.source.split("\n");
74
87
  err = new Error([
75
88
  "Error formatting using Lightning CSS:",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwindcss",
3
- "version": "0.0.0-insiders.fd500fc",
3
+ "version": "0.0.0-insiders.fd74f04",
4
4
  "description": "A utility-first CSS framework for rapidly building custom user interfaces.",
5
5
  "license": "MIT",
6
6
  "main": "lib/index.js",
@@ -47,7 +47,6 @@
47
47
  "@swc/core": "^1.3.56",
48
48
  "@swc/jest": "^0.2.26",
49
49
  "@swc/register": "^0.1.10",
50
- "autoprefixer": "^10.4.14",
51
50
  "concurrently": "^8.0.1",
52
51
  "eslint": "^8.39.0",
53
52
  "eslint-config-prettier": "^8.8.0",
@@ -61,9 +60,9 @@
61
60
  },
62
61
  "dependencies": {
63
62
  "@alloc/quick-lru": "^5.2.0",
64
- "@tailwindcss/oxide": "0.0.0-insiders.fd500fc",
63
+ "@tailwindcss/oxide": "0.0.0-insiders.fd74f04",
65
64
  "arg": "^5.0.2",
66
- "browserslist": "^4.21.5",
65
+ "browserslist": "^4.21.7",
67
66
  "chokidar": "^3.5.3",
68
67
  "didyoumean": "^1.2.2",
69
68
  "dlv": "^1.1.3",
@@ -77,7 +76,7 @@
77
76
  "normalize-path": "^3.0.0",
78
77
  "object-hash": "^3.0.0",
79
78
  "picocolors": "^1.0.0",
80
- "postcss": "^8.4.23",
79
+ "postcss": "^8.4.24",
81
80
  "postcss-import": "^15.1.0",
82
81
  "postcss-js": "^4.0.1",
83
82
  "postcss-load-config": "^4.0.1",
@@ -1 +1 @@
1
- export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]
1
+ export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","textWrap","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]
@@ -386,6 +386,26 @@ export let variantPlugins = {
386
386
  )
387
387
  },
388
388
 
389
+ hasVariants: ({ matchVariant }) => {
390
+ matchVariant('has', (value) => `&:has(${normalize(value)})`, { values: {} })
391
+ matchVariant(
392
+ 'group-has',
393
+ (value, { modifier }) =>
394
+ modifier
395
+ ? `:merge(.group\\/${modifier}):has(${normalize(value)}) &`
396
+ : `:merge(.group):has(${normalize(value)}) &`,
397
+ { values: {} }
398
+ )
399
+ matchVariant(
400
+ 'peer-has',
401
+ (value, { modifier }) =>
402
+ modifier
403
+ ? `:merge(.peer\\/${modifier}):has(${normalize(value)}) ~ &`
404
+ : `:merge(.peer):has(${normalize(value)}) ~ &`,
405
+ { values: {} }
406
+ )
407
+ },
408
+
389
409
  ariaVariants: ({ matchVariant, theme }) => {
390
410
  matchVariant('aria', (value) => `&[aria-${normalize(value)}]`, { values: theme('aria') ?? {} })
391
411
  matchVariant(
@@ -1503,6 +1523,14 @@ export let corePlugins = {
1503
1523
  })
1504
1524
  },
1505
1525
 
1526
+ textWrap: ({ addUtilities }) => {
1527
+ addUtilities({
1528
+ '.text-wrap': { 'text-wrap': 'wrap' },
1529
+ '.text-nowrap': { 'text-wrap': 'nowrap' },
1530
+ '.text-balance': { 'text-wrap': 'balance' },
1531
+ })
1532
+ },
1533
+
1506
1534
  wordBreak: ({ addUtilities }) => {
1507
1535
  addUtilities({
1508
1536
  '.break-normal': { 'overflow-wrap': 'normal', 'word-break': 'normal' },
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs'
2
2
  import LRU from '@alloc/quick-lru'
3
- import { parseCandidateStringsFromFiles } from '@tailwindcss/oxide'
3
+ import { parseCandidateStrings, IO, Parsing } from '@tailwindcss/oxide'
4
4
  import * as sharedState from './sharedState'
5
5
  import { generateRules } from './generateRules'
6
6
  import log from '../util/log'
@@ -26,7 +26,10 @@ function getExtractor(context, fileExtension) {
26
26
  extractors[fileExtension] ||
27
27
  extractors.DEFAULT ||
28
28
  builtInExtractors[fileExtension] ||
29
- builtInExtractors.DEFAULT(context)
29
+ // Because we call `DEFAULT(context)`, the returning function is always a new function without a
30
+ // stable identity. Marking it with `DEFAULT_EXTRACTOR` allows us to check if it is the default
31
+ // extractor without relying on the function identity.
32
+ Object.assign(builtInExtractors.DEFAULT(context), { DEFAULT_EXTRACTOR: true })
30
33
  )
31
34
  }
32
35
 
@@ -133,19 +136,35 @@ export default function expandTailwindAtRules(context) {
133
136
  env.DEBUG && console.time('Reading changed files')
134
137
 
135
138
  if (flagEnabled(context.tailwindConfig, 'oxideParser')) {
136
- // TODO: Pass through or implement `extractor`
137
- for (let candidate of parseCandidateStringsFromFiles(
138
- context.changedContent
139
- // Object.assign({}, builtInTransformers, context.tailwindConfig.content.transform)
140
- )) {
141
- candidates.add(candidate)
139
+ let rustParserContent = []
140
+ let regexParserContent = []
141
+
142
+ for (let item of context.changedContent) {
143
+ let transformer = getTransformer(context.tailwindConfig, item.extension)
144
+ let extractor = getExtractor(context, item.extension)
145
+
146
+ if (transformer === builtInTransformers.DEFAULT && extractor?.DEFAULT_EXTRACTOR === true) {
147
+ rustParserContent.push(item)
148
+ } else {
149
+ regexParserContent.push([item, { transformer, extractor }])
150
+ }
142
151
  }
143
152
 
144
- // for (let { file, content, extension } of context.changedContent) {
145
- // let transformer = getTransformer(context.tailwindConfig, extension)
146
- // let extractor = getExtractor(context, extension)
147
- // getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen)
148
- // }
153
+ if (rustParserContent.length > 0) {
154
+ for (let candidate of parseCandidateStrings(
155
+ rustParserContent,
156
+ IO.Parallel | Parsing.Parallel
157
+ )) {
158
+ candidates.add(candidate)
159
+ }
160
+ }
161
+
162
+ if (regexParserContent.length > 0) {
163
+ for (let [{ file, content }, { transformer, extractor }] of regexParserContent) {
164
+ content = file ? fs.readFileSync(file, 'utf8') : content
165
+ getClassCandidates(transformer(content), extractor, candidates, seen)
166
+ }
167
+ }
149
168
  } else {
150
169
  for (let { file, content, extension } of context.changedContent) {
151
170
  let transformer = getTransformer(context.tailwindConfig, extension)
@@ -164,15 +183,16 @@ export default function expandTailwindAtRules(context) {
164
183
 
165
184
  env.DEBUG && console.time('Generate rules')
166
185
  env.DEBUG && console.time('Sorting candidates')
167
- let sortedCandidates = flagEnabled(context.tailwindConfig, 'oxideParser')
168
- ? candidates
169
- : new Set(
170
- [...candidates].sort((a, z) => {
171
- if (a === z) return 0
172
- if (a < z) return -1
173
- return 1
174
- })
175
- )
186
+ // TODO: only sort if we are not using the oxide parser (flagEnabled(context.tailwindConfig,
187
+ // 'oxideParser')) AND if we got all the candidates form the oxideParser alone. This will not
188
+ // be the case currently if you have custom transformers / extractors.
189
+ let sortedCandidates = new Set(
190
+ [...candidates].sort((a, z) => {
191
+ if (a === z) return 0
192
+ if (a < z) return -1
193
+ return 1
194
+ })
195
+ )
176
196
  env.DEBUG && console.timeEnd('Sorting candidates')
177
197
  generateRules(sortedCandidates, context)
178
198
  env.DEBUG && console.timeEnd('Generate rules')
@@ -246,11 +266,21 @@ export default function expandTailwindAtRules(context) {
246
266
  )
247
267
  layerNodes.variants.remove()
248
268
  } else if (variantNodes.length > 0) {
249
- root.append(
250
- cloneNodes(variantNodes, root.source, {
251
- layer: 'variants',
269
+ let cloned = cloneNodes(variantNodes, undefined, {
270
+ layer: 'variants',
271
+ })
272
+
273
+ cloned.forEach((node) => {
274
+ let parentLayer = node.raws.tailwind?.parentLayer ?? null
275
+
276
+ node.walk((n) => {
277
+ if (!n.source) {
278
+ n.source = layerNodes[parentLayer].source
279
+ }
252
280
  })
253
- )
281
+ })
282
+
283
+ root.append(cloned)
254
284
  }
255
285
 
256
286
  // If we've got a utility layer and no utilities are generated there's likely something wrong
@@ -744,6 +744,7 @@ function resolvePlugins(context, root) {
744
744
  let beforeVariants = [
745
745
  variantPlugins['pseudoElementVariants'],
746
746
  variantPlugins['pseudoClassVariants'],
747
+ variantPlugins['hasVariants'],
747
748
  variantPlugins['ariaVariants'],
748
749
  variantPlugins['dataVariants'],
749
750
  ]
package/src/plugin.js CHANGED
@@ -40,38 +40,52 @@ module.exports = function tailwindcss(configOrPath) {
40
40
  processTailwindFeatures(context)(root, result)
41
41
  },
42
42
  function lightningCssPlugin(_root, result) {
43
+ let map = result.map ?? result.opts.map
44
+
45
+ let intermediateResult = result.root.toResult({
46
+ map: map ? { inline: true } : false,
47
+ })
48
+ let intermediateMap = intermediateResult.map?.toJSON?.() ?? map
49
+
43
50
  try {
44
51
  let transformed = lightningcss.transform({
45
52
  filename: result.opts.from,
46
- code: Buffer.from(result.root.toString()),
53
+ code: Buffer.from(intermediateResult.css),
47
54
  minify: false,
48
- sourceMap: !!result.map,
49
- inputSourceMap: result.map ? result.map.toString() : undefined,
55
+ sourceMap: !!intermediateMap,
50
56
  targets:
51
57
  typeof process !== 'undefined' && process.env.JEST_WORKER_ID
52
58
  ? { chrome: 111 << 16 }
53
59
  : lightningcss.browserslistToTargets(
54
60
  browserslist(require('../package.json').browserslist)
55
61
  ),
56
-
57
62
  drafts: {
58
63
  nesting: true,
59
64
  customMedia: true,
60
65
  },
61
66
  })
62
67
 
63
- result.map = Object.assign(result.map ?? {}, {
64
- toJSON() {
65
- return transformed.map.toJSON()
66
- },
67
- toString() {
68
- return transformed.map.toString()
69
- },
70
- })
68
+ let code = transformed.code.toString()
71
69
 
72
- result.root = postcss.parse(transformed.code.toString('utf8'))
70
+ // https://postcss.org/api/#sourcemapoptions
71
+ if (intermediateMap && transformed.map != null) {
72
+ let prev = transformed.map.toString()
73
+
74
+ if (typeof intermediateMap === 'object') {
75
+ intermediateMap.prev = prev
76
+ } else {
77
+ code = `${code}\n/*# sourceMappingURL=data:application/json;base64,${Buffer.from(
78
+ prev
79
+ ).toString('base64')} */`
80
+ }
81
+ }
82
+
83
+ result.root = postcss.parse(code, {
84
+ ...result.opts,
85
+ map: intermediateMap,
86
+ })
73
87
  } catch (err) {
74
- if (typeof process !== 'undefined' && process.env.JEST_WORKER_ID) {
88
+ if (err.source && typeof process !== 'undefined' && process.env.JEST_WORKER_ID) {
75
89
  let lines = err.source.split('\n')
76
90
  err = new Error(
77
91
  [
@@ -517,6 +517,9 @@ module.exports = {
517
517
  '5/6': '83.333333%',
518
518
  full: '100%',
519
519
  screen: '100vh',
520
+ svh: '100svh',
521
+ lvh: '100lvh',
522
+ dvh: '100dvh',
520
523
  min: 'min-content',
521
524
  max: 'max-content',
522
525
  fit: 'fit-content',
@@ -621,6 +624,9 @@ module.exports = {
621
624
  none: 'none',
622
625
  full: '100%',
623
626
  screen: '100vh',
627
+ svh: '100svh',
628
+ lvh: '100lvh',
629
+ dvh: '100dvh',
624
630
  min: 'min-content',
625
631
  max: 'max-content',
626
632
  fit: 'fit-content',
@@ -650,6 +656,9 @@ module.exports = {
650
656
  0: '0px',
651
657
  full: '100%',
652
658
  screen: '100vh',
659
+ svh: '100svh',
660
+ lvh: '100lvh',
661
+ dvh: '100dvh',
653
662
  min: 'min-content',
654
663
  max: 'max-content',
655
664
  fit: 'fit-content',
@@ -967,6 +976,9 @@ module.exports = {
967
976
  '11/12': '91.666667%',
968
977
  full: '100%',
969
978
  screen: '100vw',
979
+ svw: '100svw',
980
+ lvw: '100lvw',
981
+ dvw: '100dvw',
970
982
  min: 'min-content',
971
983
  max: 'max-content',
972
984
  fit: 'fit-content',
@@ -1 +1 @@
1
- export type CorePluginList = 'preflight' | 'container' | 'accessibility' | 'pointerEvents' | 'visibility' | 'position' | 'inset' | 'isolation' | 'zIndex' | 'order' | 'gridColumn' | 'gridColumnStart' | 'gridColumnEnd' | 'gridRow' | 'gridRowStart' | 'gridRowEnd' | 'float' | 'clear' | 'margin' | 'boxSizing' | 'lineClamp' | 'display' | 'aspectRatio' | 'height' | 'maxHeight' | 'minHeight' | 'width' | 'minWidth' | 'maxWidth' | 'flex' | 'flexShrink' | 'flexGrow' | 'flexBasis' | 'tableLayout' | 'captionSide' | 'borderCollapse' | 'borderSpacing' | 'transformOrigin' | 'translate' | 'rotate' | 'skew' | 'scale' | 'transform' | 'animation' | 'cursor' | 'touchAction' | 'userSelect' | 'resize' | 'scrollSnapType' | 'scrollSnapAlign' | 'scrollSnapStop' | 'scrollMargin' | 'scrollPadding' | 'listStylePosition' | 'listStyleType' | 'listStyleImage' | 'appearance' | 'columns' | 'breakBefore' | 'breakInside' | 'breakAfter' | 'gridAutoColumns' | 'gridAutoFlow' | 'gridAutoRows' | 'gridTemplateColumns' | 'gridTemplateRows' | 'flexDirection' | 'flexWrap' | 'placeContent' | 'placeItems' | 'alignContent' | 'alignItems' | 'justifyContent' | 'justifyItems' | 'gap' | 'space' | 'divideWidth' | 'divideStyle' | 'divideColor' | 'divideOpacity' | 'placeSelf' | 'alignSelf' | 'justifySelf' | 'overflow' | 'overscrollBehavior' | 'scrollBehavior' | 'textOverflow' | 'hyphens' | 'whitespace' | 'wordBreak' | 'borderRadius' | 'borderWidth' | 'borderStyle' | 'borderColor' | 'borderOpacity' | 'backgroundColor' | 'backgroundOpacity' | 'backgroundImage' | 'gradientColorStops' | 'boxDecorationBreak' | 'backgroundSize' | 'backgroundAttachment' | 'backgroundClip' | 'backgroundPosition' | 'backgroundRepeat' | 'backgroundOrigin' | 'fill' | 'stroke' | 'strokeWidth' | 'objectFit' | 'objectPosition' | 'padding' | 'textAlign' | 'textIndent' | 'verticalAlign' | 'fontFamily' | 'fontSize' | 'fontWeight' | 'textTransform' | 'fontStyle' | 'fontVariantNumeric' | 'lineHeight' | 'letterSpacing' | 'textColor' | 'textOpacity' | 'textDecoration' | 'textDecorationColor' | 'textDecorationStyle' | 'textDecorationThickness' | 'textUnderlineOffset' | 'fontSmoothing' | 'placeholderColor' | 'placeholderOpacity' | 'caretColor' | 'accentColor' | 'opacity' | 'backgroundBlendMode' | 'mixBlendMode' | 'boxShadow' | 'boxShadowColor' | 'outlineStyle' | 'outlineWidth' | 'outlineOffset' | 'outlineColor' | 'ringWidth' | 'ringColor' | 'ringOpacity' | 'ringOffsetWidth' | 'ringOffsetColor' | 'blur' | 'brightness' | 'contrast' | 'dropShadow' | 'grayscale' | 'hueRotate' | 'invert' | 'saturate' | 'sepia' | 'filter' | 'backdropBlur' | 'backdropBrightness' | 'backdropContrast' | 'backdropGrayscale' | 'backdropHueRotate' | 'backdropInvert' | 'backdropOpacity' | 'backdropSaturate' | 'backdropSepia' | 'backdropFilter' | 'transitionProperty' | 'transitionDelay' | 'transitionDuration' | 'transitionTimingFunction' | 'willChange' | 'content'
1
+ export type CorePluginList = 'preflight' | 'container' | 'accessibility' | 'pointerEvents' | 'visibility' | 'position' | 'inset' | 'isolation' | 'zIndex' | 'order' | 'gridColumn' | 'gridColumnStart' | 'gridColumnEnd' | 'gridRow' | 'gridRowStart' | 'gridRowEnd' | 'float' | 'clear' | 'margin' | 'boxSizing' | 'lineClamp' | 'display' | 'aspectRatio' | 'height' | 'maxHeight' | 'minHeight' | 'width' | 'minWidth' | 'maxWidth' | 'flex' | 'flexShrink' | 'flexGrow' | 'flexBasis' | 'tableLayout' | 'captionSide' | 'borderCollapse' | 'borderSpacing' | 'transformOrigin' | 'translate' | 'rotate' | 'skew' | 'scale' | 'transform' | 'animation' | 'cursor' | 'touchAction' | 'userSelect' | 'resize' | 'scrollSnapType' | 'scrollSnapAlign' | 'scrollSnapStop' | 'scrollMargin' | 'scrollPadding' | 'listStylePosition' | 'listStyleType' | 'listStyleImage' | 'appearance' | 'columns' | 'breakBefore' | 'breakInside' | 'breakAfter' | 'gridAutoColumns' | 'gridAutoFlow' | 'gridAutoRows' | 'gridTemplateColumns' | 'gridTemplateRows' | 'flexDirection' | 'flexWrap' | 'placeContent' | 'placeItems' | 'alignContent' | 'alignItems' | 'justifyContent' | 'justifyItems' | 'gap' | 'space' | 'divideWidth' | 'divideStyle' | 'divideColor' | 'divideOpacity' | 'placeSelf' | 'alignSelf' | 'justifySelf' | 'overflow' | 'overscrollBehavior' | 'scrollBehavior' | 'textOverflow' | 'hyphens' | 'whitespace' | 'textWrap' | 'wordBreak' | 'borderRadius' | 'borderWidth' | 'borderStyle' | 'borderColor' | 'borderOpacity' | 'backgroundColor' | 'backgroundOpacity' | 'backgroundImage' | 'gradientColorStops' | 'boxDecorationBreak' | 'backgroundSize' | 'backgroundAttachment' | 'backgroundClip' | 'backgroundPosition' | 'backgroundRepeat' | 'backgroundOrigin' | 'fill' | 'stroke' | 'strokeWidth' | 'objectFit' | 'objectPosition' | 'padding' | 'textAlign' | 'textIndent' | 'verticalAlign' | 'fontFamily' | 'fontSize' | 'fontWeight' | 'textTransform' | 'fontStyle' | 'fontVariantNumeric' | 'lineHeight' | 'letterSpacing' | 'textColor' | 'textOpacity' | 'textDecoration' | 'textDecorationColor' | 'textDecorationStyle' | 'textDecorationThickness' | 'textUnderlineOffset' | 'fontSmoothing' | 'placeholderColor' | 'placeholderOpacity' | 'caretColor' | 'accentColor' | 'opacity' | 'backgroundBlendMode' | 'mixBlendMode' | 'boxShadow' | 'boxShadowColor' | 'outlineStyle' | 'outlineWidth' | 'outlineOffset' | 'outlineColor' | 'ringWidth' | 'ringColor' | 'ringOpacity' | 'ringOffsetWidth' | 'ringOffsetColor' | 'blur' | 'brightness' | 'contrast' | 'dropShadow' | 'grayscale' | 'hueRotate' | 'invert' | 'saturate' | 'sepia' | 'filter' | 'backdropBlur' | 'backdropBrightness' | 'backdropContrast' | 'backdropGrayscale' | 'backdropHueRotate' | 'backdropInvert' | 'backdropOpacity' | 'backdropSaturate' | 'backdropSepia' | 'backdropFilter' | 'transitionProperty' | 'transitionDelay' | 'transitionDuration' | 'transitionTimingFunction' | 'willChange' | 'content'
@@ -241,7 +241,7 @@ export type DefaultTheme = Config['theme'] & {
241
241
  listStyleType: Record<'none' | 'disc' | 'decimal', string>
242
242
  listStyleImage: Record<'none', string>
243
243
  lineClamp: Record<'1' | '2' | '3' | '4' | '5' | '6', string>
244
- minHeight: Record<'0' | 'full' | 'screen' | 'min' | 'max' | 'fit', string>
244
+ minHeight: Record<'0' | 'full' | 'screen' | 'svh' | 'lvh' | 'dvh' | 'min' | 'max' | 'fit', string>
245
245
  minWidth: Record<'0' | 'full' | 'min' | 'max' | 'fit', string>
246
246
  objectPosition: Record<
247
247
  | 'bottom'