Skip to content

Commit cf145b4

Browse files
authored
Use matchComponents API where possible (tailwindlabs#26)
* Use `matchComponents` API where possible * Add tests * Reuse common styles
1 parent 9f68d33 commit cf145b4

File tree

3 files changed

+218
-28
lines changed

3 files changed

+218
-28
lines changed

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"trailingComma": "es5"
1515
},
1616
"scripts": {
17+
"test": "jest",
1718
"prepublishOnly": "node scripts/build.js"
1819
},
1920
"peerDependencies": {
@@ -22,7 +23,9 @@
2223
"devDependencies": {
2324
"autoprefixer": "10",
2425
"clean-css": "^4.2.1",
26+
"jest": "^27.2.4",
2527
"postcss": "^8.2.4",
26-
"tailwindcss": "^2.0.2"
28+
"tailwindcss": "^3.0.0-alpha.1",
29+
"tailwindcss-v2": "npm:tailwindcss@^2.2.16"
2730
}
2831
}

src/index.js

+57-27
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,62 @@
11
const plugin = require('tailwindcss/plugin')
22

3+
const baseStyles = {
4+
position: 'relative',
5+
paddingBottom: `calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)`,
6+
}
7+
8+
const childStyles = {
9+
position: 'absolute',
10+
height: '100%',
11+
width: '100%',
12+
top: '0',
13+
right: '0',
14+
bottom: '0',
15+
left: '0',
16+
}
17+
18+
const noneComponent = {
19+
'.aspect-none': {
20+
position: 'static',
21+
paddingBottom: '0',
22+
},
23+
'.aspect-none > *': {
24+
position: 'static',
25+
height: 'auto',
26+
width: 'auto',
27+
top: 'auto',
28+
right: 'auto',
29+
bottom: 'auto',
30+
left: 'auto',
31+
},
32+
}
33+
334
const aspectRatio = plugin(
4-
function ({ addComponents, theme, variants, e }) {
35+
function ({ addComponents, matchComponents, theme, variants, e }) {
536
const values = theme('aspectRatio')
637

38+
if (matchComponents) {
39+
matchComponents(
40+
{
41+
'aspect-w': (value) => [
42+
{
43+
...baseStyles,
44+
'--tw-aspect-w': value,
45+
},
46+
{
47+
'> *': childStyles,
48+
},
49+
],
50+
'aspect-h': (value) => ({ '--tw-aspect-h': value }),
51+
},
52+
{ values }
53+
)
54+
55+
addComponents(noneComponent)
56+
57+
return
58+
}
59+
760
const baseSelectors = Object.entries(values)
861
.map(([key, value]) => {
962
return `.${e(`aspect-w-${key}`)}`
@@ -19,33 +72,10 @@ const aspectRatio = plugin(
1972
addComponents(
2073
[
2174
{
22-
[baseSelectors]: {
23-
position: 'relative',
24-
paddingBottom: `calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)`,
25-
},
26-
[childSelectors]: {
27-
position: 'absolute',
28-
height: '100%',
29-
width: '100%',
30-
top: '0',
31-
right: '0',
32-
bottom: '0',
33-
left: '0',
34-
},
35-
'.aspect-none': {
36-
position: 'static',
37-
paddingBottom: '0',
38-
},
39-
'.aspect-none > *': {
40-
position: 'static',
41-
height: 'auto',
42-
width: 'auto',
43-
top: 'auto',
44-
right: 'auto',
45-
bottom: 'auto',
46-
left: 'auto',
47-
},
75+
[baseSelectors]: baseStyles,
76+
[childSelectors]: childStyles,
4877
},
78+
noneComponent,
4979
Object.entries(values).map(([key, value]) => {
5080
return {
5181
[`.${e(`aspect-w-${key}`)}`]: {

tests/test.js

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
const postcss = require('postcss')
2+
3+
let expectedV3 = `
4+
.aspect-w-1 {
5+
position: relative;
6+
padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%);
7+
--tw-aspect-w: 1
8+
}
9+
.aspect-w-1 > * {
10+
position: absolute;
11+
height: 100%;
12+
width: 100%;
13+
top: 0;
14+
right: 0;
15+
bottom: 0;
16+
left: 0
17+
}
18+
.aspect-w-2 {
19+
position: relative;
20+
padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%);
21+
--tw-aspect-w: 2
22+
}
23+
.aspect-w-2 > * {
24+
position: absolute;
25+
height: 100%;
26+
width: 100%;
27+
top: 0;
28+
right: 0;
29+
bottom: 0;
30+
left: 0
31+
}
32+
.aspect-h-2 {
33+
--tw-aspect-h: 2
34+
}
35+
.aspect-w-\\[123\\] {
36+
position: relative;
37+
padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%);
38+
--tw-aspect-w: 123
39+
}
40+
.aspect-w-\\[123\\] > * {
41+
position: absolute;
42+
height: 100%;
43+
width: 100%;
44+
top: 0;
45+
right: 0;
46+
bottom: 0;
47+
left: 0
48+
}
49+
.aspect-w-\\[var\\(--width\\)\\] {
50+
position: relative;
51+
padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%);
52+
--tw-aspect-w: var(--width)
53+
}
54+
.aspect-w-\\[var\\(--width\\)\\] > * {
55+
position: absolute;
56+
height: 100%;
57+
width: 100%;
58+
top: 0;
59+
right: 0;
60+
bottom: 0;
61+
left: 0
62+
}
63+
.aspect-h-\\[123\\] {
64+
--tw-aspect-h: 123
65+
}
66+
.aspect-h-\\[var\\(--height\\)\\] {
67+
--tw-aspect-h: var(--height)
68+
}
69+
.aspect-none {
70+
position: static;
71+
padding-bottom: 0
72+
}
73+
.aspect-none > * {
74+
position: static;
75+
height: auto;
76+
width: auto;
77+
top: auto;
78+
right: auto;
79+
bottom: auto;
80+
left: auto
81+
}
82+
`
83+
84+
it('v3', () => {
85+
let css = postcss([
86+
require('tailwindcss')({
87+
content: [
88+
{
89+
raw: 'aspect-none aspect-w-1 aspect-w-2 aspect-h-2 aspect-w-[123] aspect-w-[var(--width)] aspect-h-[123] aspect-h-[var(--height)]',
90+
},
91+
],
92+
plugins: [require('../')],
93+
}),
94+
]).process('@tailwind components').css
95+
96+
expect(css).toBe(expectedV3.trim())
97+
})
98+
99+
let expectedV2 = `
100+
.aspect-w-1,
101+
.aspect-w-2 {
102+
position: relative;
103+
padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)
104+
}
105+
106+
.aspect-w-1 > *,
107+
.aspect-w-2 > * {
108+
position: absolute;
109+
height: 100%;
110+
width: 100%;
111+
top: 0;
112+
right: 0;
113+
bottom: 0;
114+
left: 0
115+
}
116+
117+
.aspect-none {
118+
position: static;
119+
padding-bottom: 0
120+
}
121+
122+
.aspect-none > * {
123+
position: static;
124+
height: auto;
125+
width: auto;
126+
top: auto;
127+
right: auto;
128+
bottom: auto;
129+
left: auto
130+
}
131+
132+
.aspect-w-1 {
133+
--tw-aspect-w: 1
134+
}
135+
136+
.aspect-w-2 {
137+
--tw-aspect-w: 2
138+
}
139+
140+
.aspect-h-2 {
141+
--tw-aspect-h: 2
142+
}
143+
`
144+
145+
it('v2', () => {
146+
postcss([
147+
require('tailwindcss-v2')({
148+
purge: { enabled: true, content: [{ raw: 'aspect-none aspect-w-1 aspect-w-2 aspect-h-2' }] },
149+
variants: [],
150+
plugins: [require('../')],
151+
}),
152+
])
153+
.process('@tailwind components', { from: undefined })
154+
.then(({ css }) => {
155+
expect(css).toBe(expectedV2.trim())
156+
})
157+
})

0 commit comments

Comments
 (0)