Skip to content
153 changes: 94 additions & 59 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,97 +1,132 @@
import { View, StyleSheet, Pressable, Text } from 'react-native';
import {
StyleSheet,
Pressable,
Text,
View,
SafeAreaView,
Platform,
} from 'react-native';
import { TipKitInlineView, TipKitPopOverView } from 'react-native-tipkit';
import CloseIcon from './CloseIcon';
import DonutIcon from './DonutIcon';
import Animated, { LinearTransition } from 'react-native-reanimated';
import { useCallback, useRef } from 'react';

export default function App() {
const onActionButtonPress = () => {
const topPlusButtonRef = useRef(null);
const bottomPlusButtonRef = useRef(null);

const onActionButtonPress = useCallback(() => {
console.log('Action button pressed');
};
}, []);

return (
<View style={styles.container}>
<Text style={styles.title}>TipKit Example</Text>
<TipKitInlineView
visible={true}
tipContainer={styles.inline}
title="Set favorites"
description="Tap and hold a color to add it to your favorites"
/>

<TipKitPopOverView
// Tip Props
title="Add New Color"
description="Tap here to add a new color to the list"
tipContainer={styles.tipContainer}
leftIcon={<CloseIcon height={40} width={40} />}
actionButtonOnPress={onActionButtonPress}
actionButtonTitle="Learn more"
// Popover Button Props
popoverButtonProps={{ title: 'Show Popover Top' }}
popoverButtonArrowDirection="top"
/>
<>
<SafeAreaView style={styles.safeAreaContainer}>
<View style={styles.titleContainer}>
<Animated.Text layout={LinearTransition} style={styles.title}>
TipKit Example
</Animated.Text>
<Pressable
ref={topPlusButtonRef}
style={styles.topButton}
onPress={() => console.log('Cool feature!')}
>
<Text style={styles.buttonText}>+</Text>
</Pressable>
</View>
<Animated.View layout={LinearTransition} style={styles.container}>
<TipKitInlineView
title="Set favorites"
description="Tap and hold a color to add it to your favorites"
tipContainerStyle={styles.inline}
/>

<View style={styles.buttonContainer}>
<Pressable
ref={bottomPlusButtonRef}
style={styles.bottomButton}
onPress={() => console.log('Cool feature!')}
>
<Text style={styles.buttonText}>+hello world+</Text>
</Pressable>
</View>
</Animated.View>
</SafeAreaView>
<TipKitPopOverView
// Tip Props
targetRef={topPlusButtonRef}
title="Add New Color"
description="Tap here to add a new color to the list"
tipContainer={styles.tipContainer}
leftIcon={<CloseIcon height={40} width={40} />}
tipContainerStyle={styles.tipContainer}
icon={<DonutIcon height={40} width={40} />}
actionButtonOnPress={onActionButtonPress}
// Popover Button Props
popoverButtonProps={{ title: 'Show Popover Bottom' }}
popoverButtonArrowDirection="bottom"
/>

{/* TODO: Fix the positioning of the arrow when the button is smaller than 100% */}
<TipKitPopOverView
// Tip Props
targetRef={bottomPlusButtonRef}
title="Add New Color"
description="Tap here to add a new color to the list"
tipContainer={styles.tipContainer}
leftIcon={<CloseIcon height={40} width={40} />}
tipContainerStyle={styles.tipContainer}
icon={<DonutIcon height={40} width={40} fill={'#66b2b2'} />}
actionButtonOnPress={onActionButtonPress}
popoverButtonArrowDirection="bottom-end"
// Popover Button Props
popoverButton={
<Pressable style={styles.customPopoverButton} onPress={() => {}}>
<Text style={styles.customPopoverButtonText}>
Custom Popover button
</Text>
</Pressable>
}
actionButtonTitle="Learn more"
/>
</View>
</>
);
}

const styles = StyleSheet.create({
safeAreaContainer: {
flex: 1,
marginTop: Platform.select({ ios: 0, android: 24 }),
},
container: {
flex: 1,
gap: 12,
justifyContent: 'center',
paddingHorizontal: 12,
paddingTop: 120,
},
titleContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
paddingHorizontal: 24,
paddingTop: 16,
},
inline: {
backgroundColor: '#d7eef3',
},
tipContainer: {
backgroundColor: '#f1f4f2',
},
customPopoverButton: {
width: '60%',
backgroundColor: '#66D210',
padding: 12,
borderRadius: 8,
},
customPopoverButtonText: {
color: 'white',
textAlign: 'center',
fontWeight: 'bold',
},
title: {
fontSize: 24,
fontSize: 32,
fontWeight: 'bold',
textAlign: 'center',
color: '#333',
},
topButton: {
backgroundColor: '#66D210',
borderRadius: 100,
width: 50,
height: 50,
alignItems: 'center',
justifyContent: 'center',
},
bottomButton: {
backgroundColor: '#66D210',
borderRadius: 100,
height: 50,
width: 200,
alignItems: 'center',
justifyContent: 'center',
left: 50,
},
buttonText: {
color: '#333',
},
buttonContainer: {
width: '100%',
alignSelf: 'center',
position: 'absolute',
bottom: 24,
},
});
14 changes: 0 additions & 14 deletions example/src/CloseIcon.tsx

This file was deleted.

18 changes: 18 additions & 0 deletions example/src/DonutIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import Svg, { Path, type SvgProps } from 'react-native-svg';

type DonutIconProps = SvgProps;

const DonutIcon: React.FC<DonutIconProps> = ({ ...props }) => {
return (
<Svg viewBox="0 0 32 32" width="32px" height="32px" {...props}>
<Path d="M18.85,6.41c.15,.21,.38,.33,.62,.33,.14,0,.29-.04,.42-.13,.34-.23,.43-.7,.2-1.04l-1.08-1.59c-.23-.34-.7-.43-1.04-.2-.34,.23-.43,.7-.2,1.04l1.08,1.59Z" />
<Path d="M7.17,11.75c.09,.03,.18,.05,.27,.05,.3,0,.59-.18,.7-.48l.73-1.91c.15-.39-.04-.82-.43-.97-.38-.15-.82,.04-.97,.43l-.73,1.91c-.15,.39,.04,.82,.43,.97Z" />
<Path d="M24.68,18.13c-.41-.04-.78,.25-.83,.66l-.2,1.81c-.04,.41,.25,.78,.67,.83,.03,0,.05,0,.08,0,.38,0,.7-.28,.75-.67l.2-1.81c.04-.41-.25-.78-.67-.83Z" />
<Path d="M12.35,24.31l-1.66,.39c-.4,.09-.65,.5-.56,.9,.08,.35,.39,.58,.73,.58,.06,0,.12,0,.17-.02l1.66-.39c.4-.09,.65-.5,.56-.9-.1-.4-.51-.65-.9-.56Z" />
<Path d="M30.73,16.27c0-.09,.01-.18,.01-.27C30.75,7.87,24.13,1.25,16,1.25S1.72,7.43,1.29,15.19c-.04,.09-.07,.19-.07,.3,0,.08,.02,.16,.04,.24,0,.09-.01,.18-.01,.27,0,8.13,6.62,14.75,14.75,14.75s14.28-6.18,14.71-13.94c.04-.09,.07-.19,.07-.3,0-.08-.02-.16-.04-.24ZM16,2.75c6.94,0,12.64,5.36,13.19,12.16-.18-.09-.37-.16-.62-.16-.74,0-1.12,.53-1.33,.81-.03,.04-.07,.1-.1,.14-.03-.04-.07-.1-.1-.14-.2-.28-.58-.81-1.32-.81s-1.12,.53-1.32,.81c-.03,.04-.07,.1-.1,.14-.03-.04-.07-.1-.1-.14-.13-.18-.34-.45-.66-.63-.52-3.7-3.69-6.55-7.53-6.55s-7.04,2.88-7.54,6.6c-.2-.13-.44-.24-.76-.24-.74,0-1.12,.53-1.33,.81-.03,.04-.07,.1-.1,.14-.03-.04-.07-.1-.1-.14-.2-.28-.58-.81-1.32-.81s-1.12,.53-1.32,.81c-.03,.04-.07,.1-.1,.14-.03-.04-.07-.1-.1-.14-.11-.15-.28-.38-.52-.55C3.31,8.17,9.03,2.75,16,2.75Zm6.12,13.25c0,3.37-2.74,6.12-6.12,6.12-3.19,0-5.82-2.46-6.09-5.59,0,0,0,0,0-.01,0,0,0-.02,0-.03-.01-.16-.02-.32-.02-.48,0-3.37,2.74-6.11,6.11-6.11,3.19,0,5.82,2.46,6.09,5.59,0,0,0,.01,0,.02,0,.01,0,.02,0,.03,.01,.16,.02,.32,.02,.48Zm-6.12,13.25c-6.94,0-12.64-5.36-13.19-12.16,.17,.09,.37,.16,.62,.16,.74,0,1.12-.53,1.32-.82,.03-.04,.07-.09,.1-.14,.03,.04,.07,.1,.1,.14,.2,.28,.58,.81,1.32,.81s1.12-.53,1.32-.81c.03-.04,.07-.1,.1-.14,.03,.04,.07,.1,.1,.14,.13,.18,.34,.45,.66,.63,.52,3.7,3.69,6.55,7.53,6.55s7.04-2.88,7.54-6.6c.2,.13,.44,.24,.75,.24,.74,0,1.12-.53,1.32-.82,.03-.04,.07-.09,.1-.14,.03,.04,.07,.1,.1,.14,.2,.28,.58,.81,1.32,.81s1.12-.53,1.33-.81c.03-.04,.07-.1,.1-.14,.03,.04,.07,.1,.1,.14,.11,.15,.28,.38,.52,.55-.51,6.85-6.23,12.26-13.2,12.26Z" />
</Svg>
);
};

export default DonutIcon;
24 changes: 22 additions & 2 deletions src/TipKitInlineView/TipKitInlineView.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import React from 'react';
import BaseTipKit, { type BaseTipKitProps } from '../components/BaseTipKit';
import { StretchInY, StretchOutY } from 'react-native-reanimated';

interface TipKitInlineViewProps extends BaseTipKitProps {}
interface TipKitInlineViewProps
extends Omit<
BaseTipKitProps,
'type' | 'visible' | 'onDismiss' | 'buttonPosition'
> {}

const TipKitInlineView: React.FC<TipKitInlineViewProps> = ({ ...rest }) => {
return <BaseTipKit popoverButtonArrowDirection={undefined} {...rest} />;
const [visible, setVisible] = React.useState(true);

const onDismiss = () => {
setVisible(false);
};

return (
<BaseTipKit
type="inline"
visible={visible}
onDismiss={onDismiss}
enteringAnimation={StretchInY}
exitingAnimation={StretchOutY}
{...rest}
/>
);
};

export default TipKitInlineView;
Loading
Loading