@imksh/create 1.0.23 → 1.0.25

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.
Files changed (163) hide show
  1. package/package.json +1 -1
  2. package/src/utils/copyTemplate.js +6 -0
  3. package/templates/mern-react-native/client/src/vite-env.d.ts +1 -0
  4. package/templates/mern-react-native/mobile/babel.config.js +1 -0
  5. package/templates/mern-react-native/mobile/drizzle.config.ts +8 -0
  6. package/templates/mern-react-native/mobile/expo-env.d.ts +3 -0
  7. package/templates/mern-react-native/mobile/package.json +6 -0
  8. package/templates/mern-react-native/mobile/src/app/(auth)/_layout.tsx +12 -0
  9. package/templates/mern-react-native/mobile/src/app/(auth)/change-password.tsx +112 -0
  10. package/templates/mern-react-native/mobile/src/app/(auth)/edit-profile.tsx +160 -0
  11. package/templates/mern-react-native/mobile/src/app/(auth)/forgot-password.tsx +191 -0
  12. package/templates/mern-react-native/mobile/src/app/{login.tsx → (auth)/login.tsx} +69 -21
  13. package/templates/mern-react-native/mobile/src/app/(tabs)/index.tsx +18 -17
  14. package/templates/mern-react-native/mobile/src/app/(tabs)/profile.tsx +23 -60
  15. package/templates/mern-react-native/mobile/src/app/_layout.tsx +22 -4
  16. package/templates/mern-react-native/mobile/src/components/common/AnimatedHeader.tsx +328 -0
  17. package/templates/mern-react-native/mobile/src/components/common/LocationLoader.tsx +591 -0
  18. package/templates/mern-react-native/mobile/src/components/common/ScreenHeader.tsx +41 -17
  19. package/templates/mern-react-native/mobile/src/components/common/TabHeader.tsx +58 -0
  20. package/templates/mern-react-native/mobile/src/components/common/Typography.tsx +49 -30
  21. package/templates/mern-react-native/mobile/src/components/common/Welcome.tsx +2 -2
  22. package/templates/mern-react-native/mobile/src/components/ui/BottomModal.tsx +31 -20
  23. package/templates/mern-react-native/mobile/src/components/ui/ClassicTabBar.tsx +4 -3
  24. package/templates/mern-react-native/mobile/src/components/ui/CustomTabBar.tsx +108 -71
  25. package/templates/mern-react-native/mobile/src/components/ui/Sidebar.tsx +81 -56
  26. package/templates/mern-react-native/mobile/src/components/ui/buttons/Button.tsx +106 -37
  27. package/templates/mern-react-native/mobile/src/components/ui/buttons/IconButton.tsx +4 -2
  28. package/templates/mern-react-native/mobile/src/components/ui/data-display/Accordion.tsx +3 -2
  29. package/templates/mern-react-native/mobile/src/components/ui/data-display/Avatar.tsx +4 -3
  30. package/templates/mern-react-native/mobile/src/components/ui/data-display/Badge.tsx +45 -17
  31. package/templates/mern-react-native/mobile/src/components/ui/data-display/ImageViewer.tsx +19 -9
  32. package/templates/mern-react-native/mobile/src/components/ui/feedback/CircularProgress.tsx +5 -4
  33. package/templates/mern-react-native/mobile/src/components/ui/feedback/ProgressBar.tsx +4 -3
  34. package/templates/mern-react-native/mobile/src/components/ui/feedback/Skeleton.tsx +3 -0
  35. package/templates/mern-react-native/mobile/src/components/ui/feedback/Spinner.tsx +11 -3
  36. package/templates/mern-react-native/mobile/src/components/ui/inputs/Checkbox.tsx +3 -2
  37. package/templates/mern-react-native/mobile/src/components/ui/inputs/DatePicker.tsx +186 -0
  38. package/templates/mern-react-native/mobile/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  39. package/templates/mern-react-native/mobile/src/components/ui/inputs/Input.tsx +54 -14
  40. package/templates/mern-react-native/mobile/src/components/ui/inputs/LocationPicker.tsx +211 -0
  41. package/templates/mern-react-native/mobile/src/components/ui/inputs/OTPInput.tsx +32 -9
  42. package/templates/mern-react-native/mobile/src/components/ui/inputs/PasswordInput.tsx +2 -1
  43. package/templates/mern-react-native/mobile/src/components/ui/inputs/Radio.tsx +3 -2
  44. package/templates/mern-react-native/mobile/src/components/ui/inputs/SearchBar.tsx +41 -4
  45. package/templates/mern-react-native/mobile/src/components/ui/inputs/Slider.tsx +4 -3
  46. package/templates/mern-react-native/mobile/src/components/ui/inputs/Switch.tsx +3 -2
  47. package/templates/mern-react-native/mobile/src/components/ui/inputs/TextArea.tsx +2 -1
  48. package/templates/mern-react-native/mobile/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  49. package/templates/mern-react-native/mobile/src/components/ui/layout/Grid.tsx +52 -10
  50. package/templates/mern-react-native/mobile/src/components/ui/layout/Section.tsx +7 -8
  51. package/templates/mern-react-native/mobile/src/components/ui/navigation/Pagination.tsx +4 -3
  52. package/templates/mern-react-native/mobile/src/components/ui/navigation/ProgressStepper.tsx +6 -5
  53. package/templates/mern-react-native/mobile/src/components/ui/navigation/Tabs.tsx +30 -4
  54. package/templates/mern-react-native/mobile/src/config/api.ts +12 -1
  55. package/templates/mern-react-native/mobile/src/config/sidebar.config.ts +72 -0
  56. package/templates/mern-react-native/mobile/src/config/tabNavigation.ts +37 -7
  57. package/templates/mern-react-native/mobile/src/db/index.ts +9 -0
  58. package/templates/mern-react-native/mobile/src/db/schema.ts +14 -0
  59. package/templates/mern-react-native/mobile/src/hooks/useDebounce.ts +17 -0
  60. package/templates/mern-react-native/mobile/src/services/socket.service.ts +36 -0
  61. package/templates/mern-react-native/mobile/src/store/useAuthStore.ts +122 -27
  62. package/templates/mern-react-native/mobile/src/store/useNotificationStore.ts +53 -0
  63. package/templates/mern-react-native/mobile/src/types/auth.type.ts +14 -0
  64. package/templates/mern-react-native/mobile/tsconfig.json +1 -0
  65. package/templates/mern-ts/client/src/vite-env.d.ts +1 -0
  66. package/templates/react-native/babel.config.js +1 -0
  67. package/templates/react-native/drizzle.config.ts +8 -0
  68. package/templates/react-native/expo-env.d.ts +3 -0
  69. package/templates/react-native/package.json +6 -0
  70. package/templates/react-native/src/app/(auth)/_layout.tsx +12 -0
  71. package/templates/react-native/src/app/(auth)/change-password.tsx +112 -0
  72. package/templates/react-native/src/app/(auth)/edit-profile.tsx +160 -0
  73. package/templates/react-native/src/app/(auth)/forgot-password.tsx +191 -0
  74. package/templates/react-native/src/app/{login.tsx → (auth)/login.tsx} +69 -21
  75. package/templates/react-native/src/app/(tabs)/index.tsx +18 -17
  76. package/templates/react-native/src/app/(tabs)/profile.tsx +23 -60
  77. package/templates/react-native/src/app/_layout.tsx +22 -4
  78. package/templates/react-native/src/components/common/AnimatedHeader.tsx +328 -0
  79. package/templates/react-native/src/components/common/LocationLoader.tsx +591 -0
  80. package/templates/react-native/src/components/common/ScreenHeader.tsx +41 -17
  81. package/templates/react-native/src/components/common/TabHeader.tsx +58 -0
  82. package/templates/react-native/src/components/common/Typography.tsx +49 -30
  83. package/templates/react-native/src/components/common/Welcome.tsx +2 -2
  84. package/templates/react-native/src/components/ui/BottomModal.tsx +31 -20
  85. package/templates/react-native/src/components/ui/ClassicTabBar.tsx +4 -3
  86. package/templates/react-native/src/components/ui/CustomTabBar.tsx +108 -71
  87. package/templates/react-native/src/components/ui/Sidebar.tsx +81 -56
  88. package/templates/react-native/src/components/ui/buttons/Button.tsx +106 -37
  89. package/templates/react-native/src/components/ui/buttons/IconButton.tsx +4 -2
  90. package/templates/react-native/src/components/ui/data-display/Accordion.tsx +3 -2
  91. package/templates/react-native/src/components/ui/data-display/Avatar.tsx +4 -3
  92. package/templates/react-native/src/components/ui/data-display/Badge.tsx +45 -17
  93. package/templates/react-native/src/components/ui/data-display/ImageViewer.tsx +19 -9
  94. package/templates/react-native/src/components/ui/feedback/CircularProgress.tsx +5 -4
  95. package/templates/react-native/src/components/ui/feedback/ProgressBar.tsx +4 -3
  96. package/templates/react-native/src/components/ui/feedback/Skeleton.tsx +3 -0
  97. package/templates/react-native/src/components/ui/feedback/Spinner.tsx +11 -3
  98. package/templates/react-native/src/components/ui/inputs/Checkbox.tsx +3 -2
  99. package/templates/react-native/src/components/ui/inputs/DatePicker.tsx +186 -0
  100. package/templates/react-native/src/components/ui/inputs/ImagePickerModal.tsx +129 -0
  101. package/templates/react-native/src/components/ui/inputs/Input.tsx +54 -14
  102. package/templates/react-native/src/components/ui/inputs/LocationPicker.tsx +211 -0
  103. package/templates/react-native/src/components/ui/inputs/OTPInput.tsx +32 -9
  104. package/templates/react-native/src/components/ui/inputs/PasswordInput.tsx +2 -1
  105. package/templates/react-native/src/components/ui/inputs/Radio.tsx +3 -2
  106. package/templates/react-native/src/components/ui/inputs/SearchBar.tsx +41 -4
  107. package/templates/react-native/src/components/ui/inputs/Slider.tsx +4 -3
  108. package/templates/react-native/src/components/ui/inputs/Switch.tsx +3 -2
  109. package/templates/react-native/src/components/ui/inputs/TextArea.tsx +2 -1
  110. package/templates/react-native/src/components/ui/inputs/WebLocationPicker.tsx +321 -0
  111. package/templates/react-native/src/components/ui/layout/Grid.tsx +52 -10
  112. package/templates/react-native/src/components/ui/layout/Section.tsx +7 -8
  113. package/templates/react-native/src/components/ui/navigation/Pagination.tsx +4 -3
  114. package/templates/react-native/src/components/ui/navigation/ProgressStepper.tsx +6 -5
  115. package/templates/react-native/src/components/ui/navigation/Tabs.tsx +30 -4
  116. package/templates/react-native/src/config/api.ts +12 -1
  117. package/templates/react-native/src/config/sidebar.config.ts +72 -0
  118. package/templates/react-native/src/config/tabNavigation.ts +37 -7
  119. package/templates/react-native/src/db/index.ts +9 -0
  120. package/templates/react-native/src/db/schema.ts +14 -0
  121. package/templates/react-native/src/hooks/useDebounce.ts +17 -0
  122. package/templates/react-native/src/services/socket.service.ts +36 -0
  123. package/templates/react-native/src/store/useAuthStore.ts +122 -27
  124. package/templates/react-native/src/store/useNotificationStore.ts +53 -0
  125. package/templates/react-native/src/types/auth.type.ts +14 -0
  126. package/templates/react-native/tsconfig.json +1 -0
  127. package/templates/react-ts/src/vite-env.d.ts +1 -0
  128. package/templates/mern-react-native/mobile/.env +0 -2
  129. package/templates/mern-react-native/mobile/.env.example +0 -2
  130. package/templates/mern-react-native/mobile/.vscode/extensions.json +0 -1
  131. package/templates/mern-react-native/mobile/.vscode/settings.json +0 -7
  132. package/templates/mern-react-native/mobile/README.md +0 -159
  133. package/templates/mern-react-native/mobile/docs/README.md +0 -17
  134. package/templates/mern-react-native/mobile/docs/components/buttons.md +0 -40
  135. package/templates/mern-react-native/mobile/docs/components/data-display.md +0 -44
  136. package/templates/mern-react-native/mobile/docs/components/feedback.md +0 -36
  137. package/templates/mern-react-native/mobile/docs/components/gestures.md +0 -60
  138. package/templates/mern-react-native/mobile/docs/components/inputs.md +0 -41
  139. package/templates/mern-react-native/mobile/docs/components/layout.md +0 -34
  140. package/templates/mern-react-native/mobile/docs/components/navigation.md +0 -31
  141. package/templates/mern-react-native/mobile/docs/features.md +0 -85
  142. package/templates/mern-react-native/mobile/docs/getting-started.md +0 -47
  143. package/templates/mern-react-native/mobile/src/components/common/HomeHeader.tsx +0 -43
  144. package/templates/mern-react-native/mobile/src/components/settings/SettingToggle.tsx +0 -26
  145. package/templates/mern-react-native/mobile/src/components/settings/SettingsOptions.tsx +0 -47
  146. package/templates/react-native/.env +0 -2
  147. package/templates/react-native/.env.example +0 -2
  148. package/templates/react-native/.vscode/extensions.json +0 -1
  149. package/templates/react-native/.vscode/settings.json +0 -7
  150. package/templates/react-native/README.md +0 -159
  151. package/templates/react-native/docs/README.md +0 -17
  152. package/templates/react-native/docs/components/buttons.md +0 -40
  153. package/templates/react-native/docs/components/data-display.md +0 -44
  154. package/templates/react-native/docs/components/feedback.md +0 -36
  155. package/templates/react-native/docs/components/gestures.md +0 -60
  156. package/templates/react-native/docs/components/inputs.md +0 -41
  157. package/templates/react-native/docs/components/layout.md +0 -34
  158. package/templates/react-native/docs/components/navigation.md +0 -31
  159. package/templates/react-native/docs/features.md +0 -85
  160. package/templates/react-native/docs/getting-started.md +0 -47
  161. package/templates/react-native/src/components/common/HomeHeader.tsx +0 -43
  162. package/templates/react-native/src/components/settings/SettingToggle.tsx +0 -26
  163. package/templates/react-native/src/components/settings/SettingsOptions.tsx +0 -47
@@ -0,0 +1,58 @@
1
+ import { View, TouchableOpacity } from "react-native";
2
+ import React, { useState } from "react";
3
+ import { Txt } from "./Typography";
4
+ import { useColorScheme } from "nativewind";
5
+ import { Colors } from "../../constants/Colors";
6
+ import Sidebar from "../ui/Sidebar";
7
+ import { Ionicons } from "@expo/vector-icons";
8
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
9
+
10
+ export default function TabHeader({
11
+ title,
12
+ actions,
13
+ showMenuButton = false,
14
+ }: {
15
+ title?: string;
16
+ actions?: React.ReactNode;
17
+ showMenuButton?: boolean;
18
+ }) {
19
+ const { colorScheme } = useColorScheme();
20
+ const [isSidebarOpen, setIsSidebarOpen] = useState<boolean>(false);
21
+ const colors = Colors[colorScheme ?? "light"];
22
+ const insets = useSafeAreaInsets();
23
+
24
+ return (
25
+ <>
26
+ <View
27
+ className="px-6 flex-row items-center justify-between border-b border-base-200 w-full"
28
+ style={{
29
+ backgroundColor: colors.base200,
30
+ height: insets.top + 56,
31
+ paddingTop: insets.top,
32
+ }}
33
+ >
34
+ <View className="flex-row items-center flex-1 mr-4">
35
+ {showMenuButton && (
36
+ <TouchableOpacity
37
+ onPress={() => setIsSidebarOpen(true)}
38
+ activeOpacity={0.7}
39
+ className="w-10 h-10 rounded-full bg-base-200/80 items-center justify-center mr-3 border border-base-300/10 shadow-sm"
40
+ >
41
+ <Ionicons
42
+ name="menu-outline"
43
+ color={colors.baseContent}
44
+ size={22}
45
+ />
46
+ </TouchableOpacity>
47
+ )}
48
+ <Txt variant="xl" className="text-primary">
49
+ {title}
50
+ </Txt>
51
+ </View>
52
+ <View className="flex-row items-center gap-2">{actions}</View>
53
+ </View>
54
+
55
+ <Sidebar isOpen={isSidebarOpen} onClose={() => setIsSidebarOpen(false)} />
56
+ </>
57
+ );
58
+ }
@@ -9,27 +9,30 @@ export const FontFamily = {
9
9
  } as const;
10
10
 
11
11
  export type TxtVariant =
12
- | "h1"
13
- | "h2"
14
- | "h3"
15
- | "body"
16
- | "regular"
17
12
  | "caption"
18
- | "mid"
13
+ | "xxs"
14
+ | "xs"
15
+ | "sm"
16
+ | "base"
17
+ | "md"
18
+ | "lg"
19
19
  | "xl"
20
20
  | "2xl"
21
21
  | "3xl"
22
- | "4xl";
22
+ | "4xl"
23
+ | "5xl"
24
+ | "6xl"
25
+ | "7xl";
23
26
 
24
27
  export interface TxtProps extends TextProps {
25
28
  variant?: TxtVariant;
26
29
  color?: string;
27
30
  align?: "auto" | "left" | "right" | "center" | "justify";
28
- weight?: "normal" | "bold" | "semibold" | "black";
31
+ weight?: "normal" | "medium" | "bold" | "semibold" | "black";
29
32
  }
30
33
 
31
34
  export const Txt = ({
32
- variant = "regular",
35
+ variant = "base",
33
36
  color,
34
37
  align,
35
38
  weight,
@@ -40,36 +43,51 @@ export const Txt = ({
40
43
  }: TxtProps) => {
41
44
  const getVariantStyles = () => {
42
45
  switch (variant) {
43
- case "h1":
44
- return { fontFamily: FontFamily.bold, fontSize: 22 };
45
- case "h2":
46
- return { fontFamily: FontFamily.semibold, fontSize: 18 };
47
- case "h3":
48
- return { fontFamily: FontFamily.semibold, fontSize: 16 };
49
- case "mid":
50
- return { fontFamily: FontFamily.medium, fontSize: 15 };
51
- case "body":
52
- return { fontFamily: FontFamily.medium, fontSize: 14 };
53
- case "regular":
54
- return { fontFamily: FontFamily.regular, fontSize: 13 };
55
46
  case "caption":
47
+ return { fontFamily: FontFamily.regular, fontSize: 10 };
48
+ case "xxs":
49
+ return { fontFamily: FontFamily.regular, fontSize: 8 };
50
+ case "xs":
51
+ return { fontFamily: FontFamily.regular, fontSize: 10 };
52
+ case "sm":
56
53
  return { fontFamily: FontFamily.regular, fontSize: 12 };
54
+ case "base":
55
+ return { fontFamily: FontFamily.regular, fontSize: 14 };
56
+ case "md":
57
+ return { fontFamily: FontFamily.medium, fontSize: 16 };
58
+ case "lg":
59
+ return { fontFamily: FontFamily.semibold, fontSize: 18 };
57
60
  case "xl":
58
- return { fontFamily: FontFamily.extrabold, fontSize: 30 };
61
+ return { fontFamily: FontFamily.bold, fontSize: 20 };
59
62
  case "2xl":
60
- return { fontFamily: FontFamily.extrabold, fontSize: 36 };
63
+ return { fontFamily: FontFamily.bold, fontSize: 24 };
61
64
  case "3xl":
62
- return { fontFamily: FontFamily.extrabold, fontSize: 48 };
65
+ return { fontFamily: FontFamily.extrabold, fontSize: 30 };
63
66
  case "4xl":
67
+ return { fontFamily: FontFamily.extrabold, fontSize: 36 };
68
+ case "5xl":
69
+ return { fontFamily: FontFamily.extrabold, fontSize: 48 };
70
+ case "6xl":
64
71
  return { fontFamily: FontFamily.extrabold, fontSize: 60 };
72
+ case "7xl":
73
+ return { fontFamily: FontFamily.extrabold, fontSize: 72 };
65
74
  default:
66
- return { fontFamily: FontFamily.regular, fontSize: 13 };
75
+ return { fontFamily: FontFamily.regular, fontSize: 14 };
67
76
  }
68
77
  };
69
78
 
70
79
  const baseStyle = getVariantStyles();
71
- const defaultColorClass =
72
- variant === "caption" ? "text-secondary" : "text-base-content";
80
+ const hasColorClass = className.split(" ").some((c) => {
81
+ if (!c.startsWith("text-")) return false;
82
+ const val = c.substring(5).split("/")[0]; // handle potential opacity suffix like text-white/80
83
+ const isSize = ["xxs", "xs", "sm", "base", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl", "caption"].includes(val);
84
+ return !isSize;
85
+ });
86
+ const defaultColorClass = hasColorClass
87
+ ? ""
88
+ : variant === "xs"
89
+ ? "text-secondary"
90
+ : "text-base-content";
73
91
 
74
92
  // Override specific properties if provided
75
93
  const customStyles: any = {};
@@ -77,9 +95,10 @@ export const Txt = ({
77
95
  if (align) customStyles.textAlign = align;
78
96
  if (weight) {
79
97
  if (weight === "bold" || weight === "black")
80
- customStyles.fontFamily = "MontserratBold";
81
- if (weight === "semibold") customStyles.fontFamily = "MontserratSemiBold";
82
- if (weight === "normal") customStyles.fontFamily = "MontserratRegular";
98
+ customStyles.fontFamily = FontFamily.bold;
99
+ if (weight === "semibold") customStyles.fontFamily = FontFamily.semibold;
100
+ if (weight === "medium") customStyles.fontFamily = FontFamily.medium;
101
+ if (weight === "normal") customStyles.fontFamily = FontFamily.regular;
83
102
  }
84
103
 
85
104
  return (
@@ -27,9 +27,9 @@ const Welcome = () => {
27
27
  return (
28
28
  <View className="flex-row flex-wrap justify-between item-center pl-4 mt-6 items-center">
29
29
  <View className="w-[55%] relative justify-end">
30
- <Txt variant="h1"> Hey {user ? user.name : "There"}!</Txt>
30
+ <Txt variant="6xl"> Hey {user ? user.name : "There"}!</Txt>
31
31
  <View className="flex-row w-64 items-center">
32
- <Txt variant="h1">Welcome Back</Txt>
32
+ <Txt variant="6xl">Welcome Back</Txt>
33
33
  <Text
34
34
  key={i}
35
35
  style={{ fontSize: 28 }}
@@ -4,6 +4,8 @@ import {
4
4
  TouchableWithoutFeedback,
5
5
  Dimensions,
6
6
  StyleSheet,
7
+ KeyboardAvoidingView,
8
+ Platform,
7
9
  } from "react-native";
8
10
  import Animated, {
9
11
  useSharedValue,
@@ -12,7 +14,7 @@ import Animated, {
12
14
  Easing,
13
15
  runOnJS,
14
16
  } from "react-native-reanimated";
15
- import { Gesture, GestureDetector } from 'react-native-gesture-handler';
17
+ import { Gesture, GestureDetector } from "react-native-gesture-handler";
16
18
  import { Portal } from "react-native-paper";
17
19
  import { useColorScheme } from "nativewind";
18
20
  import { Colors } from "../../constants/Colors";
@@ -64,7 +66,7 @@ export default function BottomModal({
64
66
  }
65
67
  });
66
68
  }
67
- // eslint-disable-next-line react-hooks/exhaustive-deps
69
+
68
70
  }, [isOpen]);
69
71
 
70
72
  const panGesture = Gesture.Pan()
@@ -98,20 +100,24 @@ export default function BottomModal({
98
100
 
99
101
  return (
100
102
  <Portal>
101
- <View style={[StyleSheet.absoluteFill, { zIndex: 999 }]}>
102
- {/* Backdrop Overlay */}
103
- <TouchableWithoutFeedback onPress={onClose}>
104
- <Animated.View
105
- style={[
106
- StyleSheet.absoluteFill,
107
- { backgroundColor: "#000" },
108
- backdropAnimatedStyle,
109
- ]}
110
- />
111
- </TouchableWithoutFeedback>
103
+ <KeyboardAvoidingView
104
+ behavior={Platform.OS === "ios" ? "padding" : undefined}
105
+ style={StyleSheet.absoluteFill}
106
+ pointerEvents="box-none"
107
+ >
108
+ <View style={[StyleSheet.absoluteFill, { zIndex: 999 }]}>
109
+ {/* Backdrop Overlay */}
110
+ <TouchableWithoutFeedback onPress={onClose}>
111
+ <Animated.View
112
+ style={[
113
+ StyleSheet.absoluteFill,
114
+ { backgroundColor: "#000" },
115
+ backdropAnimatedStyle,
116
+ ]}
117
+ />
118
+ </TouchableWithoutFeedback>
112
119
 
113
- {/* Sliding Bottom Modal Panel */}
114
- <GestureDetector gesture={panGesture}>
120
+ {/* Sliding Bottom Modal Panel */}
115
121
  <Animated.View
116
122
  style={[
117
123
  {
@@ -134,15 +140,20 @@ export default function BottomModal({
134
140
  ]}
135
141
  >
136
142
  {/* Drag Handle Indicator */}
137
- <View className="items-center py-4">
138
- <View className="w-12 h-1.5 rounded-full bg-base-300" />
139
- </View>
143
+ <GestureDetector gesture={panGesture}>
144
+ <View
145
+ className="items-center pt-4 pb-6 bg-base-100 rounded-t-[30px]"
146
+ style={{ zIndex: 10 }}
147
+ >
148
+ <View className="w-16 h-1.5 rounded-full bg-base-300" />
149
+ </View>
150
+ </GestureDetector>
140
151
 
141
152
  {/* Modal Content */}
142
153
  <View className="flex-1 px-6">{children}</View>
143
154
  </Animated.View>
144
- </GestureDetector>
145
- </View>
155
+ </View>
156
+ </KeyboardAvoidingView>
146
157
  </Portal>
147
158
  );
148
159
  }
@@ -1,5 +1,6 @@
1
+ import { Txt } from "../common/Typography";
1
2
  import React from 'react';
2
- import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
3
+ import { View, TouchableOpacity, StyleSheet } from 'react-native';
3
4
  import { Ionicons } from '@expo/vector-icons';
4
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
5
6
  import { useColorScheme } from 'nativewind';
@@ -23,7 +24,7 @@ const TabItem = ({ isFocused, onPress, onLongPress, iconName, label, colors }: a
23
24
  color={isFocused ? colors.primary : colors.secondary}
24
25
  style={{ marginBottom: 4 }}
25
26
  />
26
- <Text
27
+ <Txt
27
28
  style={{
28
29
  color: isFocused ? colors.primary : colors.secondary,
29
30
  fontWeight: isFocused ? '600' : '500',
@@ -31,7 +32,7 @@ const TabItem = ({ isFocused, onPress, onLongPress, iconName, label, colors }: a
31
32
  }}
32
33
  >
33
34
  {label}
34
- </Text>
35
+ </Txt>
35
36
  </View>
36
37
  </TouchableOpacity>
37
38
  );
@@ -1,10 +1,11 @@
1
1
  import React from "react";
2
- import { View, TouchableOpacity, Text, StyleSheet } from "react-native";
2
+ import { View, TouchableOpacity, StyleSheet } from "react-native";
3
3
  import { Ionicons } from "@expo/vector-icons";
4
4
  import { useSafeAreaInsets } from "react-native-safe-area-context";
5
5
  import { useColorScheme } from "nativewind";
6
6
  import { Colors } from "../../constants/Colors";
7
7
  import { getTabConfig } from "../../config/tabNavigation";
8
+ import { LinearGradient } from "expo-linear-gradient";
8
9
 
9
10
  const TabItem = ({
10
11
  isFocused,
@@ -14,7 +15,6 @@ const TabItem = ({
14
15
  label,
15
16
  colors,
16
17
  }: any) => {
17
-
18
18
  return (
19
19
  <TouchableOpacity
20
20
  accessibilityRole="button"
@@ -25,21 +25,25 @@ const TabItem = ({
25
25
  activeOpacity={0.8}
26
26
  >
27
27
  <View style={styles.tabItem}>
28
- <Ionicons
29
- name={iconName as any}
30
- size={24}
31
- color={isFocused ? colors.primary : colors.secondary}
32
- style={{ marginBottom: 4 }}
33
- />
34
- <Text
35
- style={{
36
- color: isFocused ? colors.baseContent : colors.secondary,
37
- fontWeight: isFocused ? "600" : "400",
38
- fontSize: 11,
39
- }}
28
+ <View
29
+ style={[
30
+ styles.iconWrapper,
31
+ isFocused && {
32
+ backgroundColor: colors.primary,
33
+ width: 54,
34
+ height: 54,
35
+ borderRadius: 100,
36
+ alignItems: "center",
37
+ justifyContent: "center",
38
+ },
39
+ ]}
40
40
  >
41
- {label}
42
- </Text>
41
+ <Ionicons
42
+ name={iconName as any}
43
+ size={isFocused ? 20 : 24}
44
+ color={isFocused ? colors.primaryContent : colors.secondary}
45
+ />
46
+ </View>
43
47
  </View>
44
48
  </TouchableOpacity>
45
49
  );
@@ -76,68 +80,97 @@ export default function CustomTabBar({
76
80
  const { colorScheme } = useColorScheme();
77
81
  const colors = Colors[colorScheme ?? "light"];
78
82
 
83
+ const currentRoute = state.routes[state.index];
84
+ const currentOptions = descriptors[currentRoute.key].options;
85
+ if (currentOptions.tabBarStyle?.display === "none") {
86
+ return null;
87
+ }
88
+
89
+ const bottomOffset = insets.bottom > 0 ? insets.bottom : 20;
90
+ const totalTabBarHeight = bottomOffset + 70; // 70 is the height of the tab bar container
91
+
79
92
  return (
80
- <View
81
- style={[
82
- styles.container,
83
- {
84
- bottom: insets.bottom > 0 ? insets.bottom : 20,
85
- backgroundColor: colors.base100,
86
- borderColor: colors.base300,
87
- },
88
- ]}
89
- >
90
- {state.routes.map((route: any, index: number) => {
91
- const { options } = descriptors[route.key];
92
- const tabConfig = getTabConfig(route.name);
93
- const label =
94
- options.tabBarLabel !== undefined
95
- ? options.tabBarLabel
96
- : options.title !== undefined
97
- ? options.title
98
- : tabConfig?.title || route.name;
93
+ <View pointerEvents="box-none" style={StyleSheet.absoluteFill}>
94
+ <LinearGradient
95
+ colors={[`${colors.base100}00`, colors.base100, colors.base100]}
96
+ locations={[0, 0.5, 1]}
97
+ style={{
98
+ position: "absolute",
99
+ bottom: 0,
100
+ left: 0,
101
+ right: 0,
102
+ height: totalTabBarHeight,
103
+ }}
104
+ pointerEvents="none"
105
+ />
106
+ <View
107
+ style={[
108
+ styles.container,
109
+ {
110
+ bottom: bottomOffset,
111
+ backgroundColor: colors.base100,
112
+ borderColor: colors.base300,
113
+ },
114
+ ]}
115
+ >
116
+ {state.routes.map((route: any, index: number) => {
117
+ const { options } = descriptors[route.key];
118
+ if (
119
+ options.href === null ||
120
+ options.tabBarItemStyle?.display === "none"
121
+ )
122
+ return null;
99
123
 
100
- const isFocused = state.index === index;
124
+ const tabConfig = getTabConfig(route.name);
125
+ const label =
126
+ options.tabBarLabel !== undefined
127
+ ? options.tabBarLabel
128
+ : options.title !== undefined
129
+ ? options.title
130
+ : tabConfig?.title || route.name;
101
131
 
102
- const onPress = () => {
103
- const event = navigation.emit({
104
- type: "tabPress",
105
- target: route.key,
106
- canPreventDefault: true,
107
- });
132
+ const isFocused = state.index === index;
108
133
 
109
- if (!isFocused && !event.defaultPrevented) {
110
- navigation.navigate(route.name, route.params);
111
- }
112
- };
134
+ const onPress = () => {
135
+ const event = navigation.emit({
136
+ type: "tabPress",
137
+ target: route.key,
138
+ canPreventDefault: true,
139
+ });
113
140
 
114
- const onLongPress = () => {
115
- navigation.emit({
116
- type: "tabLongPress",
117
- target: route.key,
118
- });
119
- };
141
+ if (!isFocused && !event.defaultPrevented) {
142
+ navigation.navigate(route.name, route.params);
143
+ }
144
+ };
120
145
 
121
- let iconName: any = tabConfig?.baseIcon || "home";
122
- iconName = isFocused ? iconName : `${iconName}-outline`;
146
+ const onLongPress = () => {
147
+ navigation.emit({
148
+ type: "tabLongPress",
149
+ target: route.key,
150
+ });
151
+ };
123
152
 
124
- return (
125
- <React.Fragment key={route.key}>
126
- {showCenterButton &&
127
- index === Math.floor(state.routes.length / 2) && (
128
- <CenterButton colors={colors} onPress={onCenterButtonPress} />
129
- )}
130
- <TabItem
131
- isFocused={isFocused}
132
- onPress={onPress}
133
- onLongPress={onLongPress}
134
- iconName={iconName}
135
- label={label as string}
136
- colors={colors}
137
- />
138
- </React.Fragment>
139
- );
140
- })}
153
+ let iconName: any = tabConfig?.baseIcon || "home";
154
+ iconName = isFocused ? iconName : `${iconName}-outline`;
155
+
156
+ return (
157
+ <React.Fragment key={route.key}>
158
+ {showCenterButton &&
159
+ index === Math.floor(state.routes.length / 2) && (
160
+ <CenterButton colors={colors} onPress={onCenterButtonPress} />
161
+ )}
162
+ <TabItem
163
+ isFocused={isFocused}
164
+ onPress={onPress}
165
+ onLongPress={onLongPress}
166
+ iconName={iconName}
167
+ label={label as string}
168
+ colors={colors}
169
+ />
170
+ </React.Fragment>
171
+ );
172
+ })}
173
+ </View>
141
174
  </View>
142
175
  );
143
176
  }
@@ -173,6 +206,10 @@ const styles = StyleSheet.create({
173
206
  justifyContent: "center",
174
207
  height: 50,
175
208
  },
209
+ iconWrapper: {
210
+ alignItems: "center",
211
+ justifyContent: "center",
212
+ },
176
213
  activeIndicator: {
177
214
  width: 20,
178
215
  height: 3,