| void | typeof SkipStep | typeof DoStep,
@@ -41,6 +45,8 @@ export default (
setStep(STEP_PREPARE, true);
}
+ const STEP_QUEUE = prepareOnly ? SIMPLE_STEP_QUEUE : FULL_STEP_QUEUE;
+
useIsomorphicLayoutEffect(() => {
if (step !== STEP_NONE && step !== STEP_ACTIVATED) {
const index = STEP_QUEUE.indexOf(step);
@@ -51,7 +57,7 @@ export default (
if (result === SkipStep) {
// Skip when no needed
setStep(nextStep, true);
- } else {
+ } else if (nextStep) {
// Do as frame for step update
nextFrame(info => {
function doNext() {
diff --git a/src/interface.ts b/src/interface.ts
index 9c333d8..c513565 100644
--- a/src/interface.ts
+++ b/src/interface.ts
@@ -14,13 +14,20 @@ export const STEP_PREPARE = 'prepare' as const;
export const STEP_START = 'start' as const;
export const STEP_ACTIVE = 'active' as const;
export const STEP_ACTIVATED = 'end' as const;
+/**
+ * Used for disabled motion case.
+ * Prepare stage will still work but start & active will be skipped.
+ */
+export const STEP_PREPARED = 'prepared' as const;
export type StepStatus =
| typeof STEP_NONE
| typeof STEP_PREPARE
| typeof STEP_START
| typeof STEP_ACTIVE
- | typeof STEP_ACTIVATED;
+ | typeof STEP_ACTIVATED
+ // Skip motion only
+ | typeof STEP_PREPARED;
export type MotionEvent = (TransitionEvent | AnimationEvent) & {
deadline?: boolean;
diff --git a/tests/CSSMotion.spec.tsx b/tests/CSSMotion.spec.tsx
index d89266d..7886042 100644
--- a/tests/CSSMotion.spec.tsx
+++ b/tests/CSSMotion.spec.tsx
@@ -2,14 +2,14 @@
react/no-render-return-value, max-classes-per-file,
react/prefer-stateless-function, react/no-multi-comp
*/
+import { fireEvent, render } from '@testing-library/react';
+import classNames from 'classnames';
import React from 'react';
+import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
-import classNames from 'classnames';
-import { render, fireEvent } from '@testing-library/react';
import type { CSSMotionProps } from '../src';
import { Provider } from '../src';
import RefCSSMotion, { genCSSMotion } from '../src/CSSMotion';
-import ReactDOM from 'react-dom';
describe('CSSMotion', () => {
const CSSMotion = genCSSMotion({
@@ -482,6 +482,9 @@ describe('CSSMotion', () => {
});
it('MotionProvider to disable motion', () => {
+ const onAppearPrepare = jest.fn();
+ const onAppearStart = jest.fn();
+
const Demo = ({
motion,
visible,
@@ -495,6 +498,9 @@ describe('CSSMotion', () => {
visible={visible}
removeOnLeave={false}
leavedClassName="hidden"
+ motionAppear
+ onAppearPrepare={onAppearPrepare}
+ onAppearStart={onAppearStart}
>
{({ style, className }) => (
{
const { container, rerender } = render();
expect(container.querySelector('.motion-box')).toBeTruthy();
+ act(() => {
+ jest.runAllTimers();
+ });
+
+ expect(onAppearPrepare).toHaveBeenCalled();
+ expect(onAppearStart).not.toHaveBeenCalled();
+
// hide immediately since motion is disabled
rerender();
expect(container.querySelector('.hidden')).toBeTruthy();