├── .commitlintrc.yaml
├── .editorconfig
├── .eslintrc.yaml
├── .gitattributes
├── .github
└── workflows
│ ├── ci.yaml
│ └── deploy.yaml
├── .gitignore
├── .markdownlint.yaml
├── .npmrc
├── .prettierignore
├── .prettierrc.yaml
├── .release-it.yaml
├── .vscode
├── extensions.json
└── settings.json
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── SECURITY.md
├── docs
├── .postcssrc.yaml
├── .vitepress
│ ├── config.ts
│ └── theme
│ │ ├── Demo.vue
│ │ ├── Layout.vue
│ │ ├── index.css
│ │ ├── index.ts
│ │ └── shims.d.ts
├── advanced.md
├── animation-delay.md
├── animation-direction.md
├── animation-duration.md
├── animation-fill-mode.md
├── animation-iteration-count.md
├── animation-name.md
├── animation-play-state.md
├── animation-timing-function.md
├── animations.md
├── index.md
├── installation.md
├── public
│ ├── animate-css.svg
│ ├── commits.svg
│ ├── license.svg
│ ├── logo-dark.svg
│ ├── logo-light.svg
│ └── tailwind-css.svg
├── translation-distance.md
└── tsconfig.json
├── lefthook.yaml
├── package.json
├── patches
└── prettier@2.8.1.patch
├── pnpm-lock.yaml
├── src
├── defaults.ts
├── index.ts
├── keyframes.ts
├── types.ts
└── utilities.ts
├── tailwind.config.cjs
└── tsconfig.json
/.commitlintrc.yaml:
--------------------------------------------------------------------------------
1 | extends:
2 | - '@commitlint/config-conventional'
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_size = 2
7 | indent_style = space
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintrc.yaml:
--------------------------------------------------------------------------------
1 | root: true
2 | env:
3 | node: true
4 | extends:
5 | - plugin:eslint-comments/recommended
6 | - plugin:import/recommended
7 | - plugin:import/typescript
8 | - plugin:security/recommended
9 | - eslint:recommended
10 | - plugin:@typescript-eslint/recommended
11 | - plugin:@typescript-eslint/recommended-requiring-type-checking
12 | - airbnb-base
13 | - airbnb-typescript/base
14 | - plugin:prettier/recommended
15 | ignorePatterns:
16 | - dist
17 | - '!.vitepress'
18 | parser: '@typescript-eslint/parser'
19 | parserOptions:
20 | ecmaVersion: 2019
21 | project:
22 | - tsconfig.json
23 | - docs/tsconfig.json
24 | sourceType: module
25 | plugins:
26 | - '@typescript-eslint'
27 | - security
28 | settings:
29 | import/resolver:
30 | typescript:
31 | alwaysTryTypes: true
32 | project: .
33 | rules:
34 | eslint-comments/no-unused-disable: error
35 | security/detect-object-injection: off # ts handles this
36 | import/no-extraneous-dependencies:
37 | - error
38 | - devDependencies: true
39 | import/prefer-default-export: off
40 | '@typescript-eslint/array-type':
41 | - error
42 | - default: generic
43 | '@typescript-eslint/ban-tslint-comment': error
44 | '@typescript-eslint/class-literal-property-style': error
45 | '@typescript-eslint/consistent-indexed-object-style': error
46 | '@typescript-eslint/consistent-type-assertions': error
47 | '@typescript-eslint/consistent-type-definitions':
48 | - error
49 | - type
50 | '@typescript-eslint/consistent-type-exports': error
51 | '@typescript-eslint/consistent-type-imports':
52 | - error
53 | - disallowTypeAnnotations: false
54 | '@typescript-eslint/explicit-function-return-type': error
55 | '@typescript-eslint/explicit-member-accessibility': error
56 | '@typescript-eslint/explicit-module-boundary-types': error
57 | '@typescript-eslint/member-ordering': error
58 | '@typescript-eslint/method-signature-style': error
59 | '@typescript-eslint/naming-convention': error
60 | '@typescript-eslint/no-base-to-string': error
61 | '@typescript-eslint/no-confusing-non-null-assertion': error
62 | '@typescript-eslint/no-confusing-void-expression': error
63 | '@typescript-eslint/no-dynamic-delete': error
64 | '@typescript-eslint/no-extraneous-class': error
65 | '@typescript-eslint/no-invalid-void-type': error
66 | '@typescript-eslint/no-meaningless-void-operator': error
67 | '@typescript-eslint/no-non-null-asserted-nullish-coalescing': error
68 | '@typescript-eslint/no-parameter-properties': error
69 | '@typescript-eslint/no-require-imports': error
70 | '@typescript-eslint/no-unnecessary-boolean-literal-compare': error
71 | '@typescript-eslint/no-unnecessary-condition': error
72 | '@typescript-eslint/no-unnecessary-qualifier': error
73 | '@typescript-eslint/no-unnecessary-type-arguments': error
74 | '@typescript-eslint/non-nullable-type-assertion-style': error
75 | '@typescript-eslint/prefer-enum-initializers': error
76 | '@typescript-eslint/prefer-for-of': error
77 | '@typescript-eslint/prefer-function-type': error
78 | '@typescript-eslint/prefer-includes': error
79 | '@typescript-eslint/prefer-literal-enum-member': error
80 | '@typescript-eslint/prefer-nullish-coalescing': error
81 | '@typescript-eslint/prefer-optional-chain': error
82 | '@typescript-eslint/prefer-readonly': error
83 | '@typescript-eslint/prefer-reduce-type-parameter': error
84 | '@typescript-eslint/prefer-regexp-exec': error
85 | '@typescript-eslint/prefer-return-this-type': error
86 | '@typescript-eslint/prefer-string-starts-ends-with': error
87 | '@typescript-eslint/prefer-ts-expect-error': error
88 | '@typescript-eslint/promise-function-async': error
89 | '@typescript-eslint/require-array-sort-compare':
90 | - error
91 | - ignoreStringArrays: true
92 | '@typescript-eslint/sort-type-union-intersection-members': error
93 | '@typescript-eslint/strict-boolean-expressions': error
94 | '@typescript-eslint/switch-exhaustiveness-check': error
95 | '@typescript-eslint/type-annotation-spacing': error
96 | '@typescript-eslint/typedef': error
97 | '@typescript-eslint/unified-signatures': error
98 |
99 | # Override/Extension Rules
100 | brace-style: off
101 | '@typescript-eslint/brace-style': error
102 | comma-dangle: off
103 | '@typescript-eslint/comma-dangle': error
104 | comma-spacing: off
105 | '@typescript-eslint/comma-spacing': error
106 | default-param-last: off
107 | '@typescript-eslint/default-param-last': error
108 | dot-notation: off
109 | '@typescript-eslint/dot-notation': error
110 | func-call-spacing: off
111 | '@typescript-eslint/func-call-spacing': error
112 | init-declarations: off
113 | '@typescript-eslint/init-declarations': error
114 | keyword-spacing: off
115 | '@typescript-eslint/keyword-spacing': error
116 | lines-between-class-members: off
117 | '@typescript-eslint/lines-between-class-members': error
118 | no-dupe-class-members: off
119 | '@typescript-eslint/no-dupe-class-members': error
120 | no-duplicate-imports: off
121 | '@typescript-eslint/no-duplicate-imports': error
122 | no-extra-parens: off
123 | '@typescript-eslint/no-extra-parens': error
124 | no-invalid-this: off
125 | '@typescript-eslint/no-invalid-this': error
126 | no-loop-func: off
127 | '@typescript-eslint/no-loop-func': error
128 | no-redeclare: off
129 | '@typescript-eslint/no-redeclare': error
130 | no-restricted-imports: off
131 | '@typescript-eslint/no-restricted-imports': error
132 | no-shadow: off
133 | '@typescript-eslint/no-shadow': error
134 | no-throw-literal: off
135 | '@typescript-eslint/no-throw-literal': error
136 | no-unused-expressions: off
137 | '@typescript-eslint/no-unused-expressions': error
138 | no-use-before-define: off
139 | '@typescript-eslint/no-use-before-define': error
140 | no-useless-constructor: off
141 | '@typescript-eslint/no-useless-constructor': error
142 | object-curly-spacing: off
143 | '@typescript-eslint/object-curly-spacing': error
144 | padding-line-between-statements: off
145 | '@typescript-eslint/padding-line-between-statements': error
146 | quotes: off
147 | '@typescript-eslint/quotes': error
148 | no-return-await: off
149 | '@typescript-eslint/return-await': error
150 | semi: off
151 | space-before-function-paren: off
152 | '@typescript-eslint/space-before-function-paren': error
153 | space-infix-ops: off
154 | '@typescript-eslint/space-infix-ops': error
155 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 | types: [opened, synchronize, reopened]
9 | schedule:
10 | - cron: '0 0 */7 * *'
11 | workflow_dispatch:
12 |
13 | jobs:
14 | test:
15 | runs-on: ubuntu-latest
16 | strategy:
17 | matrix:
18 | node-version: [14, 16, 18]
19 | steps:
20 | - uses: actions/checkout@v3
21 | - uses: pnpm/action-setup@v2
22 | - uses: actions/setup-node@v3
23 | with:
24 | node-version: ${{ matrix.node-version }}
25 | cache: pnpm
26 | - run: pnpm prerelease && git add . && [ -z "$(git status --porcelain)" ]
27 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yaml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: read
10 | pages: write
11 | id-token: write
12 |
13 | concurrency:
14 | group: pages
15 | cancel-in-progress: true
16 |
17 | jobs:
18 | build:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: actions/checkout@v3
22 | with:
23 | fetch-depth: 0
24 | - uses: pnpm/action-setup@v2
25 | - uses: actions/setup-node@v3
26 | with:
27 | node-version: lts/*
28 | cache: pnpm
29 | - uses: actions/configure-pages@v1
30 | - run: pnpm i && pnpm build && pnpm vitepress build docs --base /animated-tailwindcss/
31 | - uses: actions/upload-pages-artifact@v1
32 | with:
33 | path: docs/.vitepress/dist
34 |
35 | deploy:
36 | environment:
37 | name: github-pages
38 | url: ${{ steps.deployment.outputs.page_url }}
39 | runs-on: ubuntu-latest
40 | needs: build
41 | steps:
42 | - id: deployment
43 | uses: actions/deploy-pages@v1
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | cache
4 | *.log
5 | *.tgz
6 |
--------------------------------------------------------------------------------
/.markdownlint.yaml:
--------------------------------------------------------------------------------
1 | default: true
2 | MD025: false
3 | MD033: false
4 | MD013:
5 | tables: false
6 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | shell-emulator=true
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
2 | cache
3 | pnpm-lock.yaml
4 | CHANGELOG.md
5 |
--------------------------------------------------------------------------------
/.prettierrc.yaml:
--------------------------------------------------------------------------------
1 | proseWrap: always
2 | semi: false
3 | singleQuote: true
4 | trailingComma: all
5 | printWidth: 100
6 | htmlWhitespaceSensitivity: ignore
7 | overrides:
8 | - files: '*.md'
9 | options:
10 | printWidth: 80
11 | plugins:
12 | - prettier-plugin-packagejson
13 | - prettier-plugin-tailwindcss
14 |
--------------------------------------------------------------------------------
/.release-it.yaml:
--------------------------------------------------------------------------------
1 | git:
2 | commitMessage: 'chore: release v${version}'
3 | github:
4 | release: true
5 | releaseName: v${version}
6 | plugins:
7 | '@release-it/conventional-changelog':
8 | preset: conventionalcommits
9 | infile: CHANGELOG.md
10 | ignoreRecommendedBump: true
11 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "bradlc.vscode-tailwindcss",
4 | "davidanson.vscode-markdownlint",
5 | "dbaeumer.vscode-eslint",
6 | "editorconfig.editorconfig",
7 | "esbenp.prettier-vscode",
8 | "foxundermoon.shell-format",
9 | "rohit-gohri.format-code-action",
10 | "streetsidesoftware.code-spell-checker"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.defaultFormatter": "esbenp.prettier-vscode",
3 | "[ignore][properties][shellscript]": { "editor.defaultFormatter": "foxundermoon.shell-format" },
4 | "editor.formatOnSave": false,
5 | "editor.codeActionsOnSave": ["source.fixAll.format", "source.fixAll.eslint"],
6 | "eslint.probe": ["typescript"],
7 | "typescript.tsdk": "node_modules/typescript/lib",
8 | "volar.vueserver.vitePress.processMdFile": true,
9 | "yaml.schemas": {
10 | "https://json.schemastore.org/github-workflow.json": "file:///c%3A/Users/brc-dd/Desktop/delete/animated-tailwindcss/.github/workflows/deploy.yaml"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 4.0.0 (2023-01-03)
4 |
5 |
6 | ### Features
7 |
8 | * v4 ([1b97909](https://github.com/brc-dd/animated-tailwindcss/commit/1b979095c47455b48315fb368734b150c56ee057))
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity and
10 | orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | - Demonstrating empathy and kindness toward other people
21 | - Being respectful of differing opinions, viewpoints, and experiences
22 | - Giving and gracefully accepting constructive feedback
23 | - Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | - Focusing on what is best not just for us as individuals, but for the overall
26 | community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | - The use of sexualized language or imagery, and sexual attention or advances of
31 | any kind
32 | - Trolling, insulting or derogatory comments, and personal or political attacks
33 | - Public or private harassment
34 | - Publishing others' private information, such as a physical or email address,
35 | without their explicit permission
36 | - Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | brc-dd@hotmail.com. All complaints will be reviewed and investigated promptly
64 | and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series of
86 | actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or permanent
93 | ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within the
113 | community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by
122 | [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | All sorts of contributions are welcome here!
2 |
3 | When you submit code changes, your submissions are understood to be under
4 | [the same MIT license](LICENSE.md) that covers the project. Feel free to contact
5 | the maintainers if that's a concern.
6 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Divyansh Singh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | A configuration to use Animate.css with
12 | Tailwind CSS .
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ---
40 |
41 | ## Documentation
42 |
43 | [View documentation](https://brc-dd.github.io/animated-tailwindcss/)
44 |
45 | ## Installation
46 |
47 | Please see the [full installation instructions](https://brc-dd.github.io/animated-tailwindcss/installation) for detailed steps and examples.
48 |
49 | ### Quick start with NPM
50 |
51 | In a project where you're using Tailwind CSS **v3**, run this to install this
52 | package:
53 |
54 | ```sh
55 | npm add -D animated-tailwindcss
56 | ```
57 |
58 | Then configure your `tailwind.config.js` to use the animations:
59 |
60 | ```js
61 | const { withAnimations } = require('animated-tailwindcss')
62 |
63 | module.exports = withAnimations({
64 | // your (existing) Tailwind CSS config here
65 | })
66 | ```
67 |
68 | ## Credits
69 |
70 | - [Animate.css](https://github.com/animate-css/animate.css) – for
71 | animation utilities & keyframes – used under
72 | [the MIT license](https://cdn.jsdelivr.net/npm/animate.css@4.1.1/LICENSE).
73 | - [Transform.tools](https://github.com/ritz078/transform) – for converting
74 | Animate.css to JS – used under
75 | [the MIT license](https://github.com/ritz078/transform/blob/master/LICENSE).
76 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | If you discover any security issues in this repository, please drop an email at
2 | brc-dd@hotmail.com.
3 |
4 | Thanks for helping us keep our open-source projects safe for everyone! We really
5 | appreciate it.
6 |
--------------------------------------------------------------------------------
/docs/.postcssrc.yaml:
--------------------------------------------------------------------------------
1 | plugins:
2 | tailwindcss/nesting: {}
3 | tailwindcss: {}
4 | autoprefixer: {}
5 |
--------------------------------------------------------------------------------
/docs/.vitepress/config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitepress'
2 |
3 | export default defineConfig({
4 | title: 'tw-Animated',
5 | description: 'animated-tailwindcss is a package that brings Animate.css classes to Tailwind CSS',
6 | cleanUrls: 'without-subfolders',
7 |
8 | themeConfig: {
9 | socialLinks: [{ icon: 'github', link: 'https://github.com/brc-dd/animated-tailwindcss' }],
10 |
11 | outline: false,
12 |
13 | sidebar: [
14 | {
15 | text: 'Guide',
16 | items: [
17 | { text: 'Getting Started', link: '/installation' },
18 | { text: 'Available Animations', link: '/animations' },
19 | { text: 'Miscellaneous Notes', link: '/advanced' },
20 | ],
21 | },
22 | {
23 | text: 'Available Utilities',
24 | items: [
25 | { text: 'Animation Delay', link: '/animation-delay' },
26 | { text: 'Animation Direction', link: '/animation-direction' },
27 | { text: 'Animation Duration', link: '/animation-duration' },
28 | { text: 'Animation Fill Mode', link: '/animation-fill-mode' },
29 | { text: 'Animation Iteration Count', link: '/animation-iteration-count' },
30 | { text: 'Animation Name', link: '/animation-name' },
31 | { text: 'Animation Play State', link: '/animation-play-state' },
32 | { text: 'Animation Timing Function', link: '/animation-timing-function' },
33 | { text: 'Translation Distance', link: '/translation-distance' },
34 | ],
35 | },
36 | ],
37 |
38 | editLink: { pattern: 'https://github.com/brc-dd/animated-tailwindcss/edit/main/docs/:path' },
39 |
40 | footer: {
41 | message: 'Released under the MIT License.',
42 | copyright: 'Copyright © 2023-present Divyansh Singh',
43 | },
44 | },
45 | })
46 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/Demo.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
13 |
14 |
15 |
24 |
25 |
31 |
32 |
36 |
37 |
38 |
44 |
45 |
49 |
50 |
51 |
55 |
56 |
57 |
63 |
64 |
68 |
69 |
70 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
323 |
324 |
374 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/Layout.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
19 | Easiest way to use animations in Tailwind CSS
20 |
21 |
22 |
23 |
24 |
25 |
26 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --vp-c-brand-lighter: #27b7f7 !important;
7 | --vp-c-brand-light: #09aaf2 !important;
8 | --vp-c-brand: #0792cf !important;
9 | --vp-c-brand-dark: #067aad !important;
10 | --vp-c-brand-darker: #05618a !important;
11 | --vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg) !important;
12 | }
13 |
14 | table {
15 | --vp-c-bg-mute: transparent;
16 | }
17 |
18 | th,
19 | td {
20 | white-space: pre;
21 | }
22 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/index.ts:
--------------------------------------------------------------------------------
1 | import DefaultTheme from 'vitepress/theme'
2 | import Layout from './Layout.vue'
3 |
4 | export default { ...DefaultTheme, Layout }
5 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/shims.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import type { Component } from 'vue'
3 |
4 | const component: Component
5 | export default component
6 | }
7 |
--------------------------------------------------------------------------------
/docs/advanced.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Advanced
3 | outline: [2, 3]
4 | ---
5 |
6 | # Miscellaneous
7 |
8 | ## Editor Setup
9 |
10 | You do not need any additional configuration. IntelliSense will automatically
11 | detect the animations and utilities. Refer the
12 | [official docs](https://tailwindcss.com/docs/editor-setup) on setting up your
13 | editor.
14 |
15 | ## Customizing
16 |
17 | Refer to the
18 | [Tailwind CSS docs](https://tailwindcss.com/docs/animation#using-custom-values).
19 | If present, any animation or keyframe customization should be applied properly.
20 | Create an issue on our GitHub if something is not working.
21 |
22 | ## Accessibility
23 |
24 | Use `motion-safe` and `motion-reduce` variants provided by Tailwind CSS.
25 | `print:hidden` can also be used (for example, on elements having exit
26 | animations) to hide them while printing.
27 |
28 | Refer:
29 |
30 | - [Prefers reduced motion | Handling Hover, Focus, and Other States - Tailwind CSS](https://tailwindcss.com/docs/hover-focus-and-other-states#prefers-reduced-motion)
31 | - [Prefers reduced motion | Animation - Tailwind CSS](https://tailwindcss.com/docs/animation#prefers-reduced-motion)
32 | - [Print styles | Handling Hover, Focus, and Other States - Tailwind CSS](https://tailwindcss.com/docs/hover-focus-and-other-states#print-styles)
33 |
34 | ## Optimizing
35 |
36 | Tailwind CSS v3 has JIT mode enabled by default. So, it will only generate the
37 | CSS you are actually using in your project. Please refer
38 | [the docs](https://tailwindcss.com/docs/optimizing-for-production) to learn
39 | more.
40 |
41 | ## Upgrade Guide
42 |
43 | ### From v3 to v4
44 |
45 | Default export is removed. Use named export instead:
46 |
47 | ```ts
48 | const withAnimations = require('animated-tailwindcss') // [!code --]
49 | const { withAnimations } = require('animated-tailwindcss') // [!code ++]
50 | ```
51 |
52 | ### From v2 to v3
53 |
54 | - We now require Tailwind CSS v3. So first upgrade it. You can refer their
55 | [upgrade guide](https://tailwindcss.com/docs/upgrade-guide).
56 | - `animate-animated` class is no longer required. You can remove it.
57 | - Accessibility measures are no longer enforced by us. Refer the
58 | [accessibility section](#accessibility).
59 | - Remove any experimental options that you might earlier be passing to
60 | `withAnimations` wrapper. Those features are now covered by semantic
61 | versioning and are stable.
62 |
--------------------------------------------------------------------------------
/docs/animation-delay.md:
--------------------------------------------------------------------------------
1 | # Animation Delay
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay)) |
4 | | ---------------------- | ------------------------------------------------------------------------------------ |
5 | | `animate-delay-[time]` | `animation-delay: time;` |
6 |
7 | Here `[time]` is one of `{75, 100, 150, 200, 300, 500, 700, 1000}` and is
8 | interpreted like 75ms, 100ms... You can also use `animate-delay-{1..5}s` classes
9 | or arbitrary values.
10 |
11 | ## Examples
12 |
13 | ```html
14 | Foo
15 | Bar
16 | Baz
17 | ```
18 |
--------------------------------------------------------------------------------
/docs/animation-direction.md:
--------------------------------------------------------------------------------
1 | # Animation Direction
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-direction)) |
4 | | --------------------------- | ---------------------------------------------------------------------------------------- |
5 | | `animate-normal` | `animation-direction: normal;` |
6 | | `animate-reverse` | `animation-direction: reverse;` |
7 | | `animate-alternate` | `animation-direction: alternate;` |
8 | | `animate-alternate-reverse` | `animation-direction: alternate-reverse` |
9 |
--------------------------------------------------------------------------------
/docs/animation-duration.md:
--------------------------------------------------------------------------------
1 | # Animation Duration
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-duration)) |
4 | | ------------------------- | --------------------------------------------------------------------------------------- |
5 | | `animate-faster` | `animation-duration: 0.5s;` |
6 | | `animate-fast` | `animation-duration: 0.8s;` |
7 | | `animate-slow` | `animation-duration: 2s;` |
8 | | `animate-slower` | `animation-duration: 3s;` |
9 | | `animate-duration-[time]` | `animation-duration: time;` |
10 |
11 | Here `[time]` is one of `{75, 100, 150, 200, 300, 500, 700, 1000}` and is
12 | interpreted like 75ms, 100ms... You can also use arbitrary values instead.
13 |
14 | ## Examples
15 |
16 | ```html
17 | Foo
18 | Bar
19 | ```
20 |
--------------------------------------------------------------------------------
/docs/animation-fill-mode.md:
--------------------------------------------------------------------------------
1 | # Animation Fill Mode
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode)) |
4 | | ------------------------ | ---------------------------------------------------------------------------------------- |
5 | | `animate-fill-none` | `animation-fill-mode: none;` |
6 | | `animate-fill-forwards` | `animation-fill-mode: forwards;` |
7 | | `animate-fill-backwards` | `animation-fill-mode: backwards;` |
8 | | `animate-fill-both` | `animation-fill-mode: both;` |
9 |
10 | By default `animation-fill-mode` is set to `both` for all animations in
11 | Animate.css.
12 |
13 | You can use arbitrary values if you need to reference some globals or write the
14 | fill mode for multiple animations:
15 |
16 | ```html
17 | Foo
18 | Bar
19 | ```
20 |
--------------------------------------------------------------------------------
/docs/animation-iteration-count.md:
--------------------------------------------------------------------------------
1 | # Animation Iteration Count
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-iteration-count)) |
4 | | -------------------- | ---------------------------------------------------------------------------------------------- |
5 | | `animate-infinite` | `animation-iteration-count: infinite;` |
6 | | `animate-repeat-[n]` | `animation-iteration-count: n;` |
7 |
8 | Here `[n]` is one of `0..12`. You can also use arbitrary values instead.
9 |
10 | ## Examples
11 |
12 | ```html
13 | Foo
14 | Bar
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/animation-name.md:
--------------------------------------------------------------------------------
1 | # Animation Name
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-name)) |
4 | | ---------------- | ----------------------------------------------------------------------------------- |
5 | | `animate-none` | `animation-name: none;` |
6 | | `animate-[name]` | `animation-name: name;` |
7 |
8 | ## Examples
9 |
10 | ```html
11 | Foo
12 | Bar
13 | ```
14 |
15 | Refer [the demo](./animations) to see the available animations in action. You
16 | can play with them [here](https://play.tailwindcss.com/TsNC9Yw9Nc).
17 |
18 | Also refer the official Tailwind CSS documentation on
19 | [using animations with arbitrary values](https://tailwindcss.com/docs/animation#arbitrary-values).
20 | Note that these classes add some default properties and keyframe definitions
21 | too.
22 |
--------------------------------------------------------------------------------
/docs/animation-play-state.md:
--------------------------------------------------------------------------------
1 | # Animation Play State
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-play-state)) |
4 | | ----------------- | ----------------------------------------------------------------------------------------- |
5 | | `animate-paused` | `animation-play-state: paused;` |
6 | | `animate-running` | `animation-play-state: running;` |
7 |
--------------------------------------------------------------------------------
/docs/animation-timing-function.md:
--------------------------------------------------------------------------------
1 | # Animation Timing Function
2 |
3 | | Class | Properties ([MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function)) |
4 | | ---------------------------- | ---------------------------------------------------------------------------------------------- |
5 | | `animate-ease` | `animation-timing-function: ease;` |
6 | | `animate-ease-linear` | `animation-timing-function: linear;` |
7 | | `animate-ease-in` | `animation-timing-function: ease-in;` |
8 | | `animate-ease-out` | `animation-timing-function: ease-out;` |
9 | | `animate-ease-in-out` | `animation-timing-function: ease-in-out;` |
10 | | `animate-[easing]` | `animation-timing-function: easing;` |
11 | | `animate-ease-[p0,p1,p2,p3]` | `animation-timing-function: cubic-bezier(p0, p1, p2, p4);` |
12 | | `animate-steps-start-[n]` | `animation-timing-function: steps(n, jump-start);` |
13 | | `animate-steps-end-[n]` | `animation-timing-function: steps(n, jump-end);` |
14 | | `animate-steps-both-[n]` | `animation-timing-function: steps(n, jump-both);` |
15 | | `animate-steps-none-[n]` | `animation-timing-function: steps(n, jump-none);` |
16 |
17 | Here `[easing]` is one of those listed at [easings.net](https://easings.net/) in
18 | kebab-case. Note that some of the easing functions listed there cannot be
19 | written in CSS.
20 |
21 | If you are planning on using custom cubic-bezier function, we would recommend
22 | using [cubic-bezier.com](https://cubic-bezier.com/) to find out what looks best.
23 |
24 | Here `[n]` is one of `0..12`. You can also use arbitrary values instead.
25 |
26 | ## Examples
27 |
28 | ```html
29 | Foo
30 | Bar
31 | Baz
32 | Qux
33 | ```
34 |
--------------------------------------------------------------------------------
/docs/animations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Animations
3 | ---
4 |
5 | # Demo
6 |
7 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | titleTemplate: ':title'
4 | features:
5 | - title: Derived from Animate.css
6 | details:
7 | The most popular CSS animation library with over 100 awesome cross-browser
8 | animations.
9 | - title: Enhanced for Tailwind CSS
10 | details:
11 | Fully compatible with JIT mode, allowing a vast variety of customizations
12 | and utility classes.
13 | - title: Zero extra config needed
14 | details:
15 | Wrap your Tailwind CSS config with a function and start using animations
16 | as if they are inbuilt.
17 | ---
18 |
--------------------------------------------------------------------------------
/docs/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | ---
4 |
5 | # Getting Started
6 |
7 | In a project where you're using Tailwind CSS **v3**, run this to install this
8 | package:
9 |
10 | ```sh
11 | npm add -D animated-tailwindcss
12 | ```
13 |
14 | Then configure your `tailwind.config.js` to use the animations:
15 |
16 | ```js
17 | const { withAnimations } = require('animated-tailwindcss')
18 |
19 | module.exports = withAnimations({
20 | // your (existing) Tailwind CSS config here
21 | })
22 | ```
23 |
24 | :::details Example
25 |
26 | ```js
27 | const { withAnimations } = require('animated-tailwindcss')
28 |
29 | module.exports = withAnimations({
30 | content: ['./src/**/*.{html,js}'],
31 | theme: { extend: {} },
32 | plugins: [],
33 | })
34 | ```
35 |
36 | :::
37 |
38 | After proper config, you can use the animations of Animate.css the same way as
39 | you use those of Tailwind CSS:
40 |
41 | ```html
42 | Bouncing Heading
43 | ```
44 |
45 | :::info Notes
46 |
47 | - If you're coming from classical Animate.css, please note that you need to
48 | reference the classes using hyphen instead of underscores (e.g.,
49 | `animate-bounce` instead of `animate__bounce`).
50 |
51 | - The built-in animations (`spin`, `ping`, `pulse`, `bounce`) are prefixed by
52 | `tw`. So, if you want Tailwind CSS' bounce you need to write
53 | `animate-twBounce` instead of `animate-bounce`.
54 |
55 | - The animations this package provides are not exactly same as that of
56 | Animate.css. We have done some modifications to provide you with more
57 | consistent and customizable animations.
58 |
59 | :::
60 |
61 | ## With Play CDN
62 |
63 | It is as simple as this:
64 |
65 | ```html
66 |
67 |
68 |
69 |
70 |
71 | Welcome
72 |
73 | // [!code focus:6]
74 |
75 |
79 |
80 |
81 |
84 |
85 |
86 | ```
87 |
88 |
103 |
104 | :::warning
105 |
106 | The Play CDN is not suitable for production builds, and the above example will
107 | not work if your browser does not support ES6 modules
108 | (_[Can I use?](https://caniuse.com/es6-module) _).
109 |
110 | :::
111 |
--------------------------------------------------------------------------------
/docs/public/animate-css.svg:
--------------------------------------------------------------------------------
1 | animate.css: v4.1.1 animate.css v4.1.1
--------------------------------------------------------------------------------
/docs/public/commits.svg:
--------------------------------------------------------------------------------
1 | commits: conventional commits conventional
--------------------------------------------------------------------------------
/docs/public/license.svg:
--------------------------------------------------------------------------------
1 | license: MIT license MIT
--------------------------------------------------------------------------------
/docs/public/logo-dark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/public/logo-light.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/public/tailwind-css.svg:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/docs/translation-distance.md:
--------------------------------------------------------------------------------
1 | # Translation Distance
2 |
3 | Certain animations support modifying their translation distance using
4 | `--animate-distance` CSS variable. You can set it using the following utilities:
5 |
6 | | Class | Properties |
7 | | --------------------------- | ----------------------------- |
8 | | `animate-distance-[length]` | `--animate-distance: length;` |
9 |
10 | Here `[length]` is one of Tailwind CSS-style
11 | [widths](https://tailwindcss.com/docs/width). You can also use arbitrary values
12 | instead.
13 |
14 | ::: details
15 |
16 | The following classes can be customized by these utilities:
17 |
18 | ```txt
19 | animate-backXY
20 | animate-bounceXY
21 | animate-fadeXYBig
22 | animate-hinge
23 | animate-zoomXY
24 | ```
25 |
26 | where `X` is one of `{In, Out}` and `Y` is one of `{Down, Left, Right, Up}`.
27 |
28 | `animate-distance-{min, max, fit}` are not supported.
29 |
30 | :::
31 |
32 | ## Examples
33 |
34 | ```html
35 | Foo
36 | Bar
37 | Baz
38 | ```
39 |
--------------------------------------------------------------------------------
/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.web.json",
3 | "include": [".vitepress/**/*", ".vitepress/**/*.vue"]
4 | }
5 |
--------------------------------------------------------------------------------
/lefthook.yaml:
--------------------------------------------------------------------------------
1 | skip_output:
2 | - meta
3 | - execution
4 |
5 | commit-msg:
6 | commands:
7 | commitlint:
8 | run: pnpm commitlint --edit {1}
9 |
10 | post-commit:
11 | commands:
12 | status:
13 | run: git status
14 |
15 | post-checkout:
16 | commands:
17 | install:
18 | run: pnpm i
19 |
20 | pre-commit:
21 | piped: true
22 | commands:
23 | 1_replace:
24 | glob: '*.{json,ts}'
25 | run: pnpm replace "'{\n'" "'{ '" {all_files}
26 | 2_prettify:
27 | run: pnpm prettier --write --ignore-unknown {all_files}
28 | 3_eslint:
29 | glob: '*.ts'
30 | run: pnpm eslint --fix --max-warnings 0 {all_files}
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/package.json",
3 | "name": "animated-tailwindcss",
4 | "version": "4.0.0",
5 | "description": "A configuration to use Animate.css with Tailwind CSS",
6 | "keywords": [
7 | "animate.css",
8 | "animatecss",
9 | "animations",
10 | "configuration",
11 | "css",
12 | "jit",
13 | "keyframes",
14 | "plugin",
15 | "tailwind",
16 | "tailwindcss",
17 | "utilities"
18 | ],
19 | "homepage": "https://brc-dd.github.io/animated-tailwindcss",
20 | "bugs": {
21 | "url": "https://github.com/brc-dd/animated-tailwindcss",
22 | "email": "brc-dd@hotmail.com"
23 | },
24 | "repository": "github:brc-dd/animated-tailwindcss",
25 | "funding": "https://github.com/sponsors/brc-dd",
26 | "license": "MIT",
27 | "author": "Divyansh Singh (https://github.com/brc-dd)",
28 | "sideEffects": false,
29 | "exports": {
30 | ".": {
31 | "types": "./dist/index.d.ts",
32 | "require": "./dist/index.js",
33 | "import": "./dist/index.mjs"
34 | }
35 | },
36 | "main": "dist/index.js",
37 | "module": "dist/index.mjs",
38 | "browser": "dist/index.mjs",
39 | "types": "dist/index.d.ts",
40 | "files": [
41 | "dist/*"
42 | ],
43 | "scripts": {
44 | "build": "rimraf dist && tsup ./src/index.ts --dts-resolve --format esm,cjs --minify --treeshake",
45 | "lint": "lefthook run pre-commit",
46 | "prerelease": "git add . && pnpm i && pnpm build && pnpm lint",
47 | "release": "pnpm prerelease && release-it"
48 | },
49 | "devDependencies": {
50 | "@commitlint/cli": "^17.3.0",
51 | "@commitlint/config-conventional": "^17.3.0",
52 | "@release-it/conventional-changelog": "^5.1.1",
53 | "@tsconfig/node12": "^1.0.11",
54 | "@typescript-eslint/eslint-plugin": "^5.48.0",
55 | "@typescript-eslint/parser": "^5.48.0",
56 | "@vue/tsconfig": "^0.1.3",
57 | "autoprefixer": "^10.4.13",
58 | "csstype": "^3.1.1",
59 | "eslint": "^8.31.0",
60 | "eslint-config-airbnb-base": "^15.0.0",
61 | "eslint-config-airbnb-typescript": "^17.0.0",
62 | "eslint-config-prettier": "^8.6.0",
63 | "eslint-import-resolver-node": "^0.3.6",
64 | "eslint-import-resolver-typescript": "^3.5.2",
65 | "eslint-plugin-eslint-comments": "^3.2.0",
66 | "eslint-plugin-import": "^2.26.0",
67 | "eslint-plugin-prettier": "^4.2.1",
68 | "eslint-plugin-security": "^1.5.0",
69 | "lefthook": "^1.2.6",
70 | "postcss": "^8.4.20",
71 | "prettier": "^2.8.1",
72 | "prettier-plugin-packagejson": "^2.3.0",
73 | "prettier-plugin-tailwindcss": "^0.2.1",
74 | "release-it": "^15.6.0",
75 | "replace": "^1.2.2",
76 | "rimraf": "^3.0.2",
77 | "tailwindcss": "^3.2.4",
78 | "tsup": "^6.5.0",
79 | "typescript": "~4.9.4",
80 | "vitepress": "1.0.0-alpha.35",
81 | "vue": "^3.2.45"
82 | },
83 | "peerDependencies": {
84 | "postcss": "^8",
85 | "tailwindcss": "^3"
86 | },
87 | "peerDependenciesMeta": {
88 | "postcss": {
89 | "optional": true
90 | }
91 | },
92 | "packageManager": "pnpm@7.21.0",
93 | "publishConfig": {
94 | "registry": "https://registry.npmjs.org"
95 | },
96 | "pnpm": {
97 | "peerDependencyRules": {
98 | "ignoreMissing": [
99 | "@algolia/client-search"
100 | ]
101 | },
102 | "patchedDependencies": {
103 | "prettier@2.8.1": "patches/prettier@2.8.1.patch"
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/patches/prettier@2.8.1.patch:
--------------------------------------------------------------------------------
1 | diff --git a/index.js b/index.js
2 | index e6b12ba57310caaf0497313bb0a93e0ab7cdd8ba..c2c20c22f81b795feb394b40da4d272c29a8e5d6 100644
3 | --- a/index.js
4 | +++ b/index.js
5 | @@ -32917,6 +32917,18 @@ var require_embed3 = __commonJS2({
6 | }
7 | }
8 | switch (node.type) {
9 | + case "html":
10 | + const isWrapped = !/\s*(script|style|template)/.test(node.value)
11 | + const doc = textToDoc(isWrapped ? `${node.value} ` : node.value, {
12 | + parser: "vue"
13 | + }, {
14 | + stripTrailingHardline: true
15 | + });
16 | + if (isWrapped) {
17 | + const { contents: c } = doc[0].contents;
18 | + c.contents = c.contents.find(node => node.type === "indent").contents.slice(1);
19 | + }
20 | + return [doc];
21 | case "front-matter":
22 | return printFrontMatter(node, textToDoc);
23 | case "importExport":
--------------------------------------------------------------------------------
/src/defaults.ts:
--------------------------------------------------------------------------------
1 | const range = (a: number, b?: number, c?: number): Array => {
2 | if (b != null && c != null && ((a >= b && c >= 0) || (a < b && c < 0))) return []
3 | return [...Array(Math.abs(b != null ? Math.ceil((b - a) / ((c ?? 1) || 1)) : a)).keys()].map(
4 | (k) => (k * (c ?? ((b != null ? a > b : a < 0) ? -1 : 1)) || 0) + (b != null ? a : 0),
5 | )
6 | }
7 |
8 | const expandArray = (
9 | arr: Array,
10 | append = '',
11 | inKey = false,
12 | transform = (v: T): T => v,
13 | ): Record =>
14 | arr.reduce((a, v) => ({ ...a, [`${v}${inKey ? append : ''}`]: `${transform(v)}${append}` }), {})
15 |
16 | export const duration = expandArray([75, 100, 150, 200, 300, 500, 700, 1000], 'ms')
17 |
18 | export const ease = {
19 | linear: '0,0,1,1',
20 | in: '.42,0,1,1',
21 | out: '0,0,.58,1',
22 | 'in-out': '.42,0,.58,1',
23 | 'in-sine': '.12,0,.39,0',
24 | 'out-sine': '.61,1,.88,1',
25 | 'in-out-sine': '.37,0,.63,1',
26 | 'in-quad': '.11,0,.5,0',
27 | 'out-quad': '.5,1,.89,1',
28 | 'in-out-quad': '.45,0,.55,1',
29 | 'in-cubic': '.32,0,.67,0',
30 | 'out-cubic': '.33,1,.68,1',
31 | 'in-out-cubic': '.65,0,.35,1',
32 | 'in-quart': '.5,0,.75,0',
33 | 'out-quart': '.25,1,.5,1',
34 | 'in-out-quart': '.76,0,.24,1',
35 | 'in-quint': '.64,0,.78,0',
36 | 'out-quint': '.22,1,.36,1',
37 | 'in-out-quint': '.83,0,.17,1',
38 | 'in-expo': '.7,0,.84,0',
39 | 'out-expo': '.16,1,.3,1',
40 | 'in-out-expo': '.87,0,.13,1',
41 | 'in-circ': '.55,0,1,.45',
42 | 'out-circ': '0,.55,.45,1',
43 | 'in-out-circ': '.85,0,.15,1',
44 | 'in-back': '.36,0,.66,-.56',
45 | 'out-back': '.34,1.56,.64,1',
46 | 'in-out-back': '.68,-.6,.32,1.6',
47 | }
48 |
49 | export const delay = { ...duration, ...expandArray(range(6), 's', true) }
50 |
51 | export const repeat = expandArray(range(13))
52 |
53 | export const fill = expandArray(['none', 'forwards', 'backwards', 'both'])
54 |
55 | export const distance: Record = {
56 | px: '1px',
57 | ...expandArray(
58 | [
59 | ...range(0, 4, 0.5),
60 | ...range(4, 12, 1),
61 | ...range(12, 16, 2),
62 | ...range(16, 64, 4),
63 | ...range(64, 80, 8),
64 | ...range(80, 100, 16),
65 | ],
66 | 'rem',
67 | false,
68 | (v) => v * 0.25,
69 | ),
70 | '1/2': '50%',
71 | '1/3': '33.333333%',
72 | '2/3': '66.666667%',
73 | '1/4': '25%',
74 | '2/4': '50%',
75 | '3/4': '75%',
76 | '1/5': '20%',
77 | '2/5': '40%',
78 | '3/5': '60%',
79 | '4/5': '80%',
80 | '1/6': '16.666667%',
81 | '2/6': '33.333333%',
82 | '3/6': '50%',
83 | '4/6': '66.666667%',
84 | '5/6': '83.333333%',
85 | '1/12': '8.333333%',
86 | '2/12': '16.666667%',
87 | '3/12': '25%',
88 | '4/12': '33.333333%',
89 | '5/12': '41.666667%',
90 | '6/12': '50%',
91 | '7/12': '58.333333%',
92 | '8/12': '66.666667%',
93 | '9/12': '75%',
94 | '10/12': '83.333333%',
95 | '11/12': '91.666667%',
96 | full: '100%',
97 | screen: '100vh',
98 | }
99 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | /* eslint no-param-reassign: "off" */
2 |
3 | import { delay, distance, duration, ease, fill, repeat } from './defaults.js'
4 | import { keyframes } from './keyframes.js'
5 | import type { CSSBlock, CSSProperties, EntryPoint, KeyValuePair, PluginsConfig } from './types.js'
6 | import { animationUtils, keyframeUtils } from './utilities.js'
7 |
8 | export * from './types.js'
9 |
10 | export const withAnimations: EntryPoint = (config = {}) => {
11 | config.theme = config.theme ?? {}
12 |
13 | // animations
14 | const animations: KeyValuePair = Object.fromEntries(
15 | Object.keys(keyframes).map((k) => [
16 | k,
17 | `${keyframeUtils[k]?.animationDuration ?? '1s'}
18 | ${keyframeUtils[k]?.animationTimingFunction ?? ''}
19 | both ${k}`.replace(/\s+/g, ' '),
20 | ]),
21 | )
22 |
23 | const configAnimations = config.theme.extend?.animation ?? {}
24 | config.theme.animation = { ...animations, ...configAnimations }
25 | delete config.theme.extend?.animation
26 |
27 | // patches
28 | Object.keys(animations).forEach((key) => {
29 | if (key.includes('In')) {
30 | if (!key.includes('slide'))
31 | ((keyframes[key] = keyframes[key] ?? {}).from = keyframes[key]?.from ?? {}).opacity = 0
32 | }
33 |
34 | if (key.includes('Out')) {
35 | if (!key.includes('slide'))
36 | ((keyframes[key] = keyframes[key] ?? {}).to = keyframes[key]?.to ?? {}).opacity = 0
37 | ;((keyframes[key] = keyframes[key] ?? {}).to = keyframes[key]?.to ?? {}).visibility = 'hidden'
38 | }
39 | })
40 |
41 | // keyframes
42 | const configKeyframes = config.theme.extend?.keyframes ?? {}
43 | config.theme.keyframes = { ...keyframes, ...configKeyframes }
44 | delete config.theme.extend?.keyframes
45 |
46 | // utilities
47 | const prefixed: CSSBlock = Object.fromEntries(
48 | Object.entries({ ...keyframeUtils, ...animationUtils }).flatMap(([util, block]) => {
49 | if (util in configAnimations || !block) return []
50 |
51 | const filtered: CSSProperties =
52 | util in animationUtils
53 | ? block // skip filtering
54 | : Object.fromEntries(
55 | Object.entries(block).filter(([key]) => !key.startsWith('animation')),
56 | )
57 |
58 | return Object.keys(filtered).length > 0 ? [[`.animate-${util}`, filtered]] : []
59 | }),
60 | )
61 |
62 | // plugins
63 | const plugins: PluginsConfig = [
64 | // static utilities
65 | ({ addUtilities }): void => {
66 | addUtilities(prefixed)
67 | },
68 |
69 | // dynamic utilities
70 | ({ matchUtilities }): void => {
71 | matchUtilities(
72 | { 'animate-duration': (value) => ({ animationDuration: value }) },
73 | { values: duration },
74 | )
75 |
76 | matchUtilities(
77 | { 'animate-ease': (value) => ({ animationTimingFunction: `cubic-bezier(${value})` }) },
78 | { values: ease },
79 | )
80 |
81 | matchUtilities(
82 | {
83 | 'animate-steps-start': (value) => ({
84 | animationTimingFunction: `steps(${value},jump-start)`,
85 | }),
86 | },
87 | { values: repeat },
88 | )
89 |
90 | matchUtilities(
91 | {
92 | 'animate-steps-end': (value) => ({ animationTimingFunction: `steps(${value},jump-end)` }),
93 | },
94 | { values: repeat },
95 | )
96 |
97 | matchUtilities(
98 | {
99 | 'animate-steps-both': (value) => ({
100 | animationTimingFunction: `steps(${value},jump-both)`,
101 | }),
102 | },
103 | { values: repeat },
104 | )
105 |
106 | matchUtilities(
107 | {
108 | 'animate-steps-none': (value) => ({
109 | animationTimingFunction: `steps(${value},jump-none)`,
110 | }),
111 | },
112 | { values: repeat },
113 | )
114 |
115 | matchUtilities({ 'animate-delay': (value) => ({ animationDelay: value }) }, { values: delay })
116 |
117 | matchUtilities(
118 | { 'animate-repeat': (value) => ({ animationIterationCount: value }) },
119 | { values: repeat },
120 | )
121 |
122 | matchUtilities(
123 | { 'animate-fill': (value) => ({ animationFillMode: value }) },
124 | { values: fill },
125 | )
126 |
127 | matchUtilities(
128 | { 'animate-distance': (value) => ({ '--animate-distance': value }) },
129 | { values: distance },
130 | )
131 | },
132 | ]
133 |
134 | const configPlugins = config.plugins ?? []
135 | config.plugins = [...plugins, ...configPlugins]
136 |
137 | return config
138 | }
139 |
--------------------------------------------------------------------------------
/src/keyframes.ts:
--------------------------------------------------------------------------------
1 | import type { Keyframes } from './types.js'
2 |
3 | export const keyframes: Keyframes = {
4 | twSpin: {
5 | from: { transform: 'rotate3d(0, 0, 1, 0)' },
6 | to: { transform: 'rotate3d(0, 0, 1, 360deg)' },
7 | },
8 | twPing: { '75%, 100%': { transform: 'scale3d(2, 2, 1)', opacity: '0' } },
9 | twPulse: { '0%, 100%': { opacity: 1 }, '50%': { opacity: '0.5' } },
10 | twBounce: {
11 | '0%, 100%': {
12 | transform: 'translate3d(0, -25%, 0)',
13 | animationTimingFunction: 'cubic-bezier(0.8, 0, 1, 1)',
14 | },
15 | '50%': {
16 | transform: 'translate3d(0, 0, 0)',
17 | animationTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)',
18 | },
19 | },
20 | bounce: {
21 | 'from, 20%, 53%, to': {
22 | animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
23 | transform: 'translate3d(0, 0, 0)',
24 | },
25 | '40%, 43%': {
26 | animationTimingFunction: 'cubic-bezier(0.755, 0.05, 0.855, 0.06)',
27 | transform: 'translate3d(0, -30px, 0) scale3d(1, 1.1, 1)',
28 | },
29 | '70%': {
30 | animationTimingFunction: 'cubic-bezier(0.755, 0.05, 0.855, 0.06)',
31 | transform: 'translate3d(0, -15px, 0) scale3d(1, 1.05, 1)',
32 | },
33 | '80%': {
34 | animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
35 | transform: 'translate3d(0, 0, 0) scale3d(1, 0.95, 1)',
36 | },
37 | '90%': { transform: 'translate3d(0, -4px, 0) scale3d(1, 1.02, 1)' },
38 | },
39 | flash: { '25%, 75%': { opacity: '0' }, '50%': { opacity: '1' } },
40 | pulse: { '50%': { transform: 'scale3d(1.05, 1.05, 1.05)' } },
41 | rubberBand: {
42 | '30%': { transform: 'scale3d(1.25, 0.75, 1)' },
43 | '40%': { transform: 'scale3d(0.75, 1.25, 1)' },
44 | '50%': { transform: 'scale3d(1.15, 0.85, 1)' },
45 | '65%': { transform: 'scale3d(0.95, 1.05, 1)' },
46 | '75%': { transform: 'scale3d(1.05, 0.95, 1)' },
47 | },
48 | shakeX: {
49 | '10%, 30%, 50%, 70%, 90%': { transform: 'translate3d(-10px, 0, 0)' },
50 | '20%, 40%, 60%, 80%': { transform: 'translate3d(10px, 0, 0)' },
51 | },
52 | shakeY: {
53 | '10%, 30%, 50%, 70%, 90%': { transform: 'translate3d(0, -10px, 0)' },
54 | '20%, 40%, 60%, 80%': { transform: 'translate3d(0, 10px, 0)' },
55 | },
56 | headShake: {
57 | '6.5%': { transform: 'translate3d(-6px, 0, 0) rotate3d(0, 1, 0, -9deg)' },
58 | '18.5%': { transform: 'translate3d(5px, 0, 0) rotate3d(0, 1, 0, 7deg)' },
59 | '31.5%': { transform: 'translate3d(-3px, 0, 0) rotate3d(0, 1, 0, -5deg)' },
60 | '43.5%': { transform: 'translate3d(2px, 0, 0) rotate3d(0, 1, 0, 3deg)' },
61 | '50%': { transform: 'translate3d(0, 0, 0)' },
62 | },
63 | swing: {
64 | '20%': { transform: 'rotate3d(0, 0, 1, 15deg)' },
65 | '40%': { transform: 'rotate3d(0, 0, 1, -10deg)' },
66 | '60%': { transform: 'rotate3d(0, 0, 1, 5deg)' },
67 | '80%': { transform: 'rotate3d(0, 0, 1, -5deg)' },
68 | },
69 | tada: {
70 | '10%, 20%': { transform: 'scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg)' },
71 | '30%, 50%, 70%, 90%': { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg)' },
72 | '40%, 60%, 80%': { transform: 'scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg)' },
73 | },
74 | wobble: {
75 | '15%': { transform: 'translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg)' },
76 | '30%': { transform: 'translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg)' },
77 | '45%': { transform: 'translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg)' },
78 | '60%': { transform: 'translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg)' },
79 | '75%': { transform: 'translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg)' },
80 | },
81 | jello: {
82 | '11.1%': { transform: 'translate3d(0, 0, 0)' },
83 | '22.2%': { transform: 'skew(-12.5deg, -12.5deg)' },
84 | '33.3%': { transform: 'skew(6.25deg, 6.25deg)' },
85 | '44.4%': { transform: 'skew(-3.125deg, -3.125deg)' },
86 | '55.5%': { transform: 'skew(1.5625deg, 1.5625deg)' },
87 | '66.6%': { transform: 'skew(-0.78125deg, -0.78125deg)' },
88 | '77.7%': { transform: 'skew(0.390625deg, 0.390625deg)' },
89 | '88.8%': { transform: 'skew(-0.1953125deg, -0.1953125deg)' },
90 | },
91 | heartBeat: {
92 | '14%': { transform: 'scale3d(1.3, 1.3, 1.3)' },
93 | '28%': { transform: 'scale3d(1, 1, 1)' },
94 | '42%': { transform: 'scale3d(1.3, 1.3, 1.3)' },
95 | '70%': { transform: 'scale3d(1, 1, 1)' },
96 | },
97 | backInDown: {
98 | from: {
99 | transform: 'translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0) scale3d(0, 0, 1)',
100 | },
101 | '80%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
102 | },
103 | backInLeft: {
104 | from: {
105 | transform: 'translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0) scale3d(0, 0, 1)',
106 | },
107 | '80%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
108 | },
109 | backInRight: {
110 | from: { transform: 'translate3d(var(--animate-distance, 2000px), 0, 0) scale3d(0, 0, 1)' },
111 | '80%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
112 | },
113 | backInUp: {
114 | from: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0) scale3d(0, 0, 1)' },
115 | '80%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
116 | },
117 | backOutDown: {
118 | '20%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
119 | to: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0) scale3d(0, 0, 1)' },
120 | },
121 | backOutLeft: {
122 | '20%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
123 | to: {
124 | transform: 'translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0) scale3d(0, 0, 1)',
125 | },
126 | },
127 | backOutRight: {
128 | '20%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
129 | to: { transform: 'translate3d(var(--animate-distance, 2000px), 0, 0) scale3d(0, 0, 1)' },
130 | },
131 | backOutUp: {
132 | '20%': { opacity: '0.7', transform: 'translate3d(0, 0, 0) scale3d(0.7, 0.7, 1)' },
133 | to: {
134 | transform: 'translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0) scale3d(0, 0, 1)',
135 | },
136 | },
137 | bounceIn: {
138 | from: { transform: 'scale3d(0.3, 0.3, 0.3)' },
139 | '20%': { transform: 'scale3d(1.1, 1.1, 1.1)' },
140 | '40%': { transform: 'scale3d(0.9, 0.9, 0.9)' },
141 | '60%': { opacity: '1', transform: 'scale3d(1.03, 1.03, 1.03)' },
142 | '80%': { transform: 'scale3d(0.97, 0.97, 0.97)' },
143 | },
144 | bounceInDown: {
145 | from: {
146 | transform: 'translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0) scale3d(1, 3, 1)',
147 | },
148 | '60%': { opacity: '1', transform: 'translate3d(0, 20px, 0) scale3d(1, 0.9, 1)' },
149 | '75%': { transform: 'translate3d(0, -10px, 0) scale3d(1, 0.95, 1)' },
150 | '90%': { transform: 'translate3d(0, 5px, 0) scale3d(1, 0.985, 1)' },
151 | },
152 | bounceInLeft: {
153 | from: {
154 | transform: 'translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0) scale3d(3, 1, 1)',
155 | },
156 | '60%': { opacity: '1', transform: 'translate3d(25px, 0, 0) scale3d(1, 1, 1)' },
157 | '75%': { transform: 'translate3d(-10px, 0, 0) scale3d(1, 0.98, 1)' },
158 | '90%': { transform: 'translate3d(5px, 0, 0) scale3d(1, 0.995, 1)' },
159 | },
160 | bounceInRight: {
161 | from: { transform: 'translate3d(var(--animate-distance, 2000px), 0, 0) scale3d(3, 1, 1)' },
162 | '60%': { opacity: '1', transform: 'translate3d(-25px, 0, 0) scale3d(1, 1, 1)' },
163 | '75%': { transform: 'translate3d(10px, 0, 0) scale3d(1, 0.98, 1)' },
164 | '90%': { transform: 'translate3d(-5px, 0, 0) scale3d(1, 0.995, 1)' },
165 | },
166 | bounceInUp: {
167 | from: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0) scale3d(1, 3, 1)' },
168 | '60%': { opacity: '1', transform: 'translate3d(0, -20px, 0) scale3d(1, 0.9, 1)' },
169 | '75%': { transform: 'translate3d(0, 10px, 0) scale3d(1, 0.95, 1)' },
170 | '90%': { transform: 'translate3d(0, -5px, 0) scale3d(1, 0.985, 1)' },
171 | },
172 | bounceOut: {
173 | '20%': { transform: 'scale3d(0.9, 0.9, 0.9)' },
174 | '50%, 55%': { opacity: '1', transform: 'scale3d(1.1, 1.1, 1.1)' },
175 | to: { transform: 'scale3d(0.3, 0.3, 0.3)' },
176 | },
177 | bounceOutDown: {
178 | '20%': { transform: 'translate3d(0, 10px, 0) scale3d(1, 0.985, 1)' },
179 | '40%, 45%': { opacity: '1', transform: 'translate3d(0, -20px, 0) scale3d(1, 0.9, 1)' },
180 | to: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0) scale3d(1, 3, 1)' },
181 | },
182 | bounceOutLeft: {
183 | '20%': { opacity: '1', transform: 'translate3d(20px, 0, 0) scale3d(0.9, 1, 1)' },
184 | to: {
185 | transform: 'translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0) scale3d(2, 1, 1)',
186 | },
187 | },
188 | bounceOutRight: {
189 | '20%': { opacity: '1', transform: 'translate3d(-20px, 0, 0) scale3d(0.9, 1, 1)' },
190 | to: { transform: 'translate3d(var(--animate-distance, 2000px), 0, 0) scale3d(2, 1, 1)' },
191 | },
192 | bounceOutUp: {
193 | '20%': { transform: 'translate3d(0, -10px, 0) scale3d(1, 0.985, 1)' },
194 | '40%, 45%': { opacity: '1', transform: 'translate3d(0, 20px, 0) scale3d(1, 0.9, 1)' },
195 | to: {
196 | transform: 'translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0) scale3d(1, 3, 1)',
197 | },
198 | },
199 | fadeIn: {},
200 | fadeInDown: { from: { transform: 'translate3d(0, -100%, 0)' } },
201 | fadeInDownBig: {
202 | from: { transform: 'translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0)' },
203 | },
204 | fadeInLeft: { from: { transform: 'translate3d(-100%, 0, 0)' } },
205 | fadeInLeftBig: {
206 | from: { transform: 'translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0)' },
207 | },
208 | fadeInRight: { from: { transform: 'translate3d(100%, 0, 0)' } },
209 | fadeInRightBig: { from: { transform: 'translate3d(var(--animate-distance, 2000px), 0, 0)' } },
210 | fadeInUp: { from: { transform: 'translate3d(0, 100%, 0)' } },
211 | fadeInUpBig: { from: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0)' } },
212 | fadeInTopLeft: { from: { transform: 'translate3d(-100%, -100%, 0)' } },
213 | fadeInTopRight: { from: { transform: 'translate3d(100%, -100%, 0)' } },
214 | fadeInBottomLeft: { from: { transform: 'translate3d(-100%, 100%, 0)' } },
215 | fadeInBottomRight: { from: { transform: 'translate3d(100%, 100%, 0)' } },
216 | fadeOut: {},
217 | fadeOutDown: { to: { transform: 'translate3d(0, 100%, 0)' } },
218 | fadeOutDownBig: { to: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0)' } },
219 | fadeOutLeft: { to: { transform: 'translate3d(-100%, 0, 0)' } },
220 | fadeOutLeftBig: {
221 | to: { transform: 'translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0)' },
222 | },
223 | fadeOutRight: { to: { transform: 'translate3d(100%, 0, 0)' } },
224 | fadeOutRightBig: { to: { transform: 'translate3d(var(--animate-distance, 2000px), 0, 0)' } },
225 | fadeOutUp: { to: { transform: 'translate3d(0, -100%, 0)' } },
226 | fadeOutUpBig: {
227 | to: { transform: 'translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0)' },
228 | },
229 | fadeOutTopLeft: { to: { transform: 'translate3d(-100%, -100%, 0)' } },
230 | fadeOutTopRight: { to: { transform: 'translate3d(100%, -100%, 0)' } },
231 | fadeOutBottomRight: { to: { transform: 'translate3d(100%, 100%, 0)' } },
232 | fadeOutBottomLeft: { to: { transform: 'translate3d(-100%, 100%, 0)' } },
233 | flip: {
234 | from: {
235 | animationTimingFunction: 'ease-out',
236 | transform:
237 | 'perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, -360deg)',
238 | },
239 | '40%': {
240 | animationTimingFunction: 'ease-out',
241 | transform:
242 | 'perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg)',
243 | },
244 | '50%': {
245 | animationTimingFunction: 'ease-in',
246 | transform:
247 | 'perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg)',
248 | },
249 | '80%': {
250 | animationTimingFunction: 'ease-in',
251 | transform:
252 | 'perspective(400px) scale3d(0.95, 0.95, 0.95) translate3d(0, 0, 0) rotate3d(0, 1, 0, 0deg)',
253 | },
254 | to: {
255 | animationTimingFunction: 'ease-in',
256 | transform: 'perspective(400px) scale3d(1, 1, 1) translate3d(0, 0, 0) rotate3d(0, 1, 0, 0deg)',
257 | },
258 | },
259 | flipInX: {
260 | from: {
261 | animationTimingFunction: 'ease-in',
262 | transform: 'perspective(400px) rotate3d(1, 0, 0, 90deg)',
263 | },
264 | '40%': {
265 | animationTimingFunction: 'ease-in',
266 | transform: 'perspective(400px) rotate3d(1, 0, 0, -20deg)',
267 | },
268 | '60%': { opacity: '1', transform: 'perspective(400px) rotate3d(1, 0, 0, 10deg)' },
269 | '80%': { transform: 'perspective(400px) rotate3d(1, 0, 0, -5deg)' },
270 | to: { transform: 'perspective(400px)' },
271 | },
272 | flipInY: {
273 | from: {
274 | animationTimingFunction: 'ease-in',
275 | transform: 'perspective(400px) rotate3d(0, 1, 0, 90deg)',
276 | },
277 | '40%': {
278 | animationTimingFunction: 'ease-in',
279 | transform: 'perspective(400px) rotate3d(0, 1, 0, -20deg)',
280 | },
281 | '60%': { opacity: '1', transform: 'perspective(400px) rotate3d(0, 1, 0, 10deg)' },
282 | '80%': { transform: 'perspective(400px) rotate3d(0, 1, 0, -5deg)' },
283 | to: { transform: 'perspective(400px)' },
284 | },
285 | flipOutX: {
286 | from: { transform: 'perspective(400px)' },
287 | '30%': { opacity: '1', transform: 'perspective(400px) rotate3d(1, 0, 0, -20deg)' },
288 | to: { transform: 'perspective(400px) rotate3d(1, 0, 0, 90deg)' },
289 | },
290 | flipOutY: {
291 | from: { transform: 'perspective(400px)' },
292 | '30%': { opacity: '1', transform: 'perspective(400px) rotate3d(0, 1, 0, -15deg)' },
293 | to: { transform: 'perspective(400px) rotate3d(0, 1, 0, 90deg)' },
294 | },
295 | lightSpeedInRight: {
296 | from: { transform: 'translate3d(100%, 0, 0) skew(-30deg)' },
297 | '60%': { opacity: '1', transform: 'skew(20deg)' },
298 | '80%': { transform: 'skew(-5deg)' },
299 | },
300 | lightSpeedInLeft: {
301 | from: { transform: 'translate3d(-100%, 0, 0) skew(30deg)' },
302 | '60%': { opacity: '1', transform: 'skew(-20deg)' },
303 | '80%': { transform: 'skew(5deg)' },
304 | },
305 | lightSpeedOutRight: { to: { transform: 'translate3d(100%, 0, 0) skew(30deg)' } },
306 | lightSpeedOutLeft: { to: { transform: 'translate3d(-100%, 0, 0) skew(-30deg)' } },
307 | rotateIn: { from: { transform: 'rotate3d(0, 0, 1, -200deg)' } },
308 | rotateInDownLeft: { from: { transform: 'rotate3d(0, 0, 1, -45deg)' } },
309 | rotateInDownRight: { from: { transform: 'rotate3d(0, 0, 1, 45deg)' } },
310 | rotateInUpLeft: { from: { transform: 'rotate3d(0, 0, 1, 45deg)' } },
311 | rotateInUpRight: { from: { transform: 'rotate3d(0, 0, 1, -90deg)' } },
312 | rotateOut: { to: { transform: 'rotate3d(0, 0, 1, 200deg)' } },
313 | rotateOutDownLeft: { to: { transform: 'rotate3d(0, 0, 1, 45deg)' } },
314 | rotateOutDownRight: { to: { transform: 'rotate3d(0, 0, 1, -45deg)' } },
315 | rotateOutUpLeft: { to: { transform: 'rotate3d(0, 0, 1, -45deg)' } },
316 | rotateOutUpRight: { to: { transform: 'rotate3d(0, 0, 1, 90deg)' } },
317 | hinge: {
318 | '20%, 60%': { transform: 'rotate3d(0, 0, 1, 80deg)' },
319 | '40%, 80%': { opacity: '1', transform: 'rotate3d(0, 0, 1, 60deg)' },
320 | to: { transform: 'translate3d(0, var(--animate-distance, 1000px), 0)' },
321 | },
322 | jackInTheBox: {
323 | from: {
324 | transform: 'scale3d(0.1, 0.1, 1) rotate3d(0, 0, 1, 30deg)',
325 | transformOrigin: 'center bottom',
326 | },
327 | '50%': { transform: 'rotate3d(0, 0, 1, -10deg)' },
328 | '70%': { transform: 'rotate3d(0, 0, 1, 3deg)' },
329 | },
330 | rollIn: { from: { transform: 'translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg)' } },
331 | rollOut: { to: { transform: 'translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg)' } },
332 | zoomIn: { from: { transform: 'scale3d(0.3, 0.3, 0.3)' }, '50%': { opacity: '1' } },
333 | zoomInDown: {
334 | from: {
335 | animationTimingFunction: 'cubic-bezier(0.55, 0.055, 0.675, 0.19)',
336 | transform:
337 | 'scale3d(0.1, 0.1, 0.1) translate3d(0, calc(-1 * var(--animate-distance, 2000px)), 0)',
338 | },
339 | '60%': {
340 | animationTimingFunction: 'cubic-bezier(0.175, 0.885, 0.32, 1)',
341 | opacity: '1',
342 | transform: 'scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0)',
343 | },
344 | },
345 | zoomInLeft: {
346 | from: {
347 | animationTimingFunction: 'cubic-bezier(0.55, 0.055, 0.675, 0.19)',
348 | transform:
349 | 'scale3d(0.1, 0.1, 0.1) translate3d(calc(-1 * var(--animate-distance, 1000px)), 0, 0)',
350 | },
351 | '60%': {
352 | animationTimingFunction: 'cubic-bezier(0.175, 0.885, 0.32, 1)',
353 | opacity: '1',
354 | transform: 'scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0)',
355 | },
356 | },
357 | zoomInRight: {
358 | from: {
359 | animationTimingFunction: 'cubic-bezier(0.55, 0.055, 0.675, 0.19)',
360 | transform: 'scale3d(0.1, 0.1, 0.1) translate3d(var(--animate-distance, 1000px), 0, 0)',
361 | },
362 | '60%': {
363 | animationTimingFunction: 'cubic-bezier(0.175, 0.885, 0.32, 1)',
364 | opacity: '1',
365 | transform: 'scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0)',
366 | },
367 | },
368 | zoomInUp: {
369 | from: {
370 | animationTimingFunction: 'cubic-bezier(0.55, 0.055, 0.675, 0.19)',
371 | transform: 'scale3d(0.1, 0.1, 0.1) translate3d(0, var(--animate-distance, 2000px), 0)',
372 | },
373 | '60%': {
374 | animationTimingFunction: 'cubic-bezier(0.175, 0.885, 0.32, 1)',
375 | opacity: '1',
376 | transform: 'scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0)',
377 | },
378 | },
379 | zoomOut: { '50%': { opacity: '0', transform: 'scale3d(0.3, 0.3, 0.3)' } },
380 | zoomOutDown: {
381 | '40%': {
382 | animationTimingFunction: 'cubic-bezier(0.55, 0.055, 0.675, 0.19)',
383 | opacity: '1',
384 | transform: 'scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0)',
385 | },
386 | to: {
387 | animationTimingFunction: 'cubic-bezier(0.175, 0.885, 0.32, 1)',
388 | transform: 'scale3d(0.1, 0.1, 0.1) translate3d(0, var(--animate-distance, 1000px), 0)',
389 | },
390 | },
391 | zoomOutLeft: {
392 | '40%': { opacity: '1', transform: 'scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0)' },
393 | to: {
394 | transform:
395 | 'scale3d(0.1, 0.1, 1) translate3d(calc(-1 * var(--animate-distance, 2000px)), 0, 0)',
396 | },
397 | },
398 | zoomOutRight: {
399 | '40%': { opacity: '1', transform: 'scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0)' },
400 | to: { transform: 'scale3d(0.1, 0.1, 1) translate3d(var(--animate-distance, 2000px), 0, 0)' },
401 | },
402 | zoomOutUp: {
403 | '40%': {
404 | animationTimingFunction: 'cubic-bezier(0.55, 0.055, 0.675, 0.19)',
405 | opacity: '1',
406 | transform: 'scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0)',
407 | },
408 | to: {
409 | animationTimingFunction: 'cubic-bezier(0.175, 0.885, 0.32, 1)',
410 | transform:
411 | 'scale3d(0.1, 0.1, 0.1) translate3d(0, calc(-1 * var(--animate-distance, 1000px)), 0)',
412 | },
413 | },
414 | slideInDown: { from: { transform: 'translate3d(0, -100%, 0)' } },
415 | slideInLeft: { from: { transform: 'translate3d(-100%, 0, 0)' } },
416 | slideInRight: { from: { transform: 'translate3d(100%, 0, 0)' } },
417 | slideInUp: { from: { transform: 'translate3d(0, 100%, 0)' } },
418 | slideOutDown: { to: { transform: 'translate3d(0, 100%, 0)' } },
419 | slideOutLeft: { to: { transform: 'translate3d(-100%, 0, 0)' } },
420 | slideOutRight: { to: { transform: 'translate3d(100%, 0, 0)' } },
421 | slideOutUp: { to: { transform: 'translate3d(0, -100%, 0)' } },
422 | }
423 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | // https://github.com/tailwindlabs/play.tailwindcss.com/tree/master/src/monaco/ *.d.ts
2 |
3 | import type * as CSS from 'csstype'
4 | import type * as postcss from 'postcss'
5 |
6 | export type KeyValuePair = Record
7 |
8 | export type CSSProperties = CSS.Properties & Record<`--${string}`, string>
9 |
10 | export type CSSBlock = Record
11 |
12 | export type Keyframes = Record
13 |
14 | export type ConfigUtils = {
15 | negative: (input: TInput) => TOutput
16 | breakpoints: (input: TInput) => TOutput
17 | }
18 |
19 | export type ConfigDotNotationPath = string
20 |
21 | export type ResolvableTo =
22 | | TResult
23 | | ((theme: (path: ConfigDotNotationPath) => TResult, utils: ConfigUtils) => TResult)
24 |
25 | export type BaseConfig = {
26 | important: boolean | string
27 | target: 'ie11' | 'relaxed'
28 | prefix: string | ((className: string) => string)
29 | separator: string
30 | }
31 |
32 | export type PurgeConfig =
33 | | Array
34 | | false
35 | | { enabled: boolean; mode: 'all' | 'conservative'; content: Array }
36 | | { enabled: boolean; options: { content: Array; whitelist: Array } }
37 |
38 | export type ContentConfig =
39 | | Array
40 | | {
41 | files: Array
42 | safelist?: Array }>
43 | transform?: Record string>
44 | extract?: Record Array>
45 | }
46 |
47 | export type FutureConfig = Record | 'all' | []
48 |
49 | export type ExperimentalConfig = Record | 'all' | []
50 |
51 | export type DarkModeConfig = 'class' | 'media' | false
52 |
53 | export type BaseThemeConfig = {
54 | extend: Partial>
55 |
56 | /** Responsiveness */
57 | screens: ResolvableTo
58 |
59 | /** Reusable base configs */
60 | colors: ResolvableTo>>
61 | spacing: ResolvableTo
62 |
63 | /** Background */
64 | backgroundColor: BaseThemeConfig['colors']
65 | backgroundImage: ResolvableTo
66 | gradientColorStops: BaseThemeConfig['colors']
67 | backgroundOpacity: BaseThemeConfig['opacity']
68 | backgroundPosition: ResolvableTo
69 | backgroundSize: ResolvableTo
70 | backgroundOrigin: ResolvableTo
71 |
72 | /** Border */
73 | borderColor: BaseThemeConfig['colors']
74 | borderOpacity: BaseThemeConfig['opacity']
75 | borderRadius: ResolvableTo
76 | borderWidth: ResolvableTo
77 |
78 | /** Shadow */
79 | boxShadow: ResolvableTo
80 |
81 | /** Outline */
82 | outline: ResolvableTo
83 |
84 | /** Cursor */
85 | cursor: ResolvableTo
86 |
87 | /** Content */
88 | content: ResolvableTo
89 |
90 | /** Divider */
91 | divideColor: BaseThemeConfig['borderColor']
92 | divideOpacity: BaseThemeConfig['borderOpacity']
93 | devideWidth: BaseThemeConfig['borderWidth']
94 |
95 | /** SVG */
96 | fill: ResolvableTo
97 | stroke: ResolvableTo
98 | strokeWidth: ResolvableTo
99 |
100 | /** Flexbox */
101 | flex: ResolvableTo
102 | flexGrow: ResolvableTo
103 | flexShrink: ResolvableTo
104 |
105 | /** Fonts */
106 | fontFamily: ResolvableTo>>
107 | fontSize: ResolvableTo
108 | fontWeight: ResolvableTo
109 |
110 | /** Sizes */
111 | height: BaseThemeConfig['spacing']
112 | minHeight: ResolvableTo
113 | maxHeight: ResolvableTo
114 | width: BaseThemeConfig['spacing']
115 | minWidth: ResolvableTo
116 | maxWidth: ResolvableTo
117 | aspectRatio: ResolvableTo
118 |
119 | /** Positioning */
120 | inset: ResolvableTo
121 | zIndex: ResolvableTo
122 |
123 | /** Text */
124 | letterSpacing: ResolvableTo
125 | lineHeight: ResolvableTo
126 | textColor: BaseThemeConfig['colors']
127 | textOpacity: BaseThemeConfig['opacity']
128 | textIndent: BaseThemeConfig['spacing']
129 |
130 | /** Input */
131 | placeholderColor: BaseThemeConfig['colors']
132 | placeholderOpacity: BaseThemeConfig['opacity']
133 | caretColor: BaseThemeConfig['colors']
134 |
135 | /** Lists */
136 | listStyleType: ResolvableTo
137 |
138 | /** Layout */
139 | margin: BaseThemeConfig['spacing']
140 | padding: BaseThemeConfig['spacing']
141 | space: BaseThemeConfig['spacing']
142 | opacity: ResolvableTo
143 | order: ResolvableTo
144 | columns: ResolvableTo
145 |
146 | /** Images */
147 | objectPosition: ResolvableTo
148 |
149 | /** Grid */
150 | gap: BaseThemeConfig['spacing']
151 | gridTemplateColumns: ResolvableTo
152 | gridColumn: ResolvableTo
153 | gridColumnStart: ResolvableTo
154 | gridColumnEnd: ResolvableTo
155 | gridTemplateRows: ResolvableTo
156 | gridRow: ResolvableTo
157 | gridRowStart: ResolvableTo
158 | gridRowEnd: ResolvableTo
159 |
160 | /** Transformations */
161 | transformOrigin: ResolvableTo
162 | scale: ResolvableTo
163 | rotate: ResolvableTo
164 | translate: BaseThemeConfig['spacing']
165 | skew: ResolvableTo
166 |
167 | /** Transitions */
168 | transitionProperty: ResolvableTo
169 | transitionTimingFunction: ResolvableTo
170 | transitionDuration: ResolvableTo
171 | transitionDelay: ResolvableTo
172 | willChange: ResolvableTo
173 |
174 | /** Animations */
175 | animation: ResolvableTo
176 | keyframes: ResolvableTo
177 |
178 | /** Filters */
179 | blur: ResolvableTo | string>>
180 | brightness: ResolvableTo | string>>
181 | contrast: ResolvableTo | string>>
182 | dropShadow: ResolvableTo | string>>
183 | grayscale: ResolvableTo | string>>
184 | hueRotate: ResolvableTo | string>>
185 | invert: ResolvableTo | string>>
186 | saturate: ResolvableTo | string>>
187 | sepia: ResolvableTo | string>>
188 | backdropFilter: ResolvableTo | string>>
189 | backdropBlur: ResolvableTo | string>>
190 | backdropBrightness: ResolvableTo | string>>
191 | backdropContrast: ResolvableTo | string>>
192 | backdropGrayscale: ResolvableTo | string>>
193 | backdropHueRotate: ResolvableTo | string>>
194 | backdropInvert: ResolvableTo | string>>
195 | backdropOpacity: ResolvableTo | string>>
196 | backdropSaturate: ResolvableTo | string>>
197 | backdropSepia: ResolvableTo | string>>
198 |
199 | /** Components */
200 | container: Partial<{
201 | screens: Array | Record | Record
202 | center: boolean
203 | padding: KeyValuePair | string
204 | }>
205 | }
206 |
207 | export type ThemeConfig = Partial>
208 |
209 | export type VariantsAPI = {
210 | variants: (path: string) => Array
211 |
212 | before: (
213 | toInsert: Array,
214 | variant?: string,
215 | existingPluginVariants?: Array,
216 | ) => Array
217 |
218 | after: (
219 | toInsert: Array,
220 | variant?: string,
221 | existingPluginVariants?: Array,
222 | ) => Array
223 |
224 | without: (toRemove: Array, existingPluginVariants?: Array) => Array
225 | }
226 |
227 | export type VariantsConfig =
228 | | Array
229 | | Record | ((api: VariantsAPI) => Array)>
230 | | { extend: Record> }
231 |
232 | export type CorePluginsConfig = Array | Record
233 |
234 | export type VariantConfig =
235 | | Array
236 | | Partial<{ variants: Array; respectPrefix: false; respectImportant: false }>
237 |
238 | export type ValueType =
239 | | 'absolute-size'
240 | | 'any'
241 | | 'color'
242 | | 'family-name'
243 | | 'generic-name'
244 | | 'image'
245 | | 'length'
246 | | 'line-width'
247 | | 'lookup'
248 | | 'number'
249 | | 'percentage'
250 | | 'position'
251 | | 'relative-size'
252 | | 'url'
253 |
254 | export type PluginAPI = {
255 | /** Get access to the whole config */
256 | config: (
257 | path?: ConfigDotNotationPath,
258 | defaultValue?: TDefaultValue,
259 | ) => TDefaultValue
260 |
261 | /** Escape classNames */
262 | e: (className: string) => string
263 |
264 | /** Shortcut for the theme section of the config */
265 | theme: (path: ConfigDotNotationPath, defaultValue?: TDefaultValue) => TDefaultValue
266 |
267 | variants: (
268 | path: ConfigDotNotationPath,
269 | defaultValue: TDefaultValue,
270 | ) => TDefaultValue
271 |
272 | target: (path: ConfigDotNotationPath) => string
273 |
274 | prefix: (selector: string) => string
275 |
276 | /** Ability to add utilities. E.g.: .p-4 */
277 | addUtilities: (utilities: CSSBlock, variantConfig?: VariantConfig) => void
278 |
279 | /** Ability to add components. E.g.: .btn */
280 | addComponents: (components: CSSBlock, variantConfig?: VariantConfig) => void
281 |
282 | addBase: (base: CSSBlock) => void
283 |
284 | addVariant: (
285 | name: string,
286 | generator: (api: {
287 | container: postcss.Container
288 | separator: string
289 | modifySelectors: (
290 | modifierFunction: (api: { className: string; selector: string }) => void,
291 | ) => void
292 | }) => void,
293 | ) => void
294 |
295 | matchUtilities: (
296 | utilities: Record CSSProperties>,
297 | options?: Partial<{
298 | values: Record
299 | type: Array | ValueType
300 | respectPrefix: boolean
301 | respectImportant: boolean
302 | respectVariants: boolean
303 | }>,
304 | ) => void
305 |
306 | corePlugins: (path: string) => boolean
307 |
308 | postcss: typeof postcss
309 | }
310 |
311 | export type PluginCreator = (api: PluginAPI) => void
312 |
313 | export type PluginsConfig = Array<
314 | PluginCreator | { handler: PluginCreator; config?: TailwindConfig }
315 | >
316 |
317 | /** The holy grail Tailwind config definition */
318 | export type TailwindConfig = Partial<
319 | BaseConfig &
320 | Record & {
321 | presets: Array
322 | future: FutureConfig
323 | experimental: ExperimentalConfig
324 | purge: PurgeConfig
325 | content: ContentConfig
326 | darkMode: DarkModeConfig
327 | theme: ThemeConfig
328 | variants: VariantsConfig
329 | corePlugins: CorePluginsConfig
330 | plugins: PluginsConfig
331 | mode: 'aot' | 'jit'
332 | }
333 | >
334 |
335 | export type EntryPoint = (config: TailwindConfig) => TailwindConfig
336 |
--------------------------------------------------------------------------------
/src/utilities.ts:
--------------------------------------------------------------------------------
1 | import type { CSSBlock } from './types.js'
2 |
3 | export const keyframeUtils: CSSBlock = {
4 | twSpin: { animationTimingFunction: 'linear' },
5 | twPing: { animationTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)' },
6 | twPulse: { animationDuration: '2s', animationTimingFunction: 'cubic-bezier(0.4, 0, 0.6, 1)' },
7 | bounce: { transformOrigin: 'center bottom' },
8 | pulse: { animationTimingFunction: 'ease-in-out' },
9 | headShake: { animationTimingFunction: 'ease-in-out' },
10 | swing: { transformOrigin: 'top center' },
11 | jello: { transformOrigin: 'center' },
12 | heartBeat: { animationDuration: '1.3s', animationTimingFunction: 'ease-in-out' },
13 | bounceIn: {
14 | animationDuration: '0.75s',
15 | animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
16 | },
17 | bounceInDown: { animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)' },
18 | bounceInLeft: { animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)' },
19 | bounceInRight: { animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)' },
20 | bounceInUp: { animationTimingFunction: 'cubic-bezier(0.215, 0.61, 0.355, 1)' },
21 | bounceOut: { animationDuration: '0.75s' },
22 | flip: { backfaceVisibility: 'visible' },
23 | flipInX: { backfaceVisibility: 'visible' },
24 | flipInY: { backfaceVisibility: 'visible' },
25 | flipOutX: { animationDuration: '0.75s', backfaceVisibility: 'visible' },
26 | flipOutY: { animationDuration: '0.75s', backfaceVisibility: 'visible' },
27 | lightSpeedInRight: { animationTimingFunction: 'ease-out' },
28 | lightSpeedInLeft: { animationTimingFunction: 'ease-out' },
29 | lightSpeedOutRight: { animationTimingFunction: 'ease-in' },
30 | lightSpeedOutLeft: { animationTimingFunction: 'ease-in' },
31 | rotateIn: { transformOrigin: 'center' },
32 | rotateInDownLeft: { transformOrigin: 'left bottom' },
33 | rotateInDownRight: { transformOrigin: 'right bottom' },
34 | rotateInUpLeft: { transformOrigin: 'left bottom' },
35 | rotateInUpRight: { transformOrigin: 'right bottom' },
36 | rotateOut: { transformOrigin: 'center' },
37 | rotateOutDownLeft: { transformOrigin: 'left bottom' },
38 | rotateOutDownRight: { transformOrigin: 'right bottom' },
39 | rotateOutUpLeft: { transformOrigin: 'left bottom' },
40 | rotateOutUpRight: { transformOrigin: 'right bottom' },
41 | hinge: {
42 | animationDuration: '2s',
43 | animationTimingFunction: 'ease-in-out',
44 | transformOrigin: 'top left',
45 | },
46 | zoomOutDown: { transformOrigin: 'center bottom' },
47 | zoomOutLeft: { transformOrigin: 'left center' },
48 | zoomOutRight: { transformOrigin: 'right center' },
49 | zoomOutUp: { transformOrigin: 'center bottom' },
50 | }
51 |
52 | export const animationUtils: CSSBlock = {
53 | none: { animation: 'none' },
54 |
55 | faster: { animationDuration: '0.5s' },
56 | fast: { animationDuration: '0.8s' },
57 | slow: { animationDuration: '2s' },
58 | slower: { animationDuration: '3s' },
59 |
60 | ease: { animationTimingFunction: 'cubic-bezier(.25,.1,.25,1)' },
61 |
62 | infinite: { animationIterationCount: 'infinite' },
63 |
64 | normal: { animationDirection: 'normal' },
65 | reverse: { animationDirection: 'reverse' },
66 | alternate: { animationDirection: 'alternate' },
67 | 'alternate-reverse': { animationDirection: 'alternate-reverse' },
68 |
69 | paused: { animationPlayState: 'paused' },
70 | running: { animationPlayState: 'running' },
71 | }
72 |
--------------------------------------------------------------------------------
/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | const { withAnimations } = require('.')
2 |
3 | module.exports = withAnimations({
4 | // prefix: 'tw-',
5 | content: ['./docs/.vitepress/theme/*.vue'],
6 | safelist: [{ pattern: /animate-.*/ }],
7 | })
8 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@tsconfig/node12/tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": "src",
5 | "declaration": true,
6 | "exactOptionalPropertyTypes": true,
7 | "outDir": "dist",
8 | "skipLibCheck": false
9 | },
10 | "exclude": ["dist"]
11 | }
12 |
--------------------------------------------------------------------------------