Skip to content

Commit

Permalink
Add [open] variant (#5627)
Browse files Browse the repository at this point in the history
* Add `[open]` variant

Co-Authored-By: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-Authored-By: Sean Doyle <2575027+seanpdoyle@users.noreply.github.com>

* Add new `applyStateToMarker()` function

This function replaces the existing `applyPseudoToMarker()` and `applyAttributeToMarker()` functions.

Co-Authored-By: Robin Malfait <1834413+RobinMalfait@users.noreply.github.com>

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Sean Doyle <2575027+seanpdoyle@users.noreply.github.com>
Co-authored-by: Robin Malfait <1834413+RobinMalfait@users.noreply.github.com>
  • Loading branch information
4 people committed Sep 28, 2021
1 parent c30a32e commit 8004917
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 27 deletions.
31 changes: 18 additions & 13 deletions src/corePlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import toColorValue from './util/toColorValue'
import isPlainObject from './util/isPlainObject'
import transformThemeValue from './util/transformThemeValue'
import {
applyPseudoToMarker,
applyStateToMarker,
updateLastClasses,
updateAllClasses,
transformAllSelectors,
Expand Down Expand Up @@ -128,18 +128,19 @@ export default {
pseudoClassVariants: ({ config, addVariant }) => {
let pseudoVariants = [
// Positional
['first', 'first-child'],
['last', 'last-child'],
['only', 'only-child'],
['odd', 'nth-child(odd)'],
['even', 'nth-child(even)'],
['first', ':first-child'],
['last', ':last-child'],
['only', ':only-child'],
['odd', ':nth-child(odd)'],
['even', ':nth-child(even)'],
'first-of-type',
'last-of-type',
'only-of-type',

// State
'visited',
'target',
['open', '[open]'],

// Forms
'default',
Expand Down Expand Up @@ -167,19 +168,23 @@ export default {
]

for (let variant of pseudoVariants) {
let [variantName, state] = Array.isArray(variant) ? variant : [variant, variant]
let [variantName, state] = Array.isArray(variant) ? variant : [variant, `:${variant}`]

addVariant(
variantName,
transformAllClasses((className, { withPseudo }) => {
return withPseudo(`${variantName}${config('separator')}${className}`, `:${state}`)
transformAllClasses((className, { withAttr, withPseudo }) => {
if (state.startsWith(':')) {
return withPseudo(`${variantName}${config('separator')}${className}`, state)
} else if (state.startsWith('[')) {
return withAttr(`${variantName}${config('separator')}${className}`, state)
}
})
)
}

let groupMarker = prefixSelector(config('prefix'), '.group')
for (let variant of pseudoVariants) {
let [variantName, state] = Array.isArray(variant) ? variant : [variant, variant]
let [variantName, state] = Array.isArray(variant) ? variant : [variant, `:${variant}`]
let groupVariantName = `group-${variantName}`

addVariant(
Expand All @@ -194,7 +199,7 @@ export default {
return null
}

return applyPseudoToMarker(
return applyStateToMarker(
variantSelector,
groupMarker,
state,
Expand All @@ -206,7 +211,7 @@ export default {

let peerMarker = prefixSelector(config('prefix'), '.peer')
for (let variant of pseudoVariants) {
let [variantName, state] = Array.isArray(variant) ? variant : [variant, variant]
let [variantName, state] = Array.isArray(variant) ? variant : [variant, `:${variant}`]
let peerVariantName = `peer-${variantName}`

addVariant(
Expand All @@ -221,7 +226,7 @@ export default {
return null
}

return applyPseudoToMarker(variantSelector, peerMarker, state, (marker, selector) =>
return applyStateToMarker(variantSelector, peerMarker, state, (marker, selector) =>
selector.trim().startsWith('~') ? `${marker}${selector}` : `${marker} ~ ${selector}`
)
})
Expand Down
29 changes: 15 additions & 14 deletions src/util/pluginUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,31 @@ import {
lineWidth,
} from './dataTypes'

export function applyPseudoToMarker(selector, marker, state, join) {
let states = [state]
export function applyStateToMarker(selector, marker, state, join) {
let markerIdx = selector.search(new RegExp(`${marker}[:[]`))

let markerIdx = selector.indexOf(marker + ':')

if (markerIdx !== -1) {
let existingMarker = selector.slice(markerIdx, selector.indexOf(' ', markerIdx))

states = states.concat(
selector.slice(markerIdx + marker.length + 1, existingMarker.length).split(':')
)

selector = selector.replace(existingMarker, '')
if (markerIdx === -1) {
return join(marker + state, selector)
}

return join(`${[marker, ...states].join(':')}`, selector)
let markerSelector = selector.slice(markerIdx, selector.indexOf(' ', markerIdx))

return join(
marker + state + markerSelector.slice(markerIdx + marker.length),
selector.replace(markerSelector, '')
)
}

export function updateAllClasses(selectors, updateClass) {
let parser = selectorParser((selectors) => {
selectors.walkClasses((sel) => {
let updatedClass = updateClass(sel.value, {
withAttr(className, attr) {
sel.parent.insertAfter(sel, selectorParser.attribute({ attribute: attr.slice(1, -1) }))
return className
},
withPseudo(className, pseudo) {
sel.parent.insertAfter(sel, selectorParser.pseudo({ value: `${pseudo}` }))
sel.parent.insertAfter(sel, selectorParser.pseudo({ value: pseudo }))
return className
},
})
Expand Down
21 changes: 21 additions & 0 deletions tests/variants.test.css
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
}
.open\:bg-red-200[open] {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
}
.default\:shadow-md:default {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
Expand Down Expand Up @@ -201,6 +205,10 @@
--tw-bg-opacity: 1;
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
}
.open\:hover\:bg-red-200[open]:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
}
.focus\:shadow-md:focus {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
Expand Down Expand Up @@ -276,6 +284,10 @@
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
}
.group[open] .group-open\:bg-red-200 {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
}
.group:default .group-default\:shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
Expand Down Expand Up @@ -346,11 +358,20 @@
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
}
.group[open]:hover .group-open\:group-hover\:space-x-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
}
.group:focus .group-focus\:shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
}
.group[open]:focus .group-open\:group-focus\:bg-red-200 {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity));
}
.group:focus:hover .group-focus\:group-hover\:shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -1px rgb(0 0 0 / 0.06);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
Expand Down
5 changes: 5 additions & 0 deletions tests/variants.test.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<div class="disabled:shadow-md"></div>
<div class="active:shadow-md"></div>
<div class="target:shadow-md"></div>
<div class="open:bg-red-200"></div>
<div class="visited:shadow-md"></div>
<div class="default:shadow-md"></div>
<div class="checked:shadow-md"></div>
Expand Down Expand Up @@ -50,6 +51,7 @@
<div class="after:flex after:uppercase"></div>

<!-- Group variants -->
<div class="group-open:bg-red-200"></div>
<div class="group-first:shadow-md"></div>
<div class="group-last:shadow-md"></div>
<div class="group-only:shadow-md"></div>
Expand Down Expand Up @@ -128,6 +130,7 @@
<div class="2xl:shadow-md"></div>

<!-- Stacked variants -->
<div class="open:hover:bg-red-200"></div>
<div class="file:hover:bg-blue-600"></div>
<div class="focus:hover:shadow-md"></div>
<div class="sm:active:shadow-md"></div>
Expand All @@ -137,6 +140,8 @@
<div class="2xl:dark:motion-safe:focus-within:shadow-md"></div>

<!-- Stacked group variants -->
<div class="group-open:group-focus:bg-red-200"></div>
<div class="group-open:group-hover:space-x-2"></div>
<div class="group-focus:group-hover:shadow-md"></div>
<div class="group-disabled:group-focus:group-hover:shadow-md"></div>
<div class="dark:group-disabled:group-focus:group-hover:shadow-md"></div>
Expand Down

0 comments on commit 8004917

Please sign in to comment.