Skip to content

Commit

Permalink
feat(behaviour): adding first controlled component
Browse files Browse the repository at this point in the history
  • Loading branch information
mateoguzmana committed Sep 4, 2022
1 parent bd87440 commit ed14347
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 16 deletions.
8 changes: 6 additions & 2 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactChild, useState } from 'react';
import React, { ReactChild, useRef, useState } from 'react';
import {
SafeAreaView,
StyleSheet,
Expand Down Expand Up @@ -31,6 +31,8 @@ function App() {
const textColor = lightMode ? styles.textLightColor : styles.textDarkColor;
const theme = lightMode ? FiestaThemes.Dark : FiestaThemes.Halloween;

const heartsRef = useRef<any>(null);

if (!font) return null;

return (
Expand Down Expand Up @@ -66,7 +68,7 @@ function App() {
</TouchableOpacity>

<TouchableOpacity
onPress={() => setComponentToRender(<Hearts theme={theme} />)}
onPress={() => heartsRef?.current?.start()}
style={styles.pressable}
>
<Canvas style={styles.canvas}>
Expand Down Expand Up @@ -106,6 +108,8 @@ function App() {
</TouchableOpacity>
</View>

<Hearts theme={theme} autoPlay={false} ref={heartsRef} />

{componentToRender}
</SafeAreaView>
);
Expand Down
9 changes: 5 additions & 4 deletions src/components/Hearts.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import React, { memo } from 'react';
import React, { forwardRef, memo } from 'react';
import Heart from './Heart';
import Popper, { PopperProps } from './Popper';
import Popper, { PopperHandler, PopperProps, PopperRef } from './Popper';

export interface HeartsProps extends Omit<PopperProps, 'renderItem'> {}

function Hearts(props: HeartsProps) {
function Hearts(props: HeartsProps, ref?: PopperRef) {
return (
<Popper
renderItem={({ x, y, colors }, index) => (
<Heart key={index} x={x} y={y} color={colors[index]} />
)}
{...props}
ref={ref}
/>
);
}

export default memo(Hearts);
export default memo(forwardRef<PopperHandler, HeartsProps>(Hearts));
48 changes: 38 additions & 10 deletions src/components/Popper.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import React, { memo, useCallback, useEffect, useMemo } from 'react';
import React, {
forwardRef,
memo,
useCallback,
useEffect,
useImperativeHandle,
useMemo,
ForwardedRef,
} from 'react';
import { StyleSheet } from 'react-native';
import {
Canvas,
Expand Down Expand Up @@ -27,19 +35,33 @@ export interface PopperProps {
renderItemParams: RenderItemParams,
index: number
) => React.ReactElement;
autoPlay?: boolean;
}

function Popper({
spacing = 30,
theme = FiestaThemes.Default,
renderItem,
}: PopperProps) {
export interface PopperHandler {
start(): void;
}

export type PopperRef = ForwardedRef<PopperHandler>;

const Popper = (
{
spacing = 30,
theme = FiestaThemes.Default,
renderItem,
autoPlay = true,
}: PopperProps,
ref: PopperRef
) => {
const optimalNumberOfItems = Math.floor(screenWidth / spacing);
const itemsToRenderArray = [...Array(optimalNumberOfItems)];

const yPositions = shuffleArray(
itemsToRenderArray.map((_, i) => i * spacing)
);

const containerYPosition = useValue(screenHeight);

const colors = useMemo(
() => colorsFromTheme(theme, optimalNumberOfItems),
[theme, optimalNumberOfItems]
Expand All @@ -59,9 +81,15 @@ function Popper({
[containerYPosition]
);

useImperativeHandle(ref, () => ({
start() {
changeItemPosition();
},
}));

useEffect(() => {
changeItemPosition();
}, [changeItemPosition]);
autoPlay && changeItemPosition();
}, [changeItemPosition, autoPlay]);

return (
<Canvas style={styles.canvas}>
Expand All @@ -75,7 +103,7 @@ function Popper({
</Group>
</Canvas>
);
}
};

const styles = StyleSheet.create({
canvas: {
Expand All @@ -88,4 +116,4 @@ const styles = StyleSheet.create({
},
});

export default memo(Popper);
export default memo(forwardRef<PopperHandler, PopperProps>(Popper));

0 comments on commit ed14347

Please sign in to comment.