const plugin = require('tailwindcss/plugin') /** @type {import('tailwindcss').Config} */ export default { theme: { extend: { betterStates: { action: '.action', }, }, }, plugins: [ plugin(function ({ matchVariant, theme, e }) { const values = { values: { DEFAULT: '', ...theme('betterStates', {}), }, } const selector = (state, prefix) => { return `${prefix ?? '&'}:${state}:not(:disabled)` } const maybeWrap = (state, prefix = '&', value) => { return ['', null, undefined].includes(value) ? selector(state, prefix) : `${prefix}:has(${selector(state, value)})` } const merge = (type, value, modifier, callback) => { const typeClass = modifier ? `.${type}\\/${e(modifier)}` : `.${type}` const append = type === 'group' ? ' &' : ' ~ &' return callback(value, `:merge(${typeClass})`).map((x) => `${x}${append}`) } // Hovered ________________________________________________________________________ const hovered = (value = null, prefix = '&') => [ maybeWrap('focus-visible', prefix, value), maybeWrap('hover', prefix, value), maybeWrap('has(:focus-visible)', prefix, value), ] matchVariant('hovered', (value) => hovered(value), values) matchVariant( 'group-hovered', (value, { modifier }) => merge('group', value, modifier, hovered), values, ) matchVariant( 'peer-hovered', (value, { modifier }) => merge('peer', value, modifier, hovered), values, ) // Pressed ________________________________________________________________________ const pressed = (value = null, prefix = '&') => [ maybeWrap('active', prefix, value), maybeWrap('has(:active)', prefix, value), `@media (hover: none) { ${maybeWrap('hover', prefix, value)} & }`, `@media (hover: none) { ${maybeWrap('focus-visible', prefix, value)} & }`, `@media (hover: none) { ${maybeWrap('has(:focus-visible)', prefix, value)} & }`, `@media (hover: none) { ${maybeWrap('focus', prefix, value)} & }`, `@media (hover: none) { ${maybeWrap('has(:focus)', prefix, value)} & }` ] matchVariant('pressed', (value) => pressed(value), values) matchVariant( 'group-pressed', (value, { modifier }) => merge('group', value, modifier, pressed), values, ) matchVariant( 'peer-pressed', (value, { modifier }) => merge('peer', value, modifier, pressed), values, ) }), ], }