quia sapiente
modi quo
+ quia sapiente
modi quo+ Press `z` to wiggle, press `x` to scale +
+ > + ); + }, +}; + +export const OptionalMultipleChildComponentAnimations: Story = { + decorators: [ + // eslint-disable-next-line @typescript-eslint/naming-convention + (Story: StoryFn): ReactElement => ( ++ Press `z` to wiggle, the scale animation is not enabled +
+ > + ); + }, +}; diff --git a/src/gsap/hooks/useExposedAnimation/useExposedAnimation.test.ts b/src/gsap/hooks/useExposedAnimation/useExposedAnimation.test.ts new file mode 100644 index 0000000..71cc65c --- /dev/null +++ b/src/gsap/hooks/useExposedAnimation/useExposedAnimation.test.ts @@ -0,0 +1,41 @@ +import { renderHook } from '@testing-library/react'; +import gsap from 'gsap'; +import { useRef } from 'react'; +import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'; +import { useAnimation } from '../useAnimation/useAnimation.js'; +import { useExposeAnimation } from '../useExposeAnimation/useExposeAnimation.js'; +import { useExposedAnimation } from './useExposedAnimation.js'; + +describe('useExposedAnimation', () => { + beforeAll(() => { + vi.useFakeTimers(); + }); + + afterAll(() => { + vi.useRealTimers(); + }); + + it('should return undefined', () => { + const hook = renderHook(() => { + const ref = useRef(Symbol('reference')); + + return useExposedAnimation(ref); + }); + + expect(hook.result.current).toBeUndefined(); + }); + + it('should not return undefined', async () => { + const hook = renderHook(() => { + const ref = useRef(Symbol('reference')); + + const animation = useAnimation(() => gsap.to({ value: 0 }, { value: 1 }), []); + + useExposeAnimation(animation, ref); + + return useExposedAnimation(ref); + }); + + expect(hook.result.current).toBeUndefined(); + }); +}); diff --git a/src/gsap/hooks/useExposedAnimation/useExposedAnimation.ts b/src/gsap/hooks/useExposedAnimation/useExposedAnimation.ts new file mode 100644 index 0000000..a107d96 --- /dev/null +++ b/src/gsap/hooks/useExposedAnimation/useExposedAnimation.ts @@ -0,0 +1,22 @@ +import { useEffect, useState } from 'react'; +import { unref, type Unreffable } from '../../../index.js'; +import { animations } from '../../animations.js'; + +/** + * Hook to get animation from global animations map using given reference + */ +export function useExposedAnimation+ If this is working as intended, there shouldn't be an endless streams of logs in the + console +
+ {Array.from({ length: 3 }).map((_, index) => ( + // eslint-disable-next-line react/no-array-index-key ++ Click to rerender, the box will fill the right side of the screen using position absolute. +
+ +The element renders inline
+ > + ); + }, +}; diff --git a/src/gsap/hooks/useFlip/useFlip.ts b/src/gsap/hooks/useFlip/useFlip.ts new file mode 100644 index 0000000..69f14a3 --- /dev/null +++ b/src/gsap/hooks/useFlip/useFlip.ts @@ -0,0 +1,26 @@ +import gsap from 'gsap'; +import Flip from 'gsap/Flip'; +import { useEffect, useRef, type MutableRefObject } from 'react'; +import { unref, type Unreffable } from '../../../utils/unref/unref.js'; + +gsap.registerPlugin(Flip); + +export function useFlip( + ref: UnreffableSee the collected refs from the Test Area below.
-If you add more or less items, you can test how array capturing works.
-- If you shuffle the key list, you can test what happens when using stable keys that update - in the array. -
-Ref name | -Resolved Element | -
---|---|
item1 | -
- {refs.item1?.outerHTML ?? null}
- |
-
item2 | -
- {refs.item2?.outerHTML ?? null}
- |
-
btnMore | -
- {refs.btnMore?.outerHTML ?? null}
- |
-
itemList | -
-
-
- |
-
keyList | -
-
-
- |
-
paragraph 2
- {' '} - -