diff --git a/__fixtures__/config/config.js b/__fixtures__/config/config.js index df10aaa5..3e7ecd8b 100644 --- a/__fixtures__/config/config.js +++ b/__fixtures__/config/config.js @@ -4,6 +4,8 @@ import tw from './macro' * Test the config matching is working correctly */ +tw`animate-zoom-.5` + tw`text-number` tw`text-purple` tw`text-purple-hyphen` diff --git a/__fixtures__/config/tailwind.config.js b/__fixtures__/config/tailwind.config.js index b9f783dd..0749123f 100644 --- a/__fixtures__/config/tailwind.config.js +++ b/__fixtures__/config/tailwind.config.js @@ -1,5 +1,8 @@ module.exports = { theme: { + animation: { + 'zoom-.5': 'zoom-.5 2s', + }, colors: { number: 0, purple: 'purple', diff --git a/__fixtures__/!screens.js b/__fixtures__/screens/screens.js similarity index 66% rename from __fixtures__/!screens.js rename to __fixtures__/screens/screens.js index a294d7e7..943cec46 100644 --- a/__fixtures__/!screens.js +++ b/__fixtures__/screens/screens.js @@ -5,3 +5,6 @@ tw`md:block` tw`lg:block` tw`xl:block` tw`2xl:block` +tw`2xl:block` + +tw`:font-bold` diff --git a/__fixtures__/screens/tailwind.config.js b/__fixtures__/screens/tailwind.config.js new file mode 100644 index 00000000..62208fa8 --- /dev/null +++ b/__fixtures__/screens/tailwind.config.js @@ -0,0 +1,10 @@ +module.exports = { + theme: { + extend: { + screens: { + '': { min: '500px' }, + }, + }, + }, +} diff --git a/__fixtures__/utiltiesSizing/height.js b/__fixtures__/utiltiesSizing/height.js index 41ac7f05..1346e9f7 100644 --- a/__fixtures__/utiltiesSizing/height.js +++ b/__fixtures__/utiltiesSizing/height.js @@ -64,3 +64,6 @@ tw`h-[32rem]` tw`h-[3.23rem]` tw`h-[calc(100%+1rem)]` tw`h-[var(--height)]` + +tw`h-[calc(100%-theme('spacing.16'))]` +tw`h-[calc(100%-theme("spacing.16"))]` diff --git a/__fixtures__/visitedOpacity/visitedOpacity.js b/__fixtures__/visitedOpacity/visitedOpacity.js new file mode 100644 index 00000000..efbfe3af --- /dev/null +++ b/__fixtures__/visitedOpacity/visitedOpacity.js @@ -0,0 +1,6 @@ +import tw from './macro' + +tw`visited:border-red-500 visited:bg-red-500 visited:text-red-500` +tw`visited:border-red-500/20 visited:bg-red-500/20 visited:text-red-500/20` +tw`visited:border-red-500/[20] visited:bg-red-500/[20] visited:text-red-500/[20]` +tw`visited:(border-red-500 border-opacity-50) visited:(bg-red-500 bg-opacity-50) visited:(text-red-500 text-opacity-50)` diff --git a/__snapshots__/plugin.test.js.snap b/__snapshots__/plugin.test.js.snap index 4901cdc0..285c9c8d 100644 --- a/__snapshots__/plugin.test.js.snap +++ b/__snapshots__/plugin.test.js.snap @@ -502,7 +502,6 @@ html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; --o-tab-size: 4; tab-size: 4; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } @@ -516,7 +515,6 @@ color: inherit; border-top-width: 1px; } abbr:where([title]) { --webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, h2, h3, h4, h5, h6 { @@ -978,47 +976,6 @@ const Component7 = () => ( ) -`; - -exports[`twin.macro !screens.js: !screens.js 1`] = ` - -import tw from './macro' - -tw\`sm:block\` -tw\`md:block\` -tw\`lg:block\` -tw\`xl:block\` -tw\`2xl:block\` - - ↓ ↓ ↓ ↓ ↓ ↓ - -;({ - '@media (min-width: 640px)': { - display: 'block', - }, -}) -;({ - '@media (min-width: 768px)': { - display: 'block', - }, -}) -;({ - '@media (min-width: 1024px)': { - display: 'block', - }, -}) -;({ - '@media (min-width: 1280px)': { - display: 'block', - }, -}) -;({ - '@media (min-width: 1536px)': { - display: 'block', - }, -}) - - `; exports[`twin.macro !variantGrouping.js: !variantGrouping.js 1`] = ` @@ -3541,7 +3498,6 @@ html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; --o-tab-size: 4; tab-size: 4; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } @@ -3557,7 +3513,6 @@ color: inherit; border-top-width: 1px; } abbr:where([title]) { --webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, h2, h3, h4, h5, h6 { @@ -3796,7 +3751,6 @@ src: url('./fonts/myfont.ttf'); lineHeight: '1.5', WebkitTextSizeAdjust: '100%', MozTabSize: '4', - OTabSize: '4', tabSize: '4', fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"', @@ -3813,7 +3767,6 @@ src: url('./fonts/myfont.ttf'); borderTopWidth: '1px', }, 'abbr:where([title])': { - WebkitTextDecoration: 'underline dotted', textDecoration: 'underline dotted', }, 'h1, h2, h3, h4, h5, h6': { @@ -4047,7 +4000,6 @@ theme\`keyframes\` lineHeight: '1.5', WebkitTextSizeAdjust: '100%', MozTabSize: '4', - OTabSize: '4', tabSize: '4', fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"', @@ -4062,7 +4014,6 @@ theme\`keyframes\` borderTopWidth: '1px', }, 'abbr:where([title])': { - WebkitTextDecoration: 'underline dotted', textDecoration: 'underline dotted', }, 'h1, h2, h3, h4, h5, h6': { @@ -20027,7 +19978,6 @@ html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; --o-tab-size: 4; tab-size: 4; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } @@ -20041,7 +19991,6 @@ color: inherit; border-top-width: 1px; } abbr:where([title]) { --webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, h2, h3, h4, h5, h6 { @@ -20512,6 +20461,8 @@ import tw from './macro' * Test the config matching is working correctly */ +tw\`animate-zoom-.5\` + tw\`text-number\` tw\`text-purple\` tw\`text-purple-hyphen\` @@ -20551,6 +20502,9 @@ tw\`font-customFontWeightAsNumber\` /** * Test the config matching is working correctly */ +;({ + animation: 'zoom-.5 2s', +}) ;({ color: '0', }) @@ -25817,72 +25771,40 @@ tw\`stacked-fractions\` }) ;({ '--tw-ordinal': 'ordinal', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-slashed-zero': 'slashed-zero', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-numeric-figure': 'lining-nums', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-numeric-figure': 'oldstyle-nums', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-numeric-spacing': 'proportional-nums', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-numeric-spacing': 'tabular-nums', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-numeric-fraction': 'diagonal-fractions', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', }) ;({ - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', '--tw-numeric-fraction': 'stacked-fractions', fontVariantNumeric: 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', @@ -26469,7 +26391,6 @@ const _GlobalStyles = () => ( line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; - -o-tab-size: 4; tab-size: 4; font-family: testSans, testSans2; } @@ -26483,7 +26404,6 @@ const _GlobalStyles = () => ( border-top-width: 1px; } abbr:where([title]) { - -webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, @@ -31356,6 +31276,9 @@ tw\`h-[3.23rem]\` tw\`h-[calc(100%+1rem)]\` tw\`h-[var(--height)]\` +tw\`h-[calc(100%-theme('spacing.16'))]\` +tw\`h-[calc(100%-theme("spacing.16"))]\` + ↓ ↓ ↓ ↓ ↓ ↓ // https://tailwindcss.com/docs/height @@ -31597,6 +31520,12 @@ tw\`h-[var(--height)]\` ;({ height: 'var(--height)', }) +;({ + height: 'calc(100%-4rem)', +}) +;({ + height: 'calc(100%-4rem)', +}) `; @@ -40769,7 +40698,6 @@ html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; --o-tab-size: 4; tab-size: 4; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; } @@ -40783,7 +40711,6 @@ color: inherit; border-top-width: 1px; } abbr:where([title]) { --webkit-text-decoration: underline dotted; text-decoration: underline dotted; } h1, h2, h3, h4, h5, h6 { @@ -46789,6 +46716,63 @@ tw\`not-sr-only\` }) +`; + +exports[`twin.macro screens.js: screens.js 1`] = ` + +import tw from './macro' + +tw\`sm:block\` +tw\`md:block\` +tw\`lg:block\` +tw\`xl:block\` +tw\`2xl:block\` +tw\`2xl:block\` + +tw\`:font-bold\` + + ↓ ↓ ↓ ↓ ↓ ↓ + +;({ + '@media (min-width: 640px)': { + display: 'block', + }, +}) +;({ + '@media (min-width: 768px)': { + display: 'block', + }, +}) +;({ + '@media (min-width: 1024px)': { + display: 'block', + }, +}) +;({ + '@media (min-width: 1280px)': { + display: 'block', + }, +}) +;({ + '@media (min-width: 1536px)': { + display: 'block', + }, +}) +;({ + '@media (min-width: 1536px)': { + display: 'block', + }, +}) +;({ + '@media (max-width: 399px)': { + textDecorationLine: 'underline', + }, + '@media (min-width: 500px)': { + fontWeight: '700', + }, +}) + + `; exports[`twin.macro scrollBehavior.js: scrollBehavior.js 1`] = ` @@ -51085,7 +51069,6 @@ const globals = global({ lineHeight: '1.5', WebkitTextSizeAdjust: '100%', MozTabSize: '4', - OTabSize: '4', tabSize: '4', fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"', @@ -51100,7 +51083,6 @@ const globals = global({ borderTopWidth: '1px', }, 'abbr:where([title])': { - WebkitTextDecoration: 'underline dotted', textDecoration: 'underline dotted', }, 'h1, h2, h3, h4, h5, h6': { @@ -59505,7 +59487,7 @@ tw\`transform-none\` transform: 'var(--tw-transform)', }) ;({ - '--tw-transform': + transform: 'translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))', }) ;({ @@ -59681,6 +59663,52 @@ tw\`invisible\` }) +`; + +exports[`twin.macro visitedOpacity.js: visitedOpacity.js 1`] = ` + +import tw from './macro' + +tw\`visited:border-red-500 visited:bg-red-500 visited:text-red-500\` +tw\`visited:border-red-500/20 visited:bg-red-500/20 visited:text-red-500/20\` +tw\`visited:border-red-500/[20] visited:bg-red-500/[20] visited:text-red-500/[20]\` +tw\`visited:(border-red-500 border-opacity-50) visited:(bg-red-500 bg-opacity-50) visited:(text-red-500 text-opacity-50)\` + + ↓ ↓ ↓ ↓ ↓ ↓ + +;({ + ':visited': { + borderColor: '#ef4444', + backgroundColor: '#ef4444', + color: '#ef4444', + }, +}) +;({ + ':visited': { + borderColor: '#ef4444', + backgroundColor: '#ef4444', + color: '#ef4444', + }, +}) +;({ + ':visited': { + borderColor: '#ef4444', + backgroundColor: '#ef4444', + color: '#ef4444', + }, +}) +;({ + ':visited': { + borderColor: '#ef4444', + '--tw-border-opacity': '0.5', + backgroundColor: '#ef4444', + color: '#ef4444', + '--tw-text-opacity': '0.5', + '--tw-bg-opacity': '0.5', + }, +}) + + `; exports[`twin.macro whitespace.js: whitespace.js 1`] = ` diff --git a/src/coerced.js b/src/coerced.js index e931e659..df71cc66 100644 --- a/src/coerced.js +++ b/src/coerced.js @@ -1,7 +1,6 @@ import deepMerge from 'lodash.merge' import { throwIf, - withAlpha, toAlpha, splitOnFirst, isSpaceSeparatedColor, @@ -50,12 +49,7 @@ const coercedTypeMap = { .map(p => typeof value === 'string' && value.startsWith('var(') ? null - : withAlpha({ - color: value, - property: p, - pieces, - ...(variable && { variable }), - }) + : toAlpha({ pieces, variable, property: p })(value, pieces.alpha) ) .filter(Boolean) diff --git a/src/config/corePlugins.js b/src/config/corePlugins.js index 5f665937..c4b780b9 100644 --- a/src/config/corePlugins.js +++ b/src/config/corePlugins.js @@ -1,15 +1,8 @@ // https://tailwindcss.com/docs/font-variant-numeric // This feature uses var+comment hacks to get around property stripping: // https://github.com/tailwindlabs/tailwindcss.com/issues/522#issuecomment-687667238 -const fontVariants = { - '--tw-ordinal': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-slashed-zero': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-figure': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-spacing': 'var(--tw-empty,/*!*/ /*!*/)', - '--tw-numeric-fraction': 'var(--tw-empty,/*!*/ /*!*/)', - fontVariantNumeric: - 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)', -} +const cssFontVariantNumericValue = + 'var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)' const cssFilterValue = [ 'var(--tw-blur)', @@ -413,7 +406,7 @@ export default { 'transform-gpu': { output: { - '--tw-transform': + transform: 'translate3d(var(--tw-translate-x), var(--tw-translate-y), 0) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))', }, }, @@ -1325,27 +1318,53 @@ export default { // https://tailwindcss.com/docs/font-variant-numeric 'normal-nums': { output: { fontVariantNumeric: 'normal' } }, - ordinal: { output: { ...fontVariants, '--tw-ordinal': 'ordinal' } }, + ordinal: { + output: { + '--tw-ordinal': 'ordinal', + fontVariantNumeric: cssFontVariantNumericValue, + }, + }, 'slashed-zero': { - output: { ...fontVariants, '--tw-slashed-zero': 'slashed-zero' }, + output: { + '--tw-slashed-zero': 'slashed-zero', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, 'lining-nums': { - output: { ...fontVariants, '--tw-numeric-figure': 'lining-nums' }, + output: { + '--tw-numeric-figure': 'lining-nums', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, 'oldstyle-nums': { - output: { ...fontVariants, '--tw-numeric-figure': 'oldstyle-nums' }, + output: { + '--tw-numeric-figure': 'oldstyle-nums', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, 'proportional-nums': { - output: { ...fontVariants, '--tw-numeric-spacing': 'proportional-nums' }, + output: { + '--tw-numeric-spacing': 'proportional-nums', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, 'tabular-nums': { - output: { ...fontVariants, '--tw-numeric-spacing': 'tabular-nums' }, + output: { + '--tw-numeric-spacing': 'tabular-nums', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, 'diagonal-fractions': { - output: { ...fontVariants, '--tw-numeric-fraction': 'diagonal-fractions' }, + output: { + '--tw-numeric-fraction': 'diagonal-fractions', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, 'stacked-fractions': { - output: { ...fontVariants, '--tw-numeric-fraction': 'stacked-fractions' }, + output: { + '--tw-numeric-fraction': 'stacked-fractions', + fontVariantNumeric: cssFontVariantNumericValue, + }, }, // https://tailwindcss.com/docs/line-height diff --git a/src/config/globalStyles.js b/src/config/globalStyles.js index 4695450d..3a961034 100644 --- a/src/config/globalStyles.js +++ b/src/config/globalStyles.js @@ -1,3 +1,4 @@ +// Reference: https://github.com/tailwindlabs/tailwindcss/blob/master/src/css/preflight.css export const globalPreflightStyles = ({ theme }) => ({ '*, ::before, ::after': { boxSizing: 'border-box', @@ -5,14 +6,11 @@ export const globalPreflightStyles = ({ theme }) => ({ borderStyle: 'solid', borderColor: theme`borderColor.DEFAULT` || 'currentColor', }, - '::before, ::after': { - '--tw-content': "''", - }, + '::before, ::after': { '--tw-content': "''" }, html: { lineHeight: '1.5', WebkitTextSizeAdjust: '100%', MozTabSize: '4', - OTabSize: '4', tabSize: '4', fontFamily: theme`fontFamily.sans` || @@ -20,10 +18,7 @@ export const globalPreflightStyles = ({ theme }) => ({ }, body: { margin: '0', lineHeight: 'inherit' }, hr: { height: '0', color: 'inherit', borderTopWidth: '1px' }, - 'abbr:where([title])': { - WebkitTextDecoration: 'underline dotted', - textDecoration: 'underline dotted', - }, + 'abbr:where([title])': { textDecoration: 'underline dotted' }, 'h1, h2, h3, h4, h5, h6': { fontSize: 'inherit', fontWeight: 'inherit' }, a: { color: 'inherit', textDecoration: 'inherit' }, 'b, strong': { fontWeight: 'bolder' }, diff --git a/src/handlers/arbitraryCss.js b/src/handlers/arbitraryCss.js index d4f253d9..6b7eea95 100644 --- a/src/handlers/arbitraryCss.js +++ b/src/handlers/arbitraryCss.js @@ -128,17 +128,18 @@ const getArbitraryStyle = ( return coercedConfigResult } -// Arbitrary values with a theme value, eg: tw`text - [theme(colors.red.500)]` +// Arbitrary values with a theme value, eg: tw`h-[calc(100%-theme('spacing.16'))]` const replaceThemeValue = (value, { theme }) => { - const themeMatch = value.match(/theme\('?([^']+)'?\)/) - if (!themeMatch) return value + const match = value.match(/theme\(["']?([^"']+)["']?\)/) + if (!match) return value - const themeValue = theme(themeMatch[1]) + const themeFunction = match[0] + const themeValue = theme(match[1]) throwIf(!themeValue, () => - logGeneralError(`No theme value found for “${themeMatch[1]}”`) + logGeneralError(`No theme value found for “${match[1]}”`) ) - return themeValue + return value.replace(themeFunction, themeValue) } export default props => { diff --git a/src/pieces.js b/src/pieces.js index c9cc7b57..9a276fa0 100644 --- a/src/pieces.js +++ b/src/pieces.js @@ -28,10 +28,7 @@ const fullVariantConfig = variantConfig({ createPeer, }) -/** - * Validate variants against the variants config key - */ -const validateVariants = ({ variants, state, ...rest }) => { +const getVariants = ({ variants, state, ...rest }) => { if (!variants) return [] const screens = get(state.config, ['theme', 'screens']) @@ -98,7 +95,7 @@ const splitVariants = ({ classNameRaw, state }) => { let className = classNameRaw while (variant !== null) { // Match arbitrary variants - variant = className.match(/^([\d_a-z-]+):|^\[.*?]:/) + variant = className.match(/^([\d<>_a-z-]+):|^\[.*?]:/) if (variant) { className = className.slice(variant[0].length) @@ -124,7 +121,7 @@ const splitVariants = ({ classNameRaw, state }) => { const hasGroupVariant = variantsList.some(v => v.startsWith('group-')) // Match the filtered variants - const variants = validateVariants({ + const variants = getVariants({ variants: variantsList, state, hasDarkVariant, @@ -140,6 +137,7 @@ const splitVariants = ({ classNameRaw, state }) => { className, variants, hasVariants, + hasVariantVisited: variants.includes(':visited'), } } diff --git a/src/utils/alpha.js b/src/utils/alpha.js index 18e5df59..b6bf30fb 100644 --- a/src/utils/alpha.js +++ b/src/utils/alpha.js @@ -21,11 +21,15 @@ const maybeAddAlpha = (value, { pieces, variable = '' }) => const toAlpha = ({ pieces, property, variable }) => (color, alpha, fallBackColor) => { - const newPieces = alpha ? { ...pieces, alpha, hasAlpha: true } : pieces + const newPieces = + (pieces.hasVariantVisited && { ...pieces, alpha: '', hasAlpha: false }) || + (alpha && { ...pieces, alpha, hasAlpha: true }) || + pieces + return withAlpha({ color, property, - variable, + ...(!pieces.hasVariantVisited && { variable }), pieces: newPieces, fallBackColor, }) diff --git a/src/variants.js b/src/variants.js index 1ffb1a9f..170607d9 100644 --- a/src/variants.js +++ b/src/variants.js @@ -102,7 +102,7 @@ function spreadVariantGroups( classes = classes.slice(start, end).trim() // variant / class / group - const reg = /(\[.*?]:|[\w-]+:)|([\w-./[\]]+!?)|\(|(\S+)/g + const reg = /(\[.*?]:|[\w-<>]+:)|([\w-./[\]]+!?)|\(|(\S+)/g let match const baseContext = context