tailwindcss 3.0.0-alpha.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -2
- package/colors.js +2 -1
- package/defaultConfig.js +2 -1
- package/defaultTheme.js +2 -1
- package/lib/cli.js +58 -58
- package/lib/corePluginList.js +3 -0
- package/lib/corePlugins.js +227 -172
- package/lib/css/preflight.css +5 -3
- package/lib/featureFlags.js +3 -1
- package/lib/lib/detectNesting.js +17 -2
- package/lib/lib/evaluateTailwindFunctions.js +6 -2
- package/lib/lib/expandApplyAtRules.js +23 -6
- package/lib/lib/expandTailwindAtRules.js +19 -1
- package/lib/lib/generateRules.js +54 -0
- package/lib/lib/resolveDefaultsAtRules.js +23 -9
- package/lib/lib/setupContextUtils.js +48 -71
- package/lib/lib/substituteScreenAtRules.js +7 -4
- package/lib/util/buildMediaQuery.js +13 -24
- package/lib/util/dataTypes.js +14 -3
- package/lib/util/defaults.js +6 -0
- package/lib/util/formatVariantSelector.js +88 -4
- package/lib/util/isValidArbitraryValue.js +64 -0
- package/lib/util/log.js +4 -0
- package/lib/util/nameClass.js +1 -0
- package/lib/util/normalizeConfig.js +34 -5
- package/lib/util/normalizeScreens.js +61 -0
- package/lib/util/resolveConfig.js +8 -8
- package/package.json +14 -13
- package/peers/index.js +3739 -3027
- package/plugin.js +2 -1
- package/resolveConfig.js +2 -1
- package/src/corePluginList.js +1 -1
- package/src/corePlugins.js +205 -165
- package/src/css/preflight.css +5 -3
- package/src/featureFlags.js +5 -1
- package/src/lib/detectNesting.js +22 -3
- package/src/lib/evaluateTailwindFunctions.js +5 -2
- package/src/lib/expandApplyAtRules.js +29 -2
- package/src/lib/expandTailwindAtRules.js +18 -0
- package/src/lib/generateRules.js +57 -0
- package/src/lib/resolveDefaultsAtRules.js +28 -7
- package/src/lib/setupContextUtils.js +45 -64
- package/src/lib/substituteScreenAtRules.js +6 -3
- package/src/util/buildMediaQuery.js +14 -18
- package/src/util/dataTypes.js +11 -6
- package/src/util/defaults.js +6 -0
- package/src/util/formatVariantSelector.js +92 -1
- package/src/util/isValidArbitraryValue.js +61 -0
- package/src/util/log.js +4 -0
- package/src/util/nameClass.js +1 -1
- package/src/util/normalizeConfig.js +14 -1
- package/src/util/normalizeScreens.js +45 -0
- package/stubs/defaultConfig.stub.js +17 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
let matchingBrackets = new Map([
|
|
2
|
+
['{', '}'],
|
|
3
|
+
['[', ']'],
|
|
4
|
+
['(', ')'],
|
|
5
|
+
])
|
|
6
|
+
let inverseMatchingBrackets = new Map(
|
|
7
|
+
Array.from(matchingBrackets.entries()).map(([k, v]) => [v, k])
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
let quotes = new Set(['"', "'", '`'])
|
|
11
|
+
|
|
12
|
+
// Arbitrary values must contain balanced brackets (), [] and {}. Escaped
|
|
13
|
+
// values don't count, and brackets inside quotes also don't count.
|
|
14
|
+
//
|
|
15
|
+
// E.g.: w-[this-is]w-[weird-and-invalid]
|
|
16
|
+
// E.g.: w-[this-is\\]w-\\[weird-but-valid]
|
|
17
|
+
// E.g.: content-['this-is-also-valid]-weirdly-enough']
|
|
18
|
+
export default function isValidArbitraryValue(value) {
|
|
19
|
+
let stack = []
|
|
20
|
+
let inQuotes = false
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < value.length; i++) {
|
|
23
|
+
let char = value[i]
|
|
24
|
+
|
|
25
|
+
if (char === ':' && !inQuotes && stack.length === 0) {
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Non-escaped quotes allow us to "allow" anything in between
|
|
30
|
+
if (quotes.has(char) && value[i - 1] !== '\\') {
|
|
31
|
+
inQuotes = !inQuotes
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (inQuotes) continue
|
|
35
|
+
if (value[i - 1] === '\\') continue // Escaped
|
|
36
|
+
|
|
37
|
+
if (matchingBrackets.has(char)) {
|
|
38
|
+
stack.push(char)
|
|
39
|
+
} else if (inverseMatchingBrackets.has(char)) {
|
|
40
|
+
let inverse = inverseMatchingBrackets.get(char)
|
|
41
|
+
|
|
42
|
+
// Nothing to pop from, therefore it is unbalanced
|
|
43
|
+
if (stack.length <= 0) {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Popped value must match the inverse value, otherwise it is unbalanced
|
|
48
|
+
if (stack.pop() !== inverse) {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// If there is still something on the stack, it is also unbalanced
|
|
55
|
+
if (stack.length > 0) {
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// All good, totally balanced!
|
|
60
|
+
return true
|
|
61
|
+
}
|
package/src/util/log.js
CHANGED
|
@@ -12,6 +12,10 @@ function log(chalk, messages, key) {
|
|
|
12
12
|
messages.forEach((message) => console.warn(chalk, '-', message))
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export function dim(input) {
|
|
16
|
+
return chalk.dim(input)
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
export default {
|
|
16
20
|
info(key, messages) {
|
|
17
21
|
log(chalk.bold.cyan('info'), ...(Array.isArray(key) ? [key] : [messages, key]))
|
package/src/util/nameClass.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import log from './log'
|
|
1
|
+
import log, { dim } from './log'
|
|
2
2
|
|
|
3
3
|
export function normalizeConfig(config) {
|
|
4
4
|
// Quick structure validation
|
|
@@ -245,5 +245,18 @@ export function normalizeConfig(config) {
|
|
|
245
245
|
})(),
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
// Validate globs to prevent bogus globs.
|
|
249
|
+
// E.g.: `./src/*.{html}` is invalid, the `{html}` should just be `html`
|
|
250
|
+
for (let file of config.content.files) {
|
|
251
|
+
if (typeof file === 'string' && /{([^,]*?)}/g.test(file)) {
|
|
252
|
+
log.warn('invalid-glob-braces', [
|
|
253
|
+
`The glob pattern ${dim(file)} in your config is invalid.`,
|
|
254
|
+
` Update it to ${dim(file.replace(/{([^,]*?)}/g, '$1'))} to silence this warning.`,
|
|
255
|
+
// TODO: Add https://tw.wtf/invalid-glob-braces
|
|
256
|
+
])
|
|
257
|
+
break
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
248
261
|
return config
|
|
249
262
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A function that normalizes the various forms that the screens object can be
|
|
3
|
+
* provided in.
|
|
4
|
+
*
|
|
5
|
+
* Input(s):
|
|
6
|
+
* - ['100px', '200px'] // Raw strings
|
|
7
|
+
* - { sm: '100px', md: '200px' } // Object with string values
|
|
8
|
+
* - { sm: { min: '100px' }, md: { max: '100px' } } // Object with object values
|
|
9
|
+
* - { sm: [{ min: '100px' }, { max: '200px' }] } // Object with object array (multiple values)
|
|
10
|
+
*
|
|
11
|
+
* Output(s):
|
|
12
|
+
* - [{ name: 'sm', values: [{ min: '100px', max: '200px' }] }] // List of objects, that contains multiple values
|
|
13
|
+
*/
|
|
14
|
+
export function normalizeScreens(screens, root = true) {
|
|
15
|
+
if (Array.isArray(screens)) {
|
|
16
|
+
return screens.map((screen) => {
|
|
17
|
+
if (root && Array.isArray(screen)) {
|
|
18
|
+
throw new Error('The tuple syntax is not supported for `screens`.')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof screen === 'string') {
|
|
22
|
+
return { name: screen.toString(), values: [{ min: screen, max: undefined }] }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let [name, options] = screen
|
|
26
|
+
name = name.toString()
|
|
27
|
+
|
|
28
|
+
if (typeof options === 'string') {
|
|
29
|
+
return { name, values: [{ min: options, max: undefined }] }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (Array.isArray(options)) {
|
|
33
|
+
return { name, values: options.map((option) => resolveValue(option)) }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { name, values: [resolveValue(options)] }
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return normalizeScreens(Object.entries(screens ?? {}), false)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function resolveValue({ 'min-width': _minWidth, min = _minWidth, max, raw } = {}) {
|
|
44
|
+
return { min, max, raw }
|
|
45
|
+
}
|
|
@@ -797,6 +797,23 @@ module.exports = {
|
|
|
797
797
|
},
|
|
798
798
|
textColor: ({ theme }) => theme('colors'),
|
|
799
799
|
textDecorationColor: ({ theme }) => theme('colors'),
|
|
800
|
+
textDecorationThickness: {
|
|
801
|
+
auto: 'auto',
|
|
802
|
+
'from-font': 'from-font',
|
|
803
|
+
0: '0px',
|
|
804
|
+
1: '1px',
|
|
805
|
+
2: '2px',
|
|
806
|
+
4: '4px',
|
|
807
|
+
8: '8px',
|
|
808
|
+
},
|
|
809
|
+
textUnderlineOffset: {
|
|
810
|
+
auto: 'auto',
|
|
811
|
+
0: '0px',
|
|
812
|
+
1: '1px',
|
|
813
|
+
2: '2px',
|
|
814
|
+
4: '4px',
|
|
815
|
+
8: '8px',
|
|
816
|
+
},
|
|
800
817
|
textIndent: ({ theme }) => ({
|
|
801
818
|
...theme('spacing'),
|
|
802
819
|
}),
|