Skip to content
This repository was archived by the owner on Apr 6, 2021. It is now read-only.

Commit 00197fc

Browse files
committed
Add custom separator support
1 parent 7ff6acd commit 00197fc

File tree

5 files changed

+89
-24
lines changed

5 files changed

+89
-24
lines changed

src/corePlugins/index.js

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const {
1111
} = require('../pluginUtils')
1212

1313
module.exports = {
14-
pseudoClassVariants: function ({ jit: { config, theme, addUtilities, addVariant, e } }) {
14+
pseudoClassVariants: function ({ config, theme, addVariant }) {
1515
let pseudoVariants = [
1616
['first', 'first-child'],
1717
['last', 'last-child'],
@@ -33,7 +33,7 @@ module.exports = {
3333
addVariant(
3434
variantName,
3535
transformAllClasses((className, { withPseudo }) => {
36-
return withPseudo(`${variantName}:${className}`, state)
36+
return withPseudo(`${variantName}${config('separator')}${className}`, state)
3737
})
3838
)
3939
}
@@ -46,24 +46,24 @@ module.exports = {
4646
groupVariantName,
4747
transformAllSelectors((selector) => {
4848
let variantSelector = updateAllClasses(selector, (className) => {
49-
return `${groupVariantName}:${className}`
49+
return `${groupVariantName}${config('separator')}${className}`
5050
})
5151

5252
if (variantSelector === selector) {
5353
return null
5454
}
5555

56-
return `.group:${state} ${variantSelector}`
56+
return `.group${config('separator')}${state} ${variantSelector}`
5757
})
5858
)
5959
}
6060
},
61-
reducedMotionVariants: function ({ jit: { config, theme, addUtilities, addVariant, e } }) {
61+
reducedMotionVariants: function ({ config, theme, addVariant }) {
6262
addVariant(
6363
'motion-safe',
6464
transformLastClasses(
6565
(className) => {
66-
return `motion-safe:${className}`
66+
return `motion-safe${config('separator')}${className}`
6767
},
6868
() => postcss.atRule({ name: 'media', params: '(prefers-reduced-motion: no-preference)' })
6969
)
@@ -73,34 +73,42 @@ module.exports = {
7373
'motion-reduce',
7474
transformLastClasses(
7575
(className) => {
76-
return `motion-reduce:${className}`
76+
return `motion-reduce${config('separator')}${className}`
7777
},
7878
() => postcss.atRule({ name: 'media', params: '(prefers-reduced-motion: reduce)' })
7979
)
8080
)
8181
},
82-
directionVariants: function ({ jit: { config, theme, addUtilities, addVariant, e } }) {
82+
directionVariants: function ({ config, theme, addVariant }) {
8383
addVariant(
8484
'ltr',
8585
transformAllSelectors(
86-
(selector) => `[dir="ltr"] ${updateAllClasses(selector, (className) => `ltr:${className}`)}`
86+
(selector) =>
87+
`[dir="ltr"] ${updateAllClasses(
88+
selector,
89+
(className) => `ltr${config('separator')}${className}`
90+
)}`
8791
)
8892
)
8993

9094
addVariant(
9195
'rtl',
9296
transformAllSelectors(
93-
(selector) => `[dir="rtl"] ${updateAllClasses(selector, (className) => `rtl:${className}`)}`
97+
(selector) =>
98+
`[dir="rtl"] ${updateAllClasses(
99+
selector,
100+
(className) => `rtl${config('separator')}${className}`
101+
)}`
94102
)
95103
)
96104
},
97-
darkVariants: function ({ jit: { config, theme, addUtilities, addVariant, e } }) {
98-
if (config.darkMode === 'class') {
105+
darkVariants: function ({ config, theme, addVariant }) {
106+
if (config('darkMode') === 'class') {
99107
addVariant(
100108
'dark',
101109
transformAllSelectors((selector) => {
102110
let variantSelector = updateLastClasses(selector, (className) => {
103-
return `dark:${className}`
111+
return `dark${config('separator')}${className}`
104112
})
105113

106114
if (variantSelector === selector) {
@@ -110,28 +118,28 @@ module.exports = {
110118
return `.dark ${variantSelector}`
111119
})
112120
)
113-
} else if (config.darkMode === 'media') {
121+
} else if (config('darkMode') === 'media') {
114122
addVariant(
115123
'dark',
116124
transformLastClasses(
117125
(className) => {
118-
return `dark:${className}`
126+
return `dark${config('separator')}${className}`
119127
},
120128
() => postcss.atRule({ name: 'media', params: '(prefers-color-scheme: dark)' })
121129
)
122130
)
123131
}
124132
},
125-
screenVariants: function ({ jit: { config, theme, addUtilities, addVariant, e } }) {
126-
for (let screen in theme.screens) {
127-
let size = theme.screens[screen]
133+
screenVariants: function ({ config, theme, addVariant }) {
134+
for (let screen in theme('screens')) {
135+
let size = theme('screens')[screen]
128136
let query = buildMediaQuery(size)
129137

130138
addVariant(
131139
screen,
132140
transformLastClasses(
133141
(className) => {
134-
return `${screen}:${className}`
142+
return `${screen}${config('separator')}${className}`
135143
},
136144
() => postcss.atRule({ name: 'media', params: query })
137145
)

src/lib/generateRules.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ function* candidatePermutations(prefix, modifier = '') {
3939
// and `focus:hover:text-center` in the same project, but it doesn't feel
4040
// worth the complexity for that case.
4141

42-
function applyVariant(variant, matches, { variantMap }) {
42+
function applyVariant(variant, matches, context) {
4343
if (matches.length === 0) {
4444
return matches
4545
}
4646

47-
if (variantMap.has(variant)) {
48-
let [variantSort, applyThisVariant] = variantMap.get(variant)
47+
if (context.variantMap.has(variant)) {
48+
let [variantSort, applyThisVariant] = context.variantMap.get(variant)
4949
let result = []
5050

5151
for (let [{ sort, layer, options }, rule] of matches) {
@@ -74,7 +74,11 @@ function applyVariant(variant, matches, { variantMap }) {
7474
return container
7575
}
7676

77-
let ruleWithVariant = applyThisVariant({ container, separator: ':', modifySelectors })
77+
let ruleWithVariant = applyThisVariant({
78+
container,
79+
separator: context.tailwindConfig.separator,
80+
modifySelectors,
81+
})
7882

7983
if (ruleWithVariant === null) {
8084
continue
@@ -137,7 +141,8 @@ function sortAgainst(toSort, against) {
137141
}
138142

139143
function* resolveMatches(candidate, context) {
140-
let [classCandidate, ...variants] = candidate.split(':').reverse()
144+
let separator = context.tailwindConfig.separator
145+
let [classCandidate, ...variants] = candidate.split(separator).reverse()
141146

142147
// Strip prefix
143148
// md:hover:tw-bg-black

tests/02-custom-separator.test.css

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.group_hover .group-hover_focus-within_text-left:focus-within {
2+
text-align: left;
3+
}
4+
[dir='rtl'] .rtl_active_text-center:active {
5+
text-align: center;
6+
}
7+
@media (prefers-reduced-motion: no-preference) {
8+
.motion-safe_hover_text-center:hover {
9+
text-align: center;
10+
}
11+
}
12+
.dark .dark_focus_text-left:focus {
13+
text-align: left;
14+
}
15+
@media (min-width: 768px) {
16+
.md_hover_text-right:hover {
17+
text-align: right;
18+
}
19+
}

tests/02-custom-separator.test.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="md_hover_text-right"></div>
2+
<div class="motion-safe_hover_text-center"></div>
3+
<div class="dark_focus_text-left"></div>
4+
<div class="group-hover_focus-within_text-left"></div>
5+
<div class="rtl_active_text-center"></div>

tests/02-custom-separator.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const postcss = require('postcss')
2+
const tailwind = require('../src/index.js')
3+
const fs = require('fs')
4+
const path = require('path')
5+
6+
function run(input, config = {}) {
7+
return postcss([tailwind(config)]).process(input, { from: path.resolve(__filename) })
8+
}
9+
10+
test('custom separator', () => {
11+
let config = {
12+
darkMode: 'class',
13+
purge: [path.resolve(__dirname, './02-custom-separator.test.html')],
14+
separator: '_',
15+
corePlugins: {},
16+
theme: {},
17+
plugins: [],
18+
}
19+
20+
let css = `@tailwind utilities`
21+
22+
return run(css, config).then((result) => {
23+
let expectedPath = path.resolve(__dirname, './02-custom-separator.test.css')
24+
let expected = fs.readFileSync(expectedPath, 'utf8')
25+
26+
expect(result.css).toMatchCss(expected)
27+
})
28+
})

0 commit comments

Comments
 (0)