From 8c832a35285dbf849f360c550e4c1f2736c03ff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Heidk=C3=A4mper?= Date: Mon, 27 May 2024 21:05:09 +0000 Subject: [PATCH] use css variables for animation properties --- .gitignore | 6 +- index.html | 13 + jest/index.test.js | 108 ++++-- package.json | 2 + public/tailwind.css | 587 ++++++++++++++++++++++++++++++++ src/theme.js | 34 +- src/utilities/composition.js | 43 ++- src/utilities/delay.js | 3 +- src/utilities/direction.js | 12 +- src/utilities/duration.js | 3 +- src/utilities/fillMode.js | 12 +- src/utilities/iterationCount.js | 12 +- src/utilities/playState.js | 12 +- src/utilities/timingFunction.js | 12 +- tailwind.config.js | 5 + 15 files changed, 790 insertions(+), 74 deletions(-) create mode 100644 index.html create mode 100644 public/tailwind.css create mode 100644 tailwind.config.js diff --git a/.gitignore b/.gitignore index 9416060..859cfa5 100644 --- a/.gitignore +++ b/.gitignore @@ -12,9 +12,11 @@ yarn-debug.log* yarn-error.log* # misc +/.build /.idea +/.nvmrc /.vscode -.nvmrc -.DS_Store +/dist *.local +.DS_Store .env diff --git a/index.html b/index.html new file mode 100644 index 0000000..a8dbb4a --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + tailwindcss-animated examples + + + + + + + diff --git a/jest/index.test.js b/jest/index.test.js index 92d41d1..78bcef9 100644 --- a/jest/index.test.js +++ b/jest/index.test.js @@ -6,7 +6,7 @@ function run(config, plugin = tailwindcss) { const { currentTestName } = expect.getState() config = { - plugins: [require('./../src/index.js')], + plugins: [require('./../src')], corePlugins: { preflight: false }, ...config, } @@ -21,8 +21,14 @@ it('should add `delay` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-delay-75 { animation-delay: 75ms; } - .animate-delay-\[333ms\] { animation-delay: 333ms; } + .animate-delay-75 { + --tw-animate-delay: 75ms; + animation-delay: var(--tw-animate-delay); + } + .animate-delay-\[333ms\] { + --tw-animate-delay: 333ms; + animation-delay: var(--tw-animate-delay); + } `) }) }) @@ -32,8 +38,14 @@ it('should add `duration` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-duration-75 { animation-duration: 75ms; } - .animate-duration-\[333ms\] { animation-duration: 333ms; } + .animate-duration-75 { + --tw-animate-duration: 75ms; + animation-duration: var(--tw-animate-duration); + } + .animate-duration-\[333ms\] { + --tw-animate-duration: 333ms; + animation-duration: var(--tw-animate-duration); + } `) }) }) @@ -43,8 +55,14 @@ it('should add `direction` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-normal { animation-direction: normal; } - .animate-reverse { animation-direction: reverse; } + .animate-normal { + --tw-animate-direction: normal; + animation-direction: var(--tw-animate-direction); + } + .animate-reverse { + --tw-animate-direction: reverse; + animation-direction: var(--tw-animate-direction); + } `) }) }) @@ -54,8 +72,14 @@ it('should add `fill-mode` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-fill-none { animation-fill-mode: normal; } - .animate-fill-both { animation-fill-mode: both; } + .animate-fill-none { + --tw-animate-fill: normal; + animation-fill-mode: var(--tw-animate-fill); + } + .animate-fill-both { + --tw-animate-fill: both; + animation-fill-mode: var(--tw-animate-fill); + } `) }) }) @@ -65,8 +89,14 @@ it('should add `iteration-count` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-infinite { animation-iteration-count: infinite; } - .animate-once { animation-iteration-count: 1; } + .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); + } `) }) }) @@ -76,8 +106,14 @@ it('should add `play-state` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-play { animation-play-state: running; } - .animate-stop { animation-play-state: paused; } + .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); + } `) }) }) @@ -87,8 +123,14 @@ it('should add `timing-function` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-ease-linear { animation-timing-function: linear; } - .animate-ease-in-out { animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); } + .animate-ease-linear { + --tw-animate-easing: linear; + animation-timing-function: var(--tw-animate-easing); + } + .animate-ease-in-out { + --tw-animate-easing: cubic-bezier(0.4, 0, 0.2, 1); + animation-timing-function: var(--tw-animate-easing); + } `) }) }) @@ -98,28 +140,46 @@ it('should add `composition` utilities', () => { content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` - .animate-replace { animation-composition: replace; } - .animate-add { animation-composition: add; } - .animate-accumulate { animation-composition: accumulate; } + .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); + } `) }) }) it('should add predefined animations', () => { return run({ - content: [{ raw: String.raw`
` }], + content: [{ raw: String.raw`
` }], }).then(result => { expect(result.css).toMatchCss(String.raw` @keyframes fade { 0% { opacity: 0; } 100% { opacity: 1; } } - .animate-fade { animation: fade 1s both; } - @keyframes wiggle { - 0%, 100% { transform: rotate(-3deg); } - 50% { transform: rotate(3deg); } + .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); + } + @keyframes spin { + to { transform: rotate(360deg); } + } + .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); + } + .animate-fade { + animation-composition: var(--tw-animate-composition); + } + .animate-spin { + animation-composition: var(--tw-animate-composition); } - .animate-wiggle { animation: wiggle 1s both; } `) }) }) diff --git a/package.json b/package.json index 94c5eb6..b177b22 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ ], "main": "src/index.js", "scripts": { + "watch": "npm run dev -- -w", + "dev": "tailwindcss -o public/tailwind.css", "test": "jest --setupFilesAfterEnv '/jest/customMatchers.js'", "eslint": "npx eslint {src,jest}/**", "eslint:fix": "npx eslint {src,jest}/** --fix" diff --git a/public/tailwind.css b/public/tailwind.css new file mode 100644 index 0000000..7bbdaf3 --- /dev/null +++ b/public/tailwind.css @@ -0,0 +1,587 @@ +/* +! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ + +html, +:host { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + -webkit-tap-highlight-color: transparent; + /* 7 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-feature-settings: normal; + /* 2 */ + font-variation-settings: normal; + /* 3 */ + font-size: 1em; + /* 4 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + letter-spacing: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} + +@keyframes fade { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +.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); +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.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); +} + +.animate-fade { + animation-composition: var(--tw-animate-composition); +} + +.animate-spin { + animation-composition: var(--tw-animate-composition); +} \ No newline at end of file diff --git a/src/theme.js b/src/theme.js index 2a57a53..7cd697a 100644 --- a/src/theme.js +++ b/src/theme.js @@ -150,21 +150,25 @@ module.exports = { }, }, animation: { - 'wiggle': 'wiggle 1s both', - 'wiggle-more': 'wiggle-more 1s both', - 'rotate-y': 'rotate-y 1s both', - 'rotate-x': 'rotate-x 1s both', - 'jump': 'jump .5s both', - 'jump-in': 'jump-in .5s both', - 'jump-out': 'jump-out .5s both', - 'shake': 'shake .5s both', - 'fade': 'fade 1s both', - 'fade-down': 'fade-down 1s both', - 'fade-up': 'fade-up 1s both', - 'fade-left': 'fade-left 1s both', - 'fade-right': 'fade-right 1s both', - 'flip-up': 'flip-up 1s both', - 'flip-down': 'flip-down 1s both', + '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)', }, animationDelay: { none: '0ms', diff --git a/src/utilities/composition.js b/src/utilities/composition.js index 42f8e59..ea89486 100644 --- a/src/utilities/composition.js +++ b/src/utilities/composition.js @@ -1,11 +1,32 @@ -module.exports = ({ addUtilities }) => addUtilities({ - '.animate-replace': { - 'animation-composition': 'replace', - }, - '.animate-add': { - 'animation-composition': 'add', - }, - '.animate-accumulate': { - 'animation-composition': 'accumulate', - }, -}) +module.exports = ({ addUtilities, matchUtilities, theme }) => { + 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)', + }, + }) + + matchUtilities({ + animate: value => { + const properties = value.split(/ +(?![^(]*\))/g) + + if (properties.includes('replace') || properties.includes('add') || properties.includes('accumulate')) { + return + } + + return { + 'animation-composition': 'var(--tw-animate-composition)', + } + }, + }, { + values: theme('animation'), + }) +} diff --git a/src/utilities/delay.js b/src/utilities/delay.js index b11b6b9..2d032ad 100644 --- a/src/utilities/delay.js +++ b/src/utilities/delay.js @@ -1,6 +1,7 @@ module.exports = ({ matchUtilities, theme }) => matchUtilities({ 'animate-delay': value => ({ - 'animation-delay': value, + '--tw-animate-delay': value, + 'animation-delay': 'var(--tw-animate-delay)', }), }, { values: theme('animationDelay'), diff --git a/src/utilities/direction.js b/src/utilities/direction.js index f4b848e..8bd1aca 100644 --- a/src/utilities/direction.js +++ b/src/utilities/direction.js @@ -1,14 +1,18 @@ module.exports = ({ addUtilities }) => addUtilities({ '.animate-normal': { - 'animation-direction': 'normal', + '--tw-animate-direction': 'normal', + 'animation-direction': 'var(--tw-animate-direction)', }, '.animate-reverse': { - 'animation-direction': 'reverse', + '--tw-animate-direction': 'reverse', + 'animation-direction': 'var(--tw-animate-direction)', }, '.animate-alternate': { - 'animation-direction': 'alternate', + '--tw-animate-direction': 'alternate', + 'animation-direction': 'var(--tw-animate-direction)', }, '.animate-alternate-reverse': { - 'animation-direction': 'alternate-reverse', + '--tw-animate-direction': 'alternate-reverse', + 'animation-direction': 'var(--tw-animate-direction)', }, }) diff --git a/src/utilities/duration.js b/src/utilities/duration.js index 43247dc..0a2f9e1 100644 --- a/src/utilities/duration.js +++ b/src/utilities/duration.js @@ -1,6 +1,7 @@ module.exports = ({ matchUtilities, theme }) => matchUtilities({ 'animate-duration': value => ({ - 'animation-duration': value, + '--tw-animate-duration': value, + 'animation-duration': 'var(--tw-animate-duration)', }), }, { values: theme('animationDuration'), diff --git a/src/utilities/fillMode.js b/src/utilities/fillMode.js index 99bd95a..c77c7f4 100644 --- a/src/utilities/fillMode.js +++ b/src/utilities/fillMode.js @@ -1,14 +1,18 @@ module.exports = ({ addUtilities }) => addUtilities({ '.animate-fill-none': { - 'animation-fill-mode': 'normal', + '--tw-animate-fill': 'normal', + 'animation-fill-mode': 'var(--tw-animate-fill)', }, '.animate-fill-forwards': { - 'animation-fill-mode': 'forwards', + '--tw-animate-fill': 'forwards', + 'animation-fill-mode': 'var(--tw-animate-fill)', }, '.animate-fill-backwards': { - 'animation-fill-mode': 'backwards', + '--tw-animate-fill': 'backwards', + 'animation-fill-mode': 'var(--tw-animate-fill)', }, '.animate-fill-both': { - 'animation-fill-mode': 'both', + '--tw-animate-fill': 'both', + 'animation-fill-mode': 'var(--tw-animate-fill)', }, }) diff --git a/src/utilities/iterationCount.js b/src/utilities/iterationCount.js index 3e4ccd0..60ad1b1 100644 --- a/src/utilities/iterationCount.js +++ b/src/utilities/iterationCount.js @@ -1,14 +1,18 @@ module.exports = ({ addUtilities }) => addUtilities({ '.animate-infinite': { - 'animation-iteration-count': 'infinite', + '--tw-animate-iteration': 'infinite', + 'animation-iteration-count': 'var(--tw-animate-iteration)', }, '.animate-once': { - 'animation-iteration-count': '1', + '--tw-animate-iteration': '1', + 'animation-iteration-count': 'var(--tw-animate-iteration)', }, '.animate-twice': { - 'animation-iteration-count': '2', + '--tw-animate-iteration': '2', + 'animation-iteration-count': 'var(--tw-animate-iteration)', }, '.animate-thrice': { - 'animation-iteration-count': '3', + '--tw-animate-iteration': '3', + 'animation-iteration-count': 'var(--tw-animate-iteration)', }, }) diff --git a/src/utilities/playState.js b/src/utilities/playState.js index 8e86961..54214b7 100644 --- a/src/utilities/playState.js +++ b/src/utilities/playState.js @@ -1,14 +1,18 @@ module.exports = ({ addUtilities }) => addUtilities({ '.animate-run': { - 'animation-play-state': 'running', + '--tw-animate-state': 'running', + 'animation-play-state': 'var(--tw-animate-state)', }, '.animate-play': { - 'animation-play-state': 'running', + '--tw-animate-state': 'running', + 'animation-play-state': 'var(--tw-animate-state)', }, '.animate-stop': { - 'animation-play-state': 'paused', + '--tw-animate-state': 'paused', + 'animation-play-state': 'var(--tw-animate-state)', }, '.animate-pause': { - 'animation-play-state': 'paused', + '--tw-animate-state': 'paused', + 'animation-play-state': 'var(--tw-animate-state)', }, }) diff --git a/src/utilities/timingFunction.js b/src/utilities/timingFunction.js index 40d39b2..e55147b 100644 --- a/src/utilities/timingFunction.js +++ b/src/utilities/timingFunction.js @@ -1,14 +1,18 @@ module.exports = ({ addUtilities }) => addUtilities({ '.animate-ease-linear': { - 'animation-timing-function': 'linear', + '--tw-animate-easing': 'linear', + 'animation-timing-function': 'var(--tw-animate-easing)', }, '.animate-ease-in': { - 'animation-timing-function': 'cubic-bezier(0.4, 0, 1, 1)', + '--tw-animate-easing': 'cubic-bezier(0.4, 0, 1, 1)', + 'animation-timing-function': 'var(--tw-animate-easing)', }, '.animate-ease-out': { - 'animation-timing-function': 'cubic-bezier(0, 0, 0.2, 1)', + '--tw-animate-easing': 'cubic-bezier(0, 0, 0.2, 1)', + 'animation-timing-function': 'var(--tw-animate-easing)', }, '.animate-ease-in-out': { - 'animation-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)', + '--tw-animate-easing': 'cubic-bezier(0.4, 0, 0.2, 1)', + 'animation-timing-function': 'var(--tw-animate-easing)', }, }) diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..eda5b57 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,5 @@ +module.exports = { + content: ['./index.html'], + theme: {}, + plugins: [require('./src')], +}