feature & fix

deskripsi:
feature:
- floating button
- Forum create

fix:
- Base box
- Avatar : penambahan onPres & href
- Text custom : penambahan warna props green
- Text Area : penambhaan hight
- ViewWrapper : penambahan props floating
# No Issue "
This commit is contained in:
2025-07-14 11:56:44 +08:00
parent 5183769a7c
commit ac9dae7c5b
16 changed files with 1060 additions and 537 deletions

View File

@@ -1,4 +1,5 @@
import { AccentColor } from "@/constants/color-palet";
import { PADDING_EXTRA_SMALL, PADDING_MEDIUM, PADDING_SMALL } from "@/constants/constans-value";
import { StyleProp, TouchableHighlight, View, ViewStyle } from "react-native";
interface BaseBoxProps {
@@ -8,14 +9,16 @@ interface BaseBoxProps {
marginBottom?: number;
padding?: number;
paddingInline?: number;
paddingBlock?: number;
}
export default function BaseBox({
children,
style,
onPress,
marginBottom = 16,
padding = 12,
marginBottom = PADDING_MEDIUM,
paddingBlock = PADDING_EXTRA_SMALL,
paddingInline = PADDING_SMALL,
}: BaseBoxProps) {
return (
<>
@@ -29,7 +32,8 @@ export default function BaseBox({
borderWidth: 1,
borderRadius: 10,
marginBottom,
padding,
paddingBlock,
paddingInline,
},
style,
]}
@@ -46,7 +50,8 @@ export default function BaseBox({
borderWidth: 1,
borderRadius: 10,
marginBottom,
padding,
paddingBlock,
paddingInline,
},
style,
]}

View File

@@ -0,0 +1,45 @@
// components/FloatingButton.tsx
import { AccentColor, MainColor } from "@/constants/color-palet";
import React from "react";
import { StyleSheet, ViewStyle } from "react-native";
import { FAB } from "react-native-paper";
// Props untuk komponen
interface FloatingButtonProps {
onPress: () => void;
// label?: string;
icon?: string; // MaterialCommunityIcons
style?: ViewStyle;
}
const FloatingButton: React.FC<FloatingButtonProps> = ({
onPress,
// label = "Buat",
icon = "pencil-plus-outline",
style,
}) => {
return (
<FAB
style={[styles.fab, style]}
icon={icon}
color={MainColor.white}
// label={label}
onPress={onPress}
/>
);
};
const styles = StyleSheet.create({
fab: {
position: "absolute",
margin: 16,
right: 0,
bottom: 0,
backgroundColor: AccentColor.softblue, // Warna Twitter biru
borderRadius: 50,
borderColor: AccentColor.blue,
borderWidth: 1,
},
});
export default FloatingButton;

View File

@@ -1,12 +1,21 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { MainColor } from "@/constants/color-palet";
import DUMMY_IMAGE from "@/constants/dummy-image-value";
import { Image, ImageSourcePropType, StyleSheet } from "react-native";
import { Href, router } from "expo-router";
import {
Image,
ImageSourcePropType,
StyleSheet,
TouchableOpacity,
} from "react-native";
type Size = "base" | "sm" | "md" | "lg" | "xl";
interface AvatarCustomProps {
source?: ImageSourcePropType;
size?: Size;
onPress?: () => void;
href?: Href | undefined;
}
const sizeMap = {
@@ -20,24 +29,42 @@ const sizeMap = {
export default function AvatarCustom({
source = DUMMY_IMAGE.avatar,
size = "base",
onPress,
href,
}: AvatarCustomProps) {
const dimension = sizeMap[size];
const ImageView = ({source}: {source: ImageSourcePropType}) => {
return (
<Image
source={source}
style={[
// styles.overlappingAvatar,
{
width: dimension,
height: dimension,
borderRadius: dimension / 2,
},
]}
resizeMode="cover"
/>
)
}
return (
<Image
source={source}
style={[
styles.overlappingAvatar,
{
width: dimension,
height: dimension,
borderRadius: dimension / 2,
},
]}
resizeMode="cover"
/>
<>
{onPress || href ? (
<TouchableOpacity
onPress={href ? () => router.navigate(href as any) : onPress}
>
<ImageView source={source} />
</TouchableOpacity>
) : (
<ImageView source={source} />
)}
</>
);
}
}
const styles = StyleSheet.create({
container: {

View File

@@ -22,7 +22,7 @@ interface TextCustomProps {
bold?: boolean;
semiBold?: boolean;
size?: "default" | "large" | "small";
color?: "default" | "yellow" | "red" | "gray";
color?: "default" | "yellow" | "red" | "gray" | "green";
align?: TextAlign; // Prop untuk alignment
truncate?: boolean | number;
onPress?: () => void;
@@ -57,6 +57,7 @@ const TextCustom: React.FC<TextCustomProps> = ({
if (color === "yellow") selectedStyles.push(styles.yellow);
else if (color === "red") selectedStyles.push(styles.red);
else if (color === "gray") selectedStyles.push(styles.gray);
else if (color === "green") selectedStyles.push(styles.green);
// Alignment
if (align) {
@@ -126,4 +127,7 @@ export const styles = StyleSheet.create({
gray: {
color: MainColor.placeholder,
},
green: {
color: MainColor.green,
},
});

View File

@@ -24,6 +24,7 @@ type BaseProps = {
maxRows?: number;
showCount?: boolean;
maxLength?: number;
height?: number;
style?: StyleProp<ViewStyle>;
};
@@ -44,12 +45,13 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
disabled = false,
borderRadius = 8,
autosize = false,
minRows = 3,
minRows = 4,
maxRows = 6,
showCount = false,
maxLength,
value,
onChangeText,
height = 100,
style,
...rest
}) => {
@@ -90,6 +92,7 @@ const TextAreaCustom: React.FC<TextAreaCustomProps> = ({
disabled && GStyles.disabledBox,
hasError ? GStyles.inputErrorBorder : {},
{ borderRadius },
{ height },
style,
]}
>

View File

@@ -18,6 +18,7 @@ interface ViewWrapperProps {
withBackground?: boolean;
headerComponent?: React.ReactNode;
footerComponent?: React.ReactNode;
floatingButton?: React.ReactNode;
style?: StyleProp<ViewStyle>;
}
@@ -26,6 +27,7 @@ const ViewWrapper = ({
withBackground = false,
headerComponent,
footerComponent,
floatingButton,
style,
}: ViewWrapperProps) => {
const assetBackground = require("../../assets/images/main-background.png");
@@ -79,43 +81,12 @@ const ViewWrapper = ({
style={{ backgroundColor: MainColor.darkblue }}
/>
)}
{/* Floating Component (misal: FAB) */}
{floatingButton && (
<View style={GStyles.floatingContainer}>{floatingButton}</View>
)}
</KeyboardAvoidingView>
{/* <SafeAreaView
edges={["bottom"]}
style={{ flex: 1, backgroundColor: MainColor.soft_darkblue }}
>
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={{ flex: 1 }}
>
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
{withBackground ? (
<ImageBackground
source={assetBackground}
resizeMode="cover"
style={GStyles.imageBackground}
>
<View style={GStyles.containerWithBackground}>{children}</View>
</ImageBackground>
) : (
<View style={GStyles.container}>{children}</View>
)}
</ScrollView>
{footerComponent ? (
<SafeAreaView
edges={["bottom"]}
style={{
// flex: 1,
backgroundColor: MainColor.darkblue,
}}
>
{footerComponent}
</SafeAreaView>
) : null}
</KeyboardAvoidingView>
</SafeAreaView> */}
</>
);
};