├── .github
└── workflows
│ └── tests.yml
├── .gitignore
├── .prettierrc
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── astro.config.ts
├── dev
├── env.d.ts
├── group.tsx
├── kitchen-sink.tsx
├── layout.astro
├── pages
│ ├── group.astro
│ └── index.astro
└── styles.css
├── netlify.toml
├── package.json
├── pnpm-lock.yaml
├── src
└── index.ts
├── tailwind.config.cjs
├── test
├── index.test.tsx
└── server.test.tsx
├── tsconfig.build.json
├── tsconfig.json
└── vitest.config.ts
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: Build and Test
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout repo
15 | uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 |
19 | - uses: pnpm/action-setup@v4
20 |
21 | - name: Setup Node.js environment
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: 22
25 | cache: pnpm
26 |
27 | - name: Install dependencies
28 | run: pnpm install --no-frozen-lockfile
29 |
30 | - name: Build
31 | run: pnpm run build
32 | env:
33 | CI: true
34 |
35 | - name: Test
36 | run: pnpm run test
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | dist/
3 | lib/
4 | coverage/
5 | types/
6 | *.tsbuildinfo
7 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "tabWidth": 2,
4 | "printWidth": 100,
5 | "semi": true,
6 | "singleQuote": false,
7 | "useTabs": false,
8 | "arrowParens": "avoid",
9 | "bracketSpacing": true,
10 | "endOfLine": "lf",
11 | "plugins": []
12 | }
13 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "esbenp.prettier-vscode",
4 | "astro-build.astro-vscode",
5 | "bradlc.vscode-tailwindcss"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": ["astrojs", "outin"],
3 | "css.validate": false
4 | }
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020-2021 Ryan Carniato
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, 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,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # Solid Transition Group
6 |
7 | [](https://pnpm.io/)
8 | [](https://www.npmjs.com/package/solid-transition-group)
9 | [](https://www.npmjs.com/package/solid-transition-group)
10 |
11 | Components for applying animations when children elements enter or leave the DOM. Influenced by React Transition Group and Vue Transitions for the SolidJS library.
12 |
13 | ## Installation
14 |
15 | ```bash
16 | npm install solid-transition-group
17 | # or
18 | yarn add solid-transition-group
19 | # or
20 | pnpm add solid-transition-group
21 | ```
22 |
23 | ## Transition
24 |
25 | `` serve as transition effects for single element/component. The `` only applies the transition behavior to the wrapped content inside; it doesn't render an extra DOM element, or show up in the inspected component hierarchy.
26 |
27 | All props besides `children` are optional.
28 |
29 | ### Using with CSS
30 |
31 | Usage with CSS is straightforward. Just add the `name` prop and the CSS classes will be automatically generated for you. The `name` prop is used as a prefix for the generated CSS classes. For example, if you use `name="slide-fade"`, the generated CSS classes will be `.slide-fade-enter`, `.slide-fade-enter-active`, etc.
32 |
33 | The exitting element will be removed from the DOM when the first transition ends. You can override this behavior by providing a `done` callback to the `onExit` prop.
34 |
35 | ```tsx
36 | import { Transition } from "solid-transition-group"
37 |
38 | const [isVisible, setVisible] = createSignal(true)
39 |
40 |
41 |
42 |
Hello
43 |
44 |
45 |
46 | setVisible(false) // triggers exit transition
47 | ```
48 |
49 | Example CSS transition:
50 |
51 | ```css
52 | .slide-fade-enter-active,
53 | .slide-fade-exit-active {
54 | transition: opacity 0.3s, transform 0.3s;
55 | }
56 | .slide-fade-enter,
57 | .slide-fade-exit-to {
58 | transform: translateX(10px);
59 | opacity: 0;
60 | }
61 | .slide-fade-enter {
62 | transform: translateX(-10px);
63 | }
64 | ```
65 |
66 | Props for customizing the CSS classes applied by ``:
67 |
68 | | Name | Description |
69 | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70 | | `name` | Used to automatically generate transition CSS class names. e.g. `name: 'fade'` will auto expand to `.fade-enter`, `.fade-enter-active`, etc. Defaults to `"s"`. |
71 | | `enterClass` | CSS class applied to the entering element at the start of the enter transition, and removed the frame after. Defaults to `"s-enter"`. |
72 | | `enterToClass` | CSS class applied to the entering element after the enter transition starts. Defaults to `"s-enter-to"`. |
73 | | `enterActiveClass` | CSS class applied to the entering element for the entire duration of the enter transition. Defaults to `"s-enter-active"`. |
74 | | `exitClass` | CSS class applied to the exiting element at the start of the exit transition, and removed the frame after. Defaults to `"s-exit"`. |
75 | | `exitToClass` | CSS class applied to the exiting element after the exit transition starts. Defaults to `"s-exit-to"`. |
76 | | `exitActiveClass` | CSS class applied to the exiting element for the entire duration of the exit transition. Defaults to `"s-exit-active"`. |
77 |
78 | ### Using with JavaScript
79 |
80 | You can also use JavaScript to animate the transition. The `` component provides several events that you can use to hook into the transition lifecycle. The `onEnter` and `onExit` events are called when the transition starts, and the `onBeforeEnter` and `onBeforeExit` events are called before the transition starts. The `onAfterEnter` and `onAfterExit` events are called after the transition ends.
81 |
82 | ```jsx
83 | {
85 | const a = el.animate([{ opacity: 0 }, { opacity: 1 }], {
86 | duration: 600
87 | });
88 | a.finished.then(done);
89 | }}
90 | onExit={(el, done) => {
91 | const a = el.animate([{ opacity: 1 }, { opacity: 0 }], {
92 | duration: 600
93 | });
94 | a.finished.then(done);
95 | }}
96 | >
97 | {show() &&
Hello
}
98 |
99 | ```
100 |
101 | **Events** proved by `` for animating elements with JavaScript:
102 |
103 | | Name | Parameters | Description |
104 | | --------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
105 | | `onBeforeEnter` | `element: Element` | Function called before the enter transition starts. The `element` is not yet rendered. |
106 | | `onEnter` | `element: Element, done: () => void` | Function called when the enter transition starts. The `element` is rendered to the DOM. Call `done` to end the transition - removes the enter classes, and calls `onAfterEnter`. If the parameter for `done` is not provided, it will be called on `transitionend` or `animationend`. |
107 | | `onAfterEnter` | `element: Element` | Function called after the enter transition ends. The `element` is removed from the DOM. |
108 | | `onBeforeExit` | `element: Element` | Function called before the exit transition starts. The `element` is still rendered, exit classes are not yet applied. |
109 | | `onExit` | `element: Element, done: () => void` | Function called when the exit transition starts, after the exit classes are applied (`enterToClass` and `exitActiveClass`). The `element` is still rendered. Call `done` to end the transition - removes exit classes, calls `onAfterExit` and removes the element from the DOM. If the parameter for `done` is not provided, it will be called on `transitionend` or `animationend`. |
110 | | `onAfterExit` | `element: Element` | Function called after the exit transition ends. The `element` is removed from the DOM. |
111 |
112 | ### Changing Transition Mode
113 |
114 | By default, `` will apply the transition effect to both entering and exiting elements simultaneously. You can change this behavior by setting the `mode` prop to `"outin"` or `"inout"`. The `"outin"` mode will wait for the exiting element to finish before applying the transition to the entering element. The `"inout"` mode will wait for the entering element to finish before applying the transition to the exiting element.
115 |
116 | By default the transition won't be applied on initial render. You can change this behavior by setting the `appear` prop to `true`.
117 |
118 | > **Warning:** When using `appear` with SSR, the initial transition will be applied on the client-side, which might cause a flash of unstyled content.
119 | > You need to handle applying the initial transition on the server-side yourself.
120 |
121 | ## TransitionGroup
122 |
123 | ### Props
124 |
125 | - `moveClass` - CSS class applied to the moving elements for the entire duration of the move transition. Defaults to `"s-move"`.
126 | - exposes the same props as `` except `mode`.
127 |
128 | ### Usage
129 |
130 | `` serve as transition effects for multiple elements/components.
131 |
132 | `` supports moving transitions via CSS transform. When a child's position on screen has changed after an update, it will get applied a moving CSS class (auto generated from the name attribute or configured with the move-class attribute). If the CSS transform property is "transition-able" when the moving class is applied, the element will be smoothly animated to its destination using the FLIP technique.
133 |
134 | ```jsx
135 |