diff --git a/jest/content/iteration-count.html b/jest/content/iteration-count.html index 51f10b2..e7dfac2 100644 --- a/jest/content/iteration-count.html +++ b/jest/content/iteration-count.html @@ -1,3 +1,4 @@
-
+
+
diff --git a/jest/customMatchers.js b/jest/customMatchers.js new file mode 100644 index 0000000..ef91523 --- /dev/null +++ b/jest/customMatchers.js @@ -0,0 +1,24 @@ +expect.extend({ + toIncludeAll(received, expected) { + function stripped(str) { + return str.replace(/\s/g, '').replace(/;/g, '') + } + + const receivedStripped = stripped(received) + + const pass = Array.isArray(expected) && expected.every(value => receivedStripped.includes(stripped(value))) + + return { + pass, + message: () => pass + ? this.utils.matcherHint('.not.toIncludeAll') + + '\n\n' + + `Expected not to have all of: ${this.utils.printExpected(received)}\n` + + `Received: ${this.utils.printReceived(expected)}` + : this.utils.matcherHint('.toIncludeAll') + + '\n\n' + + `Expected to have all of: ${this.utils.printExpected(expected)}\n` + + `Received: ${this.utils.printReceived(received)}`, + } + }, +}) diff --git a/jest/index.test.js b/jest/index.test.js index 4abf6d1..0c3b864 100644 --- a/jest/index.test.js +++ b/jest/index.test.js @@ -2,151 +2,104 @@ const path = require('path') const postcss = require('postcss') const tailwindcss = require('@tailwindcss/postcss') -async function run(file) { +async function run(file, options = {}) { const { currentTestName } = expect.getState() - const result = await postcss(tailwindcss()).process(` - @import 'tailwindcss/utilities' source(none); - @plugin './../src/'; - @source './${file}'; - `, { + const config = [ + options.scope + ? `@import "tailwindcss/${options.scope}" source(none);` + : '@import "tailwindcss" source(none);', + options?.importType === 'legacy' + ? '@plugin "./../src/";' + : '@import "./../src/";', + `@source "./${file}";`, + ].join('\n') + + const result = await postcss(tailwindcss()).process(config, { from: `${path.resolve(__filename)}?test=${currentTestName}`, }) - return result.css.replace(/^\/\*!.*?\n/, '').trim() + return result.css } it('generates `delay` utilities', async () => { - expect(await run('content/delay.html')).toMatchInlineSnapshot(` - ".animate-delay-75 { - --tw-animate-delay: 75ms; - animation-delay: var(--tw-animate-delay); - } - .animate-delay-333 { - --tw-animate-delay: 333ms; - animation-delay: var(--tw-animate-delay); - } - .animate-delay-\\[666ms\\] { - --tw-animate-delay: 666ms; - animation-delay: var(--tw-animate-delay); - }" - `) + expect(await run('content/delay.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-delay-75 { animation-delay: 75ms; }', + '.animate-delay-333 { animation-delay: 333ms; }', + '.animate-delay-\\[666ms\\] { animation-delay: 666ms; }', + ]) }) it('generates `duration` utilities', async () => { - expect(await run('content/duration.html')).toMatchInlineSnapshot(` - ".animate-duration-75 { - --tw-animate-duration: 75ms; - animation-duration: var(--tw-animate-duration); - } - .animate-duration-333 { - --tw-animate-duration: 333ms; - animation-duration: var(--tw-animate-duration); - } - .animate-duration-\\[666ms\\] { - --tw-animate-duration: 666ms; - animation-duration: var(--tw-animate-duration); - }" - `) + expect(await run('content/duration.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-duration-75 { animation-duration: 75ms; }', + '.animate-duration-333 { animation-duration: 333ms; }', + '.animate-duration-\\[666ms\\] { animation-duration: 666ms; }', + ]) }) it('generates `direction` utilities', async () => { - expect(await run('content/direction.html')).toMatchInlineSnapshot(` - ".animate-normal { - --tw-animate-direction: normal; - animation-direction: var(--tw-animate-direction); - } - .animate-reverse { - --tw-animate-direction: reverse; - animation-direction: var(--tw-animate-direction); - }" - `) + expect(await run('content/direction.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-normal { animation-direction: normal; }', + '.animate-reverse { animation-direction: reverse; }', + ]) }) it('generates `fill-mode` utilities', async () => { - expect(await run('content/fill-mode.html')).toMatchInlineSnapshot(` - ".animate-fill-both { - --tw-animate-fill: both; - animation-fill-mode: var(--tw-animate-fill); - } - .animate-fill-none { - --tw-animate-fill: normal; - animation-fill-mode: var(--tw-animate-fill); - }" - `) + expect(await run('content/fill-mode.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-fill-both { animation-fill-mode: both; }', + '.animate-fill-none { animation-fill-mode: normal; }', + ]) }) it('generates `iteration-count` utilities', async () => { - expect(await run('content/iteration-count.html')).toMatchInlineSnapshot(` - ".animate-infinite { - --tw-animate-iteration: infinite; - animation-iteration-count: var(--tw-animate-iteration); - } - .animate-iteration-\\[7\\] { - --tw-animate-iteration: 7; - animation-iteration-count: var(--tw-animate-iteration); - } - .animate-once { - --tw-animate-iteration: 1; - animation-iteration-count: var(--tw-animate-iteration); - }" - `) + expect(await run('content/iteration-count.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-infinite { animation-iteration-count: infinite; }', + '.animate-once { animation-iteration-count: 1; }', + '.animate-iteration-7 { animation-iteration-count: 7; }', + '.animate-iteration-\\[14\\] { animation-iteration-count: 14; }', + ]) }) it('generates `play-state` utilities', async () => { - expect(await run('content/play-state.html')).toMatchInlineSnapshot(` - ".animate-play { - --tw-animate-state: running; - animation-play-state: var(--tw-animate-state); - } - .animate-stop { - --tw-animate-state: paused; - animation-play-state: var(--tw-animate-state); - }" - `) + expect(await run('content/play-state.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-play { animation-play-state: running; }', + '.animate-stop { animation-play-state: paused; }', + ]) }) it('generates `timing-function` utilities', async () => { - expect(await run('content/timing-function.html')).toMatchInlineSnapshot(` - ".animate-ease { - --tw-animate-easing: ease; - animation-timing-function: var(--tw-animate-easing); - } - .animate-ease-\\[cubic-bezier\\(1\\,0\\.66\\,0\\.33\\,0\\)\\] { - --tw-animate-easing: cubic-bezier(1,0.66,0.33,0); - animation-timing-function: var(--tw-animate-easing); - } - .animate-ease-linear { - --tw-animate-easing: linear; - animation-timing-function: var(--tw-animate-easing); - }" - `) + expect(await run('content/timing-function.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-ease { animation-timing-function: ease; }', + '.animate-ease-linear { animation-timing-function: linear; }', + '.animate-ease-\\[cubic-bezier\\(1\\,0\\.66\\,0\\.33\\,0\\)\\] { animation-timing-function: cubic-bezier(1,0.66,0.33,0); }', + ]) }) it('generates `composition` utilities', async () => { - expect(await run('content/composition.html')).toMatchInlineSnapshot(` - ".animate-accumulate { - --tw-animate-composition: accumulate; - animation-composition: var(--tw-animate-composition); - } - .animate-add { - --tw-animate-composition: add; - animation-composition: var(--tw-animate-composition); - } - .animate-replace { - --tw-animate-composition: replace; - animation-composition: var(--tw-animate-composition); - }" - `) + expect(await run('content/composition.html', { scope: 'utilities' })).toIncludeAll([ + '.animate-add { animation-composition: add; }', + '.animate-replace { animation-composition: replace; }', + '.animate-accumulate { animation-composition: accumulate; }', + ]) +}) + +it('generates predefined animations for modern import', async () => { + expect(await run('content/predefined-animations.html', { importType: 'modern' })).toIncludeAll([ + '.animate-fade { animation: var(--animate-fade); }', + '--animate-fade: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both;', + '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', + '.animate-spin { animation: var(--animate-spin); }', + '--animate-spin: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite;', + '@keyframes spin { to { transform: rotate(360deg); }}', + ]) }) -it('generates predefined animations', async () => { - expect(await run('content/predefined-animations.html')).toMatchInlineSnapshot(` - ".animate-fade { - animation: fade var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both); - } - .animate-spin { - animation: spin var(--tw-animate-duration, 1s) var(--tw-animate-easing, linear) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, infinite) var(--tw-animate-fill, none); - }" - `) +it('generates predefined animations for legacy import', async () => { + expect(await run('content/predefined-animations.html', { importType: 'legacy' })).toIncludeAll([ + '.animate-fade { animation: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; }', + '@keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; }}', + '.animate-spin { animation: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite; }', + '@keyframes spin { to { transform: rotate(360deg); }}', + ]) }) diff --git a/package.json b/package.json index 0ab1d6b..87e766b 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,11 @@ ], "main": "src/index.js", "types": "src/index.d.ts", + "style": "src/index.css", "scripts": { "watch": "npm run dev -- -w", "dev": "npx @tailwindcss/cli -i resources/app.css -o public/app.css", - "test": "jest", + "test": "jest --setupFilesAfterEnv '/jest/customMatchers.js'", "lint": "npx eslint {src,jest}/**", "lint:fix": "npx eslint {src,jest}/** --fix" }, @@ -39,7 +40,6 @@ "eslint-plugin-jest": "^28.11.0", "jest": "^29.7.0", "postcss": "^8.5.1", - "prettier": "^2.8.8", "tailwindcss": "^4.0.0" } } diff --git a/public/index.html b/public/index.html index 22099c1..3934332 100644 --- a/public/index.html +++ b/public/index.html @@ -8,7 +8,7 @@ -

+

Test file for development

diff --git a/resources/app.css b/resources/app.css index 29401e4..abbca83 100644 --- a/resources/app.css +++ b/resources/app.css @@ -1,3 +1,5 @@ -@import "tailwindcss" source("../public"); +@import "tailwindcss" source(none); -@plugin "../src"; +@import "../src/"; + +@source "../public/index.html" diff --git a/src/compat/composition.js b/src/compat/composition.js new file mode 100644 index 0000000..1a27e50 --- /dev/null +++ b/src/compat/composition.js @@ -0,0 +1,13 @@ +module.exports = ({ addUtilities }) => { + addUtilities({ + '.animate-replace': { + 'animation-composition': 'replace', + }, + '.animate-add': { + 'animation-composition': 'add', + }, + '.animate-accumulate': { + 'animation-composition': 'accumulate', + }, + }) +} diff --git a/src/utilities/delay.js b/src/compat/delay.js similarity index 62% rename from src/utilities/delay.js rename to src/compat/delay.js index 2d032ad..b11b6b9 100644 --- a/src/utilities/delay.js +++ b/src/compat/delay.js @@ -1,7 +1,6 @@ module.exports = ({ matchUtilities, theme }) => matchUtilities({ 'animate-delay': value => ({ - '--tw-animate-delay': value, - 'animation-delay': 'var(--tw-animate-delay)', + 'animation-delay': value, }), }, { values: theme('animationDelay'), diff --git a/src/compat/direction.js b/src/compat/direction.js new file mode 100644 index 0000000..f4b848e --- /dev/null +++ b/src/compat/direction.js @@ -0,0 +1,14 @@ +module.exports = ({ addUtilities }) => addUtilities({ + '.animate-normal': { + 'animation-direction': 'normal', + }, + '.animate-reverse': { + 'animation-direction': 'reverse', + }, + '.animate-alternate': { + 'animation-direction': 'alternate', + }, + '.animate-alternate-reverse': { + 'animation-direction': 'alternate-reverse', + }, +}) diff --git a/src/utilities/duration.js b/src/compat/duration.js similarity index 61% rename from src/utilities/duration.js rename to src/compat/duration.js index 0a2f9e1..43247dc 100644 --- a/src/utilities/duration.js +++ b/src/compat/duration.js @@ -1,7 +1,6 @@ module.exports = ({ matchUtilities, theme }) => matchUtilities({ 'animate-duration': value => ({ - '--tw-animate-duration': value, - 'animation-duration': 'var(--tw-animate-duration)', + 'animation-duration': value, }), }, { values: theme('animationDuration'), diff --git a/src/compat/fill-mode.js b/src/compat/fill-mode.js new file mode 100644 index 0000000..99bd95a --- /dev/null +++ b/src/compat/fill-mode.js @@ -0,0 +1,14 @@ +module.exports = ({ addUtilities }) => addUtilities({ + '.animate-fill-none': { + 'animation-fill-mode': 'normal', + }, + '.animate-fill-forwards': { + 'animation-fill-mode': 'forwards', + }, + '.animate-fill-backwards': { + 'animation-fill-mode': 'backwards', + }, + '.animate-fill-both': { + 'animation-fill-mode': 'both', + }, +}) diff --git a/src/compat/iteration-count.js b/src/compat/iteration-count.js new file mode 100644 index 0000000..efa7229 --- /dev/null +++ b/src/compat/iteration-count.js @@ -0,0 +1,24 @@ +module.exports = ({ addUtilities, matchUtilities, theme }) => { + addUtilities({ + '.animate-infinite': { + 'animation-iteration-count': 'infinite', + }, + '.animate-once': { + 'animation-iteration-count': '1', + }, + '.animate-twice': { + 'animation-iteration-count': '2', + }, + '.animate-thrice': { + 'animation-iteration-count': '3', + }, + }) + + matchUtilities({ + 'animate-iteration': value => ({ + 'animation-iteration-count': value, + }), + }, { + values: theme('animationIteration'), + }) +} diff --git a/src/compat/play-state.js b/src/compat/play-state.js new file mode 100644 index 0000000..8e86961 --- /dev/null +++ b/src/compat/play-state.js @@ -0,0 +1,14 @@ +module.exports = ({ addUtilities }) => addUtilities({ + '.animate-run': { + 'animation-play-state': 'running', + }, + '.animate-play': { + 'animation-play-state': 'running', + }, + '.animate-stop': { + 'animation-play-state': 'paused', + }, + '.animate-pause': { + 'animation-play-state': 'paused', + }, +}) diff --git a/src/theme.js b/src/compat/theme.js similarity index 56% rename from src/theme.js rename to src/compat/theme.js index 169461d..4bbe738 100644 --- a/src/theme.js +++ b/src/compat/theme.js @@ -12,10 +12,18 @@ const bareMilliseconds = { } } +const bareIntegers = { + __BARE_VALUE__: (value) => { + if (isPositiveInteger(value.value)) { + return value.value + } + } +} + module.exports = { extend: { animationDelay: { - none: '0ms', + none: '0s', 0: '0ms', 75: '75ms', 100: '100ms', @@ -28,6 +36,7 @@ module.exports = { ...bareMilliseconds, }, animationDuration: { + none: '0s', 75: '75ms', 100: '100ms', 150: '150ms', @@ -50,30 +59,28 @@ module.exports = { 'once': '1', 'twice': '2', 'thrice': '3', - 1: '1', - 2: '2', - 3: '3', + ...bareIntegers, }, animation: { - 'spin': 'spin var(--tw-animate-duration, 1s) var(--tw-animate-easing, linear) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, infinite) var(--tw-animate-fill, none)', - 'ping': 'ping var(--tw-animate-duration, 1s) var(--tw-animate-easing, cubic-bezier(0, 0, 0.2, 1)) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, infinite) var(--tw-animate-fill, none)', - 'pulse': 'pulse var(--tw-animate-duration, 2s) var(--tw-animate-easing, cubic-bezier(0.4, 0, 0.6, 1)) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, infinite) var(--tw-animate-fill, none)', - 'bounce': 'bounce var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, infinite) var(--tw-animate-fill, none)', - 'wiggle': 'wiggle var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'wiggle-more': 'wiggle-more var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'rotate-y': 'rotate-y var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'rotate-x': 'rotate-x var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'jump': 'jump var(--tw-animate-duration, 500ms) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'jump-in': 'jump-in var(--tw-animate-duration, 500ms) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'jump-out': 'jump-out var(--tw-animate-duration, 500ms) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'shake': 'shake var(--tw-animate-duration, 500ms) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'fade': 'fade var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'fade-down': 'fade-down var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'fade-up': 'fade-up var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'fade-left': 'fade-left var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'fade-right': 'fade-right var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'flip-up': 'flip-up var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', - 'flip-down': 'flip-down var(--tw-animate-duration, 1s) var(--tw-animate-easing, ease) var(--tw-animate-delay, 0s) var(--tw-animate-iteration, 1) var(--tw-animate-fill, both)', + 'spin': 'spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite', + 'ping': 'ping var(--default-animation-duration, 1s) var(--default-animation-timing-function, cubic-bezier(0, 0, 0.2, 1)) var(--default-animation-delay, 0s) infinite', + 'pulse': 'pulse var(--default-animation-duration, 2s) var(--default-animation-timing-function, cubic-bezier(0.4, 0, 0.6, 1)) var(--default-animation-delay, 0s) infinite', + 'bounce': 'bounce var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) infinite', + 'wiggle': 'wiggle var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'wiggle-more': 'wiggle-more var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'rotate-y': 'rotate-y var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'rotate-x': 'rotate-x var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'jump': 'jump var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'jump-in': 'jump-in var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'jump-out': 'jump-out var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'shake': 'shake var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'fade': 'fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'fade-down': 'fade-down var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'fade-up': 'fade-up var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'fade-left': 'fade-left var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'fade-right': 'fade-right var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'flip-up': 'flip-up var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', + 'flip-down': 'flip-down var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both', }, keyframes: { 'wiggle': { @@ -110,35 +117,35 @@ module.exports = { }, 'jump': { '0%, 100%': { - transform: 'scale(100%)', + transform: 'scale(1)', }, '10%': { - transform: 'scale(80%)', + transform: 'scale(0.8)', }, '50%': { - transform: 'scale(120%)', + transform: 'scale(1.2)', }, }, 'jump-in': { '0%': { - transform: 'scale(0%)', + transform: 'scale(0)', }, '80%': { - transform: 'scale(120%)', + transform: 'scale(1.2)', }, '100%': { - transform: 'scale(100%)', + transform: 'scale(1)', }, }, 'jump-out': { '0%': { - transform: 'scale(100%)', + transform: 'scale(1)', }, '20%': { - transform: 'scale(120%)', + transform: 'scale(1.2)', }, '100%': { - transform: 'scale(0%)', + transform: 'scale(0)', }, }, 'shake': { diff --git a/src/utilities/timingFunction.js b/src/compat/timing-function.js similarity index 60% rename from src/utilities/timingFunction.js rename to src/compat/timing-function.js index 1322a07..639f6e6 100644 --- a/src/utilities/timingFunction.js +++ b/src/compat/timing-function.js @@ -1,7 +1,6 @@ module.exports = ({ matchUtilities, theme }) => matchUtilities({ 'animate-ease': value => ({ - '--tw-animate-easing': value, - 'animation-timing-function': 'var(--tw-animate-easing)', + 'animation-timing-function': value, }), }, { values: theme('animationTimingFunction'), diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..0fe0020 --- /dev/null +++ b/src/index.css @@ -0,0 +1,9 @@ +@import './utilities/composition.css'; +@import './utilities/delay.css'; +@import './utilities/direction.css'; +@import './utilities/duration.css'; +@import './utilities/fill-mode.css'; +@import './utilities/iteration-count.css'; +@import './utilities/play-state.css'; +@import './utilities/predefined-animations.css'; +@import './utilities/timing-function.css'; diff --git a/src/index.js b/src/index.js index 742289f..fefcf1c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,14 @@ const plugin = require('tailwindcss/plugin') module.exports = plugin(api => { - require('./utilities/composition')(api) - require('./utilities/delay')(api) - require('./utilities/direction')(api) - require('./utilities/duration')(api) - require('./utilities/fillMode')(api) - require('./utilities/iterationCount')(api) - require('./utilities/playState')(api) - require('./utilities/timingFunction')(api) + require('./compat/composition')(api) + require('./compat/delay')(api) + require('./compat/direction')(api) + require('./compat/duration')(api) + require('./compat/fill-mode')(api) + require('./compat/iteration-count')(api) + require('./compat/play-state')(api) + require('./compat/timing-function')(api) }, { - theme: require('./theme'), + theme: require('./compat/theme'), }) diff --git a/src/utilities/composition.css b/src/utilities/composition.css new file mode 100644 index 0000000..622fc85 --- /dev/null +++ b/src/utilities/composition.css @@ -0,0 +1,11 @@ +@utility animate-replace { + animation-composition: replace; +} + +@utility animate-add { + animation-composition: add; +} + +@utility animate-accumulate { + animation-composition: accumulate; +} diff --git a/src/utilities/composition.js b/src/utilities/composition.js deleted file mode 100644 index 2cc11a6..0000000 --- a/src/utilities/composition.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = ({ addUtilities }) => { - addUtilities({ - '.animate-replace': { - '--tw-animate-composition': 'replace', - 'animation-composition': 'var(--tw-animate-composition)', - }, - '.animate-add': { - '--tw-animate-composition': 'add', - 'animation-composition': 'var(--tw-animate-composition)', - }, - '.animate-accumulate': { - '--tw-animate-composition': 'accumulate', - 'animation-composition': 'var(--tw-animate-composition)', - }, - }) -} diff --git a/src/utilities/delay.css b/src/utilities/delay.css new file mode 100644 index 0000000..5d26ea3 --- /dev/null +++ b/src/utilities/delay.css @@ -0,0 +1,8 @@ +@utility animate-delay-none { + animation-delay: 0s; +} + +@utility animate-delay-* { + animation-delay: --value(integer)ms; + animation-delay: --value([*]); +} diff --git a/src/utilities/direction.css b/src/utilities/direction.css new file mode 100644 index 0000000..4cc16c4 --- /dev/null +++ b/src/utilities/direction.css @@ -0,0 +1,15 @@ +@utility animate-normal { + animation-direction: normal; +} + +@utility animate-reverse { + animation-direction: reverse; +} + +@utility animate-alternate { + animation-direction: alternate; +} + +@utility animate-alternate-reverse { + animation-direction: alternate-reverse; +} diff --git a/src/utilities/direction.js b/src/utilities/direction.js deleted file mode 100644 index 8bd1aca..0000000 --- a/src/utilities/direction.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = ({ addUtilities }) => addUtilities({ - '.animate-normal': { - '--tw-animate-direction': 'normal', - 'animation-direction': 'var(--tw-animate-direction)', - }, - '.animate-reverse': { - '--tw-animate-direction': 'reverse', - 'animation-direction': 'var(--tw-animate-direction)', - }, - '.animate-alternate': { - '--tw-animate-direction': 'alternate', - 'animation-direction': 'var(--tw-animate-direction)', - }, - '.animate-alternate-reverse': { - '--tw-animate-direction': 'alternate-reverse', - 'animation-direction': 'var(--tw-animate-direction)', - }, -}) diff --git a/src/utilities/duration.css b/src/utilities/duration.css new file mode 100644 index 0000000..e0881d2 --- /dev/null +++ b/src/utilities/duration.css @@ -0,0 +1,8 @@ +@utility animate-duration-none { + animation-duration: 0s; +} + +@utility animate-duration-* { + animation-duration: --value(integer)ms; + animation-duration: --value([*]); +} diff --git a/src/utilities/fill-mode.css b/src/utilities/fill-mode.css new file mode 100644 index 0000000..5f90993 --- /dev/null +++ b/src/utilities/fill-mode.css @@ -0,0 +1,15 @@ +@utility animate-fill-none { + animation-fill-mode: normal; +} + +@utility animate-fill-forwards { + animation-fill-mode: forwards; +} + +@utility animate-fill-backwards { + animation-fill-mode: backwards; +} + +@utility animate-fill-both { + animation-fill-mode: both; +} diff --git a/src/utilities/fillMode.js b/src/utilities/fillMode.js deleted file mode 100644 index c77c7f4..0000000 --- a/src/utilities/fillMode.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = ({ addUtilities }) => addUtilities({ - '.animate-fill-none': { - '--tw-animate-fill': 'normal', - 'animation-fill-mode': 'var(--tw-animate-fill)', - }, - '.animate-fill-forwards': { - '--tw-animate-fill': 'forwards', - 'animation-fill-mode': 'var(--tw-animate-fill)', - }, - '.animate-fill-backwards': { - '--tw-animate-fill': 'backwards', - 'animation-fill-mode': 'var(--tw-animate-fill)', - }, - '.animate-fill-both': { - '--tw-animate-fill': 'both', - 'animation-fill-mode': 'var(--tw-animate-fill)', - }, -}) diff --git a/src/utilities/iteration-count.css b/src/utilities/iteration-count.css new file mode 100644 index 0000000..ab4ba85 --- /dev/null +++ b/src/utilities/iteration-count.css @@ -0,0 +1,19 @@ +@utility animate-infinite { + animation-iteration-count: infinite; +} + +@utility animate-once { + animation-iteration-count: 1; +} + +@utility animate-twice { + animation-iteration-count: 2; +} + +@utility animate-thrice { + animation-iteration-count: 3; +} + +@utility animate-iteration-* { + animation-iteration-count: --value(integer, [integer]); +} diff --git a/src/utilities/iterationCount.js b/src/utilities/iterationCount.js deleted file mode 100644 index 1aa4383..0000000 --- a/src/utilities/iterationCount.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = ({ addUtilities, matchUtilities, theme }) => { - addUtilities({ - '.animate-infinite': { - '--tw-animate-iteration': 'infinite', - 'animation-iteration-count': 'var(--tw-animate-iteration)', - }, - '.animate-once': { - '--tw-animate-iteration': '1', - 'animation-iteration-count': 'var(--tw-animate-iteration)', - }, - '.animate-twice': { - '--tw-animate-iteration': '2', - 'animation-iteration-count': 'var(--tw-animate-iteration)', - }, - '.animate-thrice': { - '--tw-animate-iteration': '3', - 'animation-iteration-count': 'var(--tw-animate-iteration)', - }, - }) - - matchUtilities({ - 'animate-iteration': value => ({ - '--tw-animate-iteration': value, - 'animation-iteration-count': 'var(--tw-animate-iteration)', - }), - }, { - values: theme('animationIteration'), - }) -} diff --git a/src/utilities/play-state.css b/src/utilities/play-state.css new file mode 100644 index 0000000..67d0716 --- /dev/null +++ b/src/utilities/play-state.css @@ -0,0 +1,15 @@ +@utility animate-run { + animation-play-state: running; +} + +@utility animate-play { + animation-play-state: running; +} + +@utility animate-stop { + animation-play-state: paused; +} + +@utility animate-pause { + animation-play-state: paused; +} diff --git a/src/utilities/playState.js b/src/utilities/playState.js deleted file mode 100644 index 54214b7..0000000 --- a/src/utilities/playState.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = ({ addUtilities }) => addUtilities({ - '.animate-run': { - '--tw-animate-state': 'running', - 'animation-play-state': 'var(--tw-animate-state)', - }, - '.animate-play': { - '--tw-animate-state': 'running', - 'animation-play-state': 'var(--tw-animate-state)', - }, - '.animate-stop': { - '--tw-animate-state': 'paused', - 'animation-play-state': 'var(--tw-animate-state)', - }, - '.animate-pause': { - '--tw-animate-state': 'paused', - 'animation-play-state': 'var(--tw-animate-state)', - }, -}) diff --git a/src/utilities/predefined-animations.css b/src/utilities/predefined-animations.css new file mode 100644 index 0000000..ef2be73 --- /dev/null +++ b/src/utilities/predefined-animations.css @@ -0,0 +1,187 @@ +@theme default { + --animate-spin: spin var(--default-animation-duration, 1s) var(--default-animation-timing-function, linear) var(--default-animation-delay, 0s) infinite; + --animate-ping: ping var(--default-animation-duration, 1s) var(--default-animation-timing-function, cubic-bezier(0, 0, 0.2, 1)) var(--default-animation-delay, 0s) infinite; + --animate-pulse: pulse var(--default-animation-duration, 2s) var(--default-animation-timing-function, cubic-bezier(0.4, 0, 0.6, 1)) var(--default-animation-delay, 0s) infinite; + --animate-bounce: bounce var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) infinite; + + --animate-wiggle: wiggle var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-wiggle-more: wiggle-more var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-rotate-y: rotate-y var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-rotate-x: rotate-x var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-jump: jump var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-jump-in: jump-in var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-jump-out: jump-out var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-shake: shake var(--default-animation-duration, 0.5s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-fade: fade var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-fade-down: fade-down var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-fade-up: fade-up var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-fade-left: fade-left var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-fade-right: fade-right var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-flip-up: flip-up var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + --animate-flip-down: flip-down var(--default-animation-duration, 1s) var(--default-animation-timing-function, ease) var(--default-animation-delay, 0s) both; + + @keyframes wiggle { + 0%, + 100% { + transform: rotate(-3deg); + } + 50% { + transform: rotate(3deg); + } + } + + @keyframes wiggle-more { + 0%, + 100% { + transform: rotate(-12deg); + } + 50% { + transform: rotate(12deg); + } + } + + @keyframes rotate-y { + 0% { + transform: rotateY(360deg); + } + 100% { + transform: rotateY(0); + } + } + + @keyframes rotate-x { + 0% { + transform: rotateX(360deg); + } + 100% { + transform: rotateX(0); + } + } + + @keyframes jump { + 0%, + 100% { + transform: scale(1); + } + 10% { + transform: scale(0.8); + } + 50% { + transform: scale(1.2); + } + } + + @keyframes jump-in { + 0% { + transform: scale(0); + } + 80% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } + } + + @keyframes jump-out { + 0% { + transform: scale(100%); + } + 20% { + transform: scale(120%); + } + 100% { + transform: scale(0); + } + } + + @keyframes shake { + 0% { + transform: translateX(0); + } + 25% { + transform: translateX(-1rem); + } + 75% { + transform: translateX(1rem); + } + 100% { + transform: translateX(0); + } + } + + @keyframes fade { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + + @keyframes fade-down { + 0% { + opacity: 0; + transform: translateY(-2rem); + } + 100% { + opacity: 1; + transform: translateY(0); + } + } + + @keyframes fade-up { + 0% { + opacity: 0; + transform: translateY(2rem); + } + 100% { + opacity: 1; + transform: translateY(0); + } + } + + @keyframes fade-left { + 0% { + opacity: 0; + transform: translateX(2rem); + } + 100% { + opacity: 1; + transform: translateX(0); + } + } + + @keyframes fade-right { + 0% { + opacity: 0; + transform: translateX(-2rem); + } + 100% { + opacity: 1; + transform: translateX(0); + } + } + + @keyframes flip-up { + 0% { + transform: rotateX(90deg); + transform-origin: bottom; + } + 100% { + transform: rotateX(0); + transform-origin: bottom; + } + } + + @keyframes flip-down { + 0% { + transform: rotateX(-90deg); + transform-origin: top; + } + 100% { + transform: rotateX(0); + transform-origin: top; + } + } +} diff --git a/src/utilities/timing-function.css b/src/utilities/timing-function.css new file mode 100644 index 0000000..4348ba0 --- /dev/null +++ b/src/utilities/timing-function.css @@ -0,0 +1,23 @@ +@utility animate-ease { + animation-timing-function: ease; +} + +@utility animate-ease-linear { + animation-timing-function: linear; +} + +@utility animate-ease-in { + animation-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +@utility animate-ease-out { + animation-timing-function: cubic-bezier(0, 0, 0.2, 1); +} + +@utility animate-ease-in-out { + animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} + +@utility animate-ease-* { + animation-timing-function: --value([*]); +}