Skip to content

Commit 6253aa5

Browse files
authored
Fix bracket order of not variants (#1621)
* fix order of brackets in selector * setup tests for `@headlessui/tailwindcss` * update changelog
1 parent 65bbacd commit 6253aa5

File tree

5 files changed

+156
-2
lines changed

5 files changed

+156
-2
lines changed

packages/@headlessui-tailwindcss/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
10+
### Fixed
11+
12+
- Fix bracket order of `not` variants ([#1621](https://github.com/tailwindlabs/headlessui/pull/1621))
1113

1214
## [0.1.0] - 2022-05-24
1315

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
let create = require('../../jest/create-jest-config.cjs')
2+
module.exports = create(__dirname, {
3+
displayName: ' CSS ',
4+
setupFilesAfterEnv: ['./jest.setup.js'],
5+
})
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
let prettier = require('prettier')
2+
3+
function format(input) {
4+
return prettier.format(input.replace(/\n/g, ''), {
5+
parser: 'css',
6+
printWidth: 100,
7+
})
8+
}
9+
10+
expect.extend({
11+
// Compare two CSS strings with all whitespace removed
12+
// This is probably naive but it's fast and works well enough.
13+
toMatchFormattedCss(received = '', argument = '') {
14+
let options = {
15+
comment: 'stripped(received) === stripped(argument)',
16+
isNot: this.isNot,
17+
promise: this.promise,
18+
}
19+
20+
let formattedReceived = format(received)
21+
let formattedArgument = format(argument)
22+
23+
let pass = formattedReceived === formattedArgument
24+
25+
let message = pass
26+
? () => {
27+
return (
28+
this.utils.matcherHint('toMatchFormattedCss', undefined, undefined, options) +
29+
'\n\n' +
30+
`Expected: not ${this.utils.printExpected(formattedReceived)}\n` +
31+
`Received: ${this.utils.printReceived(formattedArgument)}`
32+
)
33+
}
34+
: () => {
35+
let actual = formattedReceived
36+
let expected = formattedArgument
37+
38+
let diffString = this.utils.diff(expected, actual, {
39+
expand: this.expand,
40+
})
41+
42+
return (
43+
this.utils.matcherHint('toMatchFormattedCss', undefined, undefined, options) +
44+
'\n\n' +
45+
(diffString && diffString.includes('- Expect')
46+
? `Difference:\n\n${diffString}`
47+
: `Expected: ${this.utils.printExpected(expected)}\n` +
48+
`Received: ${this.utils.printReceived(actual)}`)
49+
)
50+
}
51+
52+
return { actual: received, message, pass }
53+
},
54+
})
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import path from 'path'
2+
import postcss from 'postcss'
3+
import tailwind from 'tailwindcss'
4+
import hui from './index'
5+
6+
let html = String.raw
7+
let css = String.raw
8+
9+
function run(input: string, config: any, plugin = tailwind) {
10+
let { currentTestName } = expect.getState()
11+
12+
return postcss(plugin(config)).process(input, {
13+
from: `${path.resolve(__filename)}?test=${currentTestName}`,
14+
})
15+
}
16+
17+
it('should generate css for an exposed state', async () => {
18+
let config = {
19+
content: [{ raw: html`<div class="ui-open:underline"></div>` }],
20+
plugins: [hui],
21+
}
22+
23+
return run('@tailwind utilities', config).then((result) => {
24+
expect(result.css).toMatchFormattedCss(css`
25+
.ui-open\:underline[data-headlessui-state~='open'] {
26+
text-decoration-line: underline;
27+
}
28+
:where([data-headlessui-state~='open']) .ui-open\:underline {
29+
text-decoration-line: underline;
30+
}
31+
`)
32+
})
33+
})
34+
35+
it('should generate the inverse "not" css for an exposed state', async () => {
36+
let config = {
37+
content: [{ raw: html`<div class="ui-not-open:underline"></div>` }],
38+
plugins: [hui],
39+
}
40+
41+
return run('@tailwind utilities', config).then((result) => {
42+
expect(result.css).toMatchFormattedCss(css`
43+
.ui-not-open\:underline[data-headlessui-state]:not([data-headlessui-state~='open']) {
44+
text-decoration-line: underline;
45+
}
46+
47+
:where([data-headlessui-state]:not([data-headlessui-state~='open']))
48+
.ui-not-open\:underline:not([data-headlessui-state]) {
49+
text-decoration-line: underline;
50+
}
51+
`)
52+
})
53+
})
54+
55+
describe('custom prefix', () => {
56+
it('should generate css for an exposed state', async () => {
57+
let config = {
58+
content: [{ raw: html`<div class="hui-open:underline"></div>` }],
59+
plugins: [hui({ prefix: 'hui' })],
60+
}
61+
62+
return run('@tailwind utilities', config).then((result) => {
63+
expect(result.css).toMatchFormattedCss(css`
64+
.hui-open\:underline[data-headlessui-state~='open'] {
65+
text-decoration-line: underline;
66+
}
67+
:where([data-headlessui-state~='open']) .hui-open\:underline {
68+
text-decoration-line: underline;
69+
}
70+
`)
71+
})
72+
})
73+
74+
it('should generate the inverse "not" css for an exposed state', async () => {
75+
let config = {
76+
content: [{ raw: html`<div class="hui-not-open:underline"></div>` }],
77+
plugins: [hui({ prefix: 'hui' })],
78+
}
79+
80+
return run('@tailwind utilities', config).then((result) => {
81+
expect(result.css).toMatchFormattedCss(css`
82+
.hui-not-open\:underline[data-headlessui-state]:not([data-headlessui-state~='open']) {
83+
text-decoration-line: underline;
84+
}
85+
86+
:where([data-headlessui-state]:not([data-headlessui-state~='open']))
87+
.hui-not-open\:underline:not([data-headlessui-state]) {
88+
text-decoration-line: underline;
89+
}
90+
`)
91+
})
92+
})
93+
})

packages/@headlessui-tailwindcss/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default plugin.withOptions<Options>(({ prefix = 'ui' } = {}) => {
2929

3030
addVariant(`${prefix}-not-${state}`, [
3131
`&[data-headlessui-state]:not([data-headlessui-state~="${state}"])`,
32-
`:where([data-headlessui-state]:not([data-headlessui-state~="${state}"]) &:not([data-headlessui-state]))`,
32+
`:where([data-headlessui-state]:not([data-headlessui-state~="${state}"])) &:not([data-headlessui-state])`,
3333
])
3434
}
3535
}

0 commit comments

Comments
 (0)