internhub-v2-mobile-ui-kit 0.0.5 → 0.0.7
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/package.json +1 -1
- package/src/Avatar/Avatar.tsx +1 -1
- package/src/BottomSheet/BottomSheet.tsx +50 -0
- package/src/Checkbox/Checkbox.tsx +26 -0
- package/src/Icon/Icon.tsx +22 -0
- package/src/Skeleton/Skeleton.tsx +44 -0
- package/src/Switch/Switch.tsx +32 -0
- package/src/tokens.ts +6 -4
package/package.json
CHANGED
package/src/Avatar/Avatar.tsx
CHANGED
|
@@ -38,7 +38,7 @@ export const Avatar: React.FC<AvatarProps> = ({ source, name, size = 'md', style
|
|
|
38
38
|
|
|
39
39
|
const styles = StyleSheet.create({
|
|
40
40
|
container: {
|
|
41
|
-
backgroundColor: Colors.
|
|
41
|
+
backgroundColor: Colors.neutralBg,
|
|
42
42
|
justifyContent: 'center',
|
|
43
43
|
alignItems: 'center',
|
|
44
44
|
overflow: 'hidden',
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Modal, TouchableOpacity, StyleSheet, Dimensions } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
const { height: SCREEN_HEIGHT } = Dimensions.get('window');
|
|
6
|
+
|
|
7
|
+
interface BottomSheetProps {
|
|
8
|
+
visible: boolean;
|
|
9
|
+
onClose: () => void;
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
height?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const BottomSheet: React.FC<BottomSheetProps> = ({ visible, onClose, children, height = SCREEN_HEIGHT * 0.4 }) => {
|
|
15
|
+
return (
|
|
16
|
+
<Modal visible={visible} transparent animationType="slide" onRequestClose={onClose}>
|
|
17
|
+
<TouchableOpacity style={styles.overlay} activeOpacity={1} onPress={onClose} />
|
|
18
|
+
<View style={[styles.sheet, { height }]}>
|
|
19
|
+
<View style={styles.handle} />
|
|
20
|
+
{children}
|
|
21
|
+
</View>
|
|
22
|
+
</Modal>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const styles = StyleSheet.create({
|
|
27
|
+
overlay: { flex: 1, backgroundColor: Colors.overlay },
|
|
28
|
+
sheet: {
|
|
29
|
+
backgroundColor: Colors.surface,
|
|
30
|
+
borderTopLeftRadius: 20,
|
|
31
|
+
borderTopRightRadius: 20,
|
|
32
|
+
padding: 16,
|
|
33
|
+
bottom: 0,
|
|
34
|
+
position: 'absolute',
|
|
35
|
+
width: '100%',
|
|
36
|
+
shadowColor: Colors.shadowBlack,
|
|
37
|
+
shadowOffset: { width: 0, height: -2 },
|
|
38
|
+
shadowOpacity: 0.1,
|
|
39
|
+
shadowRadius: 10,
|
|
40
|
+
elevation: 20
|
|
41
|
+
},
|
|
42
|
+
handle: {
|
|
43
|
+
width: 40,
|
|
44
|
+
height: 4,
|
|
45
|
+
backgroundColor: Colors.border,
|
|
46
|
+
borderRadius: 2,
|
|
47
|
+
alignSelf: 'center',
|
|
48
|
+
marginBottom: 16
|
|
49
|
+
}
|
|
50
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TouchableOpacity, View, Text, StyleSheet } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
interface CheckboxProps {
|
|
6
|
+
label?: string;
|
|
7
|
+
checked: boolean;
|
|
8
|
+
onChange: (checked: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const Checkbox: React.FC<CheckboxProps> = ({ label, checked, onChange }) => (
|
|
12
|
+
<TouchableOpacity style={styles.container} onPress={() => onChange(!checked)} activeOpacity={0.7}>
|
|
13
|
+
<View style={[styles.box, checked && styles.checked]}>
|
|
14
|
+
{checked && <View style={styles.inner} />}
|
|
15
|
+
</View>
|
|
16
|
+
{label && <Text style={styles.label}>{label}</Text>}
|
|
17
|
+
</TouchableOpacity>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const styles = StyleSheet.create({
|
|
21
|
+
container: { flexDirection: 'row', alignItems: 'center', marginVertical: 8 },
|
|
22
|
+
box: { width: 20, height: 20, borderWidth: 2, borderColor: Colors.primary, borderRadius: 4, justifyContent: 'center', alignItems: 'center', marginRight: 10 },
|
|
23
|
+
checked: { backgroundColor: Colors.primary },
|
|
24
|
+
inner: { width: 10, height: 10, backgroundColor: Colors.white, borderRadius: 1 },
|
|
25
|
+
label: { fontSize: 15, color: Colors.textPrimary },
|
|
26
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Image, ImageStyle, ImageSourcePropType } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
interface IconProps {
|
|
6
|
+
source: ImageSourcePropType;
|
|
7
|
+
size?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
style?: ImageStyle;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Icon: React.FC<IconProps> = ({ source, size = 24, color, style }) => (
|
|
13
|
+
<Image
|
|
14
|
+
source={source}
|
|
15
|
+
style={[
|
|
16
|
+
{ width: size, height: size },
|
|
17
|
+
color ? { tintColor: color } : undefined,
|
|
18
|
+
style
|
|
19
|
+
]}
|
|
20
|
+
resizeMode="contain"
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { View, Animated, StyleSheet, ViewStyle, DimensionValue } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
interface SkeletonProps {
|
|
6
|
+
width?: DimensionValue;
|
|
7
|
+
height?: number;
|
|
8
|
+
borderRadius?: number;
|
|
9
|
+
style?: ViewStyle;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Skeleton: React.FC<SkeletonProps> = ({
|
|
13
|
+
width = '100%',
|
|
14
|
+
height = 20,
|
|
15
|
+
borderRadius = 4,
|
|
16
|
+
style
|
|
17
|
+
}) => {
|
|
18
|
+
const opacity = useRef(new Animated.Value(0.3)).current;
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
Animated.loop(
|
|
22
|
+
Animated.sequence([
|
|
23
|
+
Animated.timing(opacity, { toValue: 0.7, duration: 800, useNativeDriver: true }),
|
|
24
|
+
Animated.timing(opacity, { toValue: 0.3, duration: 800, useNativeDriver: true })
|
|
25
|
+
])
|
|
26
|
+
).start();
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Animated.View
|
|
31
|
+
style={[
|
|
32
|
+
styles.skeleton,
|
|
33
|
+
{ width, height, borderRadius, opacity },
|
|
34
|
+
style
|
|
35
|
+
]}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const styles = StyleSheet.create({
|
|
41
|
+
skeleton: {
|
|
42
|
+
backgroundColor: Colors.border,
|
|
43
|
+
}
|
|
44
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { TouchableOpacity, View, StyleSheet } from 'react-native';
|
|
3
|
+
import { Colors } from '../tokens';
|
|
4
|
+
|
|
5
|
+
interface SwitchProps {
|
|
6
|
+
value: boolean;
|
|
7
|
+
onValueChange: (value: boolean) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const Switch: React.FC<SwitchProps> = ({ value, onValueChange }) => (
|
|
11
|
+
<TouchableOpacity
|
|
12
|
+
activeOpacity={0.8}
|
|
13
|
+
onPress={() => onValueChange(!value)}
|
|
14
|
+
style={[styles.track, { backgroundColor: value ? Colors.success : Colors.borderAlt }]}
|
|
15
|
+
>
|
|
16
|
+
<View style={[styles.thumb, { transform: [{ translateX: value ? 20 : 2 }] }]} />
|
|
17
|
+
</TouchableOpacity>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const styles = StyleSheet.create({
|
|
21
|
+
track: { width: 44, height: 24, borderRadius: 12, justifyContent: 'center' },
|
|
22
|
+
thumb: {
|
|
23
|
+
width: 20,
|
|
24
|
+
height: 20,
|
|
25
|
+
borderRadius: 10,
|
|
26
|
+
backgroundColor: Colors.white,
|
|
27
|
+
shadowColor: Colors.shadowBlack,
|
|
28
|
+
shadowOpacity: 0.2,
|
|
29
|
+
shadowRadius: 2,
|
|
30
|
+
elevation: 2
|
|
31
|
+
},
|
|
32
|
+
});
|
package/src/tokens.ts
CHANGED
|
@@ -37,13 +37,15 @@ export const Colors = {
|
|
|
37
37
|
infoLight: '#E3F2FD',
|
|
38
38
|
|
|
39
39
|
// Special Effects (Glassmorphism)
|
|
40
|
-
shadow: '#E18308',
|
|
40
|
+
shadow: '#E18308', // Brand shadow
|
|
41
|
+
shadowBlack: '#000000', // Natural shadow
|
|
41
42
|
glassWhite: 'rgba(255, 255, 255, 0.9)',
|
|
42
|
-
glassOrange: 'rgba(255, 237, 213, 0.6)',
|
|
43
|
+
glassOrange: 'rgba(255, 237, 213, 0.6)',
|
|
43
44
|
glassBorder: 'rgba(255, 255, 255, 0.8)',
|
|
44
|
-
avatarBg: '#FFF3E0',
|
|
45
45
|
|
|
46
|
-
//
|
|
46
|
+
// Utilities & Overlays
|
|
47
|
+
overlay: 'rgba(0, 0, 0, 0.5)',
|
|
48
|
+
neutralBg: '#FFF3E0', // Was avatarBg
|
|
47
49
|
white: '#FFFFFF',
|
|
48
50
|
black: '#000000',
|
|
49
51
|
inputBackground: '#FFFFFF',
|