Skip to content

Commit d7ffa41

Browse files
authored
Merge pull request #1 from travelpassgroup/AXO-1616
Creation of the base component and basic operations
2 parents 9f81e1e + b817002 commit d7ffa41

12 files changed

Lines changed: 538 additions & 18 deletions

File tree

example/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
"react": "18.3.1",
1616
"react-dom": "18.3.1",
1717
"react-native": "0.76.6",
18+
"react-native-reanimated": "^3.16.7",
19+
"react-native-svg": "^15.11.1",
1820
"react-native-web": "~0.19.13"
1921
},
2022
"devDependencies": {

example/src/App.tsx

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,97 @@
1-
import { Text, View, StyleSheet } from 'react-native';
2-
import { multiply } from 'react-native-tipkit';
3-
4-
const result = multiply({ n1: 3, n2: 7 });
1+
import { View, StyleSheet, Pressable, Text } from 'react-native';
2+
import { TipKitInlineView, TipKitPopOverView } from 'react-native-tipkit';
3+
import CloseIcon from './CloseIcon';
54

65
export default function App() {
6+
const onActionButtonPress = () => {
7+
console.log('Action button pressed');
8+
};
9+
710
return (
811
<View style={styles.container}>
9-
<Text>Result: {result}</Text>
12+
<Text style={styles.title}>TipKit Example</Text>
13+
<TipKitInlineView
14+
visible={true}
15+
tipContainer={styles.inline}
16+
title="Set favorites"
17+
description="Tap and hold a color to add it to your favorites"
18+
/>
19+
20+
<TipKitPopOverView
21+
// Tip Props
22+
title="Add New Color"
23+
description="Tap here to add a new color to the list"
24+
tipContainer={styles.tipContainer}
25+
leftIcon={<CloseIcon height={40} width={40} />}
26+
actionButtonOnPress={onActionButtonPress}
27+
actionButtonTitle="Learn more"
28+
// Popover Button Props
29+
popoverButtonProps={{ title: 'Show Popover Top' }}
30+
popoverButtonArrowDirection="top"
31+
/>
32+
33+
<TipKitPopOverView
34+
// Tip Props
35+
title="Add New Color"
36+
description="Tap here to add a new color to the list"
37+
tipContainer={styles.tipContainer}
38+
leftIcon={<CloseIcon height={40} width={40} />}
39+
actionButtonOnPress={onActionButtonPress}
40+
// Popover Button Props
41+
popoverButtonProps={{ title: 'Show Popover Bottom' }}
42+
popoverButtonArrowDirection="bottom"
43+
/>
44+
45+
{/* TODO: Fix the positioning of the arrow when the button is smaller than 100% */}
46+
<TipKitPopOverView
47+
// Tip Props
48+
title="Add New Color"
49+
description="Tap here to add a new color to the list"
50+
tipContainer={styles.tipContainer}
51+
leftIcon={<CloseIcon height={40} width={40} />}
52+
actionButtonOnPress={onActionButtonPress}
53+
popoverButtonArrowDirection="bottom-end"
54+
// Popover Button Props
55+
popoverButton={
56+
<Pressable style={styles.customPopoverButton} onPress={() => {}}>
57+
<Text style={styles.customPopoverButtonText}>
58+
Custom Popover button
59+
</Text>
60+
</Pressable>
61+
}
62+
/>
1063
</View>
1164
);
1265
}
1366

1467
const styles = StyleSheet.create({
1568
container: {
1669
flex: 1,
17-
alignItems: 'center',
70+
gap: 12,
1871
justifyContent: 'center',
72+
paddingHorizontal: 12,
73+
},
74+
inline: {
75+
backgroundColor: '#d7eef3',
76+
},
77+
tipContainer: {
78+
backgroundColor: '#f1f4f2',
79+
},
80+
customPopoverButton: {
81+
width: '60%',
82+
backgroundColor: '#66D210',
83+
padding: 12,
84+
borderRadius: 8,
85+
},
86+
customPopoverButtonText: {
87+
color: 'white',
88+
textAlign: 'center',
89+
fontWeight: 'bold',
90+
},
91+
title: {
92+
fontSize: 24,
93+
fontWeight: 'bold',
94+
textAlign: 'center',
95+
color: '#333',
1996
},
2097
});

example/src/CloseIcon.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import Svg, { Path, type SvgProps } from 'react-native-svg';
3+
4+
type CloseIconProps = SvgProps;
5+
6+
const CloseIcon: React.FC<CloseIconProps> = ({ ...props }) => {
7+
return (
8+
<Svg viewBox="0 0 24 24" width="18px" height="18px" {...props}>
9+
<Path d="M4.99 3.99a1 1 0 00-.697 1.717L10.586 12l-6.293 6.293a1 1 0 101.414 1.414L12 13.414l6.293 6.293a1 1 0 101.414-1.414L13.414 12l6.293-6.293a1 1 0 00-.727-1.717 1 1 0 00-.687.303L12 10.586 5.707 4.293a1 1 0 00-.717-.303z" />
10+
</Svg>
11+
);
12+
};
13+
14+
export default CloseIcon;

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
"react": "18.3.1",
8181
"react-native": "0.76.6",
8282
"react-native-builder-bob": "^0.32.0",
83+
"react-native-reanimated": "^3.16.7",
84+
"react-native-svg": "^15.11.1",
8385
"release-it": "^17.10.0",
8486
"typescript": "^5.2.2"
8587
},
@@ -88,7 +90,9 @@
8890
},
8991
"peerDependencies": {
9092
"react": "*",
91-
"react-native": "*"
93+
"react-native": "*",
94+
"react-native-reanimated": "*",
95+
"react-native-svg": "*"
9296
},
9397
"workspaces": [
9498
"example"
@@ -196,8 +200,5 @@
196200
"languages": "js",
197201
"type": "library",
198202
"version": "0.45.5"
199-
},
200-
"dependencies": {
201-
"react-native-reanimated": "^3.16.7"
202203
}
203204
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
import BaseTipKit, { type BaseTipKitProps } from '../components/BaseTipKit';
3+
4+
interface TipKitInlineViewProps extends BaseTipKitProps {}
5+
6+
const TipKitInlineView: React.FC<TipKitInlineViewProps> = ({ ...rest }) => {
7+
return <BaseTipKit popoverButtonArrowDirection={undefined} {...rest} />;
8+
};
9+
10+
export default TipKitInlineView;

src/TipKitInlineView/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import TipKitInlineView from './TipKitInlineView';
2+
export { TipKitInlineView };
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import React, {
2+
Fragment,
3+
useMemo,
4+
useRef,
5+
useState,
6+
type JSXElementConstructor,
7+
type ReactElement,
8+
} from 'react';
9+
import BaseTipKit, { type BaseTipKitProps } from '../components/BaseTipKit';
10+
import { Button, StyleSheet, View, type ButtonProps } from 'react-native';
11+
12+
export type TipKitPopOverArrowDirection =
13+
| 'top-start'
14+
| 'top'
15+
| 'top-end'
16+
| 'bottom-start'
17+
| 'bottom'
18+
| 'bottom-end';
19+
20+
interface TipKitPopOverViewProps extends BaseTipKitProps {
21+
popoverButtonArrowDirection?: TipKitPopOverArrowDirection;
22+
popoverButton?: ReactElement<any, string | JSXElementConstructor<any>>;
23+
popoverButtonOnPress?: () => void;
24+
popoverButtonTitle?: string;
25+
popoverButtonProps?: ButtonProps;
26+
}
27+
28+
const TipKitPopOverView: React.FC<TipKitPopOverViewProps> = ({
29+
popoverButton,
30+
popoverButtonOnPress,
31+
popoverButtonProps,
32+
popoverButtonArrowDirection = 'bottom',
33+
...rest
34+
}) => {
35+
const buttonRef = useRef<View>(null);
36+
37+
const [visible, setVisible] = useState(false);
38+
const [buttonPosition, setButtonPosition] = useState({
39+
x: 0,
40+
y: 0,
41+
width: 0,
42+
height: 0,
43+
});
44+
45+
const measureButtonPosition = () => {
46+
buttonRef.current?.measure((_fx, _fy, width, height, px, py) => {
47+
setButtonPosition({ x: px, y: py, width, height });
48+
});
49+
};
50+
51+
const popoverStyle = useMemo(() => {
52+
const { y, x, height } = buttonPosition;
53+
const isTop = popoverButtonArrowDirection?.includes('top');
54+
55+
return {
56+
top: y + (isTop ? -height * 2.5 : height * 1.5),
57+
left: x,
58+
};
59+
}, [buttonPosition, popoverButtonArrowDirection]);
60+
61+
const onDismiss = () => {
62+
setVisible(false);
63+
};
64+
65+
const handlePopoverButtonPress = () => {
66+
measureButtonPosition();
67+
popoverButtonOnPress?.();
68+
setVisible(true);
69+
};
70+
71+
return (
72+
<Fragment>
73+
<View ref={buttonRef} style={styles.buttonContainer}>
74+
{popoverButton ? (
75+
React.cloneElement(popoverButton, {
76+
onPress: () => {
77+
handlePopoverButtonPress();
78+
popoverButton.props.onPress?.();
79+
},
80+
})
81+
) : (
82+
<Button
83+
onPress={handlePopoverButtonPress}
84+
title={popoverButtonProps?.title || ''}
85+
color="#158481"
86+
{...popoverButtonProps}
87+
/>
88+
)}
89+
</View>
90+
{visible && (
91+
<View style={[styles.popoverContainer, popoverStyle]}>
92+
<BaseTipKit
93+
visible={true}
94+
onDismiss={onDismiss}
95+
popoverButtonArrowDirection={popoverButtonArrowDirection}
96+
{...rest}
97+
/>
98+
</View>
99+
)}
100+
</Fragment>
101+
);
102+
};
103+
104+
const styles = StyleSheet.create({
105+
buttonContainer: {
106+
zIndex: 9998,
107+
},
108+
popoverContainer: {
109+
position: 'absolute',
110+
zIndex: 9999,
111+
width: '100%',
112+
},
113+
});
114+
115+
export default TipKitPopOverView;

src/TipKitPopOverView/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import TipKitPopOverView from './TipKitPopOverView';
2+
export { TipKitPopOverView };

0 commit comments

Comments
 (0)