sibujs 4.5.0 → 4.6.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.
Files changed (109) hide show
  1. package/dist/browser.cjs +309 -129
  2. package/dist/browser.d.cts +46 -14
  3. package/dist/browser.d.ts +46 -14
  4. package/dist/browser.js +8 -6
  5. package/dist/build.cjs +184 -72
  6. package/dist/build.js +15 -16
  7. package/dist/cdn.dev.global.js +12 -12
  8. package/dist/cdn.full.dev.global.js +11 -11
  9. package/dist/cdn.full.global.js +10 -10
  10. package/dist/cdn.global.js +12 -12
  11. package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
  12. package/dist/chunk-3ISI6ACU.js +44 -0
  13. package/dist/{chunk-ONOHFDLG.js → chunk-47M47FOM.js} +3 -3
  14. package/dist/chunk-5HZXGZ6T.js +24 -0
  15. package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
  16. package/dist/{chunk-UGRX3S57.js → chunk-5Q4R7HCL.js} +12 -3
  17. package/dist/{chunk-S373NSMK.js → chunk-7GQCWFOE.js} +150 -59
  18. package/dist/{chunk-FTIR4QW2.js → chunk-7NCARGJW.js} +6 -8
  19. package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
  20. package/dist/{chunk-VZKNK2V7.js → chunk-AIF3Z2T7.js} +296 -38
  21. package/dist/{chunk-4PMLNECI.js → chunk-BAAG6ZTI.js} +98 -29
  22. package/dist/{chunk-XZZOBQAY.js → chunk-D33YTSX5.js} +2 -2
  23. package/dist/{chunk-TBYTO6BS.js → chunk-DKGBBKOF.js} +136 -80
  24. package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
  25. package/dist/{chunk-GW3SCCZG.js → chunk-HYXDKS4N.js} +153 -110
  26. package/dist/chunk-J6FW5TV6.js +233 -0
  27. package/dist/{chunk-PCT43HW3.js → chunk-JSXPZCET.js} +1 -1
  28. package/dist/chunk-NYNYSPK7.js +318 -0
  29. package/dist/{chunk-RJE2BNI4.js → chunk-ORMZXBKQ.js} +108 -45
  30. package/dist/{chunk-OMJJM3KM.js → chunk-OXUY2A6L.js} +287 -130
  31. package/dist/{chunk-3JZ4L5TJ.js → chunk-PK6FK2G2.js} +181 -66
  32. package/dist/{chunk-RBTPLM32.js → chunk-QE4TTDU3.js} +2 -2
  33. package/dist/{chunk-2DCGACUU.js → chunk-SXXVZMKZ.js} +251 -66
  34. package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
  35. package/dist/{chunk-7LN645I6.js → chunk-UZQ6ALFS.js} +3 -3
  36. package/dist/{chunk-KEISJXBU.js → chunk-VVWPJ543.js} +6 -8
  37. package/dist/{chunk-RIXRAYIU.js → chunk-XC4MEKGA.js} +3 -3
  38. package/dist/{chunk-B3WHI2QA.js → chunk-XRRZKZYX.js} +55 -31
  39. package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
  40. package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
  41. package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
  42. package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
  43. package/dist/data.cjs +213 -117
  44. package/dist/data.d.cts +47 -9
  45. package/dist/data.d.ts +47 -9
  46. package/dist/data.js +12 -9
  47. package/dist/devtools.cjs +81 -57
  48. package/dist/devtools.js +7 -8
  49. package/dist/dispose-GEIG2KOF.js +28 -0
  50. package/dist/ecosystem.cjs +309 -104
  51. package/dist/ecosystem.d.cts +19 -3
  52. package/dist/ecosystem.d.ts +19 -3
  53. package/dist/ecosystem.js +12 -12
  54. package/dist/extras.cjs +2133 -863
  55. package/dist/extras.d.cts +10 -9
  56. package/dist/extras.d.ts +10 -9
  57. package/dist/extras.js +39 -28
  58. package/dist/index.cjs +184 -72
  59. package/dist/index.d.cts +22 -5
  60. package/dist/index.d.ts +22 -5
  61. package/dist/index.js +24 -27
  62. package/dist/motion.cjs +107 -41
  63. package/dist/motion.js +5 -5
  64. package/dist/patterns.cjs +317 -39
  65. package/dist/patterns.d.cts +27 -9
  66. package/dist/patterns.d.ts +27 -9
  67. package/dist/patterns.js +8 -8
  68. package/dist/performance.cjs +308 -216
  69. package/dist/performance.d.cts +2 -2
  70. package/dist/performance.d.ts +2 -2
  71. package/dist/performance.js +8 -9
  72. package/dist/plugin-DVgSnTfK.d.cts +112 -0
  73. package/dist/plugin-DVgSnTfK.d.ts +112 -0
  74. package/dist/plugins.cjs +549 -202
  75. package/dist/plugins.d.cts +3 -3
  76. package/dist/plugins.d.ts +3 -3
  77. package/dist/plugins.js +35 -23
  78. package/dist/signal-EotCj4hS.d.cts +110 -0
  79. package/dist/signal-EotCj4hS.d.ts +110 -0
  80. package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
  81. package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
  82. package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
  83. package/dist/ssr.cjs +176 -72
  84. package/dist/ssr.d.cts +9 -3
  85. package/dist/ssr.d.ts +9 -3
  86. package/dist/ssr.js +11 -12
  87. package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
  88. package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
  89. package/dist/{tagFactory-DVoDpHye.d.ts → tagFactory-DFstCLQV.d.cts} +2 -100
  90. package/dist/{tagFactory-DVoDpHye.d.cts → tagFactory-DkaNVUNV.d.ts} +2 -100
  91. package/dist/testing.cjs +2484 -2185
  92. package/dist/testing.d.cts +56 -5
  93. package/dist/testing.d.ts +56 -5
  94. package/dist/testing.js +580 -307
  95. package/dist/ui.cjs +707 -317
  96. package/dist/ui.d.cts +40 -7
  97. package/dist/ui.d.ts +40 -7
  98. package/dist/ui.js +151 -56
  99. package/dist/widgets.cjs +246 -278
  100. package/dist/widgets.js +9 -10
  101. package/package.json +1 -1
  102. package/dist/chunk-2WLZ6757.js +0 -149
  103. package/dist/chunk-CCSJMTRN.js +0 -15
  104. package/dist/chunk-QKRPLZ2V.js +0 -108
  105. package/dist/chunk-VUF4ALSW.js +0 -60
  106. package/dist/chunk-WWV3SJ3L.js +0 -131
  107. package/dist/dispose-46BOMMQJ.js +0 -19
  108. package/dist/plugin-D30wlGW5.d.cts +0 -71
  109. package/dist/plugin-D30wlGW5.d.ts +0 -71
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  catchError,
15
15
  catchErrorAsync,
16
16
  clickOutside,
17
+ context,
17
18
  copyOnClick,
18
19
  deepEqual,
19
20
  deepSignal,
@@ -52,7 +53,7 @@ import {
52
53
  unregisterIsland,
53
54
  when,
54
55
  writable
55
- } from "./chunk-S373NSMK.js";
56
+ } from "./chunk-7GQCWFOE.js";
56
57
  import {
57
58
  a,
58
59
  abbr,
@@ -190,36 +191,33 @@ import {
190
191
  use,
191
192
  var_,
192
193
  video
193
- } from "./chunk-PCT43HW3.js";
194
+ } from "./chunk-JSXPZCET.js";
194
195
  import {
195
196
  trustHTML
196
- } from "./chunk-NIOYEGBQ.js";
197
+ } from "./chunk-HURREPU2.js";
197
198
  import {
198
199
  watch
199
- } from "./chunk-7LN645I6.js";
200
+ } from "./chunk-UZQ6ALFS.js";
200
201
  import {
201
202
  __resetIdCounter,
202
203
  createId
203
- } from "./chunk-CCSJMTRN.js";
204
- import {
205
- context
206
- } from "./chunk-VUF4ALSW.js";
204
+ } from "./chunk-3ISI6ACU.js";
207
205
  import {
208
206
  SVG_NS,
209
207
  tagFactory
210
- } from "./chunk-KEISJXBU.js";
208
+ } from "./chunk-VVWPJ543.js";
211
209
  import {
212
210
  bindDynamic
213
- } from "./chunk-ONOHFDLG.js";
211
+ } from "./chunk-47M47FOM.js";
214
212
  import {
215
213
  derived
216
- } from "./chunk-RBTPLM32.js";
217
- import "./chunk-IXKSNWV5.js";
214
+ } from "./chunk-QE4TTDU3.js";
215
+ import "./chunk-2INLLLMZ.js";
218
216
  import "./chunk-7ZHH77QA.js";
219
217
  import {
220
218
  effect,
221
219
  on
222
- } from "./chunk-RIXRAYIU.js";
220
+ } from "./chunk-XC4MEKGA.js";
223
221
  import {
224
222
  disableSSR,
225
223
  enableSSR,
@@ -228,33 +226,32 @@ import {
228
226
  isSSR,
229
227
  runInSSRContext,
230
228
  withSSR
231
- } from "./chunk-5DXA2J44.js";
232
- import {
233
- MAX_DRAIN_TEARDOWNS,
234
- checkLeaks,
235
- dispose,
236
- registerDisposer,
237
- replaceChildrenSafely,
238
- reportDrainRunaway,
239
- unregisterDisposer
240
- } from "./chunk-QKRPLZ2V.js";
229
+ } from "./chunk-7XHATCIH.js";
230
+ import "./chunk-5HZXGZ6T.js";
241
231
  import {
242
232
  batch,
243
233
  enqueueBatchedSignal,
244
234
  external,
245
235
  isBatching,
246
236
  signal
247
- } from "./chunk-XZZOBQAY.js";
237
+ } from "./chunk-D33YTSX5.js";
248
238
  import {
249
239
  retrack,
250
240
  setMaxDrainIterations,
251
241
  untracked
252
- } from "./chunk-UGRX3S57.js";
242
+ } from "./chunk-5Q4R7HCL.js";
253
243
  import {
244
+ MAX_DRAIN_TEARDOWNS,
245
+ checkLeaks,
246
+ dispose,
254
247
  getRuntimeErrorHandler,
248
+ registerDisposer,
249
+ replaceChildrenSafely,
250
+ reportDrainRunaway,
255
251
  reportError,
256
- setRuntimeErrorHandler
257
- } from "./chunk-2WLZ6757.js";
252
+ setRuntimeErrorHandler,
253
+ unregisterDisposer
254
+ } from "./chunk-NYNYSPK7.js";
258
255
  export {
259
256
  DynamicComponent,
260
257
  ErrorBoundary,
package/dist/motion.cjs CHANGED
@@ -44,17 +44,6 @@ __export(motion_exports, {
44
44
  });
45
45
  module.exports = __toCommonJS(motion_exports);
46
46
 
47
- // src/core/dev.ts
48
- var DEV = typeof __SIBU_DEV__ !== "undefined" ? !!__SIBU_DEV__ : typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
49
- // safe default: off in browser, on in test/dev Node
50
- typeof process !== "undefined" && process.env?.NODE_ENV !== "production"
51
- );
52
- function devWarn(message) {
53
- if (typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) {
54
- console.warn(`[SibuJS] ${message}`);
55
- }
56
- }
57
-
58
47
  // src/core/errors.ts
59
48
  var ERROR_STATE_KEY = /* @__PURE__ */ Symbol.for("sibujs.runtime-errors.v1");
60
49
  function state() {
@@ -143,9 +132,37 @@ function reportError(error, context) {
143
132
  });
144
133
  }
145
134
 
135
+ // src/core/dev.ts
136
+ var DEV = typeof __SIBU_DEV__ !== "undefined" ? !!__SIBU_DEV__ : typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
137
+ // safe default: off in browser, on in test/dev Node
138
+ typeof process !== "undefined" && process.env?.NODE_ENV !== "production"
139
+ );
140
+ function devWarn(message) {
141
+ if (typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) {
142
+ console.warn(`[SibuJS] ${message}`);
143
+ }
144
+ }
145
+
146
146
  // src/core/rendering/dispose.ts
147
147
  var elementDisposers = /* @__PURE__ */ new WeakMap();
148
148
  var activeBindingCount = 0;
149
+ function resolveCapture(capture) {
150
+ let frame = capture;
151
+ while (frame?.closed) frame = frame.forwardTo;
152
+ return frame ?? null;
153
+ }
154
+ var registrationCaptures = [];
155
+ function currentDisposerCapture() {
156
+ return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
157
+ }
158
+ function beginDisposerCapture(capture) {
159
+ if (capture === null && registrationCaptures.length === 0) return false;
160
+ registrationCaptures.push(resolveCapture(capture));
161
+ return true;
162
+ }
163
+ function endDisposerCapture() {
164
+ registrationCaptures.pop();
165
+ }
149
166
  function registerDisposer(node, teardown) {
150
167
  let disposers = elementDisposers.get(node);
151
168
  if (!disposers) {
@@ -154,6 +171,8 @@ function registerDisposer(node, teardown) {
154
171
  }
155
172
  disposers.push(teardown);
156
173
  if (DEV) activeBindingCount++;
174
+ const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
175
+ if (capture) capture.entries.push([node, teardown]);
157
176
  }
158
177
 
159
178
  // src/ui/transition.ts
@@ -183,6 +202,15 @@ function transition(element, options = {}) {
183
202
  resolvePrev();
184
203
  }
185
204
  }
205
+ function complete(callback, name, resolve) {
206
+ try {
207
+ callback?.();
208
+ } catch (error) {
209
+ reportError(error, { phase: "async", name, node: element });
210
+ } finally {
211
+ resolve();
212
+ }
213
+ }
186
214
  function enter() {
187
215
  return new Promise((resolve) => {
188
216
  cancelPending();
@@ -195,8 +223,7 @@ function transition(element, options = {}) {
195
223
  activeTimer = null;
196
224
  pendingResolve = null;
197
225
  if (enterClass) element.classList.remove(enterClass);
198
- onEnterDone?.();
199
- resolve();
226
+ complete(onEnterDone, "transition(onEnterDone)", resolve);
200
227
  };
201
228
  if (duration > 0) {
202
229
  pendingResolve = resolve;
@@ -217,8 +244,7 @@ function transition(element, options = {}) {
217
244
  activeTimer = null;
218
245
  pendingResolve = null;
219
246
  if (leaveClass) element.classList.remove(leaveClass);
220
- onLeaveDone?.();
221
- resolve();
247
+ complete(onLeaveDone, "transition(onLeaveDone)", resolve);
222
248
  };
223
249
  if (duration > 0) {
224
250
  pendingResolve = resolve;
@@ -402,6 +428,7 @@ function retrack(effectFn, subscriber) {
402
428
  }
403
429
  currentSubscriber = subscriber;
404
430
  const sub = subscriber;
431
+ if (sub._cap === void 0) sub._cap = currentDisposerCapture();
405
432
  const epoch = ++subscriberEpochCounter;
406
433
  sub._epoch = epoch;
407
434
  sub._structDirty = false;
@@ -593,7 +620,12 @@ function drainQueue() {
593
620
  quarantined.add(sub);
594
621
  continue;
595
622
  }
596
- safeInvoke(sub);
623
+ const pushed = beginDisposerCapture(sub._cap ?? null);
624
+ try {
625
+ safeInvoke(sub);
626
+ } finally {
627
+ if (pushed) endDisposerCapture();
628
+ }
597
629
  }
598
630
  }
599
631
  function drainNotificationQueue() {
@@ -729,7 +761,7 @@ function forEachSubscriber(signal2, visit) {
729
761
  }
730
762
 
731
763
  // src/reactivity/track.ts
732
- var _runtimeVersion = true ? "4.5.0" : "dev";
764
+ var _runtimeVersion = true ? "4.6.0" : "dev";
733
765
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
734
766
  function resolveReactiveApi() {
735
767
  const g = globalThis;
@@ -1083,22 +1115,54 @@ async function sequence(steps) {
1083
1115
  }
1084
1116
  }
1085
1117
 
1118
+ // src/utils/adoptThenable.ts
1119
+ function adoptThenable(value) {
1120
+ if (value === null || typeof value !== "object" && typeof value !== "function") return null;
1121
+ let then;
1122
+ try {
1123
+ then = value.then;
1124
+ } catch (error) {
1125
+ return Promise.reject(error);
1126
+ }
1127
+ if (typeof then !== "function") return null;
1128
+ return new Promise((resolve, reject) => {
1129
+ queueMicrotask(() => {
1130
+ try {
1131
+ Reflect.apply(then, value, [resolve, reject]);
1132
+ } catch (error) {
1133
+ reject(error);
1134
+ }
1135
+ });
1136
+ });
1137
+ }
1138
+
1086
1139
  // src/ui/TransitionGroup.ts
1087
1140
  function TransitionGroup(options) {
1088
1141
  const [elements, setElements] = signal([]);
1089
1142
  const positions = /* @__PURE__ */ new Map();
1143
+ function runCallback(name, callback, el) {
1144
+ const report = (error) => reportError(error, { phase: "async", name: `TransitionGroup.${name}`, node: el });
1145
+ try {
1146
+ adoptThenable(callback(el))?.then(void 0, report);
1147
+ } catch (error) {
1148
+ report(error);
1149
+ }
1150
+ }
1090
1151
  function add(el) {
1091
1152
  setElements((prev) => [...prev, el]);
1092
- if (options.enter) {
1093
- options.enter(el);
1094
- }
1153
+ if (options.enter) runCallback("enter", options.enter, el);
1095
1154
  }
1096
1155
  async function remove(el) {
1097
- if (options.leave) {
1098
- await options.leave(el);
1156
+ try {
1157
+ if (options.leave) {
1158
+ await adoptThenable(options.leave(el));
1159
+ }
1160
+ } catch (error) {
1161
+ reportError(error, { phase: "async", name: "TransitionGroup.leave", node: el });
1162
+ } finally {
1163
+ positions.delete(el);
1164
+ setElements((prev) => prev.filter((e) => e !== el));
1099
1165
  }
1100
- positions.delete(el);
1101
- setElements((prev) => prev.filter((e) => e !== el));
1102
1166
  }
1103
1167
  function track3(newElements) {
1104
1168
  const oldPositions = /* @__PURE__ */ new Map();
@@ -1110,17 +1174,13 @@ function TransitionGroup(options) {
1110
1174
  const currentSet = new Set(elements());
1111
1175
  for (const el of newElements) {
1112
1176
  if (!currentSet.has(el)) {
1113
- if (options.enter) {
1114
- options.enter(el);
1115
- }
1177
+ if (options.enter) runCallback("enter", options.enter, el);
1116
1178
  }
1117
1179
  }
1118
1180
  const newSet = new Set(newElements);
1119
1181
  for (const el of elements()) {
1120
1182
  if (!newSet.has(el)) {
1121
- if (options.leave) {
1122
- options.leave(el);
1123
- }
1183
+ if (options.leave) runCallback("leave", options.leave, el);
1124
1184
  }
1125
1185
  }
1126
1186
  setElements(newElements);
@@ -1130,7 +1190,7 @@ function TransitionGroup(options) {
1130
1190
  if (oldRect && typeof el.getBoundingClientRect === "function") {
1131
1191
  const newRect = el.getBoundingClientRect();
1132
1192
  if (oldRect.left !== newRect.left || oldRect.top !== newRect.top) {
1133
- options.move(el);
1193
+ runCallback("move", options.move, el);
1134
1194
  }
1135
1195
  }
1136
1196
  }
@@ -1181,9 +1241,13 @@ function springSignal(initial, options) {
1181
1241
  let target = initial;
1182
1242
  let rafId = null;
1183
1243
  let lastTime = 0;
1244
+ let disposed = false;
1245
+ const canAnimate = () => typeof requestAnimationFrame === "function";
1184
1246
  const REF_DT_MS = 1e3 / 60;
1185
1247
  const MAX_STEP_RATIO = 4;
1186
1248
  function tick(now) {
1249
+ rafId = null;
1250
+ if (disposed) return;
1187
1251
  if (lastTime === 0) lastTime = now;
1188
1252
  const rawDt = now - lastTime;
1189
1253
  lastTime = now;
@@ -1196,23 +1260,27 @@ function springSignal(initial, options) {
1196
1260
  if (Math.abs(current - target) < precision && Math.abs(velocity) < precision) {
1197
1261
  current = target;
1198
1262
  velocity = 0;
1199
- rafId = null;
1200
1263
  lastTime = 0;
1201
1264
  setValue(current);
1202
1265
  return;
1203
1266
  }
1204
1267
  setValue(current);
1268
+ if (disposed || rafId !== null) return;
1205
1269
  rafId = requestAnimationFrame(tick);
1206
1270
  }
1271
+ function cancelFrame() {
1272
+ if (rafId !== null) {
1273
+ if (typeof cancelAnimationFrame === "function") cancelAnimationFrame(rafId);
1274
+ rafId = null;
1275
+ }
1276
+ }
1207
1277
  function set(newTarget) {
1278
+ if (disposed) return;
1208
1279
  target = newTarget;
1209
- if (prefersReducedMotion()) {
1280
+ if (!canAnimate() || prefersReducedMotion()) {
1210
1281
  current = newTarget;
1211
1282
  velocity = 0;
1212
- if (rafId !== null) {
1213
- cancelAnimationFrame(rafId);
1214
- rafId = null;
1215
- }
1283
+ cancelFrame();
1216
1284
  lastTime = 0;
1217
1285
  setValue(current);
1218
1286
  return;
@@ -1223,10 +1291,8 @@ function springSignal(initial, options) {
1223
1291
  }
1224
1292
  }
1225
1293
  function dispose() {
1226
- if (rafId !== null) {
1227
- cancelAnimationFrame(rafId);
1228
- rafId = null;
1229
- }
1294
+ disposed = true;
1295
+ cancelFrame();
1230
1296
  lastTime = 0;
1231
1297
  }
1232
1298
  return [value, set, dispose];
package/dist/motion.js CHANGED
@@ -20,11 +20,11 @@ import {
20
20
  stagger,
21
21
  transition,
22
22
  viewTransition
23
- } from "./chunk-B3WHI2QA.js";
24
- import "./chunk-QKRPLZ2V.js";
25
- import "./chunk-XZZOBQAY.js";
26
- import "./chunk-UGRX3S57.js";
27
- import "./chunk-2WLZ6757.js";
23
+ } from "./chunk-XRRZKZYX.js";
24
+ import "./chunk-5HZXGZ6T.js";
25
+ import "./chunk-D33YTSX5.js";
26
+ import "./chunk-5Q4R7HCL.js";
27
+ import "./chunk-NYNYSPK7.js";
28
28
  export {
29
29
  TransitionGroup,
30
30
  animate,