@wereform/pkgm-shared 1.0.0 → 1.0.2

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 CHANGED
@@ -1,30 +1,294 @@
1
1
  # @begenone/pkgm-shared
2
2
 
3
- This is the **shared utility and components** package used across all BEGENONE modules.
3
+ Shared UI components and utilities for the BEGENONE / WeReform ecosystem.
4
4
 
5
- ## Overview
5
+ This package contains reusable, design-system–level building blocks used across mobile and web experiences. It includes buttons, inputs, dropdowns, headers, menus, metadata components, and small utilities that standardize interaction and presentation across the platform.
6
6
 
7
- It holds **reusable code** that needs to be accessed from multiple packages — reducing duplication and ensuring consistent logic.
7
+ ---
8
8
 
9
- ## Contents
9
+ ## Install
10
10
 
11
- - 🧩 UI components (buttons, cards, loaders)
12
- - 🔁 Utility functions (formatting, parsing, validators)
13
- - 🔐 Auth context & hooks
14
- - 🌐 API layer helpers
11
+ ```bash
12
+ npm install @begenone/pkgm-shared
13
+ # or
14
+ yarn add @begenone/pkgm-shared
15
+ # or
16
+ pnpm add @begenone/pkgm-shared
17
+ ```
15
18
 
16
- ## Features
19
+ ---
17
20
 
18
- - Single source of truth for design components
19
- - Shared logic between channel, video, wire, and settings packages
20
- - Centralized error and logging utilities
21
+ ## What this package gives you
21
22
 
22
- ## Usage
23
+ - Core UI components:
23
24
 
24
- Imported by all other packages that require consistent behavior or style.
25
+ - Customizable buttons
26
+ - Input fields and comment inputs
27
+ - Dropdown selector
28
+ - Global header
29
+ - Navigation menus
30
+ - Interaction menus
31
+ - Channel metadata blocks
32
+ - Title and date/views helpers
25
33
 
26
- ## Tech Stack
34
+ - Utilities:
27
35
 
28
- - React + React Native
29
- - TypeScript
30
- - React Context & Hooks
36
+ - URL normalization helper
37
+
38
+ - Built for:
39
+
40
+ - React Native / Expo
41
+ - Mobile-first layouts
42
+ - Reuse across multiple packages (`pkgm-channel`, `pkgm-settings`, etc.)
43
+
44
+ ---
45
+
46
+ ## Exports
47
+
48
+ From `@begenone/pkgm-shared` you can import:
49
+
50
+ ```ts
51
+ import {
52
+ CustomizedButton,
53
+ DropDown,
54
+ InputField,
55
+ InputComment,
56
+ HeaderGlobal,
57
+ MenuNav,
58
+ MenuInteraction,
59
+ MenuChannelMeta,
60
+ CustomizedTitle,
61
+ DateViews,
62
+ normalizeUrl,
63
+ } from "@begenone/pkgm-shared";
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Core components
69
+
70
+ ## CustomizedButton
71
+
72
+ Highly flexible button component with press feedback and optional icons.
73
+
74
+ ### Props
75
+
76
+ ```ts
77
+ CustomizedButton({
78
+ label,
79
+ onPress,
80
+ onPressStyle,
81
+ textColor,
82
+ fontSize,
83
+ fontFamily,
84
+ fontWeight,
85
+ customIcon,
86
+ style,
87
+ isDisabled,
88
+ });
89
+ ```
90
+
91
+ - Supports press-in visual feedback
92
+ - Allows custom icons and typography
93
+ - Gracefully warns if required props are missing
94
+
95
+ ---
96
+
97
+ ## InputField
98
+
99
+ Reusable text input component with icon support and multiline handling.
100
+
101
+ ### Props
102
+
103
+ ```ts
104
+ InputField({
105
+ placeholder,
106
+ error,
107
+ iconLeft,
108
+ iconRight,
109
+ onIconPress,
110
+ iconRightColor,
111
+ inputStyle,
112
+ inputWrapper,
113
+ multiline,
114
+ onChangeText,
115
+ isEditable,
116
+ secureTextEntry,
117
+ });
118
+ ```
119
+
120
+ - Uses Inter font via Expo
121
+ - Supports left and right icons
122
+ - Handles single-line and multi-line inputs
123
+
124
+ ---
125
+
126
+ ## DropDown
127
+
128
+ Modal-based dropdown selector built on `react-native-modal-selector`.
129
+
130
+ ### Props
131
+
132
+ ```ts
133
+ DropDown({
134
+ selectText,
135
+ data,
136
+ styles,
137
+ iconStyles,
138
+ });
139
+ ```
140
+
141
+ - Displays label-based selections
142
+ - Fully stylable container and icon
143
+
144
+ ---
145
+
146
+ ## HeaderGlobal
147
+
148
+ Top-level header with brand logo and action icons.
149
+
150
+ ```ts
151
+ HeaderGlobal({
152
+ aiIcon,
153
+ notificationIcon,
154
+ searchIcon,
155
+ });
156
+ ```
157
+
158
+ ---
159
+
160
+ ## MenuNav
161
+
162
+ Bottom or primary navigation bar component.
163
+
164
+ ```ts
165
+ MenuNav({
166
+ homeIcon,
167
+ wireIcon,
168
+ uploadIcon,
169
+ channelIcon,
170
+ profileIcon,
171
+ onPressHome,
172
+ onPressWire,
173
+ onPressUpload,
174
+ onPressChannel,
175
+ onPressProfile,
176
+ });
177
+ ```
178
+
179
+ ---
180
+
181
+ ## MenuInteraction
182
+
183
+ Interaction menu for content actions such as share, comment, repost, like, and dislike.
184
+
185
+ ```ts
186
+ MenuInteraction({
187
+ containerStyles,
188
+ columnMainIconStyles,
189
+ pressed,
190
+ });
191
+ ```
192
+
193
+ ---
194
+
195
+ ## MenuChannelMeta
196
+
197
+ Displays channel metadata including logo, username, subscriber count, and subscribe action.
198
+
199
+ ```ts
200
+ MenuChannelMeta({
201
+ timeAgo,
202
+ viewsText,
203
+ channelLogo,
204
+ userName,
205
+ subscribersCount,
206
+ containerStyles,
207
+ channelContainerStyles,
208
+ });
209
+ ```
210
+
211
+ ---
212
+
213
+ ## CustomizedTitle
214
+
215
+ Title renderer with automatic truncation and typography control.
216
+
217
+ ```ts
218
+ CustomizedTitle({
219
+ title,
220
+ fontSize,
221
+ fontFamily,
222
+ textColor,
223
+ style,
224
+ textStyle,
225
+ });
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Utilities
231
+
232
+ ## DateViews
233
+
234
+ Displays publish date and view count metadata.
235
+
236
+ ```ts
237
+ DateViews({
238
+ timeAgo,
239
+ viewsText,
240
+ containerStyles,
241
+ dateTextStyles,
242
+ viewsTextStyles,
243
+ dateContainerStyles,
244
+ });
245
+ ```
246
+
247
+ ---
248
+
249
+ ## normalizeUrl
250
+
251
+ Normalizes user-provided URLs into safe, clickable links.
252
+
253
+ ```ts
254
+ normalizeUrl(url): string | null
255
+ ```
256
+
257
+ - Adds `https://` when missing
258
+ - Returns `null` for invalid inputs
259
+
260
+ ---
261
+
262
+ ## Design philosophy
263
+
264
+ - Single source of truth for shared UI
265
+ - No API calls or business logic
266
+ - Consistent visual language across packages
267
+ - Mobile-first, composable components
268
+ - Designed to scale with the BEGENONE ecosystem
269
+
270
+ ---
271
+
272
+ ## License
273
+
274
+ MIT License
275
+
276
+ Copyright (c) 2025 BEGENONE / WeReform
277
+
278
+ Permission is hereby granted, free of charge, to any person obtaining a copy
279
+ of this software and associated documentation files (the “Software”), to deal
280
+ in the Software without restriction, including without limitation the rights
281
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
282
+ copies of the Software, and to permit persons to whom the Software is
283
+ furnished to do so, subject to the following conditions:
284
+
285
+ The above copyright notice and this permission notice shall be included in
286
+ all copies or substantial portions of the Software.
287
+
288
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
289
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
290
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
291
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
292
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
293
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
294
+ THE SOFTWARE.
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@wereform/pkgm-shared",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "main": "dist/index.js",
5
- "scripts": {
6
- "build": "babel src --out-dir dist --extensions .js,.jsx"
7
- },
5
+ "files": [
6
+ "dist",
7
+ "README.md"
8
+ ],
8
9
  "publishConfig": {
9
10
  "access": "public"
10
11
  },
@@ -26,5 +27,8 @@
26
27
  "@babel/core": "^7.28.5",
27
28
  "@babel/preset-env": "^7.28.5",
28
29
  "metro-react-native-babel-preset": "^0.77.0"
30
+ },
31
+ "scripts": {
32
+ "build": "babel src --out-dir dist --extensions .js,.jsx"
29
33
  }
30
- }
34
+ }
package/babel.config.js DELETED
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- presets: ["module:metro-react-native-babel-preset"],
3
- };
package/packageJSON.md DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "name": "@begenone/pkgm-shared",
3
- "version": "1.0.0",
4
- "private": true,
5
- "main": "dist/index.js",
6
- "scripts": {
7
- "build": "babel src --out-dir dist --extensions .js,.jsx"
8
- },
9
- "peerDependencies": {
10
- "@react-native-picker/picker": "^2.11.4",
11
- "react": "19.1.0",
12
- "react-native": "^0.81.4"
13
- },
14
- "dependencies": {
15
- "@expo-google-fonts/inter": "^0.4.2",
16
- "@expo/vector-icons": "^15.0.3",
17
- "expo-font": "^14.0.9",
18
- "react-native-dropdown-select-list": "^2.0.5",
19
- "react-native-modal-selector": "^2.1.2",
20
- "react-native-picker-select": "^9.3.1"
21
- },
22
- "devDependencies": {
23
- "@babel/cli": "^7.28.3",
24
- "@babel/core": "^7.28.5",
25
- "@babel/preset-env": "^7.28.5",
26
- "metro-react-native-babel-preset": "^0.77.0"
27
- }
28
- }
@@ -1,69 +0,0 @@
1
- import { Text, TouchableOpacity, View } from "react-native";
2
- import { customizableButtonStyles } from "../../styles/customizableButtonStyles";
3
- import { useState } from "react";
4
-
5
- export function CustomizedButton({
6
- label,
7
- onPress,
8
- onPressStyle,
9
- textColor,
10
- fontSize,
11
- fontFamily,
12
- fontWeight,
13
- customIcon,
14
- style,
15
- isDisabled,
16
- }) {
17
- if (!label) {
18
- console.warn("CustomizedButton: 'label' prop is missing.");
19
- }
20
-
21
- const [pressed, setPressed] = useState(false);
22
-
23
- return (
24
- <TouchableOpacity
25
- onPress={
26
- onPress ||
27
- (() => console.warn("CustomizedButton: onPress not provided"))
28
- }
29
- onPressIn={() => setPressed(true)}
30
- onPressOut={() => setPressed(false)}
31
- style={[
32
- customizableButtonStyles.buttonContainer,
33
- style,
34
- pressed && onPressStyle,
35
- ]}
36
- activeOpacity={1}
37
- disabled={isDisabled}
38
- >
39
- <View
40
- style={
41
- customIcon
42
- ? {
43
- flexDirection: "row",
44
- width: "100%",
45
- justifyContent: "space-between",
46
- alignItems: "center",
47
- paddingRight: 12,
48
- }
49
- : {}
50
- }
51
- >
52
- <Text
53
- style={[
54
- customizableButtonStyles.buttonText,
55
- {
56
- color: textColor || "#fff",
57
- fontSize: fontSize || 16,
58
- fontFamily: fontFamily,
59
- fontWeight: fontWeight,
60
- },
61
- ]}
62
- >
63
- {label || "Default Button"}
64
- </Text>
65
- <View>{customIcon && customIcon}</View>
66
- </View>
67
- </TouchableOpacity>
68
- );
69
- }
@@ -1,44 +0,0 @@
1
- import { Text, View } from "react-native";
2
- import ModalSelector from "react-native-modal-selector";
3
- import { useState } from "react";
4
- import { dropDownStyles } from "../../styles/dropDownStyles";
5
- import { Ionicons } from "@expo/vector-icons";
6
-
7
- export function DropDown({ selectText, data, styles, iconStyles }) {
8
- const [selected, setSelected] = useState(selectText);
9
- return (
10
- <View style={[dropDownStyles.container, styles]}>
11
- <ModalSelector
12
- data={data}
13
- initValue={selectText || "Select Option"}
14
- onChange={option => {
15
- console.log("Selected option:", option); // <-- key + label!
16
- setSelected(option);
17
- }}
18
- overlayStyle={dropDownStyles.overlayStyle}
19
- optionTextStyle={{ color: "#fff", fontWeight: "500" }}
20
- optionContainerStyle={dropDownStyles.optionContainerStyle}
21
- cancelTextStyle={{
22
- color: "#000",
23
- fontFamily: "Inter",
24
- fontWeight: "800",
25
- }}
26
- cancelStyle={dropDownStyles.cancelContainerStyle}
27
- >
28
- <View style={dropDownStyles.dropDownContainer}>
29
- <Text style={dropDownStyles.dropDownText}>
30
- {typeof selected === "string"
31
- ? selected // shows default selectText
32
- : selected?.label || "Select Option"}
33
- </Text>
34
- <Ionicons
35
- name="caret-down"
36
- size={16}
37
- color={"white"}
38
- style={iconStyles}
39
- />
40
- </View>
41
- </ModalSelector>
42
- </View>
43
- );
44
- }
@@ -1,26 +0,0 @@
1
- import { Image, TouchableOpacity, View } from "react-native";
2
- import { headerGlobalStyles } from "../../styles/headerGlobalStyles";
3
-
4
- export function HeaderGlobal({ aiIcon, notificationIcon, searchIcon }) {
5
- return (
6
- <View style={headerGlobalStyles.container}>
7
- <Image
8
- source={{
9
- uri: "https://begenone-images.s3.us-east-1.amazonaws.com/begenone-white-transparent-logo-beta-min.png",
10
- }}
11
- style={headerGlobalStyles.image}
12
- />
13
- <View style={headerGlobalStyles.iconsContainer}>
14
- <TouchableOpacity style={headerGlobalStyles.icons}>
15
- {aiIcon}
16
- </TouchableOpacity>
17
- <TouchableOpacity style={headerGlobalStyles.icons}>
18
- {notificationIcon}
19
- </TouchableOpacity>
20
- <TouchableOpacity style={headerGlobalStyles.icons}>
21
- {searchIcon}
22
- </TouchableOpacity>
23
- </View>
24
- </View>
25
- );
26
- }
@@ -1,16 +0,0 @@
1
- import { Pressable, TextInput, View } from "react-native";
2
- import { commentInputStyles } from "../../styles/commentInputStyles";
3
-
4
- export function InputComment({ placeholder, submitIcon, props }) {
5
- return (
6
- <View style={commentInputStyles.container}>
7
- <TextInput
8
- placeholder={placeholder}
9
- placeholderTextColor="#999"
10
- style={[commentInputStyles.input]}
11
- {...props}
12
- />
13
- <Pressable>{submitIcon}</Pressable>
14
- </View>
15
- );
16
- }
@@ -1,85 +0,0 @@
1
- // packages/begenone-pkgm-shared/src/components/inputs/InputField.jsx
2
- import React, { useState } from "react";
3
- import {
4
- View,
5
- TextInput,
6
- Text,
7
- StyleSheet,
8
- TouchableOpacity,
9
- } from "react-native";
10
- import { inputStyles } from "../../styles/inputStyles";
11
- import {
12
- useFonts,
13
- Inter_400Regular,
14
- Inter_700Bold,
15
- } from "@expo-google-fonts/inter";
16
- import { Ionicons } from "@expo/vector-icons";
17
-
18
- export function InputField({
19
- placeholder,
20
- error,
21
- iconLeft,
22
- iconRight,
23
- onIconPress,
24
- iconRightColor,
25
- inputStyle,
26
- inputWrapper,
27
- multiline,
28
- onChangeText,
29
- isEditable,
30
- secureTextEntry,
31
- Children,
32
- // onPressFunction,
33
- ...props
34
- }) {
35
- const [fontsLoaded] = useFonts({
36
- Inter_400Regular,
37
- Inter_700Bold,
38
- });
39
-
40
- if (!fontsLoaded) {
41
- return null; // or <AppLoading />
42
- }
43
-
44
- // console.log(`Multi Line CHECK`, multiline);
45
-
46
- const isMultiline = multiline || false;
47
-
48
- return (
49
- <View>
50
- <View style={[inputStyles.inputWrapper, inputWrapper]}>
51
- {iconLeft && <View style={inputStyles.icon}>{iconLeft}</View>}
52
- <TextInput
53
- editable={isEditable}
54
- placeholder={placeholder}
55
- placeholderTextColor="#999"
56
- multiline={isMultiline}
57
- style={[
58
- inputStyles.input,
59
- inputStyle,
60
- isMultiline && { textAlignVertical: "top" },
61
- ]}
62
- onChangeText={onChangeText}
63
- secureTextEntry={secureTextEntry}
64
- {...props}
65
- />
66
- {iconRight && (
67
- <TouchableOpacity
68
- style={inputStyles.icon}
69
- onPress={onIconPress}
70
- disabled={!onIconPress}
71
- >
72
- <Ionicons
73
- name={iconRight}
74
- size={18}
75
- color={iconRightColor || "#fff"}
76
- />
77
- </TouchableOpacity>
78
- )}
79
- </View>
80
- {error && <Text style={customErrorStyle}>{error}</Text>}
81
- </View>
82
- );
83
- }
84
- // ~2.28.0
85
- // ~4.16.0
@@ -1,94 +0,0 @@
1
- import {
2
- Image,
3
- Platform,
4
- Pressable,
5
- StyleSheet,
6
- Text,
7
- useWindowDimensions,
8
- View,
9
- } from "react-native";
10
- import { MenuChannelMetaStyles } from "../../styles/MenuChannelMetaStyles";
11
- import { Ionicons } from "@expo/vector-icons";
12
- import { useEffect } from "react";
13
-
14
- let calcWidth;
15
- let calcHeight;
16
-
17
- export const MenuChannelMeta = ({
18
- timeAgo,
19
- viewsText,
20
- channelLogo,
21
- userName,
22
- subscribersCount,
23
- containerStyles,
24
- channelContainerStyles,
25
- }) => {
26
- return (
27
- <View style={[MenuChannelMetaStyles.container, containerStyles]}>
28
- <View style={MenuChannelMetaStyles.dateViewsContainer}>
29
- <View style={MenuChannelMetaStyles.dateContainer}>
30
- <View style={MenuChannelMetaStyles.dateIcon}>
31
- <Ionicons name="calendar" size={16} color="white" />
32
- </View>
33
- <Text style={MenuChannelMetaStyles.dateText}>
34
- {timeAgo || "14 Hours Ago"}
35
- </Text>
36
- </View>
37
- {/* <View style={MenuChannelMetaStyles.viewsContainer}>
38
- <Text style={MenuChannelMetaStyles.viewsText}>
39
- {viewsText || "0"}
40
- </Text>
41
- <View style={MenuChannelMetaStyles.eyeIcon}>
42
- <Ionicons name="eye" size={16} color="white" />
43
- </View>
44
- </View> */}
45
- </View>
46
- <View style={MenuChannelMetaStyles.channelMetaContainer}>
47
- <View style={MenuChannelMetaStyles.channelMetaContainer_ColumnOne}>
48
- <Image
49
- source={{
50
- uri:
51
- channelLogo ||
52
- "https://begenone-images.s3.us-east-1.amazonaws.com/default-user-photo.jpg",
53
- }}
54
- style={MenuChannelMetaStyles.userImage}
55
- />
56
- <View style={MenuChannelMetaStyles.nameSubcountContainer}>
57
- <Text
58
- style={[MenuChannelMetaStyles.userName, inlineStyles.userName]}
59
- >
60
- {userName || "Default Username"}
61
- </Text>
62
- <View style={MenuChannelMetaStyles.subCountContainer}>
63
- <Text style={MenuChannelMetaStyles.subCount}>
64
- {subscribersCount || "0"}
65
- </Text>
66
- <Text style={MenuChannelMetaStyles.subText}>Subscribers</Text>
67
- </View>
68
- </View>
69
- </View>
70
- <Pressable
71
- style={[
72
- MenuChannelMetaStyles.subscribeButtonContainer,
73
- { backgroundColor: "#303030" },
74
- ]}
75
- >
76
- <Text
77
- style={[
78
- MenuChannelMetaStyles.subscribeButtonText,
79
- { color: "#7f7f7f" },
80
- ]}
81
- >
82
- Subscribe
83
- </Text>
84
- </Pressable>
85
- </View>
86
- </View>
87
- );
88
- };
89
-
90
- const inlineStyles = StyleSheet.create({
91
- userName: {
92
- width: "",
93
- },
94
- });
@@ -1,52 +0,0 @@
1
- import { TouchableOpacity, View } from "react-native";
2
- import { MenuInteractionStyles } from "../../styles/MenuInteractionStyles";
3
- import { Ionicons } from "@expo/vector-icons";
4
- import { useState } from "react";
5
-
6
- export const MenuInteraction = ({
7
- containerStyles,
8
- columnMainIconStyles,
9
- pressed,
10
- }) => {
11
- return (
12
- <View style={[MenuInteractionStyles.container, containerStyles]}>
13
- <View
14
- style={[MenuInteractionStyles.column_mainIcons, columnMainIconStyles]}
15
- >
16
- <TouchableOpacity>
17
- <View style={MenuInteractionStyles.icon}>
18
- <Ionicons name="arrow-redo" size={24} color="white" />
19
- </View>
20
- </TouchableOpacity>
21
-
22
- <TouchableOpacity>
23
- <View style={MenuInteractionStyles.icon}>
24
- <Ionicons name="chatbubble-ellipses" size={24} color="white" />
25
- </View>
26
- </TouchableOpacity>
27
-
28
- <TouchableOpacity>
29
- <View style={MenuInteractionStyles.icon}>
30
- <Ionicons name="repeat-outline" size={24} color="white" />
31
- </View>
32
- </TouchableOpacity>
33
-
34
- <TouchableOpacity>
35
- <View style={MenuInteractionStyles.icon}>
36
- <Ionicons name="thumbs-up-outline" size={24} color="white" />
37
- </View>
38
- </TouchableOpacity>
39
-
40
- <TouchableOpacity>
41
- <View style={MenuInteractionStyles.icon}>
42
- <Ionicons name="thumbs-down-outline" size={24} color="white" />
43
- </View>
44
- </TouchableOpacity>
45
- </View>
46
-
47
- <TouchableOpacity onPress={() => pressed(true)}>
48
- <Ionicons name="ellipsis-vertical-outline" size={24} color="white" />
49
- </TouchableOpacity>
50
- </View>
51
- );
52
- };
@@ -1,33 +0,0 @@
1
- import { TouchableOpacity, View } from "react-native";
2
- import { menuNavStyles } from "../../styles/menuNavStyles";
3
- import { Ionicons } from "@expo/vector-icons";
4
-
5
- export function MenuNav({
6
- homeIcon,
7
- wireIcon,
8
- uploadIcon,
9
- channelIcon,
10
- profileIcon,
11
-
12
- onPressHome,
13
- onPressWire,
14
- onPressUpload,
15
- onPressChannel,
16
- onPressProfile,
17
- }) {
18
- return (
19
- <View style={menuNavStyles.container}>
20
- <TouchableOpacity onPress={onPressHome}>{homeIcon}</TouchableOpacity>
21
- <TouchableOpacity onPress={onPressWire}>{wireIcon}</TouchableOpacity>
22
- <TouchableOpacity onPress={onPressUpload}>{uploadIcon}</TouchableOpacity>
23
- <TouchableOpacity onPress={onPressChannel}>
24
- {channelIcon}
25
- </TouchableOpacity>
26
- <TouchableOpacity onPress={onPressProfile}>
27
- {profileIcon || (
28
- <Ionicons name="person-outline" size={24} color="white" />
29
- )}
30
- </TouchableOpacity>
31
- </View>
32
- );
33
- }
@@ -1,36 +0,0 @@
1
- import { Text, View } from "react-native";
2
-
3
- export function CustomizedTitle({
4
- title,
5
- fontSize,
6
- fontFamily,
7
- textColor,
8
- style,
9
- textStyle,
10
- dateTextStyles,
11
- }) {
12
- const displayTitle =
13
- title && title.length > 75
14
- ? title.slice(0, 75) + "…" // adds an ellipsis when truncated
15
- : title || "Here is your default Title!";
16
-
17
- return (
18
- <View style={[{ width: "100%" }, style]}>
19
- <Text
20
- style={[
21
- {
22
- flexShrink: 1,
23
- fontFamily: fontFamily,
24
- fontSize: fontSize,
25
- color: textColor,
26
- flexWrap: "wrap",
27
- },
28
- textStyle,
29
- ]}
30
- numberOfLines={2}
31
- >
32
- {displayTitle}
33
- </Text>
34
- </View>
35
- );
36
- }
package/src/index.js DELETED
@@ -1,11 +0,0 @@
1
- export { InputField } from "./components/inputs/InputField";
2
- export { MenuNav } from "./components/menus/MenuNav";
3
- export { HeaderGlobal } from "./components/headers/HeaderGlobal";
4
- export { MenuInteraction } from "./components/menus/MenuInteraction";
5
- export { MenuChannelMeta } from "./components/menus/MenuChannelMeta";
6
- export { InputComment } from "./components/inputs/InputComment.jsx";
7
- export { DropDown } from "./components/dropdowns/DropDown.jsx";
8
- export { CustomizedTitle } from "./components/titles/CustomizedTitle.jsx";
9
- export { CustomizedButton } from "./components/buttons/CustomizableButton.jsx";
10
- export { DateViews } from "./utils/DateViews.jsx";
11
- export { default as normalizeUrl } from "./utils/normalizeUrl.js";
@@ -1,114 +0,0 @@
1
- import { Platform, StyleSheet, useWindowDimensions } from "react-native";
2
- import { globalStyles } from "./globalStyles";
3
-
4
- export const checkDimensions = () => {};
5
-
6
- // checkDimensions();
7
-
8
- export const MenuChannelMetaStyles = StyleSheet.create({
9
- container: {
10
- width: "auto",
11
- marginRight: 12,
12
- marginLeft: 12,
13
- },
14
-
15
- dateViewsContainer: {
16
- width: "100%",
17
- flexDirection: "row",
18
- justifyContent: "space-between",
19
- marginTop: 12,
20
- paddingRight: 6,
21
- paddingLeft: 6,
22
- },
23
-
24
- dateContainer: {
25
- flexDirection: "row",
26
- rowGap: 20,
27
- },
28
-
29
- dateIcon: {
30
- marginRight: 8,
31
- },
32
-
33
- viewsContainer: {
34
- flexDirection: "row",
35
- alignItems: "center",
36
- },
37
-
38
- eyeIcon: {
39
- marginRight: 8,
40
- marginLeft: 8,
41
- },
42
-
43
- dateText: {
44
- color: globalStyles.colors.colorPrimary600,
45
- },
46
-
47
- viewsText: {
48
- color: globalStyles.colors.colorPrimary600,
49
- },
50
-
51
- channelMetaContainer: {
52
- flexDirection: "row",
53
- backgroundColor: globalStyles.colors.colorPrimary200,
54
- // width: "100%",
55
- // margin: 12,
56
- padding: 12,
57
- marginBottom: 6,
58
- marginTop: 12,
59
- borderRadius: globalStyles.borders.borderPrimary100,
60
- justifyContent: "space-between",
61
- },
62
-
63
- channelMetaContainer_ColumnOne: {
64
- flexDirection: "row",
65
- },
66
-
67
- userImage: {
68
- width: 40,
69
- height: 40,
70
- borderRadius: globalStyles.borders.borderPrimary50,
71
- },
72
-
73
- nameSubcountContainer: {
74
- flexDirection: "column",
75
- paddingLeft: 12,
76
- },
77
-
78
- userName: {
79
- color: "#fff",
80
- fontSize: Platform.OS === "ios" ? 16 : 14,
81
- paddingBottom: 4,
82
- fontWeight: "bold",
83
- },
84
-
85
- subCountContainer: {
86
- flexDirection: "row",
87
- },
88
-
89
- subCount: {
90
- color: globalStyles.colors.colorPrimary600,
91
- paddingRight: 6,
92
- fontSize: 12,
93
- fontWeight: "bold",
94
- },
95
-
96
- subText: {
97
- color: "#fff",
98
- fontSize: 12,
99
- },
100
-
101
- subscribeButtonContainer: {
102
- backgroundColor: globalStyles.colors.colorPrimary600,
103
- width: Platform.OS === "ios" ? 100 : 80,
104
- borderRadius: globalStyles.borders.borderPrimary400,
105
- alignItems: "center",
106
- justifyContent: "center",
107
- },
108
-
109
- subscribeButtonText: {
110
- color: "#fff",
111
- fontWeight: "bold",
112
- fontSize: Platform === "ios" ? 18 : 12,
113
- },
114
- });
@@ -1,21 +0,0 @@
1
- export const MenuInteractionStyles = {
2
- container: {
3
- width: "100%",
4
- height: 40,
5
- // backgroundColor: "#be2e2eff",
6
- flexDirection: "row",
7
- justifyContent: "space-between",
8
- alignItems: "center",
9
- paddingRight: 16,
10
- },
11
-
12
- column_mainIcons: {
13
- flexDirection: "row",
14
- // width: "100%",
15
- justifyContent: "space-evenly",
16
- },
17
-
18
- icon: {
19
- paddingLeft: 18,
20
- },
21
- };
@@ -1,30 +0,0 @@
1
- import { globalStyles } from "./globalStyles";
2
-
3
- export const commentInputStyles = {
4
- container: {
5
- flexDirection: "row",
6
- width: "auto",
7
- backgroundColor: globalStyles.colors.colorPrimary350,
8
- borderRadius: globalStyles.borders.borderPrimary200,
9
- height: 50,
10
-
11
- justifyContent: "space-between",
12
- alignItems: "center",
13
-
14
- justifySelf: "center",
15
-
16
- marginRight: 12,
17
- marginLeft: 12,
18
-
19
- paddingLeft: 12,
20
- paddingRight: 24,
21
- },
22
-
23
- input: {
24
- // width: "100%",
25
-
26
- paddingLeft: 8,
27
- paddingRight: 8,
28
- color: "#fff",
29
- },
30
- };
@@ -1,25 +0,0 @@
1
- import { StyleSheet } from "react-native";
2
- import { globalStyles } from "./globalStyles";
3
-
4
- export const customizableButtonStyles = StyleSheet.create({
5
- container: {},
6
-
7
- buttonContainer: {
8
- height: 50,
9
- width: "auto",
10
- flexGrow: 1,
11
- justifyContent: "center",
12
- alignItems: "center",
13
- borderRadius: globalStyles.borders.borderPrimary100,
14
- backgroundColor: "#fff",
15
- },
16
-
17
- buttonText: {
18
- flexDirection: "row",
19
- color: "#000",
20
- fontSize: 16,
21
- textAlign: "center",
22
- textAlignVertical: "center",
23
- alignItems: "center",
24
- },
25
- });
@@ -1,54 +0,0 @@
1
- import { globalStyles } from "./globalStyles";
2
-
3
- export const dropDownStyles = {
4
- container: {
5
- width: "auto",
6
- // marginLeft: 16,
7
- // marginRight: 16,
8
- // justifyContent: "start",
9
- },
10
-
11
- picker: {
12
- height: 40,
13
- flex: 1,
14
-
15
- // color: "#151515",
16
- },
17
-
18
- overlayStyle: {
19
- backgroundColor: globalStyles.colors.colorPrimary50,
20
- },
21
-
22
- optionTextStyle: {
23
- color: "#fff",
24
- },
25
-
26
- optionContainerStyle: {
27
- backgroundColor: globalStyles.colors.colorPrimary200,
28
- borderWidth: 1,
29
- borderRadius: globalStyles.borders.borderPrimary200,
30
- justifyContent: "space-between",
31
- },
32
-
33
- cancelContainerStyle: {
34
- backgroundColor: "#fff",
35
- },
36
-
37
- dropDownContainer: {
38
- flexDirection: "row",
39
- width: "100%",
40
- justifyContent: "space-between",
41
- // borderWidth: 1,
42
- borderRadius: globalStyles.borders.borderPrimary200,
43
- height: 50,
44
- alignItems: "center",
45
- paddingRight: 12,
46
- paddingLeft: 12,
47
- backgroundColor: globalStyles.colors.colorPrimary200,
48
- },
49
-
50
- dropDownText: {
51
- color: "#fff",
52
- paddingLeft: 12,
53
- },
54
- };
@@ -1,27 +0,0 @@
1
- export const globalStyles = {
2
- colors: {
3
- colorPrimary50: "rgba(21, 21, 21, .7)",
4
- colorPrimary100: "#151515",
5
-
6
- colorPrimary200: "#252525",
7
- colorPrimary250: "rgba(37, 37, 37, .9)",
8
-
9
- colorPrimary300: "#3C3C3C",
10
- colorPrimary350: "rgba(60,60,60,.2)",
11
-
12
- colorPrimary400: "#7F7F7F",
13
-
14
- colorPrimary500: "#D3D3D3",
15
-
16
- colorPrimary600: "#ff6600ff",
17
-
18
- colorPrimary700: "#FF8800",
19
- },
20
- borders: {
21
- borderPrimary50: 8,
22
- borderPrimary100: 10,
23
- borderPrimary200: 12,
24
- borderPrimary300: 15,
25
- borderPrimary400: 30,
26
- },
27
- };
@@ -1,26 +0,0 @@
1
- export const headerGlobalStyles = {
2
- container: {
3
- height: 75,
4
- width: "100%",
5
- // backgroundColor: "#fffffff",
6
- flexDirection: "row",
7
- justifyContent: "space-between",
8
- alignItems: "center",
9
- marginTop: -5,
10
- },
11
-
12
- iconsContainer: {
13
- flexDirection: "row",
14
- },
15
-
16
- icons: {
17
- paddingRight: 20,
18
- },
19
-
20
- image: {
21
- width: 120,
22
- height: 120,
23
- resizeMode: "contain",
24
- marginLeft: 24,
25
- },
26
- };
@@ -1,36 +0,0 @@
1
- export const inputStyles = {
2
- label: {
3
- fontSize: 14,
4
- marginBottom: 5,
5
- color: "#333",
6
- },
7
- inputWrapper: {
8
- flexDirection: "row",
9
- alignItems: "center",
10
-
11
- borderRadius: 8,
12
- borderWidth: 1,
13
- borderColor: "rgba(37, 37, 37, 0)",
14
- // backgroundColor: "#fff",
15
- // width: 320,
16
- overflow: "hidden", // necessary for clipping children
17
- },
18
- input: {
19
- // height: 50,
20
- width: "auto",
21
- paddingLeft: 14,
22
- paddingRight: 14,
23
- fontFamily: "Inter",
24
- fontWeight: "700",
25
- color: "#3c3c3c",
26
- },
27
-
28
- icon: {
29
- marginHorizontal: 5,
30
- },
31
- error: {
32
- color: "red",
33
- fontSize: 12,
34
- marginTop: 4,
35
- },
36
- };
@@ -1,23 +0,0 @@
1
- import { StyleSheet } from "react-native";
2
- import { globalStyles } from "./globalStyles";
3
-
4
- export const menuNavStyles = StyleSheet.create({
5
- container: {
6
- flexDirection: "row",
7
- justifyContent: "space-evenly",
8
-
9
- backgroundColor: globalStyles.colors.colorPrimary200,
10
-
11
- height: 60,
12
- width: "80%",
13
-
14
- alignSelf: "center",
15
- alignItems: "center",
16
-
17
- borderRadius: globalStyles.borders.borderPrimary300,
18
- },
19
-
20
- uploadIcon: {
21
- color: globalStyles.colors.colorPrimary600,
22
- },
23
- });
@@ -1,72 +0,0 @@
1
- import { StyleSheet, Text, View } from "react-native";
2
- import { globalStyles } from "../styles/globalStyles";
3
- import { Ionicons } from "@expo/vector-icons";
4
-
5
- export function DateViews({
6
- timeAgo,
7
- viewsText,
8
- containerStyles,
9
- dateTextStyles,
10
- viewsTextStyles,
11
- dateContainerStyles,
12
- }) {
13
- return (
14
- <View style={[styles.dateViewsContainer, containerStyles]}>
15
- <View style={[styles.dateContainer, dateContainerStyles]}>
16
- <View style={[styles.dateIcon]}>
17
- <Ionicons name="calendar-clear-outline" size={16} color="white" />
18
- </View>
19
- <Text style={[styles.dateText, dateTextStyles]}>
20
- {timeAgo || "14 Hours Ago"}
21
- </Text>
22
- </View>
23
- <View style={styles.viewsContainer}>
24
- <View style={[styles.eyeIcon]}>
25
- <Ionicons name="eye-outline" size={16} color="white" />
26
- </View>
27
- <Text style={[styles.viewsText, viewsTextStyles]}>
28
- {viewsText || "123.400"}
29
- <Text style={{ color: "white" }}>{" Views"}</Text>
30
- </Text>
31
- </View>
32
- </View>
33
- );
34
- }
35
-
36
- const styles = StyleSheet.create({
37
- dateViewsContainer: {
38
- width: "100%",
39
- height: 30,
40
- flexDirection: "row",
41
- justifyContent: "space-between",
42
- marginTop: 12,
43
- paddingRight: 8,
44
- // paddingLeft: 8,
45
- },
46
-
47
- dateContainer: {
48
- flexDirection: "row",
49
- rowGap: 20,
50
- paddingRight: 16,
51
- },
52
-
53
- dateIcon: {
54
- marginRight: 8,
55
- },
56
-
57
- viewsContainer: {
58
- flexDirection: "row",
59
- },
60
-
61
- eyeIcon: {
62
- marginRight: 8,
63
- },
64
-
65
- dateText: {
66
- color: globalStyles.colors.colorPrimary600,
67
- },
68
-
69
- viewsText: {
70
- color: globalStyles.colors.colorPrimary600,
71
- },
72
- });
File without changes
File without changes
File without changes
@@ -1,14 +0,0 @@
1
- const normalizeUrl = url => {
2
- if (!url) return null;
3
-
4
- // If it already starts with http:// or https://, return as-is
5
- if (/^https?:\/\//i.test(url)) return url;
6
-
7
- // If it looks like a domain (e.g. google.com or mysite.org)
8
- if (/^[\w.-]+\.[a-z]{2,}$/i.test(url)) return `https://${url}`;
9
-
10
- // Otherwise, not a valid link — return null or handle differently
11
- return null;
12
- };
13
-
14
- export default normalizeUrl;
File without changes