diff --git a/src/corePlugins.js b/src/corePlugins.js index f3f04a638ed2..6d2dda708982 100644 --- a/src/corePlugins.js +++ b/src/corePlugins.js @@ -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, @@ -128,11 +128,11 @@ 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', @@ -140,6 +140,7 @@ export default { // State 'visited', 'target', + ['open', '[open]'], // Forms 'default', @@ -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( @@ -194,7 +199,7 @@ export default { return null } - return applyPseudoToMarker( + return applyStateToMarker( variantSelector, groupMarker, state, @@ -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( @@ -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}` ) }) diff --git a/src/util/pluginUtils.js b/src/util/pluginUtils.js index 9fdbda93b381..4fa1bdf3ffe1 100644 --- a/src/util/pluginUtils.js +++ b/src/util/pluginUtils.js @@ -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 }, }) diff --git a/tests/variants.test.css b/tests/variants.test.css index 41e1b08f64e6..7bff0c6e072d 100644 --- a/tests/variants.test.css +++ b/tests/variants.test.css @@ -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), @@ -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), @@ -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), @@ -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), diff --git a/tests/variants.test.html b/tests/variants.test.html index 70e1c1409c4d..335ce5375a80 100644 --- a/tests/variants.test.html +++ b/tests/variants.test.html @@ -22,6 +22,7 @@
+
@@ -50,6 +51,7 @@
+
@@ -128,6 +130,7 @@
+
@@ -137,6 +140,8 @@
+
+