mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
* WIP * WIP * Finish combining JIT and AOT plugins Still lots of clean up that can be done in some of the more complex ones, but at least it's one file per plugin now. * Remove unused import * Fix AOT generation bugs * Move corePlugins/index.js to corePlugins.js * Convert JIT files to ESM * Move tests * Reorder core plugins to match JIT order * Update AOT apply tests * Unify utils * Combine plugin lists to one single source of truth * Finish resolving merge conflicts, fix tests Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
359 lines
7.3 KiB
JavaScript
359 lines
7.3 KiB
JavaScript
import postcss from 'postcss'
|
|
import tailwind from '../src/index'
|
|
import createPlugin from '../src/util/createPlugin'
|
|
|
|
function run(input, config = {}) {
|
|
return postcss([tailwind(config)]).process(input, { from: undefined })
|
|
}
|
|
|
|
test('user-defined dark mode variants do not stack', () => {
|
|
const input = `
|
|
@variants dark, hover {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
.custom-dark .custom-dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
`
|
|
|
|
const userPlugin = createPlugin(function ({ addVariant }) {
|
|
addVariant('dark', function ({ modifySelectors }) {
|
|
modifySelectors(function ({ className }) {
|
|
return `.custom-dark .custom-dark\\:${className}`
|
|
})
|
|
})
|
|
})
|
|
|
|
expect.assertions(2)
|
|
|
|
return postcss([tailwind({ plugins: [userPlugin] })])
|
|
.process(input, { from: undefined })
|
|
.then((result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
})
|
|
})
|
|
|
|
test('dark mode variants can be generated using the class strategy', () => {
|
|
const input = `
|
|
@variants dark {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
.dark\\:text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input, { darkMode: 'media' }).then((result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
})
|
|
})
|
|
|
|
test('dark mode variants can be generated even when the user has their own plugins array', () => {
|
|
const input = `
|
|
@variants dark {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
.dark\\:text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input, { darkMode: 'media', plugins: [] }).then((result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
})
|
|
})
|
|
|
|
test('dark mode variants can be generated using the class strategy', () => {
|
|
const input = `
|
|
@variants dark {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
.dark .dark\\:text-red {
|
|
color: red;
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input, { darkMode: 'class' }).then((result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
})
|
|
})
|
|
|
|
test('dark mode variants can be disabled', () => {
|
|
const input = `
|
|
@variants dark {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input, { dark: false }).then((result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
})
|
|
})
|
|
|
|
test('dark mode variants are disabled by default', () => {
|
|
const input = `
|
|
@variants dark {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input).then((result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
})
|
|
})
|
|
|
|
test('dark mode variants stack with other variants', () => {
|
|
const input = `
|
|
@variants responsive, dark, hover, focus {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
.hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
.dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.dark\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
}
|
|
@media (min-width: 500px) {
|
|
.sm\\:text-red {
|
|
color: red;
|
|
}
|
|
.sm\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.sm\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
.sm\\:dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.sm\\:dark\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.sm\\:dark\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
}
|
|
}
|
|
@media (min-width: 800px) {
|
|
.lg\\:text-red {
|
|
color: red;
|
|
}
|
|
.lg\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.lg\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
.lg\\:dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.lg\\:dark\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.lg\\:dark\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input, { darkMode: 'media', theme: { screens: { sm: '500px', lg: '800px' } } }).then(
|
|
(result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
}
|
|
)
|
|
})
|
|
|
|
test('dark mode variants stack with other variants when using the class strategy', () => {
|
|
const input = `
|
|
@variants responsive, dark, group-hover, hover, focus {
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
const expected = `
|
|
.text-red {
|
|
color: red;
|
|
}
|
|
.group:hover .group-hover\\:text-red {
|
|
color: red;
|
|
}
|
|
.hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
.dark .dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark .group:hover .dark\\:group-hover\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark .dark\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.dark .dark\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
@media (min-width: 500px) {
|
|
.sm\\:text-red {
|
|
color: red;
|
|
}
|
|
.group:hover .sm\\:group-hover\\:text-red {
|
|
color: red;
|
|
}
|
|
.sm\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.sm\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
.dark .sm\\:dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark .group:hover .sm\\:dark\\:group-hover\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark .sm\\:dark\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.dark .sm\\:dark\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
}
|
|
@media (min-width: 800px) {
|
|
.lg\\:text-red {
|
|
color: red;
|
|
}
|
|
.group:hover .lg\\:group-hover\\:text-red {
|
|
color: red;
|
|
}
|
|
.lg\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.lg\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
.dark .lg\\:dark\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark .group:hover .lg\\:dark\\:group-hover\\:text-red {
|
|
color: red;
|
|
}
|
|
.dark .lg\\:dark\\:hover\\:text-red:hover {
|
|
color: red;
|
|
}
|
|
.dark .lg\\:dark\\:focus\\:text-red:focus {
|
|
color: red;
|
|
}
|
|
}
|
|
`
|
|
|
|
expect.assertions(2)
|
|
|
|
return run(input, { darkMode: 'class', theme: { screens: { sm: '500px', lg: '800px' } } }).then(
|
|
(result) => {
|
|
expect(result.css).toMatchCss(expected)
|
|
expect(result.warnings().length).toBe(0)
|
|
}
|
|
)
|
|
})
|