diff --git a/src/pluginUtils.js b/src/pluginUtils.js index 7b400b6..3f15a0f 100644 --- a/src/pluginUtils.js +++ b/src/pluginUtils.js @@ -110,8 +110,15 @@ function asValue(modifier, lookup = {}, { validate = () => true, transform = (v) function asUnit(modifier, units, lookup = {}) { return asValue(modifier, lookup, { validate: (value) => { - let pattern = new RegExp(`.+(${units.join('|')})$`, 'g') - return value.match(pattern) !== null + let unitsPattern = `(?:${units.join('|')})` + return ( + new RegExp(`${unitsPattern}$`).test(value) || + new RegExp(`^calc\\(.+?${unitsPattern}`).test(value) + ) + }, + transform: (value) => { + // add spaces around operators inside calc() that do not follow an operator or ( + return value.replace(/(?<=^calc\(.+?)(? :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(20cm * var(--tw-space-x-reverse)); + margin-left: calc(20cm * calc(1 - var(--tw-space-x-reverse))); +} +.space-x-\[calc\(20\%-1cm\)\] > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(calc(20% - 1cm) * var(--tw-space-x-reverse)); + margin-left: calc(calc(20% - 1cm) * calc(1 - var(--tw-space-x-reverse))); +} +.border-\[2\.5px\] { + border-width: 2.5px; +} +.border-\[\#f00\] { + --tw-border-opacity: 1; + border-color: rgba(255, 0, 0, var(--tw-border-opacity)); +} +.bg-\[\#0f0\] { + --tw-bg-opacity: 1; + background-color: rgba(0, 255, 0, var(--tw-bg-opacity)); +} +.bg-\[\#ff0000\] { + --tw-bg-opacity: 1; + background-color: rgba(255, 0, 0, var(--tw-bg-opacity)); +} +.bg-\[\#0000ffcc\] { + background-color: #0000ffcc; +} +.bg-\[rgb\(123\,123\,123\)\] { + --tw-bg-opacity: 1; + background-color: rgba(123, 123, 123, var(--tw-bg-opacity)); +} +.bg-\[rgba\(123\,123\,123\,0\.5\)\] { + background-color: rgba(123, 123, 123, 0.5); +} +.bg-\[hsl\(0\,100\%\,50\%\)\] { + --tw-bg-opacity: 1; + background-color: rgba(255, 0, 0, var(--tw-bg-opacity)); +} +.bg-\[hsla\(0\,100\%\,50\%\,0\.3\)\] { + background-color: hsla(0, 100%, 50%, 0.3); +} +.bg-opacity-\[0\.11\] { + --tw-bg-opacity: 0.11; +} +.text-\[2\.23rem\] { + font-size: 2.23rem; +} diff --git a/tests/08-arbitrary-values.test.html b/tests/08-arbitrary-values.test.html new file mode 100644 index 0000000..68f9db4 --- /dev/null +++ b/tests/08-arbitrary-values.test.html @@ -0,0 +1,25 @@ + + + + + + + Title + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/tests/08-arbitrary-values.test.js b/tests/08-arbitrary-values.test.js new file mode 100644 index 0000000..cbf173c --- /dev/null +++ b/tests/08-arbitrary-values.test.js @@ -0,0 +1,30 @@ +const postcss = require('postcss') +const tailwind = require('../src/index.js') +const fs = require('fs') +const path = require('path') + +function run(input, config = {}) { + return postcss([tailwind(config)]).process(input, { from: path.resolve(__filename) }) +} + +test('arbitrary values', () => { + let config = { + purge: [path.resolve(__dirname, './08-arbitrary-values.test.html')], + corePlugins: { preflight: false }, + theme: {}, + plugins: [], + } + + let css = ` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + + return run(css, config).then((result) => { + let expectedPath = path.resolve(__dirname, './08-arbitrary-values.test.css') + let expected = fs.readFileSync(expectedPath, 'utf8') + + expect(result.css).toMatchCss(expected) + }) +})