react-transition-state 1.1.3 → 1.2.0-alpha.1
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 +28 -14
- package/dist/cjs/index.js +267 -0
- package/dist/{index.es.js → es/hooks/useTransition.js} +7 -38
- package/dist/es/hooks/useTransitionMap.js +155 -0
- package/dist/es/hooks/utils.js +27 -0
- package/dist/es/index.js +2 -0
- package/package.json +15 -15
- package/dist/index.js +0 -121
package/README.md
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
[](https://bundlephobia.com/package/react-transition-state)
|
|
6
6
|
[](https://snyk.io/test/github/szhsin/react-transition-state)
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Features
|
|
9
9
|
|
|
10
10
|
Inspired by the [React Transition Group](https://github.com/reactjs/react-transition-group), this tiny library helps you easily perform animations/transitions of your React component in a [fully controlled](https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#common-bugs-when-using-derived-state) manner, using a Hook API.
|
|
11
11
|
|
|
12
12
|
- 🍭 Working with both CSS animation and transition.
|
|
13
13
|
- 🔄 Moving React components in and out of DOM seamlessly.
|
|
14
14
|
- 🚫 Using no [derived state](https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html).
|
|
15
|
-
- 🚀 Efficient: each state transition results in at most one extract render for
|
|
15
|
+
- 🚀 Efficient: each state transition results in at most one extract render for consuming component.
|
|
16
16
|
- 🤏 Tiny: [~0.7KB](https://bundlephobia.com/package/react-transition-state) and no dependencies, ideal for both component libraries and applications.
|
|
17
17
|
|
|
18
18
|
🤔 Not convinced? [See a comparison with _React Transition Group_](#comparisons-with-react-transition-group)
|
|
@@ -75,14 +75,13 @@ export default Example;
|
|
|
75
75
|
}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
**[Edit on CodeSandbox](https://codesandbox.io/s/react-transition-
|
|
78
|
+
**[Edit on CodeSandbox](https://codesandbox.io/s/react-transition-state-100io)**
|
|
79
79
|
|
|
80
80
|
<br/>
|
|
81
81
|
|
|
82
82
|
### styled-components example
|
|
83
83
|
|
|
84
84
|
```jsx
|
|
85
|
-
import React from 'react';
|
|
86
85
|
import styled from 'styled-components';
|
|
87
86
|
import { useTransition } from 'react-transition-state';
|
|
88
87
|
|
|
@@ -132,18 +131,33 @@ export default StyledExample;
|
|
|
132
131
|
|
|
133
132
|
<br/>
|
|
134
133
|
|
|
135
|
-
|
|
134
|
+
### Perform appearing transition when page loads or a component mounts
|
|
135
|
+
|
|
136
|
+
You can toggle on transition with the `useEffect` hook.
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
useEffect(() => {
|
|
140
|
+
toggle(true);
|
|
141
|
+
}, [toggle]);
|
|
142
|
+
```
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
| 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_ |
|
|
143
|
-
| Bundle size | [](https://bundlephobia.com/package/react-transition-group) | ✅ [](https://bundlephobia.com/package/react-transition-state) |
|
|
144
|
-
| Dependency count | [](https://www.npmjs.com/package/react-transition-group?activeTab=dependencies) | ✅ [](https://www.npmjs.com/package/react-transition-state?activeTab=dependencies) |
|
|
144
|
+
**[Edit on CodeSandbox](https://codesandbox.io/s/react-transition-appear-9kkss3)**
|
|
145
|
+
|
|
146
|
+
<br/>
|
|
147
|
+
|
|
148
|
+
## Comparisons with _React Transition Group_
|
|
145
149
|
|
|
146
|
-
|
|
150
|
+
| | React Transition Group | This library |
|
|
151
|
+
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
152
|
+
| 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 |
|
|
153
|
+
| 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. |
|
|
154
|
+
| 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` |
|
|
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:1007-1188) | _Pure_ – rendering based on [transition state](https://codesandbox.io/s/react-transition-state-vs-group-p45iy?file=/src/App.js:2140-2325) |
|
|
156
|
+
| 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_ |
|
|
157
|
+
| Bundle size | [](https://bundlephobia.com/package/react-transition-group) | ✅ [](https://bundlephobia.com/package/react-transition-state) |
|
|
158
|
+
| Dependency count | [](https://www.npmjs.com/package/react-transition-group?activeTab=dependencies) | ✅ [](https://www.npmjs.com/package/react-transition-state?activeTab=dependencies) |
|
|
159
|
+
|
|
160
|
+
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_.
|
|
147
161
|
|
|
148
162
|
<br/>
|
|
149
163
|
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var react = require('react');
|
|
6
|
+
|
|
7
|
+
var PRE_ENTER = 0;
|
|
8
|
+
var ENTERING = 1;
|
|
9
|
+
var ENTERED = 2;
|
|
10
|
+
var PRE_EXIT = 3;
|
|
11
|
+
var EXITING = 4;
|
|
12
|
+
var EXITED = 5;
|
|
13
|
+
var UNMOUNTED = 6;
|
|
14
|
+
var STATES = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
15
|
+
var startOrEnd = function startOrEnd(unmounted) {
|
|
16
|
+
return unmounted ? UNMOUNTED : EXITED;
|
|
17
|
+
};
|
|
18
|
+
var getEndState = function getEndState(state, unmountOnExit) {
|
|
19
|
+
switch (state) {
|
|
20
|
+
case ENTERING:
|
|
21
|
+
case PRE_ENTER:
|
|
22
|
+
return ENTERED;
|
|
23
|
+
|
|
24
|
+
case EXITING:
|
|
25
|
+
case PRE_EXIT:
|
|
26
|
+
return startOrEnd(unmountOnExit);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var getTimeout = function getTimeout(timeout) {
|
|
30
|
+
return typeof timeout === 'object' ? [timeout.enter, timeout.exit] : [timeout, timeout];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
var updateState$1 = function updateState(state, setState, latestState, timeoutId, onChange) {
|
|
34
|
+
clearTimeout(timeoutId.current);
|
|
35
|
+
setState(state);
|
|
36
|
+
latestState.current = state;
|
|
37
|
+
onChange && onChange({
|
|
38
|
+
state: STATES[state]
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
var useTransition = function useTransition(_temp) {
|
|
43
|
+
var _ref = _temp === void 0 ? {} : _temp,
|
|
44
|
+
_ref$enter = _ref.enter,
|
|
45
|
+
enter = _ref$enter === void 0 ? true : _ref$enter,
|
|
46
|
+
_ref$exit = _ref.exit,
|
|
47
|
+
exit = _ref$exit === void 0 ? true : _ref$exit,
|
|
48
|
+
preEnter = _ref.preEnter,
|
|
49
|
+
preExit = _ref.preExit,
|
|
50
|
+
timeout = _ref.timeout,
|
|
51
|
+
initialEntered = _ref.initialEntered,
|
|
52
|
+
mountOnEnter = _ref.mountOnEnter,
|
|
53
|
+
unmountOnExit = _ref.unmountOnExit,
|
|
54
|
+
onChange = _ref.onChange;
|
|
55
|
+
|
|
56
|
+
var _useState = react.useState(initialEntered ? ENTERED : startOrEnd(mountOnEnter)),
|
|
57
|
+
state = _useState[0],
|
|
58
|
+
setState = _useState[1];
|
|
59
|
+
|
|
60
|
+
var latestState = react.useRef(state);
|
|
61
|
+
var timeoutId = react.useRef();
|
|
62
|
+
|
|
63
|
+
var _getTimeout = getTimeout(timeout),
|
|
64
|
+
enterTimeout = _getTimeout[0],
|
|
65
|
+
exitTimeout = _getTimeout[1];
|
|
66
|
+
|
|
67
|
+
var endTransition = react.useCallback(function () {
|
|
68
|
+
var newState = getEndState(latestState.current, unmountOnExit);
|
|
69
|
+
newState && updateState$1(newState, setState, latestState, timeoutId, onChange);
|
|
70
|
+
}, [onChange, unmountOnExit]);
|
|
71
|
+
var toggle = react.useCallback(function (toEnter) {
|
|
72
|
+
var transitState = function transitState(newState) {
|
|
73
|
+
updateState$1(newState, setState, latestState, timeoutId, onChange);
|
|
74
|
+
|
|
75
|
+
switch (newState) {
|
|
76
|
+
case ENTERING:
|
|
77
|
+
if (enterTimeout >= 0) timeoutId.current = setTimeout(endTransition, enterTimeout);
|
|
78
|
+
break;
|
|
79
|
+
|
|
80
|
+
case EXITING:
|
|
81
|
+
if (exitTimeout >= 0) timeoutId.current = setTimeout(endTransition, exitTimeout);
|
|
82
|
+
break;
|
|
83
|
+
|
|
84
|
+
case PRE_ENTER:
|
|
85
|
+
case PRE_EXIT:
|
|
86
|
+
timeoutId.current = setTimeout(function () {
|
|
87
|
+
return transitState(newState + 1);
|
|
88
|
+
}, 0);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
var enterStage = latestState.current <= ENTERED;
|
|
94
|
+
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
95
|
+
|
|
96
|
+
if (toEnter) {
|
|
97
|
+
if (!enterStage) {
|
|
98
|
+
transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
if (enterStage) {
|
|
102
|
+
transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}, [endTransition, onChange, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
|
|
106
|
+
react.useEffect(function () {
|
|
107
|
+
return function () {
|
|
108
|
+
return clearTimeout(timeoutId.current);
|
|
109
|
+
};
|
|
110
|
+
}, []);
|
|
111
|
+
return [STATES[state], toggle, endTransition];
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
var initialStateMap = new Map();
|
|
115
|
+
var initialConfigMap = new Map();
|
|
116
|
+
|
|
117
|
+
var updateState = function updateState(_ref) {
|
|
118
|
+
var item = _ref.item,
|
|
119
|
+
_state = _ref.newState,
|
|
120
|
+
setStateMap = _ref.setStateMap,
|
|
121
|
+
latestStateMap = _ref.latestStateMap,
|
|
122
|
+
timeoutId = _ref.timeoutId,
|
|
123
|
+
onChange = _ref.onChange;
|
|
124
|
+
clearTimeout(timeoutId);
|
|
125
|
+
var state = {
|
|
126
|
+
state: STATES[_state],
|
|
127
|
+
_state: _state
|
|
128
|
+
};
|
|
129
|
+
var stateMap = new Map(latestStateMap.current);
|
|
130
|
+
stateMap.set(item, state);
|
|
131
|
+
setStateMap(stateMap);
|
|
132
|
+
latestStateMap.current = stateMap;
|
|
133
|
+
onChange && onChange(item, state);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
var useTransitionMap = function useTransitionMap() {
|
|
137
|
+
var _useState = react.useState(initialStateMap),
|
|
138
|
+
stateMap = _useState[0],
|
|
139
|
+
setStateMap = _useState[1];
|
|
140
|
+
|
|
141
|
+
var latestStateMap = react.useRef(stateMap);
|
|
142
|
+
var configMap = react.useRef(initialConfigMap);
|
|
143
|
+
var addItem = react.useCallback(function (item, config) {
|
|
144
|
+
var initialEntered = config.initialEntered,
|
|
145
|
+
mountOnEnter = config.mountOnEnter;
|
|
146
|
+
var newState = initialEntered ? ENTERED : startOrEnd(mountOnEnter);
|
|
147
|
+
updateState({
|
|
148
|
+
item: item,
|
|
149
|
+
newState: newState,
|
|
150
|
+
setStateMap: setStateMap,
|
|
151
|
+
latestStateMap: latestStateMap
|
|
152
|
+
});
|
|
153
|
+
configMap.current.set(item, config);
|
|
154
|
+
}, []);
|
|
155
|
+
var removeItem = react.useCallback(function (item) {
|
|
156
|
+
var newStateMap = new Map(latestStateMap.current);
|
|
157
|
+
|
|
158
|
+
if (newStateMap.delete(item)) {
|
|
159
|
+
setStateMap(newStateMap);
|
|
160
|
+
latestStateMap.current = newStateMap;
|
|
161
|
+
configMap.current.delete(item);
|
|
162
|
+
}
|
|
163
|
+
}, []);
|
|
164
|
+
var endTransition = react.useCallback(function (item) {
|
|
165
|
+
var stateObj = latestStateMap.current.get(item);
|
|
166
|
+
|
|
167
|
+
if (!stateObj) {
|
|
168
|
+
process.env.NODE_ENV !== 'production' && console.error("[React-Transition-State] invalid item key for " + item);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
var _configMap$current$ge = configMap.current.get(item),
|
|
173
|
+
timeoutId = _configMap$current$ge.timeoutId,
|
|
174
|
+
onChange = _configMap$current$ge.onChange,
|
|
175
|
+
unmountOnExit = _configMap$current$ge.unmountOnExit;
|
|
176
|
+
|
|
177
|
+
var newState = getEndState(stateObj._state, unmountOnExit);
|
|
178
|
+
newState && updateState({
|
|
179
|
+
item: item,
|
|
180
|
+
newState: newState,
|
|
181
|
+
setStateMap: setStateMap,
|
|
182
|
+
latestStateMap: latestStateMap,
|
|
183
|
+
timeoutId: timeoutId,
|
|
184
|
+
onChange: onChange
|
|
185
|
+
});
|
|
186
|
+
}, []);
|
|
187
|
+
var toggle = react.useCallback(function (item, toEnter) {
|
|
188
|
+
var stateObj = latestStateMap.current.get(item);
|
|
189
|
+
|
|
190
|
+
if (!stateObj) {
|
|
191
|
+
process.env.NODE_ENV !== 'production' && console.error("[React-Transition-State] invalid item key for " + item);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
var config = configMap.current.get(item);
|
|
196
|
+
var _config$enter = config.enter,
|
|
197
|
+
enter = _config$enter === void 0 ? true : _config$enter,
|
|
198
|
+
_config$exit = config.exit,
|
|
199
|
+
exit = _config$exit === void 0 ? true : _config$exit,
|
|
200
|
+
preEnter = config.preEnter,
|
|
201
|
+
preExit = config.preExit,
|
|
202
|
+
timeout = config.timeout,
|
|
203
|
+
unmountOnExit = config.unmountOnExit,
|
|
204
|
+
onChange = config.onChange,
|
|
205
|
+
timeoutId = config.timeoutId;
|
|
206
|
+
|
|
207
|
+
var transitState = function transitState(newState) {
|
|
208
|
+
updateState({
|
|
209
|
+
item: item,
|
|
210
|
+
newState: newState,
|
|
211
|
+
setStateMap: setStateMap,
|
|
212
|
+
latestStateMap: latestStateMap,
|
|
213
|
+
timeoutId: timeoutId,
|
|
214
|
+
onChange: onChange
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
var _getTimeout = getTimeout(timeout),
|
|
218
|
+
enterTimeout = _getTimeout[0],
|
|
219
|
+
exitTimeout = _getTimeout[1];
|
|
220
|
+
|
|
221
|
+
switch (newState) {
|
|
222
|
+
case ENTERING:
|
|
223
|
+
if (enterTimeout >= 0) config.timeoutId = setTimeout(function () {
|
|
224
|
+
return endTransition(item);
|
|
225
|
+
}, enterTimeout);
|
|
226
|
+
break;
|
|
227
|
+
|
|
228
|
+
case EXITING:
|
|
229
|
+
if (exitTimeout >= 0) config.timeoutId = setTimeout(function () {
|
|
230
|
+
return endTransition(item);
|
|
231
|
+
}, exitTimeout);
|
|
232
|
+
break;
|
|
233
|
+
|
|
234
|
+
case PRE_ENTER:
|
|
235
|
+
case PRE_EXIT:
|
|
236
|
+
config.timeoutId = setTimeout(function () {
|
|
237
|
+
return transitState(newState + 1);
|
|
238
|
+
}, 0);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
var enterStage = stateObj._state <= ENTERED;
|
|
244
|
+
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
245
|
+
|
|
246
|
+
if (toEnter) {
|
|
247
|
+
if (!enterStage) {
|
|
248
|
+
transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
if (enterStage) {
|
|
252
|
+
transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}, [endTransition]);
|
|
256
|
+
return {
|
|
257
|
+
stateMap: stateMap,
|
|
258
|
+
toggle: toggle,
|
|
259
|
+
endTransition: endTransition,
|
|
260
|
+
addItem: addItem,
|
|
261
|
+
removeItem: removeItem
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
exports["default"] = useTransition;
|
|
266
|
+
exports.useTransition = useTransition;
|
|
267
|
+
exports.useTransitionMap = useTransitionMap;
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
var PRE_ENTER = 0;
|
|
4
|
-
var ENTERING = 1;
|
|
5
|
-
var ENTERED = 2;
|
|
6
|
-
var PRE_EXIT = 3;
|
|
7
|
-
var EXITING = 4;
|
|
8
|
-
var EXITED = 5;
|
|
9
|
-
var UNMOUNTED = 6;
|
|
10
|
-
var STATES = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
11
|
-
|
|
12
|
-
var startOrEnd = function startOrEnd(unmounted) {
|
|
13
|
-
return unmounted ? UNMOUNTED : EXITED;
|
|
14
|
-
};
|
|
2
|
+
import { ENTERED, startOrEnd, getTimeout, getEndState, PRE_EXIT, EXITING, STATES, PRE_ENTER, ENTERING } from './utils.js';
|
|
15
3
|
|
|
16
4
|
var updateState = function updateState(state, setState, latestState, timeoutId, onChange) {
|
|
17
5
|
clearTimeout(timeoutId.current);
|
|
@@ -42,33 +30,14 @@ var useTransition = function useTransition(_temp) {
|
|
|
42
30
|
|
|
43
31
|
var latestState = useRef(state);
|
|
44
32
|
var timeoutId = useRef();
|
|
45
|
-
var enterTimeout, exitTimeout;
|
|
46
33
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} else {
|
|
51
|
-
enterTimeout = exitTimeout = timeout;
|
|
52
|
-
}
|
|
34
|
+
var _getTimeout = getTimeout(timeout),
|
|
35
|
+
enterTimeout = _getTimeout[0],
|
|
36
|
+
exitTimeout = _getTimeout[1];
|
|
53
37
|
|
|
54
38
|
var endTransition = useCallback(function () {
|
|
55
|
-
var newState;
|
|
56
|
-
|
|
57
|
-
switch (latestState.current) {
|
|
58
|
-
case ENTERING:
|
|
59
|
-
case PRE_ENTER:
|
|
60
|
-
newState = ENTERED;
|
|
61
|
-
break;
|
|
62
|
-
|
|
63
|
-
case EXITING:
|
|
64
|
-
case PRE_EXIT:
|
|
65
|
-
newState = startOrEnd(unmountOnExit);
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (newState !== undefined) {
|
|
70
|
-
updateState(newState, setState, latestState, timeoutId, onChange);
|
|
71
|
-
}
|
|
39
|
+
var newState = getEndState(latestState.current, unmountOnExit);
|
|
40
|
+
newState && updateState(newState, setState, latestState, timeoutId, onChange);
|
|
72
41
|
}, [onChange, unmountOnExit]);
|
|
73
42
|
var toggle = useCallback(function (toEnter) {
|
|
74
43
|
var transitState = function transitState(newState) {
|
|
@@ -113,4 +82,4 @@ var useTransition = function useTransition(_temp) {
|
|
|
113
82
|
return [STATES[state], toggle, endTransition];
|
|
114
83
|
};
|
|
115
84
|
|
|
116
|
-
export { useTransition
|
|
85
|
+
export { useTransition };
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from 'react';
|
|
2
|
+
import { ENTERED, startOrEnd, getEndState, PRE_EXIT, EXITING, PRE_ENTER, ENTERING, STATES, getTimeout } from './utils.js';
|
|
3
|
+
|
|
4
|
+
var initialStateMap = new Map();
|
|
5
|
+
var initialConfigMap = new Map();
|
|
6
|
+
|
|
7
|
+
var updateState = function updateState(_ref) {
|
|
8
|
+
var item = _ref.item,
|
|
9
|
+
_state = _ref.newState,
|
|
10
|
+
setStateMap = _ref.setStateMap,
|
|
11
|
+
latestStateMap = _ref.latestStateMap,
|
|
12
|
+
timeoutId = _ref.timeoutId,
|
|
13
|
+
onChange = _ref.onChange;
|
|
14
|
+
clearTimeout(timeoutId);
|
|
15
|
+
var state = {
|
|
16
|
+
state: STATES[_state],
|
|
17
|
+
_state: _state
|
|
18
|
+
};
|
|
19
|
+
var stateMap = new Map(latestStateMap.current);
|
|
20
|
+
stateMap.set(item, state);
|
|
21
|
+
setStateMap(stateMap);
|
|
22
|
+
latestStateMap.current = stateMap;
|
|
23
|
+
onChange && onChange(item, state);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
var useTransitionMap = function useTransitionMap() {
|
|
27
|
+
var _useState = useState(initialStateMap),
|
|
28
|
+
stateMap = _useState[0],
|
|
29
|
+
setStateMap = _useState[1];
|
|
30
|
+
|
|
31
|
+
var latestStateMap = useRef(stateMap);
|
|
32
|
+
var configMap = useRef(initialConfigMap);
|
|
33
|
+
var addItem = useCallback(function (item, config) {
|
|
34
|
+
var initialEntered = config.initialEntered,
|
|
35
|
+
mountOnEnter = config.mountOnEnter;
|
|
36
|
+
var newState = initialEntered ? ENTERED : startOrEnd(mountOnEnter);
|
|
37
|
+
updateState({
|
|
38
|
+
item: item,
|
|
39
|
+
newState: newState,
|
|
40
|
+
setStateMap: setStateMap,
|
|
41
|
+
latestStateMap: latestStateMap
|
|
42
|
+
});
|
|
43
|
+
configMap.current.set(item, config);
|
|
44
|
+
}, []);
|
|
45
|
+
var removeItem = useCallback(function (item) {
|
|
46
|
+
var newStateMap = new Map(latestStateMap.current);
|
|
47
|
+
|
|
48
|
+
if (newStateMap.delete(item)) {
|
|
49
|
+
setStateMap(newStateMap);
|
|
50
|
+
latestStateMap.current = newStateMap;
|
|
51
|
+
configMap.current.delete(item);
|
|
52
|
+
}
|
|
53
|
+
}, []);
|
|
54
|
+
var endTransition = useCallback(function (item) {
|
|
55
|
+
var stateObj = latestStateMap.current.get(item);
|
|
56
|
+
|
|
57
|
+
if (!stateObj) {
|
|
58
|
+
process.env.NODE_ENV !== 'production' && console.error("[React-Transition-State] invalid item key for " + item);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
var _configMap$current$ge = configMap.current.get(item),
|
|
63
|
+
timeoutId = _configMap$current$ge.timeoutId,
|
|
64
|
+
onChange = _configMap$current$ge.onChange,
|
|
65
|
+
unmountOnExit = _configMap$current$ge.unmountOnExit;
|
|
66
|
+
|
|
67
|
+
var newState = getEndState(stateObj._state, unmountOnExit);
|
|
68
|
+
newState && updateState({
|
|
69
|
+
item: item,
|
|
70
|
+
newState: newState,
|
|
71
|
+
setStateMap: setStateMap,
|
|
72
|
+
latestStateMap: latestStateMap,
|
|
73
|
+
timeoutId: timeoutId,
|
|
74
|
+
onChange: onChange
|
|
75
|
+
});
|
|
76
|
+
}, []);
|
|
77
|
+
var toggle = useCallback(function (item, toEnter) {
|
|
78
|
+
var stateObj = latestStateMap.current.get(item);
|
|
79
|
+
|
|
80
|
+
if (!stateObj) {
|
|
81
|
+
process.env.NODE_ENV !== 'production' && console.error("[React-Transition-State] invalid item key for " + item);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var config = configMap.current.get(item);
|
|
86
|
+
var _config$enter = config.enter,
|
|
87
|
+
enter = _config$enter === void 0 ? true : _config$enter,
|
|
88
|
+
_config$exit = config.exit,
|
|
89
|
+
exit = _config$exit === void 0 ? true : _config$exit,
|
|
90
|
+
preEnter = config.preEnter,
|
|
91
|
+
preExit = config.preExit,
|
|
92
|
+
timeout = config.timeout,
|
|
93
|
+
unmountOnExit = config.unmountOnExit,
|
|
94
|
+
onChange = config.onChange,
|
|
95
|
+
timeoutId = config.timeoutId;
|
|
96
|
+
|
|
97
|
+
var transitState = function transitState(newState) {
|
|
98
|
+
updateState({
|
|
99
|
+
item: item,
|
|
100
|
+
newState: newState,
|
|
101
|
+
setStateMap: setStateMap,
|
|
102
|
+
latestStateMap: latestStateMap,
|
|
103
|
+
timeoutId: timeoutId,
|
|
104
|
+
onChange: onChange
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
var _getTimeout = getTimeout(timeout),
|
|
108
|
+
enterTimeout = _getTimeout[0],
|
|
109
|
+
exitTimeout = _getTimeout[1];
|
|
110
|
+
|
|
111
|
+
switch (newState) {
|
|
112
|
+
case ENTERING:
|
|
113
|
+
if (enterTimeout >= 0) config.timeoutId = setTimeout(function () {
|
|
114
|
+
return endTransition(item);
|
|
115
|
+
}, enterTimeout);
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case EXITING:
|
|
119
|
+
if (exitTimeout >= 0) config.timeoutId = setTimeout(function () {
|
|
120
|
+
return endTransition(item);
|
|
121
|
+
}, exitTimeout);
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case PRE_ENTER:
|
|
125
|
+
case PRE_EXIT:
|
|
126
|
+
config.timeoutId = setTimeout(function () {
|
|
127
|
+
return transitState(newState + 1);
|
|
128
|
+
}, 0);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
var enterStage = stateObj._state <= ENTERED;
|
|
134
|
+
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
135
|
+
|
|
136
|
+
if (toEnter) {
|
|
137
|
+
if (!enterStage) {
|
|
138
|
+
transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
if (enterStage) {
|
|
142
|
+
transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}, [endTransition]);
|
|
146
|
+
return {
|
|
147
|
+
stateMap: stateMap,
|
|
148
|
+
toggle: toggle,
|
|
149
|
+
endTransition: endTransition,
|
|
150
|
+
addItem: addItem,
|
|
151
|
+
removeItem: removeItem
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export { useTransitionMap };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var PRE_ENTER = 0;
|
|
2
|
+
var ENTERING = 1;
|
|
3
|
+
var ENTERED = 2;
|
|
4
|
+
var PRE_EXIT = 3;
|
|
5
|
+
var EXITING = 4;
|
|
6
|
+
var EXITED = 5;
|
|
7
|
+
var UNMOUNTED = 6;
|
|
8
|
+
var STATES = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
9
|
+
var startOrEnd = function startOrEnd(unmounted) {
|
|
10
|
+
return unmounted ? UNMOUNTED : EXITED;
|
|
11
|
+
};
|
|
12
|
+
var getEndState = function getEndState(state, unmountOnExit) {
|
|
13
|
+
switch (state) {
|
|
14
|
+
case ENTERING:
|
|
15
|
+
case PRE_ENTER:
|
|
16
|
+
return ENTERED;
|
|
17
|
+
|
|
18
|
+
case EXITING:
|
|
19
|
+
case PRE_EXIT:
|
|
20
|
+
return startOrEnd(unmountOnExit);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var getTimeout = function getTimeout(timeout) {
|
|
24
|
+
return typeof timeout === 'object' ? [timeout.enter, timeout.exit] : [timeout, timeout];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { ENTERED, ENTERING, EXITED, EXITING, PRE_ENTER, PRE_EXIT, STATES, UNMOUNTED, getEndState, getTimeout, startOrEnd };
|
package/dist/es/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-transition-state",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.0-alpha.1",
|
|
4
4
|
"description": "Zero dependency, 0.7KB react-transition-group alternative.",
|
|
5
5
|
"author": "Zheng Song",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": "szhsin/react-transition-state",
|
|
8
8
|
"homepage": "https://szhsin.github.io/react-transition-state/",
|
|
9
|
-
"main": "dist/index.js",
|
|
10
|
-
"module": "dist/index.
|
|
9
|
+
"main": "dist/cjs/index.js",
|
|
10
|
+
"module": "dist/es/index.js",
|
|
11
11
|
"types": "dist/index.d.ts",
|
|
12
12
|
"sideEffects": false,
|
|
13
13
|
"files": [
|
|
@@ -39,24 +39,24 @@
|
|
|
39
39
|
"react-dom": ">=16.8.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@babel/core": "^7.
|
|
43
|
-
"@babel/preset-env": "^7.16.
|
|
44
|
-
"@rollup/plugin-babel": "^5.3.
|
|
42
|
+
"@babel/core": "^7.17.9",
|
|
43
|
+
"@babel/preset-env": "^7.16.11",
|
|
44
|
+
"@rollup/plugin-babel": "^5.3.1",
|
|
45
45
|
"@testing-library/react-hooks": "^7.0.2",
|
|
46
|
-
"@types/jest": "^27.
|
|
46
|
+
"@types/jest": "^27.4.1",
|
|
47
47
|
"babel-plugin-pure-annotations": "^0.1.2",
|
|
48
48
|
"dtslint": "^4.1.6",
|
|
49
|
-
"eslint": "^
|
|
50
|
-
"eslint-config-prettier": "^8.
|
|
51
|
-
"eslint-plugin-jest": "^
|
|
52
|
-
"eslint-plugin-react-hooks": "^4.
|
|
53
|
-
"jest": "^27.
|
|
49
|
+
"eslint": "^8.12.0",
|
|
50
|
+
"eslint-config-prettier": "^8.5.0",
|
|
51
|
+
"eslint-plugin-jest": "^26.1.3",
|
|
52
|
+
"eslint-plugin-react-hooks": "^4.4.0",
|
|
53
|
+
"jest": "^27.5.1",
|
|
54
54
|
"npm-run-all": "^4.1.5",
|
|
55
|
-
"prettier": "^2.
|
|
55
|
+
"prettier": "^2.6.2",
|
|
56
56
|
"react": "^17.0.2",
|
|
57
57
|
"react-dom": "^17.0.2",
|
|
58
58
|
"regenerator-runtime": "^0.13.9",
|
|
59
|
-
"rollup": "^2.
|
|
60
|
-
"typescript": "^4.
|
|
59
|
+
"rollup": "^2.70.1",
|
|
60
|
+
"typescript": "^4.6.3"
|
|
61
61
|
}
|
|
62
62
|
}
|
package/dist/index.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var react = require('react');
|
|
6
|
-
|
|
7
|
-
var PRE_ENTER = 0;
|
|
8
|
-
var ENTERING = 1;
|
|
9
|
-
var ENTERED = 2;
|
|
10
|
-
var PRE_EXIT = 3;
|
|
11
|
-
var EXITING = 4;
|
|
12
|
-
var EXITED = 5;
|
|
13
|
-
var UNMOUNTED = 6;
|
|
14
|
-
var STATES = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
15
|
-
|
|
16
|
-
var startOrEnd = function startOrEnd(unmounted) {
|
|
17
|
-
return unmounted ? UNMOUNTED : EXITED;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
var updateState = function updateState(state, setState, latestState, timeoutId, onChange) {
|
|
21
|
-
clearTimeout(timeoutId.current);
|
|
22
|
-
setState(state);
|
|
23
|
-
latestState.current = state;
|
|
24
|
-
onChange && onChange({
|
|
25
|
-
state: STATES[state]
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
var useTransition = function useTransition(_temp) {
|
|
30
|
-
var _ref = _temp === void 0 ? {} : _temp,
|
|
31
|
-
_ref$enter = _ref.enter,
|
|
32
|
-
enter = _ref$enter === void 0 ? true : _ref$enter,
|
|
33
|
-
_ref$exit = _ref.exit,
|
|
34
|
-
exit = _ref$exit === void 0 ? true : _ref$exit,
|
|
35
|
-
preEnter = _ref.preEnter,
|
|
36
|
-
preExit = _ref.preExit,
|
|
37
|
-
timeout = _ref.timeout,
|
|
38
|
-
initialEntered = _ref.initialEntered,
|
|
39
|
-
mountOnEnter = _ref.mountOnEnter,
|
|
40
|
-
unmountOnExit = _ref.unmountOnExit,
|
|
41
|
-
onChange = _ref.onChange;
|
|
42
|
-
|
|
43
|
-
var _useState = react.useState(initialEntered ? ENTERED : startOrEnd(mountOnEnter)),
|
|
44
|
-
state = _useState[0],
|
|
45
|
-
setState = _useState[1];
|
|
46
|
-
|
|
47
|
-
var latestState = react.useRef(state);
|
|
48
|
-
var timeoutId = react.useRef();
|
|
49
|
-
var enterTimeout, exitTimeout;
|
|
50
|
-
|
|
51
|
-
if (typeof timeout === 'object') {
|
|
52
|
-
enterTimeout = timeout.enter;
|
|
53
|
-
exitTimeout = timeout.exit;
|
|
54
|
-
} else {
|
|
55
|
-
enterTimeout = exitTimeout = timeout;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
var endTransition = react.useCallback(function () {
|
|
59
|
-
var newState;
|
|
60
|
-
|
|
61
|
-
switch (latestState.current) {
|
|
62
|
-
case ENTERING:
|
|
63
|
-
case PRE_ENTER:
|
|
64
|
-
newState = ENTERED;
|
|
65
|
-
break;
|
|
66
|
-
|
|
67
|
-
case EXITING:
|
|
68
|
-
case PRE_EXIT:
|
|
69
|
-
newState = startOrEnd(unmountOnExit);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (newState !== undefined) {
|
|
74
|
-
updateState(newState, setState, latestState, timeoutId, onChange);
|
|
75
|
-
}
|
|
76
|
-
}, [onChange, unmountOnExit]);
|
|
77
|
-
var toggle = react.useCallback(function (toEnter) {
|
|
78
|
-
var transitState = function transitState(newState) {
|
|
79
|
-
updateState(newState, setState, latestState, timeoutId, onChange);
|
|
80
|
-
|
|
81
|
-
switch (newState) {
|
|
82
|
-
case ENTERING:
|
|
83
|
-
if (enterTimeout >= 0) timeoutId.current = setTimeout(endTransition, enterTimeout);
|
|
84
|
-
break;
|
|
85
|
-
|
|
86
|
-
case EXITING:
|
|
87
|
-
if (exitTimeout >= 0) timeoutId.current = setTimeout(endTransition, exitTimeout);
|
|
88
|
-
break;
|
|
89
|
-
|
|
90
|
-
case PRE_ENTER:
|
|
91
|
-
case PRE_EXIT:
|
|
92
|
-
timeoutId.current = setTimeout(function () {
|
|
93
|
-
return transitState(newState + 1);
|
|
94
|
-
}, 0);
|
|
95
|
-
break;
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
var enterStage = latestState.current <= ENTERED;
|
|
100
|
-
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
101
|
-
|
|
102
|
-
if (toEnter) {
|
|
103
|
-
if (!enterStage) {
|
|
104
|
-
transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
105
|
-
}
|
|
106
|
-
} else {
|
|
107
|
-
if (enterStage) {
|
|
108
|
-
transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}, [endTransition, onChange, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
|
|
112
|
-
react.useEffect(function () {
|
|
113
|
-
return function () {
|
|
114
|
-
return clearTimeout(timeoutId.current);
|
|
115
|
-
};
|
|
116
|
-
}, []);
|
|
117
|
-
return [STATES[state], toggle, endTransition];
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
exports['default'] = useTransition;
|
|
121
|
-
exports.useTransition = useTransition;
|