Skip to content

Commit

Permalink
Use refs in useAnimation and write documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
leroykorterink committed Jan 6, 2023
1 parent 28b380d commit 5dfbca7
Show file tree
Hide file tree
Showing 23 changed files with 837 additions and 118 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/update-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ jobs:

- name: Build Storybook
run: |
npm ci
npm run build
npm run storybook:build
cp -r ./packages/*/.docs/ ./.docs
npm ci;
npm run build;
npm run storybook:build;
cp -r ./packages/*/.docs/ ./.docs;
- name: Create artifact
uses: actions/upload-pages-artifact@v1
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,6 @@ node_modules/

dist/
.docs/

# npmrc contains auth token for private gsap npm registry
.npmrc
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,18 @@ getting started guides.
## 💪 Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would
like to change.
like to change. Please make sure to update tests accordingly.

Please make sure to update tests as appropriate.
Installation requires a greensock license, create a .npmrc file in the root of the repository with
the necessary configuration to install the business package.

```
.npmrc
//npm.greensock.com/:_authToken=<your-auth-token>
@gsap:registry=https://npm.greensock.com
```

## 📝 License

Expand Down
24 changes: 18 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
},
"devDependencies": {
"@mediamonks/prettier-config": "^1.0.1",
"@storybook/react-vite": "^7.0.0-beta.19",
"@storybook/cli": "^7.0.0-beta.19",
"@storybook/react-vite": "^7.0.0-beta.19",
"@storybook/types": "^7.0.0-beta.19",
"husky": "^7.0.4",
"lerna": "^6.1.0",
Expand Down
8 changes: 6 additions & 2 deletions packages/react-animation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"author": "frontend.monks",
"license": "MIT",
"devDependencies": {
"@jest/globals": "^29.3.1",
"@mediamonks/eslint-config": "^2.0.6",
"@mediamonks/eslint-config-react": "^2.1.11",
"@mediamonks/eslint-config-typescript": "^1.0.8",
Expand All @@ -47,8 +48,8 @@
"@storybook/addon-interactions": "^7.0.0-beta.19",
"@storybook/addon-links": "^7.0.0-beta.19",
"@storybook/blocks": "^7.0.0-beta.19",
"@storybook/react-vite": "^7.0.0-beta.19",
"@storybook/cli": "^7.0.0-beta.19",
"@storybook/react-vite": "^7.0.0-beta.19",
"@storybook/types": "^7.0.0-beta.19",
"@swc/cli": "^0.1.57",
"@swc/core": "^1.3.24",
Expand All @@ -63,7 +64,7 @@
},
"peerDependencies": {
"@mediamonks/react-hooks": "^1.0.3",
"gsap": "^3.11.4",
"gsap": "npm:@gsap/business@^3.11.4",
"react": ">=17",
"react-dom": ">=17"
},
Expand All @@ -76,6 +77,9 @@
],
"parserOptions": {
"project": "tsconfig.eslint.json"
},
"rules": {
"@typescript-eslint/no-redundant-type-constituents": "off"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import { Meta } from '@storybook/blocks';
import { Meta, Canvas, Story, Source } from '@storybook/blocks';
import { Example } from './SplitTextWrapper.stories';

<Meta title="components/SplitTextWrapper" />

# SplitTextWrapper

The SplitTextWrapper creates a SplitText instance that can be retrieved using a ref. The SplitText
is available as soon as the just before the components is finished mounting. A new SplitText
instance is created when the children or variables change.

## Example

<Canvas>
<Story name="Example" />
</Canvas>

## Usage

The SplitTextWrapper accepts 1 child, this child is rendered to HTML inside the component to make
sure that compnents from the vDOM are not changed on render making them untargetable in the created
SplitText instance.

<Source name="Example" dark language="tsx" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable react/jsx-no-literals */
import gsap from 'gsap';
import { useCallback, useRef, type ReactElement } from 'react';
import { useAnimation } from '../useAnimation/useAnimation.js';
import { SplitTextWrapper } from './SplitTextWrapper.js';

export default {
title: 'components/SplitTextWrapper',
};

export function Example(): ReactElement {
const splitTextRef = useRef<SplitText>(null);

const animation = useAnimation(() => {
if (!splitTextRef.current) {
return;
}

return gsap.from(splitTextRef.current.words, {
y: 20,
x: 4,
opacity: 0,
duration: 0.2,
stagger: 0.05,
});
}, []);

const onReplay = useCallback(() => {
animation.current?.play(0);
}, [animation]);

return (
<>
<h1>
<SplitTextWrapper ref={splitTextRef}>
<>
Lorem ipsum dolor sit <i>amet consectetur</i>
<br /> adipisicing elit. <b>Tenetur perspiciatis</b> eius ea, ratione,
<br /> illo molestias, <code>quia sapiente</code> modi quo
<br /> molestiae temporibus.
</>
</SplitTextWrapper>
</h1>

<button onClick={onReplay} type="button">
Replay
</button>
</>
);
}
38 changes: 38 additions & 0 deletions packages/react-animation/src/animations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
class AnimationsMap extends Map {
private readonly callbacks = new Set<() => void>();

private updateQueued = false;

public set(key: unknown, value: gsap.core.Animation): this {
const result = super.set(key, value);

if (this.updateQueued) {
return result;
}

this.updateQueued = true;

queueMicrotask(() => {
for (const callback of this.callbacks) {
callback();
}

this.updateQueued = false;
});

return result;
}

public listen(callback: () => void): () => void {
this.callbacks.add(callback);

return () => {
this.callbacks.delete(callback);
};
}
}

/**
* Global map of animations that can be accessed by reference
*/
export const animations = new AnimationsMap();
1 change: 0 additions & 1 deletion packages/react-animation/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './SplitTextWrapper/SplitTextWrapper.js';
export * from './useAnimation/useAnimation.js';
export * from './useExposeAnimation/useExposeAnimation.js';
export * from './useScrollAnimation/useScrollAnimation.js';
Loading

0 comments on commit 5dfbca7

Please sign in to comment.