From c8bf2d49b619e454722e7c72bce34b284b2d7529 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 17 Feb 2023 20:21:22 +0100 Subject: [PATCH] Disable color opacity plugins by default in the `oxide` engine (#10618) * disable color opacity plugins by default for the `oxide` engine * update tests to reflect this change in the `oxide` engine * update changelog * reflect changes in integration tests --- CHANGELOG.md | 4 + integrations/parcel/tests/integration.test.js | 137 +++-- .../postcss-cli/tests/integration.test.js | 143 +++-- .../rollup-sass/tests/integration.test.js | 185 ++++-- integrations/rollup/tests/integration.test.js | 142 +++-- .../tailwindcss-cli/tests/cli.test.js | 101 +++- .../tailwindcss-cli/tests/integration.test.js | 363 ++++++++---- integrations/vite/tests/integration.test.js | 145 +++-- .../webpack-4/tests/integration.test.js | 142 +++-- .../webpack-5/tests/integration.test.js | 192 +++++-- src/featureFlags.js | 4 + tests/any-type.test.js | 21 - tests/apply.test.js | 392 ++++++++++++- tests/arbitrary-values.oxide.test.css | 97 +--- tests/arbitrary-values.test.js | 28 +- tests/arbitrary-variants.test.js | 26 +- tests/basic-usage.oxide.test.css | 59 +- tests/basic-usage.test.js | 38 +- tests/blocklist.test.js | 27 +- tests/collapse-adjacent-rules.test.js | 80 ++- tests/color-opacity-modifiers.test.js | 34 +- tests/import-syntax.test.js | 49 +- tests/kitchen-sink.test.js | 539 +++++++++++++++++- tests/match-variants.test.js | 40 +- tests/opacity.test.js | 112 +++- tests/plugins/gradientColorStops.test.js | 36 +- tests/prefers-contrast.test.js | 35 +- tests/raw-content.oxide.test.css | 36 +- tests/safelist.test.js | 173 +++++- tests/syntax-lit-html.test.js | 29 +- tests/variants.oxide.test.css | 68 +-- tests/variants.test.js | 41 +- 32 files changed, 2746 insertions(+), 772 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de9618db4016..3931d5f91a47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `caption-side` utilities ([#10470](https://github.com/tailwindlabs/tailwindcss/pull/10470)) - Add `justify-normal` and `justify-stretch` utilities ([#10560](https://github.com/tailwindlabs/tailwindcss/pull/10560)) +### Changed + +- [Oxide] Disable color opacity plugins by default in the `oxide` engine ([#10618](https://github.com/tailwindlabs/tailwindcss/pull/10618)) + ## [3.2.7] - 2023-02-16 ### Fixed diff --git a/integrations/parcel/tests/integration.test.js b/integrations/parcel/tests/integration.test.js index 646ca051ae5c..0fc539f37eec 100644 --- a/integrations/parcel/tests/integration.test.js +++ b/integrations/parcel/tests/integration.test.js @@ -1,5 +1,6 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, @@ -74,20 +75,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) }) - expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -128,20 +147,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) }) - expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -281,20 +318,36 @@ describe('watcher', () => { ) }) - expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( - css` - /* prettier-ignore */ - .btn { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - border-radius: .25rem; - padding: .25rem .5rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .btn { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .btn { + background-color: #ef4444; + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/postcss-cli/tests/integration.test.js b/integrations/postcss-cli/tests/integration.test.js index 964c57b82e39..36cfe7f4c4f5 100644 --- a/integrations/postcss-cli/tests/integration.test.js +++ b/integrations/postcss-cli/tests/integration.test.js @@ -1,5 +1,6 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ output: 'dist', @@ -60,20 +61,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -109,20 +128,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -247,22 +284,40 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + /* prettier-ignore */ + .btn { + border-radius: 0.25rem; + background-color: #ef4444; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/rollup-sass/tests/integration.test.js b/integrations/rollup-sass/tests/integration.test.js index cdf9a11fb2cc..7d359577eea1 100644 --- a/integrations/rollup-sass/tests/integration.test.js +++ b/integrations/rollup-sass/tests/integration.test.js @@ -1,5 +1,6 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ output: 'dist', @@ -60,20 +61,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -109,20 +128,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -245,22 +282,36 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .btn { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .btn { + background-color: #ef4444; + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) @@ -326,22 +377,36 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .btn { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .btn { + background-color: #ef4444; + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/rollup/tests/integration.test.js b/integrations/rollup/tests/integration.test.js index 63a28bcb54c4..1daea888a875 100644 --- a/integrations/rollup/tests/integration.test.js +++ b/integrations/rollup/tests/integration.test.js @@ -1,5 +1,6 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ output: 'dist', @@ -60,20 +61,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -109,20 +128,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -245,22 +282,39 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('index.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + background-color: #ef4444; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/tailwindcss-cli/tests/cli.test.js b/integrations/tailwindcss-cli/tests/cli.test.js index b43f2975aa1f..def432cab4e5 100644 --- a/integrations/tailwindcss-cli/tests/cli.test.js +++ b/integrations/tailwindcss-cli/tests/cli.test.js @@ -2,6 +2,7 @@ let path = require('path') let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') let resolveToolRoot = require('../../resolve-tool-root') +let { env } = require('../../../lib/lib/sharedState') let version = require('../../../package.json').version @@ -215,22 +216,42 @@ describe('Build command', () => { await $(`${EXECUTABLE} --output ./dist/main.css --postcss`) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .font-bold-after { - font-weight: 700; - } + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .font-bold-after { + font-weight: 700; + } - .btn-after { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - ` - ) + .btn-after { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .font-bold-after { + font-weight: 700; + } + + .btn-after { + background-color: #ef4444; + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + ` + ) + } }) test('--postcss (custom.postcss.config.js)', async () => { @@ -266,22 +287,42 @@ describe('Build command', () => { await $(`${EXECUTABLE} --output ./dist/main.css --postcss ./custom.postcss.config.js`) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .font-bold-after { - font-weight: 700; - } + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .font-bold-after { + font-weight: 700; + } - .btn-after { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - ` - ) + .btn-after { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .font-bold-after { + font-weight: 700; + } + + .btn-after { + background-color: #ef4444; + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + ` + ) + } }) test('--postcss supports process options', async () => { diff --git a/integrations/tailwindcss-cli/tests/integration.test.js b/integrations/tailwindcss-cli/tests/integration.test.js index 42e35a895218..ff8db20b8a2d 100644 --- a/integrations/tailwindcss-cli/tests/integration.test.js +++ b/integrations/tailwindcss-cli/tests/integration.test.js @@ -1,6 +1,7 @@ let fs = require('fs') let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ output: 'dist', @@ -71,23 +72,43 @@ describe('static build', () => { env: { NODE_ENV: 'production' }, }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } - .bg-red-600 { - --tw-bg-opacity: 1; - background-color: rgb(220 38 38 / var(--tw-bg-opacity)); - } + .bg-red-600 { + --tw-bg-opacity: 1; + background-color: rgb(220 38 38 / var(--tw-bg-opacity)); + } - .font-bold { - font-weight: 700; - } - ` - ) + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + + .bg-red-600 { + background-color: #dc2626; + } + + .font-bold { + font-weight: 700; + } + ` + ) + } }) it('can read from a config file from an @config directive', async () => { @@ -127,14 +148,26 @@ describe('static build', () => { env: { NODE_ENV: 'production' }, }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-yellow { - --tw-bg-opacity: 1; - background-color: rgb(255 255 0 / var(--tw-bg-opacity)); - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + --tw-bg-opacity: 1; + background-color: rgb(255 255 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + background-color: #ff0; + } + ` + ) + } }) it('can read from a config file from an @config directive inside an @import from postcss-import', async () => { @@ -182,14 +215,26 @@ describe('static build', () => { env: { NODE_ENV: 'production' }, }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-yellow { - --tw-bg-opacity: 1; - background-color: rgb(255 255 0 / var(--tw-bg-opacity)); - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + --tw-bg-opacity: 1; + background-color: rgb(255 255 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + background-color: #ff0; + } + ` + ) + } }) it('should work with raw content', async () => { @@ -216,14 +261,26 @@ describe('static build', () => { env: { NODE_ENV: 'production' }, }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + ` + ) + } }) }) @@ -259,20 +316,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -308,20 +383,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -496,22 +589,42 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + background-color: #ef4444; + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) @@ -573,14 +686,26 @@ describe('watcher', () => { let runningProcess = $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css -w') await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-yellow { - --tw-bg-opacity: 1; - background-color: rgb(255 255 0 / var(--tw-bg-opacity)); - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + --tw-bg-opacity: 1; + background-color: rgb(255 255 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + background-color: #ff0; + } + ` + ) + } await writeInputFile( 'index.css', @@ -593,14 +718,26 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-yellow { - --tw-bg-opacity: 1; - background-color: rgb(255 255 119 / var(--tw-bg-opacity)); - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + --tw-bg-opacity: 1; + background-color: rgb(255 255 119 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + background-color: #ff7; + } + ` + ) + } await writeInputFile( 'tailwind.2.config.js', @@ -625,14 +762,26 @@ describe('watcher', () => { ) await runningProcess.onStderr(ready) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-yellow { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-yellow { + background-color: #fff; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/vite/tests/integration.test.js b/integrations/vite/tests/integration.test.js index b2d08bc27d01..1e5cd2d3345e 100644 --- a/integrations/vite/tests/integration.test.js +++ b/integrations/vite/tests/integration.test.js @@ -2,6 +2,7 @@ require('isomorphic-fetch') let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ output: 'dist', @@ -83,20 +84,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) await runningProcess.onStdout((message) => message.includes('page reload')) - expect(await fetchCSS()).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await fetchCSS()).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await fetchCSS()).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -136,20 +155,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) await runningProcess.onStdout((message) => message.includes('page reload')) - expect(await fetchCSS()).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await fetchCSS()).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await fetchCSS()).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -288,22 +325,42 @@ describe('watcher', () => { ) await runningProcess.onStdout((message) => message.includes('hmr update /index.css')) - expect(await fetchCSS()).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await fetchCSS()).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await fetchCSS()).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + background-color: #ef4444; + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/webpack-4/tests/integration.test.js b/integrations/webpack-4/tests/integration.test.js index 63ab3cbbf130..6bbf3f879fcd 100644 --- a/integrations/webpack-4/tests/integration.test.js +++ b/integrations/webpack-4/tests/integration.test.js @@ -1,5 +1,6 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, @@ -60,20 +61,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -112,20 +131,38 @@ describe('watcher', () => { await appendToInputFile('glob/index.html', html`
`) }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -253,22 +290,39 @@ describe('watcher', () => { ) }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + background-color: #ef4444; + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/integrations/webpack-5/tests/integration.test.js b/integrations/webpack-5/tests/integration.test.js index 95f3d5f5f890..fde0d60c5364 100644 --- a/integrations/webpack-5/tests/integration.test.js +++ b/integrations/webpack-5/tests/integration.test.js @@ -1,5 +1,6 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') +let { env } = require('../../../lib/lib/sharedState') let { readOutputFile, @@ -60,20 +61,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -112,20 +131,38 @@ describe('watcher', () => { await appendToInputFile('index.html', html`
`) }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } - .font-bold { - font-weight: 700; - } - .font-normal { - font-weight: 400; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + .font-bold { + font-weight: 700; + } + .font-normal { + font-weight: 400; + } + ` + ) + } return runningProcess.stop() }) @@ -253,22 +290,39 @@ describe('watcher', () => { ) }) - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .btn { - border-radius: 0.25rem; - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - padding-left: 0.5rem; - padding-right: 0.5rem; - padding-top: 0.25rem; - padding-bottom: 0.25rem; - } - .font-bold { - font-weight: 700; - } - ` - ) + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + border-radius: 0.25rem; + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .btn { + background-color: #ef4444; + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + } + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) @@ -299,23 +353,43 @@ describe('watcher', () => { await waitForOutputFileCreation('main.css') - expect(await readOutputFile('main.css')).toIncludeCss( - css` - .bg-red-500 { - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); - } + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + } - .bg-red-600 { - --tw-bg-opacity: 1; - background-color: rgb(220 38 38 / var(--tw-bg-opacity)); - } + .bg-red-600 { + --tw-bg-opacity: 1; + background-color: rgb(220 38 38 / var(--tw-bg-opacity)); + } - .font-bold { - font-weight: 700; - } - ` - ) + .font-bold { + font-weight: 700; + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-red-500 { + background-color: #ef4444; + } + + .bg-red-600 { + background-color: #dc2626; + } + + .font-bold { + font-weight: 700; + } + ` + ) + } return runningProcess.stop() }) diff --git a/src/featureFlags.js b/src/featureFlags.js index f07229d492e1..7013c7534ffd 100644 --- a/src/featureFlags.js +++ b/src/featureFlags.js @@ -1,9 +1,13 @@ import colors from 'picocolors' import log from './util/log' +import { env } from './lib/sharedState' let defaults = { optimizeUniversalDefaults: false, generalizedModifiers: true, + get disableColorOpacityUtilitiesByDefault() { + return env.OXIDE + }, } let featureFlags = { diff --git a/tests/any-type.test.js b/tests/any-type.test.js index add8a1795551..a7e266176828 100644 --- a/tests/any-type.test.js +++ b/tests/any-type.test.js @@ -444,9 +444,6 @@ crosscheck(({ stable, oxide }) => { .divide-\[var\(--any-value\)\] > :not([hidden]) ~ :not([hidden]) { border-color: var(--any-value); } - .divide-opacity-\[var\(--any-value\)\] > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: var(--any-value); - } .rounded-\[var\(--any-value\)\] { border-radius: var(--any-value); } @@ -501,15 +498,9 @@ crosscheck(({ stable, oxide }) => { .border-t-\[var\(--any-value\)\] { border-top-color: var(--any-value); } - .border-opacity-\[var\(--any-value\)\] { - --tw-border-opacity: var(--any-value); - } .bg-\[var\(--any-value\)\] { background-color: var(--any-value); } - .bg-opacity-\[var\(--any-value\)\] { - --tw-bg-opacity: var(--any-value); - } .from-\[var\(--any-value\)\] { --tw-gradient-from: var(--any-value); --tw-gradient-to: #fff0; @@ -572,9 +563,6 @@ crosscheck(({ stable, oxide }) => { .text-\[var\(--any-value\)\] { color: var(--any-value); } - .text-opacity-\[var\(--any-value\)\] { - --tw-text-opacity: var(--any-value); - } .decoration-\[var\(--any-value\)\] { text-decoration-color: var(--any-value); } @@ -584,9 +572,6 @@ crosscheck(({ stable, oxide }) => { .placeholder-\[var\(--any-value\)\]::placeholder { color: var(--any-value); } - .placeholder-opacity-\[var\(--any-value\)\]::placeholder { - --tw-placeholder-opacity: var(--any-value); - } .caret-\[var\(--any-value\)\] { caret-color: var(--any-value); } @@ -609,9 +594,6 @@ crosscheck(({ stable, oxide }) => { .ring-\[var\(--any-value\)\] { --tw-ring-color: var(--any-value); } - .ring-opacity-\[var\(--any-value\)\] { - --tw-ring-opacity: var(--any-value); - } .ring-offset-\[var\(--any-value\)\] { --tw-ring-offset-color: var(--any-value); } @@ -743,15 +725,12 @@ crosscheck(({ stable, oxide }) => { .duration-\[var\(--any-value\)\] { transition-duration: var(--any-value); } - .ease-\[var\(--any-value\)\] { transition-timing-function: var(--any-value); } - .will-change-\[var\(--any-value\)\] { will-change: var(--any-value); } - .content-\[var\(--any-value\)\] { --tw-content: var(--any-value); content: var(--tw-content); diff --git a/tests/apply.test.js b/tests/apply.test.js index a90bdf23cec1..cb5c6be068a6 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css, defaults } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { let sharedHtml = html`
@@ -159,7 +159,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .basic-example { --tw-bg-opacity: 1; background-color: rgb(59 130 246 / var(--tw-bg-opacity)); @@ -457,6 +457,299 @@ crosscheck(() => { animation: 2s cubic-bezier(0.4, 0, 0.6, 1) infinite pulse !important; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .basic-example { + background-color: #3b82f6; + border-radius: 0.375rem; + padding: 0.5rem 1rem; + } + .class-order { + padding: 1rem 0.25rem 1.75rem 0.75rem; + } + .with-additional-properties { + text-align: right; + font-weight: 500; + } + .variants { + font-weight: 600; + } + .variants:hover { + font-weight: 700; + } + .variants:focus { + font-weight: 500; + } + @media (min-width: 1024px) { + .variants { + font-weight: 300; + } + } + @media (min-width: 1280px) { + .variants:focus { + font-weight: 900; + } + } + .only-variants:hover { + font-weight: 700; + } + .only-variants:focus { + font-weight: 500; + } + @media (min-width: 1024px) { + .only-variants { + font-weight: 300; + } + } + @media (min-width: 1280px) { + .only-variants:focus { + font-weight: 900; + } + } + .group:hover .apply-group-variant { + text-align: center; + } + @media (min-width: 1024px) { + .group:hover .apply-group-variant { + text-align: left; + } + } + .dark .apply-dark-variant { + text-align: center; + } + .dark .apply-dark-variant:hover { + text-align: right; + } + @media (min-width: 1024px) { + .dark .apply-dark-variant { + text-align: left; + } + } + .apply-custom-utility, + .apply-custom-utility:hover { + custom: stuff; + } + @media (min-width: 1024px) { + .apply-custom-utility { + custom: stuff; + } + } + @media (min-width: 1280px) { + .apply-custom-utility:focus { + custom: stuff; + } + } + .multiple, + .selectors { + background-color: #3b82f6; + border-radius: 0.375rem; + padding: 0.5rem 1rem; + } + .multiple-variants:hover, + .selectors-variants:hover { + text-align: center; + } + .multiple-variants:active, + .selectors-variants:active { + text-align: right; + } + @media (min-width: 1024px) { + .multiple-variants:focus, + .selectors-variants:focus { + text-align: left; + } + } + .group:hover .multiple-group, + .group:hover .selectors-group { + text-align: center; + } + @media (min-width: 1024px) { + .group:hover .multiple-group, + .group:hover .selectors-group { + text-align: left; + } + } + .complex-utilities { + --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); + --tw-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a; + --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); + } + .complex-utilities:hover { + --tw-shadow: 0 20px 25px -5px #0000001a, 0 8px 10px -6px #0000001a; + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), + 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); + } + .complex-utilities:focus { + --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); + } + .use-base-only-a { + font-weight: 700; + } + .use-dependant-only-b { + font-weight: 400; + } + .btn { + border-radius: 0.25rem; + padding: 0.5rem 1rem; + font-weight: 700; + } + .btn-blue { + color: #fff; + background-color: #3b82f6; + border-radius: 0.25rem; + padding: 0.5rem 1rem; + font-weight: 700; + } + .btn-blue:hover { + background-color: #1d4ed8; + } + .recursive-apply-a { + font-weight: 900; + } + @media (min-width: 640px) { + .recursive-apply-a { + font-weight: 100; + } + } + .recursive-apply-b { + font-weight: 900; + } + @media (min-width: 640px) { + .recursive-apply-b { + font-weight: 100; + } + } + .recursive-apply-b { + font-weight: 600; + } + @media (min-width: 768px) { + .recursive-apply-b { + font-weight: 200; + } + } + .recursive-apply-c { + font-weight: 900; + } + @media (min-width: 640px) { + .recursive-apply-c { + font-weight: 100; + } + } + .recursive-apply-c { + font-weight: 600; + } + @media (min-width: 768px) { + .recursive-apply-c { + font-weight: 200; + } + } + .recursive-apply-c { + font-weight: 700; + } + @media (min-width: 1024px) { + .recursive-apply-c { + font-weight: 300; + } + } + .use-with-other-properties-base, + .use-with-other-properties-component { + color: green; + font-weight: 700; + } + .add-sibling-properties { + padding: 2rem 1rem; + } + .add-sibling-properties:hover { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + @media (min-width: 1024px) { + .add-sibling-properties { + padding-left: 2.5rem; + padding-right: 2.5rem; + } + } + @media (min-width: 1280px) { + .add-sibling-properties:focus { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + } + .add-sibling-properties { + color: green; + padding-top: 3px; + font-weight: 700; + } + h1 { + font-size: 1.5rem; + line-height: 2rem; + } + @media (min-width: 640px) { + h1 { + font-size: 1.875rem; + line-height: 2.25rem; + } + } + @media (min-width: 1024px) { + h1 { + font-size: 1.5rem; + line-height: 2rem; + } + } + h2 { + font-size: 1.5rem; + line-height: 2rem; + } + @media (min-width: 1024px) { + h2 { + font-size: 1.5rem; + line-height: 2rem; + } + } + @media (min-width: 640px) { + h2 { + font-size: 1.5rem; + line-height: 2rem; + } + } + .important-modifier { + padding-left: 1rem; + padding-right: 1rem; + border-radius: 0.375rem !important; + } + .important-modifier-variant { + padding-left: 1rem; + padding-right: 1rem; + } + .important-modifier-variant:hover { + border-radius: 0.375rem !important; + } + @keyframes spin { + to { + transform: rotate(360deg); + } + } + .foo { + animation: 1s linear infinite spin; + } + @keyframes pulse { + 50% { + opacity: 0.5; + } + } + .bar { + animation: 2s cubic-bezier(0.4, 0, 0.6, 1) infinite pulse !important; + } + `) }) }) @@ -645,7 +938,7 @@ crosscheck(() => { ` await run(input, config).then((result) => { - return expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .font-bold, .foo { font-weight: 700; @@ -673,6 +966,30 @@ crosscheck(() => { color: green; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .font-bold, + .foo { + font-weight: 700; + } + .bar { + color: #ef4444; + font-weight: 700; + } + .bar:hover { + color: #22c55e; + } + .baz { + color: #ef4444; + font-weight: 700; + text-decoration-line: underline; + } + .baz:hover { + color: #22c55e; + } + .keep-me-even-though-I-am-not-used-in-content { + color: green; + } + `) }) }) @@ -888,13 +1205,19 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-gray-500, .focus\:bg-gray-500 { --tw-bg-opacity: 1; background-color: rgb(107 114 128 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-gray-500, + .focus\:bg-gray-500 { + background-color: #6b7280; + } + `) }) }) @@ -1441,7 +1764,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - return expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .a { color: red; --tw-text-opacity: 1; @@ -1455,6 +1778,18 @@ crosscheck(() => { text-decoration: underline; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .a { + color: red; + color: #22c55e; + color: #00f; + text-decoration: underline; + } + .b { + color: #22c55e; + text-decoration: underline; + } + `) }) }) @@ -1565,23 +1900,33 @@ crosscheck(() => { let result result = await run(input, config) - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .input-text { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: red; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .input-text { + background-color: red; + } + `) result = await run(input, config) - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .input-text { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: red; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .input-text { + background-color: red; + } + `) }) it('should work in layer', async () => { @@ -1603,13 +1948,18 @@ crosscheck(() => { await run(input, config) const result = await run(input, config) - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .input-text { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); background-color: red; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .input-text { + background-color: red; + } + `) }) it('apply partitioning works with media queries', async () => { @@ -1640,7 +1990,7 @@ crosscheck(() => { await run(input, config) const result = await run(input, config) - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` html, body { --tw-text-opacity: 1; @@ -1657,6 +2007,21 @@ crosscheck(() => { } ${defaults} `) + oxide.expect(result.css).toMatchFormattedCss(css` + html, + body { + color: #16a34a; + font-size: 1rem; + } + @media print { + html, + body { + color: #dc2626; + font-size: 2rem; + } + } + ${defaults} + `) }) it('should be possible to use apply in plugins', async () => { @@ -1975,7 +2340,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .foo:hover.bar .baz, .foo:hover.bar > .baz { --tw-bg-opacity: 1; @@ -1983,6 +2348,13 @@ crosscheck(() => { color: red; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .foo:hover.bar .baz, + .foo:hover.bar > .baz { + color: red; + background-color: #000; + } + `) }) }) }) diff --git a/tests/arbitrary-values.oxide.test.css b/tests/arbitrary-values.oxide.test.css index acd68ee3386a..c8dfb24a7007 100644 --- a/tests/arbitrary-values.oxide.test.css +++ b/tests/arbitrary-values.oxide.test.css @@ -137,13 +137,13 @@ min-height: var(--height); } .w-\[\'\)\(\)\'\] { - width: ')()'; + width: ")()"; } .w-\[\'\]\[\]\'\] { - width: '][]'; + width: "][]"; } .w-\[\'\}\{\}\'\] { - width: '}{}'; + width: "}{}"; } .w-\[\(\(\)\)\] { width: (()); @@ -348,10 +348,10 @@ cursor: pointer; } .cursor-\[url\(\'\.\/path_to_hand\.cur\'\)_2_2\,pointer\] { - cursor: url('./path_to_hand.cur') 2 2, pointer; + cursor: url("./path_to_hand.cur") 2 2, pointer; } .cursor-\[url\(hand\.cur\)_2_2\,pointer\] { - cursor: url('hand.cur') 2 2, pointer; + cursor: url("hand.cur") 2 2, pointer; } .cursor-\[var\(--value\)\] { cursor: var(--value); @@ -409,7 +409,7 @@ scroll-padding-top: var(--scroll-padding); } .list-\[\'\\1f44d\'\] { - list-style-type: '👍'; + list-style-type: "👍"; } .list-\[var\(--value\)\] { list-style-type: var(--value); @@ -494,18 +494,11 @@ border-bottom-width: calc(calc(20% - 1cm) * var(--tw-divide-y-reverse)); } .divide-\[black\] > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 1; - border-color: rgb(0 0 0 / var(--tw-divide-opacity)); + border-color: #000; } .divide-\[var\(--value\)\] > :not([hidden]) ~ :not([hidden]) { border-color: var(--value); } -.divide-opacity-\[0\.8\] > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 0.8; -} -.divide-opacity-\[var\(--value\)\] > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: var(--value); -} .rounded-\[11px\] { border-radius: 11px; } @@ -568,8 +561,7 @@ border-top-width: var(--value); } .border-\[\#f00\] { - --tw-border-opacity: 1; - border-color: rgb(255 0 0 / var(--tw-border-opacity)); + border-color: red; } .border-\[color\:var\(--value\)\] { border-color: var(--value); @@ -578,75 +570,60 @@ border-color: red #000; } .border-b-\[\#f00\] { - --tw-border-opacity: 1; - border-bottom-color: rgb(255 0 0 / var(--tw-border-opacity)); + border-bottom-color: red; } .border-b-\[color\:var\(--value\)\] { border-bottom-color: var(--value); } .border-l-\[\#f00\] { - --tw-border-opacity: 1; - border-left-color: rgb(255 0 0 / var(--tw-border-opacity)); + border-left-color: red; } .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-right-color: red; } .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-top-color: red; } .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: #00fc; } .bg-\[\#0f0\] { - --tw-bg-opacity: 1; - background-color: rgb(0 255 0 / var(--tw-bg-opacity)); + background-color: #0f0; } .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)); + background-color: red; } .bg-\[color\:var\(--value1\)_var\(--value2\)\] { background-color: var(--value1) var(--value2); } .bg-\[hsl\(0\,100\%\,50\%\)\], .bg-\[hsl\(0rad\,100\%\,50\%\)\] { - --tw-bg-opacity: 1; - background-color: hsl(0 100% 50% / var(--tw-bg-opacity)); + background-color: red; } .bg-\[hsla\(0\,100\%\,50\%\,0\.3\)\], .bg-\[hsla\(0turn\,100\%\,50\%\,0\.3\)\] { background-color: #ff00004d; } .bg-\[rgb\(123\,123\,123\)\] { - --tw-bg-opacity: 1; - background-color: rgb(123 123 123 / var(--tw-bg-opacity)); + background-color: #7b7b7b; } .bg-\[rgb\(123\,_456\,_123\)_black\] { background-color: #7bff7b black; } .bg-\[rgb\(123_456_789\)\] { - --tw-bg-opacity: 1; - background-color: rgb(123 255 255 / var(--tw-bg-opacity)); + background-color: #7bffff; } .bg-\[rgba\(123\,123\,123\,0\.5\)\] { background-color: #7b7b7b80; @@ -657,12 +634,6 @@ .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-\[image\(\)\,var\(--value\)\] { background-image: image(), var(--value); } @@ -679,7 +650,7 @@ background-image: linear-gradient(to left, rgb(var(--green)), blue); } .bg-\[url\(\'\/path-to-image\.png\'\)\] { - background-image: url('/path-to-image.png'); + background-image: url("/path-to-image.png"); } .bg-\[url\:var\(--url\)\] { background-image: var(--url); @@ -727,7 +698,7 @@ fill: #da5b66; } .fill-\[url\(\#icon-gradient\)\] { - fill: url('#icon-gradient'); + fill: url("#icon-gradient"); } .fill-\[var\(--value\)\] { fill: var(--value); @@ -739,7 +710,7 @@ stroke: var(--value); } .stroke-\[url\(\#icon-gradient\)\] { - stroke: url('#icon-gradient'); + stroke: url("#icon-gradient"); } .stroke-\[20px\] { stroke-width: 20px; @@ -801,7 +772,7 @@ font-family: Some Font, sans-serif; } .font-\[\'Some_Font\'\,var\(--other-font\)\] { - font-family: 'Some Font', var(--other-font); + font-family: "Some Font", var(--other-font); } .font-\[Georgia\,serif\] { font-family: Georgia, serif; @@ -846,8 +817,7 @@ letter-spacing: var(--tracking); } .text-\[black\] { - --tw-text-opacity: 1; - color: rgb(0 0 0 / var(--tw-text-opacity)); + color: #000; } .text-\[color\:var\(--color\)\] { color: var(--color); @@ -855,14 +825,7 @@ .text-\[rgb\(123\,123\,123\)\], .text-\[rgb\(123\,_123\,_123\)\], .text-\[rgb\(123_123_123\)\] { - --tw-text-opacity: 1; - color: rgb(123 123 123 / var(--tw-text-opacity)); -} -.text-opacity-\[0\.8\] { - --tw-text-opacity: 0.8; -} -.text-opacity-\[var\(--value\)\] { - --tw-text-opacity: var(--value); + color: #7b7b7b; } .decoration-\[black\] { text-decoration-color: #000; @@ -884,9 +847,6 @@ .placeholder-\[var\(--placeholder\)\]::placeholder { color: var(--placeholder); } -.placeholder-opacity-\[var\(--placeholder-opacity\)\]::placeholder { - --tw-placeholder-opacity: var(--placeholder-opacity); -} .caret-\[black\] { caret-color: #000; } @@ -947,15 +907,11 @@ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); } .ring-\[\#76ad65\] { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(118 173 101 / var(--tw-ring-opacity)); + --tw-ring-color: #76ad65; } .ring-\[color\:var\(--value\)\] { --tw-ring-color: var(--value); } -.ring-opacity-\[var\(--ring-opacity\)\] { - --tw-ring-opacity: var(--ring-opacity); -} .ring-offset-\[19rem\] { --tw-ring-offset-width: 19rem; } @@ -1091,11 +1047,11 @@ will-change: var(--will-change); } .content-\[\'\>\'\] { - --tw-content: '>'; + --tw-content: ">"; content: var(--tw-content); } .content-\[\'hello\'\] { - --tw-content: 'hello'; + --tw-content: "hello"; content: var(--tw-content); } .content-\[attr\(content-before\)\] { @@ -1107,3 +1063,4 @@ 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 183fcf57c3c9..df7cca3398e8 100644 --- a/tests/arbitrary-values.test.js +++ b/tests/arbitrary-values.test.js @@ -105,7 +105,7 @@ crosscheck(({ stable, oxide }) => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-\[\#ff0000\] { --tw-bg-opacity: 1; background-color: rgb(255 0 0 / var(--tw-bg-opacity)); @@ -133,6 +133,32 @@ crosscheck(({ stable, oxide }) => { background-image: linear-gradient(to right, var(--tw-gradient-stops)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-\[\#ff0000\] { + background-color: red; + } + .bg-\[color\:var\(--bg-color\)\] { + background-color: var(--bg-color); + } + .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 { + background-color: #ef4444; + } + .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)); + } + `) }) }) diff --git a/tests/arbitrary-variants.test.js b/tests/arbitrary-variants.test.js index 8bc02a582783..46da5cdf2027 100644 --- a/tests/arbitrary-variants.test.js +++ b/tests/arbitrary-variants.test.js @@ -540,7 +540,7 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .\[\&_\.foo\]\:tw-text-red-400 .foo, .\[\&_\.foo\]\:hover\:tw-text-red-400:hover .foo, .hover\:\[\&_\.foo\]\:tw-text-red-400 .foo:hover, @@ -549,6 +549,14 @@ crosscheck(({ stable, oxide }) => { color: rgb(248 113 113 / var(--tw-text-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .\[\&_\.foo\]\:tw-text-red-400 .foo, + .\[\&_\.foo\]\:hover\:tw-text-red-400:hover .foo, + .hover\:\[\&_\.foo\]\:tw-text-red-400 .foo:hover, + .foo .\[\.foo_\&\]\:tw-text-red-400 { + color: #f87171; + } + `) }) }) @@ -577,7 +585,7 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .\[\&_\.foo\]\:tw-bg-white .foo { --tw-bg-opacity: 1; background-color: rgb(255 255 255 / var(--tw-bg-opacity)); @@ -595,6 +603,20 @@ crosscheck(({ stable, oxide }) => { color: rgb(248 113 113 / var(--tw-text-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .\[\&_\.foo\]\:tw-bg-white .foo { + background-color: #fff; + } + .\[\&_\.foo\]\:tw-text-red-400 .foo { + color: #f87171; + } + .foo .\[\.foo_\&\]\:tw-bg-white { + background-color: #fff; + } + .foo .\[\.foo_\&\]\:tw-text-red-400 { + color: #f87171; + } + `) }) }) diff --git a/tests/basic-usage.oxide.test.css b/tests/basic-usage.oxide.test.css index de40c07498a0..ac91e67e81f9 100644 --- a/tests/basic-usage.oxide.test.css +++ b/tests/basic-usage.oxide.test.css @@ -514,11 +514,7 @@ border-style: dotted; } .divide-gray-200 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 1; - border-color: rgb(229 231 235 / var(--tw-divide-opacity)); -} -.divide-opacity-50 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 0.5; + border-color: #e5e7eb; } .place-self-center { place-self: center; @@ -579,44 +575,30 @@ border-style: hidden; } .border-black { - --tw-border-opacity: 1; - border-color: rgb(0 0 0 / var(--tw-border-opacity)); + border-color: #000; } .border-x-black { - --tw-border-opacity: 1; - border-left-color: rgb(0 0 0 / var(--tw-border-opacity)); - border-right-color: rgb(0 0 0 / var(--tw-border-opacity)); + border-left-color: #000; + border-right-color: #000; } .border-y-black { - --tw-border-opacity: 1; - border-top-color: rgb(0 0 0 / var(--tw-border-opacity)); - border-bottom-color: rgb(0 0 0 / var(--tw-border-opacity)); + border-top-color: #000; + border-bottom-color: #000; } .border-b-black { - --tw-border-opacity: 1; - border-bottom-color: rgb(0 0 0 / var(--tw-border-opacity)); + border-bottom-color: #000; } .border-l-black { - --tw-border-opacity: 1; - border-left-color: rgb(0 0 0 / var(--tw-border-opacity)); + border-left-color: #000; } .border-r-black { - --tw-border-opacity: 1; - border-right-color: rgb(0 0 0 / var(--tw-border-opacity)); + border-right-color: #000; } .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; + border-top-color: #000; } .bg-green-500 { - --tw-bg-opacity: 1; - background-color: rgb(34 197 94 / var(--tw-bg-opacity)); -} -.bg-opacity-20 { - --tw-bg-opacity: 0.2; + background-color: #22c55e; } .bg-gradient-to-r { background-image: linear-gradient(to right, var(--tw-gradient-stops)); @@ -766,11 +748,7 @@ letter-spacing: -0.025em; } .text-indigo-500 { - --tw-text-opacity: 1; - color: rgb(99 102 241 / var(--tw-text-opacity)); -} -.text-opacity-10 { - --tw-text-opacity: 0.1; + color: #6366f1; } .underline { text-decoration-line: underline; @@ -798,11 +776,7 @@ -moz-osx-font-smoothing: grayscale; } .placeholder-green-300::placeholder { - --tw-placeholder-opacity: 1; - color: rgb(134 239 172 / var(--tw-placeholder-opacity)); -} -.placeholder-opacity-60::placeholder { - --tw-placeholder-opacity: 0.6; + color: #86efac; } .caret-red-600 { caret-color: #dc2626; @@ -893,11 +867,7 @@ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); } .ring-white { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity)); -} -.ring-opacity-40 { - --tw-ring-opacity: 0.4; + --tw-ring-color: #fff; } .ring-offset-2 { --tw-ring-offset-width: 2px; @@ -1049,3 +1019,4 @@ --tw-content: none; content: var(--tw-content); } + diff --git a/tests/basic-usage.test.js b/tests/basic-usage.test.js index 4b39eb68177d..90d480380fce 100644 --- a/tests/basic-usage.test.js +++ b/tests/basic-usage.test.js @@ -245,12 +245,17 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-green-light { --tw-bg-opacity: 1; background-color: rgb(0 128 0 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-green-light { + background-color: green; + } + `) }) }) @@ -293,7 +298,7 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-theme { --tw-bg-opacity: 1; background-color: rgb(255 0 0 / var(--tw-bg-opacity)); @@ -303,6 +308,14 @@ crosscheck(({ stable, oxide }) => { color: rgb(0 128 0 / var(--tw-text-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-theme { + background-color: red; + } + .text-theme { + color: green; + } + `) }) }) @@ -825,7 +838,7 @@ crosscheck(({ stable, oxide }) => { }) }) - it('A bare ring-opacity utility is supported when using respectDefaultRingColorOpacity', () => { + test('A bare ring-opacity utility is supported when using respectDefaultRingColorOpacity', () => { let config = { future: { respectDefaultRingColorOpacity: true }, content: [{ raw: html`
` }], @@ -842,11 +855,13 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .ring-opacity { --tw-ring-opacity: 0.33; } `) + // The opacity plugins are disabled by default in the `oxide` engine + oxide.expect(result.css).toMatchFormattedCss(css``) }) }) @@ -862,7 +877,7 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .ring { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); @@ -876,6 +891,19 @@ crosscheck(({ stable, oxide }) => { --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .ring { + --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(3px + 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); + } + .ring-blue-500 { + --tw-ring-color: #3b82f6; + } + `) }) }) diff --git a/tests/blocklist.test.js b/tests/blocklist.test.js index b9667101cd19..f5627d20c932 100644 --- a/tests/blocklist.test.js +++ b/tests/blocklist.test.js @@ -1,7 +1,7 @@ import log from '../src/util/log' import { crosscheck, run, html, css } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { let warn beforeEach(() => { @@ -30,7 +30,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .font-bold { font-weight: 700; } @@ -67,7 +67,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .font-bold { font-weight: 700; } @@ -83,7 +83,7 @@ crosscheck(() => { let result = await run('@tailwind utilities', config) - expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-\[\#f00d1e\] { --tw-bg-opacity: 1; background-color: rgb(240 13 30 / var(--tw-bg-opacity)); @@ -93,6 +93,15 @@ crosscheck(() => { } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-\[\#f00d1e\] { + background-color: #f00d1e; + } + .font-bold { + font-weight: 700; + } + `) + expect(warn).toHaveBeenCalledTimes(1) expect(warn.mock.calls.map((x) => x[0])).toEqual(['blocklist-invalid']) }) @@ -105,7 +114,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-red-400 { --tw-bg-opacity: 1; background-color: rgb(248 113 113 / var(--tw-bg-opacity)); @@ -114,6 +123,14 @@ crosscheck(() => { font-weight: 700; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-red-400 { + background-color: #f87171; + } + .font-bold { + font-weight: 700; + } + `) }) }) }) diff --git a/tests/collapse-adjacent-rules.test.js b/tests/collapse-adjacent-rules.test.js index 5033d27a35e2..4dbaab769ed4 100644 --- a/tests/collapse-adjacent-rules.test.js +++ b/tests/collapse-adjacent-rules.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css, defaults } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('collapse adjacent rules', () => { let config = { content: [ @@ -71,7 +71,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` @font-face { font-family: Poppins; src: url('/fonts/Poppins.woff2') format('woff2'), @@ -150,6 +150,82 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + @font-face { + font-family: Poppins; + src: url('/fonts/Poppins.woff2') format('woff2'), + url('/fonts/Poppins.woff') format('woff'); + } + @font-face { + font-family: Proxima Nova; + src: url('/fonts/ProximaNova.woff2') format('woff2'), + url('/fonts/ProximaNova.woff') format('woff'); + } + ${defaults} + @font-face { + font-family: Inter; + src: url('/fonts/Inter.woff2') format('woff2'), url('/fonts/Inter.woff') format('woff'); + } + @font-face { + font-family: Gilroy; + src: url('/fonts/Gilroy.woff2') format('woff2'), url('/fonts/Gilroy.woff') format('woff'); + } + @page { + margin: 1cm; + } + .font-bold { + font-weight: 700; + } + .foo, + .bar { + color: #000; + font-weight: 700; + } + @supports (foo: bar) { + .some-apply-thing { + color: #000; + font-weight: 700; + } + } + @media (min-width: 768px) { + .some-apply-thing { + color: #000; + font-weight: 700; + } + } + @supports (foo: bar) { + @media (min-width: 768px) { + .some-apply-thing { + color: #000; + font-weight: 700; + } + } + } + @media (min-width: 640px) { + .sm\:text-center { + text-align: center; + } + .sm\:font-bold { + font-weight: 700; + } + } + @media (min-width: 768px) { + .md\:text-center { + text-align: center; + } + .md\:font-bold { + font-weight: 700; + } + } + @media (min-width: 1024px) { + .lg\:text-center { + text-align: center; + } + .lg\:font-bold { + font-weight: 700; + } + } + `) }) }) diff --git a/tests/color-opacity-modifiers.test.js b/tests/color-opacity-modifiers.test.js index 435511affcbb..e7d285740714 100644 --- a/tests/color-opacity-modifiers.test.js +++ b/tests/color-opacity-modifiers.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('basic color opacity modifier', async () => { let config = { content: [{ raw: html`
` }], @@ -28,12 +28,17 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-red-500\/50 { --tw-bg-opacity: 1; background-color: rgb(255 0 0 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-red-500\/50 { + background-color: red; + } + `) }) }) @@ -205,7 +210,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-\[hsl\(123\,50\%\,var\(--foo\)\)\] { --tw-bg-opacity: 1; background-color: hsl(123 50% var(--foo) / var(--tw-bg-opacity)); @@ -231,6 +236,29 @@ crosscheck(() => { background-color: hsl(var(--foo) var(--bar) var(--baz) / 0.5); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-\[hsl\(123\,50\%\,var\(--foo\)\)\] { + background-color: hsl(123, 50%, var(--foo)); + } + .bg-\[hsl\(123\,50\%\,var\(--foo\)\)\]\/50 { + background-color: hsl(123 50% var(--foo) / 0.5); + } + .bg-\[hsl\(123\,var\(--foo\)\,50\%\)\] { + background-color: hsl(123, var(--foo), 50%); + } + .bg-\[hsl\(123\,var\(--foo\)\,50\%\)\]\/50 { + background-color: hsl(123 var(--foo) 50% / 0.5); + } + .bg-\[hsl\(var\(--foo\)\,50\%\,50\%\)\] { + background-color: hsl(var(--foo), 50%, 50%); + } + .bg-\[hsl\(var\(--foo\)\,50\%\,50\%\)\]\/50 { + background-color: hsl(var(--foo) 50% 50% / 0.5); + } + .bg-\[hsl\(var\(--foo\)\,var\(--bar\)\,var\(--baz\)\)\]\/50 { + background-color: hsl(var(--foo) var(--bar) var(--baz) / 0.5); + } + `) }) }) }) diff --git a/tests/import-syntax.test.js b/tests/import-syntax.test.js index c10d8b1427a8..992ef81d5f51 100644 --- a/tests/import-syntax.test.js +++ b/tests/import-syntax.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css, defaults } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('using @import instead of @tailwind', () => { let config = { content: [ @@ -33,7 +33,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` h1 { font-size: 32px; } @@ -79,6 +79,51 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + h1 { + font-size: 32px; + } + ${defaults} + .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; + } + } + .mt-6 { + margin-top: 1.5rem; + } + .bg-black { + background-color: #000; + } + @media (min-width: 768px) { + .md\:hover\:text-center:hover { + text-align: center; + } + } + `) }) }) }) diff --git a/tests/kitchen-sink.test.js b/tests/kitchen-sink.test.js index a750ff6566d7..d6d74225d293 100644 --- a/tests/kitchen-sink.test.js +++ b/tests/kitchen-sink.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css, defaults } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('it works', () => { let config = { darkMode: 'class', @@ -234,7 +234,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .theme-test { color: #3b82f6; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, @@ -783,6 +783,541 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .theme-test { + color: #3b82f6; + 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; + } + @media (min-width: 1024px) { + .screen-test { + color: purple; + } + } + .apply-1, + .apply-2 { + margin-top: 1.5rem; + } + .apply-test { + background-color: #ec4899; + margin-top: 1.5rem; + } + .apply-test:hover, + .apply-test:hover:focus { + font-weight: 700; + } + @media (min-width: 640px) { + .apply-test { + background-color: #22c55e; + } + .apply-test:nth-child(2n):focus { + background-color: #fbcfe8; + } + } + .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, + .group:hover .apply-group, + .dark .apply-dark-mode { + font-weight: 700; + } + .apply-with-existing:hover { + font-weight: 400; + } + @media (min-width: 640px) { + .apply-with-existing:hover { + background-color: #22c55e; + } + } + .multiple, + .selectors { + font-weight: 700; + } + .group:hover .multiple, + .group:hover .selectors { + font-weight: 400; + } + .list > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); + } + .nested .example { + font-weight: 700; + } + .nested .example:hover { + font-weight: 400; + } + .apply-order-a, + .apply-order-b { + margin: 1.5rem 1.25rem 1.25rem; + } + .dark .group:hover .apply-dark-group-example-a { + background-color: #22c55e; + } + @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: 0; + } + div { + background: #654321; + } + ${defaults} + .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; + } + .inset-6 { + inset: 1.5rem; + } + .inset-x-1 { + left: 0.25rem; + right: 0.25rem; + } + .end-8 { + inset-inline-end: 2rem; + } + .start-4 { + inset-inline-start: 1rem; + } + .mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; + } + .me-8 { + margin-inline-end: 2rem; + } + .ms-4 { + margin-inline-start: 1rem; + } + .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\,repeat\(auto-fill\,minmax\(15\%\,100px\)\)\,300px\] { + grid-template-columns: 200px repeat(auto-fill, minmax(15%, 100px)) 300px; + } + .rounded-e { + border-start-end-radius: 0.25rem; + border-end-end-radius: 0.25rem; + } + .rounded-s { + border-start-start-radius: 0.25rem; + border-end-start-radius: 0.25rem; + } + .rounded-es { + border-end-start-radius: 0.25rem; + } + .rounded-ss { + border-start-start-radius: 0.25rem; + } + .border-2 { + border-width: 2px; + } + .border-e-4 { + border-inline-end-width: 4px; + } + .border-s-0 { + border-inline-start-width: 0; + } + .border-black { + border-color: #000; + } + .border-e-red-400 { + border-inline-end-color: #f87171; + } + .border-s-green-500 { + border-inline-start-color: #22c55e; + } + .bg-black { + background-color: #000; + } + .bg-green-500 { + background-color: #22c55e; + } + .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: #bada5500; + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + } + .px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; + } + .pe-8 { + padding-inline-end: 2rem; + } + .ps-4 { + padding-inline-start: 1rem; + } + .pt-6 { + padding-top: 1.5rem; + } + .text-center { + text-align: center; + } + .font-medium { + font-weight: 500; + } + .shadow-md { + --tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a; + --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 #0000000d; + --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; + } + .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; + } + } + @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; + } + } + } + @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; + } + } + } + .first\:pt-0:first-child { + padding-top: 0; + } + .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 #0000001a, 0 4px 6px -4px #0000001a; + --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-color: #3b82f6; + } + .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, + .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-duration: 0.15s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + .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-duration: 0.15s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + } + .dark .dark\:custom-util { + background: #abcdef; + } + @media (min-width: 640px) { + .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\:text-center { + text-align: center; + } + .md\:opacity-50 { + opacity: 0.5; + } + .md\:shadow-sm { + --tw-shadow: 0 1px 2px 0 #0000000d; + --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: #3b82f64d; + } + .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-duration: 0.15s; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } + .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/match-variants.test.js b/tests/match-variants.test.js index 8b1f95429048..e4330f7a92cc 100644 --- a/tests/match-variants.test.js +++ b/tests/match-variants.test.js @@ -3,7 +3,7 @@ import { createContext } from '../src/lib/setupContextUtils' import { crosscheck, run, html, css } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('partial arbitrary variants', () => { let config = { content: [ @@ -24,7 +24,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .potato-baked .potato-\[baked\]\:w-3 { width: 0.75rem; } @@ -33,6 +33,14 @@ crosscheck(() => { background-color: rgb(254 240 138 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .potato-baked .potato-\[baked\]\:w-3 { + width: 0.75rem; + } + .potato-yellow .potato-\[yellow\]\:bg-yellow-200 { + background-color: #fef08a; + } + `) }) }) @@ -56,7 +64,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` @media (potato: baked) { .potato-\[baked\]\:w-3 { width: 0.75rem; @@ -69,6 +77,18 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + @media (potato: baked) { + .potato-\[baked\]\:w-3 { + width: 0.75rem; + } + } + @media (potato: yellow) { + .potato-\[yellow\]\:bg-yellow-200 { + background-color: #fef08a; + } + } + `) }) }) @@ -92,7 +112,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` @media (potato: baked) { .potato-\[baked\]\:w-3:potato { width: 0.75rem; @@ -105,6 +125,18 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + @media (potato: baked) { + .potato-\[baked\]\:w-3:potato { + width: 0.75rem; + } + } + @media (potato: yellow) { + .potato-\[yellow\]\:bg-yellow-200:potato { + background-color: #fef08a; + } + } + `) }) }) diff --git a/tests/opacity.test.js b/tests/opacity.test.js index c435676dd5ae..82b437ce8b0d 100644 --- a/tests/opacity.test.js +++ b/tests/opacity.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('opacity', () => { let config = { darkMode: 'class', @@ -25,7 +25,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .divide-black > :not([hidden]) ~ :not([hidden]), .border-black { border-color: #000; @@ -73,7 +73,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .divide-primary > :not([hidden]) ~ :not([hidden]), .border-primary { border-color: rgb(var(--color-primary)); @@ -117,7 +117,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .divide-primary > :not([hidden]) ~ :not([hidden]) { --tw-divide-opacity: 1; border-color: rgb(var(--color-primary) / var(--tw-divide-opacity)); @@ -161,6 +161,22 @@ crosscheck(() => { --tw-ring-opacity: 0.5; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .divide-primary > :not([hidden]) ~ :not([hidden]), + .border-primary { + border-color: rgb(var(--color-primary) / 1); + } + .bg-primary { + background-color: rgb(var(--color-primary) / 1); + } + .text-primary, + .placeholder-primary::placeholder { + color: rgb(var(--color-primary) / 1); + } + .ring-primary { + --tw-ring-color: rgb(var(--color-primary) / 1); + } + `) }) }) @@ -269,7 +285,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .divide-primary > :not([hidden]) ~ :not([hidden]) { --tw-divide-opacity: 1; border-color: hsl(var(--color-primary) / var(--tw-divide-opacity)); @@ -313,6 +329,22 @@ crosscheck(() => { --tw-ring-opacity: 0.5; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .divide-primary > :not([hidden]) ~ :not([hidden]), + .border-primary { + border-color: hsl(var(--color-primary) / 1); + } + .bg-primary { + background-color: hsl(var(--color-primary) / 1); + } + .text-primary, + .placeholder-primary::placeholder { + color: hsl(var(--color-primary) / 1); + } + .ring-primary { + --tw-ring-color: hsl(var(--color-primary) / 1); + } + `) }) }) @@ -352,7 +384,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .divide-primary > :not([hidden]) ~ :not([hidden]) { border-color: hsl(var(--color-primary) / 1); } @@ -416,7 +448,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -444,7 +476,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -472,7 +504,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -500,7 +532,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -528,7 +560,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -556,7 +588,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -588,7 +620,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -620,7 +652,7 @@ crosscheck(() => { }, }, }).then((result) => { - expect(result.css).toMatchCss(output) + expect(result.css).toMatchFormattedCss(output) expect(result.warnings().length).toBe(0) }) }) @@ -641,7 +673,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .bg-primary { --tw-bg-opacity: 1; background-color: rgb(var(--color-primary) / var(--tw-bg-opacity)); @@ -666,7 +698,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .bg-primary\/50 { background-color: rgb(var(--color-primary) / 0.5); } @@ -690,7 +722,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .bg-primary { background-color: rgb(var(--color-primary) / 1); } @@ -714,7 +746,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .bg-\[rgb\(var\(--color-primary\)\/\\)\]\/50 { background-color: rgb(var(--color-primary) / 0.5); } @@ -743,7 +775,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-foo1 { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); @@ -752,6 +784,14 @@ crosscheck(() => { background-color: #00000080; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-foo1 { + background-color: #000; + } + .bg-foo2 { + background-color: #00000080; + } + `) }) }) @@ -791,7 +831,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-foo10 { background-color: #ff6400; } @@ -819,6 +859,32 @@ crosscheck(() => { background-color: #ff640080; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-foo10 { + background-color: #ff6400; + } + .bg-foo11 { + background-color: #ff640080; + } + .bg-foo20 { + background-color: #ff6400; + } + .bg-foo21 { + background-color: #ff640080; + } + .bg-foo30 { + background-color: #ff6400; + } + .bg-foo31 { + background-color: #ff640080; + } + .bg-foo40 { + background-color: #ff6400; + } + .bg-foo41 { + background-color: #ff640080; + } + `) }) }) @@ -848,7 +914,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .divide-blue-300 > :not([hidden]) ~ :not([hidden]) { border-color: #93c5fd; } @@ -941,7 +1007,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .divide-blue-300 > :not([hidden]) ~ :not([hidden]) { --tw-divide-opacity: 1; border-color: rgb(147 197 253 / var(--tw-divide-opacity)); @@ -1037,7 +1103,7 @@ crosscheck(() => { let result = await run('@tailwind utilities', config) - expect(result.css).toMatchCss(css` + expect(result.css).toMatchFormattedCss(css` .text-primary-hsla\/50 { color: hsla(var(--color), 0.5); } diff --git a/tests/plugins/gradientColorStops.test.js b/tests/plugins/gradientColorStops.test.js index cf9fbd6e4cbb..6a26e2e33901 100644 --- a/tests/plugins/gradientColorStops.test.js +++ b/tests/plugins/gradientColorStops.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css } from '../util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('opacity variables are given to colors defined as closures', () => { let config = { content: [ @@ -32,7 +32,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .from-primary { --tw-gradient-from: #1f1f1f; --tw-gradient-to: #1f1f1f00; @@ -69,6 +69,38 @@ crosscheck(() => { --tw-text-opacity: 0.5; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .from-primary { + --tw-gradient-from: #1f1f1f; + --tw-gradient-to: #1f1f1f00; + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + } + .from-secondary { + --tw-gradient-from: #bf5540; + --tw-gradient-to: #bf554000; + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); + } + .via-primary { + --tw-gradient-to: #1f1f1f00; + --tw-gradient-stops: var(--tw-gradient-from), #1f1f1f, var(--tw-gradient-to); + } + .via-secondary { + --tw-gradient-to: #bf554000; + --tw-gradient-stops: var(--tw-gradient-from), #bf5540, var(--tw-gradient-to); + } + .to-primary { + --tw-gradient-to: #1f1f1f; + } + .to-secondary { + --tw-gradient-to: #bf5540; + } + .text-primary { + color: #1f1f1f; + } + .text-secondary { + color: #bf5540; + } + `) }) }) }) diff --git a/tests/prefers-contrast.test.js b/tests/prefers-contrast.test.js index 1d658437ee9b..e3b940da858c 100644 --- a/tests/prefers-contrast.test.js +++ b/tests/prefers-contrast.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, html, css, defaults } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { it('should be possible to use contrast-more and contrast-less variants', () => { let config = { content: [ @@ -18,7 +18,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` ${defaults} .bg-white { --tw-bg-opacity: 1; @@ -37,6 +37,22 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + ${defaults} + .bg-white { + background-color: #fff; + } + @media (prefers-contrast: more) { + .contrast-more\:bg-pink-500 { + background-color: #ec4899; + } + } + @media (prefers-contrast: less) { + .contrast-less\:bg-black { + background-color: #000; + } + } + `) }) }) @@ -53,7 +69,7 @@ crosscheck(() => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` ${defaults} @media (prefers-contrast: more) { .contrast-more\:bg-black { @@ -68,6 +84,19 @@ crosscheck(() => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + ${defaults} + @media (prefers-contrast: more) { + .contrast-more\:bg-black { + background-color: #000; + } + } + @media (prefers-color-scheme: dark) { + .dark\:bg-white { + background-color: #fff; + } + } + `) }) }) }) diff --git a/tests/raw-content.oxide.test.css b/tests/raw-content.oxide.test.css index 6f59c98b4f4f..f50f95e878cb 100644 --- a/tests/raw-content.oxide.test.css +++ b/tests/raw-content.oxide.test.css @@ -367,11 +367,7 @@ border-style: dotted; } .divide-gray-200 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 1; - border-color: rgb(229 231 235 / var(--tw-divide-opacity)); -} -.divide-opacity-50 > :not([hidden]) ~ :not([hidden]) { - --tw-divide-opacity: 0.5; + border-color: #e5e7eb; } .place-self-center { place-self: center; @@ -418,18 +414,10 @@ border-style: solid; } .border-black { - --tw-border-opacity: 1; - border-color: rgb(0 0 0 / var(--tw-border-opacity)); -} -.border-opacity-10 { - --tw-border-opacity: 0.1; + border-color: #000; } .bg-green-500 { - --tw-bg-opacity: 1; - background-color: rgb(34 197 94 / var(--tw-bg-opacity)); -} -.bg-opacity-20 { - --tw-bg-opacity: 0.2; + background-color: #22c55e; } .bg-gradient-to-r { background-image: linear-gradient(to right, var(--tw-gradient-stops)); @@ -565,11 +553,7 @@ letter-spacing: -0.025em; } .text-indigo-500 { - --tw-text-opacity: 1; - color: rgb(99 102 241 / var(--tw-text-opacity)); -} -.text-opacity-10 { - --tw-text-opacity: 0.1; + color: #6366f1; } .underline { text-decoration-line: underline; @@ -579,11 +563,7 @@ -moz-osx-font-smoothing: grayscale; } .placeholder-green-300::placeholder { - --tw-placeholder-opacity: 1; - color: rgb(134 239 172 / var(--tw-placeholder-opacity)); -} -.placeholder-opacity-60::placeholder { - --tw-placeholder-opacity: 0.6; + color: #86efac; } .opacity-90 { opacity: 0.9; @@ -634,11 +614,7 @@ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); } .ring-white { - --tw-ring-opacity: 1; - --tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity)); -} -.ring-opacity-40 { - --tw-ring-opacity: 0.4; + --tw-ring-color: #fff; } .ring-offset-2 { --tw-ring-offset-width: 2px; diff --git a/tests/safelist.test.js b/tests/safelist.test.js index 07e9fe4061b0..cbbd1e245821 100644 --- a/tests/safelist.test.js +++ b/tests/safelist.test.js @@ -1,13 +1,13 @@ import { crosscheck, run, html, css } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { it('should not safelist anything', () => { let config = { content: [{ raw: html`
` }], } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .uppercase { text-transform: uppercase; } @@ -22,7 +22,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .mt-\[20px\] { margin-top: 20px; } @@ -40,6 +40,23 @@ crosscheck(() => { text-decoration-line: underline; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .mt-\[20px\] { + margin-top: 20px; + } + .font-bold { + font-weight: 700; + } + .uppercase { + text-transform: uppercase; + } + .text-gray-200 { + color: #e5e7eb; + } + .hover\:underline:hover { + text-decoration-line: underline; + } + `) }) }) @@ -55,7 +72,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-red-100 { --tw-bg-opacity: 1; background-color: rgb(254 226 226 / var(--tw-bg-opacity)); @@ -76,6 +93,23 @@ crosscheck(() => { background-color: rgb(254 202 202 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-red-100 { + background-color: #fee2e2; + } + .bg-red-200 { + background-color: #fecaca; + } + .uppercase { + text-transform: uppercase; + } + .hover\:bg-red-100:hover { + background-color: #fee2e2; + } + .hover\:bg-red-200:hover { + background-color: #fecaca; + } + `) }) }) @@ -100,7 +134,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-red-100 { --tw-bg-opacity: 1; background-color: rgb(254 226 226 / var(--tw-bg-opacity)); @@ -121,6 +155,23 @@ crosscheck(() => { background-color: rgb(254 202 202 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-red-100 { + background-color: #fee2e2; + } + .bg-red-200 { + background-color: #fecaca; + } + .uppercase { + text-transform: uppercase; + } + .hover\:bg-red-100:hover { + background-color: #fee2e2; + } + .hover\:bg-red-200:hover { + background-color: #fecaca; + } + `) }) }) @@ -136,7 +187,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .tw-bg-red-100 { --tw-bg-opacity: 1; background-color: rgb(254 226 226 / var(--tw-bg-opacity)); @@ -149,6 +200,17 @@ crosscheck(() => { text-transform: uppercase; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .tw-bg-red-100 { + background-color: #fee2e2; + } + .tw-bg-red-200 { + background-color: #fecaca; + } + .tw-uppercase { + text-transform: uppercase; + } + `) }) }) @@ -159,7 +221,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .uppercase { text-transform: uppercase; } @@ -174,7 +236,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .uppercase { text-transform: uppercase; } @@ -194,7 +256,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-red-100 { --tw-bg-opacity: 1; background-color: rgb(254 226 226 / var(--tw-bg-opacity)); @@ -207,6 +269,17 @@ crosscheck(() => { text-transform: uppercase; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .bg-red-100 { + background-color: #fee2e2; + } + .bg-red-200 { + background-color: #fecaca; + } + .uppercase { + text-transform: uppercase; + } + `) }) }) @@ -222,7 +295,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .-top-1 { top: -0.25rem; } @@ -252,7 +325,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .bg-red-400 { --tw-bg-opacity: 1; background-color: rgb(248 113 113 / var(--tw-bg-opacity)); @@ -325,7 +398,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .\!grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; } @@ -350,7 +423,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + return expect(result.css).toMatchFormattedCss(css` .\!tw-grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; } @@ -379,7 +452,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .\!bg-gray-500 { --tw-bg-opacity: 1 !important; background-color: rgb(107 114 128 / var(--tw-bg-opacity)) !important; @@ -416,6 +489,35 @@ crosscheck(() => { background-color: rgb(31 41 55 / var(--tw-bg-opacity)) !important; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .\!bg-gray-500 { + background-color: #6b7280 !important; + } + .\!bg-gray-600 { + background-color: #4b5563 !important; + } + .\!bg-gray-700 { + background-color: #374151 !important; + } + .\!bg-gray-800 { + background-color: #1f2937 !important; + } + .uppercase { + text-transform: uppercase; + } + .hover\:\!bg-gray-500:hover { + background-color: #6b7280 !important; + } + .hover\:\!bg-gray-600:hover { + background-color: #4b5563 !important; + } + .hover\:\!bg-gray-700:hover { + background-color: #374151 !important; + } + .hover\:\!bg-gray-800:hover { + background-color: #1f2937 !important; + } + `) }) }) @@ -435,7 +537,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .\!bg-gray-200 { --tw-bg-opacity: 1 !important; background-color: rgb(229 231 235 / var(--tw-bg-opacity)) !important; @@ -488,6 +590,47 @@ crosscheck(() => { color: rgb(17 24 39 / var(--tw-text-opacity)) !important; } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .\!bg-gray-200 { + background-color: #e5e7eb !important; + } + .\!bg-gray-300 { + background-color: #d1d5db !important; + } + .\!bg-gray-400 { + background-color: #9ca3af !important; + } + .uppercase { + text-transform: uppercase; + } + .\!text-gray-700 { + color: #374151 !important; + } + .\!text-gray-800 { + color: #1f2937 !important; + } + .\!text-gray-900 { + color: #111827 !important; + } + .hover\:\!bg-gray-200:hover { + background-color: #e5e7eb !important; + } + .hover\:\!bg-gray-300:hover { + background-color: #d1d5db !important; + } + .hover\:\!bg-gray-400:hover { + background-color: #9ca3af !important; + } + .hover\:\!text-gray-700:hover { + color: #374151 !important; + } + .hover\:\!text-gray-800:hover { + color: #1f2937 !important; + } + .hover\:\!text-gray-900:hover { + color: #111827 !important; + } + `) }) }) }) diff --git a/tests/syntax-lit-html.test.js b/tests/syntax-lit-html.test.js index 3e00ebf5469e..952a9b969cdc 100644 --- a/tests/syntax-lit-html.test.js +++ b/tests/syntax-lit-html.test.js @@ -1,6 +1,6 @@ import { crosscheck, run, css } from './util/run' -crosscheck(() => { +crosscheck(({ stable, oxide }) => { test('it detects classes in lit-html templates', () => { let config = { content: [ @@ -14,7 +14,7 @@ crosscheck(() => { } return run('@tailwind utilities', config).then((result) => { - expect(result.css).toMatchCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .rounded { border-radius: 0.25rem; } @@ -42,6 +42,31 @@ crosscheck(() => { background-color: rgb(37 99 235 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .rounded { + border-radius: 0.25rem; + } + .bg-blue-400 { + background-color: #60a5fa; + } + .px-4 { + padding-left: 1rem; + padding-right: 1rem; + } + .py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + } + .font-bold { + font-weight: 700; + } + .text-white { + color: #fff; + } + .hover\:bg-blue-600:hover { + background-color: #2563eb; + } + `) }) }) }) diff --git a/tests/variants.oxide.test.css b/tests/variants.oxide.test.css index a00e42f2f0bf..db3a5283f1a1 100644 --- a/tests/variants.oxide.test.css +++ b/tests/variants.oxide.test.css @@ -52,12 +52,10 @@ line-height: 2rem; } .first-letter\:text-red-500:first-letter { - --tw-text-opacity: 1; - color: rgb(239 68 68 / var(--tw-text-opacity)); + color: #ef4444; } .first-line\:bg-yellow-300:first-line { - --tw-bg-opacity: 1; - background-color: rgb(253 224 71 / var(--tw-bg-opacity)); + background-color: #fde047; } .first-line\:underline:first-line { text-decoration-line: underline; @@ -77,35 +75,28 @@ color: #ef4444; } .selection\:bg-blue-500 ::selection { - --tw-bg-opacity: 1; - background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + background-color: #3b82f6; } .selection\:text-white ::selection { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); + color: #fff; } .selection\:bg-blue-500::selection { - --tw-bg-opacity: 1; - background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + background-color: #3b82f6; } .selection\:text-white::selection { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); + color: #fff; } .file\:bg-blue-500::file-selector-button { - --tw-bg-opacity: 1; - background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + background-color: #3b82f6; } .file\:text-white::file-selector-button { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); + color: #fff; } .placeholder\:font-bold::placeholder { font-weight: 700; } .placeholder\:text-red-500::placeholder { - --tw-text-opacity: 1; - color: rgb(239 68 68 / var(--tw-text-opacity)); + color: #ef4444; } .backdrop\:shadow-md::backdrop { --tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a; @@ -119,8 +110,7 @@ } .before\:bg-red-500:before { content: var(--tw-content); - --tw-bg-opacity: 1; - background-color: rgb(239 68 68 / var(--tw-bg-opacity)); + background-color: #ef4444; } .after\:flex:after { content: var(--tw-content); @@ -146,8 +136,7 @@ var(--tw-shadow); } .open\:bg-red-200[open] { - --tw-bg-opacity: 1; - background-color: rgb(254 202 202 / var(--tw-bg-opacity)); + background-color: #fecaca; } .default\:shadow-md:default, .checked\:shadow-md:checked, @@ -183,12 +172,10 @@ var(--tw-shadow); } .file\:hover\:bg-blue-600:hover::file-selector-button { - --tw-bg-opacity: 1; - background-color: rgb(37 99 235 / var(--tw-bg-opacity)); + background-color: #2563eb; } .open\:hover\:bg-red-200:hover[open] { - --tw-bg-opacity: 1; - background-color: rgb(254 202 202 / var(--tw-bg-opacity)); + background-color: #fecaca; } .focus\:shadow-md:focus, .focus\:hover\:shadow-md:hover:focus, @@ -212,8 +199,7 @@ var(--tw-shadow); } .group[open] .group-open\:bg-red-200 { - --tw-bg-opacity: 1; - background-color: rgb(254 202 202 / var(--tw-bg-opacity)); + background-color: #fecaca; } .group:default .group-default\:shadow-md, .group:checked .group-checked\:shadow-md, @@ -247,8 +233,7 @@ var(--tw-shadow); } .group[open]:focus .group-open\:group-focus\:bg-red-200 { - --tw-bg-opacity: 1; - background-color: rgb(254 202 202 / var(--tw-bg-opacity)); + background-color: #fecaca; } .group:focus:hover .group-focus\:group-hover\:shadow-md, .group:focus-visible .group-focus-visible\:shadow-md, @@ -273,8 +258,7 @@ var(--tw-shadow); } .peer[open] ~ .peer-open\:bg-red-200 { - --tw-bg-opacity: 1; - background-color: rgb(254 202 202 / var(--tw-bg-opacity)); + background-color: #fecaca; } .peer:default ~ .peer-default\:shadow-md, .peer:checked ~ .peer-checked\:shadow-md, @@ -299,8 +283,8 @@ .peer:disabled ~ .peer-disabled\:shadow-md, .peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:shadow-md, .peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:first\:shadow-md:first-child, -[dir='ltr'] .ltr\:shadow-md, -[dir='rtl'] .rtl\:shadow-md { +[dir="ltr"] .ltr\:shadow-md, +[dir="rtl"] .rtl\:shadow-md { --tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a; --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), @@ -326,14 +310,12 @@ } @media (prefers-contrast: more) { .contrast-more\:bg-yellow-300 { - --tw-bg-opacity: 1; - background-color: rgb(253 224 71 / var(--tw-bg-opacity)); + background-color: #fde047; } } @media (prefers-contrast: less) { .contrast-less\:bg-yellow-300 { - --tw-bg-opacity: 1; - background-color: rgb(253 224 71 / var(--tw-bg-opacity)); + background-color: #fde047; } } .dark .dark\:shadow-md, @@ -346,8 +328,7 @@ } @media print { .print\:bg-yellow-300 { - --tw-bg-opacity: 1; - background-color: rgb(253 224 71 / var(--tw-bg-opacity)); + background-color: #fde047; } } @media (min-width: 640px) { @@ -418,13 +399,12 @@ } @media (orientation: portrait) { .portrait\:bg-yellow-300 { - --tw-bg-opacity: 1; - background-color: rgb(253 224 71 / var(--tw-bg-opacity)); + background-color: #fde047; } } @media (orientation: landscape) { .landscape\:bg-yellow-300 { - --tw-bg-opacity: 1; - background-color: rgb(253 224 71 / var(--tw-bg-opacity)); + background-color: #fde047; } } + diff --git a/tests/variants.test.js b/tests/variants.test.js index f37897d804f3..a762745f082f 100644 --- a/tests/variants.test.js +++ b/tests/variants.test.js @@ -44,7 +44,7 @@ crosscheck(({ stable, oxide }) => { } return run('@tailwind utilities', config).then((result) => { - return expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` .file\:hover\:bg-pink-600:hover::file-selector-button { --tw-bg-opacity: 1; background-color: rgb(219 39 119 / var(--tw-bg-opacity)); @@ -54,6 +54,14 @@ crosscheck(({ stable, oxide }) => { background-color: rgb(219 39 119 / var(--tw-bg-opacity)); } `) + oxide.expect(result.css).toMatchFormattedCss(css` + .file\:hover\:bg-pink-600:hover::file-selector-button { + background-color: #db2777; + } + .hover\:file\:bg-pink-600::file-selector-button:hover { + background-color: #db2777; + } + `) }) }) @@ -254,15 +262,18 @@ crosscheck(({ stable, oxide }) => { @tailwind utilities; ` - let expected = css` + let result = await run(input, config) + stable.expect(result.css).toIncludeCss(css` .peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:border-blue-500 { --tw-border-opacity: 1; border-color: rgb(59 130 246 / var(--tw-border-opacity)); } - ` - - let result = await run(input, config) - expect(result.css).toIncludeCss(expected) + `) + oxide.expect(result.css).toIncludeCss(css` + .peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:border-blue-500 { + border-color: #3b82f6; + } + `) }) it('should properly handle keyframes with multiple variants', async () => { @@ -1007,7 +1018,7 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` @media (min-aspect-ratio: 1 / 10) { .ar-1\/10\:text-red-500 { --tw-text-opacity: 1; @@ -1015,6 +1026,13 @@ crosscheck(({ stable, oxide }) => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + @media (min-aspect-ratio: 1 / 10) { + .ar-1\/10\:text-red-500 { + color: #ef4444; + } + } + `) }) }) @@ -1044,7 +1062,7 @@ crosscheck(({ stable, oxide }) => { ` return run(input, config).then((result) => { - expect(result.css).toMatchFormattedCss(css` + stable.expect(result.css).toMatchFormattedCss(css` @media (min-aspect-ratio: 1 / 10) and (foo: 20) { .ar-1\/10\/20\:text-red-500 { --tw-text-opacity: 1; @@ -1052,6 +1070,13 @@ crosscheck(({ stable, oxide }) => { } } `) + oxide.expect(result.css).toMatchFormattedCss(css` + @media (min-aspect-ratio: 1 / 10) and (foo: 20) { + .ar-1\/10\/20\:text-red-500 { + color: #ef4444; + } + } + `) }) })