internhub-v2-mobile-ui-kit 0.0.7 → 0.0.9
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/README.md +77 -17
- package/package.json +1 -1
- package/src/Alert/Alert.tsx +2 -2
- package/src/Avatar/Avatar.tsx +1 -1
- package/src/Badge/Badge.tsx +1 -1
- package/src/BottomSheet/BottomSheet.tsx +1 -1
- package/src/Button/Button.tsx +5 -5
- package/src/Card/Card.tsx +1 -1
- package/src/Checkbox/Checkbox.tsx +1 -1
- package/src/DatePicker/DatePicker.tsx +0 -0
- package/src/Divider/Divider.tsx +1 -1
- package/src/EmptyState/EmptyState.tsx +2 -2
- package/src/GradientBackground/GradientBackground.tsx +1 -1
- package/src/Header/Header.tsx +69 -0
- package/src/Icon/Icon.tsx +1 -1
- package/src/Input/Input.tsx +1 -1
- package/src/Loading/Loading.tsx +25 -0
- package/src/Modal/Modal.tsx +1 -1
- package/src/OTPInput/OTPInput.tsx +1 -1
- package/src/PasswordChecker/PasswordChecker.tsx +2 -2
- package/src/Select/Select.tsx +1 -1
- package/src/Skeleton/Skeleton.tsx +1 -1
- package/src/Switch/Switch.tsx +1 -1
- package/src/TimePicker/TimePicker.tsx +0 -0
- package/src/Toast/Toast.tsx +0 -0
- package/src/index.ts +1 -1
- package/src/tokens.ts +27 -6
package/README.md
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
# InternHub v2 Mobile UI Kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Premium Design System and UI Components for the InternHub v2 Mobile Application. Provides standardized React Native components and design tokens (colors, typography, spacing) extracted from Figma to ensure visual consistency across the entire application ecosystem.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
To integrate the UI kit into your project, install it via npm or yarn:
|
|
8
|
-
|
|
9
7
|
```bash
|
|
10
8
|
npm install internhub-v2-mobile-ui-kit
|
|
11
9
|
```
|
|
@@ -20,25 +18,30 @@ Ensure the following peer dependencies are installed in your project root:
|
|
|
20
18
|
## Usage
|
|
21
19
|
|
|
22
20
|
### 1. Design Tokens
|
|
23
|
-
The UI kit exposes a comprehensive set of design tokens tailored for the application's theme.
|
|
21
|
+
The UI kit exposes a comprehensive set of design tokens tailored for the application's premium orange theme.
|
|
24
22
|
|
|
25
23
|
```tsx
|
|
26
|
-
import { Colors, Spacing } from 'internhub-v2-mobile-ui-kit';
|
|
24
|
+
import { Colors, Spacing, BorderRadius, FontSize, FontWeight, Shadow } from 'internhub-v2-mobile-ui-kit';
|
|
27
25
|
|
|
28
26
|
const styles = StyleSheet.create({
|
|
29
27
|
container: {
|
|
30
28
|
backgroundColor: Colors.background,
|
|
31
29
|
padding: Spacing.md,
|
|
30
|
+
borderRadius: BorderRadius.lg,
|
|
31
|
+
},
|
|
32
|
+
card: {
|
|
33
|
+
...Shadow.card,
|
|
34
|
+
backgroundColor: Colors.surface,
|
|
32
35
|
},
|
|
33
36
|
primaryText: {
|
|
34
37
|
color: Colors.primary,
|
|
35
|
-
|
|
38
|
+
fontSize: FontSize.lg,
|
|
39
|
+
fontWeight: FontWeight.bold,
|
|
36
40
|
}
|
|
37
41
|
});
|
|
38
42
|
```
|
|
39
43
|
|
|
40
44
|
### 2. Components
|
|
41
|
-
Import components directly from the package. All components adhere to the project's design guidelines.
|
|
42
45
|
|
|
43
46
|
#### Button
|
|
44
47
|
Supported variants: `primary`, `secondary`, `outline`, `ghost`.
|
|
@@ -55,7 +58,7 @@ import { Button } from 'internhub-v2-mobile-ui-kit';
|
|
|
55
58
|
```
|
|
56
59
|
|
|
57
60
|
#### Input Field
|
|
58
|
-
Standard input field with integrated label and
|
|
61
|
+
Standard input field with integrated label, error handling, and password toggle.
|
|
59
62
|
|
|
60
63
|
```tsx
|
|
61
64
|
import { Input } from 'internhub-v2-mobile-ui-kit';
|
|
@@ -66,11 +69,18 @@ import { Input } from 'internhub-v2-mobile-ui-kit';
|
|
|
66
69
|
value={name}
|
|
67
70
|
onChangeText={setName}
|
|
68
71
|
error={errors.name}
|
|
72
|
+
required
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
<Input
|
|
76
|
+
label="Password"
|
|
77
|
+
isPassword
|
|
78
|
+
value={password}
|
|
79
|
+
onChangeText={setPassword}
|
|
69
80
|
/>
|
|
70
81
|
```
|
|
71
82
|
|
|
72
83
|
#### Selection Controls (Checkbox & Switch)
|
|
73
|
-
New in v0.0.4.
|
|
74
84
|
|
|
75
85
|
```tsx
|
|
76
86
|
import { Checkbox, Switch } from 'internhub-v2-mobile-ui-kit';
|
|
@@ -87,18 +97,68 @@ import { Checkbox, Switch } from 'internhub-v2-mobile-ui-kit';
|
|
|
87
97
|
/>
|
|
88
98
|
```
|
|
89
99
|
|
|
100
|
+
#### Badge
|
|
101
|
+
Status indicators with preset color schemes.
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { Badge } from 'internhub-v2-mobile-ui-kit';
|
|
105
|
+
|
|
106
|
+
<Badge label="Approved" type="success" />
|
|
107
|
+
<Badge label="Pending" type="warning" size="md" />
|
|
108
|
+
<Badge label="Rejected" type="error" />
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Avatar
|
|
112
|
+
User avatar with image support and fallback initials.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { Avatar } from 'internhub-v2-mobile-ui-kit';
|
|
116
|
+
|
|
117
|
+
<Avatar name="Nguyen Van A" size="lg" />
|
|
118
|
+
<Avatar source={{ uri: 'https://...' }} size="md" />
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Skeleton Loading
|
|
122
|
+
Animated placeholder for loading states.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
import { Skeleton } from 'internhub-v2-mobile-ui-kit';
|
|
126
|
+
|
|
127
|
+
<Skeleton width="60%" height={16} borderRadius={8} />
|
|
128
|
+
<Skeleton width="100%" height={80} borderRadius={16} />
|
|
129
|
+
```
|
|
130
|
+
|
|
90
131
|
## Component Library
|
|
91
132
|
|
|
92
|
-
| Category | Components | Status |
|
|
93
|
-
|
|
94
|
-
| **Inputs** | Button, Input, Select, Checkbox, Switch, OTPInput, DatePicker, TimePicker | Stable |
|
|
95
|
-
| **Feedback** | Alert, Badge, Toast, Loading, EmptyState, Modal | Stable |
|
|
96
|
-
| **Data Display** | Card, Avatar, Divider, Header | Stable |
|
|
97
|
-
| **Layout** | GradientBackground | Stable |
|
|
133
|
+
| Category | Components | Count | Status |
|
|
134
|
+
|----------|------------|-------|--------|
|
|
135
|
+
| **Inputs & Forms** | Button, Input, Select, Checkbox, Switch, OTPInput, PasswordChecker, DatePicker, TimePicker | 9 | Stable |
|
|
136
|
+
| **Feedback & Status** | Alert, Badge, Toast, Loading, EmptyState, Modal, BottomSheet, Skeleton | 8 | Stable |
|
|
137
|
+
| **Data Display** | Card, Avatar, Divider, Header, Icon | 5 | Stable |
|
|
138
|
+
| **Layout** | GradientBackground | 1 | Stable |
|
|
139
|
+
| **Design Tokens** | Colors, Spacing, BorderRadius, FontSize, FontWeight, Shadow | 6 | Stable |
|
|
140
|
+
|
|
141
|
+
**Total: 23 components + 6 design token sets**
|
|
142
|
+
|
|
143
|
+
## Changelog
|
|
144
|
+
|
|
145
|
+
### v0.0.8 (2026-02-22)
|
|
146
|
+
- Fix Quick Action icons matching Figma design
|
|
147
|
+
- Standardize header spacing across all mini-app screens
|
|
148
|
+
- Add iconCircle style definition
|
|
149
|
+
- Optimize mini-app loading (direct import strategy)
|
|
150
|
+
|
|
151
|
+
### v0.0.7
|
|
152
|
+
- Add Skeleton, BottomSheet, Icon components
|
|
153
|
+
- Add PasswordChecker component
|
|
154
|
+
- Stabilize all component APIs
|
|
98
155
|
|
|
99
|
-
|
|
156
|
+
### v0.0.4
|
|
157
|
+
- Add Checkbox, Switch, Select components
|
|
158
|
+
- Add DatePicker, TimePicker components
|
|
100
159
|
|
|
101
|
-
|
|
160
|
+
### v0.0.1
|
|
161
|
+
- Initial release with Button, Input, Card, Avatar, Badge, Alert, Toast
|
|
102
162
|
|
|
103
163
|
## Authors
|
|
104
164
|
|
package/package.json
CHANGED
package/src/Alert/Alert.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet } from 'react-native';
|
|
3
3
|
import { Colors, Spacing, FontSize, BorderRadius } from '../tokens';
|
|
4
4
|
|
|
@@ -20,7 +20,7 @@ export const Alert = ({ type, message, subMessage }: AlertProps) => {
|
|
|
20
20
|
case 'error':
|
|
21
21
|
return {
|
|
22
22
|
container: styles.errorContainer,
|
|
23
|
-
icon: '
|
|
23
|
+
icon: '!',
|
|
24
24
|
iconStyle: styles.errorIcon,
|
|
25
25
|
};
|
|
26
26
|
case 'warning':
|
package/src/Avatar/Avatar.tsx
CHANGED
package/src/Badge/Badge.tsx
CHANGED
package/src/Button/Button.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import {
|
|
3
3
|
TouchableOpacity,
|
|
4
4
|
Text,
|
|
@@ -69,7 +69,7 @@ export const Button = ({
|
|
|
69
69
|
activeOpacity={0.85}>
|
|
70
70
|
{loading ? (
|
|
71
71
|
<ActivityIndicator
|
|
72
|
-
color={variant === 'outline' ?
|
|
72
|
+
color={variant === 'outline' ? Colors.primary : Colors.textLight}
|
|
73
73
|
/>
|
|
74
74
|
) : (
|
|
75
75
|
<Text style={[styles.text, getTextStyle()]}>{title}</Text>
|
|
@@ -88,8 +88,8 @@ const styles = StyleSheet.create({
|
|
|
88
88
|
minHeight: 52,
|
|
89
89
|
},
|
|
90
90
|
buttonPrimary: {
|
|
91
|
-
backgroundColor:
|
|
92
|
-
shadowColor:
|
|
91
|
+
backgroundColor: Colors.primary,
|
|
92
|
+
shadowColor: Colors.primary,
|
|
93
93
|
shadowOffset: { width: 0, height: 4 },
|
|
94
94
|
shadowOpacity: 0.3,
|
|
95
95
|
shadowRadius: 8,
|
|
@@ -128,7 +128,7 @@ const styles = StyleSheet.create({
|
|
|
128
128
|
color: '#757575',
|
|
129
129
|
},
|
|
130
130
|
textGhost: {
|
|
131
|
-
color:
|
|
131
|
+
color: Colors.primary,
|
|
132
132
|
},
|
|
133
133
|
textDisabled: {
|
|
134
134
|
color: '#9E9E9E',
|
package/src/Card/Card.tsx
CHANGED
|
Binary file
|
package/src/Divider/Divider.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, Image, ImageSourcePropType, ViewStyle } from 'react-native';
|
|
3
3
|
import { Colors } from '../tokens';
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ export const EmptyState: React.FC<EmptyStateProps> = ({
|
|
|
21
21
|
{image ? (
|
|
22
22
|
<Image source={image} style={styles.image} resizeMode="contain" />
|
|
23
23
|
) : (
|
|
24
|
-
<Text style={styles.icon}
|
|
24
|
+
<Text style={styles.icon}>📋</Text>
|
|
25
25
|
)}
|
|
26
26
|
</View>
|
|
27
27
|
{title && <Text style={styles.title}>{title}</Text>}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text, TouchableOpacity, StyleSheet, ViewStyle } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
interface HeaderProps {
|
|
6
|
+
title: string;
|
|
7
|
+
onBack?: () => void;
|
|
8
|
+
rightElement?: React.ReactNode;
|
|
9
|
+
style?: ViewStyle;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Header: React.FC<HeaderProps> = ({ title, onBack, rightElement, style }) => {
|
|
13
|
+
return (
|
|
14
|
+
<View style={[styles.container, style]}>
|
|
15
|
+
<View style={styles.leftContainer}>
|
|
16
|
+
{onBack && (
|
|
17
|
+
<TouchableOpacity onPress={onBack} style={styles.backButton}>
|
|
18
|
+
<View style={styles.backIcon} />
|
|
19
|
+
</TouchableOpacity>
|
|
20
|
+
)}
|
|
21
|
+
</View>
|
|
22
|
+
<Text style={styles.title} numberOfLines={1}>{title}</Text>
|
|
23
|
+
<View style={styles.rightContainer}>
|
|
24
|
+
{rightElement}
|
|
25
|
+
</View>
|
|
26
|
+
</View>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const styles = StyleSheet.create({
|
|
31
|
+
container: {
|
|
32
|
+
height: 56,
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
justifyContent: 'space-between',
|
|
36
|
+
paddingHorizontal: 16,
|
|
37
|
+
backgroundColor: Colors.white,
|
|
38
|
+
borderBottomWidth: 1,
|
|
39
|
+
borderBottomColor: Colors.divider,
|
|
40
|
+
},
|
|
41
|
+
leftContainer: {
|
|
42
|
+
width: 40,
|
|
43
|
+
height: 40,
|
|
44
|
+
justifyContent: 'center',
|
|
45
|
+
},
|
|
46
|
+
title: {
|
|
47
|
+
flex: 1,
|
|
48
|
+
textAlign: 'center',
|
|
49
|
+
fontSize: 18,
|
|
50
|
+
fontWeight: 'bold',
|
|
51
|
+
color: Colors.textDark,
|
|
52
|
+
},
|
|
53
|
+
rightContainer: {
|
|
54
|
+
width: 40,
|
|
55
|
+
alignItems: 'flex-end',
|
|
56
|
+
justifyContent: 'center',
|
|
57
|
+
},
|
|
58
|
+
backButton: {
|
|
59
|
+
padding: 8,
|
|
60
|
+
},
|
|
61
|
+
backIcon: {
|
|
62
|
+
width: 12,
|
|
63
|
+
height: 12,
|
|
64
|
+
borderLeftWidth: 2,
|
|
65
|
+
borderBottomWidth: 2,
|
|
66
|
+
borderColor: Colors.textDark,
|
|
67
|
+
transform: [{ rotate: '45deg' }],
|
|
68
|
+
},
|
|
69
|
+
});
|
package/src/Icon/Icon.tsx
CHANGED
package/src/Input/Input.tsx
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, ActivityIndicator, StyleSheet, ColorValue } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
interface LoadingProps {
|
|
6
|
+
color?: ColorValue;
|
|
7
|
+
size?: 'small' | 'large';
|
|
8
|
+
style?: any;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Loading: React.FC<LoadingProps> = ({ color = Colors.primary, size = 'large', style }) => {
|
|
12
|
+
return (
|
|
13
|
+
<View style={[styles.container, style]}>
|
|
14
|
+
<ActivityIndicator color={color} size={size} />
|
|
15
|
+
</View>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const styles = StyleSheet.create({
|
|
20
|
+
container: {
|
|
21
|
+
flex: 1,
|
|
22
|
+
justifyContent: 'center',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
},
|
|
25
|
+
});
|
package/src/Modal/Modal.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet } from 'react-native';
|
|
3
3
|
import { Colors, Spacing, FontSize } from '../tokens';
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ export const PasswordChecker = ({ requirements }: PasswordCheckerProps) => {
|
|
|
21
21
|
styles.checkbox,
|
|
22
22
|
req.isValid ? styles.checkboxValid : styles.checkboxInvalid,
|
|
23
23
|
]}>
|
|
24
|
-
{req.isValid && <Text style={styles.checkmark}
|
|
24
|
+
{req.isValid && <Text style={styles.checkmark}>✓</Text>}
|
|
25
25
|
</View>
|
|
26
26
|
<Text
|
|
27
27
|
style={[
|
package/src/Select/Select.tsx
CHANGED
package/src/Switch/Switch.tsx
CHANGED
|
Binary file
|
package/src/Toast/Toast.tsx
CHANGED
|
Binary file
|
package/src/index.ts
CHANGED
package/src/tokens.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
// Design Tokens - Extracted from Figma
|
|
1
|
+
// Design Tokens - Extracted from Figma
|
|
2
2
|
export const Colors = {
|
|
3
3
|
// Brand - Premium Orange
|
|
4
|
-
primary: '#
|
|
5
|
-
primaryDark: '#
|
|
4
|
+
primary: '#C36F06', // Main Brand Color - Matched with Login Title
|
|
5
|
+
primaryDark: '#A35D05',
|
|
6
6
|
primaryLight: '#FF9800',
|
|
7
7
|
secondary: '#FF9800', // Brighter Orange for accents
|
|
8
|
+
secondaryDark: '#B86500', // Darker Orange for headers
|
|
8
9
|
|
|
9
10
|
// Backgrounds - Soft Cream & Glass
|
|
10
11
|
background: '#FFF9F0', // Cream Background
|
|
12
|
+
backgroundAlt: '#FFF8F0', // Slightly warmer cream
|
|
11
13
|
surface: '#FFFFFF', // Pure White
|
|
12
14
|
surfaceAlt: '#FFFBF5', // Soft Cream Surface
|
|
13
15
|
|
|
@@ -21,33 +23,52 @@ export const Colors = {
|
|
|
21
23
|
textMuted: '#8A9499',
|
|
22
24
|
textDisabled: '#BDBDBD',
|
|
23
25
|
|
|
24
|
-
// Borders
|
|
26
|
+
// Borders & Dividers
|
|
25
27
|
border: '#FFE0B2',
|
|
26
28
|
borderAlt: 'rgba(0, 0, 0, 0.08)',
|
|
27
29
|
inputBorder: '#E0E0E0',
|
|
30
|
+
divider: '#F5F5F5', // Light divider line
|
|
31
|
+
attendanceBorder: '#CCCCCC', // Neutral border for calendar
|
|
28
32
|
|
|
29
33
|
// Functionals
|
|
30
34
|
success: '#4CAF50',
|
|
31
35
|
successLight: '#E8F5E9',
|
|
36
|
+
successMint: '#99D8B1', // Mint green for attendance
|
|
32
37
|
error: '#F44336',
|
|
38
|
+
errorDark: '#E1251B', // Darker red
|
|
33
39
|
errorLight: '#FFEBEE',
|
|
40
|
+
errorPink: '#FFE4E1', // Light pink bg for error icons
|
|
34
41
|
warning: '#FFC107',
|
|
35
42
|
warningLight: '#FFF8E1',
|
|
36
43
|
info: '#2196F3',
|
|
37
44
|
infoLight: '#E3F2FD',
|
|
45
|
+
disabled: '#BDBDBD', // Disabled state
|
|
46
|
+
lateRed: '#FF3B30', // iOS-style red for late status
|
|
38
47
|
|
|
39
48
|
// Special Effects (Glassmorphism)
|
|
40
49
|
shadow: '#E18308', // Brand shadow
|
|
41
50
|
shadowBlack: '#000000', // Natural shadow
|
|
42
51
|
glassWhite: 'rgba(255, 255, 255, 0.9)',
|
|
52
|
+
glassWhiteWarm: 'rgba(255, 250, 240, 0.92)', // Warmer glass
|
|
43
53
|
glassOrange: 'rgba(255, 237, 213, 0.6)',
|
|
44
54
|
glassBorder: 'rgba(255, 255, 255, 0.8)',
|
|
55
|
+
orangeShadow: 'rgba(225, 131, 8, 0.4)', // Orange glow shadow
|
|
56
|
+
transparentCam: 'rgba(225, 131, 8, 0.05)', // Very subtle orange bg
|
|
45
57
|
|
|
46
|
-
//
|
|
58
|
+
// Gradient & Glow
|
|
59
|
+
glowStart: '#FFE4C4', // Gradient start
|
|
60
|
+
glowMid: '#FFECD2', // Gradient mid
|
|
61
|
+
|
|
62
|
+
// Neutral & Utility
|
|
47
63
|
overlay: 'rgba(0, 0, 0, 0.5)',
|
|
48
|
-
neutralBg: '#FFF3E0', //
|
|
64
|
+
neutralBg: '#FFF3E0', // Neutral warm bg (avatar, etc.)
|
|
65
|
+
avatarBg: '#FFF3E0', // Avatar background (alias of neutralBg)
|
|
49
66
|
white: '#FFFFFF',
|
|
50
67
|
black: '#000000',
|
|
68
|
+
offWhite: '#F9F9F9', // Slightly off-white
|
|
69
|
+
lightGray: '#F5F5F5', // Light gray bg
|
|
70
|
+
placeholderGray: '#E9EEF1', // Placeholder/skeleton bg
|
|
71
|
+
mutedGray: '#A0B2C1', // Muted cool gray
|
|
51
72
|
inputBackground: '#FFFFFF',
|
|
52
73
|
cardBackground: '#FFFFFF',
|
|
53
74
|
transparent: 'transparent',
|