Skip to content

Commit 6b60a7f

Browse files
author
Jan Fischer
committed
feat: bump to 3.1.0 and optimize Timeline target handling
1 parent cf6f257 commit 6b60a7f

File tree

9 files changed

+266
-42
lines changed

9 files changed

+266
-42
lines changed

packages/docz/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"gsap": "^3.2.6",
2424
"react": "^16.8.6",
2525
"react-dom": "^16.8.6",
26-
"react-gsap": "3.0.0"
26+
"react-gsap": "3.1.0"
2727
},
2828
"devDependencies": {
2929
"@types/react": "^16.8.23",

packages/docz/src/components/Timeline.mdx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ In this way these component can be better reused and the refs not only work in a
8787
You can also pass an array ref like seen with div2. In this way you can use the `stagger` prop.
8888

8989
```javascript
90-
const TargetWithNames = forwardRef((props, ref: any) => {
90+
const TargetWithNames = forwardRef((props, ref) => {
9191
const div1 = useRef(null);
9292
const div2 = useRef([]);
9393
const div3 = useRef(null);
@@ -112,6 +112,26 @@ const TargetWithNames = forwardRef((props, ref: any) => {
112112

113113
```
114114

115+
If you want to combine multiple of those named components, you can do it like this:
116+
117+
```javascript
118+
const TargetWithNamesCombined = forwardRef((props, ref) => {
119+
const target1 = useRef({});
120+
const target2 = useRef({});
121+
useImperativeHandle(ref, () => ({
122+
...target1.current,
123+
...target2.current,
124+
}));
125+
return (
126+
<>
127+
<TargetWithNames1 ref={target1} />
128+
<TargetWithNames2 ref={target2} />
129+
</>
130+
);
131+
});
132+
133+
```
134+
115135
For version < 3:
116136

117137
If you need to target individual elements you can use a special forwardRef function.

packages/next/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"next": "^9.5.1",
1313
"react": "^16.12.0",
1414
"react-dom": "^16.12.0",
15-
"react-gsap": "3.0.0"
15+
"react-gsap": "3.1.0"
1616
},
1717
"devDependencies": {
1818
"@types/node": "^14.14.22",

packages/playground/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"gsap": "^3.2.6",
1818
"react": "^16.13.1",
1919
"react-dom": "^16.13.1",
20-
"react-gsap": "3.0.0",
20+
"react-gsap": "3.1.0",
2121
"react-router-dom": "^5.1.2",
2222
"react-scripts": "4.0.1",
2323
"react-transition-group": "^4.3.0",

packages/playground/src/examples/Timeline.tsx

Lines changed: 138 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ import { Tween, Timeline, SplitWords, SplitChars, Controls, PlayState } from 're
1414

1515
const TimelineStyled = styled.div``;
1616

17+
const StyledTarget1 = styled.div`
18+
height: 200px;
19+
background-color: #accef7;
20+
`;
21+
22+
const StyledTarget2 = styled.div`
23+
height: 50px;
24+
background-color: #ff4757;
25+
padding: 50px;
26+
`;
27+
28+
const Inline = styled.div`
29+
display: inline-block;
30+
font-size: 40px;
31+
`;
32+
1733
const TimelinePlayState = () => {
1834
const [playing, setPlaying] = React.useState(false);
1935
const [progress, setProgress] = React.useState(0);
@@ -147,6 +163,44 @@ const TargetWithNames = forwardRef((props, ref: any) => {
147163
);
148164
});
149165

166+
const TargetWithNames2 = forwardRef((props, ref: any) => {
167+
const div4 = useRef(null);
168+
const div5 = useRef<MutableRefObject<any>[]>([]);
169+
const div6 = useRef(null);
170+
useImperativeHandle(ref, () => ({
171+
div4,
172+
div5,
173+
div6,
174+
}));
175+
return (
176+
<div>
177+
<div ref={div4}>first</div>
178+
<SplitChars
179+
ref={(charRef: MutableRefObject<any>) => div5.current.push(charRef)}
180+
wrapper={<span style={{ display: 'inline-block' }} />}
181+
>
182+
second
183+
</SplitChars>
184+
<div ref={div6}>third</div>
185+
</div>
186+
);
187+
});
188+
189+
const TargetWithNamesCombined = forwardRef((props, ref: any) => {
190+
const target1 = useRef({});
191+
const target2 = useRef({});
192+
useImperativeHandle(ref, () => ({
193+
...target1.current,
194+
...target2.current,
195+
}));
196+
return (
197+
<>
198+
<TargetWithNames ref={target1} />
199+
<TargetWithNames2 ref={target2} />
200+
</>
201+
);
202+
});
203+
150204
const TimelineTargets = () => {
151205
return (
152206
<Timeline target={<TargetWithNames />}>
@@ -159,6 +213,16 @@ const TimelineTargets = () => {
159213

160214
//export default TimelineTargets;
161215

216+
const ForwardRefComponent = forwardRef(({ children }, ref: any) => {
217+
return (
218+
<div>
219+
<StyledTarget1 ref={ref}>
220+
<span>{children}</span>
221+
</StyledTarget1>
222+
</div>
223+
);
224+
});
225+
162226
const Component = forwardRef(({ children }, ref?) => {
163227
const div1 = useRef(null);
164228
const div2 = useRef(null);
@@ -213,34 +277,98 @@ const Out = () => {
213277
const divRef1 = useCallback(ref => {
214278
if (ref !== null) {
215279
// Ref never updates
216-
console.log(ref);
280+
// console.log(ref);
217281
}
218282
}, []);
219283

220284
const divRef2 = useRef(null);
221285

222286
useEffect(() => {
223287
// Ref never updates
224-
console.log(divRef2.current);
288+
// console.log(divRef2.current);
225289
}, []);
226290

227291
return (
228292
<div className="App">
229-
<Timeline target={<TargetWithNames />}>
230-
<Tween from={{ x: -100 }} to={{ x: 100 }}>
231-
<div ref={divRef1} style={{ width: 200, height: 200, background: 'rebeccapurple' }} />
232-
</Tween>
293+
<Timeline
294+
// target={
295+
// <>
296+
// <StyledTarget1>
297+
// <StyledTarget2 />
298+
// </StyledTarget1>
299+
// <StyledTarget1>
300+
// <StyledTarget2 />
301+
// </StyledTarget1>
302+
// </>
303+
// }
304+
// target={<div style={{ height: '300px', backgroundColor: '#ccc' }} />}
305+
// target={<TargetWithNames />}
306+
target={
307+
<>
308+
<TargetWithNames />
309+
<TargetWithNames2 />
310+
</>
311+
}
312+
// target={<TargetWithNamesCombined />}
313+
// target={
314+
// <>
315+
// <TargetWithNames />
316+
// <ForwardRefComponent>ForwardRefComponent 1</ForwardRefComponent>
317+
// <ForwardRefComponent>ForwardRefComponent 2</ForwardRefComponent>
318+
// </>
319+
// }
320+
>
321+
{/*<Tween from={{ x: -100 }} to={{ x: 100 }}>*/}
322+
{/* <div ref={divRef1} style={{ width: 200, height: 200, background: 'rebeccapurple' }} />*/}
323+
{/*</Tween>*/}
233324

234-
<Tween from={{ x: -100 }} to={{ x: 100 }}>
235-
<div ref={divRef2} style={{ width: 200, height: 200, background: 'fuchsia' }} />
236-
</Tween>
325+
{/*<Tween from={{ x: -100 }} to={{ x: 100 }}>*/}
326+
{/* <div ref={divRef2} style={{ width: 200, height: 200, background: 'fuchsia' }} />*/}
327+
{/*</Tween>*/}
237328

238329
<Tween to={{ x: '200px' }} target="div3" position="0" />
239330
<Tween to={{ x: '200px' }} target="div1" position="0.5" />
240331
<Tween to={{ x: '200px' }} target="div2" position="1" stagger={0.1} />
332+
333+
<Tween to={{ x: '200px' }} target="div6" position="2" />
334+
<Tween to={{ x: '200px' }} target="div4" position="2.5" />
335+
<Tween to={{ x: '200px' }} target="div5" position="3" stagger={0.1} />
336+
337+
{/*<Tween to={{ x: '200px' }} target={3} />*/}
338+
{/*<Tween to={{ x: '200px' }} target={4} />*/}
241339
</Timeline>
242340
</div>
243341
);
244342
};
245343

246-
export default Out;
344+
//export default Out;
345+
346+
const Test = () => {
347+
// the array gets filled up with every new render!
348+
// can SplitWords outputs it's refs as array, so that we don't need to push into?
349+
const ref = useRef<MutableRefObject<any>[]>([]);
350+
351+
useEffect(() => {
352+
console.log(ref);
353+
}, []);
354+
355+
return (
356+
<Controls playState={PlayState.stop}>
357+
<Timeline
358+
target={
359+
<Fragment>
360+
<SplitWords ref={(charRef: any) => ref.current.push(charRef)} wrapper={<Inline />}>
361+
This text gets splitted by words.
362+
</SplitWords>
363+
</Fragment>
364+
}
365+
>
366+
<Tween to={{ y: '-20px' }} position={0.5} duration={0.1} target={1} />
367+
<Tween to={{ y: '-20px' }} position="+=0.5" duration={0.1} target={3} />
368+
<Tween to={{ y: '-20px' }} position="+=0.5" duration={0.1} target={5} />
369+
</Timeline>
370+
</Controls>
371+
);
372+
};
373+
374+
export default Test;

packages/react-gsap/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-gsap",
3-
"version": "3.0.0",
3+
"version": "3.1.0",
44
"description": "React components for GSAP",
55
"author": "bitworking",
66
"license": "MIT",

packages/react-gsap/src/Timeline.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@ import React, { Fragment, ReactNode, ReactElement } from 'react';
22
import { gsap } from 'gsap';
33
import { isForwardRef, isFragment } from 'react-is';
44
import { PlayState } from './types';
5-
import {
6-
getTweenFunction,
7-
setPlayState,
8-
nullishCoalescing,
9-
getRefProp,
10-
getTargetRefProp,
11-
} from './helper';
5+
import { getTweenFunction, setPlayState, nullishCoalescing, getTargetRefProp } from './helper';
126
import Provider, { Context } from './Provider';
137
import { TweenProps } from './Tween';
148

@@ -205,7 +199,7 @@ class Timeline extends Provider<TimelineProps> {
205199

206200
cloneElement(child: any) {
207201
// @ts-ignore
208-
return React.cloneElement(child, getRefProp(child, this.addTarget));
202+
return React.cloneElement(child, getTargetRefProp(child, this.setTarget, this.addTarget));
209203
}
210204

211205
renderTarget(target?: Target): ReactNode {
@@ -215,8 +209,7 @@ class Timeline extends Provider<TimelineProps> {
215209

216210
// if is forwardRef clone and pass targets as ref
217211
if (isForwardRef(target)) {
218-
// @ts-ignore
219-
return React.cloneElement(target, getTargetRefProp(target, this.setTarget));
212+
return this.cloneElement(target);
220213
}
221214

222215
// else iterate the first level of children and set targets

0 commit comments

Comments
 (0)