Skip to content

Commit 432ff49

Browse files
committed
feat(nc): add components
1 parent 16c09ed commit 432ff49

8 files changed

+285
-8
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import React from 'react';
2+
import {
3+
StyleSheet,
4+
View,
5+
TouchableOpacity
6+
} from 'react-native';
7+
import { COLORS } from '../styles/themes';
8+
9+
import { PenIcon } from './Icon/Pen.icon';
10+
11+
export const EditInfoContainer = ({ center, onPress, children }) => (
12+
<TouchableOpacity
13+
style={[
14+
center && styles.editInfoWrapperCentered
15+
]}
16+
onPress={onPress}
17+
>
18+
<View style={[
19+
styles.editInfoContainer,
20+
center && styles.editInfoContainerCentered,
21+
]}
22+
>
23+
<View style={[
24+
center && styles.alignCenter,
25+
]}
26+
>
27+
{children}
28+
</View>
29+
<View style={styles.editIcon}>
30+
<PenIcon />
31+
</View>
32+
</View>
33+
</TouchableOpacity>
34+
);
35+
36+
const styles = StyleSheet.create({
37+
editInfoWrapperCentered: {
38+
alignSelf: 'center',
39+
},
40+
editInfoContainer: {
41+
paddingVertical: 8,
42+
paddingLeft: 8,
43+
paddingRight: 40,
44+
borderRadius: 8,
45+
backgroundColor: COLORS.white,
46+
},
47+
editInfoContainerCentered: {
48+
paddingLeft: 40,
49+
},
50+
alignCenter: {
51+
alignItems: 'center',
52+
},
53+
editIcon: {
54+
position: 'absolute',
55+
display: 'flex',
56+
justifyContent: 'center',
57+
top: 0,
58+
right: 0,
59+
bottom: 0,
60+
width: 24,
61+
height: '100%',
62+
marginVertical: 8,
63+
marginRight: 8,
64+
},
65+
});

src/components/HathorHeader.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ const HathorHeader = ({
3030
const left = React.Children.toArray(children).find(
3131
(child) => child.type.displayName === HathorHeaderLeft.displayName
3232
);
33+
const central = React.Children.toArray(children).find(
34+
(child) => child.type.displayName === HathorHeaderCentral.displayName
35+
);
3336
const right = React.Children.toArray(children).find(
3437
(child) => child.type.displayName === HathorHeaderRight.displayName
3538
);
@@ -40,6 +43,7 @@ const HathorHeader = ({
4043
&& (
4144
<InnerWrapper>
4245
{left}
46+
{central}
4347
{right}
4448
</InnerWrapper>
4549
)}
@@ -70,10 +74,14 @@ const InnerWrapper = ({ children }) => (
7074
const HathorHeaderLeft = ({ children }) => (<View>{children}</View>);
7175
HathorHeaderLeft.displayName = 'HathorHeaderLeft';
7276

77+
const HathorHeaderCentral = ({ style, children }) => <View style={style}>{children}</View>;
78+
HathorHeaderCentral.displayName = 'HathorHeaderCentral';
79+
7380
const HathorHeaderRight = ({ children }) => <View>{children}</View>;
7481
HathorHeaderRight.displayName = 'HathorHeaderRight';
7582

7683
HathorHeader.Left = HathorHeaderLeft;
84+
HathorHeader.Central = HathorHeaderCentral;
7785
HathorHeader.Right = HathorHeaderRight;
7886

7987
const CancelButton = ({ onCancel }) => (
@@ -118,7 +126,7 @@ const RightComponent = ({ rightElement, onCancel }) => {
118126

119127
const styles = StyleSheet.create({
120128
wrapper: {
121-
height: STYLE.headerHeight,
129+
minHeight: STYLE.headerHeight,
122130
flexDirection: 'row',
123131
alignItems: 'flex-end',
124132
borderColor: COLORS.borderColor,

src/components/ModalBase.component.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* Copyright (c) Hathor Labs and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import React, { ReactNode } from 'react';
9+
import {
10+
StyleSheet,
11+
View,
12+
Text,
13+
StyleProp,
14+
ViewStyle
15+
} from 'react-native';
16+
import Modal from 'react-native-modal';
17+
18+
import { COLORS } from '../styles/themes';
19+
import NewHathorButton from './NewHathorButton';
20+
21+
const ModalBase = ({ styleModal, styleWrapper, show, onDismiss, children }) => {
22+
const hasChildren = children != null;
23+
24+
const title = hasChildren && React.Children.toArray(children).find(
25+
(child) => child.type.displayName === Title.displayName
26+
);
27+
const body = hasChildren && React.Children.toArray(children).find(
28+
(child) => child.type.displayName === Body.displayName
29+
);
30+
const button = hasChildren && React.Children.toArray(children).find(
31+
(child) => child.type.displayName === Button.displayName
32+
);
33+
34+
const discreteButton = hasChildren && React.Children.toArray(children).find(
35+
(child) => child.type.displayName === DiscreteButton.displayName
36+
);
37+
38+
return (
39+
<Modal
40+
isVisible={show}
41+
animationIn='slideInUp'
42+
swipeDirection={['down']}
43+
onSwipeComplete={onDismiss}
44+
onBackButtonPress={onDismiss}
45+
onBackdropPress={onDismiss}
46+
style={styleModal}
47+
propagateSwipe
48+
>
49+
<View style={[
50+
styles.wrapper,
51+
styleWrapper,
52+
]}
53+
>
54+
{title && title}
55+
{body && body}
56+
{button && button}
57+
{discreteButton && discreteButton}
58+
</View>
59+
</Modal>
60+
);
61+
};
62+
63+
const Title = ({ children }) => (
64+
<View style={styles.titleWrapper}>
65+
<Text style={styles.title}>
66+
{children}
67+
</Text>
68+
</View>
69+
);
70+
Title.displayName = 'ModalBaseTitle';
71+
72+
/**
73+
* @typedef {Object} Properties p
74+
* @property {ReactNode} p.children
75+
* @property {StyleProp<ViewStyle>} p.style
76+
*
77+
* @param {Properties}
78+
*/
79+
const Body = ({ style, children }) => (
80+
<View style={style}>
81+
{children}
82+
</View>
83+
);
84+
Body.displayName = 'ModalBaseBody';
85+
86+
const Button = ({ title, disabled, secondary, danger, onPress }) => (
87+
<NewHathorButton title={title} {...{ disabled, secondary, danger, onPress }} />
88+
);
89+
Button.displayName = 'ModalBaseButton';
90+
91+
const DiscreteButton = ({ title, onPress }) => (
92+
<NewHathorButton title={title} discrete {...{ onPress }} wrapperStyle={styles.discreteButton} />
93+
);
94+
DiscreteButton.displayName = 'ModalBaseDiscreteButton';
95+
96+
ModalBase.Title = Title;
97+
ModalBase.Body = Body;
98+
ModalBase.Button = Button;
99+
ModalBase.DiscreteButton = DiscreteButton;
100+
101+
const styles = StyleSheet.create({
102+
wrapper: {
103+
borderRadius: 8,
104+
paddingVertical: 24,
105+
paddingHorizontal: 16,
106+
backgroundColor: COLORS.white,
107+
},
108+
titleWrapper: {
109+
paddingBottom: 20,
110+
},
111+
title: {
112+
color: 'black',
113+
fontSize: 18,
114+
lineHeight: 20,
115+
},
116+
discreteButton: {
117+
marginTop: 8,
118+
},
119+
});
120+
121+
export { ModalBase }

src/components/NewHathorButton.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ const NewHathorButton = (props) => {
2121
textStyle.push(style.textDisabled);
2222
}
2323

24+
if (props.discrete) {
25+
wrapperViewStyle.push(style.wrapperDiscrete);
26+
textStyle.push(style.textDiscrete);
27+
}
28+
2429
if (props.secondary) {
2530
wrapperViewStyle.push(style.wrapperSecondary);
2631
textStyle.push(style.textSecondary);
@@ -34,6 +39,11 @@ const NewHathorButton = (props) => {
3439
}
3540
}
3641

42+
if (props.danger) {
43+
wrapperViewStyle.push(style.wrapperSecondaryDanger);
44+
textStyle.push(style.textSecondaryDanger);
45+
}
46+
3747
return (
3848
<View style={[...wrapperViewStyle, props.wrapperStyle, props.style]}>
3949
<TouchableOpacity onPress={props.onPress} style={style.touchable} disabled={props.disabled}>
@@ -79,6 +89,14 @@ const style = StyleSheet.create({
7989
wrapperSecondaryDisabled: {
8090
borderColor: COLORS.textColorShadow,
8191
},
92+
wrapperDiscrete: {
93+
backgroundColor: COLORS.backgroundColor,
94+
borderColor: COLORS.backgroundColor,
95+
borderWidth: 1.5,
96+
},
97+
wrapperSecondaryDanger: {
98+
borderColor: COLORS.errorBgColor,
99+
},
82100
touchable: {
83101
flex: 1,
84102
flexDirection: 'row',
@@ -101,6 +119,12 @@ const style = StyleSheet.create({
101119
textDisabled: {
102120
color: COLORS.textColorShadow,
103121
},
122+
textDiscrete: {
123+
color: COLORS.freeze300,
124+
},
125+
textSecondaryDanger: {
126+
color: COLORS.errorBgColor,
127+
},
104128
});
105129

106130
export default NewHathorButton;

src/components/TextLabel.component.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import {
3+
StyleSheet,
4+
Text,
5+
} from 'react-native';
6+
7+
export const TextLabel = ({ pb8, bold, children }) => (
8+
<Text style={[
9+
styles.textLabel,
10+
pb8 && styles.pb8,
11+
bold && styles.bold,
12+
]}
13+
>{children}</Text>
14+
);
15+
16+
const styles = StyleSheet.create({
17+
textLabel: {
18+
fontSize: 12,
19+
lineHeight: 20,
20+
color: 'hsla(0, 0%, 38%, 1)',
21+
},
22+
pb8: {
23+
paddingBottom: 8,
24+
},
25+
bold: {
26+
fontWeight: 'bold',
27+
},
28+
});

src/components/TextValue.component.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import {
3+
StyleSheet,
4+
Text,
5+
} from 'react-native';
6+
7+
export const TextValue = ({ bold, pb4, children }) => (
8+
<Text style={[
9+
styles.textValue,
10+
bold && styles.bold,
11+
pb4 && styles.pb4,
12+
]}
13+
>{children}</Text>
14+
);
15+
16+
const styles = StyleSheet.create({
17+
textValue: {
18+
fontSize: 14,
19+
lineHeight: 20,
20+
color: 'black',
21+
},
22+
pb4: {
23+
paddingBottom: 4,
24+
},
25+
bold: {
26+
fontWeight: 'bold',
27+
},
28+
});

src/components/TransactionStatusLabel.component.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import React from 'react';
99
import { StyleSheet, Text, View, } from 'react-native';
1010
import { t } from 'ttag';
1111
import { COLORS } from '../styles/themes';
12-
import { CircleCheck } from './CircleCheck.icon';
13-
import { CircleClock } from './CircleClock.icon';
14-
import { CircleError } from './CircleError.icon';
12+
import { CircleCheckIcon } from './Icon/CircleCheck.icon';
13+
import { CircleClockIcon } from './Icon/CircleClock.icon';
14+
import { CircleErrorIcon } from './Icon/CircleError.icon';
1515

1616
const styles = StyleSheet.create({
1717
wrapper: {
@@ -69,22 +69,22 @@ const TransactionStatusBase = ({ label, style, children: icon }) => (
6969

7070
const Confirmed = () => (
7171
<TransactionStatusBase style={styles.feedbackSuccess} label={t`Confirmed`}>
72-
<CircleCheck size={16} color={styles.feedbackSuccess.color} />
72+
<CircleCheckIcon size={16} color={styles.feedbackSuccess.color} />
7373
</TransactionStatusBase>
7474
);
7575
const Processing = () => (
7676
<TransactionStatusBase style={styles.feedbackWarning} label={t`Processing`}>
77-
<CircleClock size={16} color={styles.feedbackWarning.color} />
77+
<CircleClockIcon size={16} color={styles.feedbackWarning.color} />
7878
</TransactionStatusBase>
7979
);
8080
const Voided = () => (
8181
<TransactionStatusBase style={styles.feedbackError} label={t`Voided`}>
82-
<CircleError size={16} color={styles.feedbackError.color} />
82+
<CircleErrorIcon size={16} color={styles.feedbackError.color} />
8383
</TransactionStatusBase>
8484
);
8585
const Unkown = () => (
8686
<TransactionStatusBase style={styles.freeze} label={t`Unkown`}>
87-
<CircleError size={16} color={styles.freeze.color} />
87+
<CircleErrorIcon size={16} color={styles.freeze.color} />
8888
</TransactionStatusBase>
8989
);
9090

src/utils.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import React from 'react';
1111
import { t } from 'ttag';
1212
import { Linking, Platform, Text } from 'react-native';
1313
import { getStatusBarHeight } from 'react-native-status-bar-height';
14+
import moment from 'moment';
1415
import baseStyle from './styles/init';
1516
import { KEYCHAIN_USER } from './constants';
1617
import { STORE } from './store';
@@ -383,3 +384,5 @@ export function combineURLs(baseURL, relativeURL) {
383384
export const isPushNotificationAvailableForUser = (state) => (
384385
state.pushNotification.available && state.pushNotification.deviceRegistered
385386
);
387+
388+
export const getTimestampFormat = (timestamp) => moment.unix(timestamp).format('DD MMM YYYY [•] HH:mm')

0 commit comments

Comments
 (0)