(null);
- const rotateAnimationRef = useAnimationRef();
- const rotateAnimation = useExposedAnimation(rotateAnimationRef);
+ const rotateAnimationReference = useStaticValue(() => Symbol('rotateAnimation'));
+ const scaleAnimationReference = useStaticValue(() => Symbol('scaleAnimation'));
- const scaleAnimationRef = useAnimationRef();
- const scaleAnimation = useExposedAnimation(scaleAnimationRef);
+ const rotateAnimation = useExposedAnimation(rotateAnimationReference);
+ const scaleAnimation = useExposedAnimation(scaleAnimationReference);
useEventListener(globalThis.document, 'keydown', (event) => {
if (event instanceof KeyboardEvent) {
@@ -105,10 +145,56 @@ export const MultipleChildComponentAnimations = {
<>
- Press `z` to rotate, press `x` to scale
+
+ Press `z` to wiggle, press `x` to scale
+
+ >
+ );
+ },
+};
+
+export const OptionalMultipleChildComponentAnimations: Story = {
+ decorators: [
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ (Story: StoryFn): ReactElement => (
+
+
+
+ ),
+ ],
+ render(): ReactElement {
+ const ref = useRef(null);
+ const rotateAnimationReference = useStaticValue(() => Symbol('rotateAnimation'));
+ const rotateAnimation = useExposedAnimation(rotateAnimationReference);
+
+ useEventListener(globalThis.document, 'keydown', (event) => {
+ if (event instanceof KeyboardEvent) {
+ switch (event.key) {
+ case 'z': {
+ rotateAnimation?.play(0);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+ });
+
+ const animation = useExposedAnimation(ref);
+
+ // eslint-disable-next-line no-console
+ console.log('useExposedAnimation', animation);
+
+ return (
+ <>
+
+
+ Press `z` to wiggle, the scale animation is not enabled
+
>
);
},
diff --git a/packages/react-animation/src/useExposedAnimation/useExposedAnimation.ts b/packages/react-animation/src/useExposedAnimation/useExposedAnimation.ts
index ac7e16c..69e853f 100644
--- a/packages/react-animation/src/useExposedAnimation/useExposedAnimation.ts
+++ b/packages/react-animation/src/useExposedAnimation/useExposedAnimation.ts
@@ -1,20 +1,21 @@
-import { useEffect, useState, type RefObject } from 'react';
+import { unref, type Unreffable } from '@mediamonks/react-hooks';
+import { useEffect, useState } from 'react';
import { animations } from '../animations.js';
/**
* Hook to get animation from global animations map using given reference
*/
export function useExposedAnimation(
- ref: RefObject,
+ target: Unreffable,
): T | undefined {
const [animation, setAnimation] = useState();
useEffect(
() =>
animations.listen(() => {
- setAnimation(animations.get(ref.current));
+ setAnimation(animations.get(unref(target)));
}),
- [ref],
+ [target],
);
return animation;
diff --git a/packages/react-animation/src/useExposedAnimations/useExposedAnimations.ts b/packages/react-animation/src/useExposedAnimations/useExposedAnimations.ts
index 66f6829..41763eb 100644
--- a/packages/react-animation/src/useExposedAnimations/useExposedAnimations.ts
+++ b/packages/react-animation/src/useExposedAnimations/useExposedAnimations.ts
@@ -1,11 +1,12 @@
-import { useEffect, useState, type RefObject } from 'react';
+import { unref, type Unreffable } from '@mediamonks/react-hooks';
+import { useEffect, useState } from 'react';
import { animations } from '../animations.js';
/**
* Hook to get animation from global animations map using given reference
*/
export function useExposedAnimations(
- arrayRef: RefObject>,
+ target: Unreffable>,
): ReadonlyArray {
const [exposedAnimations, setExposedAnimations] = useState>(
[],
@@ -14,8 +15,10 @@ export function useExposedAnimations(
useEffect(
() =>
animations.listen(() => {
- if (arrayRef.current) {
- const newAnimations = arrayRef.current.map((ref) => animations.get(ref));
+ const array = unref(target);
+
+ if (array) {
+ const newAnimations = array.map((ref) => animations.get(ref));
// this should only be done when the refs have been updated, otherwise we're returning
// a new array ref with the same values, which will cause a re-render
setExposedAnimations((currentAnimations) =>
@@ -23,7 +26,8 @@ export function useExposedAnimations(
);
}
}),
- [arrayRef],
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [target],
);
return exposedAnimations;