tailwindcss
Advanced tools
Comparing version 0.0.0-insiders.1454190 to 0.0.0-insiders.1676118
@@ -12,6 +12,14 @@ "use strict"; | ||
_export(exports, { | ||
lazyPostcss: ()=>lazyPostcss, | ||
lazyPostcssImport: ()=>lazyPostcssImport, | ||
lazyAutoprefixer: ()=>lazyAutoprefixer, | ||
lazyCssnano: ()=>lazyCssnano | ||
lazyPostcss: function() { | ||
return lazyPostcss; | ||
}, | ||
lazyPostcssImport: function() { | ||
return lazyPostcssImport; | ||
}, | ||
lazyAutoprefixer: function() { | ||
return lazyAutoprefixer; | ||
}, | ||
lazyCssnano: function() { | ||
return lazyCssnano; | ||
} | ||
}); | ||
@@ -18,0 +26,0 @@ function lazyPostcss() { |
#!/usr/bin/env node | ||
"use strict"; | ||
if (process.env.OXIDE) { | ||
module.exports = require("./oxide/cli"); | ||
} else { | ||
module.exports = require("./cli/index"); | ||
} | ||
module.exports = require("./cli/index"); |
@@ -13,8 +13,16 @@ // @ts-check | ||
_export(exports, { | ||
loadPostcss: ()=>loadPostcss, | ||
loadPostcssImport: ()=>loadPostcssImport, | ||
loadCssNano: ()=>loadCssNano, | ||
loadAutoprefixer: ()=>loadAutoprefixer | ||
loadPostcss: function() { | ||
return loadPostcss; | ||
}, | ||
loadPostcssImport: function() { | ||
return loadPostcssImport; | ||
}, | ||
loadCssNano: function() { | ||
return loadCssNano; | ||
}, | ||
loadAutoprefixer: function() { | ||
return loadAutoprefixer; | ||
} | ||
}); | ||
const _indexJs = require("../../../peers/index.js"); | ||
const _index = require("../../../peers/index.js"); | ||
function loadPostcss() { | ||
@@ -25,3 +33,3 @@ // Try to load a local `postcss` version first | ||
} catch {} | ||
return (0, _indexJs.lazyPostcss)(); | ||
return (0, _index.lazyPostcss)(); | ||
} | ||
@@ -33,3 +41,3 @@ function loadPostcssImport() { | ||
} catch {} | ||
return (0, _indexJs.lazyPostcssImport)(); | ||
return (0, _index.lazyPostcssImport)(); | ||
} | ||
@@ -49,3 +57,3 @@ function loadCssNano() { | ||
} catch {} | ||
return (0, _indexJs.lazyCssnano)()(options); | ||
return (0, _index.lazyCssnano)()(options); | ||
} | ||
@@ -57,3 +65,3 @@ function loadAutoprefixer() { | ||
} catch {} | ||
return (0, _indexJs.lazyAutoprefixer)(); | ||
return (0, _index.lazyAutoprefixer)(); | ||
} |
@@ -8,8 +8,11 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>build | ||
get: function() { | ||
return build; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
const _pluginJs = require("./plugin.js"); | ||
function _interopRequireDefault(obj) { | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
const _resolveConfigPath = require("../../util/resolveConfigPath.js"); | ||
const _plugin = require("./plugin.js"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -19,3 +22,3 @@ default: obj | ||
} | ||
async function build(args, configs) { | ||
async function build(args) { | ||
let input = args["--input"]; | ||
@@ -37,4 +40,4 @@ let shouldWatch = args["--watch"]; | ||
// TODO: Reference the @config path here if exists | ||
let configPath = args["--config"] ? args["--config"] : ((defaultPath)=>_fs.default.existsSync(defaultPath) ? defaultPath : null)(_path.default.resolve(`./${configs.tailwind}`)); | ||
let processor = await (0, _pluginJs.createProcessor)(args, configPath); | ||
let configPath = args["--config"] ? args["--config"] : (0, _resolveConfigPath.resolveDefaultConfigPath)(); | ||
let processor = await (0, _plugin.createProcessor)(args, configPath); | ||
if (shouldWatch) { | ||
@@ -49,4 +52,7 @@ // Abort the watcher if stdin is closed to avoid zombie processes | ||
} else { | ||
await processor.build(); | ||
await processor.build().catch((e)=>{ | ||
console.error(e); | ||
process.exit(1); | ||
}); | ||
} | ||
} |
@@ -8,24 +8,27 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>createProcessor | ||
get: function() { | ||
return createProcessor; | ||
} | ||
}); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _postcssLoadConfig = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-config")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _postcssloadconfig = /*#__PURE__*/ _interop_require_default(require("postcss-load-config")); | ||
const _lilconfig = require("lilconfig"); | ||
const _plugins = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-config/src/plugins" // Little bit scary, looking at private/internal API | ||
const _plugins = /*#__PURE__*/ _interop_require_default(require("postcss-load-config/src/plugins" // Little bit scary, looking at private/internal API | ||
)); | ||
const _options = /*#__PURE__*/ _interopRequireDefault(require("postcss-load-config/src/options" // Little bit scary, looking at private/internal API | ||
const _options = /*#__PURE__*/ _interop_require_default(require("postcss-load-config/src/options" // Little bit scary, looking at private/internal API | ||
)); | ||
const _processTailwindFeatures = /*#__PURE__*/ _interopRequireDefault(require("../../processTailwindFeatures")); | ||
const _processTailwindFeatures = /*#__PURE__*/ _interop_require_default(require("../../processTailwindFeatures")); | ||
const _deps = require("./deps"); | ||
const _utils = require("./utils"); | ||
const _shared = require("../shared"); | ||
const _resolveConfigJs = /*#__PURE__*/ _interopRequireDefault(require("../../../resolveConfig.js")); | ||
const _getModuleDependenciesJs = /*#__PURE__*/ _interopRequireDefault(require("../../lib/getModuleDependencies.js")); | ||
const _contentJs = require("../../lib/content.js"); | ||
const _watchingJs = require("./watching.js"); | ||
const _fastGlob = /*#__PURE__*/ _interopRequireDefault(require("fast-glob")); | ||
const _findAtConfigPathJs = require("../../lib/findAtConfigPath.js"); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../../util/log")); | ||
function _interopRequireDefault(obj) { | ||
const _sharedState = require("../../lib/sharedState"); | ||
const _resolveConfig = /*#__PURE__*/ _interop_require_default(require("../../../resolveConfig.js")); | ||
const _content = require("../../lib/content.js"); | ||
const _watching = require("./watching.js"); | ||
const _fastglob = /*#__PURE__*/ _interop_require_default(require("fast-glob")); | ||
const _findAtConfigPath = require("../../lib/findAtConfigPath.js"); | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../../util/log")); | ||
const _loadconfig = require("../../lib/load-config"); | ||
const _getModuleDependencies = /*#__PURE__*/ _interop_require_default(require("../../lib/getModuleDependencies")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -58,3 +61,3 @@ default: obj | ||
}; | ||
})() : await (0, _postcssLoadConfig.default)(); | ||
})() : await (0, _postcssloadconfig.default)(); | ||
let configPlugins = config.plugins; | ||
@@ -114,3 +117,3 @@ let configPluginTailwindIdx = configPlugins.findIndex((plugin)=>{ | ||
/** @type {{content: string, extension: string}[]} */ changedContent: [], | ||
configDependencies: new Set(), | ||
/** @type {ReturnType<typeof load> | null} */ configBag: null, | ||
contextDependencies: new Set(), | ||
@@ -120,3 +123,3 @@ /** @type {import('../../lib/content.js').ContentPath[]} */ contentPaths: [], | ||
var _this_context; | ||
this.contentPaths = (0, _contentJs.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig); | ||
this.contentPaths = (0, _content.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig); | ||
}, | ||
@@ -134,7 +137,17 @@ get config () { | ||
if (this.watcher && configPath) { | ||
this.refreshConfigDependencies(configPath); | ||
this.refreshConfigDependencies(); | ||
} | ||
let config = configPath ? require(configPath) : {}; | ||
let config = (0, _loadconfig.loadConfig)(configPath); | ||
let dependencies = (0, _getModuleDependencies.default)(configPath); | ||
this.configBag = { | ||
config, | ||
dependencies, | ||
dispose () { | ||
for (let file of dependencies){ | ||
delete require.cache[require.resolve(file)]; | ||
} | ||
} | ||
}; | ||
// @ts-ignore | ||
config = (0, _resolveConfigJs.default)(config, { | ||
this.configBag.config = (0, _resolveConfig.default)(this.configBag.config, { | ||
content: { | ||
@@ -146,18 +159,11 @@ files: [] | ||
if ((content === null || content === void 0 ? void 0 : content.length) > 0) { | ||
config.content.files = content; | ||
this.configBag.config.content.files = content; | ||
} | ||
return config; | ||
return this.configBag.config; | ||
}, | ||
refreshConfigDependencies (configPath) { | ||
_shared.env.DEBUG && console.time("Module dependencies"); | ||
for (let file of this.configDependencies){ | ||
delete require.cache[require.resolve(file)]; | ||
} | ||
if (configPath) { | ||
let deps = (0, _getModuleDependenciesJs.default)(configPath).map(({ file })=>file); | ||
for (let dependency of deps){ | ||
this.configDependencies.add(dependency); | ||
} | ||
} | ||
_shared.env.DEBUG && console.timeEnd("Module dependencies"); | ||
refreshConfigDependencies () { | ||
var _this_configBag; | ||
_sharedState.env.DEBUG && console.time("Module dependencies"); | ||
(_this_configBag = this.configBag) === null || _this_configBag === void 0 ? void 0 : _this_configBag.dispose(); | ||
_sharedState.env.DEBUG && console.timeEnd("Module dependencies"); | ||
}, | ||
@@ -168,15 +174,10 @@ readContentPaths () { | ||
// TODO: When we make the postcss plugin async-capable this can become async | ||
let files = _fastGlob.default.sync(this.contentPatterns.all); | ||
let files = _fastglob.default.sync(this.contentPatterns.all); | ||
let checkBroadPattern = (0, _content.createBroadPatternCheck)(this.contentPatterns.all); | ||
for (let file of files){ | ||
if (_shared.env.OXIDE) { | ||
content.push({ | ||
file, | ||
extension: _path.default.extname(file).slice(1) | ||
}); | ||
} else { | ||
content.push({ | ||
content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"), | ||
extension: _path.default.extname(file).slice(1) | ||
}); | ||
} | ||
checkBroadPattern(file); | ||
content.push({ | ||
content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"), | ||
extension: _path.default.extname(file).slice(1) | ||
}); | ||
} | ||
@@ -196,2 +197,6 @@ // Resolve raw content in the tailwind config | ||
getContext ({ createContext , cliConfigPath , root , result , content }) { | ||
_sharedState.env.DEBUG && console.time("Searching for config"); | ||
var _findAtConfigPath1; | ||
let configPath = (_findAtConfigPath1 = (0, _findAtConfigPath.findAtConfigPath)(root, result)) !== null && _findAtConfigPath1 !== void 0 ? _findAtConfigPath1 : cliConfigPath; | ||
_sharedState.env.DEBUG && console.timeEnd("Searching for config"); | ||
if (this.context) { | ||
@@ -201,10 +206,6 @@ this.context.changedContent = this.changedContent.splice(0); | ||
} | ||
_shared.env.DEBUG && console.time("Searching for config"); | ||
var _findAtConfigPath; | ||
let configPath = (_findAtConfigPath = (0, _findAtConfigPathJs.findAtConfigPath)(root, result)) !== null && _findAtConfigPath !== void 0 ? _findAtConfigPath : cliConfigPath; | ||
_shared.env.DEBUG && console.timeEnd("Searching for config"); | ||
_shared.env.DEBUG && console.time("Loading config"); | ||
_sharedState.env.DEBUG && console.time("Loading config"); | ||
let config = this.loadConfig(configPath, content); | ||
_shared.env.DEBUG && console.timeEnd("Loading config"); | ||
_shared.env.DEBUG && console.time("Creating context"); | ||
_sharedState.env.DEBUG && console.timeEnd("Loading config"); | ||
_sharedState.env.DEBUG && console.time("Creating context"); | ||
this.context = createContext(config, []); | ||
@@ -214,10 +215,10 @@ Object.assign(this.context, { | ||
}); | ||
_shared.env.DEBUG && console.timeEnd("Creating context"); | ||
_shared.env.DEBUG && console.time("Resolving content paths"); | ||
_sharedState.env.DEBUG && console.timeEnd("Creating context"); | ||
_sharedState.env.DEBUG && console.time("Resolving content paths"); | ||
this.refreshContentPaths(); | ||
_shared.env.DEBUG && console.timeEnd("Resolving content paths"); | ||
_sharedState.env.DEBUG && console.timeEnd("Resolving content paths"); | ||
if (this.watcher) { | ||
_shared.env.DEBUG && console.time("Watch new files"); | ||
_sharedState.env.DEBUG && console.time("Watch new files"); | ||
this.watcher.refreshWatchedFiles(); | ||
_shared.env.DEBUG && console.timeEnd("Watch new files"); | ||
_sharedState.env.DEBUG && console.timeEnd("Watch new files"); | ||
} | ||
@@ -252,5 +253,5 @@ for (let file of this.readContentPaths()){ | ||
postcssPlugin: "tailwindcss", | ||
Once (root, { result }) { | ||
_shared.env.DEBUG && console.time("Compiling CSS"); | ||
(0, _processTailwindFeatures.default)(({ createContext })=>{ | ||
async Once (root, { result }) { | ||
_sharedState.env.DEBUG && console.time("Compiling CSS"); | ||
await (0, _processTailwindFeatures.default)(({ createContext })=>{ | ||
console.error(); | ||
@@ -268,3 +269,3 @@ console.error("Rebuilding..."); | ||
})(root, result); | ||
_shared.env.DEBUG && console.timeEnd("Compiling CSS"); | ||
_sharedState.env.DEBUG && console.timeEnd("Compiling CSS"); | ||
} | ||
@@ -293,3 +294,3 @@ }; | ||
} | ||
// No input file provided, fallback to default atrules | ||
// No input file provided, fallback to default at-rules | ||
return "@tailwind base; @tailwind components; @tailwind utilities"; | ||
@@ -307,3 +308,3 @@ } | ||
} | ||
_shared.env.DEBUG && console.time("Recording PostCSS dependencies"); | ||
_sharedState.env.DEBUG && console.time("Recording PostCSS dependencies"); | ||
for (let message of result.messages){ | ||
@@ -314,7 +315,7 @@ if (message.type === "dependency") { | ||
} | ||
_shared.env.DEBUG && console.timeEnd("Recording PostCSS dependencies"); | ||
_sharedState.env.DEBUG && console.timeEnd("Recording PostCSS dependencies"); | ||
// TODO: This needs to be in a different spot | ||
_shared.env.DEBUG && console.time("Watch new files"); | ||
_sharedState.env.DEBUG && console.time("Watch new files"); | ||
state.watcher.refreshWatchedFiles(); | ||
_shared.env.DEBUG && console.timeEnd("Watch new files"); | ||
_sharedState.env.DEBUG && console.timeEnd("Watch new files"); | ||
return result; | ||
@@ -344,3 +345,7 @@ }).then((result)=>{ | ||
// resilient to future errors. | ||
console.error(err); | ||
if (state.watcher) { | ||
console.error(err); | ||
} else { | ||
return Promise.reject(err); | ||
} | ||
}); | ||
@@ -362,3 +367,3 @@ } | ||
watch: async ()=>{ | ||
state.watcher = (0, _watchingJs.createWatcher)(args, { | ||
state.watcher = (0, _watching.createWatcher)(args, { | ||
state, | ||
@@ -369,3 +374,4 @@ /** | ||
let needsNewContext = changes.some((change)=>{ | ||
return state.configDependencies.has(change.file) || state.contextDependencies.has(change.file); | ||
var _state_configBag; | ||
return ((_state_configBag = state.configBag) === null || _state_configBag === void 0 ? void 0 : _state_configBag.dependencies.has(change.file)) || state.contextDependencies.has(change.file); | ||
}); | ||
@@ -372,0 +378,0 @@ if (needsNewContext) { |
@@ -13,11 +13,21 @@ // @ts-check | ||
_export(exports, { | ||
indentRecursive: ()=>indentRecursive, | ||
formatNodes: ()=>formatNodes, | ||
readFileWithRetries: ()=>readFileWithRetries, | ||
drainStdin: ()=>drainStdin, | ||
outputFile: ()=>outputFile | ||
indentRecursive: function() { | ||
return indentRecursive; | ||
}, | ||
formatNodes: function() { | ||
return formatNodes; | ||
}, | ||
readFileWithRetries: function() { | ||
return readFileWithRetries; | ||
}, | ||
drainStdin: function() { | ||
return drainStdin; | ||
}, | ||
outputFile: function() { | ||
return outputFile; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
function _interopRequireDefault(obj) { | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -24,0 +34,0 @@ default: obj |
@@ -8,11 +8,13 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>createWatcher | ||
get: function() { | ||
return createWatcher; | ||
} | ||
}); | ||
const _chokidar = /*#__PURE__*/ _interopRequireDefault(require("chokidar")); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _micromatch = /*#__PURE__*/ _interopRequireDefault(require("micromatch")); | ||
const _normalizePath = /*#__PURE__*/ _interopRequireDefault(require("normalize-path")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
const _utilsJs = require("./utils.js"); | ||
function _interopRequireDefault(obj) { | ||
const _chokidar = /*#__PURE__*/ _interop_require_default(require("chokidar")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _micromatch = /*#__PURE__*/ _interop_require_default(require("micromatch")); | ||
const _normalizepath = /*#__PURE__*/ _interop_require_default(require("normalize-path")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
const _utils = require("./utils.js"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -68,3 +70,5 @@ default: obj | ||
// Resolve the promise even when the rebuild fails | ||
return rebuild(changes).then(()=>{}, ()=>{}); | ||
return rebuild(changes).then(()=>{}, (e)=>{ | ||
console.error(e.toString()); | ||
}); | ||
} | ||
@@ -114,3 +118,3 @@ /** | ||
watcher.on("unlink", (file)=>{ | ||
file = (0, _normalizePath.default)(file); | ||
file = (0, _normalizepath.default)(file); | ||
// Only re-add the file if it's not covered by a dynamic pattern | ||
@@ -128,3 +132,3 @@ if (!_micromatch.default.some([ | ||
watcher.on("raw", (evt, filePath, meta)=>{ | ||
if (evt !== "rename") { | ||
if (evt !== "rename" || filePath === null) { | ||
return; | ||
@@ -155,3 +159,3 @@ } | ||
// immediately increases the chance that the file is still there | ||
let content = await (0, _utilsJs.readFileWithRetries)(_path.default.resolve(filePath)); | ||
let content = await (0, _utils.readFileWithRetries)(_path.default.resolve(filePath)); | ||
if (content === undefined) { | ||
@@ -179,3 +183,3 @@ return; | ||
watcher.add(Array.from(state.contextDependencies)); | ||
watcher.add(Array.from(state.configDependencies)); | ||
watcher.add(Array.from(state.configBag.dependencies)); | ||
watcher.add(state.contentPatterns.all); | ||
@@ -182,0 +186,0 @@ } |
@@ -8,6 +8,8 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>help | ||
get: function() { | ||
return help; | ||
} | ||
}); | ||
const _packageJson = /*#__PURE__*/ _interopRequireDefault(require("../../../package.json")); | ||
function _interopRequireDefault(obj) { | ||
const _packagejson = /*#__PURE__*/ _interop_require_default(require("../../../package.json")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -21,3 +23,3 @@ default: obj | ||
console.log(); | ||
console.log(`${_packageJson.default.name} v${_packageJson.default.version}`); | ||
console.log(`${_packagejson.default.name} v${_packagejson.default.version}`); | ||
// Render message | ||
@@ -24,0 +26,0 @@ if (message) { |
@@ -6,9 +6,9 @@ #!/usr/bin/env node | ||
}); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
const _arg = /*#__PURE__*/ _interopRequireDefault(require("arg")); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
const _arg = /*#__PURE__*/ _interop_require_default(require("arg")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _build = require("./build"); | ||
const _help = require("./help"); | ||
const _init = require("./init"); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -18,19 +18,2 @@ default: obj | ||
} | ||
function isESM() { | ||
const pkgPath = _path.default.resolve("./package.json"); | ||
try { | ||
let pkg = JSON.parse(_fs.default.readFileSync(pkgPath, "utf8")); | ||
return pkg.type && pkg.type === "module"; | ||
} catch (err) { | ||
return false; | ||
} | ||
} | ||
let configs = isESM() ? { | ||
tailwind: "tailwind.config.cjs", | ||
postcss: "postcss.config.cjs" | ||
} : { | ||
tailwind: "tailwind.config.js", | ||
postcss: "postcss.config.js" | ||
}; | ||
// --- | ||
function oneOf(...options) { | ||
@@ -53,10 +36,18 @@ return Object.assign((value = true)=>{ | ||
args: { | ||
"--full": { | ||
"--esm": { | ||
type: Boolean, | ||
description: `Initialize a full \`${configs.tailwind}\` file` | ||
description: `Initialize configuration file as ESM` | ||
}, | ||
"--ts": { | ||
type: Boolean, | ||
description: `Initialize configuration file as TypeScript` | ||
}, | ||
"--postcss": { | ||
type: Boolean, | ||
description: `Initialize a \`${configs.postcss}\` file` | ||
description: `Initialize a \`postcss.config.js\` file` | ||
}, | ||
"--full": { | ||
type: Boolean, | ||
description: `Include the default values for all options in the generated configuration file` | ||
}, | ||
"-f": "--full", | ||
@@ -242,2 +233,2 @@ "-p": "--postcss" | ||
} | ||
run(args, configs); | ||
run(args); |
@@ -8,7 +8,9 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>init | ||
get: function() { | ||
return init; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
function _interopRequireDefault(obj) { | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -18,12 +20,27 @@ default: obj | ||
} | ||
function init(args, configs) { | ||
function isESM() { | ||
const pkgPath = _path.default.resolve("./package.json"); | ||
try { | ||
let pkg = JSON.parse(_fs.default.readFileSync(pkgPath, "utf8")); | ||
return pkg.type && pkg.type === "module"; | ||
} catch (err) { | ||
return false; | ||
} | ||
} | ||
function init(args) { | ||
let messages = []; | ||
let isProjectESM = args["--ts"] || args["--esm"] || isESM(); | ||
let syntax = args["--ts"] ? "ts" : isProjectESM ? "js" : "cjs"; | ||
let extension = args["--ts"] ? "ts" : "js"; | ||
var _args___; | ||
let tailwindConfigLocation = _path.default.resolve((_args___ = args["_"][1]) !== null && _args___ !== void 0 ? _args___ : `./${configs.tailwind}`); | ||
let tailwindConfigLocation = _path.default.resolve((_args___ = args["_"][1]) !== null && _args___ !== void 0 ? _args___ : `./tailwind.config.${extension}`); | ||
if (_fs.default.existsSync(tailwindConfigLocation)) { | ||
messages.push(`${_path.default.basename(tailwindConfigLocation)} already exists.`); | ||
} else { | ||
let stubFile = _fs.default.readFileSync(args["--full"] ? _path.default.resolve(__dirname, "../../../stubs/defaultConfig.stub.js") : _path.default.resolve(__dirname, "../../../stubs/simpleConfig.stub.js"), "utf8"); | ||
let stubContentsFile = _fs.default.readFileSync(args["--full"] ? _path.default.resolve(__dirname, "../../../stubs/config.full.js") : _path.default.resolve(__dirname, "../../../stubs/config.simple.js"), "utf8"); | ||
let stubFile = _fs.default.readFileSync(_path.default.resolve(__dirname, `../../../stubs/tailwind.config.${syntax}`), "utf8"); | ||
// Change colors import | ||
stubFile = stubFile.replace("../colors", "tailwindcss/colors"); | ||
stubContentsFile = stubContentsFile.replace("../colors", "tailwindcss/colors"); | ||
// Replace contents of {ts,js,cjs} file with the stub {simple,full}. | ||
stubFile = stubFile.replace("__CONFIG__", stubContentsFile.replace("module.exports =", "").trim()).trim() + "\n\n"; | ||
_fs.default.writeFileSync(tailwindConfigLocation, stubFile, "utf8"); | ||
@@ -33,8 +50,8 @@ messages.push(`Created Tailwind CSS config file: ${_path.default.basename(tailwindConfigLocation)}`); | ||
if (args["--postcss"]) { | ||
let postcssConfigLocation = _path.default.resolve(`./${configs.postcss}`); | ||
let postcssConfigLocation = _path.default.resolve("./postcss.config.js"); | ||
if (_fs.default.existsSync(postcssConfigLocation)) { | ||
messages.push(`${_path.default.basename(postcssConfigLocation)} already exists.`); | ||
} else { | ||
let stubFile1 = _fs.default.readFileSync(_path.default.resolve(__dirname, "../../../stubs/defaultPostCssConfig.stub.js"), "utf8"); | ||
_fs.default.writeFileSync(postcssConfigLocation, stubFile1, "utf8"); | ||
let stubFile = _fs.default.readFileSync(isProjectESM ? _path.default.resolve(__dirname, "../../../stubs/postcss.config.js") : _path.default.resolve(__dirname, "../../../stubs/postcss.config.cjs"), "utf8"); | ||
_fs.default.writeFileSync(postcssConfigLocation, stubFile, "utf8"); | ||
messages.push(`Created PostCSS config file: ${_path.default.basename(postcssConfigLocation)}`); | ||
@@ -41,0 +58,0 @@ } |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
@@ -31,4 +33,6 @@ const _default = [ | ||
"boxSizing", | ||
"lineClamp", | ||
"display", | ||
"aspectRatio", | ||
"size", | ||
"height", | ||
@@ -45,2 +49,3 @@ "maxHeight", | ||
"tableLayout", | ||
"captionSide", | ||
"borderCollapse", | ||
@@ -66,2 +71,3 @@ "borderSpacing", | ||
"listStyleType", | ||
"listStyleImage", | ||
"appearance", | ||
@@ -98,3 +104,5 @@ "columns", | ||
"textOverflow", | ||
"hyphens", | ||
"whitespace", | ||
"textWrap", | ||
"wordBreak", | ||
@@ -185,3 +193,5 @@ "borderRadius", | ||
"willChange", | ||
"content" | ||
"contain", | ||
"content", | ||
"forcedColorAdjust" | ||
]; |
@@ -12,9 +12,15 @@ "use strict"; | ||
_export(exports, { | ||
flagEnabled: ()=>flagEnabled, | ||
issueFlagNotices: ()=>issueFlagNotices, | ||
default: ()=>_default | ||
flagEnabled: function() { | ||
return flagEnabled; | ||
}, | ||
issueFlagNotices: function() { | ||
return issueFlagNotices; | ||
}, | ||
default: function() { | ||
return _default; | ||
} | ||
}); | ||
const _picocolors = /*#__PURE__*/ _interopRequireDefault(require("picocolors")); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("./util/log")); | ||
function _interopRequireDefault(obj) { | ||
const _picocolors = /*#__PURE__*/ _interop_require_default(require("picocolors")); | ||
const _log = /*#__PURE__*/ _interop_require_default(require("./util/log")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -26,3 +32,5 @@ default: obj | ||
optimizeUniversalDefaults: false, | ||
generalizedModifiers: true | ||
generalizedModifiers: true, | ||
disableColorOpacityUtilitiesByDefault: false, | ||
relativeContentPathsByDefault: false | ||
}; | ||
@@ -29,0 +37,0 @@ let featureFlags = { |
"use strict"; | ||
if (process.env.OXIDE) { | ||
module.exports = require("./oxide/postcss-plugin"); | ||
} else { | ||
module.exports = require("./plugin"); | ||
} | ||
module.exports = require("./plugin"); |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>hasContentChanged | ||
get: function() { | ||
return hasContentChanged; | ||
} | ||
}); | ||
const _crypto = /*#__PURE__*/ _interopRequireDefault(require("crypto")); | ||
const _sharedState = /*#__PURE__*/ _interopRequireWildcard(require("./sharedState")); | ||
function _interopRequireDefault(obj) { | ||
const _crypto = /*#__PURE__*/ _interop_require_default(require("crypto")); | ||
const _sharedState = /*#__PURE__*/ _interop_require_wildcard(require("./sharedState")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -25,3 +27,3 @@ default: obj | ||
} | ||
function _interopRequireWildcard(obj, nodeInterop) { | ||
function _interop_require_wildcard(obj, nodeInterop) { | ||
if (!nodeInterop && obj && obj.__esModule) { | ||
@@ -28,0 +30,0 @@ return obj; |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>collapseAdjacentRules | ||
get: function() { | ||
return collapseAdjacentRules; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ let comparisonMap = { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>collapseDuplicateDeclarations | ||
get: function() { | ||
return collapseDuplicateDeclarations; | ||
} | ||
}); | ||
@@ -55,4 +57,4 @@ function collapseDuplicateDeclarations() { | ||
let byUnit = new Map(); | ||
for (let decl1 of declarations){ | ||
let unit = resolveUnit(decl1.value); | ||
for (let decl of declarations){ | ||
let unit = resolveUnit(decl.value); | ||
if (unit === null) { | ||
@@ -64,9 +66,9 @@ continue; | ||
} | ||
byUnit.get(unit).add(decl1); | ||
byUnit.get(unit).add(decl); | ||
} | ||
for (let declarations1 of byUnit.values()){ | ||
for (let declarations of byUnit.values()){ | ||
// Get all but the last one | ||
let removableDeclarations = Array.from(declarations1).slice(0, -1); | ||
for (let decl2 of removableDeclarations){ | ||
decl2.remove(); | ||
let removableDeclarations = Array.from(declarations).slice(0, -1); | ||
for (let decl of removableDeclarations){ | ||
decl.remove(); | ||
} | ||
@@ -73,0 +75,0 @@ } |
@@ -13,13 +13,22 @@ // @ts-check | ||
_export(exports, { | ||
parseCandidateFiles: ()=>parseCandidateFiles, | ||
resolvedChangedContent: ()=>resolvedChangedContent | ||
parseCandidateFiles: function() { | ||
return parseCandidateFiles; | ||
}, | ||
resolvedChangedContent: function() { | ||
return resolvedChangedContent; | ||
}, | ||
createBroadPatternCheck: function() { | ||
return createBroadPatternCheck; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
const _isGlob = /*#__PURE__*/ _interopRequireDefault(require("is-glob")); | ||
const _fastGlob = /*#__PURE__*/ _interopRequireDefault(require("fast-glob")); | ||
const _normalizePath = /*#__PURE__*/ _interopRequireDefault(require("normalize-path")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
const _isglob = /*#__PURE__*/ _interop_require_default(require("is-glob")); | ||
const _fastglob = /*#__PURE__*/ _interop_require_default(require("fast-glob")); | ||
const _normalizepath = /*#__PURE__*/ _interop_require_default(require("normalize-path")); | ||
const _parseGlob = require("../util/parseGlob"); | ||
const _sharedState = require("./sharedState"); | ||
function _interopRequireDefault(obj) { | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
const _micromatch = /*#__PURE__*/ _interop_require_default(require("micromatch")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -33,5 +42,5 @@ default: obj | ||
files = files.filter((filePath)=>typeof filePath === "string"); | ||
files = files.map(_normalizePath.default); | ||
files = files.map(_normalizepath.default); | ||
// Split into included and excluded globs | ||
let tasks = _fastGlob.default.generateTasks(files); | ||
let tasks = _fastglob.default.generateTasks(files); | ||
/** @type {ContentPath[]} */ let included = []; | ||
@@ -68,3 +77,3 @@ /** @type {ContentPath[]} */ let excluded = []; | ||
}; | ||
if ((0, _isGlob.default)(filePath)) { | ||
if ((0, _isglob.default)(filePath)) { | ||
Object.assign(contentPath, (0, _parseGlob.parseGlob)(filePath)); | ||
@@ -83,6 +92,6 @@ } | ||
// a package which can't handle mixed directory separators | ||
let base = (0, _normalizePath.default)(contentPath.base); | ||
let base = (0, _normalizepath.default)(contentPath.base); | ||
// If the user's file path contains any special characters (like parens) for instance fast-glob | ||
// is like "OOOH SHINY" and treats them as such. So we have to escape the base path to fix this | ||
base = _fastGlob.default.escapePath(base); | ||
base = _fastglob.default.escapePath(base); | ||
contentPath.pattern = contentPath.glob ? `${base}/${contentPath.glob}` : base; | ||
@@ -155,2 +164,51 @@ contentPath.pattern = contentPath.ignore ? `!${contentPath.pattern}` : contentPath.pattern; | ||
} | ||
const LARGE_DIRECTORIES = [ | ||
"node_modules", | ||
"vendor" | ||
]; | ||
// Ensures that `node_modules` has to match as-is, otherwise `mynode_modules` | ||
// would match as well, but that is not a known large directory. | ||
const LARGE_DIRECTORIES_REGEX = new RegExp(`(${LARGE_DIRECTORIES.map((dir)=>String.raw`\b${dir}\b`).join("|")})`); | ||
function createBroadPatternCheck(paths) { | ||
// Detect whether a glob pattern might be too broad. This means that it: | ||
// - Includes `**` | ||
// - Does not include any of the known large directories (e.g.: node_modules) | ||
let maybeBroadPattern = paths.some((path)=>path.includes("**") && !LARGE_DIRECTORIES_REGEX.test(path)); | ||
// Didn't detect any potentially broad patterns, so we can skip further | ||
// checks. | ||
if (!maybeBroadPattern) { | ||
return ()=>{}; | ||
} | ||
// All globs that explicitly contain any of the known large directories (e.g.: | ||
// node_modules). | ||
let explicitGlobs = paths.filter((path)=>LARGE_DIRECTORIES_REGEX.test(path)); | ||
// Keep track of whether we already warned about the broad pattern issue or | ||
// not. The `log.warn` function already does something similar where we only | ||
// output the log once. However, with this we can also skip the other checks | ||
// when we already warned about the broad pattern. | ||
let warned = false; | ||
/** | ||
* @param {string} file | ||
*/ return (file)=>{ | ||
if (warned) return; // Already warned about the broad pattern | ||
if (_micromatch.default.isMatch(file, explicitGlobs)) return; // Explicitly included, so we can skip further checks | ||
// When a broad pattern is used, we have to double check that the file was | ||
// not explicitly included in the globs. | ||
let matchingGlob = paths.find((path)=>_micromatch.default.isMatch(file, path)); | ||
if (!matchingGlob) return; // This should never happen | ||
// Create relative paths to make the output a bit more readable. | ||
let relativeMatchingGlob = _path.default.relative(process.cwd(), matchingGlob); | ||
if (relativeMatchingGlob[0] !== ".") relativeMatchingGlob = `./${relativeMatchingGlob}`; | ||
let largeDirectory = LARGE_DIRECTORIES.find((directory)=>file.includes(directory)); | ||
if (largeDirectory) { | ||
warned = true; | ||
_log.default.warn("broad-content-glob-pattern", [ | ||
`Your \`content\` configuration includes a pattern which looks like it's accidentally matching all of \`${largeDirectory}\` and can cause serious performance issues.`, | ||
`Pattern: \`${relativeMatchingGlob}\``, | ||
`See our documentation for recommendations:`, | ||
"https://tailwindcss.com/docs/content-configuration#pattern-recommendations" | ||
]); | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -164,8 +222,10 @@ * | ||
let mTimesToCommit = new Map(); | ||
let checkBroadPattern = createBroadPatternCheck(paths); | ||
let changedFiles = new Set(); | ||
_sharedState.env.DEBUG && console.time("Finding changed files"); | ||
let files = _fastGlob.default.sync(paths, { | ||
let files = _fastglob.default.sync(paths, { | ||
absolute: true | ||
}); | ||
for (let file of files){ | ||
checkBroadPattern(file); | ||
let prevModified = fileModifiedMap.get(file) || -Infinity; | ||
@@ -172,0 +232,0 @@ let modified = _fs.default.statSync(file).mtimeMs; |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>defaultExtractor | ||
get: function() { | ||
return defaultExtractor; | ||
} | ||
}); | ||
const _featureFlags = require("../featureFlags"); | ||
const _regex = /*#__PURE__*/ _interopRequireWildcard(require("./regex")); | ||
const _regex = /*#__PURE__*/ _interop_require_wildcard(require("./regex")); | ||
const _splitAtTopLevelOnly = require("../util/splitAtTopLevelOnly"); | ||
function _getRequireWildcardCache(nodeInterop) { | ||
@@ -20,3 +22,3 @@ if (typeof WeakMap !== "function") return null; | ||
} | ||
function _interopRequireWildcard(obj, nodeInterop) { | ||
function _interop_require_wildcard(obj, nodeInterop) { | ||
if (!nodeInterop && obj && obj.__esModule) { | ||
@@ -60,8 +62,28 @@ return obj; | ||
var _content_match; | ||
results = [ | ||
...results, | ||
...(_content_match = content.match(pattern)) !== null && _content_match !== void 0 ? _content_match : [] | ||
]; | ||
for (let result of (_content_match = content.match(pattern)) !== null && _content_match !== void 0 ? _content_match : []){ | ||
results.push(clipAtBalancedParens(result)); | ||
} | ||
} | ||
return results.filter((v)=>v !== undefined).map(clipAtBalancedParens); | ||
// Extract any subclasses from languages like Slim and Pug, eg: | ||
// div.flex.px-5.underline | ||
for (let result of results.slice()){ | ||
let segments = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(result, "."); | ||
for(let idx = 0; idx < segments.length; idx++){ | ||
let segment = segments[idx]; | ||
if (idx >= segments.length - 1) { | ||
results.push(segment); | ||
continue; | ||
} | ||
// If the next segment is a number, discard both, for example seeing | ||
// `px-1` and `5` means the real candidate was `px-1.5` which is already | ||
// captured. | ||
let next = Number(segments[idx + 1]); | ||
if (isNaN(next)) { | ||
results.push(segment); | ||
} else { | ||
idx++; | ||
} | ||
} | ||
} | ||
return results; | ||
}; | ||
@@ -71,3 +93,2 @@ } | ||
let separator = context.tailwindConfig.separator; | ||
let variantGroupingEnabled = (0, _featureFlags.flagEnabled)(context.tailwindConfig, "variantGrouping"); | ||
let prefix = context.tailwindConfig.prefix !== "" ? _regex.optional(_regex.pattern([ | ||
@@ -84,7 +105,11 @@ /-?/, | ||
// while fixing a problem with the regex matching too much | ||
/\[[^\s:'"`]+:[^\s]+?\[[^\s]+?\][^\s]+?\]/, | ||
/\[[^\s:'"`\]]+:[^\s]+?\[[^\s]+\][^\s]+?\]/, | ||
// Utilities | ||
_regex.pattern([ | ||
// Utility Name / Group Name | ||
/-?(?:\w+)/, | ||
_regex.any([ | ||
/-?(?:\w+)/, | ||
// This is here to make sure @container supports everything that other utilities do | ||
/@(?:\w+)/ | ||
]), | ||
// Normal/Arbitrary values | ||
@@ -94,3 +119,8 @@ _regex.optional(_regex.any([ | ||
// Arbitrary values | ||
/-(?:\w+-)*\[[^\s:]+\]/, | ||
_regex.any([ | ||
/-(?:\w+-)*\['[^\s]+'\]/, | ||
/-(?:\w+-)*\["[^\s]+"\]/, | ||
/-(?:\w+-)*\[`[^\s]+`\]/, | ||
/-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s:\[\]]+\]/ | ||
]), | ||
// Not immediately followed by an `{[(` | ||
@@ -103,3 +133,8 @@ /(?![{([]])/, | ||
// Arbitrary values | ||
/-(?:\w+-)*\[[^\s]+\]/, | ||
_regex.any([ | ||
/-(?:\w+-)*\['[^\s]+'\]/, | ||
/-(?:\w+-)*\["[^\s]+"\]/, | ||
/-(?:\w+-)*\[`[^\s]+`\]/, | ||
/-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s\[\]]+\]/ | ||
]), | ||
// Not immediately followed by an `{[(` | ||
@@ -123,3 +158,8 @@ /(?![{([]])/, | ||
]), | ||
// With variant modifier (e.g.: group-[..]/modifier) | ||
_regex.pattern([ | ||
/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]\/[\w_-]+/, | ||
separator | ||
]), | ||
_regex.pattern([ | ||
/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/, | ||
@@ -135,3 +175,8 @@ separator | ||
_regex.any([ | ||
// With variant modifier (e.g.: group-[..]/modifier) | ||
_regex.pattern([ | ||
/([^\s"'`\[\\]+-)?\[[^\s`]+\]\/[\w_-]+/, | ||
separator | ||
]), | ||
_regex.pattern([ | ||
/([^\s"'`\[\\]+-)?\[[^\s`]+\]/, | ||
@@ -155,20 +200,7 @@ separator | ||
prefix, | ||
variantGroupingEnabled ? _regex.any([ | ||
// Or any of those things but grouped separated by commas | ||
_regex.pattern([ | ||
/\(/, | ||
utility, | ||
_regex.zeroOrMore([ | ||
/,/, | ||
utility | ||
]), | ||
/\)/ | ||
]), | ||
// Arbitrary properties, constrained utilities, arbitrary values, etc… | ||
utility | ||
]) : utility | ||
utility | ||
]); | ||
} | ||
// 5. Inner matches | ||
yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g; | ||
yield /[^<>"'`\s.(){}[\]#=%$][^<>"'`\s(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g; | ||
} | ||
@@ -175,0 +207,0 @@ // We want to capture any "special" characters |
@@ -7,15 +7,17 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _dlv = /*#__PURE__*/ _interopRequireDefault(require("dlv")); | ||
const _didyoumean = /*#__PURE__*/ _interopRequireDefault(require("didyoumean")); | ||
const _transformThemeValue = /*#__PURE__*/ _interopRequireDefault(require("../util/transformThemeValue")); | ||
const _postcssValueParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-value-parser")); | ||
const _dlv = /*#__PURE__*/ _interop_require_default(require("dlv")); | ||
const _didyoumean = /*#__PURE__*/ _interop_require_default(require("didyoumean")); | ||
const _transformThemeValue = /*#__PURE__*/ _interop_require_default(require("../util/transformThemeValue")); | ||
const _index = /*#__PURE__*/ _interop_require_default(require("../value-parser/index")); | ||
const _normalizeScreens = require("../util/normalizeScreens"); | ||
const _buildMediaQuery = /*#__PURE__*/ _interopRequireDefault(require("../util/buildMediaQuery")); | ||
const _buildMediaQuery = /*#__PURE__*/ _interop_require_default(require("../util/buildMediaQuery")); | ||
const _toPath = require("../util/toPath"); | ||
const _withAlphaVariable = require("../util/withAlphaVariable"); | ||
const _pluginUtils = require("../util/pluginUtils"); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../util/log")); | ||
function _interopRequireDefault(obj) { | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -90,12 +92,12 @@ default: obj | ||
if (!(typeof value === "string" || typeof value === "number" || typeof value === "function" || value instanceof String || value instanceof Number || Array.isArray(value))) { | ||
let error1 = `'${pathString}' was found but does not resolve to a string.`; | ||
let error = `'${pathString}' was found but does not resolve to a string.`; | ||
if (isObject(value)) { | ||
let validKeys1 = Object.keys(value).filter((key)=>validatePath(config, [ | ||
let validKeys = Object.keys(value).filter((key)=>validatePath(config, [ | ||
...pathSegments, | ||
key | ||
]).isValid); | ||
if (validKeys1.length) { | ||
error1 += ` Did you mean something like '${pathToString([ | ||
if (validKeys.length) { | ||
error += ` Did you mean something like '${pathToString([ | ||
...pathSegments, | ||
validKeys1[0] | ||
validKeys[0] | ||
])}'?`; | ||
@@ -106,3 +108,3 @@ } | ||
isValid: false, | ||
error: error1 | ||
error | ||
}; | ||
@@ -125,3 +127,3 @@ } | ||
} else { | ||
args[args.length - 1] += _postcssValueParser.default.stringify(vNode); | ||
args[args.length - 1] += _index.default.stringify(vNode); | ||
} | ||
@@ -140,3 +142,5 @@ } | ||
function resolveFunctions(node, input, functions) { | ||
return (0, _postcssValueParser.default)(input).walk((vNode)=>{ | ||
let hasAnyFn = Object.keys(functions).some((fn)=>input.includes(`${fn}(`)); | ||
if (!hasAnyFn) return input; | ||
return (0, _index.default)(input).walk((vNode)=>{ | ||
resolveVNode(node, vNode, functions); | ||
@@ -143,0 +147,0 @@ }).toString(); |
@@ -7,9 +7,13 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>expandApplyAtRules | ||
get: function() { | ||
return expandApplyAtRules; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
const _generateRules = require("./generateRules"); | ||
const _escapeClassName = /*#__PURE__*/ _interopRequireDefault(require("../util/escapeClassName")); | ||
function _interopRequireDefault(obj) { | ||
const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("../util/escapeClassName")); | ||
const _applyImportantSelector = require("../util/applyImportantSelector"); | ||
const _pseudoElements = require("../util/pseudoElements"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -27,3 +31,3 @@ default: obj | ||
container.walkRules((rule)=>{ | ||
(0, _postcssSelectorParser.default)((selectors)=>{ | ||
(0, _postcssselectorparser.default)((selectors)=>{ | ||
selectors.walkClasses((classSelector)=>{ | ||
@@ -45,3 +49,3 @@ let parentSelector = classSelector.parent.toString(); | ||
} | ||
let selectorExtractor = (0, _postcssSelectorParser.default)(); | ||
let selectorExtractor = (0, _postcssselectorparser.default)(); | ||
/** | ||
@@ -315,7 +319,7 @@ * @param {string} ruleSelectors | ||
// This happens when replacing `.bar` in `.foo.bar` with a tag like `section` | ||
for (let sel1 of replaced){ | ||
for (let sel of replaced){ | ||
let groups = [ | ||
[] | ||
]; | ||
for (let node of sel1.nodes){ | ||
for (let node of sel.nodes){ | ||
if (node.type === "combinator") { | ||
@@ -329,3 +333,3 @@ groups.push(node); | ||
} | ||
sel1.nodes = []; | ||
sel.nodes = []; | ||
for (let group of groups){ | ||
@@ -346,3 +350,3 @@ if (Array.isArray(group)) { | ||
} | ||
sel1.nodes = sel1.nodes.concat(group); | ||
sel.nodes = sel.nodes.concat(group); | ||
} | ||
@@ -365,11 +369,11 @@ } | ||
]); | ||
let [applyCandidates1, important] = extractApplyCandidates(apply.params); | ||
let [applyCandidates, important] = extractApplyCandidates(apply.params); | ||
if (apply.parent.type === "atrule") { | ||
if (apply.parent.name === "screen") { | ||
let screenType = apply.parent.params; | ||
throw apply.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${applyCandidates1.map((c)=>`${screenType}:${c}`).join(" ")} instead.`); | ||
throw apply.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${applyCandidates.map((c)=>`${screenType}:${c}`).join(" ")} instead.`); | ||
} | ||
throw apply.error(`@apply is not supported within nested at-rules like @${apply.parent.name}. You can fix this by un-nesting @${apply.parent.name}.`); | ||
} | ||
for (let applyCandidate of applyCandidates1){ | ||
for (let applyCandidate of applyCandidates){ | ||
if ([ | ||
@@ -386,2 +390,15 @@ prefix(context, "group"), | ||
let rules = applyClassCache.get(applyCandidate); | ||
// Verify that we can apply the class | ||
for (let [, rule] of rules){ | ||
if (rule.type === "atrule") { | ||
continue; | ||
} | ||
rule.walkRules(()=>{ | ||
throw apply.error([ | ||
`The \`${applyCandidate}\` class cannot be used with \`@apply\` because \`@apply\` does not currently support nested CSS.`, | ||
"Rewrite the selector without nesting or configure the `tailwindcss/nesting` plugin:", | ||
"https://tailwindcss.com/docs/using-with-preprocessors#nesting" | ||
].join("\n")); | ||
}); | ||
} | ||
candidates.push([ | ||
@@ -394,12 +411,12 @@ applyCandidate, | ||
} | ||
for (let [parent, [candidates1, atApplySource]] of perParentApplies){ | ||
for (let [parent, [candidates, atApplySource]] of perParentApplies){ | ||
let siblings = []; | ||
for (let [applyCandidate1, important1, rules1] of candidates1){ | ||
for (let [applyCandidate, important, rules] of candidates){ | ||
let potentialApplyCandidates = [ | ||
applyCandidate1, | ||
applyCandidate, | ||
...extractBaseCandidates([ | ||
applyCandidate1 | ||
applyCandidate | ||
], context.tailwindConfig.separator) | ||
]; | ||
for (let [meta, node] of rules1){ | ||
for (let [meta, node] of rules){ | ||
let parentClasses = extractClasses(parent); | ||
@@ -435,5 +452,5 @@ let nodeClasses = extractClasses(node); | ||
if (intersects) { | ||
throw node.error(`You cannot \`@apply\` the \`${applyCandidate1}\` utility here because it creates a circular dependency.`); | ||
throw node.error(`You cannot \`@apply\` the \`${applyCandidate}\` utility here because it creates a circular dependency.`); | ||
} | ||
let root1 = _postcss.default.root({ | ||
let root = _postcss.default.root({ | ||
nodes: [ | ||
@@ -444,3 +461,3 @@ node.clone() | ||
// Make sure every node in the entire tree points back at the @apply rule that generated it | ||
root1.walk((node)=>{ | ||
root.walk((node)=>{ | ||
node.source = atApplySource; | ||
@@ -450,3 +467,3 @@ }); | ||
if (canRewriteSelector) { | ||
root1.walkRules((rule)=>{ | ||
root.walkRules((rule)=>{ | ||
// Let's imagine you have the following structure: | ||
@@ -483,3 +500,3 @@ // | ||
// case it would result in `{}` instead of `.something-unrelated {}` | ||
if (!extractClasses(rule).some((candidate)=>candidate === applyCandidate1)) { | ||
if (!extractClasses(rule).some((candidate)=>candidate === applyCandidate)) { | ||
rule.remove(); | ||
@@ -494,10 +511,20 @@ return; | ||
let parentSelector = isGenerated && importantSelector && parent.selector.indexOf(importantSelector) === 0 ? parent.selector.slice(importantSelector.length) : parent.selector; | ||
rule.selector = replaceSelector(parentSelector, rule.selector, applyCandidate1); | ||
// If the selector becomes empty after replacing the important selector | ||
// This means that it's the same as the parent selector and we don't want to replace it | ||
// Otherwise we'll crash | ||
if (parentSelector === "") { | ||
parentSelector = parent.selector; | ||
} | ||
rule.selector = replaceSelector(parentSelector, rule.selector, applyCandidate); | ||
// And then re-add it if it was removed | ||
if (importantSelector && parentSelector !== parent.selector) { | ||
rule.selector = `${importantSelector} ${rule.selector}`; | ||
rule.selector = (0, _applyImportantSelector.applyImportantSelector)(rule.selector, importantSelector); | ||
} | ||
rule.walkDecls((d)=>{ | ||
d.important = meta.important || important1; | ||
d.important = meta.important || important; | ||
}); | ||
// Move pseudo elements to the end of the selector (if necessary) | ||
let selector = (0, _postcssselectorparser.default)().astSync(rule.selector); | ||
selector.each((sel)=>(0, _pseudoElements.movePseudos)(sel)); | ||
rule.selector = selector.toString(); | ||
}); | ||
@@ -507,3 +534,3 @@ } | ||
// If that was the *only* rule in the parent, then we have nothing add so we skip it | ||
if (!root1.nodes[0]) { | ||
if (!root.nodes[0]) { | ||
continue; | ||
@@ -514,3 +541,3 @@ } | ||
meta.sort, | ||
root1.nodes[0] | ||
root.nodes[0] | ||
]); | ||
@@ -524,9 +551,9 @@ } | ||
} | ||
for (let apply1 of applies){ | ||
for (let apply of applies){ | ||
// If there are left-over declarations, just remove the @apply | ||
if (apply1.parent.nodes.length > 1) { | ||
apply1.remove(); | ||
if (apply.parent.nodes.length > 1) { | ||
apply.remove(); | ||
} else { | ||
// The node is empty, drop the full node | ||
apply1.parent.remove(); | ||
apply.parent.remove(); | ||
} | ||
@@ -533,0 +560,0 @@ } |
@@ -7,13 +7,14 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>expandTailwindAtRules | ||
get: function() { | ||
return expandTailwindAtRules; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _quickLru = /*#__PURE__*/ _interopRequireDefault(require("quick-lru")); | ||
const _sharedState = /*#__PURE__*/ _interopRequireWildcard(require("./sharedState")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _quicklru = /*#__PURE__*/ _interop_require_default(require("@alloc/quick-lru")); | ||
const _sharedState = /*#__PURE__*/ _interop_require_wildcard(require("./sharedState")); | ||
const _generateRules = require("./generateRules"); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../util/log")); | ||
const _cloneNodes = /*#__PURE__*/ _interopRequireDefault(require("../util/cloneNodes")); | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
const _cloneNodes = /*#__PURE__*/ _interop_require_default(require("../util/cloneNodes")); | ||
const _defaultExtractor = require("./defaultExtractor"); | ||
const _oxide = /*#__PURE__*/ _interopRequireDefault(require("@tailwindcss/oxide")); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -31,3 +32,3 @@ default: obj | ||
} | ||
function _interopRequireWildcard(obj, nodeInterop) { | ||
function _interop_require_wildcard(obj, nodeInterop) { | ||
if (!nodeInterop && obj && obj.__esModule) { | ||
@@ -85,3 +86,3 @@ return obj; | ||
if (!extractorCache.has(extractor)) { | ||
extractorCache.set(extractor, new _quickLru.default({ | ||
extractorCache.set(extractor, new _quicklru.default({ | ||
maxSize: 25000 | ||
@@ -103,4 +104,4 @@ })); | ||
let lineMatchesSet = new Set(extractorMatches); | ||
for (let match1 of lineMatchesSet){ | ||
candidates.add(match1); | ||
for (let match of lineMatchesSet){ | ||
candidates.add(match); | ||
} | ||
@@ -130,3 +131,3 @@ extractorCache.get(extractor).set(line, lineMatchesSet); | ||
function expandTailwindAtRules(context) { | ||
return (root)=>{ | ||
return async (root)=>{ | ||
let layerNodes = { | ||
@@ -161,19 +162,21 @@ base: null, | ||
env.DEBUG && console.time("Reading changed files"); | ||
if (env.OXIDE) { | ||
// TODO: Pass through or implement `extractor` | ||
for (let candidate of _oxide.default.parseCandidateStringsFromFiles(context.changedContent)){ | ||
candidates.add(candidate); | ||
} | ||
// for (let { file, content, extension } of context.changedContent) { | ||
// let transformer = getTransformer(context.tailwindConfig, extension) | ||
// let extractor = getExtractor(context, extension) | ||
// getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen) | ||
// } | ||
} else { | ||
for (let { file , content , extension } of context.changedContent){ | ||
let transformer = getTransformer(context.tailwindConfig, extension); | ||
let extractor = getExtractor(context, extension); | ||
content = file ? _fs.default.readFileSync(file, "utf8") : content; | ||
/** @type {[item: {file?: string, content?: string}, meta: {transformer: any, extractor: any}][]} */ let regexParserContent = []; | ||
for (let item of context.changedContent){ | ||
let transformer = getTransformer(context.tailwindConfig, item.extension); | ||
let extractor = getExtractor(context, item.extension); | ||
regexParserContent.push([ | ||
item, | ||
{ | ||
transformer, | ||
extractor | ||
} | ||
]); | ||
} | ||
const BATCH_SIZE = 500; | ||
for(let i = 0; i < regexParserContent.length; i += BATCH_SIZE){ | ||
let batch = regexParserContent.slice(i, i + BATCH_SIZE); | ||
await Promise.all(batch.map(async ([{ file , content }, { transformer , extractor }])=>{ | ||
content = file ? await _fs.default.promises.readFile(file, "utf8") : content; | ||
getClassCandidates(transformer(content), extractor, candidates, seen); | ||
} | ||
})); | ||
} | ||
@@ -185,6 +188,4 @@ env.DEBUG && console.timeEnd("Reading changed files"); | ||
env.DEBUG && console.time("Generate rules"); | ||
// TODO: Sorting is _probably_ slow, but right now it can guarantee the same order. Eventually | ||
// we will be able to get rid of this. | ||
env.DEBUG && console.time("Sorting candidates"); | ||
let sortedCandidates = typeof process !== "undefined" && process.env.JEST_WORKER_ID ? new Set([ | ||
let sortedCandidates = new Set([ | ||
...candidates | ||
@@ -195,3 +196,3 @@ ].sort((a, z)=>{ | ||
return 1; | ||
})) : candidates; | ||
})); | ||
env.DEBUG && console.timeEnd("Sorting candidates"); | ||
@@ -258,2 +259,5 @@ (0, _generateRules.generateRules)(sortedCandidates, context); | ||
} | ||
var _root_source_end; | ||
// TODO: Why is the root node having no source location for `end` possible? | ||
root.source.end = (_root_source_end = root.source.end) !== null && _root_source_end !== void 0 ? _root_source_end : root.source.start; | ||
// If we've got a utility layer and no utilities are generated there's likely something wrong | ||
@@ -260,0 +264,0 @@ const hasUtilityVariants = variantNodes.some((node)=>{ |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>findAtConfigPath | ||
get: function() { | ||
return findAtConfigPath; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
function _interopRequireDefault(obj) { | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -14,0 +16,0 @@ default: obj |
@@ -12,14 +12,20 @@ "use strict"; | ||
_export(exports, { | ||
getClassNameFromSelector: ()=>getClassNameFromSelector, | ||
resolveMatches: ()=>resolveMatches, | ||
generateRules: ()=>generateRules | ||
getClassNameFromSelector: function() { | ||
return getClassNameFromSelector; | ||
}, | ||
resolveMatches: function() { | ||
return resolveMatches; | ||
}, | ||
generateRules: function() { | ||
return generateRules; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _parseObjectStyles = /*#__PURE__*/ _interopRequireDefault(require("../util/parseObjectStyles")); | ||
const _isPlainObject = /*#__PURE__*/ _interopRequireDefault(require("../util/isPlainObject")); | ||
const _prefixSelector = /*#__PURE__*/ _interopRequireDefault(require("../util/prefixSelector")); | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
const _parseObjectStyles = /*#__PURE__*/ _interop_require_default(require("../util/parseObjectStyles")); | ||
const _isPlainObject = /*#__PURE__*/ _interop_require_default(require("../util/isPlainObject")); | ||
const _prefixSelector = /*#__PURE__*/ _interop_require_default(require("../util/prefixSelector")); | ||
const _pluginUtils = require("../util/pluginUtils"); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../util/log")); | ||
const _sharedState = /*#__PURE__*/ _interopRequireWildcard(require("./sharedState")); | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
const _sharedState = /*#__PURE__*/ _interop_require_wildcard(require("./sharedState")); | ||
const _formatVariantSelector = require("../util/formatVariantSelector"); | ||
@@ -29,6 +35,7 @@ const _nameClass = require("../util/nameClass"); | ||
const _setupContextUtils = require("./setupContextUtils"); | ||
const _isSyntacticallyValidPropertyValue = /*#__PURE__*/ _interopRequireDefault(require("../util/isSyntacticallyValidPropertyValue")); | ||
const _splitAtTopLevelOnlyJs = require("../util/splitAtTopLevelOnly.js"); | ||
const _isSyntacticallyValidPropertyValue = /*#__PURE__*/ _interop_require_default(require("../util/isSyntacticallyValidPropertyValue")); | ||
const _splitAtTopLevelOnly = require("../util/splitAtTopLevelOnly.js"); | ||
const _featureFlags = require("../featureFlags"); | ||
function _interopRequireDefault(obj) { | ||
const _applyImportantSelector = require("../util/applyImportantSelector"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -46,3 +53,3 @@ default: obj | ||
} | ||
function _interopRequireWildcard(obj, nodeInterop) { | ||
function _interop_require_wildcard(obj, nodeInterop) { | ||
if (!nodeInterop && obj && obj.__esModule) { | ||
@@ -78,3 +85,3 @@ return obj; | ||
} | ||
let classNameParser = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
let classNameParser = (0, _postcssselectorparser.default)((selectors)=>{ | ||
return selectors.first.filter(({ type })=>type === "class").pop().value; | ||
@@ -162,2 +169,5 @@ }); | ||
let result = []; | ||
function isInKeyframes(rule) { | ||
return rule.parent && rule.parent.type === "atrule" && rule.parent.name === "keyframes"; | ||
} | ||
for (let [meta, rule] of matches){ | ||
@@ -170,8 +180,13 @@ let container = _postcss.default.root({ | ||
container.walkRules((r)=>{ | ||
r.selector = (0, _pluginUtils.updateAllClasses)((0, _pluginUtils.filterSelectorsForClass)(r.selector, classCandidate), (className)=>{ | ||
if (className === classCandidate) { | ||
return `!${className}`; | ||
} | ||
return className; | ||
}); | ||
// Declarations inside keyframes cannot be marked as important | ||
// They will be ignored by the browser | ||
if (isInKeyframes(r)) { | ||
return; | ||
} | ||
let ast = (0, _postcssselectorparser.default)().astSync(r.selector); | ||
// Remove extraneous selectors that do not include the base candidate | ||
ast.each((sel)=>(0, _formatVariantSelector.eliminateIrrelevantSelectors)(sel, classCandidate)); | ||
// Update all instances of the base candidate to include the important marker | ||
(0, _pluginUtils.updateAllClasses)(ast, (className)=>className === classCandidate ? `!${className}` : className); | ||
r.selector = ast.toString(); | ||
r.walkDecls((d)=>d.important = true); | ||
@@ -207,6 +222,12 @@ }); | ||
{ | ||
let match = /(.*)\/(.*)$/g.exec(variant); | ||
if (match && !context.variantMap.has(variant)) { | ||
variant = match[1]; | ||
args.modifier = match[2]; | ||
let [baseVariant, ...modifiers] = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(variant, "/"); | ||
// This is a hack to support variants with `/` in them, like `ar-1/10/20:text-red-500` | ||
// In this case 1/10 is a value but /20 is a modifier | ||
if (modifiers.length > 1) { | ||
baseVariant = baseVariant + "/" + modifiers.slice(0, -1).join("/"); | ||
modifiers = modifiers.slice(-1); | ||
} | ||
if (modifiers.length && !context.variantMap.has(variant)) { | ||
variant = baseVariant; | ||
args.modifier = modifiers[0]; | ||
if (!(0, _featureFlags.flagEnabled)(context.tailwindConfig, "generalizedModifiers")) { | ||
@@ -226,10 +247,10 @@ return []; | ||
// group[:hover] (`-` is missing) | ||
let match1 = /(.)(-?)\[(.*)\]/g.exec(variant); | ||
if (match1) { | ||
let [, char, seperator, value] = match1; | ||
let match = /(.)(-?)\[(.*)\]/g.exec(variant); | ||
if (match) { | ||
let [, char, separator, value] = match; | ||
// @-[200px] case | ||
if (char === "@" && seperator === "-") return []; | ||
if (char === "@" && separator === "-") return []; | ||
// group[:hover] case | ||
if (char !== "@" && seperator === "") return []; | ||
variant = variant.replace(`${seperator}[${value}]`, ""); | ||
if (char !== "@" && separator === "") return []; | ||
variant = variant.replace(`${separator}[${value}]`, ""); | ||
args.value = value; | ||
@@ -240,19 +261,30 @@ } | ||
if (isArbitraryValue(variant) && !context.variantMap.has(variant)) { | ||
let sort = context.offsets.recordVariant(variant); | ||
let selector = (0, _dataTypes.normalize)(variant.slice(1, -1)); | ||
if (!(0, _setupContextUtils.isValidVariantFormatString)(selector)) { | ||
let selectors = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(selector, ","); | ||
// We do not support multiple selectors for arbitrary variants | ||
if (selectors.length > 1) { | ||
return []; | ||
} | ||
let fn = (0, _setupContextUtils.parseVariant)(selector); | ||
let sort = context.offsets.recordVariant(variant); | ||
context.variantMap.set(variant, [ | ||
[ | ||
sort, | ||
fn | ||
] | ||
]); | ||
if (!selectors.every(_setupContextUtils.isValidVariantFormatString)) { | ||
return []; | ||
} | ||
let records = selectors.map((sel, idx)=>[ | ||
context.offsets.applyParallelOffset(sort, idx), | ||
(0, _setupContextUtils.parseVariant)(sel.trim()) | ||
]); | ||
context.variantMap.set(variant, records); | ||
} | ||
if (context.variantMap.has(variant)) { | ||
var _context_variantOptions_get; | ||
let isArbitraryVariant = isArbitraryValue(variant); | ||
var _context_variantOptions_get_INTERNAL_FEATURES; | ||
let internalFeatures = (_context_variantOptions_get_INTERNAL_FEATURES = (_context_variantOptions_get = context.variantOptions.get(variant)) === null || _context_variantOptions_get === void 0 ? void 0 : _context_variantOptions_get[_setupContextUtils.INTERNAL_FEATURES]) !== null && _context_variantOptions_get_INTERNAL_FEATURES !== void 0 ? _context_variantOptions_get_INTERNAL_FEATURES : {}; | ||
let variantFunctionTuples = context.variantMap.get(variant).slice(); | ||
let result = []; | ||
let respectPrefix = (()=>{ | ||
if (isArbitraryVariant) return false; | ||
if (internalFeatures.respectPrefix === false) return false; | ||
return true; | ||
})(); | ||
for (let [meta, rule] of matches){ | ||
@@ -314,3 +346,3 @@ // Don't generate variants for user css | ||
format: selectorFormat, | ||
isArbitraryVariant | ||
respectPrefix | ||
}); | ||
@@ -323,3 +355,3 @@ }, | ||
if (Array.isArray(ruleWithVariant)) { | ||
for (let [idx, variantFunction1] of ruleWithVariant.entries()){ | ||
for (let [idx, variantFunction] of ruleWithVariant.entries()){ | ||
// This is a little bit scary since we are pushing to an array of items that we are | ||
@@ -331,3 +363,3 @@ // currently looping over. However, you can also think of it like a processing queue | ||
context.offsets.applyParallelOffset(variantSort, idx), | ||
variantFunction1, | ||
variantFunction, | ||
// If the clone has been modified we have to pass that back | ||
@@ -343,3 +375,3 @@ // though so each rule can use the modified container | ||
format: ruleWithVariant, | ||
isArbitraryVariant | ||
respectPrefix | ||
}); | ||
@@ -365,3 +397,3 @@ } | ||
// classes, pseudos, ids, ... | ||
let rebuiltBase = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
let rebuiltBase = (0, _postcssselectorparser.default)((selectors)=>{ | ||
selectors.walkClasses((classNode)=>{ | ||
@@ -384,3 +416,3 @@ classNode.value = `${variant}${context.tailwindConfig.separator}${classNode.value}`; | ||
format: modified.replace(rebuiltBase, "&"), | ||
isArbitraryVariant | ||
respectPrefix | ||
}); | ||
@@ -494,7 +526,9 @@ rule.selector = before; | ||
} | ||
let normalized = (0, _dataTypes.normalize)(value); | ||
let normalized = (0, _dataTypes.normalize)(value, { | ||
property | ||
}); | ||
if (!isParsableCssValue(property, normalized)) { | ||
return null; | ||
} | ||
let sort = context.offsets.arbitraryProperty(); | ||
let sort = context.offsets.arbitraryProperty(classCandidate); | ||
return [ | ||
@@ -504,3 +538,6 @@ [ | ||
sort, | ||
layer: "utilities" | ||
layer: "utilities", | ||
options: { | ||
respectImportant: true | ||
} | ||
}, | ||
@@ -560,3 +597,3 @@ ()=>({ | ||
} | ||
return (0, _splitAtTopLevelOnlyJs.splitAtTopLevelOnly)(input, separator); | ||
return (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(input, separator); | ||
} | ||
@@ -575,3 +612,3 @@ function* recordCandidates(matches, classCandidate) { | ||
} | ||
function* resolveMatches(candidate, context, original = candidate) { | ||
function* resolveMatches(candidate, context) { | ||
let separator = context.tailwindConfig.separator; | ||
@@ -584,10 +621,2 @@ let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse(); | ||
} | ||
if ((0, _featureFlags.flagEnabled)(context.tailwindConfig, "variantGrouping")) { | ||
if (classCandidate.startsWith("(") && classCandidate.endsWith(")")) { | ||
let base = variants.slice().reverse().join(separator); | ||
for (let part of (0, _splitAtTopLevelOnlyJs.splitAtTopLevelOnly)(classCandidate.slice(1, -1), ",")){ | ||
yield* resolveMatches(base + separator + part, context, original); | ||
} | ||
} | ||
} | ||
// TODO: Reintroduce this in ways that doesn't break on false positives | ||
@@ -630,5 +659,5 @@ // function sortAgainst(toSort, against) { | ||
} else if (modifier === "DEFAULT" || modifier === "-DEFAULT") { | ||
let ruleSet1 = plugin; | ||
let [rules1, options1] = parseRules(ruleSet1, context.postCssNodeCache); | ||
for (let rule1 of rules1){ | ||
let ruleSet = plugin; | ||
let [rules, options] = parseRules(ruleSet, context.postCssNodeCache); | ||
for (let rule of rules){ | ||
matchesPerPlugin.push([ | ||
@@ -639,6 +668,6 @@ { | ||
...sort.options, | ||
...options1 | ||
...options | ||
} | ||
}, | ||
rule1 | ||
rule | ||
]); | ||
@@ -719,7 +748,7 @@ } | ||
for (let [idx, group] of typesPerPlugin.entries()){ | ||
for (let type1 of group){ | ||
let rules2 = matches[idx].map(([, rule])=>rule).flat().map((rule)=>rule.toString().split("\n").slice(1, -1) // Remove selector and closing '}' | ||
for (let type of group){ | ||
let rules = matches[idx].map(([, rule])=>rule).flat().map((rule)=>rule.toString().split("\n").slice(1, -1) // Remove selector and closing '}' | ||
.map((line)=>line.trim()).map((x)=>` ${x}`) // Re-indent | ||
.join("\n")).join("\n\n"); | ||
messages.push(` Use \`${candidate.replace("[", `[${type1}:`)}\` for \`${rules2.trim()}\``); | ||
messages.push(` Use \`${candidate.replace("[", `[${type}:`)}\` for \`${rules.trim()}\``); | ||
break; | ||
@@ -755,4 +784,3 @@ } | ||
context, | ||
candidate, | ||
original | ||
candidate | ||
}); | ||
@@ -769,3 +797,3 @@ // Skip rules with invalid selectors | ||
} | ||
function applyFinalFormat(match, { context , candidate , original }) { | ||
function applyFinalFormat(match, { context , candidate }) { | ||
if (!match[0].collectedFormats) { | ||
@@ -803,6 +831,13 @@ return match; | ||
try { | ||
rule.selector = (0, _formatVariantSelector.finalizeSelector)(rule.selector, finalFormat, { | ||
candidate: original, | ||
let selector = (0, _formatVariantSelector.finalizeSelector)(rule.selector, finalFormat, { | ||
candidate, | ||
context | ||
}); | ||
// Finalize Selector determined that this candidate is irrelevant | ||
// TODO: This elimination should happen earlier so this never happens | ||
if (selector === null) { | ||
rule.remove(); | ||
return; | ||
} | ||
rule.selector = selector; | ||
} catch { | ||
@@ -818,2 +853,6 @@ // If this selector is invalid we also want to skip it | ||
} | ||
// If all rules have been eliminated we can skip this candidate entirely | ||
if (container.nodes.length === 0) { | ||
return null; | ||
} | ||
match[1] = container.nodes[0]; | ||
@@ -844,3 +883,3 @@ return match; | ||
rule.selectors = rule.selectors.map((selector)=>{ | ||
return `${important} ${selector}`; | ||
return (0, _applyImportantSelector.applyImportantSelector)(selector, important); | ||
}); | ||
@@ -850,3 +889,3 @@ }; | ||
} | ||
function generateRules(candidates, context) { | ||
function generateRules(candidates, context, isSorting = false) { | ||
let allRules = []; | ||
@@ -882,5 +921,7 @@ let strategy = getImportantStrategy(context.tailwindConfig.important); | ||
} | ||
// Note: We have to clone rules during sorting | ||
// so we eliminate some shared mutable state | ||
let newEntry = [ | ||
sort, | ||
rule | ||
isSorting ? rule.clone() : rule | ||
]; | ||
@@ -887,0 +928,0 @@ rules.add(newEntry); |
@@ -7,9 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>getModuleDependencies | ||
get: function() { | ||
return getModuleDependencies; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
const _resolve = /*#__PURE__*/ _interopRequireDefault(require("resolve")); | ||
const _detective = /*#__PURE__*/ _interopRequireDefault(require("detective")); | ||
function _interopRequireDefault(obj) { | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -19,35 +19,83 @@ default: obj | ||
} | ||
function createModule(file) { | ||
const source = _fs.default.readFileSync(file, "utf-8"); | ||
const requires = (0, _detective.default)(source); | ||
return { | ||
file, | ||
requires | ||
}; | ||
let jsExtensions = [ | ||
".js", | ||
".cjs", | ||
".mjs" | ||
]; | ||
// Given the current file `a.ts`, we want to make sure that when importing `b` that we resolve | ||
// `b.ts` before `b.js` | ||
// | ||
// E.g.: | ||
// | ||
// a.ts | ||
// b // .ts | ||
// c // .ts | ||
// a.js | ||
// b // .js or .ts | ||
let jsResolutionOrder = [ | ||
"", | ||
".js", | ||
".cjs", | ||
".mjs", | ||
".ts", | ||
".cts", | ||
".mts", | ||
".jsx", | ||
".tsx" | ||
]; | ||
let tsResolutionOrder = [ | ||
"", | ||
".ts", | ||
".cts", | ||
".mts", | ||
".tsx", | ||
".js", | ||
".cjs", | ||
".mjs", | ||
".jsx" | ||
]; | ||
function resolveWithExtension(file, extensions) { | ||
// Try to find `./a.ts`, `./a.ts`, ... from `./a` | ||
for (let ext of extensions){ | ||
let full = `${file}${ext}`; | ||
if (_fs.default.existsSync(full) && _fs.default.statSync(full).isFile()) { | ||
return full; | ||
} | ||
} | ||
// Try to find `./a/index.js` from `./a` | ||
for (let ext of extensions){ | ||
let full = `${file}/index${ext}`; | ||
if (_fs.default.existsSync(full)) { | ||
return full; | ||
} | ||
} | ||
return null; | ||
} | ||
function getModuleDependencies(entryFile) { | ||
const rootModule = createModule(entryFile); | ||
const modules = [ | ||
rootModule | ||
]; | ||
// Iterate over the modules, even when new | ||
// ones are being added | ||
for (const mdl of modules){ | ||
mdl.requires.filter((dep)=>{ | ||
// Only track local modules, not node_modules | ||
return dep.startsWith("./") || dep.startsWith("../"); | ||
}).forEach((dep)=>{ | ||
try { | ||
const basedir = _path.default.dirname(mdl.file); | ||
const depPath = _resolve.default.sync(dep, { | ||
basedir | ||
}); | ||
const depModule = createModule(depPath); | ||
modules.push(depModule); | ||
} catch (_err) { | ||
// eslint-disable-next-line no-empty | ||
} | ||
}); | ||
function* _getModuleDependencies(filename, base, seen, ext = _path.default.extname(filename)) { | ||
// Try to find the file | ||
let absoluteFile = resolveWithExtension(_path.default.resolve(base, filename), jsExtensions.includes(ext) ? jsResolutionOrder : tsResolutionOrder); | ||
if (absoluteFile === null) return; // File doesn't exist | ||
// Prevent infinite loops when there are circular dependencies | ||
if (seen.has(absoluteFile)) return; // Already seen | ||
seen.add(absoluteFile); | ||
// Mark the file as a dependency | ||
yield absoluteFile; | ||
// Resolve new base for new imports/requires | ||
base = _path.default.dirname(absoluteFile); | ||
ext = _path.default.extname(absoluteFile); | ||
let contents = _fs.default.readFileSync(absoluteFile, "utf-8"); | ||
// Find imports/requires | ||
for (let match of [ | ||
...contents.matchAll(/import[\s\S]*?['"](.{3,}?)['"]/gi), | ||
...contents.matchAll(/import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi), | ||
...contents.matchAll(/require\(['"`](.+)['"`]\)/gi) | ||
]){ | ||
// Bail out if it's not a relative file | ||
if (!match[1].startsWith(".")) continue; | ||
yield* _getModuleDependencies(match[1], base, seen, ext); | ||
} | ||
return modules; | ||
} | ||
function getModuleDependencies(absoluteFilePath) { | ||
if (absoluteFilePath === null) return new Set(); | ||
return new Set(_getModuleDependencies(absoluteFilePath, _path.default.dirname(absoluteFilePath), new Set())); | ||
} |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>normalizeTailwindDirectives | ||
get: function() { | ||
return normalizeTailwindDirectives; | ||
} | ||
}); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../util/log")); | ||
function _interopRequireDefault(obj) { | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -13,0 +15,0 @@ default: obj |
@@ -8,7 +8,9 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>Offsets | ||
get: function() { | ||
return Offsets; | ||
} | ||
}); | ||
const _bigSign = /*#__PURE__*/ _interopRequireDefault(require("../util/bigSign")); | ||
const _remapBitfieldJs = require("./remap-bitfield.js"); | ||
function _interopRequireDefault(obj) { | ||
const _bigSign = /*#__PURE__*/ _interop_require_default(require("../util/bigSign")); | ||
const _remapbitfield = require("./remap-bitfield.js"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -68,2 +70,4 @@ default: obj | ||
index: this.offsets[layer]++, | ||
propertyOffset: 0n, | ||
property: "", | ||
options: [] | ||
@@ -73,7 +77,9 @@ }; | ||
/** | ||
* @param {string} name | ||
* @returns {RuleOffset} | ||
*/ arbitraryProperty() { | ||
*/ arbitraryProperty(name) { | ||
return { | ||
...this.create("utilities"), | ||
arbitrary: 1n | ||
arbitrary: 1n, | ||
property: name | ||
}; | ||
@@ -173,2 +179,7 @@ } | ||
} | ||
// When sorting the `variants` layer, we need to sort based on the parent layer as well within | ||
// this variants layer. | ||
if (a.parentLayer !== b.parentLayer) { | ||
return this.layerPositions[a.parentLayer] - this.layerPositions[b.parentLayer]; | ||
} | ||
// Sort based on the sorting function | ||
@@ -214,2 +225,6 @@ for (let aOptions of a.options){ | ||
} | ||
// Always sort arbitrary properties alphabetically | ||
if (a.propertyOffset !== b.propertyOffset) { | ||
return a.propertyOffset - b.propertyOffset; | ||
} | ||
// Sort utilities, components, etc… in the order they were registered | ||
@@ -256,3 +271,3 @@ return a.index - b.index; | ||
...offset, | ||
variants: (0, _remapBitfieldJs.remapBitfield)(offset.variants, mapping) | ||
variants: (0, _remapbitfield.remapBitfield)(offset.variants, mapping) | ||
}; | ||
@@ -269,4 +284,45 @@ return [ | ||
* @returns {[RuleOffset, T][]} | ||
*/ sortArbitraryProperties(list) { | ||
// Collect all known arbitrary properties | ||
let known = new Set(); | ||
for (let [offset] of list){ | ||
if (offset.arbitrary === 1n) { | ||
known.add(offset.property); | ||
} | ||
} | ||
// No arbitrary properties? Nothing to do. | ||
if (known.size === 0) { | ||
return list; | ||
} | ||
// Sort the properties alphabetically | ||
let properties = Array.from(known).sort(); | ||
// Create a map from the property name to its offset | ||
let offsets = new Map(); | ||
let offset = 1n; | ||
for (let property of properties){ | ||
offsets.set(property, offset++); | ||
} | ||
// Apply the sorted offsets to the list | ||
return list.map((item)=>{ | ||
let [offset, rule] = item; | ||
var _offsets_get; | ||
offset = { | ||
...offset, | ||
propertyOffset: (_offsets_get = offsets.get(offset.property)) !== null && _offsets_get !== void 0 ? _offsets_get : 0n | ||
}; | ||
return [ | ||
offset, | ||
rule | ||
]; | ||
}); | ||
} | ||
/** | ||
* @template T | ||
* @param {[RuleOffset, T][]} list | ||
* @returns {[RuleOffset, T][]} | ||
*/ sort(list) { | ||
// Sort arbitrary variants so they're in alphabetical order | ||
list = this.remapArbitraryVariantOffsets(list); | ||
// Sort arbitrary properties so they're in alphabetical order | ||
list = this.sortArbitraryProperties(list); | ||
return list.sort(([a], [b])=>(0, _bigSign.default)(this.compare(a, b))); | ||
@@ -273,0 +329,0 @@ } |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>expandApplyAtRules | ||
get: function() { | ||
return expandApplyAtRules; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function partitionRules(root) { |
@@ -12,9 +12,23 @@ "use strict"; | ||
_export(exports, { | ||
pattern: ()=>pattern, | ||
withoutCapturing: ()=>withoutCapturing, | ||
any: ()=>any, | ||
optional: ()=>optional, | ||
zeroOrMore: ()=>zeroOrMore, | ||
nestedBrackets: ()=>nestedBrackets, | ||
escape: ()=>escape | ||
pattern: function() { | ||
return pattern; | ||
}, | ||
withoutCapturing: function() { | ||
return withoutCapturing; | ||
}, | ||
any: function() { | ||
return any; | ||
}, | ||
optional: function() { | ||
return optional; | ||
}, | ||
zeroOrMore: function() { | ||
return zeroOrMore; | ||
}, | ||
nestedBrackets: function() { | ||
return nestedBrackets; | ||
}, | ||
escape: function() { | ||
return escape; | ||
} | ||
}); | ||
@@ -21,0 +35,0 @@ const REGEX_SPECIAL = /[\\^$.*+?()[\]{}|]/g; |
@@ -72,3 +72,5 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>remapBitfield | ||
get: function() { | ||
return remapBitfield; | ||
} | ||
}); | ||
@@ -75,0 +77,0 @@ function remapBitfield(num, mapping) { |
@@ -12,9 +12,13 @@ "use strict"; | ||
_export(exports, { | ||
elementSelectorParser: ()=>elementSelectorParser, | ||
default: ()=>resolveDefaultsAtRules | ||
elementSelectorParser: function() { | ||
return elementSelectorParser; | ||
}, | ||
default: function() { | ||
return resolveDefaultsAtRules; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
const _featureFlags = require("../featureFlags"); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -26,3 +30,3 @@ default: obj | ||
id (node) { | ||
return _postcssSelectorParser.default.attribute({ | ||
return _postcssselectorparser.default.attribute({ | ||
attribute: "id", | ||
@@ -65,3 +69,3 @@ operator: "=", | ||
rest.splice(0, combinatorIdx); | ||
rest.unshift(_postcssSelectorParser.default.universal()); | ||
rest.unshift(_postcssselectorparser.default.universal()); | ||
} | ||
@@ -73,3 +77,3 @@ return [ | ||
} | ||
let elementSelectorParser = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
let elementSelectorParser = (0, _postcssselectorparser.default)((selectors)=>{ | ||
return selectors.map((s)=>{ | ||
@@ -114,3 +118,5 @@ let nodes = s.split((n)=>n.type === "combinator" && n.value === " ").pop(); | ||
// vendor prefix to throw out the whole rule | ||
let selectorGroupName = selector.includes(":-") || selector.includes("::-") ? selector : "__DEFAULT__"; | ||
// Additionally if a selector contains `:has` we also consider | ||
// it separately because FF only recently gained support for it | ||
let selectorGroupName = selector.includes(":-") || selector.includes("::-") || selector.includes(":has") ? selector : "__DEFAULT__"; | ||
var _selectorGroups_get; | ||
@@ -127,3 +133,3 @@ let selectors = (_selectorGroups_get = selectorGroups.get(selectorGroupName)) !== null && _selectorGroups_get !== void 0 ? _selectorGroups_get : new Set(); | ||
} | ||
for (let [, selectors1] of selectorGroups){ | ||
for (let [, selectors] of selectorGroups){ | ||
let universalRule = _postcss.default.rule({ | ||
@@ -133,3 +139,3 @@ source: universal.source | ||
universalRule.selectors = [ | ||
...selectors1 | ||
...selectors | ||
]; | ||
@@ -143,3 +149,3 @@ universalRule.append(universal.nodes.map((node)=>node.clone())); | ||
} else if (universals.size) { | ||
let universalRule1 = _postcss.default.rule({ | ||
let universalRule = _postcss.default.rule({ | ||
selectors: [ | ||
@@ -151,13 +157,13 @@ "*", | ||
}); | ||
for (let universal1 of universals){ | ||
universalRule1.append(universal1.nodes); | ||
if (!universalRule1.parent) { | ||
universal1.before(universalRule1); | ||
for (let universal of universals){ | ||
universalRule.append(universal.nodes); | ||
if (!universalRule.parent) { | ||
universal.before(universalRule); | ||
} | ||
if (!universalRule1.source) { | ||
universalRule1.source = universal1.source; | ||
if (!universalRule.source) { | ||
universalRule.source = universal.source; | ||
} | ||
universal1.remove(); | ||
universal.remove(); | ||
} | ||
let backdropRule = universalRule1.clone({ | ||
let backdropRule = universalRule.clone({ | ||
selectors: [ | ||
@@ -167,5 +173,5 @@ "::backdrop" | ||
}); | ||
universalRule1.after(backdropRule); | ||
universalRule.after(backdropRule); | ||
} | ||
}; | ||
} |
@@ -12,32 +12,45 @@ "use strict"; | ||
_export(exports, { | ||
isValidVariantFormatString: ()=>isValidVariantFormatString, | ||
parseVariant: ()=>parseVariant, | ||
getFileModifiedMap: ()=>getFileModifiedMap, | ||
createContext: ()=>createContext, | ||
getContext: ()=>getContext | ||
INTERNAL_FEATURES: function() { | ||
return INTERNAL_FEATURES; | ||
}, | ||
isValidVariantFormatString: function() { | ||
return isValidVariantFormatString; | ||
}, | ||
parseVariant: function() { | ||
return parseVariant; | ||
}, | ||
getFileModifiedMap: function() { | ||
return getFileModifiedMap; | ||
}, | ||
createContext: function() { | ||
return createContext; | ||
}, | ||
getContext: function() { | ||
return getContext; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _url = /*#__PURE__*/ _interopRequireDefault(require("url")); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _dlv = /*#__PURE__*/ _interopRequireDefault(require("dlv")); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _transformThemeValue = /*#__PURE__*/ _interopRequireDefault(require("../util/transformThemeValue")); | ||
const _parseObjectStyles = /*#__PURE__*/ _interopRequireDefault(require("../util/parseObjectStyles")); | ||
const _prefixSelector = /*#__PURE__*/ _interopRequireDefault(require("../util/prefixSelector")); | ||
const _isPlainObject = /*#__PURE__*/ _interopRequireDefault(require("../util/isPlainObject")); | ||
const _escapeClassName = /*#__PURE__*/ _interopRequireDefault(require("../util/escapeClassName")); | ||
const _nameClass = /*#__PURE__*/ _interopRequireWildcard(require("../util/nameClass")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _url = /*#__PURE__*/ _interop_require_default(require("url")); | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _dlv = /*#__PURE__*/ _interop_require_default(require("dlv")); | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
const _transformThemeValue = /*#__PURE__*/ _interop_require_default(require("../util/transformThemeValue")); | ||
const _parseObjectStyles = /*#__PURE__*/ _interop_require_default(require("../util/parseObjectStyles")); | ||
const _prefixSelector = /*#__PURE__*/ _interop_require_default(require("../util/prefixSelector")); | ||
const _isPlainObject = /*#__PURE__*/ _interop_require_default(require("../util/isPlainObject")); | ||
const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("../util/escapeClassName")); | ||
const _nameClass = /*#__PURE__*/ _interop_require_wildcard(require("../util/nameClass")); | ||
const _pluginUtils = require("../util/pluginUtils"); | ||
const _corePlugins = require("../corePlugins"); | ||
const _sharedState = /*#__PURE__*/ _interopRequireWildcard(require("./sharedState")); | ||
const _sharedState = /*#__PURE__*/ _interop_require_wildcard(require("./sharedState")); | ||
const _toPath = require("../util/toPath"); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../util/log")); | ||
const _negateValue = /*#__PURE__*/ _interopRequireDefault(require("../util/negateValue")); | ||
const _isSyntacticallyValidPropertyValue = /*#__PURE__*/ _interopRequireDefault(require("../util/isSyntacticallyValidPropertyValue")); | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
const _negateValue = /*#__PURE__*/ _interop_require_default(require("../util/negateValue")); | ||
const _isSyntacticallyValidPropertyValue = /*#__PURE__*/ _interop_require_default(require("../util/isSyntacticallyValidPropertyValue")); | ||
const _generateRules = require("./generateRules"); | ||
const _cacheInvalidationJs = require("./cacheInvalidation.js"); | ||
const _offsetsJs = require("./offsets.js"); | ||
const _featureFlagsJs = require("../featureFlags.js"); | ||
const _cacheInvalidation = require("./cacheInvalidation.js"); | ||
const _offsets = require("./offsets.js"); | ||
const _featureFlags = require("../featureFlags.js"); | ||
const _formatVariantSelector = require("../util/formatVariantSelector"); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -55,3 +68,3 @@ default: obj | ||
} | ||
function _interopRequireWildcard(obj, nodeInterop) { | ||
function _interop_require_wildcard(obj, nodeInterop) { | ||
if (!nodeInterop && obj && obj.__esModule) { | ||
@@ -87,2 +100,3 @@ return obj; | ||
} | ||
const INTERNAL_FEATURES = Symbol(); | ||
const VARIANT_TYPES = { | ||
@@ -181,3 +195,3 @@ AddVariant: Symbol.for("ADD_VARIANT"), | ||
function getClasses(selector, mutate) { | ||
let parser = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
let parser = (0, _postcssselectorparser.default)((selectors)=>{ | ||
let allClasses = []; | ||
@@ -194,2 +208,16 @@ if (mutate) { | ||
} | ||
/** | ||
* Ignore everything inside a :not(...). This allows you to write code like | ||
* `div:not(.foo)`. If `.foo` is never found in your code, then we used to | ||
* not generated it. But now we will ignore everything inside a `:not`, so | ||
* that it still gets generated. | ||
* | ||
* @param {selectorParser.Root} selectors | ||
*/ function ignoreNot(selectors) { | ||
selectors.walkPseudos((pseudo)=>{ | ||
if (pseudo.value === ":not") { | ||
pseudo.remove(); | ||
} | ||
}); | ||
} | ||
function extractCandidates(node, state = { | ||
@@ -199,31 +227,19 @@ containsNonOnDemandable: false | ||
let classes = []; | ||
// Handle normal rules | ||
let selectors = []; | ||
if (node.type === "rule") { | ||
// Ignore everything inside a :not(...). This allows you to write code like | ||
// `div:not(.foo)`. If `.foo` is never found in your code, then we used to | ||
// not generated it. But now we will ignore everything inside a `:not`, so | ||
// that it still gets generated. | ||
function ignoreNot(selectors) { | ||
selectors.walkPseudos((pseudo)=>{ | ||
if (pseudo.value === ":not") { | ||
pseudo.remove(); | ||
} | ||
}); | ||
// Handle normal rules | ||
selectors.push(...node.selectors); | ||
} else if (node.type === "atrule") { | ||
// Handle at-rules (which contains nested rules) | ||
node.walkRules((rule)=>selectors.push(...rule.selectors)); | ||
} | ||
for (let selector of selectors){ | ||
let classCandidates = getClasses(selector, ignoreNot); | ||
// At least one of the selectors contains non-"on-demandable" candidates. | ||
if (classCandidates.length === 0) { | ||
state.containsNonOnDemandable = true; | ||
} | ||
for (let selector of node.selectors){ | ||
let classCandidates = getClasses(selector, ignoreNot); | ||
// At least one of the selectors contains non-"on-demandable" candidates. | ||
if (classCandidates.length === 0) { | ||
state.containsNonOnDemandable = true; | ||
} | ||
for (let classCandidate of classCandidates){ | ||
classes.push(classCandidate); | ||
} | ||
for (let classCandidate of classCandidates){ | ||
classes.push(classCandidate); | ||
} | ||
} else if (node.type === "atrule") { | ||
node.walkRules((rule)=>{ | ||
for (let classCandidate of rule.selectors.flatMap((selector)=>getClasses(selector))){ | ||
classes.push(classCandidate); | ||
} | ||
}); | ||
} | ||
@@ -269,7 +285,10 @@ if (depth === 0) { | ||
} | ||
let [, name, params] = /@(.*?)( .+|[({].*)/g.exec(str); | ||
return ({ wrap })=>wrap(_postcss.default.atRule({ | ||
let [, name, params] = /@(\S*)( .+|[({].*)?/g.exec(str); | ||
var _params_trim; | ||
return ({ wrap })=>{ | ||
return wrap(_postcss.default.atRule({ | ||
name, | ||
params: params.trim() | ||
params: (_params_trim = params === null || params === void 0 ? void 0 : params.trim()) !== null && _params_trim !== void 0 ? _params_trim : "" | ||
})); | ||
}; | ||
}).reverse(); | ||
@@ -461,3 +480,3 @@ return (api)=>{ | ||
}; | ||
let modifiersEnabled = (0, _featureFlagsJs.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let modifiersEnabled = (0, _featureFlags.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let ruleSets = [].concat(modifiersEnabled ? rule(value, extras) : rule(value)).filter(Boolean).map((declaration)=>({ | ||
@@ -528,3 +547,3 @@ [(0, _nameClass.default)(identifier, modifier)]: declaration | ||
}; | ||
let modifiersEnabled = (0, _featureFlagsJs.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let modifiersEnabled = (0, _featureFlags.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let ruleSets = [].concat(modifiersEnabled ? rule(value, extras) : rule(value)).filter(Boolean).map((declaration)=>({ | ||
@@ -590,3 +609,3 @@ [(0, _nameClass.default)(identifier, modifier)]: declaration | ||
let isSpecial = variant === "@"; | ||
let modifiersEnabled = (0, _featureFlagsJs.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let modifiersEnabled = (0, _featureFlags.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
var _options_values; | ||
@@ -702,5 +721,5 @@ for (let [key, value] of Object.entries((_options_values = options === null || options === void 0 ? void 0 : options.values) !== null && _options_values !== void 0 ? _options_values : {})){ | ||
} else if (layerRule.params === "components") { | ||
for (let node1 of layerRule.nodes){ | ||
for (let node of layerRule.nodes){ | ||
layerPlugins.push(function({ addComponents }) { | ||
addComponents(node1, { | ||
addComponents(node, { | ||
respectPrefix: false, | ||
@@ -713,5 +732,5 @@ preserveSource: true | ||
} else if (layerRule.params === "utilities") { | ||
for (let node2 of layerRule.nodes){ | ||
for (let node of layerRule.nodes){ | ||
layerPlugins.push(function({ addUtilities }) { | ||
addUtilities(node2, { | ||
addUtilities(node, { | ||
respectPrefix: false, | ||
@@ -747,4 +766,6 @@ preserveSource: true | ||
let beforeVariants = [ | ||
_corePlugins.variantPlugins["childVariant"], | ||
_corePlugins.variantPlugins["pseudoElementVariants"], | ||
_corePlugins.variantPlugins["pseudoClassVariants"], | ||
_corePlugins.variantPlugins["hasVariants"], | ||
_corePlugins.variantPlugins["ariaVariants"], | ||
@@ -755,10 +776,27 @@ _corePlugins.variantPlugins["dataVariants"] | ||
_corePlugins.variantPlugins["supportsVariants"], | ||
_corePlugins.variantPlugins["directionVariants"], | ||
_corePlugins.variantPlugins["reducedMotionVariants"], | ||
_corePlugins.variantPlugins["prefersContrastVariants"], | ||
_corePlugins.variantPlugins["screenVariants"], | ||
_corePlugins.variantPlugins["orientationVariants"], | ||
_corePlugins.variantPlugins["directionVariants"], | ||
_corePlugins.variantPlugins["darkVariants"], | ||
_corePlugins.variantPlugins["printVariant"], | ||
_corePlugins.variantPlugins["screenVariants"], | ||
_corePlugins.variantPlugins["orientationVariants"] | ||
_corePlugins.variantPlugins["forcedColorsVariants"], | ||
_corePlugins.variantPlugins["printVariant"] | ||
]; | ||
// This is a compatibility fix for the pre 3.4 dark mode behavior | ||
// `class` retains the old behavior, but `selector` keeps the new behavior | ||
let isLegacyDarkMode = context.tailwindConfig.darkMode === "class" || Array.isArray(context.tailwindConfig.darkMode) && context.tailwindConfig.darkMode[0] === "class"; | ||
if (isLegacyDarkMode) { | ||
afterVariants = [ | ||
_corePlugins.variantPlugins["supportsVariants"], | ||
_corePlugins.variantPlugins["reducedMotionVariants"], | ||
_corePlugins.variantPlugins["prefersContrastVariants"], | ||
_corePlugins.variantPlugins["darkVariants"], | ||
_corePlugins.variantPlugins["screenVariants"], | ||
_corePlugins.variantPlugins["orientationVariants"], | ||
_corePlugins.variantPlugins["directionVariants"], | ||
_corePlugins.variantPlugins["forcedColorsVariants"], | ||
_corePlugins.variantPlugins["printVariant"] | ||
]; | ||
} | ||
return [ | ||
@@ -776,3 +814,3 @@ ...corePluginList, | ||
context.variantMap = variantMap; | ||
let offsets = new _offsetsJs.Offsets(); | ||
let offsets = new _offsets.Offsets(); | ||
context.offsets = offsets; | ||
@@ -868,3 +906,3 @@ let classList = new Set(); | ||
]; | ||
for (let util1 of utils){ | ||
for (let util of utils){ | ||
for (let { pattern , variants =[] } of checks){ | ||
@@ -877,6 +915,6 @@ // RegExp with the /g flag are stateful, so let's reset the last | ||
} | ||
if (!pattern.test(util1)) continue; | ||
if (!pattern.test(util)) continue; | ||
patternMatchingCount.set(pattern, patternMatchingCount.get(pattern) + 1); | ||
context.changedContent.push({ | ||
content: util1, | ||
content: util, | ||
extension: "html" | ||
@@ -886,3 +924,3 @@ }); | ||
context.changedContent.push({ | ||
content: variant + context.tailwindConfig.separator + util1, | ||
content: variant + context.tailwindConfig.separator + util, | ||
extension: "html" | ||
@@ -916,4 +954,12 @@ }); | ||
context.getClassOrder = function getClassOrder(classes) { | ||
// Sort classes so they're ordered in a deterministic manner | ||
let sorted = [ | ||
...classes | ||
].sort((a, z)=>{ | ||
if (a === z) return 0; | ||
if (a < z) return -1; | ||
return 1; | ||
}); | ||
// Non-util classes won't be generated, so we default them to null | ||
let sortedClassNames = new Map(classes.map((className)=>[ | ||
let sortedClassNames = new Map(sorted.map((className)=>[ | ||
className, | ||
@@ -924,7 +970,11 @@ null | ||
// Non-tailwind classes won't be generated and will be left as `null` | ||
let rules = (0, _generateRules.generateRules)(new Set(classes), context); | ||
let rules = (0, _generateRules.generateRules)(new Set(sorted), context, true); | ||
rules = context.offsets.sort(rules); | ||
let idx = BigInt(parasiteUtilities.length); | ||
for (const [, rule] of rules){ | ||
sortedClassNames.set(rule.raws.tailwind.candidate, idx++); | ||
let candidate = rule.raws.tailwind.candidate; | ||
var _sortedClassNames_get; | ||
// When multiple rules match a candidate | ||
// always take the position of the first one | ||
sortedClassNames.set(candidate, (_sortedClassNames_get = sortedClassNames.get(candidate)) !== null && _sortedClassNames_get !== void 0 ? _sortedClassNames_get : idx++); | ||
} | ||
@@ -949,10 +999,21 @@ return classes.map((className)=>{ | ||
// ['uppercase', 'lowercase', ...] | ||
context.getClassList = function getClassList() { | ||
context.getClassList = function getClassList(options = {}) { | ||
let output = []; | ||
for (let util of classList){ | ||
if (Array.isArray(util)) { | ||
let [utilName, options] = util; | ||
var _utilOptions_types; | ||
let [utilName, utilOptions] = util; | ||
let negativeClasses = []; | ||
var _options_values; | ||
for (let [key, value] of Object.entries((_options_values = options === null || options === void 0 ? void 0 : options.values) !== null && _options_values !== void 0 ? _options_values : {})){ | ||
var _utilOptions_modifiers; | ||
let modifiers = Object.keys((_utilOptions_modifiers = utilOptions === null || utilOptions === void 0 ? void 0 : utilOptions.modifiers) !== null && _utilOptions_modifiers !== void 0 ? _utilOptions_modifiers : {}); | ||
if (utilOptions === null || utilOptions === void 0 ? void 0 : (_utilOptions_types = utilOptions.types) === null || _utilOptions_types === void 0 ? void 0 : _utilOptions_types.some(({ type })=>type === "color")) { | ||
var _context_tailwindConfig_theme_opacity; | ||
modifiers.push(...Object.keys((_context_tailwindConfig_theme_opacity = context.tailwindConfig.theme.opacity) !== null && _context_tailwindConfig_theme_opacity !== void 0 ? _context_tailwindConfig_theme_opacity : {})); | ||
} | ||
let metadata = { | ||
modifiers | ||
}; | ||
let includeMetadata = options.includeMetadata && modifiers.length > 0; | ||
var _utilOptions_values; | ||
for (let [key, value] of Object.entries((_utilOptions_values = utilOptions === null || utilOptions === void 0 ? void 0 : utilOptions.values) !== null && _utilOptions_values !== void 0 ? _utilOptions_values : {})){ | ||
// Ignore undefined and null values | ||
@@ -962,5 +1023,13 @@ if (value == null) { | ||
} | ||
output.push((0, _nameClass.formatClass)(utilName, key)); | ||
if ((options === null || options === void 0 ? void 0 : options.supportsNegativeValues) && (0, _negateValue.default)(value)) { | ||
negativeClasses.push((0, _nameClass.formatClass)(utilName, `-${key}`)); | ||
let cls = (0, _nameClass.formatClass)(utilName, key); | ||
output.push(includeMetadata ? [ | ||
cls, | ||
metadata | ||
] : cls); | ||
if ((utilOptions === null || utilOptions === void 0 ? void 0 : utilOptions.supportsNegativeValues) && (0, _negateValue.default)(value)) { | ||
let cls = (0, _nameClass.formatClass)(utilName, `-${key}`); | ||
negativeClasses.push(includeMetadata ? [ | ||
cls, | ||
metadata | ||
] : cls); | ||
} | ||
@@ -977,2 +1046,6 @@ } | ||
context.getVariants = function getVariants() { | ||
// We use a unique, random ID for candidate names to avoid conflicts | ||
// We can't use characters like `_`, `:`, `@` or `.` because they might | ||
// be used as a separator | ||
let id = Math.random().toString(36).substring(7).toUpperCase(); | ||
let result = []; | ||
@@ -988,3 +1061,3 @@ for (let [name, options] of context.variantOptions.entries()){ | ||
selectors ({ modifier , value } = {}) { | ||
let candidate = "__TAILWIND_PLACEHOLDER__"; | ||
let candidate = `TAILWINDPLACEHOLDER${id}`; | ||
let rule = _postcss.default.rule({ | ||
@@ -1060,3 +1133,3 @@ selector: `.${candidate}` | ||
// classes, pseudos, ids, ... | ||
let rebuiltBase = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
let rebuiltBase = (0, _postcssselectorparser.default)((selectors)=>{ | ||
selectors.walkClasses((classNode)=>{ | ||
@@ -1086,9 +1159,16 @@ classNode.value = `${name}${context.tailwindConfig.separator}${classNode.value}`; | ||
let isArbitraryVariant = !(value in ((_options_values1 = options.values) !== null && _options_values1 !== void 0 ? _options_values1 : {})); | ||
var _options_INTERNAL_FEATURES; | ||
let internalFeatures = (_options_INTERNAL_FEATURES = options[INTERNAL_FEATURES]) !== null && _options_INTERNAL_FEATURES !== void 0 ? _options_INTERNAL_FEATURES : {}; | ||
let respectPrefix = (()=>{ | ||
if (isArbitraryVariant) return false; | ||
if (internalFeatures.respectPrefix === false) return false; | ||
return true; | ||
})(); | ||
formatStrings = formatStrings.map((format)=>format.map((str)=>({ | ||
format: str, | ||
isArbitraryVariant | ||
respectPrefix | ||
}))); | ||
manualFormatStrings = manualFormatStrings.map((format)=>({ | ||
format, | ||
isArbitraryVariant | ||
respectPrefix | ||
})); | ||
@@ -1186,3 +1266,3 @@ let opts = { | ||
} | ||
let cssDidChange = (0, _cacheInvalidationJs.hasContentChanged)(sourcePath, root); | ||
let cssDidChange = (0, _cacheInvalidation.hasContentChanged)(sourcePath, root); | ||
// If there's already a context in the cache and we don't need to | ||
@@ -1213,5 +1293,5 @@ // reset the context, return the cached context. | ||
contextSourcesMap.delete(oldContext); | ||
for (let [tailwindConfigHash1, context1] of configContextMap){ | ||
if (context1 === oldContext) { | ||
configContextMap.delete(tailwindConfigHash1); | ||
for (let [tailwindConfigHash, context] of configContextMap){ | ||
if (context === oldContext) { | ||
configContextMap.delete(tailwindConfigHash); | ||
} | ||
@@ -1226,22 +1306,22 @@ } | ||
_sharedState.env.DEBUG && console.log("Setting up new context..."); | ||
let context2 = createContext(tailwindConfig, [], root); | ||
Object.assign(context2, { | ||
let context = createContext(tailwindConfig, [], root); | ||
Object.assign(context, { | ||
userConfigPath | ||
}); | ||
let [, mtimesToCommit1] = trackModified([ | ||
let [, mtimesToCommit] = trackModified([ | ||
...contextDependencies | ||
], getFileModifiedMap(context2)); | ||
], getFileModifiedMap(context)); | ||
// --- | ||
// Update all context tracking state | ||
configContextMap.set(tailwindConfigHash, context2); | ||
contextMap.set(sourcePath, context2); | ||
if (!contextSourcesMap.has(context2)) { | ||
contextSourcesMap.set(context2, new Set()); | ||
configContextMap.set(tailwindConfigHash, context); | ||
contextMap.set(sourcePath, context); | ||
if (!contextSourcesMap.has(context)) { | ||
contextSourcesMap.set(context, new Set()); | ||
} | ||
contextSourcesMap.get(context2).add(sourcePath); | ||
contextSourcesMap.get(context).add(sourcePath); | ||
return [ | ||
context2, | ||
context, | ||
true, | ||
mtimesToCommit1 | ||
mtimesToCommit | ||
]; | ||
} |
@@ -12,15 +12,18 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>setupTrackingContext | ||
get: function() { | ||
return setupTrackingContext; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _quickLru = /*#__PURE__*/ _interopRequireDefault(require("quick-lru")); | ||
const _hashConfig = /*#__PURE__*/ _interopRequireDefault(require("../util/hashConfig")); | ||
const _getModuleDependencies = /*#__PURE__*/ _interopRequireDefault(require("../lib/getModuleDependencies")); | ||
const _resolveConfig = /*#__PURE__*/ _interopRequireDefault(require("../public/resolve-config")); | ||
const _resolveConfigPath = /*#__PURE__*/ _interopRequireDefault(require("../util/resolveConfigPath")); | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _quicklru = /*#__PURE__*/ _interop_require_default(require("@alloc/quick-lru")); | ||
const _hashConfig = /*#__PURE__*/ _interop_require_default(require("../util/hashConfig")); | ||
const _resolveconfig = /*#__PURE__*/ _interop_require_default(require("../public/resolve-config")); | ||
const _resolveConfigPath = /*#__PURE__*/ _interop_require_default(require("../util/resolveConfigPath")); | ||
const _setupContextUtils = require("./setupContextUtils"); | ||
const _parseDependency = /*#__PURE__*/ _interopRequireDefault(require("../util/parseDependency")); | ||
const _validateConfigJs = require("../util/validateConfig.js"); | ||
const _contentJs = require("./content.js"); | ||
function _interopRequireDefault(obj) { | ||
const _parseDependency = /*#__PURE__*/ _interop_require_default(require("../util/parseDependency")); | ||
const _validateConfig = require("../util/validateConfig.js"); | ||
const _content = require("./content.js"); | ||
const _loadconfig = require("../lib/load-config"); | ||
const _getModuleDependencies = /*#__PURE__*/ _interop_require_default(require("./getModuleDependencies")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -30,3 +33,3 @@ default: obj | ||
} | ||
let configPathCache = new _quickLru.default({ | ||
let configPathCache = new _quicklru.default({ | ||
maxSize: 100 | ||
@@ -39,3 +42,3 @@ }); | ||
} | ||
let candidateFiles = (0, _contentJs.parseCandidateFiles)(context, tailwindConfig); | ||
let candidateFiles = (0, _content.parseCandidateFiles)(context, tailwindConfig); | ||
return candidateFilesCache.set(context, candidateFiles).get(context); | ||
@@ -48,3 +51,3 @@ } | ||
let [prevConfig, prevConfigHash, prevDeps, prevModified] = configPathCache.get(userConfigPath) || []; | ||
let newDeps = (0, _getModuleDependencies.default)(userConfigPath).map((dep)=>dep.file); | ||
let newDeps = (0, _getModuleDependencies.default)(userConfigPath); | ||
let modified = false; | ||
@@ -69,7 +72,6 @@ let newModified = new Map(); | ||
// It has changed (based on timestamps), or first run | ||
for (let file1 of newDeps){ | ||
delete require.cache[file1]; | ||
for (let file of newDeps){ | ||
delete require.cache[file]; | ||
} | ||
let newConfig = (0, _resolveConfig.default)(require(userConfigPath)); | ||
newConfig = (0, _validateConfigJs.validateConfig)(newConfig); | ||
let newConfig = (0, _validateConfig.validateConfig)((0, _resolveconfig.default)((0, _loadconfig.loadConfig)(userConfigPath))); | ||
let newHash = (0, _hashConfig.default)(newConfig); | ||
@@ -89,9 +91,10 @@ configPathCache.set(userConfigPath, [ | ||
} | ||
var _configOrPath_config, _ref; | ||
// It's a plain object, not a path | ||
let newConfig1 = (0, _resolveConfig.default)(configOrPath.config === undefined ? configOrPath : configOrPath.config); | ||
newConfig1 = (0, _validateConfigJs.validateConfig)(newConfig1); | ||
let newConfig = (0, _resolveconfig.default)((_ref = (_configOrPath_config = configOrPath === null || configOrPath === void 0 ? void 0 : configOrPath.config) !== null && _configOrPath_config !== void 0 ? _configOrPath_config : configOrPath) !== null && _ref !== void 0 ? _ref : {}); | ||
newConfig = (0, _validateConfig.validateConfig)(newConfig); | ||
return [ | ||
newConfig1, | ||
newConfig, | ||
null, | ||
(0, _hashConfig.default)(newConfig1), | ||
(0, _hashConfig.default)(newConfig), | ||
[] | ||
@@ -136,3 +139,3 @@ ]; | ||
} | ||
let [changedContent, contentMTimesToCommit] = (0, _contentJs.resolvedChangedContent)(context, candidateFiles, fileModifiedMap); | ||
let [changedContent, contentMTimesToCommit] = (0, _content.resolvedChangedContent)(context, candidateFiles, fileModifiedMap); | ||
for (let content of changedContent){ | ||
@@ -164,4 +167,4 @@ context.changedContent.push(content); | ||
// read the "old" mtime even when it's a context dependency. | ||
for (let [path1, mtime1] of mTimesToCommit.entries()){ | ||
fileModifiedMap.set(path1, mtime1); | ||
for (let [path, mtime] of mTimesToCommit.entries()){ | ||
fileModifiedMap.set(path, mtime); | ||
} | ||
@@ -168,0 +171,0 @@ return context; |
@@ -12,15 +12,33 @@ "use strict"; | ||
_export(exports, { | ||
env: ()=>env, | ||
contextMap: ()=>contextMap, | ||
configContextMap: ()=>configContextMap, | ||
contextSourcesMap: ()=>contextSourcesMap, | ||
sourceHashMap: ()=>sourceHashMap, | ||
NOT_ON_DEMAND: ()=>NOT_ON_DEMAND, | ||
NONE: ()=>NONE, | ||
resolveDebug: ()=>resolveDebug | ||
env: function() { | ||
return env; | ||
}, | ||
contextMap: function() { | ||
return contextMap; | ||
}, | ||
configContextMap: function() { | ||
return configContextMap; | ||
}, | ||
contextSourcesMap: function() { | ||
return contextSourcesMap; | ||
}, | ||
sourceHashMap: function() { | ||
return sourceHashMap; | ||
}, | ||
NOT_ON_DEMAND: function() { | ||
return NOT_ON_DEMAND; | ||
}, | ||
NONE: function() { | ||
return NONE; | ||
}, | ||
resolveDebug: function() { | ||
return resolveDebug; | ||
} | ||
}); | ||
const env = { | ||
const env = typeof process !== "undefined" ? { | ||
NODE_ENV: process.env.NODE_ENV, | ||
DEBUG: resolveDebug(process.env.DEBUG), | ||
OXIDE: process.env.OXIDE | ||
DEBUG: resolveDebug(process.env.DEBUG) | ||
} : { | ||
NODE_ENV: "production", | ||
DEBUG: false | ||
}; | ||
@@ -27,0 +45,0 @@ const contextMap = new Map(); |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _normalizeScreens = require("../util/normalizeScreens"); | ||
const _buildMediaQuery = /*#__PURE__*/ _interopRequireDefault(require("../util/buildMediaQuery")); | ||
function _interopRequireDefault(obj) { | ||
const _buildMediaQuery = /*#__PURE__*/ _interop_require_default(require("../util/buildMediaQuery")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -14,0 +16,0 @@ default: obj |
@@ -5,7 +5,7 @@ "use strict"; | ||
}); | ||
const _setupTrackingContext = /*#__PURE__*/ _interopRequireDefault(require("./lib/setupTrackingContext")); | ||
const _processTailwindFeatures = /*#__PURE__*/ _interopRequireDefault(require("./processTailwindFeatures")); | ||
const _setupTrackingContext = /*#__PURE__*/ _interop_require_default(require("./lib/setupTrackingContext")); | ||
const _processTailwindFeatures = /*#__PURE__*/ _interop_require_default(require("./processTailwindFeatures")); | ||
const _sharedState = require("./lib/sharedState"); | ||
const _findAtConfigPath = require("./lib/findAtConfigPath"); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -24,3 +24,3 @@ default: obj | ||
}, | ||
function(root, result) { | ||
async function(root, result) { | ||
var _findAtConfigPath1; | ||
@@ -33,5 +33,5 @@ // Use the path for the `@config` directive if it exists, otherwise use the | ||
let roots = root.nodes.filter((node)=>node.type === "root"); | ||
for (const root1 of roots){ | ||
if (root1.type === "root") { | ||
(0, _processTailwindFeatures.default)(context)(root1, result); | ||
for (const root of roots){ | ||
if (root.type === "root") { | ||
await (0, _processTailwindFeatures.default)(context)(root, result); | ||
} | ||
@@ -41,3 +41,3 @@ } | ||
} | ||
(0, _processTailwindFeatures.default)(context)(root, result); | ||
await (0, _processTailwindFeatures.default)(context)(root, result); | ||
}, | ||
@@ -44,0 +44,0 @@ _sharedState.env.DEBUG && function(root) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ const _plugin = require("./plugin"); |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>nesting | ||
get: function() { | ||
return nesting; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _postcssNested = /*#__PURE__*/ _interopRequireDefault(require("postcss-nested")); | ||
function _interopRequireDefault(obj) { | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _postcssnested = /*#__PURE__*/ _interop_require_default(require("postcss-nested")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -17,3 +19,3 @@ default: obj | ||
} | ||
function nesting(opts = _postcssNested.default) { | ||
function nesting(opts = _postcssnested.default) { | ||
return (root, result)=>{ | ||
@@ -41,3 +43,3 @@ root.walkAtRules("screen", (rule)=>{ | ||
if (Object.keys(opts).length <= 0) { | ||
return _postcssNested.default; | ||
return _postcssnested.default; | ||
} | ||
@@ -44,0 +46,0 @@ throw new Error("tailwindcss/nesting should be loaded with a nesting plugin."); |
@@ -7,17 +7,18 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>processTailwindFeatures | ||
get: function() { | ||
return processTailwindFeatures; | ||
} | ||
}); | ||
const _normalizeTailwindDirectives = /*#__PURE__*/ _interopRequireDefault(require("./lib/normalizeTailwindDirectives")); | ||
const _expandTailwindAtRules = /*#__PURE__*/ _interopRequireDefault(require("./lib/expandTailwindAtRules")); | ||
const _expandApplyAtRules = /*#__PURE__*/ _interopRequireDefault(require("./lib/expandApplyAtRules")); | ||
const _evaluateTailwindFunctions = /*#__PURE__*/ _interopRequireDefault(require("./lib/evaluateTailwindFunctions")); | ||
const _substituteScreenAtRules = /*#__PURE__*/ _interopRequireDefault(require("./lib/substituteScreenAtRules")); | ||
const _resolveDefaultsAtRules = /*#__PURE__*/ _interopRequireDefault(require("./lib/resolveDefaultsAtRules")); | ||
const _collapseAdjacentRules = /*#__PURE__*/ _interopRequireDefault(require("./lib/collapseAdjacentRules")); | ||
const _collapseDuplicateDeclarations = /*#__PURE__*/ _interopRequireDefault(require("./lib/collapseDuplicateDeclarations")); | ||
const _partitionApplyAtRules = /*#__PURE__*/ _interopRequireDefault(require("./lib/partitionApplyAtRules")); | ||
const _detectNesting = /*#__PURE__*/ _interopRequireDefault(require("./lib/detectNesting")); | ||
const _normalizeTailwindDirectives = /*#__PURE__*/ _interop_require_default(require("./lib/normalizeTailwindDirectives")); | ||
const _expandTailwindAtRules = /*#__PURE__*/ _interop_require_default(require("./lib/expandTailwindAtRules")); | ||
const _expandApplyAtRules = /*#__PURE__*/ _interop_require_default(require("./lib/expandApplyAtRules")); | ||
const _evaluateTailwindFunctions = /*#__PURE__*/ _interop_require_default(require("./lib/evaluateTailwindFunctions")); | ||
const _substituteScreenAtRules = /*#__PURE__*/ _interop_require_default(require("./lib/substituteScreenAtRules")); | ||
const _resolveDefaultsAtRules = /*#__PURE__*/ _interop_require_default(require("./lib/resolveDefaultsAtRules")); | ||
const _collapseAdjacentRules = /*#__PURE__*/ _interop_require_default(require("./lib/collapseAdjacentRules")); | ||
const _collapseDuplicateDeclarations = /*#__PURE__*/ _interop_require_default(require("./lib/collapseDuplicateDeclarations")); | ||
const _partitionApplyAtRules = /*#__PURE__*/ _interop_require_default(require("./lib/partitionApplyAtRules")); | ||
const _setupContextUtils = require("./lib/setupContextUtils"); | ||
const _featureFlags = require("./featureFlags"); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -28,5 +29,4 @@ default: obj | ||
function processTailwindFeatures(setupContext) { | ||
return function(root, result) { | ||
return async function(root, result) { | ||
let { tailwindDirectives , applyDirectives } = (0, _normalizeTailwindDirectives.default)(root); | ||
(0, _detectNesting.default)()(root, result); | ||
// Partition apply rules that are found in the css | ||
@@ -53,3 +53,3 @@ // itself. | ||
(0, _featureFlags.issueFlagNotices)(context.tailwindConfig); | ||
(0, _expandTailwindAtRules.default)(context)(root, result); | ||
await (0, _expandTailwindAtRules.default)(context)(root, result); | ||
// Partition apply rules that are generated by | ||
@@ -56,0 +56,0 @@ // addComponents, addUtilities and so on. |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("../util/log")); | ||
function _interopRequireDefault(obj) { | ||
const _log = /*#__PURE__*/ _interop_require_default(require("../util/log")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -38,3 +40,4 @@ default: obj | ||
800: "#1e293b", | ||
900: "#0f172a" | ||
900: "#0f172a", | ||
950: "#020617" | ||
}, | ||
@@ -51,3 +54,4 @@ gray: { | ||
800: "#1f2937", | ||
900: "#111827" | ||
900: "#111827", | ||
950: "#030712" | ||
}, | ||
@@ -64,3 +68,4 @@ zinc: { | ||
800: "#27272a", | ||
900: "#18181b" | ||
900: "#18181b", | ||
950: "#09090b" | ||
}, | ||
@@ -77,3 +82,4 @@ neutral: { | ||
800: "#262626", | ||
900: "#171717" | ||
900: "#171717", | ||
950: "#0a0a0a" | ||
}, | ||
@@ -90,3 +96,4 @@ stone: { | ||
800: "#292524", | ||
900: "#1c1917" | ||
900: "#1c1917", | ||
950: "#0c0a09" | ||
}, | ||
@@ -103,3 +110,4 @@ red: { | ||
800: "#991b1b", | ||
900: "#7f1d1d" | ||
900: "#7f1d1d", | ||
950: "#450a0a" | ||
}, | ||
@@ -116,3 +124,4 @@ orange: { | ||
800: "#9a3412", | ||
900: "#7c2d12" | ||
900: "#7c2d12", | ||
950: "#431407" | ||
}, | ||
@@ -129,3 +138,4 @@ amber: { | ||
800: "#92400e", | ||
900: "#78350f" | ||
900: "#78350f", | ||
950: "#451a03" | ||
}, | ||
@@ -142,3 +152,4 @@ yellow: { | ||
800: "#854d0e", | ||
900: "#713f12" | ||
900: "#713f12", | ||
950: "#422006" | ||
}, | ||
@@ -155,3 +166,4 @@ lime: { | ||
800: "#3f6212", | ||
900: "#365314" | ||
900: "#365314", | ||
950: "#1a2e05" | ||
}, | ||
@@ -168,3 +180,4 @@ green: { | ||
800: "#166534", | ||
900: "#14532d" | ||
900: "#14532d", | ||
950: "#052e16" | ||
}, | ||
@@ -181,3 +194,4 @@ emerald: { | ||
800: "#065f46", | ||
900: "#064e3b" | ||
900: "#064e3b", | ||
950: "#022c22" | ||
}, | ||
@@ -194,3 +208,4 @@ teal: { | ||
800: "#115e59", | ||
900: "#134e4a" | ||
900: "#134e4a", | ||
950: "#042f2e" | ||
}, | ||
@@ -207,3 +222,4 @@ cyan: { | ||
800: "#155e75", | ||
900: "#164e63" | ||
900: "#164e63", | ||
950: "#083344" | ||
}, | ||
@@ -220,3 +236,4 @@ sky: { | ||
800: "#075985", | ||
900: "#0c4a6e" | ||
900: "#0c4a6e", | ||
950: "#082f49" | ||
}, | ||
@@ -233,3 +250,4 @@ blue: { | ||
800: "#1e40af", | ||
900: "#1e3a8a" | ||
900: "#1e3a8a", | ||
950: "#172554" | ||
}, | ||
@@ -246,3 +264,4 @@ indigo: { | ||
800: "#3730a3", | ||
900: "#312e81" | ||
900: "#312e81", | ||
950: "#1e1b4b" | ||
}, | ||
@@ -259,3 +278,4 @@ violet: { | ||
800: "#5b21b6", | ||
900: "#4c1d95" | ||
900: "#4c1d95", | ||
950: "#2e1065" | ||
}, | ||
@@ -272,3 +292,4 @@ purple: { | ||
800: "#6b21a8", | ||
900: "#581c87" | ||
900: "#581c87", | ||
950: "#3b0764" | ||
}, | ||
@@ -285,3 +306,4 @@ fuchsia: { | ||
800: "#86198f", | ||
900: "#701a75" | ||
900: "#701a75", | ||
950: "#4a044e" | ||
}, | ||
@@ -298,3 +320,4 @@ pink: { | ||
800: "#9d174d", | ||
900: "#831843" | ||
900: "#831843", | ||
950: "#500724" | ||
}, | ||
@@ -311,3 +334,4 @@ rose: { | ||
800: "#9f1239", | ||
900: "#881337" | ||
900: "#881337", | ||
950: "#4c0519" | ||
}, | ||
@@ -314,0 +338,0 @@ get lightBlue () { |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _createPlugin = /*#__PURE__*/ _interopRequireDefault(require("../util/createPlugin")); | ||
function _interopRequireDefault(obj) { | ||
const _createPlugin = /*#__PURE__*/ _interop_require_default(require("../util/createPlugin")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -13,0 +15,0 @@ default: obj |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _cloneDeep = require("../util/cloneDeep"); | ||
const _defaultConfigStub = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/defaultConfig.stub")); | ||
function _interopRequireDefault(obj) { | ||
const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -17,2 +19,2 @@ default: obj | ||
} | ||
const _default = (0, _cloneDeep.cloneDeep)(_defaultConfigStub.default); | ||
const _default = (0, _cloneDeep.cloneDeep)(_configfull.default); |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _cloneDeep = require("../util/cloneDeep"); | ||
const _defaultConfigStub = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/defaultConfig.stub")); | ||
function _interopRequireDefault(obj) { | ||
const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -17,2 +19,2 @@ default: obj | ||
} | ||
const _default = (0, _cloneDeep.cloneDeep)(_defaultConfigStub.default.theme); | ||
const _default = (0, _cloneDeep.cloneDeep)(_configfull.default.theme); |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>resolveConfig | ||
get: function() { | ||
return resolveConfig; | ||
} | ||
}); | ||
const _resolveConfig = /*#__PURE__*/ _interopRequireDefault(require("../util/resolveConfig")); | ||
const _getAllConfigs = /*#__PURE__*/ _interopRequireDefault(require("../util/getAllConfigs")); | ||
function _interopRequireDefault(obj) { | ||
const _resolveConfig = /*#__PURE__*/ _interop_require_default(require("../util/resolveConfig")); | ||
const _getAllConfigs = /*#__PURE__*/ _interop_require_default(require("../util/getAllConfigs")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -14,0 +16,0 @@ default: obj |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>bigSign | ||
get: function() { | ||
return bigSign; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function bigSign(bigIntValue) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>buildMediaQuery | ||
get: function() { | ||
return buildMediaQuery; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function buildMediaQuery(screens) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>cloneDeep | ||
get: function() { | ||
return cloneDeep; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function cloneDeep(value) { |
@@ -1,2 +0,7 @@ | ||
"use strict"; | ||
/** | ||
* @param {import('postcss').Container[]} nodes | ||
* @param {any} source | ||
* @param {any} raws | ||
* @returns {import('postcss').Container[]} | ||
*/ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
@@ -7,19 +12,9 @@ value: true | ||
enumerable: true, | ||
get: ()=>cloneNodes | ||
get: function() { | ||
return cloneNodes; | ||
} | ||
}); | ||
function cloneNodes(nodes, source = undefined, raws = undefined) { | ||
return nodes.map((node)=>{ | ||
var _node_raws_tailwind; | ||
let cloned = node.clone(); | ||
// We always want override the source map | ||
// except when explicitly told not to | ||
let shouldOverwriteSource = ((_node_raws_tailwind = node.raws.tailwind) === null || _node_raws_tailwind === void 0 ? void 0 : _node_raws_tailwind.preserveSource) !== true || !cloned.source; | ||
if (source !== undefined && shouldOverwriteSource) { | ||
cloned.source = source; | ||
if ("walk" in cloned) { | ||
cloned.walk((child)=>{ | ||
child.source = source; | ||
}); | ||
} | ||
} | ||
if (raws !== undefined) { | ||
@@ -31,4 +26,31 @@ cloned.raws.tailwind = { | ||
} | ||
if (source !== undefined) { | ||
traverse(cloned, (node)=>{ | ||
var _node_raws_tailwind; | ||
// Do not traverse nodes that have opted | ||
// to preserve their original source | ||
let shouldPreserveSource = ((_node_raws_tailwind = node.raws.tailwind) === null || _node_raws_tailwind === void 0 ? void 0 : _node_raws_tailwind.preserveSource) === true && node.source; | ||
if (shouldPreserveSource) { | ||
return false; | ||
} | ||
// Otherwise we can safely replace the source | ||
// And continue traversing | ||
node.source = source; | ||
}); | ||
} | ||
return cloned; | ||
}); | ||
} | ||
/** | ||
* Traverse a tree of nodes and don't traverse children if the callback | ||
* returns false. Ideally we'd use Container#walk instead of this | ||
* function but it stops traversing siblings too. | ||
* | ||
* @param {import('postcss').Container} node | ||
* @param {(node: import('postcss').Container) => boolean} onNode | ||
*/ function traverse(node, onNode) { | ||
if (onNode(node) !== false) { | ||
var _node_each; | ||
(_node_each = node.each) === null || _node_each === void 0 ? void 0 : _node_each.call(node, (child)=>traverse(child, onNode)); | ||
} | ||
} |
@@ -12,7 +12,11 @@ "use strict"; | ||
_export(exports, { | ||
parseColor: ()=>parseColor, | ||
formatColor: ()=>formatColor | ||
parseColor: function() { | ||
return parseColor; | ||
}, | ||
formatColor: function() { | ||
return formatColor; | ||
} | ||
}); | ||
const _colorName = /*#__PURE__*/ _interopRequireDefault(require("color-name")); | ||
function _interopRequireDefault(obj) { | ||
const _colorNames = /*#__PURE__*/ _interop_require_default(require("./colorNames")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -27,5 +31,5 @@ default: obj | ||
let ALPHA_SEP = /\s*[,/]\s*/; | ||
let CUSTOM_PROPERTY = /var\(--(?:[^ )]*?)\)/; | ||
let RGB = new RegExp(`^(rgb)a?\\(\\s*(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`); | ||
let HSL = new RegExp(`^(hsl)a?\\(\\s*((?:${VALUE.source})(?:deg|rad|grad|turn)?|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`); | ||
let CUSTOM_PROPERTY = /var\(--(?:[^ )]*?)(?:,(?:[^ )]*?|var\(--[^ )]*?\)))?\)/; | ||
let RGB = new RegExp(`^(rgba?)\\(\\s*(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`); | ||
let HSL = new RegExp(`^(hsla?)\\(\\s*((?:${VALUE.source})(?:deg|rad|grad|turn)?|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`); | ||
function parseColor(value, { loose =false } = {}) { | ||
@@ -48,6 +52,6 @@ var _match_, _match__toString; | ||
} | ||
if (value in _colorName.default) { | ||
if (value in _colorNames.default) { | ||
return { | ||
mode: "rgb", | ||
color: _colorName.default[value].map((v)=>v.toString()) | ||
color: _colorNames.default[value].map((v)=>v.toString()) | ||
}; | ||
@@ -86,2 +90,13 @@ } | ||
].filter(Boolean).map((v)=>v.toString()); | ||
// rgba(var(--my-color), 0.1) | ||
// hsla(var(--my-color), 0.1) | ||
if (color.length === 2 && color[0].startsWith("var(")) { | ||
return { | ||
mode: match[1], | ||
color: [ | ||
color[0] | ||
], | ||
alpha: color[1] | ||
}; | ||
} | ||
if (!loose && color.length !== 3) { | ||
@@ -101,3 +116,6 @@ return null; | ||
let hasAlpha = alpha !== undefined; | ||
if (mode === "rgba" || mode === "hsla") { | ||
return `${mode}(${color.join(", ")}${hasAlpha ? `, ${alpha}` : ""})`; | ||
} | ||
return `${mode}(${color.join(" ")}${hasAlpha ? ` / ${alpha}` : ""})`; | ||
} |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function _default(pluginConfig, plugins) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function createPlugin(plugin, config) { |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>createUtilityPlugin | ||
get: function() { | ||
return createUtilityPlugin; | ||
} | ||
}); | ||
const _transformThemeValue = /*#__PURE__*/ _interopRequireDefault(require("./transformThemeValue")); | ||
function _interopRequireDefault(obj) { | ||
const _transformThemeValue = /*#__PURE__*/ _interop_require_default(require("./transformThemeValue")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -13,0 +15,0 @@ default: obj |
@@ -12,17 +12,50 @@ "use strict"; | ||
_export(exports, { | ||
normalize: ()=>normalize, | ||
url: ()=>url, | ||
number: ()=>number, | ||
percentage: ()=>percentage, | ||
length: ()=>length, | ||
lineWidth: ()=>lineWidth, | ||
shadow: ()=>shadow, | ||
color: ()=>color, | ||
image: ()=>image, | ||
gradient: ()=>gradient, | ||
position: ()=>position, | ||
familyName: ()=>familyName, | ||
genericName: ()=>genericName, | ||
absoluteSize: ()=>absoluteSize, | ||
relativeSize: ()=>relativeSize | ||
normalize: function() { | ||
return normalize; | ||
}, | ||
normalizeAttributeSelectors: function() { | ||
return normalizeAttributeSelectors; | ||
}, | ||
url: function() { | ||
return url; | ||
}, | ||
number: function() { | ||
return number; | ||
}, | ||
percentage: function() { | ||
return percentage; | ||
}, | ||
length: function() { | ||
return length; | ||
}, | ||
lineWidth: function() { | ||
return lineWidth; | ||
}, | ||
shadow: function() { | ||
return shadow; | ||
}, | ||
color: function() { | ||
return color; | ||
}, | ||
image: function() { | ||
return image; | ||
}, | ||
gradient: function() { | ||
return gradient; | ||
}, | ||
position: function() { | ||
return position; | ||
}, | ||
familyName: function() { | ||
return familyName; | ||
}, | ||
genericName: function() { | ||
return genericName; | ||
}, | ||
absoluteSize: function() { | ||
return absoluteSize; | ||
}, | ||
relativeSize: function() { | ||
return relativeSize; | ||
} | ||
}); | ||
@@ -42,6 +75,32 @@ const _color = require("./color"); | ||
} | ||
const placeholder = "--tw-placeholder"; | ||
const placeholderRe = new RegExp(placeholder, "g"); | ||
function normalize(value, isRoot = true) { | ||
if (value.startsWith("--")) { | ||
// These properties accept a `<dashed-ident>` as one of the values. This means that you can use them | ||
// as: `timeline-scope: --tl;` | ||
// | ||
// Without the `var(--tl)`, in these cases we don't want to normalize the value, and you should add | ||
// the `var()` yourself. | ||
// | ||
// More info: | ||
// - https://drafts.csswg.org/scroll-animations/#propdef-timeline-scope | ||
// - https://developer.mozilla.org/en-US/docs/Web/CSS/timeline-scope#dashed-ident | ||
// - https://www.w3.org/TR/css-anchor-position-1 | ||
// | ||
const AUTO_VAR_INJECTION_EXCEPTIONS = new Set([ | ||
// Concrete properties | ||
"scroll-timeline-name", | ||
"timeline-scope", | ||
"view-timeline-name", | ||
"font-palette", | ||
"anchor-name", | ||
"anchor-scope", | ||
"position-anchor", | ||
"position-try-options", | ||
// Shorthand properties | ||
"scroll-timeline", | ||
"animation-timeline", | ||
"view-timeline", | ||
"position-try" | ||
]); | ||
function normalize(value, context = null, isRoot = true) { | ||
let isVarException = context && AUTO_VAR_INJECTION_EXCEPTIONS.has(context.property); | ||
if (value.startsWith("--") && !isVarException) { | ||
return `var(${value})`; | ||
@@ -55,3 +114,3 @@ } | ||
} | ||
return normalize(part, false); | ||
return normalize(part, context, false); | ||
}).join(""); | ||
@@ -65,13 +124,130 @@ } | ||
} | ||
// Add spaces around operators inside math functions like calc() that do not follow an operator | ||
// or '('. | ||
value = value.replace(/(calc|min|max|clamp)\(.+\)/g, (match)=>{ | ||
let vars = []; | ||
return match.replace(/var\((--.+?)[,)]/g, (match, g1)=>{ | ||
vars.push(g1); | ||
return match.replace(g1, placeholder); | ||
}).replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, "$1 $2 ").replace(placeholderRe, ()=>vars.shift()); | ||
}); | ||
value = normalizeMathOperatorSpacing(value); | ||
return value; | ||
} | ||
function normalizeAttributeSelectors(value) { | ||
// Wrap values in attribute selectors with quotes | ||
if (value.includes("=")) { | ||
value = value.replace(/(=.*)/g, (_fullMatch, match)=>{ | ||
if (match[1] === "'" || match[1] === '"') { | ||
return match; | ||
} | ||
// Handle regex flags on unescaped values | ||
if (match.length > 2) { | ||
let trailingCharacter = match[match.length - 1]; | ||
if (match[match.length - 2] === " " && (trailingCharacter === "i" || trailingCharacter === "I" || trailingCharacter === "s" || trailingCharacter === "S")) { | ||
return `="${match.slice(1, -2)}" ${match[match.length - 1]}`; | ||
} | ||
} | ||
return `="${match.slice(1)}"`; | ||
}); | ||
} | ||
return value; | ||
} | ||
/** | ||
* Add spaces around operators inside math functions | ||
* like calc() that do not follow an operator, '(', or `,`. | ||
* | ||
* @param {string} value | ||
* @returns {string} | ||
*/ function normalizeMathOperatorSpacing(value) { | ||
let preventFormattingInFunctions = [ | ||
"theme" | ||
]; | ||
let preventFormattingKeywords = [ | ||
"min-content", | ||
"max-content", | ||
"fit-content", | ||
// Env | ||
"safe-area-inset-top", | ||
"safe-area-inset-right", | ||
"safe-area-inset-bottom", | ||
"safe-area-inset-left", | ||
"titlebar-area-x", | ||
"titlebar-area-y", | ||
"titlebar-area-width", | ||
"titlebar-area-height", | ||
"keyboard-inset-top", | ||
"keyboard-inset-right", | ||
"keyboard-inset-bottom", | ||
"keyboard-inset-left", | ||
"keyboard-inset-width", | ||
"keyboard-inset-height", | ||
"radial-gradient", | ||
"linear-gradient", | ||
"conic-gradient", | ||
"repeating-radial-gradient", | ||
"repeating-linear-gradient", | ||
"repeating-conic-gradient" | ||
]; | ||
return value.replace(/(calc|min|max|clamp)\(.+\)/g, (match)=>{ | ||
let result = ""; | ||
function lastChar() { | ||
let char = result.trimEnd(); | ||
return char[char.length - 1]; | ||
} | ||
for(let i = 0; i < match.length; i++){ | ||
function peek(word) { | ||
return word.split("").every((char, j)=>match[i + j] === char); | ||
} | ||
function consumeUntil(chars) { | ||
let minIndex = Infinity; | ||
for (let char of chars){ | ||
let index = match.indexOf(char, i); | ||
if (index !== -1 && index < minIndex) { | ||
minIndex = index; | ||
} | ||
} | ||
let result = match.slice(i, minIndex); | ||
i += result.length - 1; | ||
return result; | ||
} | ||
let char = match[i]; | ||
// Handle `var(--variable)` | ||
if (peek("var")) { | ||
// When we consume until `)`, then we are dealing with this scenario: | ||
// `var(--example)` | ||
// | ||
// When we consume until `,`, then we are dealing with this scenario: | ||
// `var(--example, 1rem)` | ||
// | ||
// In this case we do want to "format", the default value as well | ||
result += consumeUntil([ | ||
")", | ||
"," | ||
]); | ||
} else if (preventFormattingKeywords.some((keyword)=>peek(keyword))) { | ||
let keyword = preventFormattingKeywords.find((keyword)=>peek(keyword)); | ||
result += keyword; | ||
i += keyword.length - 1; | ||
} else if (preventFormattingInFunctions.some((fn)=>peek(fn))) { | ||
result += consumeUntil([ | ||
")" | ||
]); | ||
} else if (peek("[")) { | ||
result += consumeUntil([ | ||
"]" | ||
]); | ||
} else if ([ | ||
"+", | ||
"-", | ||
"*", | ||
"/" | ||
].includes(char) && ![ | ||
"(", | ||
"+", | ||
"-", | ||
"*", | ||
"/", | ||
"," | ||
].includes(lastChar())) { | ||
result += ` ${char} `; | ||
} else { | ||
result += char; | ||
} | ||
} | ||
// Simplify multiple spaces | ||
return result.replace(/\s+/g, " "); | ||
}); | ||
} | ||
function url(value) { | ||
@@ -176,7 +352,8 @@ return value.startsWith("url("); | ||
let gradientTypes = new Set([ | ||
"conic-gradient", | ||
"linear-gradient", | ||
"radial-gradient", | ||
"repeating-conic-gradient", | ||
"repeating-linear-gradient", | ||
"repeating-radial-gradient", | ||
"conic-gradient" | ||
"repeating-radial-gradient" | ||
]); | ||
@@ -259,3 +436,3 @@ function gradient(value) { | ||
"x-large", | ||
"x-large", | ||
"xx-large", | ||
"xxx-large" | ||
@@ -262,0 +439,0 @@ ]); |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>defaults | ||
get: function() { | ||
return defaults; | ||
} | ||
}); | ||
@@ -18,6 +20,6 @@ function defaults(target, ...sources) { | ||
} | ||
for (let k1 of Object.getOwnPropertySymbols(source)){ | ||
for (let k of Object.getOwnPropertySymbols(source)){ | ||
var _target_hasOwnProperty1; | ||
if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty1 = target.hasOwnProperty) === null || _target_hasOwnProperty1 === void 0 ? void 0 : _target_hasOwnProperty1.call(target, k1))) { | ||
target[k1] = source[k1]; | ||
if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty1 = target.hasOwnProperty) === null || _target_hasOwnProperty1 === void 0 ? void 0 : _target_hasOwnProperty1.call(target, k))) { | ||
target[k] = source[k]; | ||
} | ||
@@ -24,0 +26,0 @@ } |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>escapeClassName | ||
get: function() { | ||
return escapeClassName; | ||
} | ||
}); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _escapeCommas = /*#__PURE__*/ _interopRequireDefault(require("./escapeCommas")); | ||
function _interopRequireDefault(obj) { | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -19,3 +21,3 @@ default: obj | ||
var _node_raws; | ||
let node = _postcssSelectorParser.default.className(); | ||
let node = _postcssselectorparser.default.className(); | ||
node.value = className; | ||
@@ -22,0 +24,0 @@ var _node_raws_value; |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>escapeCommas | ||
get: function() { | ||
return escapeCommas; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function escapeCommas(className) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ 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])=>({ |
@@ -12,11 +12,22 @@ "use strict"; | ||
_export(exports, { | ||
formatVariantSelector: ()=>formatVariantSelector, | ||
finalizeSelector: ()=>finalizeSelector, | ||
handleMergePseudo: ()=>handleMergePseudo | ||
formatVariantSelector: function() { | ||
return formatVariantSelector; | ||
}, | ||
eliminateIrrelevantSelectors: function() { | ||
return eliminateIrrelevantSelectors; | ||
}, | ||
finalizeSelector: function() { | ||
return finalizeSelector; | ||
}, | ||
handleMergePseudo: function() { | ||
return handleMergePseudo; | ||
} | ||
}); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _unesc = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser/dist/util/unesc")); | ||
const _escapeClassName = /*#__PURE__*/ _interopRequireDefault(require("../util/escapeClassName")); | ||
const _prefixSelector = /*#__PURE__*/ _interopRequireDefault(require("../util/prefixSelector")); | ||
function _interopRequireDefault(obj) { | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
const _unesc = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser/dist/util/unesc")); | ||
const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("../util/escapeClassName")); | ||
const _prefixSelector = /*#__PURE__*/ _interop_require_default(require("../util/prefixSelector")); | ||
const _pseudoElements = require("./pseudoElements"); | ||
const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -26,3 +37,3 @@ default: obj | ||
} | ||
/** @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"; | ||
/** @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, respectPrefix: boolean}[]} RawFormats */ /** @typedef {import('postcss-selector-parser').Root} ParsedFormats */ /** @typedef {RawFormats | ParsedFormats} AcceptedFormats */ let MERGE = ":merge"; | ||
function formatVariantSelector(formats, { context , candidate }) { | ||
@@ -33,14 +44,14 @@ var _context_tailwindConfig_prefix; | ||
let parsedFormats = formats.map((format)=>{ | ||
let ast = (0, _postcssSelectorParser.default)().astSync(format.format); | ||
let ast = (0, _postcssselectorparser.default)().astSync(format.format); | ||
return { | ||
...format, | ||
ast: format.isArbitraryVariant ? ast : (0, _prefixSelector.default)(prefix, ast) | ||
ast: format.respectPrefix ? (0, _prefixSelector.default)(prefix, ast) : ast | ||
}; | ||
}); | ||
// We start with the candidate selector | ||
let formatAst = _postcssSelectorParser.default.root({ | ||
let formatAst = _postcssselectorparser.default.root({ | ||
nodes: [ | ||
_postcssSelectorParser.default.selector({ | ||
_postcssselectorparser.default.selector({ | ||
nodes: [ | ||
_postcssSelectorParser.default.className({ | ||
_postcssselectorparser.default.className({ | ||
value: (0, _escapeClassName.default)(candidate) | ||
@@ -104,14 +115,3 @@ }) | ||
} | ||
/** | ||
* Remove extraneous selectors that do not include the base class/candidate | ||
* | ||
* Example: | ||
* Given the utility `.a, .b { color: red}` | ||
* Given the candidate `sm:b` | ||
* | ||
* The final selector should be `.sm\:b` and not `.a, .sm\:b` | ||
* | ||
* @param {Selector} ast | ||
* @param {string} base | ||
*/ function eliminateIrrelevantSelectors(sel, base) { | ||
function eliminateIrrelevantSelectors(sel, base) { | ||
let hasClassesMatchingCandidate = false; | ||
@@ -146,5 +146,5 @@ sel.walk((child)=>{ | ||
// | ||
base = base !== null && base !== void 0 ? base : candidate.split(new RegExp(`\\${separator}(?![^[]*\\])`)).pop(); | ||
base = base !== null && base !== void 0 ? base : (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(candidate, separator).pop(); | ||
// Parse the selector into an AST | ||
let selector = (0, _postcssSelectorParser.default)().astSync(current); | ||
let selector = (0, _postcssselectorparser.default)().astSync(current); | ||
// Normalize escaped classes, e.g.: | ||
@@ -168,2 +168,8 @@ // | ||
selector.each((sel)=>eliminateIrrelevantSelectors(sel, base)); | ||
// If ffter eliminating irrelevant selectors, we end up with nothing | ||
// Then the whole "rule" this is associated with does not need to exist | ||
// We use `null` as a marker value for that case | ||
if (selector.length === 0) { | ||
return null; | ||
} | ||
// If there are no formats that means there were no variants added to the candidate | ||
@@ -178,6 +184,6 @@ // so we can just return the selector as-is | ||
} | ||
let simpleStart = _postcssSelectorParser.default.comment({ | ||
let simpleStart = _postcssselectorparser.default.comment({ | ||
value: "/*__simple__*/" | ||
}); | ||
let simpleEnd = _postcssSelectorParser.default.comment({ | ||
let simpleEnd = _postcssselectorparser.default.comment({ | ||
value: "/*__simple__*/" | ||
@@ -202,3 +208,3 @@ }); | ||
for (let child of formatNodes){ | ||
parent.insertBefore(simpleSelector[0], child); | ||
parent.insertBefore(simpleSelector[0], child.clone()); | ||
} | ||
@@ -209,3 +215,3 @@ node.remove(); | ||
let firstNode = parent.index(simpleStart); | ||
parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(_postcssSelectorParser.default.selector({ | ||
parent.nodes.splice(firstNode, simpleSelector.length, ...resortSelector(_postcssselectorparser.default.selector({ | ||
nodes: simpleSelector | ||
@@ -223,8 +229,3 @@ })).nodes); | ||
// Move pseudo elements to the end of the selector (if necessary) | ||
selector.each((sel)=>{ | ||
let pseudoElements = collectPseudoElements(sel); | ||
if (pseudoElements.length > 0) { | ||
sel.nodes.push(pseudoElements.sort(sortSelector)); | ||
} | ||
}); | ||
selector.each((sel)=>(0, _pseudoElements.movePseudos)(sel)); | ||
return selector.toString(); | ||
@@ -263,3 +264,3 @@ } | ||
let combinator = next; | ||
existing.pseudo.parent.insertAfter(existing.pseudo, _postcssSelectorParser.default.selector({ | ||
existing.pseudo.parent.insertAfter(existing.pseudo, _postcssselectorparser.default.selector({ | ||
nodes: attachments.map((node)=>node.clone()) | ||
@@ -281,83 +282,1 @@ })); | ||
} | ||
// Note: As a rule, double colons (::) should be used instead of a single colon | ||
// (:). This distinguishes pseudo-classes from pseudo-elements. However, since | ||
// this distinction was not present in older versions of the W3C spec, most | ||
// browsers support both syntaxes for the original pseudo-elements. | ||
let pseudoElementsBC = [ | ||
":before", | ||
":after", | ||
":first-line", | ||
":first-letter" | ||
]; | ||
// These pseudo-elements _can_ be combined with other pseudo selectors AND the order does matter. | ||
let pseudoElementExceptions = [ | ||
"::file-selector-button", | ||
// Webkit scroll bar pseudo elements can be combined with user-action pseudo classes | ||
"::-webkit-scrollbar", | ||
"::-webkit-scrollbar-button", | ||
"::-webkit-scrollbar-thumb", | ||
"::-webkit-scrollbar-track", | ||
"::-webkit-scrollbar-track-piece", | ||
"::-webkit-scrollbar-corner", | ||
"::-webkit-resizer" | ||
]; | ||
/** | ||
* This will make sure to move pseudo's to the correct spot (the end for | ||
* pseudo elements) because otherwise the selector will never work | ||
* anyway. | ||
* | ||
* E.g.: | ||
* - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before` | ||
* - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before` | ||
* | ||
* `::before:hover` doesn't work, which means that we can make it work for you by flipping the order. | ||
* | ||
* @param {Selector} selector | ||
**/ function collectPseudoElements(selector) { | ||
/** @type {Node[]} */ let nodes = []; | ||
for (let node of selector.nodes){ | ||
if (isPseudoElement(node)) { | ||
nodes.push(node); | ||
selector.removeChild(node); | ||
} | ||
if (node === null || node === void 0 ? void 0 : node.nodes) { | ||
nodes.push(...collectPseudoElements(node)); | ||
} | ||
} | ||
return nodes; | ||
} | ||
// This will make sure to move pseudo's to the correct spot (the end for | ||
// pseudo elements) because otherwise the selector will never work | ||
// anyway. | ||
// | ||
// E.g.: | ||
// - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before` | ||
// - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before` | ||
// | ||
// `::before:hover` doesn't work, which means that we can make it work | ||
// for you by flipping the order. | ||
function sortSelector(a, z) { | ||
// Both nodes are non-pseudo's so we can safely ignore them and keep | ||
// them in the same order. | ||
if (a.type !== "pseudo" && z.type !== "pseudo") { | ||
return 0; | ||
} | ||
// If one of them is a combinator, we need to keep it in the same order | ||
// because that means it will start a new "section" in the selector. | ||
if (a.type === "combinator" ^ z.type === "combinator") { | ||
return 0; | ||
} | ||
// One of the items is a pseudo and the other one isn't. Let's move | ||
// the pseudo to the right. | ||
if (a.type === "pseudo" ^ z.type === "pseudo") { | ||
return (a.type === "pseudo") - (z.type === "pseudo"); | ||
} | ||
// Both are pseudo's, move the pseudo elements (except for | ||
// ::file-selector-button) to the right. | ||
return isPseudoElement(a) - isPseudoElement(z); | ||
} | ||
function isPseudoElement(node) { | ||
if (node.type !== "pseudo") return false; | ||
if (pseudoElementExceptions.includes(node.value)) return false; | ||
return node.value.startsWith("::") || pseudoElementsBC.includes(node.value); | ||
} |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>getAllConfigs | ||
get: function() { | ||
return getAllConfigs; | ||
} | ||
}); | ||
const _defaultConfigStubJs = /*#__PURE__*/ _interopRequireDefault(require("../../stubs/defaultConfig.stub.js")); | ||
const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full.js")); | ||
const _featureFlags = require("../featureFlags"); | ||
function _interopRequireDefault(obj) { | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -20,3 +22,3 @@ default: obj | ||
const configs = ((_config_presets = config === null || config === void 0 ? void 0 : config.presets) !== null && _config_presets !== void 0 ? _config_presets : [ | ||
_defaultConfigStubJs.default | ||
_configfull.default | ||
]).slice().reverse().flatMap((preset)=>getAllConfigs(preset instanceof Function ? preset() : preset)); | ||
@@ -23,0 +25,0 @@ const features = { |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>hashConfig | ||
get: function() { | ||
return hashConfig; | ||
} | ||
}); | ||
const _objectHash = /*#__PURE__*/ _interopRequireDefault(require("object-hash")); | ||
function _interopRequireDefault(obj) { | ||
const _objecthash = /*#__PURE__*/ _interop_require_default(require("object-hash")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -17,5 +19,5 @@ default: obj | ||
function hashConfig(config) { | ||
return (0, _objectHash.default)(config, { | ||
return (0, _objecthash.default)(config, { | ||
ignoreUnknown: true | ||
}); | ||
} |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>isKeyframeRule | ||
get: function() { | ||
return isKeyframeRule; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function isKeyframeRule(rule) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>isPlainObject | ||
get: function() { | ||
return isPlainObject; | ||
} | ||
}); | ||
@@ -15,3 +17,3 @@ function isPlainObject(value) { | ||
const prototype = Object.getPrototypeOf(value); | ||
return prototype === null || prototype === Object.prototype; | ||
return prototype === null || Object.getPrototypeOf(prototype) === null; | ||
} |
@@ -13,3 +13,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>isSyntacticallyValidPropertyValue | ||
get: function() { | ||
return isSyntacticallyValidPropertyValue; | ||
} | ||
}); | ||
@@ -16,0 +18,0 @@ let matchingBrackets = new Map([ |
@@ -12,7 +12,11 @@ "use strict"; | ||
_export(exports, { | ||
dim: ()=>dim, | ||
default: ()=>_default | ||
dim: function() { | ||
return dim; | ||
}, | ||
default: function() { | ||
return _default; | ||
} | ||
}); | ||
const _picocolors = /*#__PURE__*/ _interopRequireDefault(require("picocolors")); | ||
function _interopRequireDefault(obj) { | ||
const _picocolors = /*#__PURE__*/ _interop_require_default(require("picocolors")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -19,0 +23,0 @@ default: obj |
@@ -12,9 +12,15 @@ "use strict"; | ||
_export(exports, { | ||
asClass: ()=>asClass, | ||
default: ()=>nameClass, | ||
formatClass: ()=>formatClass | ||
asClass: function() { | ||
return asClass; | ||
}, | ||
default: function() { | ||
return nameClass; | ||
}, | ||
formatClass: function() { | ||
return formatClass; | ||
} | ||
}); | ||
const _escapeClassName = /*#__PURE__*/ _interopRequireDefault(require("./escapeClassName")); | ||
const _escapeCommas = /*#__PURE__*/ _interopRequireDefault(require("./escapeCommas")); | ||
function _interopRequireDefault(obj) { | ||
const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("./escapeClassName")); | ||
const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -21,0 +27,0 @@ default: obj |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>negateValue | ||
get: function() { | ||
return negateValue; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function negateValue(value) { |
@@ -7,5 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>normalizeConfig | ||
get: function() { | ||
return normalizeConfig; | ||
} | ||
}); | ||
const _log = /*#__PURE__*/ _interopRequireWildcard(require("./log")); | ||
const _featureFlags = require("../featureFlags"); | ||
const _log = /*#__PURE__*/ _interop_require_wildcard(require("./log")); | ||
function _getRequireWildcardCache(nodeInterop) { | ||
@@ -19,3 +22,3 @@ if (typeof WeakMap !== "function") return null; | ||
} | ||
function _interopRequireWildcard(obj, nodeInterop) { | ||
function _interop_require_wildcard(obj, nodeInterop) { | ||
if (!nodeInterop && obj && obj.__esModule) { | ||
@@ -133,4 +136,4 @@ return obj; | ||
if (typeof config.content.transform === "object") { | ||
for (let value1 of Object.values(config.content.transform)){ | ||
if (typeof value1 !== "function") { | ||
for (let value of Object.values(config.content.transform)){ | ||
if (typeof value !== "function") { | ||
return false; | ||
@@ -197,3 +200,2 @@ } | ||
relative: (()=>{ | ||
var _config_future; | ||
let { content } = config; | ||
@@ -203,4 +205,3 @@ if (content === null || content === void 0 ? void 0 : content.relative) { | ||
} | ||
var _config_future_relativeContentPathsByDefault; | ||
return (_config_future_relativeContentPathsByDefault = (_config_future = config.future) === null || _config_future === void 0 ? void 0 : _config_future.relativeContentPathsByDefault) !== null && _config_future_relativeContentPathsByDefault !== void 0 ? _config_future_relativeContentPathsByDefault : false; | ||
return (0, _featureFlags.flagEnabled)(config, "relativeContentPathsByDefault"); | ||
})(), | ||
@@ -267,4 +268,3 @@ files: (()=>{ | ||
transformers.DEFAULT = transform; | ||
} | ||
if (typeof transform === "object" && transform !== null) { | ||
} else if (typeof transform === "object" && transform !== null) { | ||
Object.assign(transformers, transform); | ||
@@ -271,0 +271,0 @@ } |
@@ -36,6 +36,14 @@ /** | ||
_export(exports, { | ||
normalizeScreens: ()=>normalizeScreens, | ||
isScreenSortable: ()=>isScreenSortable, | ||
compareScreens: ()=>compareScreens, | ||
toScreen: ()=>toScreen | ||
normalizeScreens: function() { | ||
return normalizeScreens; | ||
}, | ||
isScreenSortable: function() { | ||
return isScreenSortable; | ||
}, | ||
compareScreens: function() { | ||
return compareScreens; | ||
}, | ||
toScreen: function() { | ||
return toScreen; | ||
} | ||
}); | ||
@@ -42,0 +50,0 @@ function normalizeScreens(screens, root = true) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>parseAnimationValue | ||
get: function() { | ||
return parseAnimationValue; | ||
} | ||
}); | ||
@@ -42,3 +44,3 @@ const DIRECTIONS = new Set([ | ||
]; | ||
const COMMA = /\,(?![^(]*\))/g // Comma separator that is not located between brackets. E.g.: `cubiz-bezier(a, b, c)` these don't count. | ||
const COMMA = /\,(?![^(]*\))/g // Comma separator that is not located between brackets. E.g.: `cubic-bezier(a, b, c)` these don't count. | ||
; | ||
@@ -45,0 +47,0 @@ const SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces instead. |
@@ -12,4 +12,8 @@ "use strict"; | ||
_export(exports, { | ||
parseBoxShadowValue: ()=>parseBoxShadowValue, | ||
formatBoxShadowValue: ()=>formatBoxShadowValue | ||
parseBoxShadowValue: function() { | ||
return parseBoxShadowValue; | ||
}, | ||
formatBoxShadowValue: function() { | ||
return formatBoxShadowValue; | ||
} | ||
}); | ||
@@ -16,0 +20,0 @@ const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly"); |
@@ -14,3 +14,5 @@ // @ts-check | ||
enumerable: true, | ||
get: ()=>parseDependency | ||
get: function() { | ||
return parseDependency; | ||
} | ||
}); | ||
@@ -17,0 +19,0 @@ function parseDependency(contentPath) { |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>parseGlob | ||
get: function() { | ||
return parseGlob; | ||
} | ||
}); | ||
const _globParent = /*#__PURE__*/ _interopRequireDefault(require("glob-parent")); | ||
function _interopRequireDefault(obj) { | ||
const _globparent = /*#__PURE__*/ _interop_require_default(require("glob-parent")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -18,3 +20,3 @@ default: obj | ||
let glob = pattern; | ||
let base = (0, _globParent.default)(pattern); | ||
let base = (0, _globparent.default)(pattern); | ||
if (base !== ".") { | ||
@@ -28,4 +30,3 @@ glob = pattern.substr(base.length); | ||
glob = glob.substr(2); | ||
} | ||
if (glob.charAt(0) === "/") { | ||
} else if (glob.charAt(0) === "/") { | ||
glob = glob.substr(1); | ||
@@ -32,0 +33,0 @@ } |
@@ -7,8 +7,10 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>parseObjectStyles | ||
get: function() { | ||
return parseObjectStyles; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _postcssNested = /*#__PURE__*/ _interopRequireDefault(require("postcss-nested")); | ||
const _postcssJs = /*#__PURE__*/ _interopRequireDefault(require("postcss-js")); | ||
function _interopRequireDefault(obj) { | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _postcssnested = /*#__PURE__*/ _interop_require_default(require("postcss-nested")); | ||
const _postcssjs = /*#__PURE__*/ _interop_require_default(require("postcss-js")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -26,3 +28,3 @@ default: obj | ||
return (0, _postcss.default)([ | ||
(0, _postcssNested.default)({ | ||
(0, _postcssnested.default)({ | ||
bubble: [ | ||
@@ -33,5 +35,5 @@ "screen" | ||
]).process(style, { | ||
parser: _postcssJs.default | ||
parser: _postcssjs.default | ||
}).root.nodes; | ||
}); | ||
} |
@@ -12,20 +12,34 @@ "use strict"; | ||
_export(exports, { | ||
updateAllClasses: ()=>updateAllClasses, | ||
filterSelectorsForClass: ()=>filterSelectorsForClass, | ||
asValue: ()=>asValue, | ||
parseColorFormat: ()=>parseColorFormat, | ||
asColor: ()=>asColor, | ||
asLookupValue: ()=>asLookupValue, | ||
typeMap: ()=>typeMap, | ||
coerceValue: ()=>coerceValue, | ||
getMatchingTypes: ()=>getMatchingTypes | ||
updateAllClasses: function() { | ||
return updateAllClasses; | ||
}, | ||
asValue: function() { | ||
return asValue; | ||
}, | ||
parseColorFormat: function() { | ||
return parseColorFormat; | ||
}, | ||
asColor: function() { | ||
return asColor; | ||
}, | ||
asLookupValue: function() { | ||
return asLookupValue; | ||
}, | ||
typeMap: function() { | ||
return typeMap; | ||
}, | ||
coerceValue: function() { | ||
return coerceValue; | ||
}, | ||
getMatchingTypes: function() { | ||
return getMatchingTypes; | ||
} | ||
}); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
const _escapeCommas = /*#__PURE__*/ _interopRequireDefault(require("./escapeCommas")); | ||
const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas")); | ||
const _withAlphaVariable = require("./withAlphaVariable"); | ||
const _dataTypes = require("./dataTypes"); | ||
const _negateValue = /*#__PURE__*/ _interopRequireDefault(require("./negateValue")); | ||
const _negateValue = /*#__PURE__*/ _interop_require_default(require("./negateValue")); | ||
const _validateFormalSyntax = require("./validateFormalSyntax"); | ||
const _featureFlagsJs = require("../featureFlags.js"); | ||
function _interopRequireDefault(obj) { | ||
const _featureFlags = require("../featureFlags.js"); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -36,26 +50,9 @@ default: obj | ||
function updateAllClasses(selectors, updateClass) { | ||
let parser = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
selectors.walkClasses((sel)=>{ | ||
let updatedClass = updateClass(sel.value); | ||
sel.value = updatedClass; | ||
if (sel.raws && sel.raws.value) { | ||
sel.raws.value = (0, _escapeCommas.default)(sel.raws.value); | ||
} | ||
}); | ||
selectors.walkClasses((sel)=>{ | ||
sel.value = updateClass(sel.value); | ||
if (sel.raws && sel.raws.value) { | ||
sel.raws.value = (0, _escapeCommas.default)(sel.raws.value); | ||
} | ||
}); | ||
let result = parser.processSync(selectors); | ||
return result; | ||
} | ||
function filterSelectorsForClass(selectors, classCandidate) { | ||
let parser = (0, _postcssSelectorParser.default)((selectors)=>{ | ||
selectors.each((sel)=>{ | ||
const containsClass = sel.nodes.some((node)=>node.type === "class" && node.value === classCandidate); | ||
if (!containsClass) { | ||
sel.remove(); | ||
} | ||
}); | ||
}); | ||
let result = parser.processSync(selectors); | ||
return result; | ||
} | ||
function resolveArbitraryValue(modifier, validate) { | ||
@@ -100,2 +97,15 @@ if (!isArbitraryValue(modifier)) { | ||
let slashIdx = modifier.lastIndexOf("/"); | ||
// If the `/` is inside an arbitrary, we want to find the previous one if any | ||
// This logic probably isn't perfect but it should work for most cases | ||
let arbitraryStartIdx = modifier.lastIndexOf("[", slashIdx); | ||
let arbitraryEndIdx = modifier.indexOf("]", slashIdx); | ||
let isNextToArbitrary = modifier[slashIdx - 1] === "]" || modifier[slashIdx + 1] === "["; | ||
// Backtrack to the previous `/` if the one we found was inside an arbitrary | ||
if (!isNextToArbitrary) { | ||
if (arbitraryStartIdx !== -1 && arbitraryEndIdx !== -1) { | ||
if (arbitraryStartIdx < slashIdx && slashIdx < arbitraryEndIdx) { | ||
slashIdx = modifier.lastIndexOf("/", arbitraryStartIdx); | ||
} | ||
} | ||
} | ||
if (slashIdx === -1 || slashIdx === modifier.length - 1) { | ||
@@ -125,3 +135,3 @@ return [ | ||
let oldValue = value; | ||
return ({ opacityValue =1 })=>oldValue.replace("<alpha-value>", opacityValue); | ||
return ({ opacityValue =1 })=>oldValue.replace(/<alpha-value>/g, opacityValue); | ||
} | ||
@@ -131,7 +141,3 @@ return value; | ||
function unwrapArbitraryModifier(modifier) { | ||
modifier = modifier.slice(1, -1); | ||
if (modifier.startsWith("--")) { | ||
modifier = `var(${modifier})`; | ||
} | ||
return modifier; | ||
return (0, _dataTypes.normalize)(modifier.slice(1, -1)); | ||
} | ||
@@ -251,3 +257,3 @@ function asColor(modifier, options = {}, { tailwindConfig ={} } = {}) { | ||
function* getMatchingTypes(types, rawModifier, options, tailwindConfig) { | ||
let modifiersEnabled = (0, _featureFlagsJs.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let modifiersEnabled = (0, _featureFlags.flagEnabled)(tailwindConfig, "generalizedModifiers"); | ||
let [modifier, utilityModifier] = splitUtilityModifier(rawModifier); | ||
@@ -254,0 +260,0 @@ let canUseUtilityModifier = modifiersEnabled && options.modifiers != null && (options.modifiers === "any" || typeof options.modifiers === "object" && (utilityModifier && isArbitraryValue(utilityModifier) || utilityModifier in options.modifiers)); |
@@ -18,6 +18,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>_default | ||
get: function() { | ||
return _default; | ||
} | ||
}); | ||
const _postcssSelectorParser = /*#__PURE__*/ _interopRequireDefault(require("postcss-selector-parser")); | ||
function _interopRequireDefault(obj) { | ||
const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -31,3 +33,3 @@ default: obj | ||
} | ||
let ast = typeof selector === "string" ? (0, _postcssSelectorParser.default)().astSync(selector) : selector; | ||
/** @type {import('postcss-selector-parser').Root} */ let ast = typeof selector === "string" ? (0, _postcssselectorparser.default)().astSync(selector) : selector; | ||
ast.walkClasses((classSelector)=>{ | ||
@@ -34,0 +36,0 @@ let baseClass = classSelector.value; |
@@ -15,3 +15,5 @@ /** | ||
enumerable: true, | ||
get: ()=>removeAlphaVariables | ||
get: function() { | ||
return removeAlphaVariables; | ||
} | ||
}); | ||
@@ -18,0 +20,0 @@ function removeAlphaVariables(container, toRemove) { |
@@ -7,17 +7,19 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>resolveConfig | ||
get: function() { | ||
return resolveConfig; | ||
} | ||
}); | ||
const _negateValue = /*#__PURE__*/ _interopRequireDefault(require("./negateValue")); | ||
const _corePluginList = /*#__PURE__*/ _interopRequireDefault(require("../corePluginList")); | ||
const _configurePlugins = /*#__PURE__*/ _interopRequireDefault(require("./configurePlugins")); | ||
const _colors = /*#__PURE__*/ _interopRequireDefault(require("../public/colors")); | ||
const _negateValue = /*#__PURE__*/ _interop_require_default(require("./negateValue")); | ||
const _corePluginList = /*#__PURE__*/ _interop_require_default(require("../corePluginList")); | ||
const _configurePlugins = /*#__PURE__*/ _interop_require_default(require("./configurePlugins")); | ||
const _colors = /*#__PURE__*/ _interop_require_default(require("../public/colors")); | ||
const _defaults = require("./defaults"); | ||
const _toPath = require("./toPath"); | ||
const _normalizeConfig = require("./normalizeConfig"); | ||
const _isPlainObject = /*#__PURE__*/ _interopRequireDefault(require("./isPlainObject")); | ||
const _isPlainObject = /*#__PURE__*/ _interop_require_default(require("./isPlainObject")); | ||
const _cloneDeep = require("./cloneDeep"); | ||
const _pluginUtils = require("./pluginUtils"); | ||
const _withAlphaVariable = require("./withAlphaVariable"); | ||
const _toColorValue = /*#__PURE__*/ _interopRequireDefault(require("./toColorValue")); | ||
function _interopRequireDefault(obj) { | ||
const _toColorValue = /*#__PURE__*/ _interop_require_default(require("./toColorValue")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -24,0 +26,0 @@ default: obj |
@@ -5,9 +5,19 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "default", { | ||
enumerable: true, | ||
get: ()=>resolveConfigPath | ||
function _export(target, all) { | ||
for(var name in all)Object.defineProperty(target, name, { | ||
enumerable: true, | ||
get: all[name] | ||
}); | ||
} | ||
_export(exports, { | ||
default: function() { | ||
return resolveConfigPath; | ||
}, | ||
resolveDefaultConfigPath: function() { | ||
return resolveDefaultConfigPath; | ||
} | ||
}); | ||
const _fs = /*#__PURE__*/ _interopRequireDefault(require("fs")); | ||
const _path = /*#__PURE__*/ _interopRequireDefault(require("path")); | ||
function _interopRequireDefault(obj) { | ||
const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
const _path = /*#__PURE__*/ _interop_require_default(require("path")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -17,2 +27,10 @@ default: obj | ||
} | ||
const defaultConfigFiles = [ | ||
"./tailwind.config.js", | ||
"./tailwind.config.cjs", | ||
"./tailwind.config.mjs", | ||
"./tailwind.config.ts", | ||
"./tailwind.config.cts", | ||
"./tailwind.config.mts" | ||
]; | ||
function isObject(value) { | ||
@@ -45,6 +63,6 @@ return typeof value === "object" && value !== null; | ||
// require('tailwindcss') | ||
for (const configFile of [ | ||
"./tailwind.config.js", | ||
"./tailwind.config.cjs" | ||
]){ | ||
return resolveDefaultConfigPath(); | ||
} | ||
function resolveDefaultConfigPath() { | ||
for (const configFile of defaultConfigFiles){ | ||
try { | ||
@@ -51,0 +69,0 @@ const configPath = _path.default.resolve(configFile); |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>responsive | ||
get: function() { | ||
return responsive; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _cloneNodes = /*#__PURE__*/ _interopRequireDefault(require("./cloneNodes")); | ||
function _interopRequireDefault(obj) { | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _cloneNodes = /*#__PURE__*/ _interop_require_default(require("./cloneNodes")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -14,0 +16,0 @@ default: obj |
@@ -21,3 +21,5 @@ /** | ||
enumerable: true, | ||
get: ()=>splitAtTopLevelOnly | ||
get: function() { | ||
return splitAtTopLevelOnly; | ||
} | ||
}); | ||
@@ -28,5 +30,6 @@ function splitAtTopLevelOnly(input, separator) { | ||
let lastPos = 0; | ||
let isEscaped = false; | ||
for(let idx = 0; idx < input.length; idx++){ | ||
let char = input[idx]; | ||
if (stack.length === 0 && char === separator[0]) { | ||
if (stack.length === 0 && char === separator[0] && !isEscaped) { | ||
if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) { | ||
@@ -37,2 +40,3 @@ parts.push(input.slice(lastPos, idx)); | ||
} | ||
isEscaped = isEscaped ? false : char === "\\"; | ||
if (char === "(" || char === "[" || char === "{") { | ||
@@ -39,0 +43,0 @@ stack.push(char); |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>tap | ||
get: function() { | ||
return tap; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function tap(value, mutator) { |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>toColorValue | ||
get: function() { | ||
return toColorValue; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ function toColorValue(maybeFunction) { |
@@ -20,3 +20,5 @@ /** | ||
enumerable: true, | ||
get: ()=>toPath | ||
get: function() { | ||
return toPath; | ||
} | ||
}); | ||
@@ -23,0 +25,0 @@ function toPath(path) { |
@@ -7,7 +7,9 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>transformThemeValue | ||
get: function() { | ||
return transformThemeValue; | ||
} | ||
}); | ||
const _postcss = /*#__PURE__*/ _interopRequireDefault(require("postcss")); | ||
const _isPlainObject = /*#__PURE__*/ _interopRequireDefault(require("./isPlainObject")); | ||
function _interopRequireDefault(obj) { | ||
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); | ||
const _isPlainObject = /*#__PURE__*/ _interop_require_default(require("./isPlainObject")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -14,0 +16,0 @@ default: obj |
@@ -7,6 +7,8 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>validateConfig | ||
get: function() { | ||
return validateConfig; | ||
} | ||
}); | ||
const _log = /*#__PURE__*/ _interopRequireDefault(require("./log")); | ||
function _interopRequireDefault(obj) { | ||
const _log = /*#__PURE__*/ _interop_require_default(require("./log")); | ||
function _interop_require_default(obj) { | ||
return obj && obj.__esModule ? obj : { | ||
@@ -24,3 +26,14 @@ default: obj | ||
} | ||
// Warn if the line-clamp plugin is installed | ||
try { | ||
let plugin = require("@tailwindcss/line-clamp"); | ||
if (config.plugins.includes(plugin)) { | ||
_log.default.warn("line-clamp-in-core", [ | ||
"As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.", | ||
"Remove it from the `plugins` array in your configuration to eliminate this warning." | ||
]); | ||
config.plugins = config.plugins.filter((p)=>p !== plugin); | ||
} | ||
} catch {} | ||
return config; | ||
} |
@@ -7,3 +7,5 @@ "use strict"; | ||
enumerable: true, | ||
get: ()=>backgroundSize | ||
get: function() { | ||
return backgroundSize; | ||
} | ||
}); | ||
@@ -10,0 +12,0 @@ const _dataTypes = require("./dataTypes"); |
@@ -12,4 +12,8 @@ "use strict"; | ||
_export(exports, { | ||
withAlphaValue: ()=>withAlphaValue, | ||
default: ()=>withAlphaVariable | ||
withAlphaValue: function() { | ||
return withAlphaValue; | ||
}, | ||
default: function() { | ||
return withAlphaVariable; | ||
} | ||
}); | ||
@@ -16,0 +20,0 @@ const _color = require("./color"); |
{ | ||
"name": "tailwindcss", | ||
"version": "0.0.0-insiders.1454190", | ||
"version": "0.0.0-insiders.1676118", | ||
"description": "A utility-first CSS framework for rapidly building custom user interfaces.", | ||
@@ -15,6 +15,2 @@ "license": "MIT", | ||
}, | ||
"workspaces": [ | ||
"integrations/*", | ||
"oxide/crates/node" | ||
], | ||
"scripts": { | ||
@@ -27,3 +23,3 @@ "prebuild": "npm run generate && rimraf lib", | ||
"pretest": "npm run generate", | ||
"test": "jest && OXIDE=1 jest", | ||
"test": "jest", | ||
"test:integrations": "npm run test --prefix ./integrations", | ||
@@ -36,5 +32,2 @@ "install:integrations": "node scripts/install-integrations.js", | ||
"release-notes": "node ./scripts/release-notes.js", | ||
"oxide:install": "npm run install:all --prefix ./oxide", | ||
"oxide:dev": "concurrently -n tailwind,oxide-node -c green,yellow 'npm run build -- --watch' 'npm run --prefix ./oxide dev:node'", | ||
"oxide:build": "npm run --prefix ./oxide build:node && npm run build", | ||
"prepublishOnly": "npm install --force && npm run build" | ||
@@ -48,6 +41,5 @@ }, | ||
"scripts/*.js", | ||
"stubs/*.stub.js", | ||
"stubs/*", | ||
"nesting/*", | ||
"types/**/*", | ||
"oxide-node-api-shim", | ||
"*.d.ts", | ||
@@ -58,37 +50,33 @@ "*.css", | ||
"devDependencies": { | ||
"@swc/cli": "0.1.59", | ||
"@swc/core": "1.3.24", | ||
"@swc/jest": "0.2.24", | ||
"@swc/register": "0.1.10", | ||
"autoprefixer": "^10.4.13", | ||
"concurrently": "^7.5.0", | ||
"cssnano": "^5.1.14", | ||
"esbuild": "^0.16.10", | ||
"eslint": "^8.31.0", | ||
"eslint-config-prettier": "^8.6.0", | ||
"@swc/cli": "^0.1.62", | ||
"@swc/core": "^1.3.55", | ||
"@swc/jest": "^0.2.26", | ||
"@swc/register": "^0.1.10", | ||
"autoprefixer": "^10.4.14", | ||
"browserslist": "^4.21.5", | ||
"concurrently": "^8.0.1", | ||
"cssnano": "^6.1.2", | ||
"esbuild": "^0.20.2", | ||
"eslint": "^8.39.0", | ||
"eslint-config-prettier": "^8.8.0", | ||
"eslint-plugin-prettier": "^4.2.1", | ||
"jest": "^28.1.3", | ||
"jest-diff": "^28.1.3", | ||
"prettier": "^2.8.1", | ||
"rimraf": "^3.0.0", | ||
"jest": "^29.6.0", | ||
"jest-diff": "^29.6.0", | ||
"lightningcss": "1.24.1", | ||
"prettier": "^2.8.8", | ||
"rimraf": "^5.0.0", | ||
"source-map-js": "^1.0.2", | ||
"turbo": "^1.7.0" | ||
"turbo": "^1.9.3" | ||
}, | ||
"peerDependencies": { | ||
"postcss": "^8.0.9" | ||
}, | ||
"dependencies": { | ||
"@tailwindcss/oxide": "file:./oxide-node-api-shim", | ||
"@alloc/quick-lru": "^5.2.0", | ||
"arg": "^5.0.2", | ||
"browserslist": "^4.21.4", | ||
"chokidar": "^3.5.3", | ||
"color-name": "^1.1.4", | ||
"detective": "^5.2.1", | ||
"didyoumean": "^1.2.2", | ||
"dlv": "^1.1.3", | ||
"fast-glob": "^3.2.12", | ||
"fast-glob": "^3.3.0", | ||
"glob-parent": "^6.0.2", | ||
"is-glob": "^4.0.3", | ||
"lightningcss": "^1.17.1", | ||
"lilconfig": "^2.0.6", | ||
"jiti": "^1.21.0", | ||
"lilconfig": "^2.1.0", | ||
"micromatch": "^4.0.5", | ||
@@ -98,11 +86,10 @@ "normalize-path": "^3.0.0", | ||
"picocolors": "^1.0.0", | ||
"postcss": "^8.4.21", | ||
"postcss-import": "^14.1.0", | ||
"postcss-js": "^4.0.0", | ||
"postcss-load-config": "^3.1.4", | ||
"postcss-nested": "6.0.0", | ||
"postcss": "^8.4.23", | ||
"postcss-import": "^15.1.0", | ||
"postcss-js": "^4.0.1", | ||
"postcss-load-config": "^4.0.1", | ||
"postcss-nested": "^6.0.1", | ||
"postcss-selector-parser": "^6.0.11", | ||
"postcss-value-parser": "^4.2.0", | ||
"quick-lru": "^5.1.1", | ||
"resolve": "^1.22.1" | ||
"resolve": "^1.22.2", | ||
"sucrase": "^3.32.0" | ||
}, | ||
@@ -126,2 +113,5 @@ "browserslist": [ | ||
], | ||
"transformIgnorePatterns": [ | ||
"node_modules/(?!lightningcss)" | ||
], | ||
"transform": { | ||
@@ -133,4 +123,4 @@ "\\.js$": "@swc/jest", | ||
"engines": { | ||
"node": ">=12.13.0" | ||
"node": ">=14.0.0" | ||
} | ||
} |
@@ -15,11 +15,10 @@ <p align="center"> | ||
<p align="center"> | ||
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/nodejs.yml?branch=master" alt="Build Status"></a> | ||
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/ci.yml?branch=main" alt="Build Status"></a> | ||
<a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a> | ||
<a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a> | ||
<a href="https://github.com/tailwindcss/tailwindcss/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a> | ||
<a href="https://github.com/tailwindcss/tailwindcss/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a> | ||
</p> | ||
------ | ||
--- | ||
@@ -42,2 +41,2 @@ ## Documentation | ||
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/master/.github/CONTRIBUTING.md) **before submitting a pull request**. | ||
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/main/.github/CONTRIBUTING.md) **before submitting a pull request**. |
@@ -1,3 +0,12 @@ | ||
import type { Config, ResolvableTo } from './types/config' | ||
import { Config, ResolvableTo, ThemeConfig } from './types/config' | ||
import { DefaultTheme } from './types/generated/default-theme' | ||
import { DefaultColors } from './types/generated/colors' | ||
type ResolvedConfig<T extends Config> = Omit<T, 'theme'> & { | ||
theme: MergeThemes< | ||
UnwrapResolvables<Omit<T['theme'], 'extend'>>, | ||
T['theme'] extends { extend: infer TExtend } ? UnwrapResolvables<TExtend> : {} | ||
> | ||
} | ||
type UnwrapResolvables<T> = { | ||
@@ -7,4 +16,14 @@ [K in keyof T]: T[K] extends ResolvableTo<infer R> ? R : T[K] | ||
type ResolvedConfig<T extends Config> = Omit<T, 'theme'> & { | ||
theme: UnwrapResolvables<T['theme']> | ||
type ThemeConfigResolved = UnwrapResolvables<ThemeConfig> | ||
type DefaultThemeFull = DefaultTheme & { colors: DefaultColors } | ||
type MergeThemes<Overrides extends object, Extensions extends object> = { | ||
[K in keyof ThemeConfigResolved | keyof Overrides]: (K extends keyof Overrides | ||
? Overrides[K] | ||
: K extends keyof DefaultThemeFull | ||
? DefaultThemeFull[K] | ||
: K extends keyof ThemeConfigResolved | ||
? ThemeConfigResolved[K] | ||
: never) & | ||
(K extends keyof Extensions ? Extensions[K] : {}) | ||
} | ||
@@ -11,0 +30,0 @@ |
@@ -94,5 +94,4 @@ import prettier from 'prettier' | ||
` | ||
import { Config } from '../../types' | ||
type CSSDeclarationList = Record<string, string> | ||
export type DefaultTheme = Config['theme'] & { ${defaultThemeTypes} } | ||
export type DefaultTheme = { ${defaultThemeTypes} } | ||
`, | ||
@@ -99,0 +98,0 @@ { |
#!/usr/bin/env node | ||
if (process.env.OXIDE) { | ||
module.exports = require('./oxide/cli') | ||
} else { | ||
module.exports = require('./cli/index') | ||
} | ||
module.exports = require('./cli/index') |
@@ -5,5 +5,6 @@ // @ts-check | ||
import path from 'path' | ||
import { resolveDefaultConfigPath } from '../../util/resolveConfigPath.js' | ||
import { createProcessor } from './plugin.js' | ||
export async function build(args, configs) { | ||
export async function build(args) { | ||
let input = args['--input'] | ||
@@ -29,7 +30,3 @@ let shouldWatch = args['--watch'] | ||
// TODO: Reference the @config path here if exists | ||
let configPath = args['--config'] | ||
? args['--config'] | ||
: ((defaultPath) => (fs.existsSync(defaultPath) ? defaultPath : null))( | ||
path.resolve(`./${configs.tailwind}`) | ||
) | ||
let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath() | ||
@@ -49,4 +46,7 @@ let processor = await createProcessor(args, configPath) | ||
} else { | ||
await processor.build() | ||
await processor.build().catch((e) => { | ||
console.error(e) | ||
process.exit(1) | ||
}) | ||
} | ||
} |
@@ -13,6 +13,5 @@ // @ts-check | ||
import { formatNodes, drainStdin, outputFile } from './utils' | ||
import { env } from '../shared' | ||
import { env } from '../../lib/sharedState' | ||
import resolveConfig from '../../../resolveConfig.js' | ||
import getModuleDependencies from '../../lib/getModuleDependencies.js' | ||
import { parseCandidateFiles } from '../../lib/content.js' | ||
import { createBroadPatternCheck, parseCandidateFiles } from '../../lib/content.js' | ||
import { createWatcher } from './watching.js' | ||
@@ -22,2 +21,4 @@ import fastGlob from 'fast-glob' | ||
import log from '../../util/log' | ||
import { loadConfig } from '../../lib/load-config' | ||
import getModuleDependencies from '../../lib/getModuleDependencies' | ||
@@ -122,3 +123,5 @@ /** | ||
configDependencies: new Set(), | ||
/** @type {ReturnType<typeof load> | null} */ | ||
configBag: null, | ||
contextDependencies: new Set(), | ||
@@ -148,33 +151,31 @@ | ||
if (this.watcher && configPath) { | ||
this.refreshConfigDependencies(configPath) | ||
this.refreshConfigDependencies() | ||
} | ||
let config = configPath ? require(configPath) : {} | ||
let config = loadConfig(configPath) | ||
let dependencies = getModuleDependencies(configPath) | ||
this.configBag = { | ||
config, | ||
dependencies, | ||
dispose() { | ||
for (let file of dependencies) { | ||
delete require.cache[require.resolve(file)] | ||
} | ||
}, | ||
} | ||
// @ts-ignore | ||
config = resolveConfig(config, { content: { files: [] } }) | ||
this.configBag.config = resolveConfig(this.configBag.config, { content: { files: [] } }) | ||
// Override content files if `--content` has been passed explicitly | ||
if (content?.length > 0) { | ||
config.content.files = content | ||
this.configBag.config.content.files = content | ||
} | ||
return config | ||
return this.configBag.config | ||
}, | ||
refreshConfigDependencies(configPath) { | ||
refreshConfigDependencies() { | ||
env.DEBUG && console.time('Module dependencies') | ||
for (let file of this.configDependencies) { | ||
delete require.cache[require.resolve(file)] | ||
} | ||
if (configPath) { | ||
let deps = getModuleDependencies(configPath).map(({ file }) => file) | ||
for (let dependency of deps) { | ||
this.configDependencies.add(dependency) | ||
} | ||
} | ||
this.configBag?.dispose() | ||
env.DEBUG && console.timeEnd('Module dependencies') | ||
@@ -190,14 +191,11 @@ }, | ||
let checkBroadPattern = createBroadPatternCheck(this.contentPatterns.all) | ||
for (let file of files) { | ||
if (env.OXIDE) { | ||
content.push({ | ||
file, | ||
extension: path.extname(file).slice(1), | ||
}) | ||
} else { | ||
content.push({ | ||
content: fs.readFileSync(path.resolve(file), 'utf8'), | ||
extension: path.extname(file).slice(1), | ||
}) | ||
} | ||
checkBroadPattern(file) | ||
content.push({ | ||
content: fs.readFileSync(path.resolve(file), 'utf8'), | ||
extension: path.extname(file).slice(1), | ||
}) | ||
} | ||
@@ -218,2 +216,6 @@ | ||
getContext({ createContext, cliConfigPath, root, result, content }) { | ||
env.DEBUG && console.time('Searching for config') | ||
let configPath = findAtConfigPath(root, result) ?? cliConfigPath | ||
env.DEBUG && console.timeEnd('Searching for config') | ||
if (this.context) { | ||
@@ -225,6 +227,2 @@ this.context.changedContent = this.changedContent.splice(0) | ||
env.DEBUG && console.time('Searching for config') | ||
let configPath = findAtConfigPath(root, result) ?? cliConfigPath | ||
env.DEBUG && console.timeEnd('Searching for config') | ||
env.DEBUG && console.time('Loading config') | ||
@@ -287,5 +285,5 @@ let config = this.loadConfig(configPath, content) | ||
postcssPlugin: 'tailwindcss', | ||
Once(root, { result }) { | ||
async Once(root, { result }) { | ||
env.DEBUG && console.time('Compiling CSS') | ||
tailwind(({ createContext }) => { | ||
await tailwind(({ createContext }) => { | ||
console.error() | ||
@@ -335,3 +333,3 @@ console.error('Rebuilding...') | ||
// No input file provided, fallback to default atrules | ||
// No input file provided, fallback to default at-rules | ||
return '@tailwind base; @tailwind components; @tailwind utilities' | ||
@@ -395,3 +393,7 @@ } | ||
console.error(err) | ||
if (state.watcher) { | ||
console.error(err) | ||
} else { | ||
return Promise.reject(err) | ||
} | ||
} | ||
@@ -429,3 +431,3 @@ ) | ||
return ( | ||
state.configDependencies.has(change.file) || | ||
state.configBag?.dependencies.has(change.file) || | ||
state.contextDependencies.has(change.file) | ||
@@ -432,0 +434,0 @@ ) |
@@ -92,3 +92,5 @@ // @ts-check | ||
() => {}, | ||
() => {} | ||
(e) => { | ||
console.error(e.toString()) | ||
} | ||
) | ||
@@ -166,3 +168,3 @@ } | ||
watcher.on('raw', (evt, filePath, meta) => { | ||
if (evt !== 'rename') { | ||
if (evt !== 'rename' || filePath === null) { | ||
return | ||
@@ -225,3 +227,3 @@ } | ||
watcher.add(Array.from(state.contextDependencies)) | ||
watcher.add(Array.from(state.configDependencies)) | ||
watcher.add(Array.from(state.configBag.dependencies)) | ||
watcher.add(state.contentPatterns.all) | ||
@@ -228,0 +230,0 @@ }, |
@@ -11,25 +11,2 @@ #!/usr/bin/env node | ||
function isESM() { | ||
const pkgPath = path.resolve('./package.json') | ||
try { | ||
let pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) | ||
return pkg.type && pkg.type === 'module' | ||
} catch (err) { | ||
return false | ||
} | ||
} | ||
let configs = isESM() | ||
? { | ||
tailwind: 'tailwind.config.cjs', | ||
postcss: 'postcss.config.cjs', | ||
} | ||
: { | ||
tailwind: 'tailwind.config.js', | ||
postcss: 'postcss.config.js', | ||
} | ||
// --- | ||
function oneOf(...options) { | ||
@@ -55,4 +32,9 @@ return Object.assign( | ||
args: { | ||
'--full': { type: Boolean, description: `Initialize a full \`${configs.tailwind}\` file` }, | ||
'--postcss': { type: Boolean, description: `Initialize a \`${configs.postcss}\` file` }, | ||
'--esm': { type: Boolean, description: `Initialize configuration file as ESM` }, | ||
'--ts': { type: Boolean, description: `Initialize configuration file as TypeScript` }, | ||
'--postcss': { type: Boolean, description: `Initialize a \`postcss.config.js\` file` }, | ||
'--full': { | ||
type: Boolean, | ||
description: `Include the default values for all options in the generated configuration file`, | ||
}, | ||
'-f': '--full', | ||
@@ -236,2 +218,2 @@ '-p': '--postcss', | ||
run(args, configs) | ||
run(args) |
@@ -6,19 +6,46 @@ // @ts-check | ||
export function init(args, configs) { | ||
function isESM() { | ||
const pkgPath = path.resolve('./package.json') | ||
try { | ||
let pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) | ||
return pkg.type && pkg.type === 'module' | ||
} catch (err) { | ||
return false | ||
} | ||
} | ||
export function init(args) { | ||
let messages = [] | ||
let tailwindConfigLocation = path.resolve(args['_'][1] ?? `./${configs.tailwind}`) | ||
let isProjectESM = args['--ts'] || args['--esm'] || isESM() | ||
let syntax = args['--ts'] ? 'ts' : isProjectESM ? 'js' : 'cjs' | ||
let extension = args['--ts'] ? 'ts' : 'js' | ||
let tailwindConfigLocation = path.resolve(args['_'][1] ?? `./tailwind.config.${extension}`) | ||
if (fs.existsSync(tailwindConfigLocation)) { | ||
messages.push(`${path.basename(tailwindConfigLocation)} already exists.`) | ||
} else { | ||
let stubFile = fs.readFileSync( | ||
let stubContentsFile = fs.readFileSync( | ||
args['--full'] | ||
? path.resolve(__dirname, '../../../stubs/defaultConfig.stub.js') | ||
: path.resolve(__dirname, '../../../stubs/simpleConfig.stub.js'), | ||
? path.resolve(__dirname, '../../../stubs/config.full.js') | ||
: path.resolve(__dirname, '../../../stubs/config.simple.js'), | ||
'utf8' | ||
) | ||
let stubFile = fs.readFileSync( | ||
path.resolve(__dirname, `../../../stubs/tailwind.config.${syntax}`), | ||
'utf8' | ||
) | ||
// Change colors import | ||
stubFile = stubFile.replace('../colors', 'tailwindcss/colors') | ||
stubContentsFile = stubContentsFile.replace('../colors', 'tailwindcss/colors') | ||
// Replace contents of {ts,js,cjs} file with the stub {simple,full}. | ||
stubFile = | ||
stubFile | ||
.replace('__CONFIG__', stubContentsFile.replace('module.exports =', '').trim()) | ||
.trim() + '\n\n' | ||
fs.writeFileSync(tailwindConfigLocation, stubFile, 'utf8') | ||
@@ -30,3 +57,3 @@ | ||
if (args['--postcss']) { | ||
let postcssConfigLocation = path.resolve(`./${configs.postcss}`) | ||
let postcssConfigLocation = path.resolve('./postcss.config.js') | ||
if (fs.existsSync(postcssConfigLocation)) { | ||
@@ -36,3 +63,5 @@ messages.push(`${path.basename(postcssConfigLocation)} already exists.`) | ||
let stubFile = fs.readFileSync( | ||
path.resolve(__dirname, '../../../stubs/defaultPostCssConfig.stub.js'), | ||
isProjectESM | ||
? path.resolve(__dirname, '../../../stubs/postcss.config.js') | ||
: path.resolve(__dirname, '../../../stubs/postcss.config.cjs'), | ||
'utf8' | ||
@@ -39,0 +68,0 @@ ) |
@@ -1,1 +0,1 @@ | ||
export default ["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","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","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"] | ||
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","size","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","contain","content","forcedColorAdjust"] |
@@ -7,2 +7,4 @@ import colors from 'picocolors' | ||
generalizedModifiers: true, | ||
disableColorOpacityUtilitiesByDefault: false, | ||
relativeContentPathsByDefault: false, | ||
} | ||
@@ -17,7 +19,3 @@ | ||
], | ||
experimental: [ | ||
'optimizeUniversalDefaults', | ||
'generalizedModifiers', | ||
// 'variantGrouping', | ||
], | ||
experimental: ['optimizeUniversalDefaults', 'generalizedModifiers'], | ||
} | ||
@@ -24,0 +22,0 @@ |
@@ -1,5 +0,1 @@ | ||
if (process.env.OXIDE) { | ||
module.exports = require('./oxide/postcss-plugin') | ||
} else { | ||
module.exports = require('./plugin') | ||
} | ||
module.exports = require('./plugin') |
@@ -10,2 +10,4 @@ // @ts-check | ||
import { env } from './sharedState' | ||
import log from '../util/log' | ||
import micromatch from 'micromatch' | ||
@@ -185,3 +187,71 @@ /** @typedef {import('../../types/config.js').RawFile} RawFile */ | ||
const LARGE_DIRECTORIES = [ | ||
'node_modules', // Node | ||
'vendor', // PHP | ||
] | ||
// Ensures that `node_modules` has to match as-is, otherwise `mynode_modules` | ||
// would match as well, but that is not a known large directory. | ||
const LARGE_DIRECTORIES_REGEX = new RegExp( | ||
`(${LARGE_DIRECTORIES.map((dir) => String.raw`\b${dir}\b`).join('|')})` | ||
) | ||
/** | ||
* @param {string[]} paths | ||
*/ | ||
export function createBroadPatternCheck(paths) { | ||
// Detect whether a glob pattern might be too broad. This means that it: | ||
// - Includes `**` | ||
// - Does not include any of the known large directories (e.g.: node_modules) | ||
let maybeBroadPattern = paths.some( | ||
(path) => path.includes('**') && !LARGE_DIRECTORIES_REGEX.test(path) | ||
) | ||
// Didn't detect any potentially broad patterns, so we can skip further | ||
// checks. | ||
if (!maybeBroadPattern) { | ||
return () => {} | ||
} | ||
// All globs that explicitly contain any of the known large directories (e.g.: | ||
// node_modules). | ||
let explicitGlobs = paths.filter((path) => LARGE_DIRECTORIES_REGEX.test(path)) | ||
// Keep track of whether we already warned about the broad pattern issue or | ||
// not. The `log.warn` function already does something similar where we only | ||
// output the log once. However, with this we can also skip the other checks | ||
// when we already warned about the broad pattern. | ||
let warned = false | ||
/** | ||
* @param {string} file | ||
*/ | ||
return (file) => { | ||
if (warned) return // Already warned about the broad pattern | ||
if (micromatch.isMatch(file, explicitGlobs)) return // Explicitly included, so we can skip further checks | ||
// When a broad pattern is used, we have to double check that the file was | ||
// not explicitly included in the globs. | ||
let matchingGlob = paths.find((path) => micromatch.isMatch(file, path)) | ||
if (!matchingGlob) return // This should never happen | ||
// Create relative paths to make the output a bit more readable. | ||
let relativeMatchingGlob = path.relative(process.cwd(), matchingGlob) | ||
if (relativeMatchingGlob[0] !== '.') relativeMatchingGlob = `./${relativeMatchingGlob}` | ||
let largeDirectory = LARGE_DIRECTORIES.find((directory) => file.includes(directory)) | ||
if (largeDirectory) { | ||
warned = true | ||
log.warn('broad-content-glob-pattern', [ | ||
`Your \`content\` configuration includes a pattern which looks like it's accidentally matching all of \`${largeDirectory}\` and can cause serious performance issues.`, | ||
`Pattern: \`${relativeMatchingGlob}\``, | ||
`See our documentation for recommendations:`, | ||
'https://tailwindcss.com/docs/content-configuration#pattern-recommendations', | ||
]) | ||
} | ||
} | ||
} | ||
/** | ||
* | ||
@@ -196,2 +266,4 @@ * @param {ContentPath[]} candidateFiles | ||
let checkBroadPattern = createBroadPatternCheck(paths) | ||
let changedFiles = new Set() | ||
@@ -201,2 +273,4 @@ env.DEBUG && console.time('Finding changed files') | ||
for (let file of files) { | ||
checkBroadPattern(file) | ||
let prevModified = fileModifiedMap.get(file) || -Infinity | ||
@@ -203,0 +277,0 @@ let modified = fs.statSync(file).mtimeMs |
@@ -1,3 +0,3 @@ | ||
import { flagEnabled } from '../featureFlags' | ||
import * as regex from './regex' | ||
import { splitAtTopLevelOnly } from '../util/splitAtTopLevelOnly' | ||
@@ -15,6 +15,32 @@ export function defaultExtractor(context) { | ||
for (let pattern of patterns) { | ||
results = [...results, ...(content.match(pattern) ?? [])] | ||
for (let result of content.match(pattern) ?? []) { | ||
results.push(clipAtBalancedParens(result)) | ||
} | ||
} | ||
return results.filter((v) => v !== undefined).map(clipAtBalancedParens) | ||
// Extract any subclasses from languages like Slim and Pug, eg: | ||
// div.flex.px-5.underline | ||
for (let result of results.slice()) { | ||
let segments = splitAtTopLevelOnly(result, '.') | ||
for (let idx = 0; idx < segments.length; idx++) { | ||
let segment = segments[idx] | ||
if (idx >= segments.length - 1) { | ||
results.push(segment) | ||
continue | ||
} | ||
// If the next segment is a number, discard both, for example seeing | ||
// `px-1` and `5` means the real candidate was `px-1.5` which is already | ||
// captured. | ||
let next = Number(segments[idx + 1]) | ||
if (isNaN(next)) { | ||
results.push(segment) | ||
} else { | ||
idx++ | ||
} | ||
} | ||
} | ||
return results | ||
} | ||
@@ -25,3 +51,2 @@ } | ||
let separator = context.tailwindConfig.separator | ||
let variantGroupingEnabled = flagEnabled(context.tailwindConfig, 'variantGrouping') | ||
let prefix = | ||
@@ -40,3 +65,3 @@ context.tailwindConfig.prefix !== '' | ||
// while fixing a problem with the regex matching too much | ||
/\[[^\s:'"`]+:[^\s]+?\[[^\s]+?\][^\s]+?\]/, | ||
/\[[^\s:'"`\]]+:[^\s]+?\[[^\s]+\][^\s]+?\]/, | ||
@@ -46,4 +71,9 @@ // Utilities | ||
// Utility Name / Group Name | ||
/-?(?:\w+)/, | ||
regex.any([ | ||
/-?(?:\w+)/, | ||
// This is here to make sure @container supports everything that other utilities do | ||
/@(?:\w+)/, | ||
]), | ||
// Normal/Arbitrary values | ||
@@ -54,3 +84,8 @@ regex.optional( | ||
// Arbitrary values | ||
/-(?:\w+-)*\[[^\s:]+\]/, | ||
regex.any([ | ||
/-(?:\w+-)*\['[^\s]+'\]/, | ||
/-(?:\w+-)*\["[^\s]+"\]/, | ||
/-(?:\w+-)*\[`[^\s]+`\]/, | ||
/-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s:\[\]]+\]/, | ||
]), | ||
@@ -66,3 +101,8 @@ // Not immediately followed by an `{[(` | ||
// Arbitrary values | ||
/-(?:\w+-)*\[[^\s]+\]/, | ||
regex.any([ | ||
/-(?:\w+-)*\['[^\s]+'\]/, | ||
/-(?:\w+-)*\["[^\s]+"\]/, | ||
/-(?:\w+-)*\[`[^\s]+`\]/, | ||
/-(?:\w+-)*\[(?:[^\s\[\]]+\[[^\s\[\]]+\])*[^\s\[\]]+\]/, | ||
]), | ||
@@ -89,2 +129,5 @@ // Not immediately followed by an `{[(` | ||
// With variant modifier (e.g.: group-[..]/modifier) | ||
regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]\/[\w_-]+/, separator]), | ||
regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/, separator]), | ||
@@ -96,2 +139,5 @@ regex.pattern([/[^\s"'`\[\\]+/, separator]), | ||
regex.any([ | ||
// With variant modifier (e.g.: group-[..]/modifier) | ||
regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s`]+\]\/[\w_-]+/, separator]), | ||
regex.pattern([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/, separator]), | ||
@@ -114,11 +160,3 @@ regex.pattern([/[^\s`\[\\]+/, separator]), | ||
variantGroupingEnabled | ||
? regex.any([ | ||
// Or any of those things but grouped separated by commas | ||
regex.pattern([/\(/, utility, regex.zeroOrMore([/,/, utility]), /\)/]), | ||
// Arbitrary properties, constrained utilities, arbitrary values, etc… | ||
utility, | ||
]) | ||
: utility, | ||
utility, | ||
]) | ||
@@ -128,3 +166,3 @@ } | ||
// 5. Inner matches | ||
yield /[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g | ||
yield /[^<>"'`\s.(){}[\]#=%$][^<>"'`\s(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g | ||
} | ||
@@ -131,0 +169,0 @@ |
import dlv from 'dlv' | ||
import didYouMean from 'didyoumean' | ||
import transformThemeValue from '../util/transformThemeValue' | ||
import parseValue from 'postcss-value-parser' | ||
import parseValue from '../value-parser/index' | ||
import { normalizeScreens } from '../util/normalizeScreens' | ||
@@ -149,2 +149,5 @@ import buildMediaQuery from '../util/buildMediaQuery' | ||
function resolveFunctions(node, input, functions) { | ||
let hasAnyFn = Object.keys(functions).some((fn) => input.includes(`${fn}(`)) | ||
if (!hasAnyFn) return input | ||
return parseValue(input) | ||
@@ -151,0 +154,0 @@ .walk((vNode) => { |
@@ -6,2 +6,4 @@ import postcss from 'postcss' | ||
import escapeClassName from '../util/escapeClassName' | ||
import { applyImportantSelector } from '../util/applyImportantSelector' | ||
import { movePseudos } from '../util/pseudoElements' | ||
@@ -434,2 +436,19 @@ /** @typedef {Map<string, [any, import('postcss').Rule[]]>} ApplyCache */ | ||
// Verify that we can apply the class | ||
for (let [, rule] of rules) { | ||
if (rule.type === 'atrule') { | ||
continue | ||
} | ||
rule.walkRules(() => { | ||
throw apply.error( | ||
[ | ||
`The \`${applyCandidate}\` class cannot be used with \`@apply\` because \`@apply\` does not currently support nested CSS.`, | ||
'Rewrite the selector without nesting or configure the `tailwindcss/nesting` plugin:', | ||
'https://tailwindcss.com/docs/using-with-preprocessors#nesting', | ||
].join('\n') | ||
) | ||
}) | ||
} | ||
candidates.push([applyCandidate, important, rules]) | ||
@@ -556,2 +575,9 @@ } | ||
// If the selector becomes empty after replacing the important selector | ||
// This means that it's the same as the parent selector and we don't want to replace it | ||
// Otherwise we'll crash | ||
if (parentSelector === '') { | ||
parentSelector = parent.selector | ||
} | ||
rule.selector = replaceSelector(parentSelector, rule.selector, applyCandidate) | ||
@@ -561,3 +587,3 @@ | ||
if (importantSelector && parentSelector !== parent.selector) { | ||
rule.selector = `${importantSelector} ${rule.selector}` | ||
rule.selector = applyImportantSelector(rule.selector, importantSelector) | ||
} | ||
@@ -568,2 +594,7 @@ | ||
}) | ||
// Move pseudo elements to the end of the selector (if necessary) | ||
let selector = parser().astSync(rule.selector) | ||
selector.each((sel) => movePseudos(sel)) | ||
rule.selector = selector.toString() | ||
}) | ||
@@ -570,0 +601,0 @@ } |
import fs from 'fs' | ||
import LRU from 'quick-lru' | ||
import LRU from '@alloc/quick-lru' | ||
import * as sharedState from './sharedState' | ||
@@ -9,4 +9,2 @@ import { generateRules } from './generateRules' | ||
import oxide from '@tailwindcss/oxide' | ||
let env = sharedState.env | ||
@@ -104,3 +102,3 @@ | ||
export default function expandTailwindAtRules(context) { | ||
return (root) => { | ||
return async (root) => { | ||
let layerNodes = { | ||
@@ -137,25 +135,23 @@ base: null, | ||
if (env.OXIDE) { | ||
// TODO: Pass through or implement `extractor` | ||
for (let candidate of oxide.parseCandidateStringsFromFiles( | ||
context.changedContent | ||
// Object.assign({}, builtInTransformers, context.tailwindConfig.content.transform) | ||
)) { | ||
candidates.add(candidate) | ||
} | ||
/** @type {[item: {file?: string, content?: string}, meta: {transformer: any, extractor: any}][]} */ | ||
let regexParserContent = [] | ||
// for (let { file, content, extension } of context.changedContent) { | ||
// let transformer = getTransformer(context.tailwindConfig, extension) | ||
// let extractor = getExtractor(context, extension) | ||
// getClassCandidatesOxide(file, transformer(content), extractor, candidates, seen) | ||
// } | ||
} else { | ||
for (let { file, content, extension } of context.changedContent) { | ||
let transformer = getTransformer(context.tailwindConfig, extension) | ||
let extractor = getExtractor(context, extension) | ||
content = file ? fs.readFileSync(file, 'utf8') : content | ||
getClassCandidates(transformer(content), extractor, candidates, seen) | ||
} | ||
for (let item of context.changedContent) { | ||
let transformer = getTransformer(context.tailwindConfig, item.extension) | ||
let extractor = getExtractor(context, item.extension) | ||
regexParserContent.push([item, { transformer, extractor }]) | ||
} | ||
const BATCH_SIZE = 500 | ||
for (let i = 0; i < regexParserContent.length; i += BATCH_SIZE) { | ||
let batch = regexParserContent.slice(i, i + BATCH_SIZE) | ||
await Promise.all( | ||
batch.map(async ([{ file, content }, { transformer, extractor }]) => { | ||
content = file ? await fs.promises.readFile(file, 'utf8') : content | ||
getClassCandidates(transformer(content), extractor, candidates, seen) | ||
}) | ||
) | ||
} | ||
env.DEBUG && console.timeEnd('Reading changed files') | ||
@@ -169,15 +165,10 @@ | ||
env.DEBUG && console.time('Generate rules') | ||
// TODO: Sorting is _probably_ slow, but right now it can guarantee the same order. Eventually | ||
// we will be able to get rid of this. | ||
env.DEBUG && console.time('Sorting candidates') | ||
let sortedCandidates = | ||
typeof process !== 'undefined' && process.env.JEST_WORKER_ID | ||
? new Set( | ||
[...candidates].sort((a, z) => { | ||
if (a === z) return 0 | ||
if (a < z) return -1 | ||
return 1 | ||
}) | ||
) | ||
: candidates | ||
let sortedCandidates = new Set( | ||
[...candidates].sort((a, z) => { | ||
if (a === z) return 0 | ||
if (a < z) return -1 | ||
return 1 | ||
}) | ||
) | ||
env.DEBUG && console.timeEnd('Sorting candidates') | ||
@@ -263,2 +254,5 @@ generateRules(sortedCandidates, context) | ||
// TODO: Why is the root node having no source location for `end` possible? | ||
root.source.end = root.source.end ?? root.source.start | ||
// If we've got a utility layer and no utilities are generated there's likely something wrong | ||
@@ -265,0 +259,0 @@ const hasUtilityVariants = variantNodes.some( |
@@ -6,12 +6,17 @@ import postcss from 'postcss' | ||
import prefixSelector from '../util/prefixSelector' | ||
import { updateAllClasses, filterSelectorsForClass, getMatchingTypes } from '../util/pluginUtils' | ||
import { updateAllClasses, getMatchingTypes } from '../util/pluginUtils' | ||
import log from '../util/log' | ||
import * as sharedState from './sharedState' | ||
import { formatVariantSelector, finalizeSelector } from '../util/formatVariantSelector' | ||
import { | ||
formatVariantSelector, | ||
finalizeSelector, | ||
eliminateIrrelevantSelectors, | ||
} from '../util/formatVariantSelector' | ||
import { asClass } from '../util/nameClass' | ||
import { normalize } from '../util/dataTypes' | ||
import { isValidVariantFormatString, parseVariant } from './setupContextUtils' | ||
import { isValidVariantFormatString, parseVariant, INTERNAL_FEATURES } from './setupContextUtils' | ||
import isValidArbitraryValue from '../util/isSyntacticallyValidPropertyValue' | ||
import { splitAtTopLevelOnly } from '../util/splitAtTopLevelOnly.js' | ||
import { flagEnabled } from '../featureFlags' | ||
import { applyImportantSelector } from '../util/applyImportantSelector' | ||
@@ -115,18 +120,34 @@ let classNameParser = selectorParser((selectors) => { | ||
} | ||
let result = [] | ||
function isInKeyframes(rule) { | ||
return rule.parent && rule.parent.type === 'atrule' && rule.parent.name === 'keyframes' | ||
} | ||
for (let [meta, rule] of matches) { | ||
let container = postcss.root({ nodes: [rule.clone()] }) | ||
container.walkRules((r) => { | ||
r.selector = updateAllClasses( | ||
filterSelectorsForClass(r.selector, classCandidate), | ||
(className) => { | ||
if (className === classCandidate) { | ||
return `!${className}` | ||
} | ||
return className | ||
} | ||
// Declarations inside keyframes cannot be marked as important | ||
// They will be ignored by the browser | ||
if (isInKeyframes(r)) { | ||
return | ||
} | ||
let ast = selectorParser().astSync(r.selector) | ||
// Remove extraneous selectors that do not include the base candidate | ||
ast.each((sel) => eliminateIrrelevantSelectors(sel, classCandidate)) | ||
// Update all instances of the base candidate to include the important marker | ||
updateAllClasses(ast, (className) => | ||
className === classCandidate ? `!${className}` : className | ||
) | ||
r.selector = ast.toString() | ||
r.walkDecls((d) => (d.important = true)) | ||
}) | ||
result.push([{ ...meta, important: true }, container.nodes[0]]) | ||
@@ -157,7 +178,15 @@ } | ||
{ | ||
let match = /(.*)\/(.*)$/g.exec(variant) | ||
if (match && !context.variantMap.has(variant)) { | ||
variant = match[1] | ||
args.modifier = match[2] | ||
let [baseVariant, ...modifiers] = splitAtTopLevelOnly(variant, '/') | ||
// This is a hack to support variants with `/` in them, like `ar-1/10/20:text-red-500` | ||
// In this case 1/10 is a value but /20 is a modifier | ||
if (modifiers.length > 1) { | ||
baseVariant = baseVariant + '/' + modifiers.slice(0, -1).join('/') | ||
modifiers = modifiers.slice(-1) | ||
} | ||
if (modifiers.length && !context.variantMap.has(variant)) { | ||
variant = baseVariant | ||
args.modifier = modifiers[0] | ||
if (!flagEnabled(context.tailwindConfig, 'generalizedModifiers')) { | ||
@@ -180,9 +209,9 @@ return [] | ||
if (match) { | ||
let [, char, seperator, value] = match | ||
let [, char, separator, value] = match | ||
// @-[200px] case | ||
if (char === '@' && seperator === '-') return [] | ||
if (char === '@' && separator === '-') return [] | ||
// group[:hover] case | ||
if (char !== '@' && seperator === '') return [] | ||
if (char !== '@' && separator === '') return [] | ||
variant = variant.replace(`${seperator}[${value}]`, '') | ||
variant = variant.replace(`${separator}[${value}]`, '') | ||
args.value = value | ||
@@ -194,13 +223,22 @@ } | ||
if (isArbitraryValue(variant) && !context.variantMap.has(variant)) { | ||
let sort = context.offsets.recordVariant(variant) | ||
let selector = normalize(variant.slice(1, -1)) | ||
let selectors = splitAtTopLevelOnly(selector, ',') | ||
if (!isValidVariantFormatString(selector)) { | ||
// We do not support multiple selectors for arbitrary variants | ||
if (selectors.length > 1) { | ||
return [] | ||
} | ||
let fn = parseVariant(selector) | ||
if (!selectors.every(isValidVariantFormatString)) { | ||
return [] | ||
} | ||
let sort = context.offsets.recordVariant(variant) | ||
let records = selectors.map((sel, idx) => [ | ||
context.offsets.applyParallelOffset(sort, idx), | ||
parseVariant(sel.trim()), | ||
]) | ||
context.variantMap.set(variant, [[sort, fn]]) | ||
context.variantMap.set(variant, records) | ||
} | ||
@@ -210,5 +248,12 @@ | ||
let isArbitraryVariant = isArbitraryValue(variant) | ||
let internalFeatures = context.variantOptions.get(variant)?.[INTERNAL_FEATURES] ?? {} | ||
let variantFunctionTuples = context.variantMap.get(variant).slice() | ||
let result = [] | ||
let respectPrefix = (() => { | ||
if (isArbitraryVariant) return false | ||
if (internalFeatures.respectPrefix === false) return false | ||
return true | ||
})() | ||
for (let [meta, rule] of matches) { | ||
@@ -274,3 +319,3 @@ // Don't generate variants for user css | ||
format: selectorFormat, | ||
isArbitraryVariant, | ||
respectPrefix, | ||
}) | ||
@@ -304,3 +349,3 @@ }, | ||
format: ruleWithVariant, | ||
isArbitraryVariant, | ||
respectPrefix, | ||
}) | ||
@@ -349,3 +394,3 @@ } | ||
format: modified.replace(rebuiltBase, '&'), | ||
isArbitraryVariant, | ||
respectPrefix, | ||
}) | ||
@@ -473,3 +518,3 @@ rule.selector = before | ||
let normalized = normalize(value) | ||
let normalized = normalize(value, { property }) | ||
@@ -480,7 +525,7 @@ if (!isParsableCssValue(property, normalized)) { | ||
let sort = context.offsets.arbitraryProperty() | ||
let sort = context.offsets.arbitraryProperty(classCandidate) | ||
return [ | ||
[ | ||
{ sort, layer: 'utilities' }, | ||
{ sort, layer: 'utilities', options: { respectImportant: true } }, | ||
() => ({ | ||
@@ -552,3 +597,3 @@ [asClass(classCandidate)]: { | ||
function* resolveMatches(candidate, context, original = candidate) { | ||
function* resolveMatches(candidate, context) { | ||
let separator = context.tailwindConfig.separator | ||
@@ -563,11 +608,2 @@ let [classCandidate, ...variants] = splitWithSeparator(candidate, separator).reverse() | ||
if (flagEnabled(context.tailwindConfig, 'variantGrouping')) { | ||
if (classCandidate.startsWith('(') && classCandidate.endsWith(')')) { | ||
let base = variants.slice().reverse().join(separator) | ||
for (let part of splitAtTopLevelOnly(classCandidate.slice(1, -1), ',')) { | ||
yield* resolveMatches(base + separator + part, context, original) | ||
} | ||
} | ||
} | ||
// TODO: Reintroduce this in ways that doesn't break on false positives | ||
@@ -761,3 +797,3 @@ // function sortAgainst(toSort, against) { | ||
// Apply final format selector | ||
match = applyFinalFormat(match, { context, candidate, original }) | ||
match = applyFinalFormat(match, { context, candidate }) | ||
@@ -776,3 +812,3 @@ // Skip rules with invalid selectors | ||
function applyFinalFormat(match, { context, candidate, original }) { | ||
function applyFinalFormat(match, { context, candidate }) { | ||
if (!match[0].collectedFormats) { | ||
@@ -812,6 +848,15 @@ return match | ||
try { | ||
rule.selector = finalizeSelector(rule.selector, finalFormat, { | ||
candidate: original, | ||
let selector = finalizeSelector(rule.selector, finalFormat, { | ||
candidate, | ||
context, | ||
}) | ||
// Finalize Selector determined that this candidate is irrelevant | ||
// TODO: This elimination should happen earlier so this never happens | ||
if (selector === null) { | ||
rule.remove() | ||
return | ||
} | ||
rule.selector = selector | ||
} catch { | ||
@@ -829,2 +874,7 @@ // If this selector is invalid we also want to skip it | ||
// If all rules have been eliminated we can skip this candidate entirely | ||
if (container.nodes.length === 0) { | ||
return null | ||
} | ||
match[1] = container.nodes[0] | ||
@@ -861,3 +911,3 @@ | ||
rule.selectors = rule.selectors.map((selector) => { | ||
return `${important} ${selector}` | ||
return applyImportantSelector(selector, important) | ||
}) | ||
@@ -868,3 +918,3 @@ } | ||
function generateRules(candidates, context) { | ||
function generateRules(candidates, context, isSorting = false) { | ||
let allRules = [] | ||
@@ -904,3 +954,5 @@ let strategy = getImportantStrategy(context.tailwindConfig.important) | ||
let newEntry = [sort, rule] | ||
// Note: We have to clone rules during sorting | ||
// so we eliminate some shared mutable state | ||
let newEntry = [sort, isSorting ? rule.clone() : rule] | ||
rules.add(newEntry) | ||
@@ -907,0 +959,0 @@ context.ruleCache.add(newEntry) |
import fs from 'fs' | ||
import path from 'path' | ||
import resolve from 'resolve' | ||
import detective from 'detective' | ||
function createModule(file) { | ||
const source = fs.readFileSync(file, 'utf-8') | ||
const requires = detective(source) | ||
let jsExtensions = ['.js', '.cjs', '.mjs'] | ||
return { file, requires } | ||
// Given the current file `a.ts`, we want to make sure that when importing `b` that we resolve | ||
// `b.ts` before `b.js` | ||
// | ||
// E.g.: | ||
// | ||
// a.ts | ||
// b // .ts | ||
// c // .ts | ||
// a.js | ||
// b // .js or .ts | ||
let jsResolutionOrder = ['', '.js', '.cjs', '.mjs', '.ts', '.cts', '.mts', '.jsx', '.tsx'] | ||
let tsResolutionOrder = ['', '.ts', '.cts', '.mts', '.tsx', '.js', '.cjs', '.mjs', '.jsx'] | ||
function resolveWithExtension(file, extensions) { | ||
// Try to find `./a.ts`, `./a.ts`, ... from `./a` | ||
for (let ext of extensions) { | ||
let full = `${file}${ext}` | ||
if (fs.existsSync(full) && fs.statSync(full).isFile()) { | ||
return full | ||
} | ||
} | ||
// Try to find `./a/index.js` from `./a` | ||
for (let ext of extensions) { | ||
let full = `${file}/index${ext}` | ||
if (fs.existsSync(full)) { | ||
return full | ||
} | ||
} | ||
return null | ||
} | ||
export default function getModuleDependencies(entryFile) { | ||
const rootModule = createModule(entryFile) | ||
const modules = [rootModule] | ||
function* _getModuleDependencies(filename, base, seen, ext = path.extname(filename)) { | ||
// Try to find the file | ||
let absoluteFile = resolveWithExtension( | ||
path.resolve(base, filename), | ||
jsExtensions.includes(ext) ? jsResolutionOrder : tsResolutionOrder | ||
) | ||
if (absoluteFile === null) return // File doesn't exist | ||
// Iterate over the modules, even when new | ||
// ones are being added | ||
for (const mdl of modules) { | ||
mdl.requires | ||
.filter((dep) => { | ||
// Only track local modules, not node_modules | ||
return dep.startsWith('./') || dep.startsWith('../') | ||
}) | ||
.forEach((dep) => { | ||
try { | ||
const basedir = path.dirname(mdl.file) | ||
const depPath = resolve.sync(dep, { basedir }) | ||
const depModule = createModule(depPath) | ||
// Prevent infinite loops when there are circular dependencies | ||
if (seen.has(absoluteFile)) return // Already seen | ||
seen.add(absoluteFile) | ||
modules.push(depModule) | ||
} catch (_err) { | ||
// eslint-disable-next-line no-empty | ||
} | ||
}) | ||
// Mark the file as a dependency | ||
yield absoluteFile | ||
// Resolve new base for new imports/requires | ||
base = path.dirname(absoluteFile) | ||
ext = path.extname(absoluteFile) | ||
let contents = fs.readFileSync(absoluteFile, 'utf-8') | ||
// Find imports/requires | ||
for (let match of [ | ||
...contents.matchAll(/import[\s\S]*?['"](.{3,}?)['"]/gi), | ||
...contents.matchAll(/import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi), | ||
...contents.matchAll(/require\(['"`](.+)['"`]\)/gi), | ||
]) { | ||
// Bail out if it's not a relative file | ||
if (!match[1].startsWith('.')) continue | ||
yield* _getModuleDependencies(match[1], base, seen, ext) | ||
} | ||
} | ||
return modules | ||
export default function getModuleDependencies(absoluteFilePath) { | ||
if (absoluteFilePath === null) return new Set() | ||
return new Set( | ||
_getModuleDependencies(absoluteFilePath, path.dirname(absoluteFilePath), new Set()) | ||
) | ||
} |
@@ -26,3 +26,5 @@ // @ts-check | ||
* @property {bigint} parallelIndex Rule index for the parallel variant. 0 if not applicable. | ||
* @property {bigint} index Index of the rule / utility in it's given *parent* layer. Monotonically increasing. | ||
* @property {bigint} index Index of the rule / utility in its given *parent* layer. Monotonically increasing. | ||
* @property {bigint} propertyOffset Offset for the arbitrary property. Only valid after sorting. | ||
* @property {string} property Name/Value of the arbitrary property. | ||
* @property {VariantOption[]} options Some information on how we can sort arbitrary variants | ||
@@ -92,2 +94,4 @@ */ | ||
index: this.offsets[layer]++, | ||
propertyOffset: 0n, | ||
property: '', | ||
options: [], | ||
@@ -98,8 +102,10 @@ } | ||
/** | ||
* @param {string} name | ||
* @returns {RuleOffset} | ||
*/ | ||
arbitraryProperty() { | ||
arbitraryProperty(name) { | ||
return { | ||
...this.create('utilities'), | ||
arbitrary: 1n, | ||
property: name, | ||
} | ||
@@ -215,2 +221,8 @@ } | ||
// When sorting the `variants` layer, we need to sort based on the parent layer as well within | ||
// this variants layer. | ||
if (a.parentLayer !== b.parentLayer) { | ||
return this.layerPositions[a.parentLayer] - this.layerPositions[b.parentLayer] | ||
} | ||
// Sort based on the sorting function | ||
@@ -263,2 +275,7 @@ for (let aOptions of a.options) { | ||
// Always sort arbitrary properties alphabetically | ||
if (a.propertyOffset !== b.propertyOffset) { | ||
return a.propertyOffset - b.propertyOffset | ||
} | ||
// Sort utilities, components, etc… in the order they were registered | ||
@@ -327,5 +344,53 @@ return a.index - b.index | ||
*/ | ||
sortArbitraryProperties(list) { | ||
// Collect all known arbitrary properties | ||
let known = new Set() | ||
for (let [offset] of list) { | ||
if (offset.arbitrary === 1n) { | ||
known.add(offset.property) | ||
} | ||
} | ||
// No arbitrary properties? Nothing to do. | ||
if (known.size === 0) { | ||
return list | ||
} | ||
// Sort the properties alphabetically | ||
let properties = Array.from(known).sort() | ||
// Create a map from the property name to its offset | ||
let offsets = new Map() | ||
let offset = 1n | ||
for (let property of properties) { | ||
offsets.set(property, offset++) | ||
} | ||
// Apply the sorted offsets to the list | ||
return list.map((item) => { | ||
let [offset, rule] = item | ||
offset = { | ||
...offset, | ||
propertyOffset: offsets.get(offset.property) ?? 0n, | ||
} | ||
return [offset, rule] | ||
}) | ||
} | ||
/** | ||
* @template T | ||
* @param {[RuleOffset, T][]} list | ||
* @returns {[RuleOffset, T][]} | ||
*/ | ||
sort(list) { | ||
// Sort arbitrary variants so they're in alphabetical order | ||
list = this.remapArbitraryVariantOffsets(list) | ||
// Sort arbitrary properties so they're in alphabetical order | ||
list = this.sortArbitraryProperties(list) | ||
return list.sort(([a], [b]) => bigSign(this.compare(a, b))) | ||
@@ -332,0 +397,0 @@ } |
@@ -107,4 +107,8 @@ import postcss from 'postcss' | ||
// vendor prefix to throw out the whole rule | ||
// Additionally if a selector contains `:has` we also consider | ||
// it separately because FF only recently gained support for it | ||
let selectorGroupName = | ||
selector.includes(':-') || selector.includes('::-') ? selector : '__DEFAULT__' | ||
selector.includes(':-') || selector.includes('::-') || selector.includes(':has') | ||
? selector | ||
: '__DEFAULT__' | ||
@@ -111,0 +115,0 @@ let selectors = selectorGroups.get(selectorGroupName) ?? new Set() |
@@ -27,2 +27,4 @@ import fs from 'fs' | ||
export const INTERNAL_FEATURES = Symbol() | ||
const VARIANT_TYPES = { | ||
@@ -150,39 +152,41 @@ AddVariant: Symbol.for('ADD_VARIANT'), | ||
/** | ||
* Ignore everything inside a :not(...). This allows you to write code like | ||
* `div:not(.foo)`. If `.foo` is never found in your code, then we used to | ||
* not generated it. But now we will ignore everything inside a `:not`, so | ||
* that it still gets generated. | ||
* | ||
* @param {selectorParser.Root} selectors | ||
*/ | ||
function ignoreNot(selectors) { | ||
selectors.walkPseudos((pseudo) => { | ||
if (pseudo.value === ':not') { | ||
pseudo.remove() | ||
} | ||
}) | ||
} | ||
function extractCandidates(node, state = { containsNonOnDemandable: false }, depth = 0) { | ||
let classes = [] | ||
let selectors = [] | ||
// Handle normal rules | ||
if (node.type === 'rule') { | ||
// Ignore everything inside a :not(...). This allows you to write code like | ||
// `div:not(.foo)`. If `.foo` is never found in your code, then we used to | ||
// not generated it. But now we will ignore everything inside a `:not`, so | ||
// that it still gets generated. | ||
function ignoreNot(selectors) { | ||
selectors.walkPseudos((pseudo) => { | ||
if (pseudo.value === ':not') { | ||
pseudo.remove() | ||
} | ||
}) | ||
} | ||
// Handle normal rules | ||
selectors.push(...node.selectors) | ||
} else if (node.type === 'atrule') { | ||
// Handle at-rules (which contains nested rules) | ||
node.walkRules((rule) => selectors.push(...rule.selectors)) | ||
} | ||
for (let selector of node.selectors) { | ||
let classCandidates = getClasses(selector, ignoreNot) | ||
// At least one of the selectors contains non-"on-demandable" candidates. | ||
if (classCandidates.length === 0) { | ||
state.containsNonOnDemandable = true | ||
} | ||
for (let selector of selectors) { | ||
let classCandidates = getClasses(selector, ignoreNot) | ||
for (let classCandidate of classCandidates) { | ||
classes.push(classCandidate) | ||
} | ||
// At least one of the selectors contains non-"on-demandable" candidates. | ||
if (classCandidates.length === 0) { | ||
state.containsNonOnDemandable = true | ||
} | ||
} | ||
// Handle at-rules (which contains nested rules) | ||
else if (node.type === 'atrule') { | ||
node.walkRules((rule) => { | ||
for (let classCandidate of rule.selectors.flatMap((selector) => getClasses(selector))) { | ||
classes.push(classCandidate) | ||
} | ||
}) | ||
for (let classCandidate of classCandidates) { | ||
classes.push(classCandidate) | ||
} | ||
} | ||
@@ -235,4 +239,4 @@ | ||
let [, name, params] = /@(.*?)( .+|[({].*)/g.exec(str) | ||
return ({ wrap }) => wrap(postcss.atRule({ name, params: params.trim() })) | ||
let [, name, params] = /@(\S*)( .+|[({].*)?/g.exec(str) | ||
return ({ wrap }) => wrap(postcss.atRule({ name, params: params?.trim() ?? '' })) | ||
}) | ||
@@ -758,4 +762,6 @@ .reverse() | ||
let beforeVariants = [ | ||
variantPlugins['childVariant'], | ||
variantPlugins['pseudoElementVariants'], | ||
variantPlugins['pseudoClassVariants'], | ||
variantPlugins['hasVariants'], | ||
variantPlugins['ariaVariants'], | ||
@@ -766,11 +772,33 @@ variantPlugins['dataVariants'], | ||
variantPlugins['supportsVariants'], | ||
variantPlugins['directionVariants'], | ||
variantPlugins['reducedMotionVariants'], | ||
variantPlugins['prefersContrastVariants'], | ||
variantPlugins['screenVariants'], | ||
variantPlugins['orientationVariants'], | ||
variantPlugins['directionVariants'], | ||
variantPlugins['darkVariants'], | ||
variantPlugins['forcedColorsVariants'], | ||
variantPlugins['printVariant'], | ||
variantPlugins['screenVariants'], | ||
variantPlugins['orientationVariants'], | ||
] | ||
// This is a compatibility fix for the pre 3.4 dark mode behavior | ||
// `class` retains the old behavior, but `selector` keeps the new behavior | ||
let isLegacyDarkMode = | ||
context.tailwindConfig.darkMode === 'class' || | ||
(Array.isArray(context.tailwindConfig.darkMode) && | ||
context.tailwindConfig.darkMode[0] === 'class') | ||
if (isLegacyDarkMode) { | ||
afterVariants = [ | ||
variantPlugins['supportsVariants'], | ||
variantPlugins['reducedMotionVariants'], | ||
variantPlugins['prefersContrastVariants'], | ||
variantPlugins['darkVariants'], | ||
variantPlugins['screenVariants'], | ||
variantPlugins['orientationVariants'], | ||
variantPlugins['directionVariants'], | ||
variantPlugins['forcedColorsVariants'], | ||
variantPlugins['printVariant'], | ||
] | ||
} | ||
return [...corePluginList, ...beforeVariants, ...userPlugins, ...afterVariants, ...layerPlugins] | ||
@@ -939,8 +967,15 @@ } | ||
context.getClassOrder = function getClassOrder(classes) { | ||
// Sort classes so they're ordered in a deterministic manner | ||
let sorted = [...classes].sort((a, z) => { | ||
if (a === z) return 0 | ||
if (a < z) return -1 | ||
return 1 | ||
}) | ||
// Non-util classes won't be generated, so we default them to null | ||
let sortedClassNames = new Map(classes.map((className) => [className, null])) | ||
let sortedClassNames = new Map(sorted.map((className) => [className, null])) | ||
// Sort all classes in order | ||
// Non-tailwind classes won't be generated and will be left as `null` | ||
let rules = generateRules(new Set(classes), context) | ||
let rules = generateRules(new Set(sorted), context, true) | ||
rules = context.offsets.sort(rules) | ||
@@ -951,3 +986,7 @@ | ||
for (const [, rule] of rules) { | ||
sortedClassNames.set(rule.raws.tailwind.candidate, idx++) | ||
let candidate = rule.raws.tailwind.candidate | ||
// When multiple rules match a candidate | ||
// always take the position of the first one | ||
sortedClassNames.set(candidate, sortedClassNames.get(candidate) ?? idx++) | ||
} | ||
@@ -972,3 +1011,3 @@ | ||
// ['uppercase', 'lowercase', ...] | ||
context.getClassList = function getClassList() { | ||
context.getClassList = function getClassList(options = {}) { | ||
let output = [] | ||
@@ -978,6 +1017,15 @@ | ||
if (Array.isArray(util)) { | ||
let [utilName, options] = util | ||
let [utilName, utilOptions] = util | ||
let negativeClasses = [] | ||
for (let [key, value] of Object.entries(options?.values ?? {})) { | ||
let modifiers = Object.keys(utilOptions?.modifiers ?? {}) | ||
if (utilOptions?.types?.some(({ type }) => type === 'color')) { | ||
modifiers.push(...Object.keys(context.tailwindConfig.theme.opacity ?? {})) | ||
} | ||
let metadata = { modifiers } | ||
let includeMetadata = options.includeMetadata && modifiers.length > 0 | ||
for (let [key, value] of Object.entries(utilOptions?.values ?? {})) { | ||
// Ignore undefined and null values | ||
@@ -988,5 +1036,8 @@ if (value == null) { | ||
output.push(formatClass(utilName, key)) | ||
if (options?.supportsNegativeValues && negateValue(value)) { | ||
negativeClasses.push(formatClass(utilName, `-${key}`)) | ||
let cls = formatClass(utilName, key) | ||
output.push(includeMetadata ? [cls, metadata] : cls) | ||
if (utilOptions?.supportsNegativeValues && negateValue(value)) { | ||
let cls = formatClass(utilName, `-${key}`) | ||
negativeClasses.push(includeMetadata ? [cls, metadata] : cls) | ||
} | ||
@@ -1006,2 +1057,7 @@ } | ||
context.getVariants = function getVariants() { | ||
// We use a unique, random ID for candidate names to avoid conflicts | ||
// We can't use characters like `_`, `:`, `@` or `.` because they might | ||
// be used as a separator | ||
let id = Math.random().toString(36).substring(7).toUpperCase() | ||
let result = [] | ||
@@ -1017,3 +1073,3 @@ for (let [name, options] of context.variantOptions.entries()) { | ||
selectors({ modifier, value } = {}) { | ||
let candidate = '__TAILWIND_PLACEHOLDER__' | ||
let candidate = `TAILWINDPLACEHOLDER${id}` | ||
@@ -1115,7 +1171,14 @@ let rule = postcss.rule({ selector: `.${candidate}` }) | ||
let isArbitraryVariant = !(value in (options.values ?? {})) | ||
let internalFeatures = options[INTERNAL_FEATURES] ?? {} | ||
let respectPrefix = (() => { | ||
if (isArbitraryVariant) return false | ||
if (internalFeatures.respectPrefix === false) return false | ||
return true | ||
})() | ||
formatStrings = formatStrings.map((format) => | ||
format.map((str) => ({ | ||
format: str, | ||
isArbitraryVariant, | ||
respectPrefix, | ||
})) | ||
@@ -1126,3 +1189,3 @@ ) | ||
format, | ||
isArbitraryVariant, | ||
respectPrefix, | ||
})) | ||
@@ -1129,0 +1192,0 @@ |
// @ts-check | ||
import fs from 'fs' | ||
import LRU from 'quick-lru' | ||
import LRU from '@alloc/quick-lru' | ||
import hash from '../util/hashConfig' | ||
import getModuleDependencies from '../lib/getModuleDependencies' | ||
import resolveConfig from '../public/resolve-config' | ||
@@ -14,2 +13,4 @@ import resolveConfigPath from '../util/resolveConfigPath' | ||
import { parseCandidateFiles, resolvedChangedContent } from './content.js' | ||
import { loadConfig } from '../lib/load-config' | ||
import getModuleDependencies from './getModuleDependencies' | ||
@@ -38,3 +39,3 @@ let configPathCache = new LRU({ maxSize: 100 }) | ||
let newDeps = getModuleDependencies(userConfigPath).map((dep) => dep.file) | ||
let newDeps = getModuleDependencies(userConfigPath) | ||
@@ -60,4 +61,3 @@ let modified = false | ||
} | ||
let newConfig = resolveConfig(require(userConfigPath)) | ||
newConfig = validateConfig(newConfig) | ||
let newConfig = validateConfig(resolveConfig(loadConfig(userConfigPath))) | ||
let newHash = hash(newConfig) | ||
@@ -69,5 +69,3 @@ configPathCache.set(userConfigPath, [newConfig, newHash, newDeps, newModified]) | ||
// It's a plain object, not a path | ||
let newConfig = resolveConfig( | ||
configOrPath.config === undefined ? configOrPath : configOrPath.config | ||
) | ||
let newConfig = resolveConfig(configOrPath?.config ?? configOrPath ?? {}) | ||
@@ -74,0 +72,0 @@ newConfig = validateConfig(newConfig) |
@@ -1,6 +0,12 @@ | ||
export const env = { | ||
NODE_ENV: process.env.NODE_ENV, | ||
DEBUG: resolveDebug(process.env.DEBUG), | ||
OXIDE: process.env.OXIDE, | ||
} | ||
export const env = | ||
typeof process !== 'undefined' | ||
? { | ||
NODE_ENV: process.env.NODE_ENV, | ||
DEBUG: resolveDebug(process.env.DEBUG), | ||
} | ||
: { | ||
NODE_ENV: 'production', | ||
DEBUG: false, | ||
} | ||
export const contextMap = new Map() | ||
@@ -7,0 +13,0 @@ export const configContextMap = new Map() |
@@ -16,3 +16,3 @@ import setupTrackingContext from './lib/setupTrackingContext' | ||
}, | ||
function (root, result) { | ||
async function (root, result) { | ||
// Use the path for the `@config` directive if it exists, otherwise use the | ||
@@ -29,3 +29,3 @@ // path for the file being processed | ||
if (root.type === 'root') { | ||
processTailwindFeatures(context)(root, result) | ||
await processTailwindFeatures(context)(root, result) | ||
} | ||
@@ -37,3 +37,3 @@ } | ||
processTailwindFeatures(context)(root, result) | ||
await processTailwindFeatures(context)(root, result) | ||
}, | ||
@@ -40,0 +40,0 @@ env.DEBUG && |
@@ -10,3 +10,2 @@ import normalizeTailwindDirectives from './lib/normalizeTailwindDirectives' | ||
import partitionApplyAtRules from './lib/partitionApplyAtRules' | ||
import detectNesting from './lib/detectNesting' | ||
import { createContext } from './lib/setupContextUtils' | ||
@@ -16,7 +15,5 @@ import { issueFlagNotices } from './featureFlags' | ||
export default function processTailwindFeatures(setupContext) { | ||
return function (root, result) { | ||
return async function (root, result) { | ||
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root) | ||
detectNesting()(root, result) | ||
// Partition apply rules that are found in the css | ||
@@ -49,3 +46,4 @@ // itself. | ||
expandTailwindAtRules(context)(root, result) | ||
await expandTailwindAtRules(context)(root, result) | ||
// Partition apply rules that are generated by | ||
@@ -52,0 +50,0 @@ // addComponents, addUtilities and so on. |
@@ -27,2 +27,3 @@ import log from '../util/log' | ||
900: '#0f172a', | ||
950: '#020617', | ||
}, | ||
@@ -40,2 +41,3 @@ gray: { | ||
900: '#111827', | ||
950: '#030712', | ||
}, | ||
@@ -53,2 +55,3 @@ zinc: { | ||
900: '#18181b', | ||
950: '#09090b', | ||
}, | ||
@@ -66,2 +69,3 @@ neutral: { | ||
900: '#171717', | ||
950: '#0a0a0a', | ||
}, | ||
@@ -79,2 +83,3 @@ stone: { | ||
900: '#1c1917', | ||
950: '#0c0a09', | ||
}, | ||
@@ -92,2 +97,3 @@ red: { | ||
900: '#7f1d1d', | ||
950: '#450a0a', | ||
}, | ||
@@ -105,2 +111,3 @@ orange: { | ||
900: '#7c2d12', | ||
950: '#431407', | ||
}, | ||
@@ -118,2 +125,3 @@ amber: { | ||
900: '#78350f', | ||
950: '#451a03', | ||
}, | ||
@@ -131,2 +139,3 @@ yellow: { | ||
900: '#713f12', | ||
950: '#422006', | ||
}, | ||
@@ -144,2 +153,3 @@ lime: { | ||
900: '#365314', | ||
950: '#1a2e05', | ||
}, | ||
@@ -157,2 +167,3 @@ green: { | ||
900: '#14532d', | ||
950: '#052e16', | ||
}, | ||
@@ -170,2 +181,3 @@ emerald: { | ||
900: '#064e3b', | ||
950: '#022c22', | ||
}, | ||
@@ -183,2 +195,3 @@ teal: { | ||
900: '#134e4a', | ||
950: '#042f2e', | ||
}, | ||
@@ -196,2 +209,3 @@ cyan: { | ||
900: '#164e63', | ||
950: '#083344', | ||
}, | ||
@@ -209,2 +223,3 @@ sky: { | ||
900: '#0c4a6e', | ||
950: '#082f49', | ||
}, | ||
@@ -222,2 +237,3 @@ blue: { | ||
900: '#1e3a8a', | ||
950: '#172554', | ||
}, | ||
@@ -235,2 +251,3 @@ indigo: { | ||
900: '#312e81', | ||
950: '#1e1b4b', | ||
}, | ||
@@ -248,2 +265,3 @@ violet: { | ||
900: '#4c1d95', | ||
950: '#2e1065', | ||
}, | ||
@@ -261,2 +279,3 @@ purple: { | ||
900: '#581c87', | ||
950: '#3b0764', | ||
}, | ||
@@ -274,2 +293,3 @@ fuchsia: { | ||
900: '#701a75', | ||
950: '#4a044e', | ||
}, | ||
@@ -287,2 +307,3 @@ pink: { | ||
900: '#831843', | ||
950: '#500724', | ||
}, | ||
@@ -300,2 +321,3 @@ rose: { | ||
900: '#881337', | ||
950: '#4c0519', | ||
}, | ||
@@ -302,0 +324,0 @@ get lightBlue() { |
import { cloneDeep } from '../util/cloneDeep' | ||
import defaultConfig from '../../stubs/defaultConfig.stub' | ||
import defaultConfig from '../../stubs/config.full' | ||
export default cloneDeep(defaultConfig) |
import { cloneDeep } from '../util/cloneDeep' | ||
import defaultConfig from '../../stubs/defaultConfig.stub' | ||
import defaultFullConfig from '../../stubs/config.full' | ||
export default cloneDeep(defaultConfig.theme) | ||
export default cloneDeep(defaultFullConfig.theme) |
@@ -0,1 +1,7 @@ | ||
/** | ||
* @param {import('postcss').Container[]} nodes | ||
* @param {any} source | ||
* @param {any} raws | ||
* @returns {import('postcss').Container[]} | ||
*/ | ||
export default function cloneNodes(nodes, source = undefined, raws = undefined) { | ||
@@ -5,16 +11,2 @@ return nodes.map((node) => { | ||
// We always want override the source map | ||
// except when explicitly told not to | ||
let shouldOverwriteSource = node.raws.tailwind?.preserveSource !== true || !cloned.source | ||
if (source !== undefined && shouldOverwriteSource) { | ||
cloned.source = source | ||
if ('walk' in cloned) { | ||
cloned.walk((child) => { | ||
child.source = source | ||
}) | ||
} | ||
} | ||
if (raws !== undefined) { | ||
@@ -27,4 +19,33 @@ cloned.raws.tailwind = { | ||
if (source !== undefined) { | ||
traverse(cloned, (node) => { | ||
// Do not traverse nodes that have opted | ||
// to preserve their original source | ||
let shouldPreserveSource = node.raws.tailwind?.preserveSource === true && node.source | ||
if (shouldPreserveSource) { | ||
return false | ||
} | ||
// Otherwise we can safely replace the source | ||
// And continue traversing | ||
node.source = source | ||
}) | ||
} | ||
return cloned | ||
}) | ||
} | ||
/** | ||
* Traverse a tree of nodes and don't traverse children if the callback | ||
* returns false. Ideally we'd use Container#walk instead of this | ||
* function but it stops traversing siblings too. | ||
* | ||
* @param {import('postcss').Container} node | ||
* @param {(node: import('postcss').Container) => boolean} onNode | ||
*/ | ||
function traverse(node, onNode) { | ||
if (onNode(node) !== false) { | ||
node.each?.((child) => traverse(child, onNode)) | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import namedColors from 'color-name' | ||
import namedColors from './colorNames' | ||
@@ -8,9 +8,9 @@ let HEX = /^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i | ||
let ALPHA_SEP = /\s*[,/]\s*/ | ||
let CUSTOM_PROPERTY = /var\(--(?:[^ )]*?)\)/ | ||
let CUSTOM_PROPERTY = /var\(--(?:[^ )]*?)(?:,(?:[^ )]*?|var\(--[^ )]*?\)))?\)/ | ||
let RGB = new RegExp( | ||
`^(rgb)a?\\(\\s*(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$` | ||
`^(rgba?)\\(\\s*(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$` | ||
) | ||
let HSL = new RegExp( | ||
`^(hsl)a?\\(\\s*((?:${VALUE.source})(?:deg|rad|grad|turn)?|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$` | ||
`^(hsla?)\\(\\s*((?:${VALUE.source})(?:deg|rad|grad|turn)?|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$` | ||
) | ||
@@ -56,2 +56,12 @@ | ||
// rgba(var(--my-color), 0.1) | ||
// hsla(var(--my-color), 0.1) | ||
if (color.length === 2 && color[0].startsWith('var(')) { | ||
return { | ||
mode: match[1], | ||
color: [color[0]], | ||
alpha: color[1], | ||
} | ||
} | ||
if (!loose && color.length !== 3) { | ||
@@ -74,3 +84,8 @@ return null | ||
let hasAlpha = alpha !== undefined | ||
if (mode === 'rgba' || mode === 'hsla') { | ||
return `${mode}(${color.join(', ')}${hasAlpha ? `, ${alpha}` : ''})` | ||
} | ||
return `${mode}(${color.join(' ')}${hasAlpha ? ` / ${alpha}` : ''})` | ||
} |
@@ -13,9 +13,36 @@ import { parseColor } from './color' | ||
const placeholder = '--tw-placeholder' | ||
const placeholderRe = new RegExp(placeholder, 'g') | ||
// These properties accept a `<dashed-ident>` as one of the values. This means that you can use them | ||
// as: `timeline-scope: --tl;` | ||
// | ||
// Without the `var(--tl)`, in these cases we don't want to normalize the value, and you should add | ||
// the `var()` yourself. | ||
// | ||
// More info: | ||
// - https://drafts.csswg.org/scroll-animations/#propdef-timeline-scope | ||
// - https://developer.mozilla.org/en-US/docs/Web/CSS/timeline-scope#dashed-ident | ||
// - https://www.w3.org/TR/css-anchor-position-1 | ||
// | ||
const AUTO_VAR_INJECTION_EXCEPTIONS = new Set([ | ||
// Concrete properties | ||
'scroll-timeline-name', | ||
'timeline-scope', | ||
'view-timeline-name', | ||
'font-palette', | ||
'anchor-name', | ||
'anchor-scope', | ||
'position-anchor', | ||
'position-try-options', | ||
// Shorthand properties | ||
'scroll-timeline', | ||
'animation-timeline', | ||
'view-timeline', | ||
'position-try', | ||
]) | ||
// This is not a data type, but rather a function that can normalize the | ||
// correct values. | ||
export function normalize(value, isRoot = true) { | ||
if (value.startsWith('--')) { | ||
export function normalize(value, context = null, isRoot = true) { | ||
let isVarException = context && AUTO_VAR_INJECTION_EXCEPTIONS.has(context.property) | ||
if (value.startsWith('--') && !isVarException) { | ||
return `var(${value})` | ||
@@ -34,3 +61,3 @@ } | ||
return normalize(part, false) | ||
return normalize(part, context, false) | ||
}) | ||
@@ -54,14 +81,3 @@ .join('') | ||
// Add spaces around operators inside math functions like calc() that do not follow an operator | ||
// or '('. | ||
value = value.replace(/(calc|min|max|clamp)\(.+\)/g, (match) => { | ||
let vars = [] | ||
return match | ||
.replace(/var\((--.+?)[,)]/g, (match, g1) => { | ||
vars.push(g1) | ||
return match.replace(g1, placeholder) | ||
}) | ||
.replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g, '$1 $2 ') | ||
.replace(placeholderRe, () => vars.shift()) | ||
}) | ||
value = normalizeMathOperatorSpacing(value) | ||
@@ -71,2 +87,144 @@ return value | ||
export function normalizeAttributeSelectors(value) { | ||
// Wrap values in attribute selectors with quotes | ||
if (value.includes('=')) { | ||
value = value.replace(/(=.*)/g, (_fullMatch, match) => { | ||
if (match[1] === "'" || match[1] === '"') { | ||
return match | ||
} | ||
// Handle regex flags on unescaped values | ||
if (match.length > 2) { | ||
let trailingCharacter = match[match.length - 1] | ||
if ( | ||
match[match.length - 2] === ' ' && | ||
(trailingCharacter === 'i' || | ||
trailingCharacter === 'I' || | ||
trailingCharacter === 's' || | ||
trailingCharacter === 'S') | ||
) { | ||
return `="${match.slice(1, -2)}" ${match[match.length - 1]}` | ||
} | ||
} | ||
return `="${match.slice(1)}"` | ||
}) | ||
} | ||
return value | ||
} | ||
/** | ||
* Add spaces around operators inside math functions | ||
* like calc() that do not follow an operator, '(', or `,`. | ||
* | ||
* @param {string} value | ||
* @returns {string} | ||
*/ | ||
function normalizeMathOperatorSpacing(value) { | ||
let preventFormattingInFunctions = ['theme'] | ||
let preventFormattingKeywords = [ | ||
'min-content', | ||
'max-content', | ||
'fit-content', | ||
// Env | ||
'safe-area-inset-top', | ||
'safe-area-inset-right', | ||
'safe-area-inset-bottom', | ||
'safe-area-inset-left', | ||
'titlebar-area-x', | ||
'titlebar-area-y', | ||
'titlebar-area-width', | ||
'titlebar-area-height', | ||
'keyboard-inset-top', | ||
'keyboard-inset-right', | ||
'keyboard-inset-bottom', | ||
'keyboard-inset-left', | ||
'keyboard-inset-width', | ||
'keyboard-inset-height', | ||
'radial-gradient', | ||
'linear-gradient', | ||
'conic-gradient', | ||
'repeating-radial-gradient', | ||
'repeating-linear-gradient', | ||
'repeating-conic-gradient', | ||
] | ||
return value.replace(/(calc|min|max|clamp)\(.+\)/g, (match) => { | ||
let result = '' | ||
function lastChar() { | ||
let char = result.trimEnd() | ||
return char[char.length - 1] | ||
} | ||
for (let i = 0; i < match.length; i++) { | ||
function peek(word) { | ||
return word.split('').every((char, j) => match[i + j] === char) | ||
} | ||
function consumeUntil(chars) { | ||
let minIndex = Infinity | ||
for (let char of chars) { | ||
let index = match.indexOf(char, i) | ||
if (index !== -1 && index < minIndex) { | ||
minIndex = index | ||
} | ||
} | ||
let result = match.slice(i, minIndex) | ||
i += result.length - 1 | ||
return result | ||
} | ||
let char = match[i] | ||
// Handle `var(--variable)` | ||
if (peek('var')) { | ||
// When we consume until `)`, then we are dealing with this scenario: | ||
// `var(--example)` | ||
// | ||
// When we consume until `,`, then we are dealing with this scenario: | ||
// `var(--example, 1rem)` | ||
// | ||
// In this case we do want to "format", the default value as well | ||
result += consumeUntil([')', ',']) | ||
} | ||
// Skip formatting of known keywords | ||
else if (preventFormattingKeywords.some((keyword) => peek(keyword))) { | ||
let keyword = preventFormattingKeywords.find((keyword) => peek(keyword)) | ||
result += keyword | ||
i += keyword.length - 1 | ||
} | ||
// Skip formatting inside known functions | ||
else if (preventFormattingInFunctions.some((fn) => peek(fn))) { | ||
result += consumeUntil([')']) | ||
} | ||
// Don't break CSS grid track names | ||
else if (peek('[')) { | ||
result += consumeUntil([']']) | ||
} | ||
// Handle operators | ||
else if ( | ||
['+', '-', '*', '/'].includes(char) && | ||
!['(', '+', '-', '*', '/', ','].includes(lastChar()) | ||
) { | ||
result += ` ${char} ` | ||
} else { | ||
result += char | ||
} | ||
} | ||
// Simplify multiple spaces | ||
return result.replace(/\s+/g, ' ') | ||
}) | ||
} | ||
export function url(value) { | ||
@@ -185,7 +343,8 @@ return value.startsWith('url(') | ||
let gradientTypes = new Set([ | ||
'conic-gradient', | ||
'linear-gradient', | ||
'radial-gradient', | ||
'repeating-conic-gradient', | ||
'repeating-linear-gradient', | ||
'repeating-radial-gradient', | ||
'conic-gradient', | ||
]) | ||
@@ -276,3 +435,3 @@ export function gradient(value) { | ||
'x-large', | ||
'x-large', | ||
'xx-large', | ||
'xxx-large', | ||
@@ -279,0 +438,0 @@ ]) |
@@ -5,2 +5,4 @@ import selectorParser from 'postcss-selector-parser' | ||
import prefixSelector from '../util/prefixSelector' | ||
import { movePseudos } from './pseudoElements' | ||
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly' | ||
@@ -12,3 +14,3 @@ /** @typedef {import('postcss-selector-parser').Root} Root */ | ||
/** @typedef {{format: string, isArbitraryVariant: boolean}[]} RawFormats */ | ||
/** @typedef {{format: string, respectPrefix: boolean}[]} RawFormats */ | ||
/** @typedef {import('postcss-selector-parser').Root} ParsedFormats */ | ||
@@ -33,3 +35,3 @@ /** @typedef {RawFormats | ParsedFormats} AcceptedFormats */ | ||
...format, | ||
ast: format.isArbitraryVariant ? ast : prefixSelector(prefix, ast), | ||
ast: format.respectPrefix ? prefixSelector(prefix, ast) : ast, | ||
} | ||
@@ -126,3 +128,3 @@ }) | ||
*/ | ||
function eliminateIrrelevantSelectors(sel, base) { | ||
export function eliminateIrrelevantSelectors(sel, base) { | ||
let hasClassesMatchingCandidate = false | ||
@@ -166,3 +168,3 @@ | ||
// | ||
base = base ?? candidate.split(new RegExp(`\\${separator}(?![^[]*\\])`)).pop() | ||
base = base ?? splitAtTopLevelOnly(candidate, separator).pop() | ||
@@ -192,2 +194,9 @@ // Parse the selector into an AST | ||
// If ffter eliminating irrelevant selectors, we end up with nothing | ||
// Then the whole "rule" this is associated with does not need to exist | ||
// We use `null` as a marker value for that case | ||
if (selector.length === 0) { | ||
return null | ||
} | ||
// If there are no formats that means there were no variants added to the candidate | ||
@@ -227,3 +236,3 @@ // so we can just return the selector as-is | ||
for (let child of formatNodes) { | ||
parent.insertBefore(simpleSelector[0], child) | ||
parent.insertBefore(simpleSelector[0], child.clone()) | ||
} | ||
@@ -255,8 +264,3 @@ | ||
// Move pseudo elements to the end of the selector (if necessary) | ||
selector.each((sel) => { | ||
let pseudoElements = collectPseudoElements(sel) | ||
if (pseudoElements.length > 0) { | ||
sel.nodes.push(pseudoElements.sort(sortSelector)) | ||
} | ||
}) | ||
selector.each((sel) => movePseudos(sel)) | ||
@@ -329,93 +333,1 @@ return selector.toString() | ||
} | ||
// Note: As a rule, double colons (::) should be used instead of a single colon | ||
// (:). This distinguishes pseudo-classes from pseudo-elements. However, since | ||
// this distinction was not present in older versions of the W3C spec, most | ||
// browsers support both syntaxes for the original pseudo-elements. | ||
let pseudoElementsBC = [':before', ':after', ':first-line', ':first-letter'] | ||
// These pseudo-elements _can_ be combined with other pseudo selectors AND the order does matter. | ||
let pseudoElementExceptions = [ | ||
'::file-selector-button', | ||
// Webkit scroll bar pseudo elements can be combined with user-action pseudo classes | ||
'::-webkit-scrollbar', | ||
'::-webkit-scrollbar-button', | ||
'::-webkit-scrollbar-thumb', | ||
'::-webkit-scrollbar-track', | ||
'::-webkit-scrollbar-track-piece', | ||
'::-webkit-scrollbar-corner', | ||
'::-webkit-resizer', | ||
] | ||
/** | ||
* This will make sure to move pseudo's to the correct spot (the end for | ||
* pseudo elements) because otherwise the selector will never work | ||
* anyway. | ||
* | ||
* E.g.: | ||
* - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before` | ||
* - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before` | ||
* | ||
* `::before:hover` doesn't work, which means that we can make it work for you by flipping the order. | ||
* | ||
* @param {Selector} selector | ||
**/ | ||
function collectPseudoElements(selector) { | ||
/** @type {Node[]} */ | ||
let nodes = [] | ||
for (let node of selector.nodes) { | ||
if (isPseudoElement(node)) { | ||
nodes.push(node) | ||
selector.removeChild(node) | ||
} | ||
if (node?.nodes) { | ||
nodes.push(...collectPseudoElements(node)) | ||
} | ||
} | ||
return nodes | ||
} | ||
// This will make sure to move pseudo's to the correct spot (the end for | ||
// pseudo elements) because otherwise the selector will never work | ||
// anyway. | ||
// | ||
// E.g.: | ||
// - `before:hover:text-center` would result in `.before\:hover\:text-center:hover::before` | ||
// - `hover:before:text-center` would result in `.hover\:before\:text-center:hover::before` | ||
// | ||
// `::before:hover` doesn't work, which means that we can make it work | ||
// for you by flipping the order. | ||
function sortSelector(a, z) { | ||
// Both nodes are non-pseudo's so we can safely ignore them and keep | ||
// them in the same order. | ||
if (a.type !== 'pseudo' && z.type !== 'pseudo') { | ||
return 0 | ||
} | ||
// If one of them is a combinator, we need to keep it in the same order | ||
// because that means it will start a new "section" in the selector. | ||
if ((a.type === 'combinator') ^ (z.type === 'combinator')) { | ||
return 0 | ||
} | ||
// One of the items is a pseudo and the other one isn't. Let's move | ||
// the pseudo to the right. | ||
if ((a.type === 'pseudo') ^ (z.type === 'pseudo')) { | ||
return (a.type === 'pseudo') - (z.type === 'pseudo') | ||
} | ||
// Both are pseudo's, move the pseudo elements (except for | ||
// ::file-selector-button) to the right. | ||
return isPseudoElement(a) - isPseudoElement(z) | ||
} | ||
function isPseudoElement(node) { | ||
if (node.type !== 'pseudo') return false | ||
if (pseudoElementExceptions.includes(node.value)) return false | ||
return node.value.startsWith('::') || pseudoElementsBC.includes(node.value) | ||
} |
@@ -1,6 +0,6 @@ | ||
import defaultConfig from '../../stubs/defaultConfig.stub.js' | ||
import defaultFullConfig from '../../stubs/config.full.js' | ||
import { flagEnabled } from '../featureFlags' | ||
export default function getAllConfigs(config) { | ||
const configs = (config?.presets ?? [defaultConfig]) | ||
const configs = (config?.presets ?? [defaultFullConfig]) | ||
.slice() | ||
@@ -7,0 +7,0 @@ .reverse() |
@@ -7,3 +7,3 @@ export default function isPlainObject(value) { | ||
const prototype = Object.getPrototypeOf(value) | ||
return prototype === null || prototype === Object.prototype | ||
return prototype === null || Object.getPrototypeOf(prototype) === null | ||
} |
@@ -0,1 +1,2 @@ | ||
import { flagEnabled } from '../featureFlags' | ||
import log, { dim } from './log' | ||
@@ -192,3 +193,3 @@ | ||
return config.future?.relativeContentPathsByDefault ?? false | ||
return flagEnabled(config, 'relativeContentPathsByDefault') | ||
})(), | ||
@@ -277,5 +278,3 @@ | ||
transformers.DEFAULT = transform | ||
} | ||
if (typeof transform === 'object' && transform !== null) { | ||
} else if (typeof transform === 'object' && transform !== null) { | ||
Object.assign(transformers, transform) | ||
@@ -282,0 +281,0 @@ } |
@@ -16,3 +16,3 @@ const DIRECTIONS = new Set(['normal', 'reverse', 'alternate', 'alternate-reverse']) | ||
const COMMA = /\,(?![^(]*\))/g // Comma separator that is not located between brackets. E.g.: `cubiz-bezier(a, b, c)` these don't count. | ||
const COMMA = /\,(?![^(]*\))/g // Comma separator that is not located between brackets. E.g.: `cubic-bezier(a, b, c)` these don't count. | ||
const SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces instead. | ||
@@ -19,0 +19,0 @@ const TIME = /^(-?[\d.]+m?s)$/ |
@@ -18,4 +18,3 @@ import globParent from 'glob-parent' | ||
glob = glob.substr(2) | ||
} | ||
if (glob.charAt(0) === '/') { | ||
} else if (glob.charAt(0) === '/') { | ||
glob = glob.substr(1) | ||
@@ -22,0 +21,0 @@ } |
@@ -1,2 +0,1 @@ | ||
import selectorParser from 'postcss-selector-parser' | ||
import escapeCommas from './escapeCommas' | ||
@@ -24,33 +23,15 @@ import { withAlphaValue } from './withAlphaVariable' | ||
/** | ||
* @param {import('postcss-selector-parser').Container} selectors | ||
* @param {(className: string) => string} updateClass | ||
* @returns {string} | ||
*/ | ||
export function updateAllClasses(selectors, updateClass) { | ||
let parser = selectorParser((selectors) => { | ||
selectors.walkClasses((sel) => { | ||
let updatedClass = updateClass(sel.value) | ||
sel.value = updatedClass | ||
if (sel.raws && sel.raws.value) { | ||
sel.raws.value = escapeCommas(sel.raws.value) | ||
} | ||
}) | ||
}) | ||
selectors.walkClasses((sel) => { | ||
sel.value = updateClass(sel.value) | ||
let result = parser.processSync(selectors) | ||
return result | ||
} | ||
export function filterSelectorsForClass(selectors, classCandidate) { | ||
let parser = selectorParser((selectors) => { | ||
selectors.each((sel) => { | ||
const containsClass = sel.nodes.some( | ||
(node) => node.type === 'class' && node.value === classCandidate | ||
) | ||
if (!containsClass) { | ||
sel.remove() | ||
} | ||
}) | ||
if (sel.raws && sel.raws.value) { | ||
sel.raws.value = escapeCommas(sel.raws.value) | ||
} | ||
}) | ||
let result = parser.processSync(selectors) | ||
return result | ||
} | ||
@@ -111,2 +92,18 @@ | ||
// If the `/` is inside an arbitrary, we want to find the previous one if any | ||
// This logic probably isn't perfect but it should work for most cases | ||
let arbitraryStartIdx = modifier.lastIndexOf('[', slashIdx) | ||
let arbitraryEndIdx = modifier.indexOf(']', slashIdx) | ||
let isNextToArbitrary = modifier[slashIdx - 1] === ']' || modifier[slashIdx + 1] === '[' | ||
// Backtrack to the previous `/` if the one we found was inside an arbitrary | ||
if (!isNextToArbitrary) { | ||
if (arbitraryStartIdx !== -1 && arbitraryEndIdx !== -1) { | ||
if (arbitraryStartIdx < slashIdx && slashIdx < arbitraryEndIdx) { | ||
slashIdx = modifier.lastIndexOf('/', arbitraryStartIdx) | ||
} | ||
} | ||
} | ||
if (slashIdx === -1 || slashIdx === modifier.length - 1) { | ||
@@ -132,3 +129,3 @@ return [modifier, undefined] | ||
return ({ opacityValue = 1 }) => oldValue.replace('<alpha-value>', opacityValue) | ||
return ({ opacityValue = 1 }) => oldValue.replace(/<alpha-value>/g, opacityValue) | ||
} | ||
@@ -140,7 +137,3 @@ | ||
function unwrapArbitraryModifier(modifier) { | ||
modifier = modifier.slice(1, -1) | ||
if (modifier.startsWith('--')) { | ||
modifier = `var(${modifier})` | ||
} | ||
return modifier | ||
return normalize(modifier.slice(1, -1)) | ||
} | ||
@@ -147,0 +140,0 @@ |
@@ -20,2 +20,3 @@ import parser from 'postcss-selector-parser' | ||
/** @type {import('postcss-selector-parser').Root} */ | ||
let ast = typeof selector === 'string' ? parser().astSync(selector) : selector | ||
@@ -22,0 +23,0 @@ |
import fs from 'fs' | ||
import path from 'path' | ||
const defaultConfigFiles = [ | ||
'./tailwind.config.js', | ||
'./tailwind.config.cjs', | ||
'./tailwind.config.mjs', | ||
'./tailwind.config.ts', | ||
'./tailwind.config.cts', | ||
'./tailwind.config.mts', | ||
] | ||
function isObject(value) { | ||
@@ -46,3 +55,7 @@ return typeof value === 'object' && value !== null | ||
// require('tailwindcss') | ||
for (const configFile of ['./tailwind.config.js', './tailwind.config.cjs']) { | ||
return resolveDefaultConfigPath() | ||
} | ||
export function resolveDefaultConfigPath() { | ||
for (const configFile of defaultConfigFiles) { | ||
try { | ||
@@ -49,0 +62,0 @@ const configPath = path.resolve(configFile) |
@@ -20,2 +20,3 @@ /** | ||
let lastPos = 0 | ||
let isEscaped = false | ||
@@ -25,3 +26,3 @@ for (let idx = 0; idx < input.length; idx++) { | ||
if (stack.length === 0 && char === separator[0]) { | ||
if (stack.length === 0 && char === separator[0] && !isEscaped) { | ||
if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) { | ||
@@ -33,2 +34,4 @@ parts.push(input.slice(lastPos, idx)) | ||
isEscaped = isEscaped ? false : char === '\\' | ||
if (char === '(' || char === '[' || char === '{') { | ||
@@ -35,0 +38,0 @@ stack.push(char) |
@@ -12,3 +12,16 @@ import log from './log' | ||
// Warn if the line-clamp plugin is installed | ||
try { | ||
let plugin = require('@tailwindcss/line-clamp') | ||
if (config.plugins.includes(plugin)) { | ||
log.warn('line-clamp-in-core', [ | ||
'As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.', | ||
'Remove it from the `plugins` array in your configuration to eliminate this warning.', | ||
]) | ||
config.plugins = config.plugins.filter((p) => p !== plugin) | ||
} | ||
} catch {} | ||
return config | ||
} |
@@ -49,14 +49,9 @@ import type { CorePluginList } from './generated/corePluginList' | ||
// Safelist related config | ||
type SafelistConfig = | ||
| string[] | ||
| { | ||
pattern: RegExp | ||
variants?: string[] | ||
}[] | ||
type SafelistConfig = string | { pattern: RegExp; variants?: string[] } | ||
// Blocklist related config | ||
type BlocklistConfig = string[] | ||
type BlocklistConfig = string | ||
// Presets related config | ||
type PresetsConfig = Config[] | ||
type PresetsConfig = Partial<Config> | ||
@@ -83,2 +78,9 @@ // Future related config | ||
| ['class', string] | ||
// Use the `selector` strategy — same as `class` but uses `:where()` for more predicable behavior | ||
| 'selector' | ||
// Use the `selector` strategy with a custom selector instead of `.dark`. | ||
| ['selector', string] | ||
// Use the `variant` strategy, which allows you to completely customize the selector | ||
// It takes a string or an array of strings, which are passed directly to `addVariant()` | ||
| ['variant', string | string[]] | ||
@@ -89,3 +91,3 @@ type Screen = { raw: string } | { min: string } | { max: string } | { min: string; max: string } | ||
// Theme related config | ||
interface ThemeConfig { | ||
export interface ThemeConfig { | ||
// Responsiveness | ||
@@ -174,3 +176,9 @@ screens: ResolvableTo<ScreensConfig> | ||
| string[] | ||
| [fontFamily: string | string[], configuration: Partial<{ fontFeatureSettings: string }>] | ||
| [ | ||
fontFamily: string | string[], | ||
configuration: Partial<{ | ||
fontFeatureSettings: string | ||
fontVariationSettings: string | ||
}> | ||
] | ||
> | ||
@@ -240,4 +248,5 @@ > | ||
content: ResolvableTo<KeyValuePair> | ||
} | ||
// Custom | ||
interface CustomThemeConfig extends ThemeConfig { | ||
[key: string]: any | ||
@@ -359,9 +368,9 @@ } | ||
separator: Partial<SeparatorConfig> | ||
safelist: Partial<SafelistConfig> | ||
blocklist: Partial<BlocklistConfig> | ||
presets: Partial<PresetsConfig> | ||
safelist: Array<SafelistConfig> | ||
blocklist: Array<BlocklistConfig> | ||
presets: Array<PresetsConfig> | ||
future: Partial<FutureConfig> | ||
experimental: Partial<ExperimentalConfig> | ||
darkMode: Partial<DarkModeConfig> | ||
theme: Partial<ThemeConfig & { extend: Partial<ThemeConfig> }> | ||
theme: Partial<CustomThemeConfig & { extend: Partial<CustomThemeConfig> }> | ||
corePlugins: Partial<CorePluginsConfig> | ||
@@ -368,0 +377,0 @@ plugins: Partial<PluginsConfig> |
@@ -18,2 +18,3 @@ export interface DefaultColors { | ||
'900': '#0f172a' | ||
'950': '#020617' | ||
} | ||
@@ -31,2 +32,3 @@ gray: { | ||
'900': '#111827' | ||
'950': '#030712' | ||
} | ||
@@ -44,2 +46,3 @@ zinc: { | ||
'900': '#18181b' | ||
'950': '#09090b' | ||
} | ||
@@ -57,2 +60,3 @@ neutral: { | ||
'900': '#171717' | ||
'950': '#0a0a0a' | ||
} | ||
@@ -70,2 +74,3 @@ stone: { | ||
'900': '#1c1917' | ||
'950': '#0c0a09' | ||
} | ||
@@ -83,2 +88,3 @@ red: { | ||
'900': '#7f1d1d' | ||
'950': '#450a0a' | ||
} | ||
@@ -96,2 +102,3 @@ orange: { | ||
'900': '#7c2d12' | ||
'950': '#431407' | ||
} | ||
@@ -109,2 +116,3 @@ amber: { | ||
'900': '#78350f' | ||
'950': '#451a03' | ||
} | ||
@@ -122,2 +130,3 @@ yellow: { | ||
'900': '#713f12' | ||
'950': '#422006' | ||
} | ||
@@ -135,2 +144,3 @@ lime: { | ||
'900': '#365314' | ||
'950': '#1a2e05' | ||
} | ||
@@ -148,2 +158,3 @@ green: { | ||
'900': '#14532d' | ||
'950': '#052e16' | ||
} | ||
@@ -161,2 +172,3 @@ emerald: { | ||
'900': '#064e3b' | ||
'950': '#022c22' | ||
} | ||
@@ -174,2 +186,3 @@ teal: { | ||
'900': '#134e4a' | ||
'950': '#042f2e' | ||
} | ||
@@ -187,2 +200,3 @@ cyan: { | ||
'900': '#164e63' | ||
'950': '#083344' | ||
} | ||
@@ -200,2 +214,3 @@ sky: { | ||
'900': '#0c4a6e' | ||
'950': '#082f49' | ||
} | ||
@@ -213,2 +228,3 @@ blue: { | ||
'900': '#1e3a8a' | ||
'950': '#172554' | ||
} | ||
@@ -226,2 +242,3 @@ indigo: { | ||
'900': '#312e81' | ||
'950': '#1e1b4b' | ||
} | ||
@@ -239,2 +256,3 @@ violet: { | ||
'900': '#4c1d95' | ||
'950': '#2e1065' | ||
} | ||
@@ -252,2 +270,3 @@ purple: { | ||
'900': '#581c87' | ||
'950': '#3b0764' | ||
} | ||
@@ -265,2 +284,3 @@ fuchsia: { | ||
'900': '#701a75' | ||
'950': '#4a044e' | ||
} | ||
@@ -278,2 +298,3 @@ pink: { | ||
'900': '#831843' | ||
'950': '#500724' | ||
} | ||
@@ -291,2 +312,3 @@ rose: { | ||
'900': '#881337' | ||
'950': '#4c0519' | ||
} | ||
@@ -293,0 +315,0 @@ /** @deprecated As of Tailwind CSS v2.2, `lightBlue` has been renamed to `sky`. Update your configuration file to silence this warning. */ lightBlue: DefaultColors['sky'] |
@@ -1,1 +0,1 @@ | ||
export type CorePluginList = 'preflight' | 'container' | 'accessibility' | 'pointerEvents' | 'visibility' | 'position' | 'inset' | 'isolation' | 'zIndex' | 'order' | 'gridColumn' | 'gridColumnStart' | 'gridColumnEnd' | 'gridRow' | 'gridRowStart' | 'gridRowEnd' | 'float' | 'clear' | 'margin' | 'boxSizing' | 'display' | 'aspectRatio' | 'height' | 'maxHeight' | 'minHeight' | 'width' | 'minWidth' | 'maxWidth' | 'flex' | 'flexShrink' | 'flexGrow' | 'flexBasis' | 'tableLayout' | 'borderCollapse' | 'borderSpacing' | 'transformOrigin' | 'translate' | 'rotate' | 'skew' | 'scale' | 'transform' | 'animation' | 'cursor' | 'touchAction' | 'userSelect' | 'resize' | 'scrollSnapType' | 'scrollSnapAlign' | 'scrollSnapStop' | 'scrollMargin' | 'scrollPadding' | 'listStylePosition' | 'listStyleType' | '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' | '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' | ||
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' | 'size' | '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' | 'contain' | 'content' | 'forcedColorAdjust' |
@@ -1,6 +0,6 @@ | ||
import { Config } from '../../types' | ||
type CSSDeclarationList = Record<string, string> | ||
export type DefaultTheme = Config['theme'] & { | ||
export type DefaultTheme = { | ||
animation: Record<'none' | 'spin' | 'ping' | 'pulse' | 'bounce', string> | ||
aria: Record< | ||
| 'busy' | ||
| 'checked' | ||
@@ -156,2 +156,26 @@ | 'disabled' | ||
> | ||
gradientColorStopPositions: Record< | ||
| '0%' | ||
| '5%' | ||
| '10%' | ||
| '15%' | ||
| '20%' | ||
| '25%' | ||
| '30%' | ||
| '35%' | ||
| '40%' | ||
| '45%' | ||
| '50%' | ||
| '55%' | ||
| '60%' | ||
| '65%' | ||
| '70%' | ||
| '75%' | ||
| '80%' | ||
| '85%' | ||
| '90%' | ||
| '95%' | ||
| '100%', | ||
string | ||
> | ||
grayscale: Record<'0' | 'DEFAULT', string> | ||
@@ -186,12 +210,34 @@ gridAutoColumns: Record<'auto' | 'min' | 'max' | 'fr', string> | ||
gridRow: Record< | ||
'auto' | 'span-1' | 'span-2' | 'span-3' | 'span-4' | 'span-5' | 'span-6' | 'span-full', | ||
| 'auto' | ||
| 'span-1' | ||
| 'span-2' | ||
| 'span-3' | ||
| 'span-4' | ||
| 'span-5' | ||
| 'span-6' | ||
| 'span-7' | ||
| 'span-8' | ||
| 'span-9' | ||
| 'span-10' | ||
| 'span-11' | ||
| 'span-12' | ||
| 'span-full', | ||
string | ||
> | ||
gridRowEnd: Record<'1' | '2' | '3' | '4' | '5' | '6' | '7' | 'auto', string> | ||
gridRowStart: Record<'1' | '2' | '3' | '4' | '5' | '6' | '7' | 'auto', string> | ||
gridRowEnd: Record< | ||
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13' | 'auto', | ||
string | ||
> | ||
gridRowStart: Record< | ||
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13' | 'auto', | ||
string | ||
> | ||
gridTemplateColumns: Record< | ||
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'none', | ||
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'none' | 'subgrid', | ||
string | ||
> | ||
gridTemplateRows: Record<'1' | '2' | '3' | '4' | '5' | '6' | 'none', string> | ||
gridTemplateRows: Record< | ||
'1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | 'none' | 'subgrid', | ||
string | ||
> | ||
hueRotate: Record<'0' | '15' | '30' | '60' | '90' | '180', string> | ||
@@ -219,4 +265,4 @@ invert: Record<'0' | 'DEFAULT', string> | ||
listStyleType: Record<'none' | 'disc' | 'decimal', string> | ||
minHeight: Record<'0' | 'full' | 'screen' | 'min' | 'max' | 'fit', string> | ||
minWidth: Record<'0' | 'full' | 'min' | 'max' | 'fit', string> | ||
listStyleImage: Record<'none', string> | ||
lineClamp: Record<'1' | '2' | '3' | '4' | '5' | '6', string> | ||
objectPosition: Record< | ||
@@ -238,11 +284,17 @@ | 'bottom' | ||
| '10' | ||
| '15' | ||
| '20' | ||
| '25' | ||
| '30' | ||
| '35' | ||
| '40' | ||
| '45' | ||
| '50' | ||
| '55' | ||
| '60' | ||
| '65' | ||
| '70' | ||
| '75' | ||
| '80' | ||
| '85' | ||
| '90' | ||
@@ -249,0 +301,0 @@ | '95' |
@@ -1,2 +0,2 @@ | ||
import { PluginCreator } from 'postcss' | ||
import type { PluginCreator } from 'postcss' | ||
import type { Config } from './config.d' | ||
@@ -6,3 +6,7 @@ | ||
export { Config } | ||
export default plugin | ||
declare type _Config = Config | ||
declare namespace plugin { | ||
export type { _Config as Config } | ||
} | ||
export = plugin |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
5558816
22
251
43
0
19
32790
41
+ Added@alloc/quick-lru@^5.2.0
+ Addedjiti@^1.21.0
+ Addedsucrase@^3.32.0
+ Added@alloc/quick-lru@5.2.0(transitive)
+ Added@isaacs/cliui@8.0.2(transitive)
+ Added@jridgewell/gen-mapping@0.3.5(transitive)
+ Added@jridgewell/resolve-uri@3.1.2(transitive)
+ Added@jridgewell/set-array@1.2.1(transitive)
+ Added@jridgewell/sourcemap-codec@1.5.0(transitive)
+ Added@jridgewell/trace-mapping@0.3.25(transitive)
+ Added@pkgjs/parseargs@0.11.0(transitive)
+ Addedansi-regex@5.0.16.1.0(transitive)
+ Addedansi-styles@4.3.06.2.1(transitive)
+ Addedany-promise@1.3.0(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcommander@4.1.1(transitive)
+ Addedcross-spawn@7.0.3(transitive)
+ Addedeastasianwidth@0.2.0(transitive)
+ Addedemoji-regex@8.0.09.2.2(transitive)
+ Addedforeground-child@3.3.0(transitive)
+ Addedglob@10.4.5(transitive)
+ Addedis-fullwidth-code-point@3.0.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedjackspeak@3.4.3(transitive)
+ Addedjiti@1.21.6(transitive)
+ Addedlilconfig@3.1.2(transitive)
+ Addedlines-and-columns@1.2.4(transitive)
+ Addedlru-cache@10.4.3(transitive)
+ Addedminimatch@9.0.5(transitive)
+ Addedminipass@7.1.2(transitive)
+ Addedmz@2.7.0(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedpackage-json-from-dist@1.0.0(transitive)
+ Addedpath-key@3.1.1(transitive)
+ Addedpath-scurry@1.11.1(transitive)
+ Addedpirates@4.0.6(transitive)
+ Addedpostcss-import@15.1.0(transitive)
+ Addedpostcss-load-config@4.0.2(transitive)
+ Addedpostcss-nested@6.2.0(transitive)
+ Addedshebang-command@2.0.0(transitive)
+ Addedshebang-regex@3.0.0(transitive)
+ Addedsignal-exit@4.1.0(transitive)
+ Addedstring-width@4.2.35.1.2(transitive)
+ Addedstrip-ansi@6.0.17.1.0(transitive)
+ Addedsucrase@3.35.0(transitive)
+ Addedthenify@3.3.1(transitive)
+ Addedthenify-all@1.6.0(transitive)
+ Addedts-interface-checker@0.1.13(transitive)
+ Addedwhich@2.0.2(transitive)
+ Addedwrap-ansi@7.0.08.1.0(transitive)
+ Addedyaml@2.5.1(transitive)
- Removedbrowserslist@^4.21.4
- Removedcolor-name@^1.1.4
- Removeddetective@^5.2.1
- Removedlightningcss@^1.17.1
- Removedpostcss-value-parser@^4.2.0
- Removedquick-lru@^5.1.1
- Removedacorn@7.4.1(transitive)
- Removedacorn-node@1.8.2(transitive)
- Removedacorn-walk@7.2.0(transitive)
- Removedbrowserslist@4.23.3(transitive)
- Removedcaniuse-lite@1.0.30001660(transitive)
- Removeddefined@1.0.1(transitive)
- Removeddetect-libc@1.0.3(transitive)
- Removeddetective@5.2.1(transitive)
- Removedelectron-to-chromium@1.5.20(transitive)
- Removedescalade@3.2.0(transitive)
- Removedlightningcss@1.27.0(transitive)
- Removedlightningcss-darwin-arm64@1.27.0(transitive)
- Removedlightningcss-darwin-x64@1.27.0(transitive)
- Removedlightningcss-freebsd-x64@1.27.0(transitive)
- Removedlightningcss-linux-arm-gnueabihf@1.27.0(transitive)
- Removedlightningcss-linux-arm64-gnu@1.27.0(transitive)
- Removedlightningcss-linux-arm64-musl@1.27.0(transitive)
- Removedlightningcss-linux-x64-gnu@1.27.0(transitive)
- Removedlightningcss-linux-x64-musl@1.27.0(transitive)
- Removedlightningcss-win32-arm64-msvc@1.27.0(transitive)
- Removedlightningcss-win32-x64-msvc@1.27.0(transitive)
- Removedminimist@1.2.8(transitive)
- Removednode-releases@2.0.18(transitive)
- Removedpostcss-import@14.1.0(transitive)
- Removedpostcss-load-config@3.1.4(transitive)
- Removedpostcss-nested@6.0.0(transitive)
- Removedquick-lru@5.1.1(transitive)
- Removedupdate-browserslist-db@1.1.0(transitive)
- Removedxtend@4.0.2(transitive)
- Removedyaml@1.10.2(transitive)
Updatedfast-glob@^3.3.0
Updatedlilconfig@^2.1.0
Updatedpostcss@^8.4.23
Updatedpostcss-import@^15.1.0
Updatedpostcss-js@^4.0.1
Updatedpostcss-load-config@^4.0.1
Updatedpostcss-nested@^6.0.1
Updatedresolve@^1.22.2