diff --git a/package-lock.json b/package-lock.json index e085a2baa..778a7f6f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,8 @@ "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.1" + "resolve": "^1.22.1", + "tailwind-oxide": "file:oxide/crates/node" }, "bin": { "tailwind": "lib/cli.js", @@ -43,6 +44,7 @@ "@swc/jest": "^0.2.23", "@swc/register": "^0.1.10", "autoprefixer": "^10.4.13", + "concurrently": "^7.5.0", "cssnano": "^5.1.14", "esbuild": "^0.15.15", "eslint": "^8.27.0", @@ -1305,6 +1307,22 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@napi-rs/cli": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.12.0.tgz", + "integrity": "sha512-DWx9jDpun9JqDBypiXKjcYMm7gEnh83bry7b6UkItpmVE3w3tNrj91fOEPKDbFQZ7EULfFt+aQBbqtUHq5oNzQ==", + "dev": true, + "bin": { + "napi": "scripts/index.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2409,6 +2427,48 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "node_modules/concurrently": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.5.0.tgz", + "integrity": "sha512-5E3mwiS+i2JYBzr5BpXkFxOnleZTMsG+WnE/dCG4/P+oiVXrbmrBwJ2ozn4SxwB2EZDrKR568X+puVohxz3/Mg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.29.1", + "lodash": "^4.17.21", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^17.3.1" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/convert-source-map": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", @@ -2584,6 +2644,19 @@ "node": ">=8.0.0" } }, + "node_modules/date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "dev": true, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -5138,6 +5211,12 @@ "node": ">=8" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -6382,6 +6461,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -6418,6 +6506,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -6466,6 +6563,12 @@ "source-map": "^0.6.0" } }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -6642,6 +6745,10 @@ "node": ">=10.13.0" } }, + "node_modules/tailwind-oxide": { + "resolved": "oxide/crates/node", + "link": true + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -6693,6 +6800,21 @@ "node": ">=4" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "dev": true + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -6906,6 +7028,35 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "oxide-setup.js": { + "extraneous": true + }, + "oxide/crates/node": { + "name": "tailwind-oxide", + "version": "0.0.0", + "license": "MIT", + "devDependencies": { + "@napi-rs/cli": "^2.12.0" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "tailwind-oxide-android-arm-eabi": "0.0.0", + "tailwind-oxide-android-arm64": "0.0.0", + "tailwind-oxide-darwin-arm64": "0.0.0", + "tailwind-oxide-darwin-x64": "0.0.0", + "tailwind-oxide-freebsd-x64": "0.0.0", + "tailwind-oxide-linux-arm-gnueabihf": "0.0.0", + "tailwind-oxide-linux-arm64-gnu": "0.0.0", + "tailwind-oxide-linux-arm64-musl": "0.0.0", + "tailwind-oxide-linux-x64-gnu": "0.0.0", + "tailwind-oxide-linux-x64-musl": "0.0.0", + "tailwind-oxide-win32-arm64-msvc": "0.0.0", + "tailwind-oxide-win32-ia32-msvc": "0.0.0", + "tailwind-oxide-win32-x64-msvc": "0.0.0" + } } }, "dependencies": { @@ -7893,6 +8044,12 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@napi-rs/cli": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.12.0.tgz", + "integrity": "sha512-DWx9jDpun9JqDBypiXKjcYMm7gEnh83bry7b6UkItpmVE3w3tNrj91fOEPKDbFQZ7EULfFt+aQBbqtUHq5oNzQ==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -8680,6 +8837,34 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concurrently": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.5.0.tgz", + "integrity": "sha512-5E3mwiS+i2JYBzr5BpXkFxOnleZTMsG+WnE/dCG4/P+oiVXrbmrBwJ2ozn4SxwB2EZDrKR568X+puVohxz3/Mg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.29.1", + "lodash": "^4.17.21", + "rxjs": "^7.0.0", + "shell-quote": "^1.7.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^17.3.1" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "convert-source-map": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", @@ -8805,6 +8990,12 @@ "css-tree": "^1.1.2" } }, + "date-fns": { + "version": "2.29.3", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz", + "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==", + "dev": true + }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -10689,6 +10880,12 @@ "p-locate": "^4.1.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -11502,6 +11699,15 @@ "queue-microtask": "^1.2.2" } }, + "rxjs": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz", + "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -11529,6 +11735,12 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -11568,6 +11780,12 @@ "source-map": "^0.6.0" } }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==", + "dev": true + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -11694,6 +11912,25 @@ "stable": "^0.1.8" } }, + "tailwind-oxide": { + "version": "file:oxide/crates/node", + "requires": { + "@napi-rs/cli": "^2.12.0", + "tailwind-oxide-android-arm-eabi": "0.0.0", + "tailwind-oxide-android-arm64": "0.0.0", + "tailwind-oxide-darwin-arm64": "0.0.0", + "tailwind-oxide-darwin-x64": "0.0.0", + "tailwind-oxide-freebsd-x64": "0.0.0", + "tailwind-oxide-linux-arm-gnueabihf": "0.0.0", + "tailwind-oxide-linux-arm64-gnu": "0.0.0", + "tailwind-oxide-linux-arm64-musl": "0.0.0", + "tailwind-oxide-linux-x64-gnu": "0.0.0", + "tailwind-oxide-linux-x64-musl": "0.0.0", + "tailwind-oxide-win32-arm64-msvc": "0.0.0", + "tailwind-oxide-win32-ia32-msvc": "0.0.0", + "tailwind-oxide-win32-x64-msvc": "0.0.0" + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -11733,6 +11970,18 @@ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "dev": true + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", diff --git a/package.json b/package.json index 25fbb36f5..24700cd07 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,19 @@ "tailwindcss": "lib/cli.js" }, "scripts": { +<<<<<<< HEAD "prebuild": "npm run generate && rimraf lib", "build": "swc src --out-dir lib --copy-files", "postbuild": "esbuild lib/cli-peer-dependencies.js --bundle --platform=node --outfile=peers/index.js", "rebuild-fixtures": "npm run build && node -r @swc/register scripts/rebuildFixtures.js", "prepublishOnly": "npm install --force && npm run build", +======= + "preswcify": "npm run generate && rimraf lib", + "swcify": "swc src --out-dir lib --copy-files", + "postswcify": "esbuild lib/cli-peer-dependencies.js --bundle --platform=node --outfile=peers/index.js", + "rebuild-fixtures": "npm run swcify && node -r @swc/register scripts/rebuildFixtures.js", + "prepublishOnly": "npm install --force && npm run oxide:install --force && npm run oxide:build", +>>>>>>> 593bb486 (use oxide) "style": "eslint .", "pretest": "npm run generate", "test": "jest", @@ -27,7 +35,10 @@ "generate:types": "node -r @swc/register scripts/generate-types.js", "generate": "npm run generate:plugin-list && npm run generate:types", "release-channel": "node ./scripts/release-channel.js", - "release-notes": "node ./scripts/release-notes.js" + "release-notes": "node ./scripts/release-notes.js", + "oxide:install": "npm install --prefix ./oxide", + "oxide:dev": "concurrently -n tailwind,oxide-node -c green,yellow 'npm run swcify -- --watch' 'npm run --prefix ./oxide dev:node'", + "oxide:build": "npm run --prefix ./oxide build:node && npm run swcify" }, "files": [ "src/*", @@ -48,6 +59,7 @@ "@swc/jest": "^0.2.23", "@swc/register": "^0.1.10", "autoprefixer": "^10.4.13", + "concurrently": "^7.5.0", "cssnano": "^5.1.14", "esbuild": "^0.15.15", "eslint": "^8.27.0", @@ -85,7 +97,8 @@ "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.1" + "resolve": "^1.22.1", + "tailwind-oxide": "file:oxide/crates/node" }, "browserslist": [ "> 1%", diff --git a/src/cli/build/plugin.js b/src/cli/build/plugin.js index 1619dd38e..e79d96dc7 100644 --- a/src/cli/build/plugin.js +++ b/src/cli/build/plugin.js @@ -184,10 +184,17 @@ let state = { let files = fastGlob.sync(this.contentPatterns.all) for (let file of files) { - content.push({ - content: fs.readFileSync(path.resolve(file), 'utf8'), - extension: path.extname(file).slice(1), - }) + 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), + }) + } } // Resolve raw content in the tailwind config @@ -234,11 +241,9 @@ let state = { env.DEBUG && console.timeEnd('Watch new files') } - env.DEBUG && console.time('Reading content files') for (let file of this.readContentPaths()) { this.context.changedContent.push(file) } - env.DEBUG && console.timeEnd('Reading content files') return this.context }, diff --git a/src/cli/shared.js b/src/cli/shared.js index 56c85fda4..9466657f5 100644 --- a/src/cli/shared.js +++ b/src/cli/shared.js @@ -2,4 +2,5 @@ export const env = { DEBUG: process.env.DEBUG !== undefined && process.env.DEBUG !== '0', + OXIDE: process.env.OXIDE, } diff --git a/src/lib/content.js b/src/lib/content.js index 0f89913d2..dae69f132 100644 --- a/src/lib/content.js +++ b/src/lib/content.js @@ -172,9 +172,8 @@ export function resolvedChangedContent(context, candidateFiles, fileModifiedMap) .map(({ raw, extension = 'html' }) => ({ content: raw, extension })) for (let changedFile of resolveChangedFiles(candidateFiles, fileModifiedMap)) { - let content = fs.readFileSync(changedFile, 'utf8') let extension = path.extname(changedFile).slice(1) - changedContent.push({ content, extension }) + changedContent.push({ file: changedFile, extension }) } return changedContent diff --git a/src/lib/expandTailwindAtRules.js b/src/lib/expandTailwindAtRules.js index 040f713b0..f363bdc13 100644 --- a/src/lib/expandTailwindAtRules.js +++ b/src/lib/expandTailwindAtRules.js @@ -1,3 +1,4 @@ +import fs from 'fs' import LRU from 'quick-lru' import * as sharedState from './sharedState' import { generateRules } from './generateRules' @@ -5,6 +6,8 @@ import log from '../util/log' import cloneNodes from '../util/cloneNodes' import { defaultExtractor } from './defaultExtractor' +import oxide from 'tailwind-oxide' + let env = sharedState.env const builtInExtractors = { @@ -124,15 +127,32 @@ export default function expandTailwindAtRules(context) { // --- // Find potential rules in changed files - let candidates = new Set([sharedState.NOT_ON_DEMAND]) + let candidates = new Set([...(context.candidates ?? []), sharedState.NOT_ON_DEMAND]) let seen = new Set() env.DEBUG && console.time('Reading changed files') - for (let { content, extension } of context.changedContent) { - let transformer = getTransformer(context.tailwindConfig, extension) - let extractor = getExtractor(context, extension) - getClassCandidates(transformer(content), extractor, candidates, seen) + 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) + } + + // 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) + } } env.DEBUG && console.timeEnd('Reading changed files') @@ -143,7 +163,21 @@ export default function expandTailwindAtRules(context) { let classCacheCount = context.classCache.size env.DEBUG && console.time('Generate rules') - generateRules(candidates, context) + // 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 + env.DEBUG && console.timeEnd('Sorting candidates') + generateRules(sortedCandidates, context) env.DEBUG && console.timeEnd('Generate rules') // We only ever add to the classCache, so if it didn't grow, there is nothing new. diff --git a/src/lib/sharedState.js b/src/lib/sharedState.js index caf7a7319..4c87a0a31 100644 --- a/src/lib/sharedState.js +++ b/src/lib/sharedState.js @@ -1,6 +1,7 @@ export const env = { NODE_ENV: process.env.NODE_ENV, DEBUG: resolveDebug(process.env.DEBUG), + OXIDE: process.env.OXIDE, } export const contextMap = new Map() export const configContextMap = new Map() diff --git a/src/util/negateValue.js b/src/util/negateValue.js index 8dfbfa358..b1cdf78ea 100644 --- a/src/util/negateValue.js +++ b/src/util/negateValue.js @@ -1,4 +1,4 @@ -export default function (value) { +export default function negateValue(value) { value = `${value}` if (value === '0') { diff --git a/tests/any-type.test.js b/tests/any-type.test.js index c7ffa8e03..ebfefd3c8 100644 --- a/tests/any-type.test.js +++ b/tests/any-type.test.js @@ -199,18 +199,18 @@ test('any types are set on correct plugins', () => { top: var(--any-value); bottom: var(--any-value); } - .top-\[var\(--any-value\)\] { - top: var(--any-value); - } - .right-\[var\(--any-value\)\] { - right: var(--any-value); - } .bottom-\[var\(--any-value\)\] { bottom: var(--any-value); } .left-\[var\(--any-value\)\] { left: var(--any-value); } + .right-\[var\(--any-value\)\] { + right: var(--any-value); + } + .top-\[var\(--any-value\)\] { + top: var(--any-value); + } .z-\[var\(--any-value\)\] { z-index: var(--any-value); } @@ -246,18 +246,18 @@ test('any types are set on correct plugins', () => { margin-top: var(--any-value); margin-bottom: var(--any-value); } - .mt-\[var\(--any-value\)\] { - margin-top: var(--any-value); - } - .mr-\[var\(--any-value\)\] { - margin-right: var(--any-value); - } .mb-\[var\(--any-value\)\] { margin-bottom: var(--any-value); } .ml-\[var\(--any-value\)\] { margin-left: var(--any-value); } + .mr-\[var\(--any-value\)\] { + margin-right: var(--any-value); + } + .mt-\[var\(--any-value\)\] { + margin-top: var(--any-value); + } .aspect-\[var\(--any-value\)\] { aspect-ratio: var(--any-value); } @@ -367,18 +367,18 @@ test('any types are set on correct plugins', () => { scroll-margin-top: var(--any-value); scroll-margin-bottom: var(--any-value); } - .scroll-mt-\[var\(--any-value\)\] { - scroll-margin-top: var(--any-value); - } - .scroll-mr-\[var\(--any-value\)\] { - scroll-margin-right: var(--any-value); - } .scroll-mb-\[var\(--any-value\)\] { scroll-margin-bottom: var(--any-value); } .scroll-ml-\[var\(--any-value\)\] { scroll-margin-left: var(--any-value); } + .scroll-mr-\[var\(--any-value\)\] { + scroll-margin-right: var(--any-value); + } + .scroll-mt-\[var\(--any-value\)\] { + scroll-margin-top: var(--any-value); + } .scroll-p-\[var\(--any-value\)\] { scroll-padding: var(--any-value); } @@ -390,18 +390,18 @@ test('any types are set on correct plugins', () => { scroll-padding-top: var(--any-value); scroll-padding-bottom: var(--any-value); } - .scroll-pt-\[var\(--any-value\)\] { - scroll-padding-top: var(--any-value); - } - .scroll-pr-\[var\(--any-value\)\] { - scroll-padding-right: var(--any-value); - } .scroll-pb-\[var\(--any-value\)\] { scroll-padding-bottom: var(--any-value); } .scroll-pl-\[var\(--any-value\)\] { scroll-padding-left: var(--any-value); } + .scroll-pr-\[var\(--any-value\)\] { + scroll-padding-right: var(--any-value); + } + .scroll-pt-\[var\(--any-value\)\] { + scroll-padding-top: var(--any-value); + } .list-\[var\(--any-value\)\] { list-style-type: var(--any-value); } @@ -453,14 +453,6 @@ test('any types are set on correct plugins', () => { .rounded-\[var\(--any-value\)\] { border-radius: var(--any-value); } - .rounded-t-\[var\(--any-value\)\] { - border-top-left-radius: var(--any-value); - border-top-right-radius: var(--any-value); - } - .rounded-r-\[var\(--any-value\)\] { - border-top-right-radius: var(--any-value); - border-bottom-right-radius: var(--any-value); - } .rounded-b-\[var\(--any-value\)\] { border-bottom-right-radius: var(--any-value); border-bottom-left-radius: var(--any-value); @@ -469,18 +461,26 @@ test('any types are set on correct plugins', () => { border-top-left-radius: var(--any-value); border-bottom-left-radius: var(--any-value); } + .rounded-r-\[var\(--any-value\)\] { + border-top-right-radius: var(--any-value); + border-bottom-right-radius: var(--any-value); + } + .rounded-t-\[var\(--any-value\)\] { + border-top-left-radius: var(--any-value); + border-top-right-radius: var(--any-value); + } + .rounded-bl-\[var\(--any-value\)\] { + border-bottom-left-radius: var(--any-value); + } + .rounded-br-\[var\(--any-value\)\] { + border-bottom-right-radius: var(--any-value); + } .rounded-tl-\[var\(--any-value\)\] { border-top-left-radius: var(--any-value); } .rounded-tr-\[var\(--any-value\)\] { border-top-right-radius: var(--any-value); } - .rounded-br-\[var\(--any-value\)\] { - border-bottom-right-radius: var(--any-value); - } - .rounded-bl-\[var\(--any-value\)\] { - border-bottom-left-radius: var(--any-value); - } .border-\[var\(--any-value\)\] { border-color: var(--any-value); } @@ -492,18 +492,18 @@ test('any types are set on correct plugins', () => { border-top-color: var(--any-value); border-bottom-color: var(--any-value); } - .border-t-\[var\(--any-value\)\] { - border-top-color: var(--any-value); - } - .border-r-\[var\(--any-value\)\] { - border-right-color: var(--any-value); - } .border-b-\[var\(--any-value\)\] { border-bottom-color: var(--any-value); } .border-l-\[var\(--any-value\)\] { border-left-color: var(--any-value); } + .border-r-\[var\(--any-value\)\] { + border-right-color: var(--any-value); + } + .border-t-\[var\(--any-value\)\] { + border-top-color: var(--any-value); + } .border-opacity-\[var\(--any-value\)\] { --tw-border-opacity: var(--any-value); } @@ -545,18 +545,18 @@ test('any types are set on correct plugins', () => { padding-top: var(--any-value); padding-bottom: var(--any-value); } - .pt-\[var\(--any-value\)\] { - padding-top: var(--any-value); - } - .pr-\[var\(--any-value\)\] { - padding-right: var(--any-value); - } .pb-\[var\(--any-value\)\] { padding-bottom: var(--any-value); } .pl-\[var\(--any-value\)\] { padding-left: var(--any-value); } + .pr-\[var\(--any-value\)\] { + padding-right: var(--any-value); + } + .pt-\[var\(--any-value\)\] { + padding-top: var(--any-value); + } .indent-\[var\(--any-value\)\] { text-indent: var(--any-value); } diff --git a/tests/arbitrary-properties.test.js b/tests/arbitrary-properties.test.js index 826cc309a..29f40f2f4 100644 --- a/tests/arbitrary-properties.test.js +++ b/tests/arbitrary-properties.test.js @@ -47,13 +47,13 @@ test('different arbitrary properties are picked up separately', () => { expect(result.css).toMatchFormattedCss(css` ${defaults} - .\[foo\:bar\] { - foo: bar; - } - .\[bar\:baz\] { bar: baz; } + + .\[foo\:bar\] { + foo: bar; + } `) }) }) @@ -378,12 +378,12 @@ test('using multiple arbitrary props having fractional spacing values', () => { return expect(result.css).toMatchFormattedCss(css` ${defaults} - .\[height\:_calc\(100vh_-_theme\(spacing\[2\.5\]\)\)\] { - height: calc(100vh - 0.625rem); - } .\[box-shadow\:_0_calc\(theme\(spacing\[0\.5\]\)_\*_-1\)_theme\(colors\.red\.400\)_inset\] { box-shadow: 0 calc(0.125rem * -1) #f87171 inset; } + .\[height\:_calc\(100vh_-_theme\(spacing\[2\.5\]\)\)\] { + height: calc(100vh - 0.625rem); + } `) }) }) @@ -430,12 +430,12 @@ it('should be possible to read theme values in arbitrary properties (with quotes return expect(result.css).toMatchFormattedCss(css` ${defaults} - .\[color\:var\(--a\)\] { - color: var(--a); - } .\[--a\:theme\(\'colors\.blue\.500\'\)\] { --a: #3b82f6; } + .\[color\:var\(--a\)\] { + color: var(--a); + } `) }) }) diff --git a/tests/arbitrary-values.test.css b/tests/arbitrary-values.test.css index 6968de725..907b24962 100644 --- a/tests/arbitrary-values.test.css +++ b/tests/arbitrary-values.test.css @@ -26,18 +26,6 @@ top: var(--value); bottom: var(--value); } -.top-\[11px\] { - top: 11px; -} -.top-\[var\(--value\)\] { - top: var(--value); -} -.right-\[11px\] { - right: 11px; -} -.right-\[var\(--value\)\] { - right: var(--value); -} .bottom-\[11px\] { bottom: 11px; } @@ -50,6 +38,18 @@ .left-\[var\(--value\)\] { left: var(--value); } +.right-\[11px\] { + right: 11px; +} +.right-\[var\(--value\)\] { + right: var(--value); +} +.top-\[11px\] { + top: 11px; +} +.top-\[var\(--value\)\] { + top: var(--value); +} .z-\[123\] { z-index: 123; } @@ -91,18 +91,18 @@ margin-top: 7px; margin-bottom: 7px; } -.mt-\[7px\] { - margin-top: 7px; -} -.mr-\[7px\] { - margin-right: 7px; -} .mb-\[7px\] { margin-bottom: 7px; } .ml-\[7px\] { margin-left: 7px; } +.mr-\[7px\] { + margin-right: 7px; +} +.mt-\[7px\] { + margin-top: 7px; +} .mt-\[clamp\(30px\2c 100px\)\] { margin-top: clamp(30px, 100px); } @@ -139,15 +139,39 @@ .min-h-\[var\(--height\)\] { min-height: var(--height); } +.w-\[\'\)\(\)\'\] { + width: ')()'; +} +.w-\[\'\]\[\]\'\] { + width: '][]'; +} +.w-\[\'\}\{\}\'\] { + width: '}{}'; +} +.w-\[\(\(\)\)\] { + width: (()); +} +.w-\[\(\)\] { + width: (); +} .w-\[0\] { width: 0; } .w-\[3\.23rem\] { width: 3.23rem; } +.w-\[\[\[\]\]\] { + width: [[]]; +} +.w-\[\[\]\] { + width: []; +} .w-\[calc\(100\%\+1rem\)\] { width: calc(100% + 1rem); } +.w-\[calc\(100\%\/3-1rem\*2\)\] { + width: calc(100% / 3 - 1rem * 2); +} .w-\[calc\(var\(--10-10px\2c calc\(-20px-\(-30px--40px\)\)\)-50px\)\] { width: calc(var(--10-10px, calc(-20px - (-30px - -40px))) - 50px); } @@ -157,39 +181,15 @@ .w-\[var\(--width\2c calc\(100\%\+1rem\)\)\] { width: var(--width, calc(100% + 1rem)); } -.w-\[calc\(100\%\/3-1rem\*2\)\] { - width: calc(100% / 3 - 1rem * 2); -} -.w-\[\{\}\] { - width: { - } -} .w-\[\{\{\}\}\] { width: { { } } } -.w-\[\[\]\] { - width: []; -} -.w-\[\[\[\]\]\] { - width: [[]]; -} -.w-\[\(\)\] { - width: (); -} -.w-\[\(\(\)\)\] { - width: (()); -} -.w-\[\'\]\[\]\'\] { - width: '][]'; -} -.w-\[\'\)\(\)\'\] { - width: ')()'; -} -.w-\[\'\}\{\}\'\] { - width: '}{}'; +.w-\[\{\}\] { + width: { + } } .min-w-\[3\.23rem\] { min-width: 3.23rem; @@ -254,8 +254,8 @@ skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.rotate-\[23deg\] { - --tw-rotate: 23deg; +.rotate-\[1\.5turn\] { + --tw-rotate: 1.5turn; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -266,14 +266,14 @@ skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.rotate-\[401grad\] { - --tw-rotate: 401grad; +.rotate-\[23deg\] { + --tw-rotate: 23deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.rotate-\[1\.5turn\] { - --tw-rotate: 1.5turn; +.rotate-\[401grad\] { + --tw-rotate: 401grad; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -349,12 +349,12 @@ .cursor-\[pointer\] { cursor: pointer; } -.cursor-\[url\(hand\.cur\)_2_2\2c pointer\] { - cursor: url(hand.cur) 2 2, pointer; -} .cursor-\[url\(\'\.\/path_to_hand\.cur\'\)_2_2\2c pointer\] { cursor: url('./path_to_hand.cur') 2 2, pointer; } +.cursor-\[url\(hand\.cur\)_2_2\2c pointer\] { + cursor: url(hand.cur) 2 2, pointer; +} .cursor-\[var\(--value\)\] { cursor: var(--value); } @@ -369,18 +369,18 @@ scroll-margin-top: 7px; scroll-margin-bottom: 7px; } -.scroll-mt-\[7px\] { - scroll-margin-top: 7px; -} -.scroll-mr-\[7px\] { - scroll-margin-right: 7px; -} .scroll-mb-\[7px\] { scroll-margin-bottom: 7px; } .scroll-ml-\[7px\] { scroll-margin-left: 7px; } +.scroll-mr-\[7px\] { + scroll-margin-right: 7px; +} +.scroll-mt-\[7px\] { + scroll-margin-top: 7px; +} .scroll-mt-\[var\(--scroll-margin\)\] { scroll-margin-top: var(--scroll-margin); } @@ -395,18 +395,18 @@ scroll-padding-top: 7px; scroll-padding-bottom: 7px; } -.scroll-pt-\[7px\] { - scroll-padding-top: 7px; -} -.scroll-pr-\[7px\] { - scroll-padding-right: 7px; -} .scroll-pb-\[7px\] { scroll-padding-bottom: 7px; } .scroll-pl-\[7px\] { scroll-padding-left: 7px; } +.scroll-pr-\[7px\] { + scroll-padding-right: 7px; +} +.scroll-pt-\[7px\] { + scroll-padding-top: 7px; +} .scroll-pt-\[var\(--scroll-padding\)\] { scroll-padding-top: var(--scroll-padding); } @@ -511,14 +511,6 @@ .rounded-\[11px\] { border-radius: 11px; } -.rounded-t-\[var\(--radius\)\] { - border-top-left-radius: var(--radius); - border-top-right-radius: var(--radius); -} -.rounded-r-\[var\(--radius\)\] { - border-top-right-radius: var(--radius); - border-bottom-right-radius: var(--radius); -} .rounded-b-\[var\(--radius\)\] { border-bottom-right-radius: var(--radius); border-bottom-left-radius: var(--radius); @@ -527,36 +519,32 @@ border-top-left-radius: var(--radius); border-bottom-left-radius: var(--radius); } -.rounded-tr-\[var\(--radius\)\] { +.rounded-r-\[var\(--radius\)\] { border-top-right-radius: var(--radius); -} -.rounded-br-\[var\(--radius\)\] { border-bottom-right-radius: var(--radius); } +.rounded-t-\[var\(--radius\)\] { + border-top-left-radius: var(--radius); + border-top-right-radius: var(--radius); +} .rounded-bl-\[var\(--radius\)\] { border-bottom-left-radius: var(--radius); } +.rounded-br-\[var\(--radius\)\] { + border-bottom-right-radius: var(--radius); +} .rounded-tl-\[var\(--radius\)\] { border-top-left-radius: var(--radius); } +.rounded-tr-\[var\(--radius\)\] { + border-top-right-radius: var(--radius); +} .border-\[2\.5px\] { border-width: 2.5px; } .border-\[length\:var\(--value\)\] { border-width: var(--value); } -.border-t-\[2\.5px\] { - border-top-width: 2.5px; -} -.border-t-\[length\:var\(--value\)\] { - border-top-width: var(--value); -} -.border-r-\[2\.5px\] { - border-right-width: 2.5px; -} -.border-r-\[length\:var\(--value\)\] { - border-right-width: var(--value); -} .border-b-\[2\.5px\] { border-bottom-width: 2.5px; } @@ -569,29 +557,27 @@ .border-l-\[length\:var\(--value\)\] { border-left-width: var(--value); } +.border-r-\[2\.5px\] { + border-right-width: 2.5px; +} +.border-r-\[length\:var\(--value\)\] { + border-right-width: var(--value); +} +.border-t-\[2\.5px\] { + border-top-width: 2.5px; +} +.border-t-\[length\:var\(--value\)\] { + border-top-width: var(--value); +} .border-\[\#f00\] { --tw-border-opacity: 1; border-color: rgb(255 0 0 / var(--tw-border-opacity)); } -.border-\[red_black\] { - border-color: red black; -} .border-\[color\:var\(--value\)\] { border-color: var(--value); } -.border-t-\[\#f00\] { - --tw-border-opacity: 1; - border-top-color: rgb(255 0 0 / var(--tw-border-opacity)); -} -.border-t-\[color\:var\(--value\)\] { - border-top-color: var(--value); -} -.border-r-\[\#f00\] { - --tw-border-opacity: 1; - border-right-color: rgb(255 0 0 / var(--tw-border-opacity)); -} -.border-r-\[color\:var\(--value\)\] { - border-right-color: var(--value); +.border-\[red_black\] { + border-color: red black; } .border-b-\[\#f00\] { --tw-border-opacity: 1; @@ -607,30 +593,61 @@ .border-l-\[color\:var\(--value\)\] { border-left-color: var(--value); } +.border-r-\[\#f00\] { + --tw-border-opacity: 1; + border-right-color: rgb(255 0 0 / var(--tw-border-opacity)); +} +.border-r-\[color\:var\(--value\)\] { + border-right-color: var(--value); +} +.border-t-\[\#f00\] { + --tw-border-opacity: 1; + border-top-color: rgb(255 0 0 / var(--tw-border-opacity)); +} +.border-t-\[color\:var\(--value\)\] { + border-top-color: var(--value); +} .border-opacity-\[0\.8\] { --tw-border-opacity: 0.8; } .border-opacity-\[var\(--value\)\] { --tw-border-opacity: var(--value); } +.bg-\[\#0000ffcc\] { + background-color: #0000ffcc; +} .bg-\[\#0f0\] { --tw-bg-opacity: 1; background-color: rgb(0 255 0 / var(--tw-bg-opacity)); } +.bg-\[\#0f0_var\(--value\)\] { + background-color: #0f0 var(--value); +} .bg-\[\#ff0000\] { --tw-bg-opacity: 1; background-color: rgb(255 0 0 / var(--tw-bg-opacity)); } -.bg-\[\#0000ffcc\] { - background-color: #0000ffcc; +.bg-\[color\:var\(--value1\)_var\(--value2\)\] { + background-color: var(--value1) var(--value2); +} +.bg-\[hsl\(0\2c 100\%\2c 50\%\)\] { + --tw-bg-opacity: 1; + background-color: hsl(0 100% 50% / var(--tw-bg-opacity)); +} +.bg-\[hsl\(0rad\2c 100\%\2c 50\%\)\] { + --tw-bg-opacity: 1; + background-color: hsl(0rad 100% 50% / var(--tw-bg-opacity)); +} +.bg-\[hsla\(0\2c 100\%\2c 50\%\2c 0\.3\)\] { + background-color: hsla(0, 100%, 50%, 0.3); +} +.bg-\[hsla\(0turn\2c 100\%\2c 50\%\2c 0\.3\)\] { + background-color: hsla(0turn, 100%, 50%, 0.3); } .bg-\[rgb\(123\2c 123\2c 123\)\] { --tw-bg-opacity: 1; background-color: rgb(123 123 123 / var(--tw-bg-opacity)); } -.bg-\[rgba\(123\2c 123\2c 123\2c 0\.5\)\] { - background-color: rgba(123, 123, 123, 0.5); -} .bg-\[rgb\(123\2c _456\2c _123\)_black\] { background-color: rgb(123, 456, 123) black; } @@ -638,49 +655,26 @@ --tw-bg-opacity: 1; background-color: rgb(123 456 789 / var(--tw-bg-opacity)); } -.bg-\[hsl\(0\2c 100\%\2c 50\%\)\] { - --tw-bg-opacity: 1; - background-color: hsl(0 100% 50% / var(--tw-bg-opacity)); -} -.bg-\[hsla\(0\2c 100\%\2c 50\%\2c 0\.3\)\] { - background-color: hsla(0, 100%, 50%, 0.3); -} -.bg-\[hsl\(0rad\2c 100\%\2c 50\%\)\] { - --tw-bg-opacity: 1; - background-color: hsl(0rad 100% 50% / var(--tw-bg-opacity)); -} -.bg-\[hsla\(0turn\2c 100\%\2c 50\%\2c 0\.3\)\] { - background-color: hsla(0turn, 100%, 50%, 0.3); -} -.bg-\[\#0f0_var\(--value\)\] { - background-color: #0f0 var(--value); -} -.bg-\[var\(--value1\)_var\(--value2\)\] { - background-color: var(--value1) var(--value2); -} -.bg-\[color\:var\(--value1\)_var\(--value2\)\] { - background-color: var(--value1) var(--value2); +.bg-\[rgba\(123\2c 123\2c 123\2c 0\.5\)\] { + background-color: rgba(123, 123, 123, 0.5); } .bg-\[var\(--value\)\2c var\(--value\)\] { background-color: var(--value), var(--value); } +.bg-\[var\(--value1\)_var\(--value2\)\] { + background-color: var(--value1) var(--value2); +} .bg-opacity-\[0\.11\] { --tw-bg-opacity: 0.11; } .bg-opacity-\[var\(--value\)\] { --tw-bg-opacity: var(--value); } -.bg-\[linear-gradient\(to_left\2c rgb\(var\(--green\)\)\2c blue\)\] { - background-image: linear-gradient(to left, rgb(var(--green)), blue); +.bg-\[image\(\)\2c var\(--value\)\] { + background-image: image(), var(--value); } -.bg-\[url\(\'\/path-to-image\.png\'\)\] { - background-image: url('/path-to-image.png'); -} -.bg-\[url\:var\(--url\)\] { - background-image: var(--url); -} -.bg-\[linear-gradient\(\#eee\2c \#fff\)\] { - background-image: linear-gradient(#eee, #fff); +.bg-\[image\:var\(--value\)\2c var\(--value\)\] { + background-image: var(--value), var(--value); } .bg-\[linear-gradient\(\#eee\2c \#fff\)\2c @@ -691,11 +685,17 @@ blue\)\] { background-image: linear-gradient(#eee, #fff), conic-gradient(red, orange, yellow, green, blue); } -.bg-\[image\(\)\2c var\(--value\)\] { - background-image: image(), var(--value); +.bg-\[linear-gradient\(\#eee\2c \#fff\)\] { + background-image: linear-gradient(#eee, #fff); } -.bg-\[image\:var\(--value\)\2c var\(--value\)\] { - background-image: var(--value), var(--value); +.bg-\[linear-gradient\(to_left\2c rgb\(var\(--green\)\)\2c blue\)\] { + background-image: linear-gradient(to left, rgb(var(--green)), blue); +} +.bg-\[url\(\'\/path-to-image\.png\'\)\] { + background-image: url('/path-to-image.png'); +} +.bg-\[url\:var\(--url\)\] { + background-image: var(--url); } .from-\[\#da5b66\] { --tw-gradient-from: #da5b66; @@ -739,12 +739,12 @@ .fill-\[\#da5b66\] { fill: #da5b66; } -.fill-\[var\(--value\)\] { - fill: var(--value); -} .fill-\[url\(\#icon-gradient\)\] { fill: url(#icon-gradient); } +.fill-\[var\(--value\)\] { + fill: var(--value); +} .stroke-\[\#da5b66\] { stroke: #da5b66; } @@ -780,18 +780,18 @@ padding-top: 7px; padding-bottom: 7px; } -.pt-\[7px\] { - padding-top: 7px; -} -.pr-\[7px\] { - padding-right: 7px; -} .pb-\[7px\] { padding-bottom: 7px; } .pl-\[7px\] { padding-left: 7px; } +.pr-\[7px\] { + padding-right: 7px; +} +.pt-\[7px\] { + padding-top: 7px; +} .pt-\[clamp\(30px\2c 100px\)\] { padding-top: clamp(30px, 100px); } @@ -804,30 +804,30 @@ .align-\[10em\] { vertical-align: 10em; } -.font-\[Georgia\2c serif\] { - font-family: Georgia, serif; -} .font-\[\'Gill_Sans\'\] { font-family: 'Gill Sans'; } -.font-\[sans-serif\2c serif\] { - font-family: sans-serif, serif; -} -.font-\[family-name\:var\(--value\)\] { - font-family: var(--value); -} -.font-\[serif\2c var\(--value\)\] { - font-family: serif, var(--value); -} -.font-\[\'Some_Font\'\2c sans-serif\] { - font-family: 'Some Font', sans-serif; -} .font-\[\'Some_Font\'\2c \'Some_Other_Font\'\] { font-family: 'Some Font', 'Some Other Font'; } +.font-\[\'Some_Font\'\2c sans-serif\] { + font-family: 'Some Font', sans-serif; +} .font-\[\'Some_Font\'\2c var\(--other-font\)\] { font-family: 'Some Font', var(--other-font); } +.font-\[Georgia\2c serif\] { + font-family: Georgia, serif; +} +.font-\[family-name\:var\(--value\)\] { + font-family: var(--value); +} +.font-\[sans-serif\2c serif\] { + font-family: sans-serif, serif; +} +.font-\[serif\2c var\(--value\)\] { + font-family: serif, var(--value); +} .text-\[0\] { font-size: 0; } @@ -859,6 +859,9 @@ --tw-text-opacity: 1; color: rgb(0 0 0 / var(--tw-text-opacity)); } +.text-\[color\:var\(--color\)\] { + color: var(--color); +} .text-\[rgb\(123\2c 123\2c 123\)\] { --tw-text-opacity: 1; color: rgb(123 123 123 / var(--tw-text-opacity)); @@ -871,9 +874,6 @@ --tw-text-opacity: 1; color: rgb(123 123 123 / var(--tw-text-opacity)); } -.text-\[color\:var\(--color\)\] { - color: var(--color); -} .text-opacity-\[0\.8\] { --tw-text-opacity: 0.8; } @@ -883,6 +883,9 @@ .decoration-\[black\] { text-decoration-color: black; } +.decoration-\[color\:var\(--color\)\] { + text-decoration-color: var(--color); +} .decoration-\[rgb\(123\2c 123\2c 123\)\] { text-decoration-color: rgb(123, 123, 123); } @@ -892,9 +895,6 @@ .decoration-\[rgb\(123_123_123\)\] { text-decoration-color: rgb(123 123 123); } -.decoration-\[color\:var\(--color\)\] { - text-decoration-color: var(--color); -} .decoration-\[length\:10px\] { text-decoration-thickness: 10px; } @@ -1110,6 +1110,10 @@ .will-change-\[var\(--will-change\)\] { will-change: var(--will-change); } +.content-\[\'\>\'\] { + --tw-content: '>'; + content: var(--tw-content); +} .content-\[\'hello\'\] { --tw-content: 'hello'; content: var(--tw-content); @@ -1118,10 +1122,6 @@ --tw-content: attr(content-before); content: var(--tw-content); } -.content-\[\'\>\'\] { - --tw-content: '>'; - content: var(--tw-content); -} @media (min-width: 1024px) { .lg\:grid-cols-\[200px\2c repeat\(auto-fill\2c minmax\(15\%\2c 100px\)\)\2c 300px\] { grid-template-columns: 200px repeat(auto-fill, minmax(15%, 100px)) 300px; diff --git a/tests/arbitrary-values.test.js b/tests/arbitrary-values.test.js index b44459074..6b157424c 100644 --- a/tests/arbitrary-values.test.js +++ b/tests/arbitrary-values.test.js @@ -81,39 +81,32 @@ it('should support arbitrary values for various background utilities', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchFormattedCss(css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .bg-\[\#ff0000\] { --tw-bg-opacity: 1; background-color: rgb(255 0 0 / var(--tw-bg-opacity)); } - - .bg-\[rgb\(var\(--bg-color\)\)\] { - background-color: rgb(var(--bg-color)); - } - - .bg-\[hsl\(var\(--bg-color\)\)\] { - background-color: hsl(var(--bg-color)); - } - .bg-\[color\:var\(--bg-color\)\] { background-color: var(--bg-color); } - - .bg-gradient-to-r { - background-image: linear-gradient(to right, var(--tw-gradient-stops)); + .bg-\[hsl\(var\(--bg-color\)\)\] { + background-color: hsl(var(--bg-color)); + } + .bg-\[rgb\(var\(--bg-color\)\)\] { + background-color: rgb(var(--bg-color)); + } + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); } - .bg-\[url\(\'\/image-1-0\.png\'\)\] { background-image: url('/image-1-0.png'); } - .bg-\[url\:var\(--image-url\)\] { background-image: var(--image-url); } + .bg-gradient-to-r { + background-image: linear-gradient(to right, var(--tw-gradient-stops)); + } `) }) }) @@ -228,8 +221,8 @@ it('should convert _ to spaces', () => { var(--tw-drop-shadow); } - .content-\\[_hello_world_\\] { - --tw-content: hello world; + .content-\\[\\'__hello__world__\\'\\] { + --tw-content: ' hello world '; content: var(--tw-content); } @@ -238,8 +231,8 @@ it('should convert _ to spaces', () => { content: var(--tw-content); } - .content-\\[\\'__hello__world__\\'\\] { - --tw-content: ' hello world '; + .content-\\[_hello_world_\\] { + --tw-content: hello world; content: var(--tw-content); } `) @@ -497,12 +490,12 @@ it('should correctly validate combination of percentage and length', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .bg-\[50px_10\%\] { - background-position: 50px 10%; - } .bg-\[50\%_10\%\] { background-position: 50% 10%; } + .bg-\[50px_10\%\] { + background-position: 50px 10%; + } .bg-\[50px_10px\] { background-position: 50px 10px; } diff --git a/tests/arbitrary-variants.test.js b/tests/arbitrary-variants.test.js index 3f8f8b81f..c5577a954 100644 --- a/tests/arbitrary-variants.test.js +++ b/tests/arbitrary-variants.test.js @@ -517,11 +517,11 @@ test('allows attribute variants with quotes', () => { expect(result.css).toMatchFormattedCss(css` ${defaults} - .\[\&\[data-test\=\'2\'\]\]\:underline[data-test="2"] { + .\[\&\[data-test\=\"2\"\]\]\:underline[data-test='2'] { text-decoration-line: underline; } - .\[\&\[data-test\=\"2\"\]\]\:underline[data-test='2'] { + .\[\&\[data-test\=\'2\'\]\]\:underline[data-test='2'] { text-decoration-line: underline; } `) @@ -554,12 +554,12 @@ test('classes in arbitrary variants should not be prefixed', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .foo .\[\.foo_\&\]\:tw-text-red-400 { + .\[\&_\.foo\]\:tw-text-red-400 .foo { --tw-text-opacity: 1; color: rgb(248 113 113 / var(--tw-text-opacity)); } - .\[\&_\.foo\]\:tw-text-red-400 .foo { + .foo .\[\.foo_\&\]\:tw-text-red-400 { --tw-text-opacity: 1; color: rgb(248 113 113 / var(--tw-text-opacity)); } @@ -593,25 +593,22 @@ test('classes in the same arbitrary variant should not be prefixed', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .foo .\[\.foo_\&\]\:tw-bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - } - - .foo .\[\.foo_\&\]\:tw-text-red-400 { - --tw-text-opacity: 1; - color: rgb(248 113 113 / var(--tw-text-opacity)); - } - .\[\&_\.foo\]\:tw-bg-white .foo { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } - .\[\&_\.foo\]\:tw-text-red-400 .foo { --tw-text-opacity: 1; color: rgb(248 113 113 / var(--tw-text-opacity)); } + .foo .\[\.foo_\&\]\:tw-bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + } + .foo .\[\.foo_\&\]\:tw-text-red-400 { + --tw-text-opacity: 1; + color: rgb(248 113 113 / var(--tw-text-opacity)); + } `) }) }) @@ -651,19 +648,16 @@ it('should support aria variants', () => { .aria-checked\:underline[aria-checked='true'] { text-decoration-line: underline; } - .aria-\[sort\=ascending\]\:underline[aria-sort='ascending'] { - text-decoration-line: underline; - } .aria-\[labelledby\=a_b\]\:underline[aria-labelledby='a b'] { text-decoration-line: underline; } - .group[aria-checked='true'] .group-aria-checked\:underline { + .aria-\[sort\=ascending\]\:underline[aria-sort='ascending'] { text-decoration-line: underline; } .group\/foo[aria-checked='true'] .group-aria-checked\/foo\:underline { text-decoration-line: underline; } - .group[aria-sort='ascending'] .group-aria-\[sort\=ascending\]\:underline { + .group[aria-checked='true'] .group-aria-checked\:underline { text-decoration-line: underline; } .group[aria-labelledby='a b'] .group-aria-\[labelledby\=a_b\]\:underline { @@ -672,13 +666,13 @@ it('should support aria variants', () => { .group\/foo[aria-sort='ascending'] .group-aria-\[sort\=ascending\]\/foo\:underline { text-decoration-line: underline; } - .peer[aria-checked='true'] ~ .peer-aria-checked\:underline { + .group[aria-sort='ascending'] .group-aria-\[sort\=ascending\]\:underline { text-decoration-line: underline; } .peer\/foo[aria-checked='true'] ~ .peer-aria-checked\/foo\:underline { text-decoration-line: underline; } - .peer[aria-sort='ascending'] ~ .peer-aria-\[sort\=ascending\]\:underline { + .peer[aria-checked='true'] ~ .peer-aria-checked\:underline { text-decoration-line: underline; } .peer[aria-labelledby='a b'] ~ .peer-aria-\[labelledby\=a_b\]\:underline { @@ -687,6 +681,9 @@ it('should support aria variants', () => { .peer\/foo[aria-sort='ascending'] ~ .peer-aria-\[sort\=ascending\]\/foo\:underline { text-decoration-line: underline; } + .peer[aria-sort='ascending'] ~ .peer-aria-\[sort\=ascending\]\:underline { + text-decoration-line: underline; + } `) }) }) @@ -731,19 +728,16 @@ it('should support data variants', () => { .data-checked\:underline[data-ui~='checked'] { text-decoration-line: underline; } - .data-\[position\=top\]\:underline[data-position='top'] { - text-decoration-line: underline; - } .data-\[foo\=bar_baz\]\:underline[data-foo='bar baz'] { text-decoration-line: underline; } - .group[data-ui~='checked'] .group-data-checked\:underline { + .data-\[position\=top\]\:underline[data-position='top'] { text-decoration-line: underline; } .group\/foo[data-ui~='checked'] .group-data-checked\/foo\:underline { text-decoration-line: underline; } - .group[data-position='top'] .group-data-\[position\=top\]\:underline { + .group[data-ui~='checked'] .group-data-checked\:underline { text-decoration-line: underline; } .group[data-foo='bar baz'] .group-data-\[foo\=bar_baz\]\:underline { @@ -752,13 +746,13 @@ it('should support data variants', () => { .group\/foo[data-position='top'] .group-data-\[position\=top\]\/foo\:underline { text-decoration-line: underline; } - .peer[data-ui~='checked'] ~ .peer-data-checked\:underline { + .group[data-position='top'] .group-data-\[position\=top\]\:underline { text-decoration-line: underline; } .peer\/foo[data-ui~='checked'] ~ .peer-data-checked\/foo\:underline { text-decoration-line: underline; } - .peer[data-position='top'] ~ .peer-data-\[position\=top\]\:underline { + .peer[data-ui~='checked'] ~ .peer-data-checked\:underline { text-decoration-line: underline; } .peer[data-foo='bar baz'] ~ .peer-data-\[foo\=bar_baz\]\:underline { @@ -767,6 +761,9 @@ it('should support data variants', () => { .peer\/foo[data-position='top'] ~ .peer-data-\[position\=top\]\/foo\:underline { text-decoration-line: underline; } + .peer[data-position='top'] ~ .peer-data-\[position\=top\]\:underline { + text-decoration-line: underline; + } `) }) }) @@ -816,48 +813,41 @@ it('should support supports', () => { text-decoration-line: underline; } } - @supports (display: grid) { .supports-\[display\:grid\]\:grid { display: grid; } } - - @supports (transform-origin: 5% 5%) { - .supports-\[transform-origin\:5\%_5\%\]\:underline { - text-decoration-line: underline; - } - } - - @supports selector(A > B) { - .supports-\[selector\(A\>B\)\]\:underline { - text-decoration-line: underline; - } - } - - @supports not (foo: bar) { - .supports-\[not\(foo\:bar\)\]\:underline { - text-decoration-line: underline; - } - } - - @supports (foo: bar) or (bar: baz) { - .supports-\[\(foo\:bar\)or\(bar\:baz\)\]\:underline { - text-decoration-line: underline; - } - } - @supports (foo: bar) and (bar: baz) { .supports-\[\(foo\:bar\)and\(bar\:baz\)\]\:underline { text-decoration-line: underline; } } - + @supports (foo: bar) or (bar: baz) { + .supports-\[\(foo\:bar\)or\(bar\:baz\)\]\:underline { + text-decoration-line: underline; + } + } @supports (container-type: var(--tw)) { .supports-\[container-type\]\:underline { text-decoration-line: underline; } } + @supports not (foo: bar) { + .supports-\[not\(foo\:bar\)\]\:underline { + text-decoration-line: underline; + } + } + @supports selector(A > B) { + .supports-\[selector\(A\>B\)\]\:underline { + text-decoration-line: underline; + } + } + @supports (transform-origin: 5% 5%) { + .supports-\[transform-origin\:5\%_5\%\]\:underline { + text-decoration-line: underline; + } + } `) }) }) @@ -917,46 +907,46 @@ it('should be possible to use modifiers and arbitrary groups', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .group:hover .group-hover\:underline { - text-decoration-line: underline; - } .group\/foo:hover .group-hover\/foo\:underline { text-decoration-line: underline; } - .group:focus .group-\[\&\:focus\]\:underline { - text-decoration-line: underline; - } - .group:hover .group-\[\:hover\]\:underline { - text-decoration-line: underline; - } - .group[data-open] .group-\[\&\[data-open\]\]\:underline { - text-decoration-line: underline; - } - .group[data-open] .group-\[\[data-open\]\]\:underline { - text-decoration-line: underline; - } - .in-foo .group .group-\[\.in-foo_\&\]\:underline { - text-decoration-line: underline; - } - .group.in-foo .group-\[\.in-foo\]\:underline { + .group:hover .group-hover\:underline { text-decoration-line: underline; } .group\/foo:focus .group-\[\&\:focus\]\/foo\:underline { text-decoration-line: underline; } - .group\/foo:hover .group-\[\:hover\]\/foo\:underline { + .group:focus .group-\[\&\:focus\]\:underline { text-decoration-line: underline; } .group\/foo[data-open] .group-\[\&\[data-open\]\]\/foo\:underline { text-decoration-line: underline; } - .group\/foo[data-open] .group-\[\[data-open\]\]\/foo\:underline { + .group[data-open] .group-\[\&\[data-open\]\]\:underline { + text-decoration-line: underline; + } + .group\/foo.in-foo .group-\[\.in-foo\]\/foo\:underline { + text-decoration-line: underline; + } + .group.in-foo .group-\[\.in-foo\]\:underline { text-decoration-line: underline; } .in-foo .group\/foo .group-\[\.in-foo_\&\]\/foo\:underline { text-decoration-line: underline; } - .group\/foo.in-foo .group-\[\.in-foo\]\/foo\:underline { + .in-foo .group .group-\[\.in-foo_\&\]\:underline { + text-decoration-line: underline; + } + .group\/foo:hover .group-\[\:hover\]\/foo\:underline { + text-decoration-line: underline; + } + .group:hover .group-\[\:hover\]\:underline { + text-decoration-line: underline; + } + .group\/foo[data-open] .group-\[\[data-open\]\]\/foo\:underline { + text-decoration-line: underline; + } + .group[data-open] .group-\[\[data-open\]\]\:underline { text-decoration-line: underline; } `) @@ -1018,48 +1008,48 @@ it('should be possible to use modifiers and arbitrary peers', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .peer:hover ~ .peer-hover\:underline { - text-decoration-line: underline; - } .peer\/foo:hover ~ .peer-hover\/foo\:underline { text-decoration-line: underline; } - .peer:focus ~ .peer-\[\&\:focus\]\:underline { - text-decoration-line: underline; - } - .peer:hover ~ .peer-\[\:hover\]\:underline { - text-decoration-line: underline; - } - .peer[data-open] ~ .peer-\[\&\[data-open\]\]\:underline { - text-decoration-line: underline; - } - .peer[data-open] ~ .peer-\[\[data-open\]\]\:underline { - text-decoration-line: underline; - } - .in-foo .peer ~ .peer-\[\.in-foo_\&\]\:underline { - text-decoration-line: underline; - } - .peer.in-foo ~ .peer-\[\.in-foo\]\:underline { + .peer:hover ~ .peer-hover\:underline { text-decoration-line: underline; } .peer\/foo:focus ~ .peer-\[\&\:focus\]\/foo\:underline { text-decoration-line: underline; } - .peer\/foo:hover ~ .peer-\[\:hover\]\/foo\:underline { + .peer:focus ~ .peer-\[\&\:focus\]\:underline { text-decoration-line: underline; } .peer\/foo[data-open] ~ .peer-\[\&\[data-open\]\]\/foo\:underline { text-decoration-line: underline; } - .peer\/foo[data-open] ~ .peer-\[\[data-open\]\]\/foo\:underline { - text-decoration-line: underline; - } - .in-foo .peer\/foo ~ .peer-\[\.in-foo_\&\]\/foo\:underline { + .peer[data-open] ~ .peer-\[\&\[data-open\]\]\:underline { text-decoration-line: underline; } .peer\/foo.in-foo ~ .peer-\[\.in-foo\]\/foo\:underline { text-decoration-line: underline; } + .peer.in-foo ~ .peer-\[\.in-foo\]\:underline { + text-decoration-line: underline; + } + .in-foo .peer\/foo ~ .peer-\[\.in-foo_\&\]\/foo\:underline { + text-decoration-line: underline; + } + .in-foo .peer ~ .peer-\[\.in-foo_\&\]\:underline { + text-decoration-line: underline; + } + .peer\/foo:hover ~ .peer-\[\:hover\]\/foo\:underline { + text-decoration-line: underline; + } + .peer:hover ~ .peer-\[\:hover\]\:underline { + text-decoration-line: underline; + } + .peer\/foo[data-open] ~ .peer-\[\[data-open\]\]\/foo\:underline { + text-decoration-line: underline; + } + .peer[data-open] ~ .peer-\[\[data-open\]\]\:underline { + text-decoration-line: underline; + } `) }) }) diff --git a/tests/basic-usage.test.css b/tests/basic-usage.test.css index a41a19407..2d1ca25c6 100644 --- a/tests/basic-usage.test.css +++ b/tests/basic-usage.test.css @@ -149,19 +149,13 @@ bottom: 0px; left: 0px; } -.inset-y-4 { - top: 1rem; - bottom: 1rem; -} .inset-x-2 { left: 0.5rem; right: 0.5rem; } -.top-6 { - top: 1.5rem; -} -.right-8 { - right: 2rem; +.inset-y-4 { + top: 1rem; + bottom: 1rem; } .bottom-12 { bottom: 3rem; @@ -169,6 +163,12 @@ .left-16 { left: 4rem; } +.right-8 { + right: 2rem; +} +.top-6 { + top: 1.5rem; +} .isolate { isolation: isolate; } @@ -178,12 +178,12 @@ .z-30 { z-index: 30; } -.order-last { - order: 9999; -} .order-2 { order: 2; } +.order-last { + order: 9999; +} .col-span-3 { grid-column: span 3 / span 3; } @@ -211,19 +211,13 @@ .m-4 { margin: 1rem; } -.my-2 { - margin-top: 0.5rem; - margin-bottom: 0.5rem; -} .mx-auto { margin-left: auto; margin-right: auto; } -.mt-0 { - margin-top: 0px; -} -.mr-1 { - margin-right: 0.25rem; +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; } .mb-3 { margin-bottom: 0.75rem; @@ -231,6 +225,12 @@ .ml-4 { margin-left: 1rem; } +.mr-1 { + margin-right: 0.25rem; +} +.mt-0 { + margin-top: 0px; +} .box-border { box-sizing: border-box; } @@ -291,12 +291,12 @@ .grow-0 { flex-grow: 0; } -.basis-auto { - flex-basis: auto; -} .basis-7 { flex-basis: 1.75rem; } +.basis-auto { + flex-basis: auto; +} .table-fixed { table-layout: fixed; } @@ -319,8 +319,8 @@ .origin-top-right { transform-origin: top right; } -.translate-x-5 { - --tw-translate-x: 1.25rem; +.-translate-x-3 { + --tw-translate-x: -0.75rem; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -331,14 +331,14 @@ skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.translate-y-6 { - --tw-translate-y: 1.5rem; +.translate-x-5 { + --tw-translate-x: 1.25rem; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.-translate-x-3 { - --tw-translate-x: -0.75rem; +.translate-y-6 { + --tw-translate-y: 1.5rem; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -349,14 +349,14 @@ skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.skew-y-12 { - --tw-skew-y: 12deg; +.skew-x-12 { + --tw-skew-x: 12deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } -.skew-x-12 { - --tw-skew-x: 12deg; +.skew-y-12 { + --tw-skew-y: 12deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); @@ -532,26 +532,26 @@ .space-x-reverse > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 1; } -.divide-x-2 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-x-reverse: 0; - border-right-width: calc(2px * var(--tw-divide-x-reverse)); - border-left-width: calc(2px * calc(1 - var(--tw-divide-x-reverse))); -} -.divide-y-4 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-y-reverse: 0; - border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); - border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); -} .divide-x-0 > :not([hidden]) ~ :not([hidden]) { --tw-divide-x-reverse: 0; border-right-width: calc(0px * var(--tw-divide-x-reverse)); border-left-width: calc(0px * calc(1 - var(--tw-divide-x-reverse))); } +.divide-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-x-reverse: 0; + border-right-width: calc(2px * var(--tw-divide-x-reverse)); + border-left-width: calc(2px * calc(1 - var(--tw-divide-x-reverse))); +} .divide-y-0 > :not([hidden]) ~ :not([hidden]) { --tw-divide-y-reverse: 0; border-top-width: calc(0px * calc(1 - var(--tw-divide-y-reverse))); border-bottom-width: calc(0px * var(--tw-divide-y-reverse)); } +.divide-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); +} .divide-dotted > :not([hidden]) ~ :not([hidden]) { border-style: dotted; } @@ -608,12 +608,12 @@ border-top-width: 4px; border-bottom-width: 4px; } -.border-t { - border-top-width: 1px; -} .border-b-4 { border-bottom-width: 4px; } +.border-t { + border-top-width: 1px; +} .border-solid { border-style: solid; } @@ -634,14 +634,6 @@ border-top-color: rgb(0 0 0 / var(--tw-border-opacity)); border-bottom-color: rgb(0 0 0 / var(--tw-border-opacity)); } -.border-t-black { - --tw-border-opacity: 1; - border-top-color: rgb(0 0 0 / var(--tw-border-opacity)); -} -.border-r-black { - --tw-border-opacity: 1; - border-right-color: rgb(0 0 0 / var(--tw-border-opacity)); -} .border-b-black { --tw-border-opacity: 1; border-bottom-color: rgb(0 0 0 / var(--tw-border-opacity)); @@ -650,6 +642,14 @@ --tw-border-opacity: 1; border-left-color: rgb(0 0 0 / var(--tw-border-opacity)); } +.border-r-black { + --tw-border-opacity: 1; + border-right-color: rgb(0 0 0 / var(--tw-border-opacity)); +} +.border-t-black { + --tw-border-opacity: 1; + border-top-color: rgb(0 0 0 / var(--tw-border-opacity)); +} .border-opacity-10 { --tw-border-opacity: 0.1; } @@ -729,19 +729,13 @@ .p-4 { padding: 1rem; } -.py-2 { - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } -.pt-1 { - padding-top: 0.25rem; -} -.pr-2 { - padding-right: 0.5rem; +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; } .pb-3 { padding-bottom: 0.75rem; @@ -749,15 +743,21 @@ .pl-4 { padding-left: 1rem; } +.pr-2 { + padding-right: 0.5rem; +} +.pt-1 { + padding-top: 0.25rem; +} .text-center { text-align: center; } -.indent-6 { - text-indent: 1.5rem; -} .-indent-12 { text-indent: -3rem; } +.indent-6 { + text-indent: 1.5rem; +} .align-middle { vertical-align: middle; } @@ -794,12 +794,12 @@ font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); } -.leading-relaxed { - line-height: 1.625; -} .leading-5 { line-height: 1.25rem; } +.leading-relaxed { + line-height: 1.625; +} .tracking-tight { letter-spacing: -0.025em; } @@ -869,12 +869,6 @@ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.shadow-md { - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), - var(--tw-shadow); -} .shadow-lg { --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), @@ -882,18 +876,24 @@ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} .shadow-black { --tw-shadow-color: #000; --tw-shadow: var(--tw-shadow-colored); } -.shadow-red-500\/25 { - --tw-shadow-color: rgb(239 68 68 / 0.25); - --tw-shadow: var(--tw-shadow-colored); -} .shadow-blue-100\/10 { --tw-shadow-color: rgb(219 234 254 / 0.1); --tw-shadow: var(--tw-shadow-colored); } +.shadow-red-500\/25 { + --tw-shadow-color: rgb(239 68 68 / 0.25); + --tw-shadow: var(--tw-shadow-colored); +} .outline-none { outline: 2px solid transparent; outline-offset: 2px; @@ -907,12 +907,12 @@ .outline-4 { outline-width: 4px; } -.outline-offset-2 { - outline-offset: 2px; -} .-outline-offset-2 { outline-offset: -2px; } +.outline-offset-2 { + outline-offset: 2px; +} .outline-black { outline-color: #000; } diff --git a/tests/color-opacity-modifiers.test.js b/tests/color-opacity-modifiers.test.js index 55e811554..eb708308f 100644 --- a/tests/color-opacity-modifiers.test.js +++ b/tests/color-opacity-modifiers.test.js @@ -205,33 +205,27 @@ test('opacity modifier in combination with partial custom properties', async () return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .bg-\[hsl\(var\(--foo\)\2c 50\%\2c 50\%\)\] { - --tw-bg-opacity: 1; - background-color: hsl(var(--foo) 50% 50% / var(--tw-bg-opacity)); - } - - .bg-\[hsl\(123\2c var\(--foo\)\2c 50\%\)\] { - --tw-bg-opacity: 1; - background-color: hsl(123 var(--foo) 50% / var(--tw-bg-opacity)); - } - .bg-\[hsl\(123\2c 50\%\2c var\(--foo\)\)\] { --tw-bg-opacity: 1; background-color: hsl(123 50% var(--foo) / var(--tw-bg-opacity)); } - - .bg-\[hsl\(var\(--foo\)\2c 50\%\2c 50\%\)\]\/50 { - background-color: hsl(var(--foo) 50% 50% / 0.5); - } - - .bg-\[hsl\(123\2c var\(--foo\)\2c 50\%\)\]\/50 { - background-color: hsl(123 var(--foo) 50% / 0.5); - } - .bg-\[hsl\(123\2c 50\%\2c var\(--foo\)\)\]\/50 { background-color: hsl(123 50% var(--foo) / 0.5); } - + .bg-\[hsl\(123\2c var\(--foo\)\2c 50\%\)\] { + --tw-bg-opacity: 1; + background-color: hsl(123 var(--foo) 50% / var(--tw-bg-opacity)); + } + .bg-\[hsl\(123\2c var\(--foo\)\2c 50\%\)\]\/50 { + background-color: hsl(123 var(--foo) 50% / 0.5); + } + .bg-\[hsl\(var\(--foo\)\2c 50\%\2c 50\%\)\] { + --tw-bg-opacity: 1; + background-color: hsl(var(--foo) 50% 50% / var(--tw-bg-opacity)); + } + .bg-\[hsl\(var\(--foo\)\2c 50\%\2c 50\%\)\]\/50 { + background-color: hsl(var(--foo) 50% 50% / 0.5); + } .bg-\[hsl\(var\(--foo\)\2c var\(--bar\)\2c var\(--baz\)\)\]\/50 { background-color: hsl(var(--foo) var(--bar) var(--baz) / 0.5); } diff --git a/tests/custom-extractors.test.js b/tests/custom-extractors.test.js index 9a8301230..8c40aa995 100644 --- a/tests/custom-extractors.test.js +++ b/tests/custom-extractors.test.js @@ -1,7 +1,8 @@ import fs from 'fs' import path from 'path' -import { run } from './util/run' +import { run, css } from './util/run' +import { env } from '../src/lib/sharedState' function customExtractor(content) { let matches = content.match(/class="([^"]+)"/) @@ -11,7 +12,9 @@ function customExtractor(content) { let expectedPath = path.resolve(__dirname, './custom-extractors.test.css') let expected = fs.readFileSync(expectedPath, 'utf8') -describe('modern', () => { +let group = env.OXIDE ? describe.skip : describe + +group('modern', () => { test('extract.DEFAULT', () => { let config = { content: { @@ -54,9 +57,34 @@ describe('modern', () => { expect(result.css).toMatchFormattedCss(expected) }) }) + + test('raw content with extension', () => { + let config = { + content: { + files: [ + { + raw: fs.readFileSync(path.resolve(__dirname, './raw-content.test.html'), 'utf8'), + extension: 'html', + }, + ], + extract: { + html: () => ['invisible'], + }, + }, + corePlugins: { preflight: false }, + } + + return run('@tailwind utilities', config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + .invisible { + visibility: hidden; + } + `) + }) + }) }) -describe('legacy', () => { +group('legacy', () => { test('defaultExtractor', () => { let config = { content: { diff --git a/tests/custom-transformers.test.js b/tests/custom-transformers.test.js index e4bea062c..20f6bd4a9 100644 --- a/tests/custom-transformers.test.js +++ b/tests/custom-transformers.test.js @@ -1,11 +1,14 @@ import path from 'path' import { run, html, css } from './util/run' +import { env } from '../src/lib/sharedState' + +let t = env.OXIDE ? test.skip : test function customTransformer(content) { return content.replace(/uppercase/g, 'lowercase') } -test('transform function', () => { +t('transform function', () => { let config = { content: { files: [{ raw: html`
` }], @@ -22,7 +25,7 @@ test('transform function', () => { }) }) -test('transform.DEFAULT', () => { +t('transform.DEFAULT', () => { let config = { content: { files: [{ raw: html`
` }], @@ -41,7 +44,7 @@ test('transform.DEFAULT', () => { }) }) -test('transform.{extension}', () => { +t('transform.{extension}', () => { let config = { content: { files: [ diff --git a/tests/customConfig.test.js b/tests/customConfig.test.js index 0b071461b..2237235b8 100644 --- a/tests/customConfig.test.js +++ b/tests/customConfig.test.js @@ -200,15 +200,15 @@ test('the default config can be overridden using the presets key', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchFormattedCss(css` + .min-h-0 { + min-height: 0px; + } .min-h-primary { min-height: 48px; } .min-h-secondary { min-height: 24px; } - .min-h-0 { - min-height: 0px; - } `) }) }) @@ -230,15 +230,15 @@ test('presets can be functions', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchFormattedCss(css` + .min-h-0 { + min-height: 0px; + } .min-h-primary { min-height: 48px; } .min-h-secondary { min-height: 24px; } - .min-h-0 { - min-height: 0px; - } `) }) }) @@ -312,15 +312,15 @@ test('presets can have their own presets', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchFormattedCss(css` + .bg-black { + background-color: black; + } .bg-red { background-color: #ee0000; } .bg-transparent { background-color: transparent; } - .bg-black { - background-color: black; - } .bg-white { background-color: white; } @@ -369,15 +369,15 @@ test('function presets can be mixed with object presets', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchFormattedCss(css` + .bg-black { + background-color: black; + } .bg-red { background-color: #ee0000; } .bg-transparent { background-color: transparent; } - .bg-black { - background-color: black; - } .bg-white { background-color: white; } diff --git a/tests/kitchen-sink.test.css b/tests/kitchen-sink.test.css index 2785325a8..e1b2a1b3a 100644 --- a/tests/kitchen-sink.test.css +++ b/tests/kitchen-sink.test.css @@ -322,18 +322,18 @@ div { .font-medium { font-weight: 500; } -.shadow-sm { - --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); - --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), - var(--tw-shadow); -} .shadow-md { --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} .magic-none { magic: none; } diff --git a/tests/kitchen-sink.test.js b/tests/kitchen-sink.test.js index 43cc1010d..9314475b2 100644 --- a/tests/kitchen-sink.test.js +++ b/tests/kitchen-sink.test.js @@ -1,9 +1,16 @@ import fs from 'fs' import path from 'path' +import { env } from '../src/lib/sharedState' import { run, css } from './util/run' -test('it works', () => { +afterEach(() => { + env.OXIDE = false +}) + +test.each([[true], [false]])('it works (using Rust: %p)', (useOxide) => { + env.OXIDE = useOxide + let config = { darkMode: 'class', content: [path.resolve(__dirname, './kitchen-sink.test.html')], diff --git a/tests/match-utilities.test.js b/tests/match-utilities.test.js index 918145382..c48268fbe 100644 --- a/tests/match-utilities.test.js +++ b/tests/match-utilities.test.js @@ -45,8 +45,8 @@ test('match utilities with modifiers', async () => { .test { color: default_null; } - .test\/foo { - color: default_foo; + .test-1\/\[foo\] { + color: one_[foo]; } .test-1\/foo { color: onefoo_null; @@ -57,8 +57,8 @@ test('match utilities with modifiers', async () => { .test\/\[foo\] { color: default_[foo]; } - .test-1\/\[foo\] { - color: one_[foo]; + .test\/foo { + color: default_foo; } .test-\[8\]\/\[9\] { color: eightnine_null; @@ -108,8 +108,8 @@ test('match utilities with modifiers in the config', async () => { .test { color: default_null; } - .test\/foo { - color: default_mewtwo; + .test-1\/\[bar\] { + color: one_bar; } .test-1\/foo { color: one_mewtwo; @@ -117,8 +117,8 @@ test('match utilities with modifiers in the config', async () => { .test\/\[bar\] { color: default_bar; } - .test-1\/\[bar\] { - color: one_bar; + .test\/foo { + color: default_mewtwo; } `) }) diff --git a/tests/min-max-screen-variants.test.js b/tests/min-max-screen-variants.test.js index cb6a06293..e55d0cf8f 100644 --- a/tests/min-max-screen-variants.test.js +++ b/tests/min-max-screen-variants.test.js @@ -436,8 +436,8 @@ it('warns when using min variants with mixed units (with no screens config)', as .font-bold { font-weight: 700; } - @media (min-width: 700rem) { - .min-\[700rem\]\:font-bold { + @media (min-width: 700px) { + .min-\[700px\]\:font-bold { font-weight: 700; } } @@ -612,8 +612,8 @@ it('warns when using max variants with mixed units (with no screens config)', as .font-bold { font-weight: 700; } - @media (max-width: 700rem) { - .max-\[700rem\]\:font-bold { + @media (max-width: 700px) { + .max-\[700px\]\:font-bold { font-weight: 700; } } diff --git a/tests/negative-prefix.test.js b/tests/negative-prefix.test.js index 09b6d3ed0..d28a6496e 100644 --- a/tests/negative-prefix.test.js +++ b/tests/negative-prefix.test.js @@ -13,12 +13,12 @@ test('using a negative prefix with a negative scale value', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt-2 { - margin-top: 8px; - } .-mt-2 { margin-top: -4px; } + .mt-2 { + margin-top: 8px; + } `) }) }) @@ -54,12 +54,12 @@ test('using a negative prefix without a negative scale value', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt-5 { - margin-top: 20px; - } .-mt-5 { margin-top: -20px; } + .mt-5 { + margin-top: 20px; + } `) }) }) @@ -114,12 +114,12 @@ test('a value that includes a variable', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt-5 { - margin-top: var(--sizing-5); - } .-mt-5 { margin-top: calc(var(--sizing-5) * -1); } + .mt-5 { + margin-top: var(--sizing-5); + } `) }) }) @@ -136,12 +136,12 @@ test('a value that includes a calc', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt-5 { - margin-top: calc(52px * -3); - } .-mt-5 { margin-top: calc(calc(52px * -3) * -1); } + .mt-5 { + margin-top: calc(52px * -3); + } `) }) }) @@ -160,23 +160,23 @@ test('a value that includes min/max/clamp functions', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt-min { - margin-top: min(100vmin, 3rem); - } - .-mt-min { - margin-top: calc(min(100vmin, 3rem) * -1); - } - .mt-max { - margin-top: max(100vmax, 3rem); + .-mt-clamp { + margin-top: calc(clamp(1rem, 100vh, 3rem) * -1); } .-mt-max { margin-top: calc(max(100vmax, 3rem) * -1); } + .-mt-min { + margin-top: calc(min(100vmin, 3rem) * -1); + } .mt-clamp { margin-top: clamp(1rem, 100vh, 3rem); } - .-mt-clamp { - margin-top: calc(clamp(1rem, 100vh, 3rem) * -1); + .mt-max { + margin-top: max(100vmax, 3rem); + } + .mt-min { + margin-top: min(100vmin, 3rem); } `) }) @@ -213,10 +213,10 @@ test('a zero value', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt-0 { + .-mt-0 { margin-top: 0; } - .-mt-0 { + .mt-0 { margin-top: 0; } `) @@ -303,12 +303,12 @@ test('using a negative prefix with a negative default scale value', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchCss(css` - .mt { - margin-top: 8px; - } .-mt { margin-top: -4px; } + .mt { + margin-top: 8px; + } `) }) }) diff --git a/tests/normalize-config.test.js b/tests/normalize-config.test.js index 1b422a4bd..ef62f0745 100644 --- a/tests/normalize-config.test.js +++ b/tests/normalize-config.test.js @@ -1,6 +1,9 @@ import { normalizeConfig } from '../src/util/normalizeConfig' import { run, css } from './util/run' import resolveConfig from '../src/public/resolve-config' +import { env } from '../src/lib/sharedState' + +let t = env.OXIDE ? test.skip : test it.each` config @@ -32,12 +35,18 @@ it.each` }) }) -it.each` +t.each` config ${{ content: [{ raw: 'text-center' }], purge: { extract: () => ['font-bold'] } }} ${{ content: [{ raw: 'text-center' }], purge: { extract: { DEFAULT: () => ['font-bold'] } } }} - ${{ content: [{ raw: 'text-center' }], purge: { options: { defaultExtractor: () => ['font-bold'] } } }} - ${{ content: [{ raw: 'text-center' }], purge: { options: { extractors: [{ extractor: () => ['font-bold'], extensions: ['html'] }] } } }} + ${{ + content: [{ raw: 'text-center' }], + purge: { options: { defaultExtractor: () => ['font-bold'] } }, + }} + ${{ + content: [{ raw: 'text-center' }], + purge: { options: { extractors: [{ extractor: () => ['font-bold'], extensions: ['html'] }] } }, + }} ${{ content: [{ raw: 'text-center' }], purge: { extract: { html: () => ['font-bold'] } } }} `('should normalize extractors $config', ({ config }) => { return run('@tailwind utilities', config).then((result) => { @@ -49,7 +58,7 @@ it.each` }) }) -it('should still be possible to use the "old" v2 config', () => { +t('should still be possible to use the "old" v2 config', () => { let config = { purge: { content: [ diff --git a/tests/opacity.test.js b/tests/opacity.test.js index 672460266..c456a4087 100644 --- a/tests/opacity.test.js +++ b/tests/opacity.test.js @@ -802,26 +802,26 @@ it('works with opacity values defined as a placeholder or a function in when col .bg-foo10 { background-color: rgb(255 100 0 / 100%); } + .bg-foo11 { + background-color: rgb(255 100 0 / 50%); + } .bg-foo20 { --tw-bg-opacity: 1; background-color: rgb(255 100 0 / var(--tw-bg-opacity)); } + .bg-foo21 { + background-color: rgb(255 100 0 / 50%); + } .bg-foo30 { background-color: rgb(255 100 0 / 100%); } + .bg-foo31 { + background-color: rgb(255 100 0 / 50%); + } .bg-foo40 { --tw-bg-opacity: 1; background-color: rgb(255 100 0 / var(--tw-bg-opacity)); } - .bg-foo11 { - background-color: rgb(255 100 0 / 50%); - } - .bg-foo21 { - background-color: rgb(255 100 0 / 50%); - } - .bg-foo31 { - background-color: rgb(255 100 0 / 50%); - } .bg-foo41 { background-color: rgb(255 100 0 / 50%); } diff --git a/tests/oxide-svelte.test.css b/tests/oxide-svelte.test.css new file mode 100644 index 000000000..64b084964 --- /dev/null +++ b/tests/oxide-svelte.test.css @@ -0,0 +1,104 @@ +*, +::before, +::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} +.bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); +} +@media (min-width: 1024px) { + .lg\:hover\:bg-blue-500:hover { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + } +} diff --git a/tests/oxide.test.css b/tests/oxide.test.css new file mode 100644 index 000000000..e1b2a1b3a --- /dev/null +++ b/tests/oxide.test.css @@ -0,0 +1,579 @@ +.theme-test { + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol', 'Noto Color Emoji'; + color: #3b82f6; +} +@media (min-width: 1024px) { + .screen-test { + color: purple; + } +} +.apply-1 { + margin-top: 1.5rem; +} +.apply-2 { + margin-top: 1.5rem; +} +.apply-test { + margin-top: 1.5rem; + --tw-bg-opacity: 1; + background-color: rgb(236 72 153 / var(--tw-bg-opacity)); +} +.apply-test:hover { + font-weight: 700; +} +.apply-test:hover:focus { + font-weight: 700; +} +@media (min-width: 640px) { + .apply-test { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); + } + .apply-test:nth-child(even):focus { + --tw-bg-opacity: 1; + background-color: rgb(251 207 232 / var(--tw-bg-opacity)); + } +} +.apply-components { + width: 100%; +} +@media (min-width: 640px) { + .apply-components { + max-width: 640px; + } +} +@media (min-width: 768px) { + .apply-components { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .apply-components { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .apply-components { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .apply-components { + max-width: 1536px; + } +} +.apply-components { + margin-left: auto; + margin-right: auto; +} +.drop-empty-rules:hover { + font-weight: 700; +} +.group:hover .apply-group { + font-weight: 700; +} +.dark .apply-dark-mode { + font-weight: 700; +} +.apply-with-existing:hover { + font-weight: 400; +} +@media (min-width: 640px) { + .apply-with-existing:hover { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); + } +} +.multiple, +.selectors { + font-weight: 700; +} +.group:hover .multiple, +.group:hover .selectors { + font-weight: 400; +} +.list > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} +.nested { + .example { + font-weight: 700; + } + .example:hover { + font-weight: 400; + } +} +.apply-order-a { + margin: 1.25rem; + margin-top: 1.5rem; +} +.apply-order-b { + margin: 1.25rem; + margin-top: 1.5rem; +} +.dark .group:hover .apply-dark-group-example-a { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} +@media (min-width: 640px) { + @media (prefers-reduced-motion: no-preference) { + .group:active .crazy-example:focus { + opacity: 0.1; + } + } +} +h1 { + font-size: 1.5rem; + font-weight: 700; +} +h1:first-child { + margin-top: 0px; +} +div { + background: #654321; +} +*, +::before, +::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} +.container { + width: 100%; +} +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} +.test-apply-font-variant { + --tw-ordinal: ordinal; + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) + var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} +.custom-component { + background: #123456; +} +*, +::before, +::after, +::backdrop { + padding: 5px; +} +.foo .bg-black { + appearance: none; +} +.mt-6 { + margin-top: 1.5rem; +} +.scale-50 { + --tw-scale-x: 0.5; + --tw-scale-y: 0.5; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); +} +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); +} +.grid-cols-\[200px\2c repeat\(auto-fill\2c minmax\(15\%\2c 100px\)\)\2c 300px\] { + grid-template-columns: 200px repeat(auto-fill, minmax(15%, 100px)) 300px; +} +.bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); +} +.bg-green-500 { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} +.bg-opacity-50 { + --tw-bg-opacity: 0.5; +} +.bg-gradient-to-r { + background-image: linear-gradient(to right, var(--tw-gradient-stops)); +} +.bg-hero--home-1 { + background-image: url('/images/homepage-1.jpg'); +} +.from-foo { + --tw-gradient-from: #bada55; + --tw-gradient-to: rgb(186 218 85 / 0); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); +} +.text-center { + text-align: center; +} +.font-medium { + font-weight: 500; +} +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} +.shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} +.magic-none { + magic: none; +} +.magic-tons { + magic: tons; +} +.custom-util { + background: #abcdef; +} +*, +::before, +::after, +::backdrop { + margin: 10px; +} +.first\:pt-0:first-child { + padding-top: 0px; +} +.hover\:container:hover { + width: 100%; +} +@media (min-width: 640px) { + .hover\:container:hover { + max-width: 640px; + } +} +@media (min-width: 768px) { + .hover\:container:hover { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .hover\:container:hover { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .hover\:container:hover { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .hover\:container:hover { + max-width: 1536px; + } +} +.hover\:scale-75:hover { + --tw-scale-x: 0.75; + --tw-scale-y: 0.75; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); +} +.hover\:font-bold:hover { + font-weight: 700; +} +.hover\:shadow-lg:hover { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), + 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} +.hover\:custom-util:hover { + background: #abcdef; +} +.focus\:font-normal:focus { + font-weight: 400; +} +.focus\:ring-2:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) + var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) + var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} +.focus\:ring-blue-500:focus { + --tw-ring-opacity: 1; + --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity)); +} +.focus\:hover\:font-light:hover:focus { + font-weight: 300; +} +.disabled\:font-bold:disabled { + font-weight: 700; +} +.group:hover .group-hover\:opacity-100 { + opacity: 1; +} +.group:hover .group-hover\:custom-util { + background: #abcdef; +} +.group:active .group-active\:opacity-10 { + opacity: 0.1; +} +.foo\:custom-util { + background: #abcdef !important; +} +.foo\:hover\:custom-util:hover { + background: #abcdef !important; +} +@media (prefers-reduced-motion: no-preference) { + .motion-safe\:transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, + opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + } + .motion-safe\:custom-util { + background: #abcdef; + } +} +@media (prefers-reduced-motion: reduce) { + .motion-reduce\:transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, + opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + } +} +.dark .dark\:custom-util { + background: #abcdef; +} +@media (min-width: 640px) { + .sm\:container { + width: 100%; + } + @media (min-width: 640px) { + .sm\:container { + max-width: 640px; + } + } + @media (min-width: 768px) { + .sm\:container { + max-width: 768px; + } + } + @media (min-width: 1024px) { + .sm\:container { + max-width: 1024px; + } + } + @media (min-width: 1280px) { + .sm\:container { + max-width: 1280px; + } + } + @media (min-width: 1536px) { + .sm\:container { + max-width: 1536px; + } + } + .sm\:text-center { + text-align: center; + } + .sm\:tabular-nums { + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) + var(--tw-numeric-spacing) var(--tw-numeric-fraction); + } + .sm\:custom-util { + background: #abcdef; + } + @media (prefers-reduced-motion: no-preference) { + .group:active .sm\:motion-safe\:group-active\:focus\:opacity-10:focus { + opacity: 0.1; + } + } +} +@media (min-width: 768px) { + .md\:container { + width: 100%; + } + @media (min-width: 640px) { + .md\:container { + max-width: 640px; + } + } + @media (min-width: 768px) { + .md\:container { + max-width: 768px; + } + } + @media (min-width: 1024px) { + .md\:container { + max-width: 1024px; + } + } + @media (min-width: 1280px) { + .md\:container { + max-width: 1280px; + } + } + @media (min-width: 1536px) { + .md\:container { + max-width: 1536px; + } + } + .md\:text-center { + text-align: center; + } + .md\:opacity-50 { + opacity: 0.5; + } + .md\:shadow-sm { + --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); + } + .md\:hover\:border-r-blue-500\/30:hover { + border-right-color: rgb(59 130 246 / 0.3); + } + .md\:hover\:opacity-20:hover { + opacity: 0.2; + } + @media (prefers-reduced-motion: no-preference) { + .md\:motion-safe\:hover\:transition:hover { + transition-property: color, background-color, border-color, text-decoration-color, fill, + stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + } + .dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active { + background: #abcdef !important; + } + } + @media (min-width: 640px) { + .md\:sm\:text-center { + text-align: center; + } + } +} +@media (min-width: 1280px) and (max-width: 1535px) { + .range\:text-right { + text-align: right; + } +} +@media (min-width: 640px) and (max-width: 767px), (max-width: 868px) { + .multi\:text-left { + text-align: left; + } +} diff --git a/tests/oxide.test.html b/tests/oxide.test.html new file mode 100644 index 000000000..5215db2ad --- /dev/null +++ b/tests/oxide.test.html @@ -0,0 +1,77 @@ + + + + + + + Title + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/tests/oxide.test.js b/tests/oxide.test.js new file mode 100644 index 000000000..75fa4b2c9 --- /dev/null +++ b/tests/oxide.test.js @@ -0,0 +1,202 @@ +import fs from 'fs' +import path from 'path' + +import { env } from '../src/lib/sharedState' +import { run, css } from './util/run' + +afterEach(() => { + env.OXIDE = false +}) + +test.each([[true], [false]])('it works (using Rust: %p)', (useOxide) => { + env.OXIDE = useOxide + + let config = { + darkMode: 'class', + content: [path.resolve(__dirname, './oxide.test.html')], + corePlugins: { preflight: false }, + theme: { + extend: { + screens: { + range: { min: '1280px', max: '1535px' }, + multi: [{ min: '640px', max: '767px' }, { max: '868px' }], + }, + gradientColorStops: { + foo: '#bada55', + }, + backgroundImage: { + 'hero--home-1': "url('/images/homepage-1.jpg')", + }, + }, + }, + plugins: [ + function ({ addVariant }) { + addVariant( + 'foo', + ({ container }) => { + container.walkRules((rule) => { + rule.selector = `.foo\\:${rule.selector.slice(1)}` + rule.walkDecls((decl) => { + decl.important = true + }) + }) + }, + { before: 'sm' } + ) + }, + function ({ addUtilities, addBase, theme }) { + addBase({ + h1: { + fontSize: theme('fontSize.2xl'), + fontWeight: theme('fontWeight.bold'), + '&:first-child': { + marginTop: '0px', + }, + }, + }) + addUtilities( + { + '.magic-none': { + magic: 'none', + }, + '.magic-tons': { + magic: 'tons', + }, + }, + ['responsive', 'hover'] + ) + }, + ], + } + + let input = css` + @layer utilities { + .custom-util { + background: #abcdef; + } + *, + ::before, + ::after, + ::backdrop { + margin: 10px; + } + } + @layer components { + .test-apply-font-variant { + @apply ordinal tabular-nums; + } + .custom-component { + background: #123456; + } + *, + ::before, + ::after, + ::backdrop { + padding: 5px; + } + .foo .bg-black { + appearance: none; + } + } + @layer base { + div { + background: #654321; + } + } + .theme-test { + font-family: theme('fontFamily.sans'); + color: theme('colors.blue.500'); + } + @screen lg { + .screen-test { + color: purple; + } + } + .apply-1 { + @apply mt-6; + } + .apply-2 { + @apply mt-6; + } + .apply-test { + @apply mt-6 bg-pink-500 hover:font-bold focus:hover:font-bold sm:bg-green-500 sm:focus:even:bg-pink-200; + } + .apply-components { + @apply container mx-auto; + } + .drop-empty-rules { + @apply hover:font-bold; + } + .apply-group { + @apply group-hover:font-bold; + } + .apply-dark-mode { + @apply dark:font-bold; + } + .apply-with-existing:hover { + @apply font-normal sm:bg-green-500; + } + .multiple, + .selectors { + @apply font-bold group-hover:font-normal; + } + .list { + @apply space-x-4; + } + .nested { + .example { + @apply font-bold hover:font-normal; + } + } + .apply-order-a { + @apply m-5 mt-6; + } + .apply-order-b { + @apply m-5 mt-6; + } + .apply-dark-group-example-a { + @apply dark:group-hover:bg-green-500; + } + .crazy-example { + @apply sm:motion-safe:group-active:focus:opacity-10; + } + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + + return run(input, config).then((result) => { + let expectedPath = path.resolve(__dirname, './oxide.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchFormattedCss(expected) + }) +}) + +xit.each([[true], [false]])( + 'should use the transformer for svelte files (using Rust: %p)', + (useOxide) => { + env.OXIDE = useOxide + + let config = { + darkMode: 'class', + content: [path.resolve(__dirname, './oxide.test.svelte')], + corePlugins: { preflight: false }, + theme: {}, + plugins: [], + } + + let input = css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + + return run(input, config).then((result) => { + let expectedPath = path.resolve(__dirname, './oxide-svelte.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchFormattedCss(expected) + }) + } +) diff --git a/tests/oxide.test.svelte b/tests/oxide.test.svelte new file mode 100644 index 000000000..5a6ea3135 --- /dev/null +++ b/tests/oxide.test.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/tests/plugins/fontSize.test.js b/tests/plugins/fontSize.test.js index 5738e0a96..59143f9b1 100644 --- a/tests/plugins/fontSize.test.js +++ b/tests/plugins/fontSize.test.js @@ -14,6 +14,10 @@ test('font-size utilities can include a default line-height', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchCss(css` + .text-lg { + font-size: 20px; + line-height: 28px; + } .text-md { font-size: 16px; line-height: 24px; @@ -21,10 +25,6 @@ test('font-size utilities can include a default line-height', () => { .text-sm { font-size: 12px; } - .text-lg { - font-size: 20px; - line-height: 28px; - } `) }) }) @@ -43,6 +43,10 @@ test('font-size utilities can include a default letter-spacing', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchCss(css` + .text-lg { + font-size: 20px; + letter-spacing: -0.02em; + } .text-md { font-size: 16px; letter-spacing: -0.01em; @@ -50,10 +54,6 @@ test('font-size utilities can include a default letter-spacing', () => { .text-sm { font-size: 12px; } - .text-lg { - font-size: 20px; - letter-spacing: -0.02em; - } `) }) }) @@ -72,6 +72,11 @@ test('font-size utilities can include a default line-height and letter-spacing', return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchCss(css` + .text-lg { + font-size: 20px; + line-height: 28px; + letter-spacing: -0.02em; + } .text-md { font-size: 16px; line-height: 24px; @@ -80,11 +85,6 @@ test('font-size utilities can include a default line-height and letter-spacing', .text-sm { font-size: 12px; } - .text-lg { - font-size: 20px; - line-height: 28px; - letter-spacing: -0.02em; - } `) }) }) @@ -103,6 +103,11 @@ test('font-size utilities can include a font-weight', () => { return run('@tailwind utilities', config).then((result) => { expect(result.css).toMatchCss(css` + .text-lg { + font-size: 20px; + line-height: 28px; + font-weight: bold; + } .text-md { font-size: 16px; line-height: 24px; @@ -111,11 +116,6 @@ test('font-size utilities can include a font-weight', () => { .text-sm { font-size: 12px; } - .text-lg { - font-size: 20px; - line-height: 28px; - font-weight: bold; - } `) }) }) diff --git a/tests/prefix.test.js b/tests/prefix.test.js index 47d0d672e..1feba26c8 100644 --- a/tests/prefix.test.js +++ b/tests/prefix.test.js @@ -2,518 +2,523 @@ import fs from 'fs' import path from 'path' import { run, html, css } from './util/run' +import { env } from '../src/lib/sharedState' -test('prefix', () => { - let config = { - prefix: 'tw-', - darkMode: 'class', - content: [path.resolve(__dirname, './prefix.test.html')], - corePlugins: { preflight: false }, - theme: { - animation: { - spin: 'spin 1s linear infinite', - ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite', +let group = env.OXIDE ? describe.skip : describe + +group('prefix', () => { + test('prefix', () => { + let config = { + prefix: 'tw-', + darkMode: 'class', + content: [path.resolve(__dirname, './prefix.test.html')], + corePlugins: { preflight: false }, + theme: { + animation: { + spin: 'spin 1s linear infinite', + ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite', + }, + keyframes: { + spin: { to: { transform: 'rotate(360deg)' } }, + }, }, - keyframes: { - spin: { to: { transform: 'rotate(360deg)' } }, - }, - }, - plugins: [ - function ({ addComponents, addUtilities }) { - addComponents({ - '.btn-prefix': { - button: 'yes', - }, - }) - addComponents( - { - '.btn-no-prefix': { + plugins: [ + function ({ addComponents, addUtilities }) { + addComponents({ + '.btn-prefix': { button: 'yes', }, - }, - { respectPrefix: false } - ) - addUtilities({ - '.custom-util-prefix': { - button: 'no', - }, - }) - addUtilities( - { - '.custom-util-no-prefix': { + }) + addComponents( + { + '.btn-no-prefix': { + button: 'yes', + }, + }, + { respectPrefix: false } + ) + addUtilities({ + '.custom-util-prefix': { button: 'no', }, - }, - { respectPrefix: false } - ) + }) + addUtilities( + { + '.custom-util-no-prefix': { + button: 'no', + }, + }, + { respectPrefix: false } + ) + }, + ], + } + + let input = css` + @tailwind base; + @tailwind components; + @layer components { + .custom-component { + @apply tw-font-bold dark:group-hover:tw-font-normal; + } + } + @tailwind utilities; + @layer utilities { + .custom-utility { + foo: bar; + } + } + ` + + return run(input, config).then((result) => { + let expectedPath = path.resolve(__dirname, './prefix.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchFormattedCss(expected) + }) + }) + + it('negative values: marker before prefix', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .-tw-top-1 { + top: -0.25rem; + } + `) + }) + + it('negative values: marker after prefix', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .tw--top-1 { + top: -0.25rem; + } + `) + }) + + it('negative values: marker before prefix and arbitrary value', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .-tw-top-\[1px\] { + top: -1px; + } + `) + }) + + it('negative values: marker after prefix and arbitrary value', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .tw--top-\[1px\] { + top: -1px; + } + `) + }) + + it('negative values: no marker and arbitrary value', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`
` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .tw-top-\[-1px\] { + top: -1px; + } + `) + }) + + it('negative values: variant versions', async () => { + let config = { + prefix: 'tw-', + content: [ + { + raw: html` +
+
+
+ + +
+ `, + }, + ], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .hover\:-tw-top-1:hover { + top: -0.25rem; + } + .hover\:-tw-top-\[1px\]:hover { + top: -1px; + } + .hover\:tw--top-1:hover { + top: -0.25rem; + } + .hover\:tw--top-\[1px\]:hover { + top: -1px; + } + .hover\:tw-top-\[-1px\]:hover { + top: -1px; + } + `) + }) + + it('negative values: prefix and apply', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + + .a { + @apply hover:tw--top-1; + } + .b { + @apply hover:-tw-top-1; + } + .c { + @apply hover:-tw-top-[1px]; + } + .d { + @apply hover:tw--top-[1px]; + } + .e { + @apply hover:tw-top-[-1px]; + } + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .a:hover { + top: -0.25rem; + } + .b:hover { + top: -0.25rem; + } + .c:hover { + top: -1px; + } + .d:hover { + top: -1px; + } + .e:hover { + top: -1px; + } + `) + }) + + it('negative values: prefix in the safelist', async () => { + let config = { + prefix: 'tw-', + safelist: [{ pattern: /-tw-top-1/g }, { pattern: /tw--top-1/g }], + theme: { + inset: { + 1: '0.25rem', + }, }, - ], - } - - let input = css` - @tailwind base; - @tailwind components; - @layer components { - .custom-component { - @apply tw-font-bold dark:group-hover:tw-font-normal; - } + content: [{ raw: html`` }], + corePlugins: { preflight: false }, } - @tailwind utilities; - @layer utilities { - .custom-utility { - foo: bar; + + let input = css` + @tailwind utilities; + ` + + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .-tw-top-1 { + top: -0.25rem; } + .tw--top-1 { + top: -0.25rem; + } + `) + }) + + it('prefix with negative values and variants in the safelist', async () => { + let config = { + prefix: 'tw-', + safelist: [ + { pattern: /-tw-top-1/, variants: ['hover', 'sm:hover'] }, + { pattern: /tw--top-1/, variants: ['hover', 'sm:hover'] }, + ], + theme: { + inset: { + 1: '0.25rem', + }, + }, + content: [{ raw: html`` }], + corePlugins: { preflight: false }, } - ` - return run(input, config).then((result) => { - let expectedPath = path.resolve(__dirname, './prefix.test.css') - let expected = fs.readFileSync(expectedPath, 'utf8') + let input = css` + @tailwind utilities; + ` - expect(result.css).toMatchFormattedCss(expected) + await run(input, config) + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .-tw-top-1 { + top: -0.25rem; + } + .tw--top-1 { + top: -0.25rem; + } + .hover\:-tw-top-1:hover { + top: -0.25rem; + } + + .hover\:tw--top-1:hover { + top: -0.25rem; + } + @media (min-width: 640px) { + .sm\:hover\:-tw-top-1:hover { + top: -0.25rem; + } + .sm\:hover\:tw--top-1:hover { + top: -0.25rem; + } + } + `) + }) + + it('prefix does not detect and generate unnecessary classes', async () => { + let config = { + prefix: 'tw-_', + content: [{ raw: html`-aaa-filter aaaa-table aaaa-hidden` }], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css``) + }) + + it('supports prefixed utilities using arbitrary values', async () => { + let config = { + prefix: 'tw-', + content: [{ raw: html`foo` }], + corePlugins: { preflight: false }, + } + + let input = css` + .foo { + @apply tw-text-[color:rgb(var(--button-background,var(--primary-button-background)))]; + @apply tw-ease-[cubic-bezier(0.77,0,0.175,1)]; + @apply tw-rounded-[min(4px,var(--input-border-radius))]; + } + ` + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .foo { + color: rgb(var(--button-background, var(--primary-button-background))); + transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1); + border-radius: min(4px, var(--input-border-radius)); + } + `) + }) + + it('supports non-word prefixes (1)', async () => { + let config = { + prefix: '@', + content: [ + { + raw: html` +
+
+
+
+
+
+ + +
+ `, + }, + ], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + @layer utilities { + .my-utility { + color: orange; + } + } + .foo { + @apply @text-white; + @apply [background-color:red]; + } + ` + + const result = await run(input, config) + + expect(result.css).toMatchFormattedCss(css` + .\@bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + .\@underline { + text-decoration-line: underline; + } + .my-utility { + color: orange; + } + .foo { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); + background-color: red; + } + .hover\:before\:\@content-\[\'Hovering\'\]:hover::before { + --tw-content: 'Hovering'; + content: var(--tw-content); + } + `) + }) + + it('supports non-word prefixes (2)', async () => { + let config = { + prefix: '@]$', + content: [ + { + raw: html` +
+
+
+
+
+
+ + +
+ `, + }, + ], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + @layer utilities { + .my-utility { + color: orange; + } + } + .foo { + @apply @]$text-white; + @apply [background-color:red]; + } + ` + + const result = await run(input, config) + + // TODO: The class `.hover\:before\:\@\]\$content-\[\'Hovering\'\]:hover::before` is not generated + // This happens because of the parenthesis/brace/bracket clipping performed on candidates + + expect(result.css).toMatchFormattedCss(css` + .\@\]\$bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + .\@\]\$underline { + text-decoration-line: underline; + } + .my-utility { + color: orange; + } + .foo { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); + background-color: red; + } + `) }) }) - -it('negative values: marker before prefix', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`
` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .-tw-top-1 { - top: -0.25rem; - } - `) -}) - -it('negative values: marker after prefix', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`
` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .tw--top-1 { - top: -0.25rem; - } - `) -}) - -it('negative values: marker before prefix and arbitrary value', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`
` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .-tw-top-\[1px\] { - top: -1px; - } - `) -}) - -it('negative values: marker after prefix and arbitrary value', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`
` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .tw--top-\[1px\] { - top: -1px; - } - `) -}) - -it('negative values: no marker and arbitrary value', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`
` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .tw-top-\[-1px\] { - top: -1px; - } - `) -}) - -it('negative values: variant versions', async () => { - let config = { - prefix: 'tw-', - content: [ - { - raw: html` -
-
-
- - -
- `, - }, - ], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .hover\:-tw-top-1:hover { - top: -0.25rem; - } - .hover\:tw--top-1:hover { - top: -0.25rem; - } - .hover\:-tw-top-\[1px\]:hover { - top: -1px; - } - .hover\:tw--top-\[1px\]:hover { - top: -1px; - } - .hover\:tw-top-\[-1px\]:hover { - top: -1px; - } - `) -}) - -it('negative values: prefix and apply', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - - .a { - @apply hover:tw--top-1; - } - .b { - @apply hover:-tw-top-1; - } - .c { - @apply hover:-tw-top-[1px]; - } - .d { - @apply hover:tw--top-[1px]; - } - .e { - @apply hover:tw-top-[-1px]; - } - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .a:hover { - top: -0.25rem; - } - .b:hover { - top: -0.25rem; - } - .c:hover { - top: -1px; - } - .d:hover { - top: -1px; - } - .e:hover { - top: -1px; - } - `) -}) - -it('negative values: prefix in the safelist', async () => { - let config = { - prefix: 'tw-', - safelist: [{ pattern: /-tw-top-1/g }, { pattern: /tw--top-1/g }], - theme: { - inset: { - 1: '0.25rem', - }, - }, - content: [{ raw: html`` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .-tw-top-1 { - top: -0.25rem; - } - .tw--top-1 { - top: -0.25rem; - } - `) -}) - -it('prefix with negative values and variants in the safelist', async () => { - let config = { - prefix: 'tw-', - safelist: [ - { pattern: /-tw-top-1/, variants: ['hover', 'sm:hover'] }, - { pattern: /tw--top-1/, variants: ['hover', 'sm:hover'] }, - ], - theme: { - inset: { - 1: '0.25rem', - }, - }, - content: [{ raw: html`` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - await run(input, config) - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .-tw-top-1 { - top: -0.25rem; - } - .tw--top-1 { - top: -0.25rem; - } - .hover\:-tw-top-1:hover { - top: -0.25rem; - } - - .hover\:tw--top-1:hover { - top: -0.25rem; - } - @media (min-width: 640px) { - .sm\:hover\:-tw-top-1:hover { - top: -0.25rem; - } - .sm\:hover\:tw--top-1:hover { - top: -0.25rem; - } - } - `) -}) - -it('prefix does not detect and generate unnecessary classes', async () => { - let config = { - prefix: 'tw-_', - content: [{ raw: html`-aaa-filter aaaa-table aaaa-hidden` }], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - ` - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css``) -}) - -it('supports prefixed utilities using arbitrary values', async () => { - let config = { - prefix: 'tw-', - content: [{ raw: html`foo` }], - corePlugins: { preflight: false }, - } - - let input = css` - .foo { - @apply tw-text-[color:rgb(var(--button-background,var(--primary-button-background)))]; - @apply tw-ease-[cubic-bezier(0.77,0,0.175,1)]; - @apply tw-rounded-[min(4px,var(--input-border-radius))]; - } - ` - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .foo { - color: rgb(var(--button-background, var(--primary-button-background))); - transition-timing-function: cubic-bezier(0.77, 0, 0.175, 1); - border-radius: min(4px, var(--input-border-radius)); - } - `) -}) - -it('supports non-word prefixes (1)', async () => { - let config = { - prefix: '@', - content: [ - { - raw: html` -
-
-
-
-
-
- - -
- `, - }, - ], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - @layer utilities { - .my-utility { - color: orange; - } - } - .foo { - @apply @text-white; - @apply [background-color:red]; - } - ` - - const result = await run(input, config) - - expect(result.css).toMatchFormattedCss(css` - .\@bg-black { - --tw-bg-opacity: 1; - background-color: rgb(0 0 0 / var(--tw-bg-opacity)); - } - .\@underline { - text-decoration-line: underline; - } - .my-utility { - color: orange; - } - .foo { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - background-color: red; - } - .hover\:before\:\@content-\[\'Hovering\'\]:hover::before { - --tw-content: 'Hovering'; - content: var(--tw-content); - } - `) -}) - -it('supports non-word prefixes (2)', async () => { - let config = { - prefix: '@]$', - content: [ - { - raw: html` -
-
-
-
-
-
- - -
- `, - }, - ], - corePlugins: { preflight: false }, - } - - let input = css` - @tailwind utilities; - @layer utilities { - .my-utility { - color: orange; - } - } - .foo { - @apply @]$text-white; - @apply [background-color:red]; - } - ` - - const result = await run(input, config) - - // TODO: The class `.hover\:before\:\@\]\$content-\[\'Hovering\'\]:hover::before` is not generated - // This happens because of the parenthesis/brace/bracket clipping performed on candidates - - expect(result.css).toMatchFormattedCss(css` - .\@\]\$bg-black { - --tw-bg-opacity: 1; - background-color: rgb(0 0 0 / var(--tw-bg-opacity)); - } - .\@\]\$underline { - text-decoration-line: underline; - } - .my-utility { - color: orange; - } - .foo { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); - background-color: red; - } - `) -}) diff --git a/tests/raw-content.test.css b/tests/raw-content.test.css index f7e87f4ae..ff17b06f4 100644 --- a/tests/raw-content.test.css +++ b/tests/raw-content.test.css @@ -55,19 +55,13 @@ bottom: 0px; left: 0px; } -.inset-y-4 { - top: 1rem; - bottom: 1rem; -} .inset-x-2 { left: 0.5rem; right: 0.5rem; } -.top-6 { - top: 1.5rem; -} -.right-8 { - right: 2rem; +.inset-y-4 { + top: 1rem; + bottom: 1rem; } .bottom-12 { bottom: 3rem; @@ -75,6 +69,12 @@ .left-16 { left: 4rem; } +.right-8 { + right: 2rem; +} +.top-6 { + top: 1.5rem; +} .isolate { isolation: isolate; } @@ -84,12 +84,12 @@ .z-30 { z-index: 30; } -.order-last { - order: 9999; -} .order-2 { order: 2; } +.order-last { + order: 9999; +} .col-span-3 { grid-column: span 3 / span 3; } @@ -117,19 +117,13 @@ .m-4 { margin: 1rem; } -.my-2 { - margin-top: 0.5rem; - margin-bottom: 0.5rem; -} .mx-auto { margin-left: auto; margin-right: auto; } -.mt-0 { - margin-top: 0px; -} -.mr-1 { - margin-right: 0.25rem; +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; } .mb-3 { margin-bottom: 0.75rem; @@ -137,6 +131,12 @@ .ml-4 { margin-left: 1rem; } +.mr-1 { + margin-right: 0.25rem; +} +.mt-0 { + margin-top: 0px; +} .box-border { box-sizing: border-box; } @@ -188,46 +188,64 @@ .origin-top-right { transform-origin: top right; } -.translate-x-5 { - --tw-translate-x: 1.25rem; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +.-translate-x-3 { + --tw-translate-x: -0.75rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .-translate-x-4 { --tw-translate-x: -1rem; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); +} +.translate-x-5 { + --tw-translate-x: 1.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .translate-y-6 { --tw-translate-y: 1.5rem; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} -.-translate-x-3 { - --tw-translate-x: -0.75rem; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .rotate-3 { --tw-rotate: 3deg; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); -} -.skew-y-12 { - --tw-skew-y: 12deg; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .skew-x-12 { --tw-skew-x: 12deg; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); +} +.skew-y-12 { + --tw-skew-y: 12deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .scale-95 { --tw-scale-x: 0.95; --tw-scale-y: 0.95; - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .transform { - transform: translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .transform-gpu { - transform: translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) - rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) - scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .animate-none { animation: none; @@ -322,26 +340,26 @@ .space-x-reverse > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 1; } -.divide-x-2 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-x-reverse: 0; - border-right-width: calc(2px * var(--tw-divide-x-reverse)); - border-left-width: calc(2px * calc(1 - var(--tw-divide-x-reverse))); -} -.divide-y-4 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-y-reverse: 0; - border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); - border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); -} .divide-x-0 > :not([hidden]) ~ :not([hidden]) { --tw-divide-x-reverse: 0; border-right-width: calc(0px * var(--tw-divide-x-reverse)); border-left-width: calc(0px * calc(1 - var(--tw-divide-x-reverse))); } +.divide-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-x-reverse: 0; + border-right-width: calc(2px * var(--tw-divide-x-reverse)); + border-left-width: calc(2px * calc(1 - var(--tw-divide-x-reverse))); +} .divide-y-0 > :not([hidden]) ~ :not([hidden]) { --tw-divide-y-reverse: 0; border-top-width: calc(0px * calc(1 - var(--tw-divide-y-reverse))); border-bottom-width: calc(0px * var(--tw-divide-y-reverse)); } +.divide-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(4px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(4px * var(--tw-divide-y-reverse)); +} .divide-dotted > :not([hidden]) ~ :not([hidden]) { border-style: dotted; } @@ -473,19 +491,13 @@ .p-4 { padding: 1rem; } -.py-2 { - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } -.pt-1 { - padding-top: 0.25rem; -} -.pr-2 { - padding-right: 0.5rem; +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; } .pb-3 { padding-bottom: 0.75rem; @@ -493,6 +505,12 @@ .pl-4 { padding-left: 1rem; } +.pr-2 { + padding-right: 0.5rem; +} +.pt-1 { + padding-top: 0.25rem; +} .text-center { text-align: center; } @@ -519,22 +537,25 @@ } .ordinal { --tw-ordinal: ordinal; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) + var(--tw-numeric-spacing) var(--tw-numeric-fraction); } .tabular-nums { --tw-numeric-spacing: tabular-nums; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) + var(--tw-numeric-spacing) var(--tw-numeric-fraction); } .diagonal-fractions { --tw-numeric-fraction: diagonal-fractions; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); -} -.leading-relaxed { - line-height: 1.625; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) + var(--tw-numeric-spacing) var(--tw-numeric-fraction); } .leading-5 { line-height: 1.25rem; } +.leading-relaxed { + line-height: 1.625; +} .tracking-tight { letter-spacing: -0.025em; } @@ -580,12 +601,6 @@ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } -.shadow-md { - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), - var(--tw-shadow); -} .shadow-lg { --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), @@ -593,6 +608,12 @@ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } +.shadow-md { + --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); +} .ring { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); @@ -622,85 +643,115 @@ } .blur-md { --tw-blur: blur(12px); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .brightness-150 { --tw-brightness: brightness(1.5); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .contrast-50 { --tw-contrast: contrast(0.5); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .drop-shadow-md { --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .grayscale { --tw-grayscale: grayscale(100%); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .hue-rotate-60 { --tw-hue-rotate: hue-rotate(60deg); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .invert { --tw-invert: invert(100%); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .saturate-200 { --tw-saturate: saturate(2); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .sepia { --tw-sepia: sepia(100%); - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .filter { - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .filter-none { filter: none; } .backdrop-blur-lg { --tw-backdrop-blur: blur(16px); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-brightness-50 { --tw-backdrop-brightness: brightness(0.5); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-contrast-0 { --tw-backdrop-contrast: contrast(0); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-grayscale { --tw-backdrop-grayscale: grayscale(100%); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-hue-rotate-90 { --tw-backdrop-hue-rotate: hue-rotate(90deg); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-invert { --tw-backdrop-invert: invert(100%); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-opacity-75 { --tw-backdrop-opacity: opacity(0.75); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-saturate-150 { --tw-backdrop-saturate: saturate(1.5); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-sepia { --tw-backdrop-sepia: sepia(100%); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-filter { - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .backdrop-filter-none { backdrop-filter: none; diff --git a/tests/raw-content.test.js b/tests/raw-content.test.js index 5e4c54de9..199acc120 100644 --- a/tests/raw-content.test.js +++ b/tests/raw-content.test.js @@ -21,28 +21,3 @@ it('raw content', () => { expect(result.css).toMatchFormattedCss(expected) }) }) - -test('raw content with extension', () => { - let config = { - content: { - files: [ - { - raw: fs.readFileSync(path.resolve(__dirname, './raw-content.test.html'), 'utf8'), - extension: 'html', - }, - ], - extract: { - html: () => ['invisible'], - }, - }, - corePlugins: { preflight: false }, - } - - return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchFormattedCss(css` - .invisible { - visibility: hidden; - } - `) - }) -}) diff --git a/tests/safelist.test.js b/tests/safelist.test.js index 430f10331..3aab69d13 100644 --- a/tests/safelist.test.js +++ b/tests/safelist.test.js @@ -273,16 +273,16 @@ it('should safelist negatives based on a pattern regex', () => { --tw-bg-opacity: 1; background-color: rgb(248 113 113 / var(--tw-bg-opacity)); } - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } .bg-red-400\/40 { background-color: rgb(248 113 113 / 0.4); } .bg-red-400\/50 { background-color: rgb(248 113 113 / 0.5); } + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } .bg-red-500\/40 { background-color: rgb(239 68 68 / 0.4); } @@ -305,16 +305,16 @@ it('should safelist negatives based on a pattern regex', () => { --tw-bg-opacity: 1; background-color: rgb(248 113 113 / var(--tw-bg-opacity)); } - .hover\:bg-red-500:hover { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } .hover\:bg-red-400\/40:hover { background-color: rgb(248 113 113 / 0.4); } .hover\:bg-red-400\/50:hover { background-color: rgb(248 113 113 / 0.5); } + .hover\:bg-red-500:hover { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } .hover\:bg-red-500\/40:hover { background-color: rgb(239 68 68 / 0.4); } diff --git a/tests/syntax-lit-html.test.js b/tests/syntax-lit-html.test.js index dbc8936d8..1a780d136 100644 --- a/tests/syntax-lit-html.test.js +++ b/tests/syntax-lit-html.test.js @@ -23,14 +23,14 @@ test('it detects classes in lit-html templates', () => { --tw-bg-opacity: 1; background-color: rgb(96 165 250 / var(--tw-bg-opacity)); } - .py-2 { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - } .px-4 { padding-left: 1rem; padding-right: 1rem; } + .py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } .font-bold { font-weight: 700; } diff --git a/tests/syntax-svelte.test.js b/tests/syntax-svelte.test.js index 83e038d1e..4f2b5b5fe 100644 --- a/tests/syntax-svelte.test.js +++ b/tests/syntax-svelte.test.js @@ -1,10 +1,13 @@ import path from 'path' import { run } from './util/run' +import { env } from '../src/lib/sharedState' let css = String.raw -test('it detects svelte based on the file extension', () => { +let t = env.OXIDE ? test.skip : test + +t('it detects svelte based on the file extension', () => { let config = { content: [path.resolve(__dirname, './syntax-svelte.test.svelte')], corePlugins: { preflight: false }, @@ -33,7 +36,7 @@ test('it detects svelte based on the file extension', () => { }) }) -test('using raw with svelte extension', () => { +t('using raw with svelte extension', () => { let config = { content: [ { diff --git a/tests/variants.test.js b/tests/variants.test.js index ab5622d13..aa85beb8b 100644 --- a/tests/variants.test.js +++ b/tests/variants.test.js @@ -39,12 +39,11 @@ test('order matters and produces different behaviour', () => { return run('@tailwind utilities', config).then((result) => { return expect(result.css).toMatchFormattedCss(css` - .hover\:file\:bg-pink-600::file-selector-button:hover { + .file\:hover\:bg-pink-600:hover::file-selector-button { --tw-bg-opacity: 1; background-color: rgb(219 39 119 / var(--tw-bg-opacity)); } - - .file\:hover\:bg-pink-600:hover::file-selector-button { + .hover\:file\:bg-pink-600::file-selector-button:hover { --tw-bg-opacity: 1; background-color: rgb(219 39 119 / var(--tw-bg-opacity)); } @@ -290,21 +289,9 @@ it('should properly handle keyframes with multiple variants', async () => { transform: rotate(360deg); } } - .animate-spin { animation: spin 1s linear infinite; } - - @keyframes spin { - to { - transform: rotate(360deg); - } - } - - .hover\:animate-spin:hover { - animation: spin 1s linear infinite; - } - @keyframes bounce { 0%, 100% { @@ -316,21 +303,17 @@ it('should properly handle keyframes with multiple variants', async () => { animation-timing-function: cubic-bezier(0, 0, 0.2, 1); } } - .hover\:animate-bounce:hover { animation: bounce 1s infinite; } - @keyframes spin { to { transform: rotate(360deg); } } - - .focus\:animate-spin:focus { + .hover\:animate-spin:hover { animation: spin 1s linear infinite; } - @keyframes bounce { 0%, 100% { @@ -342,10 +325,17 @@ it('should properly handle keyframes with multiple variants', async () => { animation-timing-function: cubic-bezier(0, 0, 0.2, 1); } } - .focus\:animate-bounce:focus { animation: bounce 1s infinite; } + @keyframes spin { + to { + transform: rotate(360deg); + } + } + .focus\:animate-spin:focus { + animation: spin 1s linear infinite; + } `) })