@teamnhz/rn-ui-toolkit 1.0.0 → 1.0.1
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 +206 -0
- package/dist/components/AppHeader/index.d.ts +17 -0
- package/dist/components/AppHeader/index.js +47 -0
- package/dist/components/DocumentPicker/index.d.ts +2 -2
- package/dist/components/DocumentPicker/index.js +2 -2
- package/dist/components/Input/index.js +4 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/styles/index.d.ts +1 -1
- package/package.json +2 -1
package/README.md
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# @teamnhz/rn-ui-toolkit
|
|
2
|
+
|
|
3
|
+
A customizable **React Native UI Toolkit** containing prebuilt components like **Buttons, Typography (T), Input, CheckBox, RadioButton, DocumentPicker, ImagePicker, DropDown, Toast, Dividers, Accordion, Modal, VStack, and HStack**.
|
|
4
|
+
This toolkit helps you build consistent, reusable, and modern UI components for your React Native applications. 🚀
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📦 Installation
|
|
9
|
+
|
|
10
|
+
Install via **npm** or **yarn**:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Using npm
|
|
14
|
+
npm install @teamnhz/rn-ui-toolkit
|
|
15
|
+
|
|
16
|
+
# Using yarn
|
|
17
|
+
yarn add @teamnhz/rn-ui-toolkit
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🚀 Quick Usage
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import React, { useState } from "react";
|
|
26
|
+
import { View, ScrollView, Alert, StyleSheet, Image } from "react-native";
|
|
27
|
+
import {
|
|
28
|
+
Buttons,
|
|
29
|
+
T,
|
|
30
|
+
Input,
|
|
31
|
+
CheckBox,
|
|
32
|
+
RadioButton,
|
|
33
|
+
DocumentPicker,
|
|
34
|
+
ImagePicker,
|
|
35
|
+
Toast,
|
|
36
|
+
DropDown,
|
|
37
|
+
Dividers,
|
|
38
|
+
Accordion,
|
|
39
|
+
Modal,
|
|
40
|
+
VStack,
|
|
41
|
+
HStack,
|
|
42
|
+
HorizontalFlatList,
|
|
43
|
+
AppHeader,
|
|
44
|
+
} from "@teamnhz/rn-ui-toolkit";
|
|
45
|
+
|
|
46
|
+
export default function App() {
|
|
47
|
+
const [name, setName] = useState("");
|
|
48
|
+
const [accepted, setAccepted] = useState(false);
|
|
49
|
+
const [selected, setSelected] = useState("option1");
|
|
50
|
+
const [visible, setVisible] = useState(false);
|
|
51
|
+
|
|
52
|
+
const close = () => setVisible(!visible);
|
|
53
|
+
|
|
54
|
+
const categories: any = [
|
|
55
|
+
{ id: 1, name: "Man Shirt", image: "https://img.icons8.com/ios/100/shirt.png" },
|
|
56
|
+
{ id: 2, name: "Dress", image: "https://img.icons8.com/ios/100/shirt.png" },
|
|
57
|
+
{ id: 3, name: "Work Equipment", image: "https://img.icons8.com/ios/100/briefcase.png" },
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
const dropdownData = [
|
|
61
|
+
{ label: "United States", value: "United States" },
|
|
62
|
+
{ label: "United Kingdom", value: "United Kingdom" },
|
|
63
|
+
{ label: "Afghanistan", value: "Afghanistan" },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<ScrollView contentContainerStyle={{ padding: 20 }}>
|
|
68
|
+
{/* Typography */}
|
|
69
|
+
<T size="xl" weight="bold">Welcome to RN UI Toolkit 🚀</T>
|
|
70
|
+
|
|
71
|
+
{/* Input */}
|
|
72
|
+
<Input placeholder="Enter your name" value={name} onChangeText={setName} />
|
|
73
|
+
|
|
74
|
+
{/* Checkbox */}
|
|
75
|
+
<CheckBox label="Accept Terms" checked={accepted} onChange={setAccepted} />
|
|
76
|
+
|
|
77
|
+
{/* Radio Buttons */}
|
|
78
|
+
<RadioButton label="Option 1" selected={selected === "option1"} onPress={() => setSelected("option1")} />
|
|
79
|
+
<RadioButton label="Option 2" selected={selected === "option2"} onPress={() => setSelected("option2")} />
|
|
80
|
+
|
|
81
|
+
{/* Document Picker */}
|
|
82
|
+
<DocumentPicker onPick={(docs) => Alert.alert("Docs", JSON.stringify(docs))} />
|
|
83
|
+
|
|
84
|
+
{/* Image Picker */}
|
|
85
|
+
<ImagePicker mediaType="photo" onPick={(img) => Alert.alert("Image", JSON.stringify(img))} />
|
|
86
|
+
|
|
87
|
+
{/* Button */}
|
|
88
|
+
<Buttons title="Submit" onPress={() => Alert.alert("Submitted", `Name: ${name}`)} />
|
|
89
|
+
|
|
90
|
+
{/* Divider */}
|
|
91
|
+
<Dividers small />
|
|
92
|
+
|
|
93
|
+
{/* DropDown */}
|
|
94
|
+
<DropDown
|
|
95
|
+
value={"United States"}
|
|
96
|
+
data={dropdownData}
|
|
97
|
+
onChange={(item) => console.log("Selected:", item.value)}
|
|
98
|
+
/>
|
|
99
|
+
|
|
100
|
+
{/* Toast */}
|
|
101
|
+
<Toast visible={true} message="Welcome to the toolkit!" />
|
|
102
|
+
|
|
103
|
+
{/* Accordion */}
|
|
104
|
+
<Accordion title="Profile Info" initiallyExpanded>
|
|
105
|
+
<T title="Name: John Doe" />
|
|
106
|
+
<T title="Email: john@example.com" />
|
|
107
|
+
</Accordion>
|
|
108
|
+
|
|
109
|
+
<Accordion title="Settings" showIcon>
|
|
110
|
+
<T title="🔔 Notifications: Enabled" />
|
|
111
|
+
<T title="🌙 Dark Mode: Off" />
|
|
112
|
+
</Accordion>
|
|
113
|
+
|
|
114
|
+
{/* Modal Example */}
|
|
115
|
+
<Buttons title="Open Modal" onPress={() => setVisible(true)} />
|
|
116
|
+
<Modal visible={visible} onClose={close}>
|
|
117
|
+
<T size="lg">This is a modal content 🎉</T>
|
|
118
|
+
<Buttons title="Close" onPress={close} />
|
|
119
|
+
</Modal>
|
|
120
|
+
|
|
121
|
+
{/* VStack (Vertical Layout) */}
|
|
122
|
+
<VStack spacing={12}>
|
|
123
|
+
<T size="lg">This is VStack</T>
|
|
124
|
+
<Buttons title="Button 1" onPress={() => {}} />
|
|
125
|
+
<Buttons title="Button 2" onPress={() => {}} />
|
|
126
|
+
</VStack>
|
|
127
|
+
|
|
128
|
+
{/* HStack (Horizontal Layout) */}
|
|
129
|
+
<HStack spacing={16}>
|
|
130
|
+
<Buttons title="Yes" onPress={() => {}} />
|
|
131
|
+
<Buttons title="No" onPress={() => {}} />
|
|
132
|
+
</HStack>
|
|
133
|
+
|
|
134
|
+
{/* Horizontal FlatList */}
|
|
135
|
+
<HorizontalFlatList
|
|
136
|
+
horizontal
|
|
137
|
+
data={categories}
|
|
138
|
+
keyExtractor={(item) => item.id.toString()}
|
|
139
|
+
renderItem={({ item }) => (
|
|
140
|
+
<View style={styles.item}>
|
|
141
|
+
<Image source={{ uri: item.image }} style={styles.image} />
|
|
142
|
+
<T>{item.name}</T>
|
|
143
|
+
</View>
|
|
144
|
+
)}
|
|
145
|
+
/>
|
|
146
|
+
|
|
147
|
+
{/* App Header */}
|
|
148
|
+
<AppHeader title="Header" onLeftPress={() => Alert.alert("Back pressed")} />
|
|
149
|
+
</ScrollView>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const styles = StyleSheet.create({
|
|
154
|
+
image: { width: 60, height: 60, marginRight: 10 },
|
|
155
|
+
item: { alignItems: "center", marginRight: 15 },
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## ⚙️ Android Permissions
|
|
162
|
+
|
|
163
|
+
Required for **ImagePicker** and **DocumentPicker**:
|
|
164
|
+
|
|
165
|
+
```xml
|
|
166
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
167
|
+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
|
168
|
+
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
|
169
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
170
|
+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
|
171
|
+
<uses-permission android:name="android.permission.CAMERA"/>
|
|
172
|
+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
173
|
+
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 📚 Components Overview
|
|
179
|
+
|
|
180
|
+
- **Typography (T)** → Consistent text styles.
|
|
181
|
+
- **Input** → Styled text input field.
|
|
182
|
+
- **Buttons** → Primary action button.
|
|
183
|
+
- **CheckBox** → Toggle for true/false.
|
|
184
|
+
- **RadioButton** → Choose between options.
|
|
185
|
+
- **DocumentPicker** → Select and upload documents.
|
|
186
|
+
- **ImagePicker** → Select single/multiple images.
|
|
187
|
+
- **Toast** → Show quick messages.
|
|
188
|
+
- **DropDown** → Select from a list.
|
|
189
|
+
- **Dividers** → Spacing/separator lines.
|
|
190
|
+
- **Accordion** → Expandable/collapsible sections.
|
|
191
|
+
- **Modal** → Popup dialog.
|
|
192
|
+
- **VStack / HStack** → Easy vertical/horizontal layout wrappers.
|
|
193
|
+
- **HorizontalFlatList** → Prebuilt horizontal list with custom render support.
|
|
194
|
+
- **AppHeader** → Customizable header with back/extra icons.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 🤝 Contribution
|
|
199
|
+
|
|
200
|
+
Feel free to open issues and submit PRs to improve this toolkit!
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 📄 License
|
|
205
|
+
|
|
206
|
+
MIT © 2025 [Team NHZ]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyleProp, ViewStyle, TextStyle } from "react-native";
|
|
3
|
+
type Props = {
|
|
4
|
+
title?: string;
|
|
5
|
+
leftIcon?: string;
|
|
6
|
+
onLeftPress?: () => void;
|
|
7
|
+
onDrawerPress?: () => void;
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
isDrawer?: boolean;
|
|
10
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
11
|
+
titleStyle?: StyleProp<TextStyle>;
|
|
12
|
+
leftContainerStyle?: StyleProp<ViewStyle>;
|
|
13
|
+
rightContainerStyle?: StyleProp<ViewStyle>;
|
|
14
|
+
iconStyle?: StyleProp<ViewStyle>;
|
|
15
|
+
};
|
|
16
|
+
declare const AppHeader: React.FC<Props>;
|
|
17
|
+
export default AppHeader;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/components/AppHeader.tsx
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { View, Text, TouchableOpacity, StyleSheet, } from "react-native";
|
|
4
|
+
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
|
5
|
+
const AppHeader = ({ title, leftIcon, onLeftPress, onDrawerPress, children, containerStyle, titleStyle, leftContainerStyle, rightContainerStyle, iconStyle, isDrawer, }) => {
|
|
6
|
+
return (React.createElement(View, { style: [styles.container, containerStyle] },
|
|
7
|
+
React.createElement(View, { style: [styles.leftContainer, leftContainerStyle] },
|
|
8
|
+
isDrawer && (React.createElement(TouchableOpacity, { style: [styles.iconBtn, iconStyle], onPress: onDrawerPress },
|
|
9
|
+
React.createElement(Icon, { name: "menu", size: 24, color: "#000" }))),
|
|
10
|
+
leftIcon && (React.createElement(TouchableOpacity, { style: [styles.iconBtn, iconStyle], onPress: onLeftPress },
|
|
11
|
+
React.createElement(Icon, { name: leftIcon, size: 24, color: "#000" }))),
|
|
12
|
+
title && (React.createElement(Text, { style: [styles.title, titleStyle], numberOfLines: 1 }, title))),
|
|
13
|
+
React.createElement(View, { style: [styles.rightContainer, rightContainerStyle] }, children)));
|
|
14
|
+
};
|
|
15
|
+
export default AppHeader;
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
container: {
|
|
18
|
+
height: 56,
|
|
19
|
+
flexDirection: "row",
|
|
20
|
+
alignItems: "center",
|
|
21
|
+
justifyContent: "space-between",
|
|
22
|
+
shadowColor: "#000",
|
|
23
|
+
shadowOpacity: 0.1,
|
|
24
|
+
shadowOffset: { width: 0, height: 2 },
|
|
25
|
+
shadowRadius: 4,
|
|
26
|
+
paddingHorizontal: 8,
|
|
27
|
+
},
|
|
28
|
+
leftContainer: {
|
|
29
|
+
flexDirection: "row",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
flexShrink: 1,
|
|
32
|
+
},
|
|
33
|
+
iconBtn: {
|
|
34
|
+
padding: 8,
|
|
35
|
+
marginRight: 5,
|
|
36
|
+
},
|
|
37
|
+
title: {
|
|
38
|
+
fontSize: 18,
|
|
39
|
+
fontWeight: "600",
|
|
40
|
+
color: "#000",
|
|
41
|
+
marginLeft: 5,
|
|
42
|
+
},
|
|
43
|
+
rightContainer: {
|
|
44
|
+
flexDirection: "row",
|
|
45
|
+
alignItems: "center",
|
|
46
|
+
},
|
|
47
|
+
});
|
|
@@ -12,5 +12,5 @@ interface AppDocumentPickerProps {
|
|
|
12
12
|
iconStyle?: StyleProp<ViewStyle>;
|
|
13
13
|
renderContent?: () => React.ReactNode;
|
|
14
14
|
}
|
|
15
|
-
declare const
|
|
16
|
-
export default
|
|
15
|
+
declare const DocumentPicker: React.FC<AppDocumentPickerProps>;
|
|
16
|
+
export default DocumentPicker;
|
|
@@ -4,7 +4,7 @@ import * as DocumentPickerLib from '@react-native-documents/picker';
|
|
|
4
4
|
import { requestDocumentPermission } from '../../utils/permissions';
|
|
5
5
|
import { Colors } from '../../styles';
|
|
6
6
|
import Image from '../Image';
|
|
7
|
-
const
|
|
7
|
+
const DocumentPicker = ({ label = 'Upload File', icon = require('../../assets/images/upload.png'), onPick, disabled = false, containerStyle, labelStyle, iconStyle, iconColor = Colors.primaryColor, renderContent, }) => {
|
|
8
8
|
const [selectedFile, setSelectedFile] = useState(null);
|
|
9
9
|
const handlePick = async () => {
|
|
10
10
|
const granted = await requestDocumentPermission();
|
|
@@ -29,7 +29,7 @@ const AppDocumentPicker = ({ label = 'Upload File', icon = require('../../assets
|
|
|
29
29
|
selectedFile ? (React.createElement(Image, { source: { uri: selectedFile.uri }, style: [styles.fileIcon, iconStyle], resizeMode: "contain" })) : (React.createElement(Image, { source: icon, style: [{ width: 20, height: 20 }, iconStyle], tintColor: iconColor, resizeMode: "contain" })),
|
|
30
30
|
React.createElement(Text, { style: [styles.label, labelStyle] }, selectedFile ? selectedFile.name || 'Uploaded File' : label)))));
|
|
31
31
|
};
|
|
32
|
-
export default
|
|
32
|
+
export default DocumentPicker;
|
|
33
33
|
const styles = StyleSheet.create({
|
|
34
34
|
container: {
|
|
35
35
|
flexDirection: 'row',
|
|
@@ -64,6 +64,7 @@ const Input = ({ intlType, textKey, placeholder, leftIcon, rightIcon, onLeftIcon
|
|
|
64
64
|
styles.container,
|
|
65
65
|
disabled && styles.disabled,
|
|
66
66
|
!!showError && styles.errorBorder,
|
|
67
|
+
isFocused && styles.focusedBorder,
|
|
67
68
|
style,
|
|
68
69
|
] },
|
|
69
70
|
leftIcon && (React.createElement(TouchableOpacity, { onPress: onLeftIconPress, disabled: !onLeftIconPress, style: styles.iconWrapper },
|
|
@@ -86,6 +87,9 @@ const styles = StyleSheet.create({
|
|
|
86
87
|
height: Scale.moderateScale(50),
|
|
87
88
|
paddingHorizontal: Scale.moderateScale(10),
|
|
88
89
|
},
|
|
90
|
+
focusedBorder: {
|
|
91
|
+
borderColor: Colors.primaryColor,
|
|
92
|
+
},
|
|
89
93
|
input: {
|
|
90
94
|
flex: 1,
|
|
91
95
|
...Typography.style.standardU(),
|
|
@@ -26,3 +26,4 @@ export { default as BottomSheet } from './BottomSheet';
|
|
|
26
26
|
export { default as ProgressBar } from './ProgressBar';
|
|
27
27
|
export { default as DocumentPicker } from './DocumentPicker';
|
|
28
28
|
export { default as ImagePicker } from './ImagePicker';
|
|
29
|
+
export { default as AppHeader } from './AppHeader';
|
package/dist/components/index.js
CHANGED
|
@@ -26,3 +26,4 @@ export { default as BottomSheet } from './BottomSheet';
|
|
|
26
26
|
export { default as ProgressBar } from './ProgressBar';
|
|
27
27
|
export { default as DocumentPicker } from './DocumentPicker';
|
|
28
28
|
export { default as ImagePicker } from './ImagePicker';
|
|
29
|
+
export { default as AppHeader } from './AppHeader';
|
package/dist/styles/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ import Images from './images';
|
|
|
3
3
|
import * as Scale from './scale';
|
|
4
4
|
import Typography from './typography';
|
|
5
5
|
import * as Mixins from './mixins';
|
|
6
|
-
declare const Icon:
|
|
6
|
+
declare const Icon: any;
|
|
7
7
|
export { Colors, Images, Scale, Typography, Icon, Mixins };
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teamnhz/rn-ui-toolkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": ["dist"],
|
|
7
|
+
"license": "MIT",
|
|
7
8
|
"scripts": {
|
|
8
9
|
"build": "tsc && cpx \"src/**/*.json\" dist && cpx \"src/assets/images/*\" dist/assets/images",
|
|
9
10
|
"prepare": "npm run build"
|