react-transition-state 2.0.0-alpha.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -39
- package/dist/cjs/index.js +8 -8
- package/dist/es/hooks/useTransition.js +1 -1
- package/dist/es/hooks/useTransitionMap.js +1 -1
- package/dist/es/hooks/utils.js +6 -6
- package/package.json +15 -14
package/README.md
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# React-Transition-State
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/react-transition-state)
|
|
4
|
-
[](https://www.npmjs.com/package/react-transition-state)
|
|
5
|
-
[](https://bundlephobia.com/package/react-transition-state)
|
|
6
|
-
[](https://snyk.io/test/github/szhsin/react-transition-state)
|
|
3
|
+
[](https://www.npmjs.com/package/react-transition-state) [](https://www.npmjs.com/package/react-transition-state) [](https://bundlephobia.com/package/react-transition-state) [](https://snyk.io/test/github/szhsin/react-transition-state)
|
|
7
4
|
|
|
8
5
|
## Features
|
|
9
6
|
|
|
@@ -13,7 +10,7 @@ Inspired by the [React Transition Group](https://github.com/reactjs/react-transi
|
|
|
13
10
|
- 🔄 Moving React components in and out of DOM seamlessly.
|
|
14
11
|
- 🚫 Using no [derived state](https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html).
|
|
15
12
|
- 🚀 Efficient: each state transition results in at most one extract render for consuming component.
|
|
16
|
-
- 🤏 Tiny: [~
|
|
13
|
+
- 🤏 Tiny: [~1KB](https://bundlephobia.com/package/react-transition-state)(post-treeshaking) and no dependencies, ideal for both component libraries and applications.
|
|
17
14
|
|
|
18
15
|
🤔 Not convinced? [See a comparison with _React Transition Group_](#comparisons-with-react-transition-group)
|
|
19
16
|
|
|
@@ -21,8 +18,7 @@ Inspired by the [React Transition Group](https://github.com/reactjs/react-transi
|
|
|
21
18
|
|
|
22
19
|
## State diagram
|
|
23
20
|
|
|
24
|
-

|
|
25
|
-
The `initialEntered` and `mountOnEnter` props are omitted from the diagram to keep it less convoluted. [Please read more details at the API section](#usetransition-hook).
|
|
21
|
+
 The `initialEntered` and `mountOnEnter` props are omitted from the diagram to keep it less convoluted. [Please read more details at the API section](#usetransition-hook).
|
|
26
22
|
|
|
27
23
|
<br/>
|
|
28
24
|
|
|
@@ -51,7 +47,7 @@ function Example() {
|
|
|
51
47
|
return (
|
|
52
48
|
<div>
|
|
53
49
|
<button onClick={() => toggle()}>toggle</button>
|
|
54
|
-
<div className={`example ${state}`}>React transition state</div>
|
|
50
|
+
<div className={`example ${state.status}`}>React transition state</div>
|
|
55
51
|
</div>
|
|
56
52
|
);
|
|
57
53
|
}
|
|
@@ -88,8 +84,8 @@ import { useTransition } from 'react-transition-state';
|
|
|
88
84
|
const Box = styled.div`
|
|
89
85
|
transition: all 500ms;
|
|
90
86
|
|
|
91
|
-
${({
|
|
92
|
-
(
|
|
87
|
+
${({ status }) =>
|
|
88
|
+
(status === 'preEnter' || status === 'exiting') &&
|
|
93
89
|
`
|
|
94
90
|
opacity: 0;
|
|
95
91
|
transform: scale(0.9);
|
|
@@ -97,19 +93,18 @@ const Box = styled.div`
|
|
|
97
93
|
`;
|
|
98
94
|
|
|
99
95
|
function StyledExample() {
|
|
100
|
-
const [
|
|
96
|
+
const [{ status, isMounted }, toggle] = useTransition({
|
|
101
97
|
timeout: 500,
|
|
102
98
|
mountOnEnter: true,
|
|
103
99
|
unmountOnExit: true,
|
|
104
100
|
preEnter: true
|
|
105
101
|
});
|
|
106
102
|
|
|
107
|
-
const showButton = state === 'unmounted';
|
|
108
103
|
return (
|
|
109
104
|
<div>
|
|
110
|
-
{
|
|
111
|
-
{
|
|
112
|
-
<Box
|
|
105
|
+
{!isMounted && <button onClick={() => toggle(true)}>Show Message</button>}
|
|
106
|
+
{isMounted && (
|
|
107
|
+
<Box status={status}>
|
|
113
108
|
<p>This message is being transitioned in and out of the DOM.</p>
|
|
114
109
|
<button onClick={() => toggle(false)}>Close</button>
|
|
115
110
|
</Box>
|
|
@@ -147,15 +142,15 @@ useEffect(() => {
|
|
|
147
142
|
|
|
148
143
|
## Comparisons with _React Transition Group_
|
|
149
144
|
|
|
150
|
-
|
|
|
151
|
-
|
|
|
152
|
-
| Use derived state
|
|
153
|
-
| Controlled
|
|
154
|
-
| DOM updates
|
|
155
|
-
| Render something in response to state updates | _Resort to side effects_ – rendering based on [state update events](https://codesandbox.io/s/react-transition-state-vs-group-p45iy?file=/src/App.js:
|
|
156
|
-
| Working with _styled-components_
|
|
157
|
-
| Bundle size
|
|
158
|
-
| Dependency count
|
|
145
|
+
| | React Transition Group | This library |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| Use derived state | _Yes_ – use an `in` prop to trigger changes in a derived transition state | _No_ – there is only a single state which is triggered by a toggle function |
|
|
148
|
+
| Controlled | _No_ – <br/>Transition state is managed internally.<br/>Resort to callback events to read the internal state. | _Yes_ – <br/>Transition state is _lifted_ up into the consuming component.<br/>You have direct access to the transition state. |
|
|
149
|
+
| DOM updates | _Imperative_ – [commit changes into DOM imperatively](https://github.com/reactjs/react-transition-group/blob/5aa3fd2d7e3354a7e42505d55af605ff44f74e2e/src/CSSTransition.js#L10) to update `classes` | _Declarative_ – you declare [what the `classes` look like](https://github.com/szhsin/react-transition-state/blob/2ab44c12ac5d5283ec3bb997bfc1d5ef6dffb0ce/example/src/components/BasicExample.js#L31) and DOM updates are taken care of by `ReactDOM` |
|
|
150
|
+
| Render something in response to state updates | _Resort to side effects_ – rendering based on [state update events](https://codesandbox.io/s/react-transition-state-vs-group-p45iy?file=/src/App.js:1010-1191) | _Pure_ – rendering based on [transition state](https://codesandbox.io/s/react-transition-state-vs-group-p45iy?file=/src/App.js:2168-2342) |
|
|
151
|
+
| Working with _styled-components_ | Your code looks like – <br/>`&.box-exit-active { opacity: 0; }`<br/>`&.box-enter-active { opacity: 1; }` | Your code looks like – <br/>`opacity: ${({ state }) => (state === 'exiting' ? '0' : '1')};` <br/> It's the way how you normally use the _styled-components_ |
|
|
152
|
+
| Bundle size | [](https://bundlephobia.com/package/react-transition-group) | ✅ [](https://bundlephobia.com/package/react-transition-state) |
|
|
153
|
+
| Dependency count | [](https://www.npmjs.com/package/react-transition-group?activeTab=dependencies) | ✅ [](https://www.npmjs.com/package/react-transition-state?activeTab=dependencies) |
|
|
159
154
|
|
|
160
155
|
This [CodeSandbox example](https://codesandbox.io/s/react-transition-state-vs-group-p45iy) demonstrates how the same transition can be implemented in a simpler, more declarative, and controllable manner than _React Transition Group_.
|
|
161
156
|
|
|
@@ -173,29 +168,45 @@ function useTransition(
|
|
|
173
168
|
|
|
174
169
|
#### Options
|
|
175
170
|
|
|
176
|
-
| Name
|
|
177
|
-
|
|
|
178
|
-
| `enter`
|
|
179
|
-
| `exit`
|
|
180
|
-
| `preEnter`
|
|
181
|
-
| `preExit`
|
|
182
|
-
| `initialEntered` | boolean
|
|
183
|
-
| `mountOnEnter`
|
|
184
|
-
| `unmountOnExit`
|
|
185
|
-
| `timeout`
|
|
186
|
-
| `
|
|
171
|
+
| Name | Type | Default | Description |
|
|
172
|
+
| --- | --- | --- | --- |
|
|
173
|
+
| `enter` | boolean | true | Enable or disable enter phase transitions |
|
|
174
|
+
| `exit` | boolean | true | Enable or disable exit phase transitions |
|
|
175
|
+
| `preEnter` | boolean | | Add a 'preEnter' state immediately before 'entering', which is necessary to change DOM elements from unmounted or `display: none` with CSS transition (not necessary for CSS animation). |
|
|
176
|
+
| `preExit` | boolean | | Add a 'preExit' state immediately before 'exiting' |
|
|
177
|
+
| `initialEntered` | boolean | | Beginning from 'entered' state |
|
|
178
|
+
| `mountOnEnter` | boolean | | State will be 'unmounted' until hit enter phase for the first time. It allows you to create lazily mounted component. |
|
|
179
|
+
| `unmountOnExit` | boolean | | State will become 'unmounted' after 'exiting' finishes. It allows you to transition component out of DOM. |
|
|
180
|
+
| `timeout` | number \| <br />{ enter?: number; exit?: number; } | | Set timeout in **ms** for transitions; you can set a single value or different values for enter and exit transitions. |
|
|
181
|
+
| `onStateChange` | (event: { current: TransitionState }) => void | | Event fired when state has changed. <br/><br/>Prefer to read state from the hook function return value directly unless you want to perform some side effects in response to state changes. <br/><br/>_Note: create an event handler with `useCallback` if you need to keep `toggle` or `endTransition` function's identity stable across re-renders._ |
|
|
187
182
|
|
|
188
183
|
#### Return value
|
|
189
184
|
|
|
190
|
-
The `useTransition` Hook returns
|
|
185
|
+
The `useTransition` Hook returns a tuple of values in the following order:
|
|
191
186
|
|
|
192
|
-
1. state:
|
|
193
|
-
|
|
187
|
+
1. state:
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
{
|
|
191
|
+
status: 'preEnter' |
|
|
192
|
+
'entering' |
|
|
193
|
+
'entered' |
|
|
194
|
+
'preExit' |
|
|
195
|
+
'exiting' |
|
|
196
|
+
'exited' |
|
|
197
|
+
'unmounted';
|
|
198
|
+
isMounted: boolean;
|
|
199
|
+
isEnter: boolean;
|
|
200
|
+
isResolved: boolean;
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
2. toggle: `(toEnter?: boolean) => void`
|
|
194
205
|
|
|
195
206
|
- If no parameter is supplied, this function will toggle state between enter and exit phases.
|
|
196
207
|
- You can set a boolean parameter to explicitly switch into one of the two phases.
|
|
197
208
|
|
|
198
|
-
3. endTransition: () => void
|
|
209
|
+
3. endTransition: `() => void`
|
|
199
210
|
|
|
200
211
|
- Call this function to stop transition which will turn state into 'entered' or 'exited'.
|
|
201
212
|
- You will normally call this function in the `onAnimationEnd` or `onTransitionEnd` event.
|
|
@@ -203,6 +214,34 @@ The `useTransition` Hook returns an array of values in the following order:
|
|
|
203
214
|
|
|
204
215
|
<br/>
|
|
205
216
|
|
|
217
|
+
### `useTransitionMap` Hook
|
|
218
|
+
|
|
219
|
+
It's similar to the `useTransition` Hook except that it manages multiple states in a [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) structure instead of a single state.
|
|
220
|
+
|
|
221
|
+
#### Options
|
|
222
|
+
|
|
223
|
+
It accepts all options as `useTransition` and the following ones:
|
|
224
|
+
|
|
225
|
+
| Name | Type | Default | Description |
|
|
226
|
+
| --- | --- | --- | --- |
|
|
227
|
+
| `allowMultiple` | boolean | | Allow multiple items to be in the enter phase at the same time. |
|
|
228
|
+
|
|
229
|
+
#### Return value
|
|
230
|
+
|
|
231
|
+
The Hook returns an object of shape:
|
|
232
|
+
|
|
233
|
+
```js
|
|
234
|
+
interface TransitionMapResult<K> {
|
|
235
|
+
stateMap: ReadonlyMap<K, TransitionState>;
|
|
236
|
+
toggle: (key: K, toEnter?: boolean) => void;
|
|
237
|
+
endTransition: (key: K) => void;
|
|
238
|
+
setItem: (key: K, options?: TransitionItemOptions) => void;
|
|
239
|
+
deleteItem: (key: K) => boolean;
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
`setItem` and `deleteItem` are used to add and remove items from the state map.
|
|
244
|
+
|
|
206
245
|
## License
|
|
207
246
|
|
|
208
247
|
[MIT](https://github.com/szhsin/react-transition-state/blob/master/LICENSE) Licensed.
|
package/dist/cjs/index.js
CHANGED
|
@@ -12,13 +12,13 @@ var EXITING = 4;
|
|
|
12
12
|
var EXITED = 5;
|
|
13
13
|
var UNMOUNTED = 6;
|
|
14
14
|
var STATUS = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
15
|
-
var getState = function getState(
|
|
15
|
+
var getState = function getState(status) {
|
|
16
16
|
return {
|
|
17
|
-
_status:
|
|
18
|
-
status: STATUS[
|
|
19
|
-
isEnter:
|
|
20
|
-
isMounted:
|
|
21
|
-
isResolved:
|
|
17
|
+
_status: status,
|
|
18
|
+
status: STATUS[status],
|
|
19
|
+
isEnter: status < PRE_EXIT,
|
|
20
|
+
isMounted: status !== UNMOUNTED,
|
|
21
|
+
isResolved: status === ENTERED || status > EXITING
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
var startOrEnd = function startOrEnd(unmounted) {
|
|
@@ -102,7 +102,7 @@ var useTransition = function useTransition(_temp) {
|
|
|
102
102
|
}
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
var enterStage = latestState.current.
|
|
105
|
+
var enterStage = latestState.current.isEnter;
|
|
106
106
|
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
107
107
|
|
|
108
108
|
if (toEnter) {
|
|
@@ -256,7 +256,7 @@ var useTransitionMap = function useTransitionMap(_temp) {
|
|
|
256
256
|
}
|
|
257
257
|
};
|
|
258
258
|
|
|
259
|
-
var enterStage = stateObj.
|
|
259
|
+
var enterStage = stateObj.isEnter;
|
|
260
260
|
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
261
261
|
|
|
262
262
|
if (toEnter) {
|
package/dist/es/hooks/utils.js
CHANGED
|
@@ -6,13 +6,13 @@ var EXITING = 4;
|
|
|
6
6
|
var EXITED = 5;
|
|
7
7
|
var UNMOUNTED = 6;
|
|
8
8
|
var STATUS = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
9
|
-
var getState = function getState(
|
|
9
|
+
var getState = function getState(status) {
|
|
10
10
|
return {
|
|
11
|
-
_status:
|
|
12
|
-
status: STATUS[
|
|
13
|
-
isEnter:
|
|
14
|
-
isMounted:
|
|
15
|
-
isResolved:
|
|
11
|
+
_status: status,
|
|
12
|
+
status: STATUS[status],
|
|
13
|
+
isEnter: status < PRE_EXIT,
|
|
14
|
+
isMounted: status !== UNMOUNTED,
|
|
15
|
+
isResolved: status === ENTERED || status > EXITING
|
|
16
16
|
};
|
|
17
17
|
};
|
|
18
18
|
var startOrEnd = function startOrEnd(unmounted) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-transition-state",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Zero dependency React transition state machine.",
|
|
5
5
|
"author": "Zheng Song",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,24 +41,25 @@
|
|
|
41
41
|
"react-dom": ">=16.8.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@babel/core": "^7.
|
|
45
|
-
"@babel/preset-env": "^7.
|
|
44
|
+
"@babel/core": "^7.18.13",
|
|
45
|
+
"@babel/preset-env": "^7.18.10",
|
|
46
46
|
"@rollup/plugin-babel": "^5.3.1",
|
|
47
|
-
"@testing-library/react
|
|
48
|
-
"@types/jest": "^
|
|
47
|
+
"@testing-library/react": "^13.3.0",
|
|
48
|
+
"@types/jest": "^29.0.0",
|
|
49
49
|
"babel-plugin-pure-annotations": "^0.1.2",
|
|
50
50
|
"dtslint": "^4.1.6",
|
|
51
|
-
"eslint": "^8.
|
|
51
|
+
"eslint": "^8.22.0",
|
|
52
52
|
"eslint-config-prettier": "^8.5.0",
|
|
53
|
-
"eslint-plugin-jest": "^26.
|
|
54
|
-
"eslint-plugin-react-hooks": "^4.
|
|
55
|
-
"jest": "^
|
|
53
|
+
"eslint-plugin-jest": "^26.9.0",
|
|
54
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
55
|
+
"jest": "^29.0.1",
|
|
56
|
+
"jest-environment-jsdom": "^29.0.1",
|
|
56
57
|
"npm-run-all": "^4.1.5",
|
|
57
|
-
"prettier": "^2.
|
|
58
|
-
"react": "^
|
|
59
|
-
"react-dom": "^
|
|
58
|
+
"prettier": "^2.7.1",
|
|
59
|
+
"react": "^18.2.0",
|
|
60
|
+
"react-dom": "^18.2.0",
|
|
60
61
|
"regenerator-runtime": "^0.13.9",
|
|
61
|
-
"rollup": "^2.
|
|
62
|
-
"typescript": "^4.
|
|
62
|
+
"rollup": "^2.79.0",
|
|
63
|
+
"typescript": "^4.7.4"
|
|
63
64
|
}
|
|
64
65
|
}
|