react-transition-state 2.0.2 → 2.1.0-alpha.0
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/dist/cjs/index.js +116 -179
- package/dist/es/hooks/useTransition.js +25 -49
- package/dist/es/hooks/useTransitionMap.js +75 -107
- package/dist/es/hooks/utils.js +18 -25
- package/package.json +15 -15
package/dist/cjs/index.js
CHANGED
|
@@ -4,267 +4,204 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var react = require('react');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var startOrEnd = function startOrEnd(unmounted) {
|
|
25
|
-
return unmounted ? UNMOUNTED : EXITED;
|
|
26
|
-
};
|
|
27
|
-
var getEndStatus = function getEndStatus(status, unmountOnExit) {
|
|
7
|
+
const PRE_ENTER = 0;
|
|
8
|
+
const ENTERING = 1;
|
|
9
|
+
const ENTERED = 2;
|
|
10
|
+
const PRE_EXIT = 3;
|
|
11
|
+
const EXITING = 4;
|
|
12
|
+
const EXITED = 5;
|
|
13
|
+
const UNMOUNTED = 6;
|
|
14
|
+
const STATUS = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
15
|
+
const getState = status => ({
|
|
16
|
+
_status: status,
|
|
17
|
+
status: STATUS[status],
|
|
18
|
+
isEnter: status < PRE_EXIT,
|
|
19
|
+
isMounted: status !== UNMOUNTED,
|
|
20
|
+
isResolved: status === ENTERED || status > EXITING
|
|
21
|
+
});
|
|
22
|
+
const startOrEnd = unmounted => unmounted ? UNMOUNTED : EXITED;
|
|
23
|
+
const getEndStatus = (status, unmountOnExit) => {
|
|
28
24
|
switch (status) {
|
|
29
25
|
case ENTERING:
|
|
30
26
|
case PRE_ENTER:
|
|
31
27
|
return ENTERED;
|
|
32
|
-
|
|
33
28
|
case EXITING:
|
|
34
29
|
case PRE_EXIT:
|
|
35
30
|
return startOrEnd(unmountOnExit);
|
|
36
31
|
}
|
|
37
32
|
};
|
|
38
|
-
|
|
39
|
-
return typeof timeout === 'object' ? [timeout.enter, timeout.exit] : [timeout, timeout];
|
|
40
|
-
};
|
|
33
|
+
const getTimeout = timeout => typeof timeout === 'object' ? [timeout.enter, timeout.exit] : [timeout, timeout];
|
|
41
34
|
|
|
42
|
-
|
|
35
|
+
const updateState$1 = (status, setState, latestState, timeoutId, onChange) => {
|
|
43
36
|
clearTimeout(timeoutId.current);
|
|
44
|
-
|
|
37
|
+
const state = getState(status);
|
|
45
38
|
setState(state);
|
|
46
39
|
latestState.current = state;
|
|
47
40
|
onChange && onChange({
|
|
48
41
|
current: state
|
|
49
42
|
});
|
|
50
43
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}),
|
|
69
|
-
state = _useState[0],
|
|
70
|
-
setState = _useState[1];
|
|
71
|
-
|
|
72
|
-
var latestState = react.useRef(state);
|
|
73
|
-
var timeoutId = react.useRef();
|
|
74
|
-
|
|
75
|
-
var _getTimeout = getTimeout(timeout),
|
|
76
|
-
enterTimeout = _getTimeout[0],
|
|
77
|
-
exitTimeout = _getTimeout[1];
|
|
78
|
-
|
|
79
|
-
var endTransition = react.useCallback(function () {
|
|
80
|
-
var status = getEndStatus(latestState.current._status, unmountOnExit);
|
|
44
|
+
const useTransition = ({
|
|
45
|
+
enter = true,
|
|
46
|
+
exit = true,
|
|
47
|
+
preEnter,
|
|
48
|
+
preExit,
|
|
49
|
+
timeout,
|
|
50
|
+
initialEntered,
|
|
51
|
+
mountOnEnter,
|
|
52
|
+
unmountOnExit,
|
|
53
|
+
onStateChange: onChange
|
|
54
|
+
} = {}) => {
|
|
55
|
+
const [state, setState] = react.useState(() => getState(initialEntered ? ENTERED : startOrEnd(mountOnEnter)));
|
|
56
|
+
const latestState = react.useRef(state);
|
|
57
|
+
const timeoutId = react.useRef();
|
|
58
|
+
const [enterTimeout, exitTimeout] = getTimeout(timeout);
|
|
59
|
+
const endTransition = react.useCallback(() => {
|
|
60
|
+
const status = getEndStatus(latestState.current._status, unmountOnExit);
|
|
81
61
|
status && updateState$1(status, setState, latestState, timeoutId, onChange);
|
|
82
62
|
}, [onChange, unmountOnExit]);
|
|
83
|
-
|
|
84
|
-
|
|
63
|
+
const toggle = react.useCallback(toEnter => {
|
|
64
|
+
const transitState = status => {
|
|
85
65
|
updateState$1(status, setState, latestState, timeoutId, onChange);
|
|
86
|
-
|
|
87
66
|
switch (status) {
|
|
88
67
|
case ENTERING:
|
|
89
68
|
if (enterTimeout >= 0) timeoutId.current = setTimeout(endTransition, enterTimeout);
|
|
90
69
|
break;
|
|
91
|
-
|
|
92
70
|
case EXITING:
|
|
93
71
|
if (exitTimeout >= 0) timeoutId.current = setTimeout(endTransition, exitTimeout);
|
|
94
72
|
break;
|
|
95
|
-
|
|
96
73
|
case PRE_ENTER:
|
|
97
74
|
case PRE_EXIT:
|
|
98
|
-
timeoutId.current = setTimeout(
|
|
99
|
-
return transitState(status + 1);
|
|
100
|
-
}, 0);
|
|
75
|
+
timeoutId.current = setTimeout(() => transitState(status + 1), 0);
|
|
101
76
|
break;
|
|
102
77
|
}
|
|
103
78
|
};
|
|
104
|
-
|
|
105
|
-
var enterStage = latestState.current.isEnter;
|
|
79
|
+
const enterStage = latestState.current.isEnter;
|
|
106
80
|
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
107
|
-
|
|
108
81
|
if (toEnter) {
|
|
109
82
|
!enterStage && transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
110
83
|
} else {
|
|
111
84
|
enterStage && transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
|
|
112
85
|
}
|
|
113
86
|
}, [endTransition, onChange, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
|
|
114
|
-
react.useEffect(
|
|
115
|
-
return function () {
|
|
116
|
-
return clearTimeout(timeoutId.current);
|
|
117
|
-
};
|
|
118
|
-
}, []);
|
|
87
|
+
react.useEffect(() => () => clearTimeout(timeoutId.current), []);
|
|
119
88
|
return [state, toggle, endTransition];
|
|
120
89
|
};
|
|
121
90
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
91
|
+
const initialStateMap = new Map();
|
|
92
|
+
const initialConfigMap = new Map();
|
|
93
|
+
const updateState = ({
|
|
94
|
+
key,
|
|
95
|
+
status,
|
|
96
|
+
setStateMap,
|
|
97
|
+
latestStateMap,
|
|
98
|
+
timeoutId,
|
|
99
|
+
onChange
|
|
100
|
+
}) => {
|
|
132
101
|
clearTimeout(timeoutId);
|
|
133
|
-
|
|
134
|
-
|
|
102
|
+
const state = getState(status);
|
|
103
|
+
const stateMap = new Map(latestStateMap.current);
|
|
135
104
|
stateMap.set(key, state);
|
|
136
105
|
setStateMap(stateMap);
|
|
137
106
|
latestStateMap.current = stateMap;
|
|
138
107
|
onChange && onChange({
|
|
139
|
-
key
|
|
108
|
+
key,
|
|
140
109
|
current: state
|
|
141
110
|
});
|
|
142
111
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
var configMap = react.useRef(initialConfigMap);
|
|
165
|
-
|
|
166
|
-
var _getTimeout = getTimeout(timeout),
|
|
167
|
-
enterTimeout = _getTimeout[0],
|
|
168
|
-
exitTimeout = _getTimeout[1];
|
|
169
|
-
|
|
170
|
-
var setItem = react.useCallback(function (key, config) {
|
|
171
|
-
var _ref3 = config || {},
|
|
172
|
-
_ref3$initialEntered = _ref3.initialEntered,
|
|
173
|
-
_initialEntered = _ref3$initialEntered === void 0 ? initialEntered : _ref3$initialEntered;
|
|
174
|
-
|
|
175
|
-
var status = _initialEntered ? ENTERED : startOrEnd(mountOnEnter);
|
|
112
|
+
const useTransitionMap = ({
|
|
113
|
+
allowMultiple,
|
|
114
|
+
enter = true,
|
|
115
|
+
exit = true,
|
|
116
|
+
preEnter,
|
|
117
|
+
preExit,
|
|
118
|
+
timeout,
|
|
119
|
+
initialEntered,
|
|
120
|
+
mountOnEnter,
|
|
121
|
+
unmountOnExit,
|
|
122
|
+
onStateChange: onChange
|
|
123
|
+
} = {}) => {
|
|
124
|
+
const [stateMap, setStateMap] = react.useState(initialStateMap);
|
|
125
|
+
const latestStateMap = react.useRef(stateMap);
|
|
126
|
+
const configMap = react.useRef(initialConfigMap);
|
|
127
|
+
const [enterTimeout, exitTimeout] = getTimeout(timeout);
|
|
128
|
+
const setItem = react.useCallback((key, config) => {
|
|
129
|
+
const {
|
|
130
|
+
initialEntered: _initialEntered = initialEntered
|
|
131
|
+
} = config || {};
|
|
132
|
+
const status = _initialEntered ? ENTERED : startOrEnd(mountOnEnter);
|
|
176
133
|
updateState({
|
|
177
|
-
key
|
|
178
|
-
status
|
|
179
|
-
setStateMap
|
|
180
|
-
latestStateMap
|
|
134
|
+
key,
|
|
135
|
+
status,
|
|
136
|
+
setStateMap,
|
|
137
|
+
latestStateMap
|
|
181
138
|
});
|
|
182
139
|
configMap.current.set(key, {});
|
|
183
140
|
}, [initialEntered, mountOnEnter]);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
141
|
+
const deleteItem = react.useCallback(key => {
|
|
142
|
+
const newStateMap = new Map(latestStateMap.current);
|
|
187
143
|
if (newStateMap.delete(key)) {
|
|
188
144
|
setStateMap(newStateMap);
|
|
189
145
|
latestStateMap.current = newStateMap;
|
|
190
146
|
configMap.current.delete(key);
|
|
191
147
|
return true;
|
|
192
148
|
}
|
|
193
|
-
|
|
194
149
|
return false;
|
|
195
150
|
}, []);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
151
|
+
const endTransition = react.useCallback(key => {
|
|
152
|
+
const stateObj = latestStateMap.current.get(key);
|
|
199
153
|
if (!stateObj) {
|
|
200
|
-
process.env.NODE_ENV !== 'production' && console.error(
|
|
154
|
+
process.env.NODE_ENV !== 'production' && console.error(`[React-Transition-State] invalid key: ${key}`);
|
|
201
155
|
return;
|
|
202
156
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
var status = getEndStatus(stateObj._status, unmountOnExit);
|
|
157
|
+
const {
|
|
158
|
+
timeoutId
|
|
159
|
+
} = configMap.current.get(key);
|
|
160
|
+
const status = getEndStatus(stateObj._status, unmountOnExit);
|
|
208
161
|
status && updateState({
|
|
209
|
-
key
|
|
210
|
-
status
|
|
211
|
-
setStateMap
|
|
212
|
-
latestStateMap
|
|
213
|
-
timeoutId
|
|
214
|
-
onChange
|
|
162
|
+
key,
|
|
163
|
+
status,
|
|
164
|
+
setStateMap,
|
|
165
|
+
latestStateMap,
|
|
166
|
+
timeoutId,
|
|
167
|
+
onChange
|
|
215
168
|
});
|
|
216
169
|
}, [onChange, unmountOnExit]);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
170
|
+
const toggle = react.useCallback((key, toEnter) => {
|
|
171
|
+
const stateObj = latestStateMap.current.get(key);
|
|
220
172
|
if (!stateObj) {
|
|
221
|
-
process.env.NODE_ENV !== 'production' && console.error(
|
|
173
|
+
process.env.NODE_ENV !== 'production' && console.error(`[React-Transition-State] invalid key: ${key}`);
|
|
222
174
|
return;
|
|
223
175
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
var transitState = function transitState(status) {
|
|
176
|
+
const config = configMap.current.get(key);
|
|
177
|
+
const transitState = status => {
|
|
228
178
|
updateState({
|
|
229
|
-
key
|
|
230
|
-
status
|
|
231
|
-
setStateMap
|
|
232
|
-
latestStateMap
|
|
179
|
+
key,
|
|
180
|
+
status,
|
|
181
|
+
setStateMap,
|
|
182
|
+
latestStateMap,
|
|
233
183
|
timeoutId: config.timeoutId,
|
|
234
|
-
onChange
|
|
184
|
+
onChange
|
|
235
185
|
});
|
|
236
|
-
|
|
237
186
|
switch (status) {
|
|
238
187
|
case ENTERING:
|
|
239
|
-
if (enterTimeout >= 0) config.timeoutId = setTimeout(
|
|
240
|
-
return endTransition(key);
|
|
241
|
-
}, enterTimeout);
|
|
188
|
+
if (enterTimeout >= 0) config.timeoutId = setTimeout(() => endTransition(key), enterTimeout);
|
|
242
189
|
break;
|
|
243
|
-
|
|
244
190
|
case EXITING:
|
|
245
|
-
if (exitTimeout >= 0) config.timeoutId = setTimeout(
|
|
246
|
-
return endTransition(key);
|
|
247
|
-
}, exitTimeout);
|
|
191
|
+
if (exitTimeout >= 0) config.timeoutId = setTimeout(() => endTransition(key), exitTimeout);
|
|
248
192
|
break;
|
|
249
|
-
|
|
250
193
|
case PRE_ENTER:
|
|
251
194
|
case PRE_EXIT:
|
|
252
|
-
config.timeoutId = setTimeout(
|
|
253
|
-
return transitState(status + 1);
|
|
254
|
-
}, 0);
|
|
195
|
+
config.timeoutId = setTimeout(() => transitState(status + 1), 0);
|
|
255
196
|
break;
|
|
256
197
|
}
|
|
257
198
|
};
|
|
258
|
-
|
|
259
|
-
var enterStage = stateObj.isEnter;
|
|
199
|
+
const enterStage = stateObj.isEnter;
|
|
260
200
|
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
261
|
-
|
|
262
201
|
if (toEnter) {
|
|
263
202
|
if (!enterStage) {
|
|
264
203
|
transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
265
|
-
!allowMultiple && latestStateMap.current.forEach(
|
|
266
|
-
return _key !== key && toggle(_key, false);
|
|
267
|
-
});
|
|
204
|
+
!allowMultiple && latestStateMap.current.forEach((_, _key) => _key !== key && toggle(_key, false));
|
|
268
205
|
}
|
|
269
206
|
} else {
|
|
270
207
|
if (enterStage) {
|
|
@@ -273,14 +210,14 @@ var useTransitionMap = function useTransitionMap(_temp) {
|
|
|
273
210
|
}
|
|
274
211
|
}, [onChange, endTransition, allowMultiple, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
|
|
275
212
|
return {
|
|
276
|
-
stateMap
|
|
277
|
-
toggle
|
|
278
|
-
endTransition
|
|
279
|
-
setItem
|
|
280
|
-
deleteItem
|
|
213
|
+
stateMap,
|
|
214
|
+
toggle,
|
|
215
|
+
endTransition,
|
|
216
|
+
setItem,
|
|
217
|
+
deleteItem
|
|
281
218
|
};
|
|
282
219
|
};
|
|
283
220
|
|
|
284
|
-
exports
|
|
221
|
+
exports.default = useTransition;
|
|
285
222
|
exports.useTransition = useTransition;
|
|
286
223
|
exports.useTransitionMap = useTransitionMap;
|
|
@@ -1,83 +1,59 @@
|
|
|
1
1
|
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
|
-
import { getState, ENTERED, startOrEnd, getTimeout, getEndStatus,
|
|
2
|
+
import { getState, ENTERED, startOrEnd, getTimeout, getEndStatus, PRE_ENTER, ENTERING, PRE_EXIT, EXITING } from './utils.js';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const updateState = (status, setState, latestState, timeoutId, onChange) => {
|
|
5
5
|
clearTimeout(timeoutId.current);
|
|
6
|
-
|
|
6
|
+
const state = getState(status);
|
|
7
7
|
setState(state);
|
|
8
8
|
latestState.current = state;
|
|
9
9
|
onChange && onChange({
|
|
10
10
|
current: state
|
|
11
11
|
});
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}),
|
|
31
|
-
state = _useState[0],
|
|
32
|
-
setState = _useState[1];
|
|
33
|
-
|
|
34
|
-
var latestState = useRef(state);
|
|
35
|
-
var timeoutId = useRef();
|
|
36
|
-
|
|
37
|
-
var _getTimeout = getTimeout(timeout),
|
|
38
|
-
enterTimeout = _getTimeout[0],
|
|
39
|
-
exitTimeout = _getTimeout[1];
|
|
40
|
-
|
|
41
|
-
var endTransition = useCallback(function () {
|
|
42
|
-
var status = getEndStatus(latestState.current._status, unmountOnExit);
|
|
13
|
+
const useTransition = ({
|
|
14
|
+
enter = true,
|
|
15
|
+
exit = true,
|
|
16
|
+
preEnter,
|
|
17
|
+
preExit,
|
|
18
|
+
timeout,
|
|
19
|
+
initialEntered,
|
|
20
|
+
mountOnEnter,
|
|
21
|
+
unmountOnExit,
|
|
22
|
+
onStateChange: onChange
|
|
23
|
+
} = {}) => {
|
|
24
|
+
const [state, setState] = useState(() => getState(initialEntered ? ENTERED : startOrEnd(mountOnEnter)));
|
|
25
|
+
const latestState = useRef(state);
|
|
26
|
+
const timeoutId = useRef();
|
|
27
|
+
const [enterTimeout, exitTimeout] = getTimeout(timeout);
|
|
28
|
+
const endTransition = useCallback(() => {
|
|
29
|
+
const status = getEndStatus(latestState.current._status, unmountOnExit);
|
|
43
30
|
status && updateState(status, setState, latestState, timeoutId, onChange);
|
|
44
31
|
}, [onChange, unmountOnExit]);
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
const toggle = useCallback(toEnter => {
|
|
33
|
+
const transitState = status => {
|
|
47
34
|
updateState(status, setState, latestState, timeoutId, onChange);
|
|
48
|
-
|
|
49
35
|
switch (status) {
|
|
50
36
|
case ENTERING:
|
|
51
37
|
if (enterTimeout >= 0) timeoutId.current = setTimeout(endTransition, enterTimeout);
|
|
52
38
|
break;
|
|
53
|
-
|
|
54
39
|
case EXITING:
|
|
55
40
|
if (exitTimeout >= 0) timeoutId.current = setTimeout(endTransition, exitTimeout);
|
|
56
41
|
break;
|
|
57
|
-
|
|
58
42
|
case PRE_ENTER:
|
|
59
43
|
case PRE_EXIT:
|
|
60
|
-
timeoutId.current = setTimeout(
|
|
61
|
-
return transitState(status + 1);
|
|
62
|
-
}, 0);
|
|
44
|
+
timeoutId.current = setTimeout(() => transitState(status + 1), 0);
|
|
63
45
|
break;
|
|
64
46
|
}
|
|
65
47
|
};
|
|
66
|
-
|
|
67
|
-
var enterStage = latestState.current.isEnter;
|
|
48
|
+
const enterStage = latestState.current.isEnter;
|
|
68
49
|
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
69
|
-
|
|
70
50
|
if (toEnter) {
|
|
71
51
|
!enterStage && transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
72
52
|
} else {
|
|
73
53
|
enterStage && transitState(exit ? preExit ? PRE_EXIT : EXITING : startOrEnd(unmountOnExit));
|
|
74
54
|
}
|
|
75
55
|
}, [endTransition, onChange, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
|
|
76
|
-
useEffect(
|
|
77
|
-
return function () {
|
|
78
|
-
return clearTimeout(timeoutId.current);
|
|
79
|
-
};
|
|
80
|
-
}, []);
|
|
56
|
+
useEffect(() => () => clearTimeout(timeoutId.current), []);
|
|
81
57
|
return [state, toggle, endTransition];
|
|
82
58
|
};
|
|
83
59
|
|
|
@@ -1,152 +1,120 @@
|
|
|
1
1
|
import { useState, useRef, useCallback } from 'react';
|
|
2
|
-
import { getTimeout, ENTERED, startOrEnd, getEndStatus,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
import { getTimeout, ENTERED, startOrEnd, getEndStatus, PRE_ENTER, ENTERING, PRE_EXIT, EXITING, getState } from './utils.js';
|
|
3
|
+
|
|
4
|
+
const initialStateMap = new Map();
|
|
5
|
+
const initialConfigMap = new Map();
|
|
6
|
+
const updateState = ({
|
|
7
|
+
key,
|
|
8
|
+
status,
|
|
9
|
+
setStateMap,
|
|
10
|
+
latestStateMap,
|
|
11
|
+
timeoutId,
|
|
12
|
+
onChange
|
|
13
|
+
}) => {
|
|
14
14
|
clearTimeout(timeoutId);
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const state = getState(status);
|
|
16
|
+
const stateMap = new Map(latestStateMap.current);
|
|
17
17
|
stateMap.set(key, state);
|
|
18
18
|
setStateMap(stateMap);
|
|
19
19
|
latestStateMap.current = stateMap;
|
|
20
20
|
onChange && onChange({
|
|
21
|
-
key
|
|
21
|
+
key,
|
|
22
22
|
current: state
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
var configMap = useRef(initialConfigMap);
|
|
47
|
-
|
|
48
|
-
var _getTimeout = getTimeout(timeout),
|
|
49
|
-
enterTimeout = _getTimeout[0],
|
|
50
|
-
exitTimeout = _getTimeout[1];
|
|
51
|
-
|
|
52
|
-
var setItem = useCallback(function (key, config) {
|
|
53
|
-
var _ref3 = config || {},
|
|
54
|
-
_ref3$initialEntered = _ref3.initialEntered,
|
|
55
|
-
_initialEntered = _ref3$initialEntered === void 0 ? initialEntered : _ref3$initialEntered;
|
|
56
|
-
|
|
57
|
-
var status = _initialEntered ? ENTERED : startOrEnd(mountOnEnter);
|
|
25
|
+
const useTransitionMap = ({
|
|
26
|
+
allowMultiple,
|
|
27
|
+
enter = true,
|
|
28
|
+
exit = true,
|
|
29
|
+
preEnter,
|
|
30
|
+
preExit,
|
|
31
|
+
timeout,
|
|
32
|
+
initialEntered,
|
|
33
|
+
mountOnEnter,
|
|
34
|
+
unmountOnExit,
|
|
35
|
+
onStateChange: onChange
|
|
36
|
+
} = {}) => {
|
|
37
|
+
const [stateMap, setStateMap] = useState(initialStateMap);
|
|
38
|
+
const latestStateMap = useRef(stateMap);
|
|
39
|
+
const configMap = useRef(initialConfigMap);
|
|
40
|
+
const [enterTimeout, exitTimeout] = getTimeout(timeout);
|
|
41
|
+
const setItem = useCallback((key, config) => {
|
|
42
|
+
const {
|
|
43
|
+
initialEntered: _initialEntered = initialEntered
|
|
44
|
+
} = config || {};
|
|
45
|
+
const status = _initialEntered ? ENTERED : startOrEnd(mountOnEnter);
|
|
58
46
|
updateState({
|
|
59
|
-
key
|
|
60
|
-
status
|
|
61
|
-
setStateMap
|
|
62
|
-
latestStateMap
|
|
47
|
+
key,
|
|
48
|
+
status,
|
|
49
|
+
setStateMap,
|
|
50
|
+
latestStateMap
|
|
63
51
|
});
|
|
64
52
|
configMap.current.set(key, {});
|
|
65
53
|
}, [initialEntered, mountOnEnter]);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
54
|
+
const deleteItem = useCallback(key => {
|
|
55
|
+
const newStateMap = new Map(latestStateMap.current);
|
|
69
56
|
if (newStateMap.delete(key)) {
|
|
70
57
|
setStateMap(newStateMap);
|
|
71
58
|
latestStateMap.current = newStateMap;
|
|
72
59
|
configMap.current.delete(key);
|
|
73
60
|
return true;
|
|
74
61
|
}
|
|
75
|
-
|
|
76
62
|
return false;
|
|
77
63
|
}, []);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
64
|
+
const endTransition = useCallback(key => {
|
|
65
|
+
const stateObj = latestStateMap.current.get(key);
|
|
81
66
|
if (!stateObj) {
|
|
82
|
-
process.env.NODE_ENV !== 'production' && console.error(
|
|
67
|
+
process.env.NODE_ENV !== 'production' && console.error(`[React-Transition-State] invalid key: ${key}`);
|
|
83
68
|
return;
|
|
84
69
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
var status = getEndStatus(stateObj._status, unmountOnExit);
|
|
70
|
+
const {
|
|
71
|
+
timeoutId
|
|
72
|
+
} = configMap.current.get(key);
|
|
73
|
+
const status = getEndStatus(stateObj._status, unmountOnExit);
|
|
90
74
|
status && updateState({
|
|
91
|
-
key
|
|
92
|
-
status
|
|
93
|
-
setStateMap
|
|
94
|
-
latestStateMap
|
|
95
|
-
timeoutId
|
|
96
|
-
onChange
|
|
75
|
+
key,
|
|
76
|
+
status,
|
|
77
|
+
setStateMap,
|
|
78
|
+
latestStateMap,
|
|
79
|
+
timeoutId,
|
|
80
|
+
onChange
|
|
97
81
|
});
|
|
98
82
|
}, [onChange, unmountOnExit]);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
83
|
+
const toggle = useCallback((key, toEnter) => {
|
|
84
|
+
const stateObj = latestStateMap.current.get(key);
|
|
102
85
|
if (!stateObj) {
|
|
103
|
-
process.env.NODE_ENV !== 'production' && console.error(
|
|
86
|
+
process.env.NODE_ENV !== 'production' && console.error(`[React-Transition-State] invalid key: ${key}`);
|
|
104
87
|
return;
|
|
105
88
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
var transitState = function transitState(status) {
|
|
89
|
+
const config = configMap.current.get(key);
|
|
90
|
+
const transitState = status => {
|
|
110
91
|
updateState({
|
|
111
|
-
key
|
|
112
|
-
status
|
|
113
|
-
setStateMap
|
|
114
|
-
latestStateMap
|
|
92
|
+
key,
|
|
93
|
+
status,
|
|
94
|
+
setStateMap,
|
|
95
|
+
latestStateMap,
|
|
115
96
|
timeoutId: config.timeoutId,
|
|
116
|
-
onChange
|
|
97
|
+
onChange
|
|
117
98
|
});
|
|
118
|
-
|
|
119
99
|
switch (status) {
|
|
120
100
|
case ENTERING:
|
|
121
|
-
if (enterTimeout >= 0) config.timeoutId = setTimeout(
|
|
122
|
-
return endTransition(key);
|
|
123
|
-
}, enterTimeout);
|
|
101
|
+
if (enterTimeout >= 0) config.timeoutId = setTimeout(() => endTransition(key), enterTimeout);
|
|
124
102
|
break;
|
|
125
|
-
|
|
126
103
|
case EXITING:
|
|
127
|
-
if (exitTimeout >= 0) config.timeoutId = setTimeout(
|
|
128
|
-
return endTransition(key);
|
|
129
|
-
}, exitTimeout);
|
|
104
|
+
if (exitTimeout >= 0) config.timeoutId = setTimeout(() => endTransition(key), exitTimeout);
|
|
130
105
|
break;
|
|
131
|
-
|
|
132
106
|
case PRE_ENTER:
|
|
133
107
|
case PRE_EXIT:
|
|
134
|
-
config.timeoutId = setTimeout(
|
|
135
|
-
return transitState(status + 1);
|
|
136
|
-
}, 0);
|
|
108
|
+
config.timeoutId = setTimeout(() => transitState(status + 1), 0);
|
|
137
109
|
break;
|
|
138
110
|
}
|
|
139
111
|
};
|
|
140
|
-
|
|
141
|
-
var enterStage = stateObj.isEnter;
|
|
112
|
+
const enterStage = stateObj.isEnter;
|
|
142
113
|
if (typeof toEnter !== 'boolean') toEnter = !enterStage;
|
|
143
|
-
|
|
144
114
|
if (toEnter) {
|
|
145
115
|
if (!enterStage) {
|
|
146
116
|
transitState(enter ? preEnter ? PRE_ENTER : ENTERING : ENTERED);
|
|
147
|
-
!allowMultiple && latestStateMap.current.forEach(
|
|
148
|
-
return _key !== key && toggle(_key, false);
|
|
149
|
-
});
|
|
117
|
+
!allowMultiple && latestStateMap.current.forEach((_, _key) => _key !== key && toggle(_key, false));
|
|
150
118
|
}
|
|
151
119
|
} else {
|
|
152
120
|
if (enterStage) {
|
|
@@ -155,11 +123,11 @@ var useTransitionMap = function useTransitionMap(_temp) {
|
|
|
155
123
|
}
|
|
156
124
|
}, [onChange, endTransition, allowMultiple, enter, exit, preEnter, preExit, enterTimeout, exitTimeout, unmountOnExit]);
|
|
157
125
|
return {
|
|
158
|
-
stateMap
|
|
159
|
-
toggle
|
|
160
|
-
endTransition
|
|
161
|
-
setItem
|
|
162
|
-
deleteItem
|
|
126
|
+
stateMap,
|
|
127
|
+
toggle,
|
|
128
|
+
endTransition,
|
|
129
|
+
setItem,
|
|
130
|
+
deleteItem
|
|
163
131
|
};
|
|
164
132
|
};
|
|
165
133
|
|
package/dist/es/hooks/utils.js
CHANGED
|
@@ -1,36 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
var startOrEnd = function startOrEnd(unmounted) {
|
|
19
|
-
return unmounted ? UNMOUNTED : EXITED;
|
|
20
|
-
};
|
|
21
|
-
var getEndStatus = function getEndStatus(status, unmountOnExit) {
|
|
1
|
+
const PRE_ENTER = 0;
|
|
2
|
+
const ENTERING = 1;
|
|
3
|
+
const ENTERED = 2;
|
|
4
|
+
const PRE_EXIT = 3;
|
|
5
|
+
const EXITING = 4;
|
|
6
|
+
const EXITED = 5;
|
|
7
|
+
const UNMOUNTED = 6;
|
|
8
|
+
const STATUS = ['preEnter', 'entering', 'entered', 'preExit', 'exiting', 'exited', 'unmounted'];
|
|
9
|
+
const getState = status => ({
|
|
10
|
+
_status: status,
|
|
11
|
+
status: STATUS[status],
|
|
12
|
+
isEnter: status < PRE_EXIT,
|
|
13
|
+
isMounted: status !== UNMOUNTED,
|
|
14
|
+
isResolved: status === ENTERED || status > EXITING
|
|
15
|
+
});
|
|
16
|
+
const startOrEnd = unmounted => unmounted ? UNMOUNTED : EXITED;
|
|
17
|
+
const getEndStatus = (status, unmountOnExit) => {
|
|
22
18
|
switch (status) {
|
|
23
19
|
case ENTERING:
|
|
24
20
|
case PRE_ENTER:
|
|
25
21
|
return ENTERED;
|
|
26
|
-
|
|
27
22
|
case EXITING:
|
|
28
23
|
case PRE_EXIT:
|
|
29
24
|
return startOrEnd(unmountOnExit);
|
|
30
25
|
}
|
|
31
26
|
};
|
|
32
|
-
|
|
33
|
-
return typeof timeout === 'object' ? [timeout.enter, timeout.exit] : [timeout, timeout];
|
|
34
|
-
};
|
|
27
|
+
const getTimeout = timeout => typeof timeout === 'object' ? [timeout.enter, timeout.exit] : [timeout, timeout];
|
|
35
28
|
|
|
36
29
|
export { ENTERED, ENTERING, EXITED, EXITING, PRE_ENTER, PRE_EXIT, STATUS, UNMOUNTED, getEndStatus, getState, getTimeout, startOrEnd };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-transition-state",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.1.0-alpha.0",
|
|
4
4
|
"description": "Zero dependency React transition state machine.",
|
|
5
5
|
"author": "Zheng Song",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,25 +41,25 @@
|
|
|
41
41
|
"react-dom": ">=16.8.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@babel/core": "^7.
|
|
45
|
-
"@babel/preset-env": "^7.
|
|
46
|
-
"@rollup/plugin-babel": "^
|
|
47
|
-
"@testing-library/react": "^13.
|
|
48
|
-
"@types/jest": "^29.
|
|
44
|
+
"@babel/core": "^7.20.12",
|
|
45
|
+
"@babel/preset-env": "^7.20.2",
|
|
46
|
+
"@rollup/plugin-babel": "^6.0.3",
|
|
47
|
+
"@testing-library/react": "^13.4.0",
|
|
48
|
+
"@types/jest": "^29.4.0",
|
|
49
49
|
"babel-plugin-pure-annotations": "^0.1.2",
|
|
50
50
|
"dtslint": "^4.1.6",
|
|
51
|
-
"eslint": "^8.
|
|
52
|
-
"eslint-config-prettier": "^8.
|
|
53
|
-
"eslint-plugin-jest": "^
|
|
51
|
+
"eslint": "^8.33.0",
|
|
52
|
+
"eslint-config-prettier": "^8.6.0",
|
|
53
|
+
"eslint-plugin-jest": "^27.2.1",
|
|
54
54
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
55
|
-
"jest": "^29.
|
|
56
|
-
"jest-environment-jsdom": "^29.
|
|
55
|
+
"jest": "^29.4.1",
|
|
56
|
+
"jest-environment-jsdom": "^29.4.1",
|
|
57
57
|
"npm-run-all": "^4.1.5",
|
|
58
|
-
"prettier": "^2.
|
|
58
|
+
"prettier": "^2.8.3",
|
|
59
59
|
"react": "^18.2.0",
|
|
60
60
|
"react-dom": "^18.2.0",
|
|
61
|
-
"regenerator-runtime": "^0.13.
|
|
62
|
-
"rollup": "^
|
|
63
|
-
"typescript": "^4.
|
|
61
|
+
"regenerator-runtime": "^0.13.11",
|
|
62
|
+
"rollup": "^3.14.0",
|
|
63
|
+
"typescript": "^4.9.5"
|
|
64
64
|
}
|
|
65
65
|
}
|