Skip to content

Commit 650fc8f

Browse files
committed
Fix plugin generating invalid CSS
Migrate plugin to use @hacknug/tailwindcss-plugin-utils
1 parent 71fedc7 commit 650fc8f

File tree

7 files changed

+931
-1082
lines changed

7 files changed

+931
-1082
lines changed

index.js

Lines changed: 11 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,13 @@
1-
var _ = require('lodash')
2-
var flatten = require('flat')
3-
4-
5-
const FLATTEN_CONFIG = { delimiter: '-', maxDepth: 2 }
6-
const getName = name => name.split('-default').join('')
7-
8-
9-
module.exports = function () {
10-
return function ({
11-
addUtilities, addComponents, addBase, addVariant,
12-
e, prefix, theme, variants, config,
13-
}) {
14-
const buildObjectFromTheme = (themeKey, ...fallbackKeys) => {
15-
const buildObject = ([ modifier, value ]) => [ modifier, { [themeKey]: value } ]
16-
const getThemeSettings = (themeKey, fallbackKeys) => {
17-
return theme(themeKey, false) || (fallbackKeys && getThemeSettings([themeKey, ...fallbackKeys] = fallbackKeys))
18-
}
19-
20-
const themeSettings = getThemeSettings(themeKey, fallbackKeys)
21-
const themeEntries = themeSettings && Object
22-
.entries(flatten(themeSettings, FLATTEN_CONFIG))
23-
.map(entry => buildObject(entry))
24-
25-
return themeSettings ? _.fromPairs(themeEntries) : false
26-
}
27-
28-
const pluginUtilities = {
29-
textFillColor: buildObjectFromTheme('textFillColor', 'borderColor'),
30-
textStrokeColor: buildObjectFromTheme('textStrokeColor', 'borderColor'),
31-
textStrokeWidth: buildObjectFromTheme('textStrokeWidth', 'borderWidth'),
32-
paintOrder: buildObjectFromTheme('paintOrder') || {
33-
'fsm': { paintOrder: 'fill, stroke, markers' },
34-
'fms': { paintOrder: 'fill, markers, stroke' },
35-
'sfm': { paintOrder: 'stroke, fill, markers' },
36-
'smf': { paintOrder: 'stroke, markers, fill' },
37-
'mfs': { paintOrder: 'markers, fill, stroke' },
38-
'msf': { paintOrder: 'markers, stroke, fill' },
39-
},
40-
}
41-
42-
Object.entries(pluginUtilities)
43-
.filter(([ modifier, values ]) => !_.isEmpty(values))
44-
.forEach(([ modifier, values ]) => {
45-
const className = _.kebabCase(modifier).split('-').reverse().slice(1).reverse().join('-')
46-
const variantName = Object.keys(Object.entries(values)[0][1])[0]
47-
const utilities = flatten({ [`.${e(`${className}`)}`]: values }, FLATTEN_CONFIG)
48-
49-
addUtilities(
50-
_.mapKeys(utilities, (value, key) => getName(key)),
51-
variants(variantName, ['responsive'])
52-
)
53-
})
1+
const tailwindConfig = require('./tailwind.config.js')
2+
const { buildPlugin } = require('@hacknug/tailwindcss-plugin-utils')
3+
4+
module.exports = function (pluginConfig) {
5+
return function (coreUtils) {
6+
return buildPlugin(coreUtils, tailwindConfig, [
7+
{ key: ['textFillColor', 'borderColor'], base: 'text-fill', property: '-webkit-text-fill-color' },
8+
{ key: ['textStrokeColor', 'borderColor'], base: 'text-stroke', property: '-webkit-text-stroke-color' },
9+
{ key: ['textStrokeWidth', 'borderWidth'], base: 'text-stroke', property: '-webkit-text-stroke-width' },
10+
{ key: ['paintOrder'], base: 'paint' },
11+
])
5412
}
5513
}

index.test.js

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
const tailwindConfig = require('./tailwind.config.js')
2+
const { generatePluginCss } = require('@hacknug/tailwindcss-plugin-utils')
3+
4+
expect.extend({ toMatchCss: require('jest-matcher-css') })
5+
6+
const commonConfig = {
7+
theme: {
8+
screens: { 'sm': '640px' },
9+
colors: {
10+
transparent: 'transparent',
11+
black: '#000',
12+
white: '#fff',
13+
gray: {
14+
'100': '#f5f5f5',
15+
'200': '#eeeeee',
16+
'300': '#e0e0e0',
17+
'400': '#bdbdbd',
18+
'500': '#9e9e9e',
19+
'600': '#757575',
20+
'700': '#616161',
21+
'800': '#424242',
22+
'900': '#212121',
23+
},
24+
},
25+
},
26+
corePlugins: false,
27+
}
28+
29+
test('generates default utilities', () => {
30+
const testConfig = { ...commonConfig }
31+
const expectedCss = `
32+
.text-fill-transparent { -webkit-text-fill-color: transparent }
33+
.text-fill-black { -webkit-text-fill-color: #000 }
34+
.text-fill-white { -webkit-text-fill-color: #fff }
35+
.text-fill-gray-100 { -webkit-text-fill-color: #f5f5f5 }
36+
.text-fill-gray-200 { -webkit-text-fill-color: #eeeeee }
37+
.text-fill-gray-300 { -webkit-text-fill-color: #e0e0e0 }
38+
.text-fill-gray-400 { -webkit-text-fill-color: #bdbdbd }
39+
.text-fill-gray-500 { -webkit-text-fill-color: #9e9e9e }
40+
.text-fill-gray-600 { -webkit-text-fill-color: #757575 }
41+
.text-fill-gray-700 { -webkit-text-fill-color: #616161 }
42+
.text-fill-gray-800 { -webkit-text-fill-color: #424242 }
43+
.text-fill-gray-900 { -webkit-text-fill-color: #212121 }
44+
.text-fill { -webkit-text-fill-color: #e0e0e0 }
45+
46+
.text-stroke-transparent { -webkit-text-stroke-color: transparent }
47+
.text-stroke-black { -webkit-text-stroke-color: #000 }
48+
.text-stroke-white { -webkit-text-stroke-color: #fff }
49+
.text-stroke-gray-100 { -webkit-text-stroke-color: #f5f5f5 }
50+
.text-stroke-gray-200 { -webkit-text-stroke-color: #eeeeee }
51+
.text-stroke-gray-300 { -webkit-text-stroke-color: #e0e0e0 }
52+
.text-stroke-gray-400 { -webkit-text-stroke-color: #bdbdbd }
53+
.text-stroke-gray-500 { -webkit-text-stroke-color: #9e9e9e }
54+
.text-stroke-gray-600 { -webkit-text-stroke-color: #757575 }
55+
.text-stroke-gray-700 { -webkit-text-stroke-color: #616161 }
56+
.text-stroke-gray-800 { -webkit-text-stroke-color: #424242 }
57+
.text-stroke-gray-900 { -webkit-text-stroke-color: #212121 }
58+
.text-stroke { -webkit-text-stroke-color: #e0e0e0 }
59+
60+
.text-stroke-0 { -webkit-text-stroke-width: 0 }
61+
.text-stroke-2 { -webkit-text-stroke-width: 2px }
62+
.text-stroke-4 { -webkit-text-stroke-width: 4px }
63+
.text-stroke-8 { -webkit-text-stroke-width: 8px }
64+
.text-stroke { -webkit-text-stroke-width: 1px }
65+
66+
.paint-fsm { paint-order: fill stroke markers }
67+
.paint-fms { paint-order: fill markers stroke }
68+
.paint-sfm { paint-order: stroke fill markers }
69+
.paint-smf { paint-order: stroke markers fill }
70+
.paint-mfs { paint-order: markers fill stroke }
71+
.paint-msf { paint-order: markers stroke fill }
72+
`
73+
74+
return generatePluginCss(tailwindConfig, testConfig).then(css => expect(css).toMatchCss(expectedCss))
75+
})
76+
77+
test('variants can be customized', () => {
78+
const testConfig = {
79+
...commonConfig,
80+
variants: {
81+
textFillColor: ['hover'],
82+
textStrokeColor: ['focus'],
83+
textStrokeWidth: ['active'],
84+
paintOrder: ['responsive', 'hover'],
85+
},
86+
}
87+
const expectedCss = `
88+
.text-fill-transparent { -webkit-text-fill-color: transparent }
89+
.text-fill-black { -webkit-text-fill-color: #000 }
90+
.text-fill-white { -webkit-text-fill-color: #fff }
91+
.text-fill-gray-100 { -webkit-text-fill-color: #f5f5f5 }
92+
.text-fill-gray-200 { -webkit-text-fill-color: #eeeeee }
93+
.text-fill-gray-300 { -webkit-text-fill-color: #e0e0e0 }
94+
.text-fill-gray-400 { -webkit-text-fill-color: #bdbdbd }
95+
.text-fill-gray-500 { -webkit-text-fill-color: #9e9e9e }
96+
.text-fill-gray-600 { -webkit-text-fill-color: #757575 }
97+
.text-fill-gray-700 { -webkit-text-fill-color: #616161 }
98+
.text-fill-gray-800 { -webkit-text-fill-color: #424242 }
99+
.text-fill-gray-900 { -webkit-text-fill-color: #212121 }
100+
.text-fill { -webkit-text-fill-color: #e0e0e0 }
101+
102+
.hover\\:text-fill-transparent:hover { -webkit-text-fill-color: transparent }
103+
.hover\\:text-fill-black:hover { -webkit-text-fill-color: #000 }
104+
.hover\\:text-fill-white:hover { -webkit-text-fill-color: #fff }
105+
.hover\\:text-fill-gray-100:hover { -webkit-text-fill-color: #f5f5f5 }
106+
.hover\\:text-fill-gray-200:hover { -webkit-text-fill-color: #eeeeee }
107+
.hover\\:text-fill-gray-300:hover { -webkit-text-fill-color: #e0e0e0 }
108+
.hover\\:text-fill-gray-400:hover { -webkit-text-fill-color: #bdbdbd }
109+
.hover\\:text-fill-gray-500:hover { -webkit-text-fill-color: #9e9e9e }
110+
.hover\\:text-fill-gray-600:hover { -webkit-text-fill-color: #757575 }
111+
.hover\\:text-fill-gray-700:hover { -webkit-text-fill-color: #616161 }
112+
.hover\\:text-fill-gray-800:hover { -webkit-text-fill-color: #424242 }
113+
.hover\\:text-fill-gray-900:hover { -webkit-text-fill-color: #212121 }
114+
.hover\\:text-fill:hover { -webkit-text-fill-color: #e0e0e0 }
115+
116+
.text-stroke-transparent { -webkit-text-stroke-color: transparent }
117+
.text-stroke-black { -webkit-text-stroke-color: #000 }
118+
.text-stroke-white { -webkit-text-stroke-color: #fff }
119+
.text-stroke-gray-100 { -webkit-text-stroke-color: #f5f5f5 }
120+
.text-stroke-gray-200 { -webkit-text-stroke-color: #eeeeee }
121+
.text-stroke-gray-300 { -webkit-text-stroke-color: #e0e0e0 }
122+
.text-stroke-gray-400 { -webkit-text-stroke-color: #bdbdbd }
123+
.text-stroke-gray-500 { -webkit-text-stroke-color: #9e9e9e }
124+
.text-stroke-gray-600 { -webkit-text-stroke-color: #757575 }
125+
.text-stroke-gray-700 { -webkit-text-stroke-color: #616161 }
126+
.text-stroke-gray-800 { -webkit-text-stroke-color: #424242 }
127+
.text-stroke-gray-900 { -webkit-text-stroke-color: #212121 }
128+
.text-stroke { -webkit-text-stroke-color: #e0e0e0 }
129+
130+
.focus\\:text-stroke-transparent:focus { -webkit-text-stroke-color: transparent }
131+
.focus\\:text-stroke-black:focus { -webkit-text-stroke-color: #000 }
132+
.focus\\:text-stroke-white:focus { -webkit-text-stroke-color: #fff }
133+
.focus\\:text-stroke-gray-100:focus { -webkit-text-stroke-color: #f5f5f5 }
134+
.focus\\:text-stroke-gray-200:focus { -webkit-text-stroke-color: #eeeeee }
135+
.focus\\:text-stroke-gray-300:focus { -webkit-text-stroke-color: #e0e0e0 }
136+
.focus\\:text-stroke-gray-400:focus { -webkit-text-stroke-color: #bdbdbd }
137+
.focus\\:text-stroke-gray-500:focus { -webkit-text-stroke-color: #9e9e9e }
138+
.focus\\:text-stroke-gray-600:focus { -webkit-text-stroke-color: #757575 }
139+
.focus\\:text-stroke-gray-700:focus { -webkit-text-stroke-color: #616161 }
140+
.focus\\:text-stroke-gray-800:focus { -webkit-text-stroke-color: #424242 }
141+
.focus\\:text-stroke-gray-900:focus { -webkit-text-stroke-color: #212121 }
142+
.focus\\:text-stroke:focus { -webkit-text-stroke-color: #e0e0e0 }
143+
144+
.text-stroke-0 { -webkit-text-stroke-width: 0 }
145+
.text-stroke-2 { -webkit-text-stroke-width: 2px }
146+
.text-stroke-4 { -webkit-text-stroke-width: 4px }
147+
.text-stroke-8 { -webkit-text-stroke-width: 8px }
148+
.text-stroke { -webkit-text-stroke-width: 1px }
149+
150+
.active\\:text-stroke-0:active { -webkit-text-stroke-width: 0 }
151+
.active\\:text-stroke-2:active { -webkit-text-stroke-width: 2px }
152+
.active\\:text-stroke-4:active { -webkit-text-stroke-width: 4px }
153+
.active\\:text-stroke-8:active { -webkit-text-stroke-width: 8px }
154+
.active\\:text-stroke:active { -webkit-text-stroke-width: 1px }
155+
156+
.paint-fsm { paint-order: fill stroke markers }
157+
.paint-fms { paint-order: fill markers stroke }
158+
.paint-sfm { paint-order: stroke fill markers }
159+
.paint-smf { paint-order: stroke markers fill }
160+
.paint-mfs { paint-order: markers fill stroke }
161+
.paint-msf { paint-order: markers stroke fill }
162+
163+
.hover\\:paint-fsm:hover { paint-order: fill stroke markers }
164+
.hover\\:paint-fms:hover { paint-order: fill markers stroke }
165+
.hover\\:paint-sfm:hover { paint-order: stroke fill markers }
166+
.hover\\:paint-smf:hover { paint-order: stroke markers fill }
167+
.hover\\:paint-mfs:hover { paint-order: markers fill stroke }
168+
.hover\\:paint-msf:hover { paint-order: markers stroke fill }
169+
170+
@media (min-width: 640px) {
171+
.sm\\:paint-fsm { paint-order: fill stroke markers }
172+
.sm\\:paint-fms { paint-order: fill markers stroke }
173+
.sm\\:paint-sfm { paint-order: stroke fill markers }
174+
.sm\\:paint-smf { paint-order: stroke markers fill }
175+
.sm\\:paint-mfs { paint-order: markers fill stroke }
176+
.sm\\:paint-msf { paint-order: markers stroke fill }
177+
178+
.sm\\:hover\\:paint-fsm:hover { paint-order: fill stroke markers }
179+
.sm\\:hover\\:paint-fms:hover { paint-order: fill markers stroke }
180+
.sm\\:hover\\:paint-sfm:hover { paint-order: stroke fill markers }
181+
.sm\\:hover\\:paint-smf:hover { paint-order: stroke markers fill }
182+
.sm\\:hover\\:paint-mfs:hover { paint-order: markers fill stroke }
183+
.sm\\:hover\\:paint-msf:hover { paint-order: markers stroke fill }
184+
}
185+
`
186+
187+
return generatePluginCss(tailwindConfig, testConfig).then(css => expect(css).toMatchCss(expectedCss))
188+
})
189+
190+
191+
test('utilities can be customized', () => {
192+
const testConfig = {
193+
theme: {
194+
textFillColor: theme => ({
195+
transparent: 'transparent',
196+
black: '#000',
197+
white: '#fff',
198+
gray: '#9e9e9e',
199+
default: '#38b2ac',
200+
}),
201+
textStrokeColor: theme => ({
202+
transparent: theme('colors.transparent'),
203+
default: '#38b2ac'
204+
}),
205+
textStrokeWidth: { default: '1px', sm: '2px', md: '4px', lg: '8px' },
206+
paintOrder: { stroke: 'stroke' }
207+
},
208+
}
209+
const expectedCss = `
210+
.text-fill-transparent { -webkit-text-fill-color: transparent }
211+
.text-fill-black { -webkit-text-fill-color: #000 }
212+
.text-fill-white { -webkit-text-fill-color: #fff }
213+
.text-fill-gray { -webkit-text-fill-color: #9e9e9e }
214+
.text-fill { -webkit-text-fill-color: #38b2ac }
215+
216+
.text-stroke-transparent { -webkit-text-stroke-color: transparent }
217+
.text-stroke { -webkit-text-stroke-color: #38b2ac }
218+
219+
.text-stroke { -webkit-text-stroke-width: 1px }
220+
.text-stroke-sm { -webkit-text-stroke-width: 2px }
221+
.text-stroke-md { -webkit-text-stroke-width: 4px }
222+
.text-stroke-lg { -webkit-text-stroke-width: 8px }
223+
224+
${ /* FIXME: Merging of configs not working */'' }
225+
.paint-fsm { paint-order: fill stroke markers }
226+
.paint-fms { paint-order: fill markers stroke }
227+
.paint-sfm { paint-order: stroke fill markers }
228+
.paint-smf { paint-order: stroke markers fill }
229+
.paint-mfs { paint-order: markers fill stroke }
230+
.paint-msf { paint-order: markers stroke fill }
231+
232+
.paint-stroke { paint-order: stroke }
233+
`
234+
235+
return generatePluginCss(tailwindConfig, testConfig).then(css => expect(css).toMatchCss(expectedCss))
236+
})

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@
3030
},
3131
"dependencies": {
3232
"flat": "^4.1.0",
33-
"lodash": "^4.17.11"
33+
"lodash": "^4.17.15"
3434
},
3535
"devDependencies": {
36-
"jest": "^24.8.0",
37-
"jest-matcher-css": "^1.0.3",
38-
"postcss": "^7.0.16",
39-
"tailwindcss": "^1.0.1"
36+
"@hacknug/tailwindcss-plugin-utils": "^0.8.0",
37+
"jest": "^24.9.0",
38+
"jest-matcher-css": "^1.1.0",
39+
"postcss": "^7.0.18",
40+
"tailwindcss": "^1.1.2"
4041
}
4142
}

0 commit comments

Comments
 (0)