aboutsummaryrefslogtreecommitdiffstats
path: root/packages/mobile/components/ui
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-03-13 21:43:44 +0000
committerMohamed Bassem <me@mbassem.com>2024-03-14 16:40:45 +0000
commit04572a8e5081b1e4871e273cde9dbaaa44c52fe0 (patch)
tree8e993acb732a50d1306d4d6953df96c165c57f57 /packages/mobile/components/ui
parent2df08ed08c065e8b91bc8df0266bd4bcbb062be4 (diff)
downloadkarakeep-04572a8e5081b1e4871e273cde9dbaaa44c52fe0.tar.zst
structure: Create apps dir and copy tooling dir from t3-turbo repo
Diffstat (limited to 'packages/mobile/components/ui')
-rw-r--r--packages/mobile/components/ui/ActionButton.tsx21
-rw-r--r--packages/mobile/components/ui/Button.tsx81
-rw-r--r--packages/mobile/components/ui/Divider.tsx28
-rw-r--r--packages/mobile/components/ui/FullPageSpinner.tsx9
-rw-r--r--packages/mobile/components/ui/Input.tsx28
-rw-r--r--packages/mobile/components/ui/Skeleton.tsx38
-rw-r--r--packages/mobile/components/ui/Toast.tsx183
7 files changed, 0 insertions, 388 deletions
diff --git a/packages/mobile/components/ui/ActionButton.tsx b/packages/mobile/components/ui/ActionButton.tsx
deleted file mode 100644
index c51eb332..00000000
--- a/packages/mobile/components/ui/ActionButton.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ActivityIndicator, Pressable, PressableProps } from "react-native";
-
-export function ActionButton({
- children,
- loading,
- disabled,
- ...props
-}: PressableProps & {
- loading: boolean;
-}) {
- if (disabled !== undefined) {
- disabled ||= loading;
- } else if (loading) {
- disabled = true;
- }
- return (
- <Pressable {...props} disabled={disabled}>
- {loading ? <ActivityIndicator /> : children}
- </Pressable>
- );
-}
diff --git a/packages/mobile/components/ui/Button.tsx b/packages/mobile/components/ui/Button.tsx
deleted file mode 100644
index 4c3cbc69..00000000
--- a/packages/mobile/components/ui/Button.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import { type VariantProps, cva } from "class-variance-authority";
-import { Text, TouchableOpacity } from "react-native";
-
-import { cn } from "@/lib/utils";
-
-const buttonVariants = cva(
- "flex flex-row items-center justify-center rounded-md",
- {
- variants: {
- variant: {
- default: "bg-primary",
- secondary: "bg-secondary",
- destructive: "bg-destructive",
- ghost: "bg-slate-700",
- link: "text-primary underline-offset-4",
- },
- size: {
- default: "h-10 px-4",
- sm: "h-8 px-2",
- lg: "h-12 px-8",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- },
-);
-
-const buttonTextVariants = cva("text-center font-medium", {
- variants: {
- variant: {
- default: "text-primary-foreground",
- secondary: "text-secondary-foreground",
- destructive: "text-destructive-foreground",
- ghost: "text-primary-foreground",
- link: "text-primary-foreground underline",
- },
- size: {
- default: "text-base",
- sm: "text-sm",
- lg: "text-xl",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
-});
-
-interface ButtonProps
- extends React.ComponentPropsWithoutRef<typeof TouchableOpacity>,
- VariantProps<typeof buttonVariants> {
- label: string;
- labelClasses?: string;
-}
-function Button({
- label,
- labelClasses,
- className,
- variant,
- size,
- ...props
-}: ButtonProps) {
- return (
- <TouchableOpacity
- className={cn(buttonVariants({ variant, size, className }))}
- {...props}
- >
- <Text
- className={cn(
- buttonTextVariants({ variant, size, className: labelClasses }),
- )}
- >
- {label}
- </Text>
- </TouchableOpacity>
- );
-}
-
-export { Button, buttonVariants, buttonTextVariants };
diff --git a/packages/mobile/components/ui/Divider.tsx b/packages/mobile/components/ui/Divider.tsx
deleted file mode 100644
index 1da0a71e..00000000
--- a/packages/mobile/components/ui/Divider.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { View } from "react-native";
-
-import { cn } from "@/lib/utils";
-
-function Divider({
- color = "#DFE4EA",
- className,
- orientation,
- ...props
-}: {
- color?: string;
- orientation: "horizontal" | "vertical";
-} & React.ComponentPropsWithoutRef<typeof View>) {
- const dividerStyles = [{ backgroundColor: color }];
-
- return (
- <View
- className={cn(
- orientation === "horizontal" ? "h-0.5" : "w-0.5",
- className,
- )}
- style={dividerStyles}
- {...props}
- />
- );
-}
-
-export { Divider };
diff --git a/packages/mobile/components/ui/FullPageSpinner.tsx b/packages/mobile/components/ui/FullPageSpinner.tsx
deleted file mode 100644
index 01187f11..00000000
--- a/packages/mobile/components/ui/FullPageSpinner.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { View, ActivityIndicator } from "react-native";
-
-export default function FullPageSpinner() {
- return (
- <View className="h-full w-full items-center justify-center">
- <ActivityIndicator />
- </View>
- );
-}
diff --git a/packages/mobile/components/ui/Input.tsx b/packages/mobile/components/ui/Input.tsx
deleted file mode 100644
index 2fcb2764..00000000
--- a/packages/mobile/components/ui/Input.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { forwardRef } from "react";
-import { Text, TextInput, View } from "react-native";
-
-import { cn } from "@/lib/utils";
-
-export interface InputProps
- extends React.ComponentPropsWithoutRef<typeof TextInput> {
- label?: string;
- labelClasses?: string;
- inputClasses?: string;
-}
-
-const Input = forwardRef<React.ElementRef<typeof TextInput>, InputProps>(
- ({ className, label, labelClasses, inputClasses, ...props }, ref) => (
- <View className={cn("flex flex-col gap-1.5", className)}>
- {label && <Text className={cn("text-base", labelClasses)}>{label}</Text>}
- <TextInput
- className={cn(
- inputClasses,
- "border-input rounded-lg border px-4 py-2.5",
- )}
- {...props}
- />
- </View>
- ),
-);
-
-export { Input };
diff --git a/packages/mobile/components/ui/Skeleton.tsx b/packages/mobile/components/ui/Skeleton.tsx
deleted file mode 100644
index 68b22e1e..00000000
--- a/packages/mobile/components/ui/Skeleton.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { useEffect, useRef } from "react";
-import { Animated, type View } from "react-native";
-
-import { cn } from "@/lib/utils";
-
-function Skeleton({
- className,
- ...props
-}: { className?: string } & React.ComponentPropsWithoutRef<typeof View>) {
- const fadeAnim = useRef(new Animated.Value(0.5)).current;
-
- useEffect(() => {
- Animated.loop(
- Animated.sequence([
- Animated.timing(fadeAnim, {
- toValue: 1,
- duration: 1000,
- useNativeDriver: true,
- }),
- Animated.timing(fadeAnim, {
- toValue: 0.5,
- duration: 1000,
- useNativeDriver: true,
- }),
- ]),
- ).start();
- }, [fadeAnim]);
-
- return (
- <Animated.View
- className={cn("bg-muted rounded-md", className)}
- style={[{ opacity: fadeAnim }]}
- {...props}
- />
- );
-}
-
-export { Skeleton };
diff --git a/packages/mobile/components/ui/Toast.tsx b/packages/mobile/components/ui/Toast.tsx
deleted file mode 100644
index fb319f84..00000000
--- a/packages/mobile/components/ui/Toast.tsx
+++ /dev/null
@@ -1,183 +0,0 @@
-import { createContext, useContext, useEffect, useRef, useState } from "react";
-import { Animated, Text, View } from "react-native";
-
-import { cn } from "@/lib/utils";
-
-const toastVariants = {
- default: "bg-foreground",
- destructive: "bg-destructive",
- success: "bg-green-500",
- info: "bg-blue-500",
-};
-
-interface ToastProps {
- id: number;
- message: string;
- onHide: (id: number) => void;
- variant?: keyof typeof toastVariants;
- duration?: number;
- showProgress?: boolean;
-}
-function Toast({
- id,
- message,
- onHide,
- variant = "default",
- duration = 3000,
- showProgress = true,
-}: ToastProps) {
- const opacity = useRef(new Animated.Value(0)).current;
- const progress = useRef(new Animated.Value(0)).current;
-
- useEffect(() => {
- Animated.sequence([
- Animated.timing(opacity, {
- toValue: 1,
- duration: 500,
- useNativeDriver: true,
- }),
- Animated.timing(progress, {
- toValue: 1,
- duration: duration - 1000,
- useNativeDriver: false,
- }),
- Animated.timing(opacity, {
- toValue: 0,
- duration: 500,
- useNativeDriver: true,
- }),
- ]).start(() => onHide(id));
- }, [duration]);
-
- return (
- <Animated.View
- className={`
- ${toastVariants[variant]}
- m-2 mb-1 transform rounded-lg p-4 shadow-md transition-all
- `}
- style={{
- opacity,
- transform: [
- {
- translateY: opacity.interpolate({
- inputRange: [0, 1],
- outputRange: [-20, 0],
- }),
- },
- ],
- }}
- >
- <Text className="text-background text-left font-semibold">{message}</Text>
- {showProgress && (
- <View className="mt-2 rounded">
- <Animated.View
- className="h-2 rounded bg-white opacity-30 dark:bg-black"
- style={{
- width: progress.interpolate({
- inputRange: [0, 1],
- outputRange: ["0%", "100%"],
- }),
- }}
- />
- </View>
- )}
- </Animated.View>
- );
-}
-
-type ToastVariant = keyof typeof toastVariants;
-
-interface ToastMessage {
- id: number;
- text: string;
- variant: ToastVariant;
- duration?: number;
- position?: string;
- showProgress?: boolean;
-}
-interface ToastContextProps {
- toast: (t: {
- message: string;
- variant?: keyof typeof toastVariants;
- duration?: number;
- position?: "top" | "bottom";
- showProgress?: boolean;
- }) => void;
- removeToast: (id: number) => void;
-}
-const ToastContext = createContext<ToastContextProps | undefined>(undefined);
-
-// TODO: refactor to pass position to Toast instead of ToastProvider
-function ToastProvider({
- children,
- position = "top",
-}: {
- children: React.ReactNode;
- position?: "top" | "bottom";
-}) {
- const [messages, setMessages] = useState<ToastMessage[]>([]);
-
- const toast: ToastContextProps["toast"] = ({
- message,
- variant = "default",
- duration = 3000,
- position = "top",
- showProgress = true,
- }: {
- message: string;
- variant?: ToastVariant;
- duration?: number;
- position?: "top" | "bottom";
- showProgress?: boolean;
- }) => {
- setMessages((prev) => [
- ...prev,
- {
- id: Date.now(),
- text: message,
- variant,
- duration,
- position,
- showProgress,
- },
- ]);
- };
-
- const removeToast = (id: number) => {
- setMessages((prev) => prev.filter((message) => message.id !== id));
- };
-
- return (
- <ToastContext.Provider value={{ toast, removeToast }}>
- {children}
- <View
- className={cn("absolute left-0 right-0", {
- "top-[45px]": position === "top",
- "bottom-0": position === "bottom",
- })}
- >
- {messages.map((message) => (
- <Toast
- key={message.id}
- id={message.id}
- message={message.text}
- variant={message.variant}
- duration={message.duration}
- showProgress={message.showProgress}
- onHide={removeToast}
- />
- ))}
- </View>
- </ToastContext.Provider>
- );
-}
-
-function useToast() {
- const context = useContext(ToastContext);
- if (!context) {
- throw new Error("useToast must be used within ToastProvider");
- }
- return context;
-}
-
-export { ToastProvider, ToastVariant, Toast, toastVariants, useToast };