@hero-design/rn 7.1.3-alpha3 → 7.1.3-alpha6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/index.js +328 -128
- package/lib/index.js +328 -126
- package/package.json +1 -1
- package/playground/components/BottomNavigation.tsx +8 -8
- package/playground/components/Button.tsx +67 -0
- package/playground/components/FAB.tsx +4 -1
- package/playground/components/Tabs.tsx +45 -0
- package/playground/index.tsx +10 -4
- package/src/components/Badge/StyledBadge.tsx +3 -5
- package/src/components/Badge/__tests__/__snapshots__/Badge.spec.tsx.snap +52 -20
- package/src/components/Badge/index.tsx +3 -1
- package/src/components/BottomNavigation/StyledBottomNavigation.tsx +7 -0
- package/src/components/BottomNavigation/__tests__/BottomNavigation.spec.tsx +1 -1
- package/src/components/BottomNavigation/index.tsx +14 -18
- package/src/components/Button/IconButton.tsx +62 -0
- package/src/components/Button/__tests__/__snapshots__/index.spec.tsx.snap +43 -0
- package/src/components/Button/__tests__/index.spec.tsx +29 -0
- package/src/components/Button/index.tsx +5 -0
- package/src/components/FAB/ActionGroup/StyledActionGroup.tsx +1 -1
- package/src/components/FAB/ActionGroup/__tests__/__snapshots__/index.spec.tsx.snap +1 -1
- package/src/components/Tabs/StyledTabs.tsx +72 -0
- package/src/components/Tabs/__tests__/Tabs.spec.tsx +79 -0
- package/src/components/Tabs/__tests__/__snapshots__/Tabs.spec.tsx.snap +295 -0
- package/src/components/Tabs/index.tsx +177 -0
- package/src/index.ts +4 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +16 -6
- package/src/theme/components/badge.ts +1 -9
- package/src/theme/components/bottomNavigation.ts +5 -1
- package/src/theme/components/fab.ts +2 -2
- package/src/theme/components/tabs.ts +20 -0
- package/src/theme/index.ts +3 -0
- package/src/utils/__tests__/scale.spec.ts +3 -3
- package/src/utils/scale.ts +4 -1
- package/types/playground/components/BottomNavigation.d.ts +2 -2
- package/types/playground/components/Button.d.ts +2 -0
- package/types/playground/components/Tabs.d.ts +2 -0
- package/types/src/components/Badge/StyledBadge.d.ts +2 -2
- package/types/src/components/BottomNavigation/StyledBottomNavigation.d.ts +2 -1
- package/types/src/components/BottomNavigation/index.d.ts +10 -10
- package/types/src/components/Button/IconButton.d.ts +34 -0
- package/types/src/components/Button/__tests__/index.spec.d.ts +1 -0
- package/types/src/components/Button/index.d.ts +4 -0
- package/types/src/components/Tabs/StyledTabs.d.ts +23 -0
- package/types/src/components/Tabs/__tests__/Tabs.spec.d.ts +1 -0
- package/types/src/components/Tabs/index.d.ts +40 -0
- package/types/src/index.d.ts +3 -1
- package/types/src/theme/components/badge.d.ts +0 -6
- package/types/src/theme/components/bottomNavigation.d.ts +3 -0
- package/types/src/theme/components/tabs.d.ts +15 -0
- package/types/src/theme/index.d.ts +2 -0
- package/types/src/utils/scale.d.ts +2 -1
package/package.json
CHANGED
|
@@ -27,35 +27,35 @@ const ProfileScreen = () => (
|
|
|
27
27
|
</View>
|
|
28
28
|
);
|
|
29
29
|
|
|
30
|
-
const tabs: Tab
|
|
30
|
+
const tabs: Tab[] = [
|
|
31
31
|
{
|
|
32
|
-
key:
|
|
32
|
+
key: 'home',
|
|
33
33
|
title: 'Home',
|
|
34
34
|
icon: 'home',
|
|
35
35
|
component: <HomeScreen />,
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
key:
|
|
38
|
+
key: 'feed',
|
|
39
39
|
title: 'Feed',
|
|
40
40
|
icon: 'speaker',
|
|
41
41
|
component: <FeedScreen />,
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
key:
|
|
44
|
+
key: 'alerts',
|
|
45
45
|
title: 'Alerts',
|
|
46
46
|
icon: 'bell',
|
|
47
47
|
component: <AlertsScreen />,
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
|
-
key:
|
|
50
|
+
key: 'profile',
|
|
51
51
|
title: 'Profile',
|
|
52
52
|
icon: 'user',
|
|
53
53
|
component: <ProfileScreen />,
|
|
54
54
|
},
|
|
55
55
|
];
|
|
56
56
|
|
|
57
|
-
const
|
|
58
|
-
const [selectedTabKey, setSelectedTabKey] = React.useState(
|
|
57
|
+
const BottomNavigationPlayground = () => {
|
|
58
|
+
const [selectedTabKey, setSelectedTabKey] = React.useState('home');
|
|
59
59
|
|
|
60
60
|
return (
|
|
61
61
|
<BottomNavigation
|
|
@@ -66,4 +66,4 @@ const MyComponent = () => {
|
|
|
66
66
|
);
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
export default
|
|
69
|
+
export default BottomNavigationPlayground;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { Button, Typography, useTheme } from '../../src/index';
|
|
5
|
+
|
|
6
|
+
const ButtonPlayground = (): JSX.Element => {
|
|
7
|
+
const theme = useTheme();
|
|
8
|
+
return (
|
|
9
|
+
<View style={{ padding: theme.space.small }}>
|
|
10
|
+
<Typography.Text style={{ marginBottom: theme.space.xsmall }}>
|
|
11
|
+
Different Intents and Sizes from Icon
|
|
12
|
+
</Typography.Text>
|
|
13
|
+
<View
|
|
14
|
+
style={{
|
|
15
|
+
flexDirection: 'row',
|
|
16
|
+
alignItems: 'center',
|
|
17
|
+
marginBottom: theme.space.large,
|
|
18
|
+
}}
|
|
19
|
+
>
|
|
20
|
+
<Button.Icon
|
|
21
|
+
icon="circle-add-outlined"
|
|
22
|
+
intent="text"
|
|
23
|
+
size="xsmall"
|
|
24
|
+
onPress={() => {}}
|
|
25
|
+
style={{ marginEnd: theme.space.medium }}
|
|
26
|
+
/>
|
|
27
|
+
<Button.Icon
|
|
28
|
+
icon="circle-add-outlined"
|
|
29
|
+
intent="primary"
|
|
30
|
+
size="xsmall"
|
|
31
|
+
onPress={() => {}}
|
|
32
|
+
style={{ marginEnd: theme.space.medium }}
|
|
33
|
+
/>
|
|
34
|
+
<Button.Icon
|
|
35
|
+
icon="circle-add-outlined"
|
|
36
|
+
intent="success"
|
|
37
|
+
size="small"
|
|
38
|
+
onPress={() => {}}
|
|
39
|
+
style={{ marginEnd: theme.space.medium }}
|
|
40
|
+
/>
|
|
41
|
+
<Button.Icon
|
|
42
|
+
icon="circle-add-outlined"
|
|
43
|
+
intent="info"
|
|
44
|
+
size="medium"
|
|
45
|
+
onPress={() => {}}
|
|
46
|
+
style={{ marginEnd: theme.space.medium }}
|
|
47
|
+
/>
|
|
48
|
+
<Button.Icon
|
|
49
|
+
icon="circle-add-outlined"
|
|
50
|
+
intent="warning"
|
|
51
|
+
size="large"
|
|
52
|
+
onPress={() => {}}
|
|
53
|
+
style={{ marginEnd: theme.space.medium }}
|
|
54
|
+
/>
|
|
55
|
+
<Button.Icon
|
|
56
|
+
icon="circle-add-outlined"
|
|
57
|
+
intent="danger"
|
|
58
|
+
size="xlarge"
|
|
59
|
+
onPress={() => {}}
|
|
60
|
+
style={{ marginEnd: theme.space.medium }}
|
|
61
|
+
/>
|
|
62
|
+
</View>
|
|
63
|
+
</View>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default ButtonPlayground;
|
|
@@ -28,12 +28,15 @@ const FABPlayground = (): JSX.Element => {
|
|
|
28
28
|
</TouchableHighlight>
|
|
29
29
|
<FAB.ActionGroup
|
|
30
30
|
style={{
|
|
31
|
-
marginBottom: theme.space.
|
|
31
|
+
marginBottom: theme.space.medium,
|
|
32
32
|
}}
|
|
33
33
|
items={[
|
|
34
|
+
{ icon: 'coin', title: 'Expense Claim' },
|
|
34
35
|
{ icon: 'speaker', title: 'Give shout out' },
|
|
35
36
|
{ icon: 'target', title: 'Goal' },
|
|
36
37
|
{ icon: 'plane', title: 'Leave request' },
|
|
38
|
+
{ icon: 'reply', title: 'Memeber Feedback' },
|
|
39
|
+
{ icon: 'star-medal', title: 'Recognition teammate' },
|
|
37
40
|
{ icon: 'health-bag', title: 'Safety incident' },
|
|
38
41
|
{ icon: 'clock', title: 'Timesheets' },
|
|
39
42
|
]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Tab } from '../../src/components/Tabs';
|
|
4
|
+
import { Tabs, Typography } from '../../src/index';
|
|
5
|
+
|
|
6
|
+
const WorkScreen = () => (
|
|
7
|
+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
8
|
+
<Typography.Text>Work Screen</Typography.Text>
|
|
9
|
+
</View>
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
const PersonalScreen = () => (
|
|
13
|
+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
|
|
14
|
+
<Typography.Text>Personal Screen</Typography.Text>
|
|
15
|
+
</View>
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const tabs: Tab[] = [
|
|
19
|
+
{
|
|
20
|
+
key: 'work',
|
|
21
|
+
title: 'Work',
|
|
22
|
+
icon: 'suitcase',
|
|
23
|
+
component: <WorkScreen />,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
key: 'personal',
|
|
27
|
+
title: 'Personal',
|
|
28
|
+
icon: 'face-smiley',
|
|
29
|
+
component: <PersonalScreen />,
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const TabsPlayground = () => {
|
|
34
|
+
const [selectedTabKey, setSelectedTabKey] = React.useState('work');
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Tabs
|
|
38
|
+
onChange={newTabKey => setSelectedTabKey(newTabKey)}
|
|
39
|
+
selectedTabKey={selectedTabKey}
|
|
40
|
+
tabs={tabs}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default TabsPlayground;
|
package/playground/index.tsx
CHANGED
|
@@ -10,11 +10,13 @@ import { SafeAreaView, FlatList } from 'react-native';
|
|
|
10
10
|
import { ThemeProvider, theme, useTheme, Typography } from '../src/index';
|
|
11
11
|
import BadgePlayground from './components/Badge';
|
|
12
12
|
import BottomNavigation from './components/BottomNavigation';
|
|
13
|
+
import Button from './components/Button';
|
|
13
14
|
import CardPlayground from './components/Card';
|
|
14
15
|
import DividerPlayground from './components/Divider';
|
|
16
|
+
import FABPlayground from './components/FAB';
|
|
15
17
|
import IconPlayground from './components/Icon';
|
|
18
|
+
import TabsPlayground from './components/Tabs';
|
|
16
19
|
import TypographyPlayground from './components/Typography';
|
|
17
|
-
import FABPlayground from './components/FAB';
|
|
18
20
|
|
|
19
21
|
const heroIconFontPath = require('../assets/fonts/hero-icons.ttf');
|
|
20
22
|
const beVietnamProLightFont = require('../assets/fonts/be-vietnam-pro-light.ttf');
|
|
@@ -22,14 +24,16 @@ const beVietnamProRegularFont = require('../assets/fonts/be-vietnam-pro-regular.
|
|
|
22
24
|
const beVietnamProSemiBoldFont = require('../assets/fonts/be-vietnam-pro-semibold.ttf');
|
|
23
25
|
|
|
24
26
|
type RootStackParamList = {
|
|
25
|
-
Home: undefined;
|
|
26
27
|
Badge: undefined;
|
|
27
28
|
BottomNavigation: undefined;
|
|
29
|
+
Button: undefined;
|
|
28
30
|
Card: undefined;
|
|
29
31
|
Divider: undefined;
|
|
32
|
+
FAB: undefined;
|
|
33
|
+
Home: undefined;
|
|
30
34
|
Icon: undefined;
|
|
35
|
+
Tabs: undefined;
|
|
31
36
|
Typography: undefined;
|
|
32
|
-
FAB: undefined;
|
|
33
37
|
};
|
|
34
38
|
|
|
35
39
|
type Navigation = NativeStackScreenProps<RootStackParamList>;
|
|
@@ -39,11 +43,13 @@ const Stack = createNativeStackNavigator<RootStackParamList>();
|
|
|
39
43
|
const components = [
|
|
40
44
|
{ name: 'Badge', component: BadgePlayground },
|
|
41
45
|
{ name: 'BottomNavigation', component: BottomNavigation },
|
|
46
|
+
{ name: 'Button', component: Button },
|
|
42
47
|
{ name: 'Card', component: CardPlayground },
|
|
43
48
|
{ name: 'Divider', component: DividerPlayground },
|
|
49
|
+
{ name: 'FAB', component: FABPlayground },
|
|
44
50
|
{ name: 'Icon', component: IconPlayground },
|
|
51
|
+
{ name: 'Tabs', component: TabsPlayground },
|
|
45
52
|
{ name: 'Typography', component: TypographyPlayground },
|
|
46
|
-
{ name: 'FAB', component: FABPlayground },
|
|
47
53
|
] as const;
|
|
48
54
|
|
|
49
55
|
const ComponentItem = ({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { View } from 'react-native';
|
|
2
2
|
import styled, { css } from 'styled-components-native';
|
|
3
|
+
import Typography from '../Typography';
|
|
3
4
|
|
|
4
5
|
const BACKGROUND_INTENTS = {
|
|
5
6
|
success: 'successBackground',
|
|
@@ -22,10 +23,7 @@ const StyledView = styled(View)<{ themeIntent: ThemeIntent }>`
|
|
|
22
23
|
`};
|
|
23
24
|
`;
|
|
24
25
|
|
|
25
|
-
const StyledText = styled(Text)<{ themeIntent: ThemeIntent }>`
|
|
26
|
-
font-family: ${({ theme }) => theme.__hd__.badge.fonts.default};
|
|
27
|
-
font-size: ${({ theme }) => theme.__hd__.badge.fontSizes.default};
|
|
28
|
-
|
|
26
|
+
const StyledText = styled(Typography.Text)<{ themeIntent: ThemeIntent }>`
|
|
29
27
|
${({ themeIntent }) => css`
|
|
30
28
|
color: ${({ theme }) => theme.__hd__.badge.colors[themeIntent]};
|
|
31
29
|
`};
|
|
@@ -27,12 +27,20 @@ exports[`Badge has danger style when intent is danger 1`] = `
|
|
|
27
27
|
>
|
|
28
28
|
<Text
|
|
29
29
|
style={
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
Array [
|
|
31
|
+
Object {
|
|
32
|
+
"fontFamily": "Be Vietnam Pro SemiBold",
|
|
33
|
+
"fontSize": 12,
|
|
34
|
+
"letterSpacing": 0.36,
|
|
35
|
+
"lineHeight": 20,
|
|
36
|
+
},
|
|
37
|
+
Object {
|
|
38
|
+
"color": "#de350b",
|
|
39
|
+
},
|
|
40
|
+
]
|
|
35
41
|
}
|
|
42
|
+
themeFontSize="small"
|
|
43
|
+
themeFontWeight="semi-bold"
|
|
36
44
|
themeIntent="danger"
|
|
37
45
|
>
|
|
38
46
|
DECLINED
|
|
@@ -67,12 +75,20 @@ exports[`Badge has info style when intent is info 1`] = `
|
|
|
67
75
|
>
|
|
68
76
|
<Text
|
|
69
77
|
style={
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
Array [
|
|
79
|
+
Object {
|
|
80
|
+
"fontFamily": "Be Vietnam Pro SemiBold",
|
|
81
|
+
"fontSize": 12,
|
|
82
|
+
"letterSpacing": 0.36,
|
|
83
|
+
"lineHeight": 20,
|
|
84
|
+
},
|
|
85
|
+
Object {
|
|
86
|
+
"color": "#4568fb",
|
|
87
|
+
},
|
|
88
|
+
]
|
|
75
89
|
}
|
|
90
|
+
themeFontSize="small"
|
|
91
|
+
themeFontWeight="semi-bold"
|
|
76
92
|
themeIntent="info"
|
|
77
93
|
>
|
|
78
94
|
SUBMITTED
|
|
@@ -107,12 +123,20 @@ exports[`Badge has success style when intent is success 1`] = `
|
|
|
107
123
|
>
|
|
108
124
|
<Text
|
|
109
125
|
style={
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
Array [
|
|
127
|
+
Object {
|
|
128
|
+
"fontFamily": "Be Vietnam Pro SemiBold",
|
|
129
|
+
"fontSize": 12,
|
|
130
|
+
"letterSpacing": 0.36,
|
|
131
|
+
"lineHeight": 20,
|
|
132
|
+
},
|
|
133
|
+
Object {
|
|
134
|
+
"color": "#017d6d",
|
|
135
|
+
},
|
|
136
|
+
]
|
|
115
137
|
}
|
|
138
|
+
themeFontSize="small"
|
|
139
|
+
themeFontWeight="semi-bold"
|
|
116
140
|
themeIntent="success"
|
|
117
141
|
>
|
|
118
142
|
APPROVED
|
|
@@ -147,12 +171,20 @@ exports[`Badge has warning style when intent is warning 1`] = `
|
|
|
147
171
|
>
|
|
148
172
|
<Text
|
|
149
173
|
style={
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
Array [
|
|
175
|
+
Object {
|
|
176
|
+
"fontFamily": "Be Vietnam Pro SemiBold",
|
|
177
|
+
"fontSize": 12,
|
|
178
|
+
"letterSpacing": 0.36,
|
|
179
|
+
"lineHeight": 20,
|
|
180
|
+
},
|
|
181
|
+
Object {
|
|
182
|
+
"color": "#d98a2c",
|
|
183
|
+
},
|
|
184
|
+
]
|
|
155
185
|
}
|
|
186
|
+
themeFontSize="small"
|
|
187
|
+
themeFontWeight="semi-bold"
|
|
156
188
|
themeIntent="warning"
|
|
157
189
|
>
|
|
158
190
|
PENDING
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { View } from 'react-native';
|
|
2
2
|
import styled from 'styled-components-native';
|
|
3
|
+
import Typography from '../Typography';
|
|
3
4
|
|
|
4
5
|
const BottomNavigationTab = styled(View)<{ themeVisibility?: boolean }>`
|
|
5
6
|
flex: 1;
|
|
@@ -48,6 +49,11 @@ const BottomBarItem = styled(View)`
|
|
|
48
49
|
align-items: center;
|
|
49
50
|
`;
|
|
50
51
|
|
|
52
|
+
const StyledBottomBarText = styled(Typography.Text)`
|
|
53
|
+
margin-top: ${({ theme }) =>
|
|
54
|
+
theme.__hd__.bottomNavigation.space.titleMarginTop};
|
|
55
|
+
`;
|
|
56
|
+
|
|
51
57
|
export {
|
|
52
58
|
BottomBar,
|
|
53
59
|
BottomBarItem,
|
|
@@ -55,4 +61,5 @@ export {
|
|
|
55
61
|
BottomNavigationContainer,
|
|
56
62
|
BottomBarWrapper,
|
|
57
63
|
ContentWrapper,
|
|
64
|
+
StyledBottomBarText,
|
|
58
65
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
TouchableWithoutFeedback,
|
|
4
4
|
StyleProp,
|
|
@@ -6,10 +6,8 @@ import {
|
|
|
6
6
|
ViewProps,
|
|
7
7
|
} from 'react-native';
|
|
8
8
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
9
|
-
import {
|
|
10
|
-
import Icon from '../Icon';
|
|
9
|
+
import Icon, { IconProps } from '../Icon';
|
|
11
10
|
import { isHeroIcon } from '../Icon/utils';
|
|
12
|
-
import Typography from '../Typography';
|
|
13
11
|
import {
|
|
14
12
|
BottomBar,
|
|
15
13
|
BottomBarItem,
|
|
@@ -17,25 +15,25 @@ import {
|
|
|
17
15
|
BottomNavigationContainer,
|
|
18
16
|
BottomNavigationTab,
|
|
19
17
|
ContentWrapper,
|
|
18
|
+
StyledBottomBarText,
|
|
20
19
|
} from './StyledBottomNavigation';
|
|
21
20
|
import { isIOS } from '../../utils/helpers';
|
|
22
21
|
|
|
23
|
-
type IconType =
|
|
22
|
+
type IconType = IconProps['icon'];
|
|
24
23
|
|
|
25
|
-
export type Tab
|
|
26
|
-
key:
|
|
24
|
+
export type Tab = {
|
|
25
|
+
key: string;
|
|
27
26
|
title?: string;
|
|
28
27
|
icon: IconType;
|
|
29
28
|
component: ReactNode;
|
|
30
29
|
testID?: string;
|
|
31
30
|
};
|
|
32
31
|
|
|
33
|
-
interface BottomNavigationType
|
|
34
|
-
extends ViewProps {
|
|
32
|
+
interface BottomNavigationType extends ViewProps {
|
|
35
33
|
/**
|
|
36
34
|
* Callback which is called on tab change, receiving id of upcoming active Tab.
|
|
37
35
|
*/
|
|
38
|
-
onChange: (key:
|
|
36
|
+
onChange: (key: string) => void;
|
|
39
37
|
/**
|
|
40
38
|
* Whether inactive tabs should be removed and unmounted in React.
|
|
41
39
|
* Defaults to `false`.
|
|
@@ -44,11 +42,11 @@ interface BottomNavigationType<V extends string | number, T extends Tab<V>>
|
|
|
44
42
|
/**
|
|
45
43
|
* Current selected tab key.
|
|
46
44
|
*/
|
|
47
|
-
selectedTabKey:
|
|
45
|
+
selectedTabKey: string;
|
|
48
46
|
/**
|
|
49
47
|
* List of Tab to be rendered. Each Tab must have an unique id.
|
|
50
48
|
*/
|
|
51
|
-
tabs:
|
|
49
|
+
tabs: Tab[];
|
|
52
50
|
/**
|
|
53
51
|
* Addditional style.
|
|
54
52
|
*/
|
|
@@ -64,14 +62,13 @@ const getInactiveIcon = (icon: IconType): IconType => {
|
|
|
64
62
|
return isHeroIcon(inactiveIcon) ? inactiveIcon : icon;
|
|
65
63
|
};
|
|
66
64
|
|
|
67
|
-
const BottomNavigation =
|
|
65
|
+
const BottomNavigation = ({
|
|
68
66
|
onChange,
|
|
69
67
|
renderActiveTabOnly = false,
|
|
70
68
|
selectedTabKey,
|
|
71
69
|
tabs,
|
|
72
70
|
...nativeProps
|
|
73
|
-
}: BottomNavigationType
|
|
74
|
-
const theme = useTheme();
|
|
71
|
+
}: BottomNavigationType): JSX.Element => {
|
|
75
72
|
const insets = useSafeAreaInsets();
|
|
76
73
|
|
|
77
74
|
/**
|
|
@@ -146,15 +143,14 @@ const BottomNavigation = <V extends string | number, T extends Tab<V>>({
|
|
|
146
143
|
testID={`hero-icon-${icon}`}
|
|
147
144
|
/>
|
|
148
145
|
{title && (
|
|
149
|
-
<
|
|
146
|
+
<StyledBottomBarText
|
|
150
147
|
fontSize="small"
|
|
151
148
|
fontWeight="semi-bold"
|
|
152
149
|
intent={active ? 'primary' : 'body'}
|
|
153
|
-
style={{ marginTop: theme.space.xsmall }}
|
|
154
150
|
numberOfLines={1}
|
|
155
151
|
>
|
|
156
152
|
{title}
|
|
157
|
-
</
|
|
153
|
+
</StyledBottomBarText>
|
|
158
154
|
)}
|
|
159
155
|
</BottomBarItem>
|
|
160
156
|
</TouchableWithoutFeedback>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
StyleProp,
|
|
5
|
+
ViewStyle,
|
|
6
|
+
TouchableOpacity,
|
|
7
|
+
TouchableOpacityProps,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
|
|
10
|
+
import Icon, { IconProps } from '../Icon';
|
|
11
|
+
|
|
12
|
+
export interface IconButtonProps {
|
|
13
|
+
/**
|
|
14
|
+
* Set how far you can touch from the button
|
|
15
|
+
*/
|
|
16
|
+
hitSlop?: TouchableOpacityProps['hitSlop'];
|
|
17
|
+
/**
|
|
18
|
+
* Name of the Icon.
|
|
19
|
+
*/
|
|
20
|
+
icon: IconProps['icon'];
|
|
21
|
+
/**
|
|
22
|
+
* Intent of the Icon.
|
|
23
|
+
*/
|
|
24
|
+
intent?: IconProps['intent'];
|
|
25
|
+
/**
|
|
26
|
+
* Set the handler to handle press event.
|
|
27
|
+
*/
|
|
28
|
+
onPress: () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Size of the Icon.
|
|
31
|
+
*/
|
|
32
|
+
size?: IconProps['size'];
|
|
33
|
+
/**
|
|
34
|
+
* Addditional style.
|
|
35
|
+
*/
|
|
36
|
+
style?: StyleProp<ViewStyle>;
|
|
37
|
+
/**
|
|
38
|
+
* Testing id of component
|
|
39
|
+
*/
|
|
40
|
+
testID?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const IconButton = ({
|
|
44
|
+
hitSlop,
|
|
45
|
+
onPress,
|
|
46
|
+
icon,
|
|
47
|
+
testID,
|
|
48
|
+
style,
|
|
49
|
+
size,
|
|
50
|
+
intent,
|
|
51
|
+
}: IconButtonProps) => (
|
|
52
|
+
<TouchableOpacity
|
|
53
|
+
style={style}
|
|
54
|
+
onPress={onPress}
|
|
55
|
+
testID={testID}
|
|
56
|
+
hitSlop={hitSlop}
|
|
57
|
+
>
|
|
58
|
+
<Icon icon={icon} size={size} intent={intent} />
|
|
59
|
+
</TouchableOpacity>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
export default IconButton;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`IconButton renders correctly 1`] = `
|
|
4
|
+
<View
|
|
5
|
+
accessible={true}
|
|
6
|
+
collapsable={false}
|
|
7
|
+
focusable={true}
|
|
8
|
+
hitSlop={
|
|
9
|
+
Object {
|
|
10
|
+
"bottom": 4,
|
|
11
|
+
"left": 6,
|
|
12
|
+
"right": 6,
|
|
13
|
+
"top": 4,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
nativeID="animatedComponent"
|
|
17
|
+
onClick={[Function]}
|
|
18
|
+
onResponderGrant={[Function]}
|
|
19
|
+
onResponderMove={[Function]}
|
|
20
|
+
onResponderRelease={[Function]}
|
|
21
|
+
onResponderTerminate={[Function]}
|
|
22
|
+
onResponderTerminationRequest={[Function]}
|
|
23
|
+
onStartShouldSetResponder={[Function]}
|
|
24
|
+
style={
|
|
25
|
+
Object {
|
|
26
|
+
"opacity": 1,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
testID="icon-btn"
|
|
30
|
+
>
|
|
31
|
+
<HeroIcon
|
|
32
|
+
name="home"
|
|
33
|
+
style={
|
|
34
|
+
Object {
|
|
35
|
+
"color": "#292a2b",
|
|
36
|
+
"fontSize": 24,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
themeIntent="text"
|
|
40
|
+
themeSize="medium"
|
|
41
|
+
/>
|
|
42
|
+
</View>
|
|
43
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { fireEvent } from '@testing-library/react-native';
|
|
3
|
+
|
|
4
|
+
import { ThemeProvider, theme } from '../../../index';
|
|
5
|
+
|
|
6
|
+
import renderWithTheme from '../../../testHelpers/renderWithTheme';
|
|
7
|
+
|
|
8
|
+
import Button from '..';
|
|
9
|
+
|
|
10
|
+
describe('IconButton', () => {
|
|
11
|
+
it('renders correctly', () => {
|
|
12
|
+
const onPress = jest.fn();
|
|
13
|
+
const { toJSON, getByTestId } = renderWithTheme(
|
|
14
|
+
<ThemeProvider theme={theme}>
|
|
15
|
+
<Button.Icon
|
|
16
|
+
icon="home"
|
|
17
|
+
onPress={onPress}
|
|
18
|
+
testID="icon-btn"
|
|
19
|
+
hitSlop={{ top: 4, bottom: 4, right: 6, left: 6 }}
|
|
20
|
+
/>
|
|
21
|
+
</ThemeProvider>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
fireEvent.press(getByTestId('icon-btn'));
|
|
25
|
+
expect(onPress).toBeCalledTimes(1);
|
|
26
|
+
|
|
27
|
+
expect(toJSON()).toMatchSnapshot();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -26,7 +26,7 @@ const StyledActionGroupContainer = styled(Animated.View)<
|
|
|
26
26
|
const StyledFAB = styled(FAB)<{}>`
|
|
27
27
|
margin-right: ${({ theme }) => theme.space.large};
|
|
28
28
|
align-self: flex-end;
|
|
29
|
-
margin-top: ${({ theme }) => theme.space.
|
|
29
|
+
margin-top: ${({ theme }) => theme.space.small};
|
|
30
30
|
`;
|
|
31
31
|
|
|
32
32
|
const StyledBackdrop = styled(Animated.View)<
|