tailwindcss 0.0.0-insiders.bd970d0 → 0.0.0-insiders.bda8421
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 -2
- package/lib/cli/build/deps.js +62 -0
- package/lib/cli/build/index.js +12 -15
- package/lib/cli/build/plugin.js +107 -167
- package/lib/cli/build/utils.js +13 -13
- package/lib/cli/build/watching.js +10 -10
- package/lib/cli/help/index.js +11 -11
- package/lib/cli/index.js +60 -61
- package/lib/cli/init/index.js +16 -16
- package/lib/cli-peer-dependencies.js +36 -0
- package/lib/cli.js +1 -1
- package/lib/corePluginList.js +4 -1
- package/lib/corePlugins.js +2018 -1905
- package/lib/css/preflight.css +18 -12
- package/lib/featureFlags.js +17 -23
- package/lib/index.js +1 -1
- package/lib/lib/cacheInvalidation.js +3 -3
- package/lib/lib/collapseAdjacentRules.js +6 -6
- package/lib/lib/collapseDuplicateDeclarations.js +1 -1
- package/lib/lib/content.js +39 -32
- package/lib/lib/defaultExtractor.js +40 -17
- package/lib/lib/evaluateTailwindFunctions.js +23 -23
- package/lib/lib/expandApplyAtRules.js +37 -18
- package/lib/lib/expandTailwindAtRules.js +49 -85
- package/lib/lib/findAtConfigPath.js +5 -5
- package/lib/lib/generateRules.js +82 -55
- package/lib/lib/getModuleDependencies.js +23 -23
- package/lib/lib/load-config.js +21 -6
- package/lib/lib/normalizeTailwindDirectives.js +36 -21
- package/lib/lib/offsets.js +97 -48
- package/lib/lib/partitionApplyAtRules.js +2 -2
- package/lib/lib/regex.js +5 -5
- package/lib/lib/resolveDefaultsAtRules.js +27 -25
- package/lib/lib/setupContextUtils.js +195 -167
- package/lib/lib/setupTrackingContext.js +4 -5
- package/lib/lib/sharedState.js +10 -10
- package/lib/lib/substituteScreenAtRules.js +4 -4
- package/lib/plugin.js +8 -124
- package/lib/postcss-plugins/nesting/index.js +2 -2
- package/lib/postcss-plugins/nesting/plugin.js +11 -11
- package/lib/processTailwindFeatures.js +3 -5
- package/lib/public/colors.js +264 -264
- package/lib/util/applyImportantSelector.js +2 -2
- package/lib/util/buildMediaQuery.js +2 -2
- package/lib/util/cloneDeep.js +1 -1
- package/lib/util/cloneNodes.js +33 -13
- package/lib/util/color.js +19 -19
- package/lib/util/createUtilityPlugin.js +3 -3
- package/lib/util/dataTypes.js +170 -113
- package/lib/util/defaults.js +4 -4
- package/lib/util/escapeClassName.js +2 -2
- package/lib/util/escapeCommas.js +1 -1
- package/lib/util/flattenColorPalette.js +2 -2
- package/lib/util/formatVariantSelector.js +24 -19
- package/lib/util/getAllConfigs.js +4 -5
- package/lib/util/isKeyframeRule.js +1 -1
- package/lib/util/isPlainObject.js +2 -2
- package/lib/util/isSyntacticallyValidPropertyValue.js +10 -10
- package/lib/util/log.js +6 -23
- package/lib/util/nameClass.js +4 -4
- package/lib/util/negateValue.js +8 -8
- package/lib/util/normalizeConfig.js +63 -94
- package/lib/util/normalizeScreens.js +18 -18
- package/lib/util/parseAnimationValue.js +38 -38
- package/lib/util/parseBoxShadowValue.js +18 -18
- package/lib/util/parseDependency.js +4 -4
- package/lib/util/parseGlob.js +4 -4
- package/lib/util/parseObjectStyles.js +1 -1
- package/lib/util/pluginUtils.js +36 -21
- package/lib/util/prefixSelector.js +4 -4
- package/lib/util/pseudoElements.js +72 -69
- package/lib/util/removeAlphaVariables.js +1 -1
- package/lib/util/resolveConfig.js +11 -15
- package/lib/util/resolveConfigPath.js +6 -6
- package/lib/util/responsive.js +1 -1
- package/lib/util/splitAtTopLevelOnly.js +3 -3
- package/lib/util/toColorValue.js +1 -1
- package/lib/util/toPath.js +2 -2
- package/lib/util/transformThemeValue.js +24 -24
- package/lib/util/validateConfig.js +9 -20
- package/lib/util/validateFormalSyntax.js +5 -5
- package/lib/util/withAlphaVariable.js +5 -5
- package/lib/value-parser/index.js +5 -5
- package/lib/value-parser/parse.js +43 -43
- package/lib/value-parser/stringify.js +11 -11
- package/lib/value-parser/unit.js +5 -5
- package/lib/value-parser/walk.js +1 -1
- package/nesting/index.d.ts +4 -0
- package/package.json +41 -36
- package/peers/index.js +96503 -0
- package/resolveConfig.d.ts +22 -3
- package/scripts/generate-types.js +1 -2
- package/scripts/release-notes.js +1 -1
- package/src/cli/build/deps.js +56 -0
- package/src/cli/build/index.js +0 -4
- package/src/cli/build/plugin.js +53 -85
- package/src/cli/build/watching.js +1 -1
- package/src/cli/index.js +0 -1
- package/src/cli-peer-dependencies.js +15 -0
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +118 -31
- package/src/css/preflight.css +18 -12
- package/src/featureFlags.js +3 -5
- package/src/lib/content.js +39 -30
- package/src/lib/defaultExtractor.js +29 -6
- package/src/lib/expandApplyAtRules.js +24 -0
- package/src/lib/expandTailwindAtRules.js +19 -56
- package/src/lib/generateRules.js +39 -8
- package/src/lib/load-config.ts +13 -0
- package/src/lib/normalizeTailwindDirectives.js +27 -0
- package/src/lib/offsets.js +62 -3
- package/src/lib/resolveDefaultsAtRules.js +5 -1
- package/src/lib/setupContextUtils.js +79 -39
- package/src/plugin.js +0 -86
- package/src/processTailwindFeatures.js +0 -3
- package/src/util/cloneNodes.js +35 -14
- package/src/util/dataTypes.js +72 -6
- package/src/util/formatVariantSelector.js +7 -0
- package/src/util/isPlainObject.js +1 -1
- package/src/util/log.js +0 -24
- package/src/util/normalizeConfig.js +11 -38
- package/src/util/pluginUtils.js +20 -0
- package/src/util/pseudoElements.js +4 -0
- package/src/util/validateConfig.js +0 -10
- package/stubs/config.full.js +68 -8
- package/stubs/config.simple.js +1 -1
- package/stubs/postcss.config.cjs +1 -0
- package/stubs/postcss.config.js +1 -0
- package/types/config.d.ts +12 -5
- package/types/generated/corePluginList.d.ts +1 -1
- package/types/generated/default-theme.d.ts +28 -9
- package/types/index.d.ts +7 -3
- package/index.css +0 -5
- package/lib/lib/detectNesting.js +0 -45
- package/lib/lib/handleImportAtRules.js +0 -50
- package/src/lib/detectNesting.js +0 -47
- package/src/lib/handleImportAtRules.js +0 -34
package/src/plugin.js
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import postcss from 'postcss'
|
|
2
|
-
import lightningcss, { Features } from 'lightningcss'
|
|
3
|
-
import browserslist from 'browserslist'
|
|
4
1
|
import setupTrackingContext from './lib/setupTrackingContext'
|
|
5
2
|
import processTailwindFeatures from './processTailwindFeatures'
|
|
6
3
|
import { env } from './lib/sharedState'
|
|
7
4
|
import { findAtConfigPath } from './lib/findAtConfigPath'
|
|
8
|
-
import { handleImportAtRules } from './lib/handleImportAtRules'
|
|
9
|
-
import { version as tailwindVersion } from '../package.json'
|
|
10
|
-
|
|
11
|
-
function license() {
|
|
12
|
-
return `/* ! tailwindcss v${tailwindVersion} | MIT License | https://tailwindcss.com */\n`
|
|
13
|
-
}
|
|
14
5
|
|
|
15
6
|
module.exports = function tailwindcss(configOrPath) {
|
|
16
7
|
return {
|
|
@@ -22,7 +13,6 @@ module.exports = function tailwindcss(configOrPath) {
|
|
|
22
13
|
console.time('JIT TOTAL')
|
|
23
14
|
return root
|
|
24
15
|
},
|
|
25
|
-
...handleImportAtRules(),
|
|
26
16
|
async function (root, result) {
|
|
27
17
|
// Use the path for the `@config` directive if it exists, otherwise use the
|
|
28
18
|
// path for the file being processed
|
|
@@ -44,82 +34,6 @@ module.exports = function tailwindcss(configOrPath) {
|
|
|
44
34
|
|
|
45
35
|
await processTailwindFeatures(context)(root, result)
|
|
46
36
|
},
|
|
47
|
-
function lightningCssPlugin(_root, result) {
|
|
48
|
-
let map = result.map ?? result.opts.map
|
|
49
|
-
|
|
50
|
-
let intermediateResult = result.root.toResult({
|
|
51
|
-
map: map ? { inline: true } : false,
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
let intermediateMap = intermediateResult.map?.toJSON?.() ?? map
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
let resolvedBrowsersListConfig = browserslist.findConfig(
|
|
58
|
-
result.opts.from ?? process.cwd()
|
|
59
|
-
)?.defaults
|
|
60
|
-
let defaultBrowsersListConfig = require('../package.json').browserslist
|
|
61
|
-
let browsersListConfig = resolvedBrowsersListConfig ?? defaultBrowsersListConfig
|
|
62
|
-
|
|
63
|
-
let transformed = lightningcss.transform({
|
|
64
|
-
filename: result.opts.from,
|
|
65
|
-
code: Buffer.from(intermediateResult.css),
|
|
66
|
-
minify: false,
|
|
67
|
-
sourceMap: !!intermediateMap,
|
|
68
|
-
targets: lightningcss.browserslistToTargets(browserslist(browsersListConfig)),
|
|
69
|
-
drafts: {
|
|
70
|
-
nesting: true,
|
|
71
|
-
customMedia: true,
|
|
72
|
-
},
|
|
73
|
-
nonStandard: {
|
|
74
|
-
deepSelectorCombinator: true,
|
|
75
|
-
},
|
|
76
|
-
include: Features.Nesting,
|
|
77
|
-
exclude: Features.LogicalProperties,
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
let code = transformed.code.toString()
|
|
81
|
-
|
|
82
|
-
// https://postcss.org/api/#sourcemapoptions
|
|
83
|
-
if (intermediateMap && transformed.map != null) {
|
|
84
|
-
let prev = transformed.map.toString()
|
|
85
|
-
|
|
86
|
-
if (typeof intermediateMap === 'object') {
|
|
87
|
-
intermediateMap.prev = prev
|
|
88
|
-
} else {
|
|
89
|
-
code = `${code}\n/*# sourceMappingURL=data:application/json;base64,${Buffer.from(
|
|
90
|
-
prev
|
|
91
|
-
).toString('base64')} */`
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
result.root = postcss.parse(license() + code, {
|
|
96
|
-
...result.opts,
|
|
97
|
-
map: intermediateMap,
|
|
98
|
-
})
|
|
99
|
-
} catch (err) {
|
|
100
|
-
if (err.source && typeof process !== 'undefined' && process.env.JEST_WORKER_ID) {
|
|
101
|
-
let lines = err.source.split('\n')
|
|
102
|
-
err = new Error(
|
|
103
|
-
[
|
|
104
|
-
'Error formatting using Lightning CSS:',
|
|
105
|
-
'',
|
|
106
|
-
...[
|
|
107
|
-
'```css',
|
|
108
|
-
...lines.slice(Math.max(err.loc.line - 3, 0), err.loc.line),
|
|
109
|
-
' '.repeat(err.loc.column - 1) + '^-- ' + err.toString(),
|
|
110
|
-
...lines.slice(err.loc.line, err.loc.line + 2),
|
|
111
|
-
'```',
|
|
112
|
-
],
|
|
113
|
-
].join('\n')
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (Error.captureStackTrace) {
|
|
118
|
-
Error.captureStackTrace(err, lightningCssPlugin)
|
|
119
|
-
}
|
|
120
|
-
throw err
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
37
|
env.DEBUG &&
|
|
124
38
|
function (root) {
|
|
125
39
|
console.timeEnd('JIT TOTAL')
|
|
@@ -7,7 +7,6 @@ import resolveDefaultsAtRules from './lib/resolveDefaultsAtRules'
|
|
|
7
7
|
import collapseAdjacentRules from './lib/collapseAdjacentRules'
|
|
8
8
|
import collapseDuplicateDeclarations from './lib/collapseDuplicateDeclarations'
|
|
9
9
|
import partitionApplyAtRules from './lib/partitionApplyAtRules'
|
|
10
|
-
import detectNesting from './lib/detectNesting'
|
|
11
10
|
import { createContext } from './lib/setupContextUtils'
|
|
12
11
|
import { issueFlagNotices } from './featureFlags'
|
|
13
12
|
|
|
@@ -15,8 +14,6 @@ export default function processTailwindFeatures(setupContext) {
|
|
|
15
14
|
return async function (root, result) {
|
|
16
15
|
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root)
|
|
17
16
|
|
|
18
|
-
detectNesting()(root, result)
|
|
19
|
-
|
|
20
17
|
// Partition apply rules that are found in the css
|
|
21
18
|
// itself.
|
|
22
19
|
partitionApplyAtRules()(root, result)
|
package/src/util/cloneNodes.js
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {import('postcss').Container[]} nodes
|
|
3
|
+
* @param {any} source
|
|
4
|
+
* @param {any} raws
|
|
5
|
+
* @returns {import('postcss').Container[]}
|
|
6
|
+
*/
|
|
1
7
|
export default function cloneNodes(nodes, source = undefined, raws = undefined) {
|
|
2
8
|
return nodes.map((node) => {
|
|
3
9
|
let cloned = node.clone()
|
|
4
10
|
|
|
5
|
-
// We always want override the source map
|
|
6
|
-
// except when explicitly told not to
|
|
7
|
-
let shouldOverwriteSource = node.raws.tailwind?.preserveSource !== true || !cloned.source
|
|
8
|
-
|
|
9
|
-
if (source !== undefined && shouldOverwriteSource) {
|
|
10
|
-
cloned.source = source
|
|
11
|
-
|
|
12
|
-
if ('walk' in cloned) {
|
|
13
|
-
cloned.walk((child) => {
|
|
14
|
-
child.source = source
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
11
|
if (raws !== undefined) {
|
|
20
12
|
cloned.raws.tailwind = {
|
|
21
13
|
...cloned.raws.tailwind,
|
|
@@ -23,6 +15,35 @@ export default function cloneNodes(nodes, source = undefined, raws = undefined)
|
|
|
23
15
|
}
|
|
24
16
|
}
|
|
25
17
|
|
|
18
|
+
if (source !== undefined) {
|
|
19
|
+
traverse(cloned, (node) => {
|
|
20
|
+
// Do not traverse nodes that have opted
|
|
21
|
+
// to preserve their original source
|
|
22
|
+
let shouldPreserveSource = node.raws.tailwind?.preserveSource === true && node.source
|
|
23
|
+
if (shouldPreserveSource) {
|
|
24
|
+
return false
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Otherwise we can safely replace the source
|
|
28
|
+
// And continue traversing
|
|
29
|
+
node.source = source
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
return cloned
|
|
27
34
|
})
|
|
28
35
|
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Traverse a tree of nodes and don't traverse children if the callback
|
|
39
|
+
* returns false. Ideally we'd use Container#walk instead of this
|
|
40
|
+
* function but it stops traversing siblings too.
|
|
41
|
+
*
|
|
42
|
+
* @param {import('postcss').Container} node
|
|
43
|
+
* @param {(node: import('postcss').Container) => boolean} onNode
|
|
44
|
+
*/
|
|
45
|
+
function traverse(node, onNode) {
|
|
46
|
+
if (onNode(node) !== false) {
|
|
47
|
+
node.each?.((child) => traverse(child, onNode))
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/util/dataTypes.js
CHANGED
|
@@ -10,10 +10,34 @@ function isCSSFunction(value) {
|
|
|
10
10
|
return cssFunctions.some((fn) => new RegExp(`^${fn}\\(.*\\)`).test(value))
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// These properties accept a `<dashed-ident>` as one of the values. This means that you can use them
|
|
14
|
+
// as: `timeline-scope: --tl;`
|
|
15
|
+
//
|
|
16
|
+
// Without the `var(--tl)`, in these cases we don't want to normalize the value, and you should add
|
|
17
|
+
// the `var()` yourself.
|
|
18
|
+
//
|
|
19
|
+
// More info:
|
|
20
|
+
// - https://drafts.csswg.org/scroll-animations/#propdef-timeline-scope
|
|
21
|
+
// - https://developer.mozilla.org/en-US/docs/Web/CSS/timeline-scope#dashed-ident
|
|
22
|
+
//
|
|
23
|
+
const AUTO_VAR_INJECTION_EXCEPTIONS = new Set([
|
|
24
|
+
// Concrete properties
|
|
25
|
+
'scroll-timeline-name',
|
|
26
|
+
'timeline-scope',
|
|
27
|
+
'view-timeline-name',
|
|
28
|
+
'font-palette',
|
|
29
|
+
|
|
30
|
+
// Shorthand properties
|
|
31
|
+
'scroll-timeline',
|
|
32
|
+
'animation-timeline',
|
|
33
|
+
'view-timeline',
|
|
34
|
+
])
|
|
35
|
+
|
|
13
36
|
// This is not a data type, but rather a function that can normalize the
|
|
14
37
|
// correct values.
|
|
15
|
-
export function normalize(value, isRoot = true) {
|
|
16
|
-
|
|
38
|
+
export function normalize(value, context = null, isRoot = true) {
|
|
39
|
+
let isVarException = context && AUTO_VAR_INJECTION_EXCEPTIONS.has(context.property)
|
|
40
|
+
if (value.startsWith('--') && !isVarException) {
|
|
17
41
|
return `var(${value})`
|
|
18
42
|
}
|
|
19
43
|
|
|
@@ -27,7 +51,7 @@ export function normalize(value, isRoot = true) {
|
|
|
27
51
|
return part
|
|
28
52
|
}
|
|
29
53
|
|
|
30
|
-
return normalize(part, false)
|
|
54
|
+
return normalize(part, context, false)
|
|
31
55
|
})
|
|
32
56
|
.join('')
|
|
33
57
|
}
|
|
@@ -53,13 +77,43 @@ export function normalize(value, isRoot = true) {
|
|
|
53
77
|
|
|
54
78
|
/**
|
|
55
79
|
* Add spaces around operators inside math functions
|
|
56
|
-
* like calc() that do not follow an operator
|
|
80
|
+
* like calc() that do not follow an operator, '(', or `,`.
|
|
57
81
|
*
|
|
58
82
|
* @param {string} value
|
|
59
83
|
* @returns {string}
|
|
60
84
|
*/
|
|
61
85
|
function normalizeMathOperatorSpacing(value) {
|
|
62
86
|
let preventFormattingInFunctions = ['theme']
|
|
87
|
+
let preventFormattingKeywords = [
|
|
88
|
+
'min-content',
|
|
89
|
+
'max-content',
|
|
90
|
+
'fit-content',
|
|
91
|
+
|
|
92
|
+
// Env
|
|
93
|
+
'safe-area-inset-top',
|
|
94
|
+
'safe-area-inset-right',
|
|
95
|
+
'safe-area-inset-bottom',
|
|
96
|
+
'safe-area-inset-left',
|
|
97
|
+
|
|
98
|
+
'titlebar-area-x',
|
|
99
|
+
'titlebar-area-y',
|
|
100
|
+
'titlebar-area-width',
|
|
101
|
+
'titlebar-area-height',
|
|
102
|
+
|
|
103
|
+
'keyboard-inset-top',
|
|
104
|
+
'keyboard-inset-right',
|
|
105
|
+
'keyboard-inset-bottom',
|
|
106
|
+
'keyboard-inset-left',
|
|
107
|
+
'keyboard-inset-width',
|
|
108
|
+
'keyboard-inset-height',
|
|
109
|
+
|
|
110
|
+
'radial-gradient',
|
|
111
|
+
'linear-gradient',
|
|
112
|
+
'conic-gradient',
|
|
113
|
+
'repeating-radial-gradient',
|
|
114
|
+
'repeating-linear-gradient',
|
|
115
|
+
'repeating-conic-gradient',
|
|
116
|
+
]
|
|
63
117
|
|
|
64
118
|
return value.replace(/(calc|min|max|clamp)\(.+\)/g, (match) => {
|
|
65
119
|
let result = ''
|
|
@@ -102,15 +156,27 @@ function normalizeMathOperatorSpacing(value) {
|
|
|
102
156
|
result += consumeUntil([')', ','])
|
|
103
157
|
}
|
|
104
158
|
|
|
159
|
+
// Skip formatting of known keywords
|
|
160
|
+
else if (preventFormattingKeywords.some((keyword) => peek(keyword))) {
|
|
161
|
+
let keyword = preventFormattingKeywords.find((keyword) => peek(keyword))
|
|
162
|
+
result += keyword
|
|
163
|
+
i += keyword.length - 1
|
|
164
|
+
}
|
|
165
|
+
|
|
105
166
|
// Skip formatting inside known functions
|
|
106
167
|
else if (preventFormattingInFunctions.some((fn) => peek(fn))) {
|
|
107
168
|
result += consumeUntil([')'])
|
|
108
169
|
}
|
|
109
170
|
|
|
171
|
+
// Don't break CSS grid track names
|
|
172
|
+
else if (peek('[')) {
|
|
173
|
+
result += consumeUntil([']'])
|
|
174
|
+
}
|
|
175
|
+
|
|
110
176
|
// Handle operators
|
|
111
177
|
else if (
|
|
112
178
|
['+', '-', '*', '/'].includes(char) &&
|
|
113
|
-
!['(', '+', '-', '*', '/'].includes(lastChar())
|
|
179
|
+
!['(', '+', '-', '*', '/', ','].includes(lastChar())
|
|
114
180
|
) {
|
|
115
181
|
result += ` ${char} `
|
|
116
182
|
} else {
|
|
@@ -327,7 +393,7 @@ let absoluteSizes = new Set([
|
|
|
327
393
|
'medium',
|
|
328
394
|
'large',
|
|
329
395
|
'x-large',
|
|
330
|
-
'
|
|
396
|
+
'xx-large',
|
|
331
397
|
'xxx-large',
|
|
332
398
|
])
|
|
333
399
|
export function absoluteSize(value) {
|
|
@@ -186,6 +186,13 @@ export function finalizeSelector(current, formats, { context, candidate, base })
|
|
|
186
186
|
// Remove extraneous selectors that do not include the base candidate
|
|
187
187
|
selector.each((sel) => eliminateIrrelevantSelectors(sel, base))
|
|
188
188
|
|
|
189
|
+
// If ffter eliminating irrelevant selectors, we end up with nothing
|
|
190
|
+
// Then the whole "rule" this is associated with does not need to exist
|
|
191
|
+
// We use `null` as a marker value for that case
|
|
192
|
+
if (selector.length === 0) {
|
|
193
|
+
return null
|
|
194
|
+
}
|
|
195
|
+
|
|
189
196
|
// If there are no formats that means there were no variants added to the candidate
|
|
190
197
|
// so we can just return the selector as-is
|
|
191
198
|
let formatAst = Array.isArray(formats)
|
package/src/util/log.js
CHANGED
|
@@ -17,30 +17,6 @@ export function dim(input) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export default {
|
|
20
|
-
group(key, cb) {
|
|
21
|
-
if (typeof process !== 'undefined' && process.env.JEST_WORKER_ID) return
|
|
22
|
-
|
|
23
|
-
if (key && alreadyShown.has(key)) return
|
|
24
|
-
if (key) alreadyShown.add(key)
|
|
25
|
-
|
|
26
|
-
console.warn('')
|
|
27
|
-
|
|
28
|
-
cb({
|
|
29
|
-
info(messages) {
|
|
30
|
-
messages.forEach((message) => console.warn(colors.bold(colors.cyan('info')), '-', message))
|
|
31
|
-
},
|
|
32
|
-
warn(messages) {
|
|
33
|
-
messages.forEach((message) =>
|
|
34
|
-
console.warn(colors.bold(colors.yellow('warn')), '-', message)
|
|
35
|
-
)
|
|
36
|
-
},
|
|
37
|
-
risk(messages) {
|
|
38
|
-
messages.forEach((message) =>
|
|
39
|
-
console.warn(colors.bold(colors.magenta('risk')), '-', message)
|
|
40
|
-
)
|
|
41
|
-
},
|
|
42
|
-
})
|
|
43
|
-
},
|
|
44
20
|
info(key, messages) {
|
|
45
21
|
log(colors.bold(colors.cyan('info')), ...(Array.isArray(key) ? [key] : [messages, key]))
|
|
46
22
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flagEnabled
|
|
1
|
+
import { flagEnabled } from '../featureFlags'
|
|
2
2
|
import log, { dim } from './log'
|
|
3
3
|
|
|
4
4
|
export function normalizeConfig(config) {
|
|
@@ -18,10 +18,6 @@ export function normalizeConfig(config) {
|
|
|
18
18
|
* }
|
|
19
19
|
*/
|
|
20
20
|
let valid = (() => {
|
|
21
|
-
if (config.content === 'auto') {
|
|
22
|
-
return true
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
// `config.purge` should not exist anymore
|
|
26
22
|
if (config.purge) {
|
|
27
23
|
return false
|
|
@@ -200,17 +196,11 @@ export function normalizeConfig(config) {
|
|
|
200
196
|
files: (() => {
|
|
201
197
|
let { content, purge } = config
|
|
202
198
|
|
|
203
|
-
if (
|
|
204
|
-
if (purge)
|
|
205
|
-
if (Array.isArray(purge)) return purge
|
|
206
|
-
if (Array.isArray(purge?.content)) return purge.content
|
|
207
|
-
return []
|
|
208
|
-
}
|
|
209
|
-
|
|
199
|
+
if (Array.isArray(purge)) return purge
|
|
200
|
+
if (Array.isArray(purge?.content)) return purge.content
|
|
210
201
|
if (Array.isArray(content)) return content
|
|
211
202
|
if (Array.isArray(content?.content)) return content.content
|
|
212
203
|
if (Array.isArray(content?.files)) return content.files
|
|
213
|
-
if (content === 'auto') return ['auto']
|
|
214
204
|
|
|
215
205
|
return []
|
|
216
206
|
})(),
|
|
@@ -294,33 +284,16 @@ export function normalizeConfig(config) {
|
|
|
294
284
|
})(),
|
|
295
285
|
}
|
|
296
286
|
|
|
297
|
-
// Force disable the `oxideParser` feature flag when using unsupported features.
|
|
298
|
-
// TODO: Remove once we have prefix or separator support in the oxide parser.
|
|
299
|
-
if (config.prefix !== '' || config.separator !== ':') {
|
|
300
|
-
if (config.experimental === 'all') {
|
|
301
|
-
config.experimental = {}
|
|
302
|
-
for (let key of featureFlags.experimental) {
|
|
303
|
-
config.experimental[key] = true
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
config.experimental = config.experimental ?? {}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
config.experimental.oxideParser = false
|
|
310
|
-
}
|
|
311
|
-
|
|
312
287
|
// Validate globs to prevent bogus globs.
|
|
313
288
|
// E.g.: `./src/*.{html}` is invalid, the `{html}` should just be `html`
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
break
|
|
323
|
-
}
|
|
289
|
+
for (let file of config.content.files) {
|
|
290
|
+
if (typeof file === 'string' && /{([^,]*?)}/g.test(file)) {
|
|
291
|
+
log.warn('invalid-glob-braces', [
|
|
292
|
+
`The glob pattern ${dim(file)} in your Tailwind CSS configuration is invalid.`,
|
|
293
|
+
`Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`,
|
|
294
|
+
// TODO: Add https://tw.wtf/invalid-glob-braces
|
|
295
|
+
])
|
|
296
|
+
break
|
|
324
297
|
}
|
|
325
298
|
}
|
|
326
299
|
|
package/src/util/pluginUtils.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from './dataTypes'
|
|
19
19
|
import negateValue from './negateValue'
|
|
20
20
|
import { backgroundSize } from './validateFormalSyntax'
|
|
21
|
+
import { flagEnabled } from '../featureFlags.js'
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* @param {import('postcss-selector-parser').Container} selectors
|
|
@@ -87,6 +88,22 @@ function isArbitraryValue(input) {
|
|
|
87
88
|
function splitUtilityModifier(modifier) {
|
|
88
89
|
let slashIdx = modifier.lastIndexOf('/')
|
|
89
90
|
|
|
91
|
+
// If the `/` is inside an arbitrary, we want to find the previous one if any
|
|
92
|
+
// This logic probably isn't perfect but it should work for most cases
|
|
93
|
+
let arbitraryStartIdx = modifier.lastIndexOf('[', slashIdx)
|
|
94
|
+
let arbitraryEndIdx = modifier.indexOf(']', slashIdx)
|
|
95
|
+
|
|
96
|
+
let isNextToArbitrary = modifier[slashIdx - 1] === ']' || modifier[slashIdx + 1] === '['
|
|
97
|
+
|
|
98
|
+
// Backtrack to the previous `/` if the one we found was inside an arbitrary
|
|
99
|
+
if (!isNextToArbitrary) {
|
|
100
|
+
if (arbitraryStartIdx !== -1 && arbitraryEndIdx !== -1) {
|
|
101
|
+
if (arbitraryStartIdx < slashIdx && slashIdx < arbitraryEndIdx) {
|
|
102
|
+
slashIdx = modifier.lastIndexOf('/', arbitraryStartIdx)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
90
107
|
if (slashIdx === -1 || slashIdx === modifier.length - 1) {
|
|
91
108
|
return [modifier, undefined]
|
|
92
109
|
}
|
|
@@ -242,9 +259,12 @@ export function coerceValue(types, modifier, options, tailwindConfig) {
|
|
|
242
259
|
* @returns {Iterator<[value: string, type: string, modifier: string | null]>}
|
|
243
260
|
*/
|
|
244
261
|
export function* getMatchingTypes(types, rawModifier, options, tailwindConfig) {
|
|
262
|
+
let modifiersEnabled = flagEnabled(tailwindConfig, 'generalizedModifiers')
|
|
263
|
+
|
|
245
264
|
let [modifier, utilityModifier] = splitUtilityModifier(rawModifier)
|
|
246
265
|
|
|
247
266
|
let canUseUtilityModifier =
|
|
267
|
+
modifiersEnabled &&
|
|
248
268
|
options.modifiers != null &&
|
|
249
269
|
(options.modifiers === 'any' ||
|
|
250
270
|
(typeof options.modifiers === 'object' &&
|
|
@@ -60,6 +60,10 @@ let elementProperties = {
|
|
|
60
60
|
':first-letter': ['terminal', 'jumpable'],
|
|
61
61
|
':first-line': ['terminal', 'jumpable'],
|
|
62
62
|
|
|
63
|
+
':where': [],
|
|
64
|
+
':is': [],
|
|
65
|
+
':has': [],
|
|
66
|
+
|
|
63
67
|
// The default value is used when the pseudo-element is not recognized
|
|
64
68
|
// Because it's not recognized, we don't know if it's terminal or not
|
|
65
69
|
// So we assume it can be moved AND can have user-action pseudo classes attached to it
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import pc from 'picocolors'
|
|
2
1
|
import log from './log'
|
|
3
2
|
|
|
4
3
|
export function validateConfig(config) {
|
|
@@ -10,15 +9,6 @@ export function validateConfig(config) {
|
|
|
10
9
|
])
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
if (config.content.files.includes('auto')) {
|
|
14
|
-
log.group('auto-content-experimental', (log) => {
|
|
15
|
-
log.info([pc.bold('Automatically detecting Tailwind CSS content sources...')])
|
|
16
|
-
log.warn([
|
|
17
|
-
'Automatic content detection is experimental, and the behavior may change at any time.',
|
|
18
|
-
])
|
|
19
|
-
})
|
|
20
|
-
}
|
|
21
|
-
|
|
22
12
|
// Warn if the line-clamp plugin is installed
|
|
23
13
|
try {
|
|
24
14
|
let plugin = require('@tailwindcss/line-clamp')
|
package/stubs/config.full.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
content: [
|
|
2
|
+
content: [],
|
|
3
3
|
presets: [],
|
|
4
4
|
darkMode: 'media', // or 'class'
|
|
5
5
|
theme: {
|
|
@@ -444,6 +444,12 @@ module.exports = {
|
|
|
444
444
|
'span-4': 'span 4 / span 4',
|
|
445
445
|
'span-5': 'span 5 / span 5',
|
|
446
446
|
'span-6': 'span 6 / span 6',
|
|
447
|
+
'span-7': 'span 7 / span 7',
|
|
448
|
+
'span-8': 'span 8 / span 8',
|
|
449
|
+
'span-9': 'span 9 / span 9',
|
|
450
|
+
'span-10': 'span 10 / span 10',
|
|
451
|
+
'span-11': 'span 11 / span 11',
|
|
452
|
+
'span-12': 'span 12 / span 12',
|
|
447
453
|
'span-full': '1 / -1',
|
|
448
454
|
},
|
|
449
455
|
gridRowEnd: {
|
|
@@ -455,6 +461,12 @@ module.exports = {
|
|
|
455
461
|
5: '5',
|
|
456
462
|
6: '6',
|
|
457
463
|
7: '7',
|
|
464
|
+
8: '8',
|
|
465
|
+
9: '9',
|
|
466
|
+
10: '10',
|
|
467
|
+
11: '11',
|
|
468
|
+
12: '12',
|
|
469
|
+
13: '13',
|
|
458
470
|
},
|
|
459
471
|
gridRowStart: {
|
|
460
472
|
auto: 'auto',
|
|
@@ -465,9 +477,16 @@ module.exports = {
|
|
|
465
477
|
5: '5',
|
|
466
478
|
6: '6',
|
|
467
479
|
7: '7',
|
|
480
|
+
8: '8',
|
|
481
|
+
9: '9',
|
|
482
|
+
10: '10',
|
|
483
|
+
11: '11',
|
|
484
|
+
12: '12',
|
|
485
|
+
13: '13',
|
|
468
486
|
},
|
|
469
487
|
gridTemplateColumns: {
|
|
470
488
|
none: 'none',
|
|
489
|
+
subgrid: 'subgrid',
|
|
471
490
|
1: 'repeat(1, minmax(0, 1fr))',
|
|
472
491
|
2: 'repeat(2, minmax(0, 1fr))',
|
|
473
492
|
3: 'repeat(3, minmax(0, 1fr))',
|
|
@@ -483,12 +502,19 @@ module.exports = {
|
|
|
483
502
|
},
|
|
484
503
|
gridTemplateRows: {
|
|
485
504
|
none: 'none',
|
|
505
|
+
subgrid: 'subgrid',
|
|
486
506
|
1: 'repeat(1, minmax(0, 1fr))',
|
|
487
507
|
2: 'repeat(2, minmax(0, 1fr))',
|
|
488
508
|
3: 'repeat(3, minmax(0, 1fr))',
|
|
489
509
|
4: 'repeat(4, minmax(0, 1fr))',
|
|
490
510
|
5: 'repeat(5, minmax(0, 1fr))',
|
|
491
511
|
6: 'repeat(6, minmax(0, 1fr))',
|
|
512
|
+
7: 'repeat(7, minmax(0, 1fr))',
|
|
513
|
+
8: 'repeat(8, minmax(0, 1fr))',
|
|
514
|
+
9: 'repeat(9, minmax(0, 1fr))',
|
|
515
|
+
10: 'repeat(10, minmax(0, 1fr))',
|
|
516
|
+
11: 'repeat(11, minmax(0, 1fr))',
|
|
517
|
+
12: 'repeat(12, minmax(0, 1fr))',
|
|
492
518
|
},
|
|
493
519
|
height: ({ theme }) => ({
|
|
494
520
|
auto: 'auto',
|
|
@@ -625,8 +651,8 @@ module.exports = {
|
|
|
625
651
|
fit: 'fit-content',
|
|
626
652
|
}),
|
|
627
653
|
maxWidth: ({ theme, breakpoints }) => ({
|
|
654
|
+
...theme('spacing'),
|
|
628
655
|
none: 'none',
|
|
629
|
-
0: '0rem',
|
|
630
656
|
xs: '20rem',
|
|
631
657
|
sm: '24rem',
|
|
632
658
|
md: '28rem',
|
|
@@ -645,8 +671,8 @@ module.exports = {
|
|
|
645
671
|
prose: '65ch',
|
|
646
672
|
...breakpoints(theme('screens')),
|
|
647
673
|
}),
|
|
648
|
-
minHeight: {
|
|
649
|
-
|
|
674
|
+
minHeight: ({ theme }) => ({
|
|
675
|
+
...theme('spacing'),
|
|
650
676
|
full: '100%',
|
|
651
677
|
screen: '100vh',
|
|
652
678
|
svh: '100svh',
|
|
@@ -655,14 +681,14 @@ module.exports = {
|
|
|
655
681
|
min: 'min-content',
|
|
656
682
|
max: 'max-content',
|
|
657
683
|
fit: 'fit-content',
|
|
658
|
-
},
|
|
659
|
-
minWidth: {
|
|
660
|
-
|
|
684
|
+
}),
|
|
685
|
+
minWidth: ({ theme }) => ({
|
|
686
|
+
...theme('spacing'),
|
|
661
687
|
full: '100%',
|
|
662
688
|
min: 'min-content',
|
|
663
689
|
max: 'max-content',
|
|
664
690
|
fit: 'fit-content',
|
|
665
|
-
},
|
|
691
|
+
}),
|
|
666
692
|
objectPosition: {
|
|
667
693
|
bottom: 'bottom',
|
|
668
694
|
center: 'center',
|
|
@@ -944,6 +970,40 @@ module.exports = {
|
|
|
944
970
|
'3/4': '75%',
|
|
945
971
|
full: '100%',
|
|
946
972
|
}),
|
|
973
|
+
size: ({ theme }) => ({
|
|
974
|
+
auto: 'auto',
|
|
975
|
+
...theme('spacing'),
|
|
976
|
+
'1/2': '50%',
|
|
977
|
+
'1/3': '33.333333%',
|
|
978
|
+
'2/3': '66.666667%',
|
|
979
|
+
'1/4': '25%',
|
|
980
|
+
'2/4': '50%',
|
|
981
|
+
'3/4': '75%',
|
|
982
|
+
'1/5': '20%',
|
|
983
|
+
'2/5': '40%',
|
|
984
|
+
'3/5': '60%',
|
|
985
|
+
'4/5': '80%',
|
|
986
|
+
'1/6': '16.666667%',
|
|
987
|
+
'2/6': '33.333333%',
|
|
988
|
+
'3/6': '50%',
|
|
989
|
+
'4/6': '66.666667%',
|
|
990
|
+
'5/6': '83.333333%',
|
|
991
|
+
'1/12': '8.333333%',
|
|
992
|
+
'2/12': '16.666667%',
|
|
993
|
+
'3/12': '25%',
|
|
994
|
+
'4/12': '33.333333%',
|
|
995
|
+
'5/12': '41.666667%',
|
|
996
|
+
'6/12': '50%',
|
|
997
|
+
'7/12': '58.333333%',
|
|
998
|
+
'8/12': '66.666667%',
|
|
999
|
+
'9/12': '75%',
|
|
1000
|
+
'10/12': '83.333333%',
|
|
1001
|
+
'11/12': '91.666667%',
|
|
1002
|
+
full: '100%',
|
|
1003
|
+
min: 'min-content',
|
|
1004
|
+
max: 'max-content',
|
|
1005
|
+
fit: 'fit-content',
|
|
1006
|
+
}),
|
|
947
1007
|
width: ({ theme }) => ({
|
|
948
1008
|
auto: 'auto',
|
|
949
1009
|
...theme('spacing'),
|
package/stubs/config.simple.js
CHANGED