diff --git a/package.json b/package.json index aaa5aee..354c5bc 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "trailingComma": "es5" }, "scripts": { + "test": "jest", "prepublishOnly": "node scripts/build.js" }, "peerDependencies": { @@ -22,7 +23,9 @@ "devDependencies": { "autoprefixer": "10", "clean-css": "^4.2.1", + "jest": "^27.2.4", "postcss": "^8.2.4", - "tailwindcss": "^2.0.2" + "tailwindcss": "^3.0.0-alpha.1", + "tailwindcss-v2": "npm:tailwindcss@^2.2.16" } } diff --git a/src/index.js b/src/index.js index 572fefb..a217a70 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,62 @@ const plugin = require('tailwindcss/plugin') +const baseStyles = { + position: 'relative', + paddingBottom: `calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)`, +} + +const childStyles = { + position: 'absolute', + height: '100%', + width: '100%', + top: '0', + right: '0', + bottom: '0', + left: '0', +} + +const noneComponent = { + '.aspect-none': { + position: 'static', + paddingBottom: '0', + }, + '.aspect-none > *': { + position: 'static', + height: 'auto', + width: 'auto', + top: 'auto', + right: 'auto', + bottom: 'auto', + left: 'auto', + }, +} + const aspectRatio = plugin( - function ({ addComponents, theme, variants, e }) { + function ({ addComponents, matchComponents, theme, variants, e }) { const values = theme('aspectRatio') + if (matchComponents) { + matchComponents( + { + 'aspect-w': (value) => [ + { + ...baseStyles, + '--tw-aspect-w': value, + }, + { + '> *': childStyles, + }, + ], + 'aspect-h': (value) => ({ '--tw-aspect-h': value }), + }, + { values } + ) + + addComponents(noneComponent) + + return + } + const baseSelectors = Object.entries(values) .map(([key, value]) => { return `.${e(`aspect-w-${key}`)}` @@ -19,33 +72,10 @@ const aspectRatio = plugin( addComponents( [ { - [baseSelectors]: { - position: 'relative', - paddingBottom: `calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%)`, - }, - [childSelectors]: { - position: 'absolute', - height: '100%', - width: '100%', - top: '0', - right: '0', - bottom: '0', - left: '0', - }, - '.aspect-none': { - position: 'static', - paddingBottom: '0', - }, - '.aspect-none > *': { - position: 'static', - height: 'auto', - width: 'auto', - top: 'auto', - right: 'auto', - bottom: 'auto', - left: 'auto', - }, + [baseSelectors]: baseStyles, + [childSelectors]: childStyles, }, + noneComponent, Object.entries(values).map(([key, value]) => { return { [`.${e(`aspect-w-${key}`)}`]: { diff --git a/tests/test.js b/tests/test.js new file mode 100644 index 0000000..0142395 --- /dev/null +++ b/tests/test.js @@ -0,0 +1,157 @@ +const postcss = require('postcss') + +let expectedV3 = ` +.aspect-w-1 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 1 +} +.aspect-w-1 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-w-2 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 2 +} +.aspect-w-2 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-h-2 { + --tw-aspect-h: 2 +} +.aspect-w-\\[123\\] { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: 123 +} +.aspect-w-\\[123\\] > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-w-\\[var\\(--width\\)\\] { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%); + --tw-aspect-w: var(--width) +} +.aspect-w-\\[var\\(--width\\)\\] > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} +.aspect-h-\\[123\\] { + --tw-aspect-h: 123 +} +.aspect-h-\\[var\\(--height\\)\\] { + --tw-aspect-h: var(--height) +} +.aspect-none { + position: static; + padding-bottom: 0 +} +.aspect-none > * { + position: static; + height: auto; + width: auto; + top: auto; + right: auto; + bottom: auto; + left: auto +} +` + +it('v3', () => { + let css = postcss([ + require('tailwindcss')({ + content: [ + { + raw: 'aspect-none aspect-w-1 aspect-w-2 aspect-h-2 aspect-w-[123] aspect-w-[var(--width)] aspect-h-[123] aspect-h-[var(--height)]', + }, + ], + plugins: [require('../')], + }), + ]).process('@tailwind components').css + + expect(css).toBe(expectedV3.trim()) +}) + +let expectedV2 = ` +.aspect-w-1, +.aspect-w-2 { + position: relative; + padding-bottom: calc(var(--tw-aspect-h) / var(--tw-aspect-w) * 100%) +} + +.aspect-w-1 > *, +.aspect-w-2 > * { + position: absolute; + height: 100%; + width: 100%; + top: 0; + right: 0; + bottom: 0; + left: 0 +} + +.aspect-none { + position: static; + padding-bottom: 0 +} + +.aspect-none > * { + position: static; + height: auto; + width: auto; + top: auto; + right: auto; + bottom: auto; + left: auto +} + +.aspect-w-1 { + --tw-aspect-w: 1 +} + +.aspect-w-2 { + --tw-aspect-w: 2 +} + +.aspect-h-2 { + --tw-aspect-h: 2 +} +` + +it('v2', () => { + postcss([ + require('tailwindcss-v2')({ + purge: { enabled: true, content: [{ raw: 'aspect-none aspect-w-1 aspect-w-2 aspect-h-2' }] }, + variants: [], + plugins: [require('../')], + }), + ]) + .process('@tailwind components', { from: undefined }) + .then(({ css }) => { + expect(css).toBe(expectedV2.trim()) + }) +})