diff --git a/.env.example b/.env.example index 2e8198c..e59b418 100644 --- a/.env.example +++ b/.env.example @@ -18,3 +18,4 @@ AUTH_SECRET='supersecret' # @see https://next-auth.js.org/providers/discord AUTH_DISCORD_ID='' AUTH_DISCORD_SECRET='' +DATABASE_URL='' \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdd48bb..564ed4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: run: cp .env.example .env - name: Lint - run: pnpm lint && pnpm lint:ws + run: pnpm lint format: runs-on: ubuntu-latest diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 4e58391..511e489 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,9 +1,8 @@ { "recommendations": [ "bradlc.vscode-tailwindcss", - "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", "expo.vscode-expo-tools", - "yoavbls.pretty-ts-errors" + "yoavbls.pretty-ts-errors", + "biomejs.biome" ] -} +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index b4c2709..2dab4e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,15 +1,11 @@ { "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" + "source.organizeImports.biome": "explicit", + "source.fixAll.biome": "explicit", + "quickfix.biome": true }, - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "biomejs.biome", "editor.formatOnSave": true, - "eslint.rules.customizations": [{ "rule": "*", "severity": "warn" }], - "eslint.workingDirectories": [ - { "pattern": "apps/*/" }, - { "pattern": "packages/*/" }, - { "pattern": "tooling/*/" } - ], "tailwindCSS.experimental.configFile": "./tooling/tailwind/index.ts", "typescript.enablePromptUseWorkspaceTsdk": true, "typescript.tsdk": "node_modules/typescript/lib", @@ -17,4 +13,4 @@ "next/router.d.ts", "next/dist/client/router.d.ts" ] -} +} \ No newline at end of file diff --git a/apps/auth-proxy/biome.json b/apps/auth-proxy/biome.json new file mode 100644 index 0000000..022bcf8 --- /dev/null +++ b/apps/auth-proxy/biome.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "../../biome.json" + ] +} \ No newline at end of file diff --git a/apps/auth-proxy/package.json b/apps/auth-proxy/package.json index 2514a41..467214c 100644 --- a/apps/auth-proxy/package.json +++ b/apps/auth-proxy/package.json @@ -6,28 +6,18 @@ "build": "nitro build", "clean": "rm -rf .turbo node_modules", "dev": "nitro dev --port 3001", - "lint": "eslint .", - "format": "prettier --check . --ignore-path ../../.gitignore", + "lint": "biome lint ./routes", + "format": "biome format ./routes ", "typecheck": "tsc --noEmit" }, "dependencies": { "@auth/core": "^0.18.0" }, "devDependencies": { - "@acme/eslint-config": "workspace:^0.2.0", - "@acme/prettier-config": "workspace:^0.1.0", + "@biomejs/biome": "^1.5.3", "@acme/tailwind-config": "workspace:^0.1.0", "@acme/tsconfig": "workspace:^0.1.0", - "eslint": "^8.53.0", "nitropack": "^2.7.2", - "prettier": "^3.1.0", "typescript": "^5.2.2" - }, - "eslintConfig": { - "root": true, - "extends": [ - "@acme/eslint-config/base" - ] - }, - "prettier": "@acme/prettier-config" -} + } +} \ No newline at end of file diff --git a/apps/auth-proxy/routes/[...auth].ts b/apps/auth-proxy/routes/[...auth].ts index f3f737b..480ca4e 100644 --- a/apps/auth-proxy/routes/[...auth].ts +++ b/apps/auth-proxy/routes/[...auth].ts @@ -3,15 +3,15 @@ import Discord from "@auth/core/providers/discord"; import { eventHandler, toWebRequest } from "h3"; export default eventHandler(async (event) => - Auth(toWebRequest(event), { - secret: process.env.AUTH_SECRET, - trustHost: !!process.env.VERCEL, - redirectProxyUrl: process.env.AUTH_REDIRECT_PROXY_URL, - providers: [ - Discord({ - clientId: process.env.AUTH_DISCORD_ID, - clientSecret: process.env.AUTH_DISCORD_SECRET, - }), - ], - }), + Auth(toWebRequest(event), { + secret: process.env.AUTH_SECRET, + trustHost: !!process.env.VERCEL, + redirectProxyUrl: process.env.AUTH_REDIRECT_PROXY_URL, + providers: [ + Discord({ + clientId: process.env.AUTH_DISCORD_ID, + clientSecret: process.env.AUTH_DISCORD_SECRET, + }), + ], + }), ); diff --git a/apps/native/biome.json b/apps/native/biome.json new file mode 100644 index 0000000..022bcf8 --- /dev/null +++ b/apps/native/biome.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "../../biome.json" + ] +} \ No newline at end of file diff --git a/apps/native/package.json b/apps/native/package.json index 2cd0ef2..c97f8b0 100644 --- a/apps/native/package.json +++ b/apps/native/package.json @@ -8,8 +8,8 @@ "dev": "expo start --go", "dev:android": "expo start --android", "dev:ios": "expo start --ios", - "lint": "eslint .", - "format": "prettier --check . --ignore-path ../../.gitignore", + "lint": "biome lint ./src", + "format": "biome format ./src ", "typecheck": "tsc --noEmit", "android": "expo run:android", "ios": "expo run:ios" @@ -41,9 +41,8 @@ "tailwind-merge": "^2.2.1" }, "devDependencies": { + "@biomejs/biome": "^1.5.3", "@acme/api": "workspace:^0.1.0", - "@acme/eslint-config": "workspace:^0.2.0", - "@acme/prettier-config": "workspace:^0.1.0", "@acme/tailwind-config": "workspace:^0.1.0", "@acme/tsconfig": "workspace:^0.1.0", "@babel/core": "^7.23.2", @@ -52,20 +51,7 @@ "@expo/config-plugins": "^7.2.5", "@types/babel__core": "^7.20.4", "@types/react": "^18.2.37", - "eslint": "^8.53.0", - "prettier": "^3.1.0", "tailwindcss": "3.3.5", "typescript": "^5.2.2" - }, - "eslintConfig": { - "root": true, - "extends": [ - "@acme/eslint-config/base", - "@acme/eslint-config/react" - ], - "ignorePatterns": [ - "expo-plugins/**" - ] - }, - "prettier": "@acme/prettier-config" + } } \ No newline at end of file diff --git a/apps/native/src/app/_layout.tsx b/apps/native/src/app/_layout.tsx index 4af7c90..eea4439 100644 --- a/apps/native/src/app/_layout.tsx +++ b/apps/native/src/app/_layout.tsx @@ -7,11 +7,11 @@ import { TRPCProvider } from "~/utils/api"; import "../styles.css"; const RootLayout = () => { - return ( - - - - ); + return ( + + + + ); }; export default RootLayout; diff --git a/apps/native/src/app/index.tsx b/apps/native/src/app/index.tsx index 1ca63ce..c27873b 100644 --- a/apps/native/src/app/index.tsx +++ b/apps/native/src/app/index.tsx @@ -4,25 +4,18 @@ import { SafeAreaView } from "react-native-safe-area-context"; import { Button } from "~/components/ui/button"; import { Card } from "~/components/ui/card"; - const Index = () => { - - return ( - - - - - - - - - - - - - ); + return ( + + + + + + + + + + ); }; export default Index; diff --git a/apps/native/src/app/post/[id].tsx b/apps/native/src/app/post/[id].tsx index 5295b57..ed83c72 100644 --- a/apps/native/src/app/post/[id].tsx +++ b/apps/native/src/app/post/[id].tsx @@ -4,19 +4,19 @@ import { Stack, useGlobalSearchParams } from "expo-router"; import { api } from "~/utils/api"; export default function Post() { - const { id } = useGlobalSearchParams(); - if (!id || typeof id !== "string") throw new Error("unreachable"); - const { data } = api.post.byId.useQuery({ id: parseInt(id) }); + const { id } = useGlobalSearchParams(); + if (!id || typeof id !== "string") throw new Error("unreachable"); + const { data } = api.post.byId.useQuery({ id: parseInt(id) }); - if (!data) return null; + if (!data) return null; - return ( - - - - {data.title} - {data.content} - - - ); + return ( + + + + {data.title} + {data.content} + + + ); } diff --git a/apps/native/src/components/DrawerToggle.tsx b/apps/native/src/components/DrawerToggle.tsx index 2a4ee48..3fbacf9 100644 --- a/apps/native/src/components/DrawerToggle.tsx +++ b/apps/native/src/components/DrawerToggle.tsx @@ -1,31 +1,31 @@ -import { DrawerNavigationProp } from '@react-navigation/drawer'; -import { useNavigation } from 'expo-router'; -import { AlignJustify } from 'lucide-react-native'; -import { Pressable, View } from 'react-native'; -import { cn } from '~/lib/utils'; +import { DrawerNavigationProp } from "@react-navigation/drawer"; +import { useNavigation } from "expo-router"; +import { AlignJustify } from "lucide-react-native"; +import { Pressable, View } from "react-native"; +import { cn } from "~/lib/utils"; export function DrawerToggle() { - const navigation = useNavigation>(); + const navigation = useNavigation>(); - return ( - - {({ pressed }) => ( - - - - )} - - ); + return ( + + {({ pressed }) => ( + + + + )} + + ); } diff --git a/apps/native/src/components/ThemeToggle.tsx b/apps/native/src/components/ThemeToggle.tsx index 546ccf0..285df23 100644 --- a/apps/native/src/components/ThemeToggle.tsx +++ b/apps/native/src/components/ThemeToggle.tsx @@ -1,40 +1,40 @@ -import AsyncStorage from '@react-native-async-storage/async-storage'; -import { MoonStar, Sun } from 'lucide-react-native'; -import { useColorScheme } from 'nativewind'; -import { Pressable, View } from 'react-native'; -import { setAndroidNavigationBar } from '~/lib/android-navigation-bar'; -import { cn } from '~/lib/utils'; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { MoonStar, Sun } from "lucide-react-native"; +import { useColorScheme } from "nativewind"; +import { Pressable, View } from "react-native"; +import { setAndroidNavigationBar } from "~/lib/android-navigation-bar"; +import { cn } from "~/lib/utils"; export function ThemeToggle() { - const { colorScheme, setColorScheme } = useColorScheme(); - return ( - { - const newTheme = colorScheme === 'dark' ? 'light' : 'dark'; - setColorScheme(newTheme); - setAndroidNavigationBar(newTheme); - AsyncStorage.setItem('theme', newTheme); - }} - className='ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50' - > - {({ pressed }) => ( - - {colorScheme === 'light' ? ( - - ) : ( - - )} - - )} - - ); + const { colorScheme, setColorScheme } = useColorScheme(); + return ( + { + const newTheme = colorScheme === "dark" ? "light" : "dark"; + setColorScheme(newTheme); + setAndroidNavigationBar(newTheme); + AsyncStorage.setItem("theme", newTheme); + }} + className="ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50" + > + {({ pressed }) => ( + + {colorScheme === "light" ? ( + + ) : ( + + )} + + )} + + ); } diff --git a/apps/native/src/components/ui/accordion.tsx b/apps/native/src/components/ui/accordion.tsx index 35e46f7..3b3d0df 100644 --- a/apps/native/src/components/ui/accordion.tsx +++ b/apps/native/src/components/ui/accordion.tsx @@ -1,205 +1,205 @@ -import { ChevronDown } from 'lucide-react-native'; -import React from 'react'; -import { LayoutChangeEvent, Pressable, View } from 'react-native'; +import { ChevronDown } from "lucide-react-native"; +import React from "react"; +import { LayoutChangeEvent, Pressable, View } from "react-native"; import Animated, { - Extrapolate, - SharedValue, - interpolate, - measure, - runOnUI, - useAnimatedStyle, - useDerivedValue, - useSharedValue, - withTiming, -} from 'react-native-reanimated'; -import { Separator } from '~/components/ui/separator'; -import { cn } from '~/lib/utils'; + Extrapolate, + SharedValue, + interpolate, + measure, + runOnUI, + useAnimatedStyle, + useDerivedValue, + useSharedValue, + withTiming, +} from "react-native-reanimated"; +import { Separator } from "~/components/ui/separator"; +import { cn } from "~/lib/utils"; const Accordion = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -Accordion.displayName = 'Accordion'; +Accordion.displayName = "Accordion"; interface AccordionItemProps { - disabled?: boolean; - defaultOpen?: boolean; - onChange?: (isOpen: boolean) => void; + disabled?: boolean; + defaultOpen?: boolean; + onChange?: (isOpen: boolean) => void; } interface AccordionItemContext extends AccordionItemProps { - innerContentRef: React.RefObject; - contentHeight: SharedValue; - progress: SharedValue; - open: SharedValue; - nativeID: string; + innerContentRef: React.RefObject; + contentHeight: SharedValue; + progress: SharedValue; + open: SharedValue; + nativeID: string; } const AccordionItemContext = React.createContext( - {} as AccordionItemContext + {} as AccordionItemContext, ); const AccordionItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & AccordionItemProps + React.ElementRef, + React.ComponentPropsWithoutRef & AccordionItemProps >( - ( - { className, disabled = false, defaultOpen = false, onChange, ...props }, - ref - ) => { - const nativeID = React.useId(); - const open = useSharedValue(defaultOpen); - const contentHeight = useSharedValue(0); - const innerContentRef = React.useRef(null); - const progress = useDerivedValue(() => - open.value ? withTiming(1) : withTiming(0) - ); - return ( - - - - ); - } + ( + { className, disabled = false, defaultOpen = false, onChange, ...props }, + ref, + ) => { + const nativeID = React.useId(); + const open = useSharedValue(defaultOpen); + const contentHeight = useSharedValue(0); + const innerContentRef = React.useRef(null); + const progress = useDerivedValue(() => + open.value ? withTiming(1) : withTiming(0), + ); + return ( + + + + ); + }, ); -AccordionItem.displayName = 'AccordionItem'; +AccordionItem.displayName = "AccordionItem"; function useAccordionItemContext() { - const context = React.useContext(AccordionItemContext); - if (!context) { - throw new Error( - 'AccordionItem compound components cannot be rendered outside the AccordionItem component' - ); - } - return context; + const context = React.useContext(AccordionItemContext); + if (!context) { + throw new Error( + "AccordionItem compound components cannot be rendered outside the AccordionItem component", + ); + } + return context; } const AccordionTrigger = React.forwardRef< - React.ElementRef, - Omit, 'onPress'> & { - children: React.ReactNode; - } + React.ElementRef, + Omit, "onPress"> & { + children: React.ReactNode; + } >(({ children, className, ...props }, ref) => { - const { - contentHeight, - open, - innerContentRef, - onChange, - disabled, - nativeID, - progress, - } = useAccordionItemContext(); - const [isOpen, setIsOpen] = React.useState(open.value); - - const chevronAnimationStyle = useAnimatedStyle(() => ({ - transform: [ - { - rotate: - contentHeight.value === 0 ? '0deg' : `${progress.value * 180}deg`, - }, - ], - opacity: interpolate(progress.value, [0, 1], [1, 0.8], Extrapolate.CLAMP), - })); - - function onPress() { - if (disabled) return; - if (contentHeight.value === 0) { - runOnUI(() => { - 'worklet'; - contentHeight.value = measure(innerContentRef).height; - })(); - } - open.value = !open.value; - setIsOpen(open.value); - onChange?.(open.value); - } - - return ( - <> - - {children} - - - - - - - ); + const { + contentHeight, + open, + innerContentRef, + onChange, + disabled, + nativeID, + progress, + } = useAccordionItemContext(); + const [isOpen, setIsOpen] = React.useState(open.value); + + const chevronAnimationStyle = useAnimatedStyle(() => ({ + transform: [ + { + rotate: + contentHeight.value === 0 ? "0deg" : `${progress.value * 180}deg`, + }, + ], + opacity: interpolate(progress.value, [0, 1], [1, 0.8], Extrapolate.CLAMP), + })); + + function onPress() { + if (disabled) return; + if (contentHeight.value === 0) { + runOnUI(() => { + "worklet"; + contentHeight.value = measure(innerContentRef).height; + })(); + } + open.value = !open.value; + setIsOpen(open.value); + onChange?.(open.value); + } + + return ( + <> + + {children} + + + + + + + ); }); -AccordionTrigger.displayName = 'AccordionTrigger'; +AccordionTrigger.displayName = "AccordionTrigger"; const AccordionContent = React.forwardRef< - React.ElementRef, - Omit, 'onLayout'> & { - children: React.ReactNode; - } + React.ElementRef, + Omit, "onLayout"> & { + children: React.ReactNode; + } >(({ children, className, ...props }, ref) => { - const { contentHeight, innerContentRef, nativeID, progress } = - useAccordionItemContext(); - - const heightAnimationStyle = useAnimatedStyle(() => ({ - height: interpolate( - progress.value, - [0, 1], - [0, contentHeight.value], - Extrapolate.CLAMP - ), - })); - - const onLayout = React.useCallback( - ({ - nativeEvent: { - layout: { height }, - }, - }: LayoutChangeEvent) => { - contentHeight.value = height; - }, - [contentHeight] - ); - - return ( - - - - {children} - - - - ); + const { contentHeight, innerContentRef, nativeID, progress } = + useAccordionItemContext(); + + const heightAnimationStyle = useAnimatedStyle(() => ({ + height: interpolate( + progress.value, + [0, 1], + [0, contentHeight.value], + Extrapolate.CLAMP, + ), + })); + + const onLayout = React.useCallback( + ({ + nativeEvent: { + layout: { height }, + }, + }: LayoutChangeEvent) => { + contentHeight.value = height; + }, + [contentHeight], + ); + + return ( + + + + {children} + + + + ); }); -AccordionContent.displayName = 'AccordionContent'; +AccordionContent.displayName = "AccordionContent"; export { Accordion, AccordionContent, AccordionItem, AccordionTrigger }; diff --git a/apps/native/src/components/ui/alert-dialog.tsx b/apps/native/src/components/ui/alert-dialog.tsx index d958671..c4f912b 100644 --- a/apps/native/src/components/ui/alert-dialog.tsx +++ b/apps/native/src/components/ui/alert-dialog.tsx @@ -1,300 +1,300 @@ -import { useColorScheme } from 'nativewind'; -import React from 'react'; +import { useColorScheme } from "nativewind"; +import React from "react"; import { - GestureResponderEvent, - Modal, - Pressable, - StyleSheet, - Text, - View, - ViewStyle, -} from 'react-native'; -import { cn } from '~/lib/utils'; -import { Button } from '~/components/ui/button'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; + GestureResponderEvent, + Modal, + Pressable, + StyleSheet, + Text, + View, + ViewStyle, +} from "react-native"; +import { cn } from "~/lib/utils"; +import { Button } from "~/components/ui/button"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; interface AlertDialogProps { - children: React.ReactNode; - closeOnOverlayPress?: boolean; - defaultOpen?: boolean; - open?: boolean; - setOpen?: React.Dispatch>; + children: React.ReactNode; + closeOnOverlayPress?: boolean; + defaultOpen?: boolean; + open?: boolean; + setOpen?: React.Dispatch>; } interface AlertDialogContext { - visible: boolean; - setVisible: React.Dispatch>; - closeOnOverlayPress: boolean; + visible: boolean; + setVisible: React.Dispatch>; + closeOnOverlayPress: boolean; } const AlertDialogContext = React.createContext( - {} as AlertDialogContext + {} as AlertDialogContext, ); const AlertDialog = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & AlertDialogProps + React.ElementRef, + React.ComponentPropsWithoutRef & AlertDialogProps >( - ( - { - open, - setOpen, - closeOnOverlayPress = false, - defaultOpen = false, - ...props - }, - ref - ) => { - const [visible, setVisible] = React.useState(defaultOpen ?? false); - return ( - - - - ); - } + ( + { + open, + setOpen, + closeOnOverlayPress = false, + defaultOpen = false, + ...props + }, + ref, + ) => { + const [visible, setVisible] = React.useState(defaultOpen ?? false); + return ( + + + + ); + }, ); -AlertDialog.displayName = 'AlertDialog'; +AlertDialog.displayName = "AlertDialog"; function useAlertDialogContext() { - const context = React.useContext(AlertDialogContext); - if (!context) { - throw new Error( - 'AlertDialog compound components cannot be rendered outside the AlertDialog component' - ); - } - return context; + const context = React.useContext(AlertDialogContext); + if (!context) { + throw new Error( + "AlertDialog compound components cannot be rendered outside the AlertDialog component", + ); + } + return context; } const AlertDialogTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } >(({ onPress, asChild = false, ...props }, ref) => { - const { setVisible } = useAlertDialogContext(); - function handleOnPress(event: GestureResponderEvent) { - setVisible(true); - onPress?.(event); - } + const { setVisible } = useAlertDialogContext(); + function handleOnPress(event: GestureResponderEvent) { + setVisible(true); + onPress?.(event); + } - const Trigger = asChild ? Slot.Pressable : Button; - return ; + const Trigger = asChild ? Slot.Pressable : Button; + return ; }); -AlertDialogTrigger.displayName = 'AlertDialogTrigger'; +AlertDialogTrigger.displayName = "AlertDialogTrigger"; const AlertDialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { overlayClass?: string } + React.ElementRef, + React.ComponentPropsWithoutRef & { overlayClass?: string } >( - ( - { - className, - children, - animationType = 'fade', - style: styleProp, - overlayClass, - ...props - }, - ref - ) => { - const { colorScheme } = useColorScheme(); - const { visible, setVisible, closeOnOverlayPress } = - useAlertDialogContext(); - const [style, setStyle] = React.useState( - StyleSheet.flatten(styleProp) - ); + ( + { + className, + children, + animationType = "fade", + style: styleProp, + overlayClass, + ...props + }, + ref, + ) => { + const { colorScheme } = useColorScheme(); + const { visible, setVisible, closeOnOverlayPress } = + useAlertDialogContext(); + const [style, setStyle] = React.useState( + StyleSheet.flatten(styleProp), + ); - React.useEffect(() => { - setStyle( - StyleSheet.flatten([ - colorScheme === 'dark' ? styles.shadowDark : styles.shadowLight, - styleProp, - ]) - ); - }, [styleProp, colorScheme]); + React.useEffect(() => { + setStyle( + StyleSheet.flatten([ + colorScheme === "dark" ? styles.shadowDark : styles.shadowLight, + styleProp, + ]), + ); + }, [styleProp, colorScheme]); - return ( - { - setVisible((prev) => !prev); - }} - statusBarTranslucent - {...props} - > - { - setVisible(false); - } - : undefined - } - className={cn( - 'flex-1 justify-center items-center p-2', - animationType !== 'slide' && 'bg-zinc-50/80 dark:bg-zinc-900/80', - overlayClass - )} - > - - {children} - - - - ); - } + return ( + { + setVisible((prev) => !prev); + }} + statusBarTranslucent + {...props} + > + { + setVisible(false); + } + : undefined + } + className={cn( + "flex-1 justify-center items-center p-2", + animationType !== "slide" && "bg-zinc-50/80 dark:bg-zinc-900/80", + overlayClass, + )} + > + + {children} + + + + ); + }, ); -AlertDialogContent.displayName = 'AlertDialogContent'; +AlertDialogContent.displayName = "AlertDialogContent"; const AlertDialogHeader = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ; + return ; }); -AlertDialogHeader.displayName = 'AlertDialogHeader'; +AlertDialogHeader.displayName = "AlertDialogHeader"; const AlertDialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); -AlertDialogTitle.displayName = 'AlertDialogTitle'; +AlertDialogTitle.displayName = "AlertDialogTitle"; const AlertDialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); -AlertDialogDescription.displayName = 'AlertDialogDescription'; +AlertDialogDescription.displayName = "AlertDialogDescription"; const AlertDialogFooter = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); -AlertDialogFooter.displayName = 'AlertDialogFooter'; +AlertDialogFooter.displayName = "AlertDialogFooter"; const AlertDialogCancel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } ->(({ variant = 'outline', asChild = false, ...props }, ref) => { - const { setVisible } = useAlertDialogContext(); - const Trigger = asChild ? Slot.Pressable : Button; - return ( - { - setVisible(false); - }} - ref={ref} - {...props} - /> - ); + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } +>(({ variant = "outline", asChild = false, ...props }, ref) => { + const { setVisible } = useAlertDialogContext(); + const Trigger = asChild ? Slot.Pressable : Button; + return ( + { + setVisible(false); + }} + ref={ref} + {...props} + /> + ); }); -AlertDialogCancel.displayName = 'AlertDialogCancel'; +AlertDialogCancel.displayName = "AlertDialogCancel"; type ButtonProps = React.ComponentPropsWithoutRef; const AlertDialogAction = React.forwardRef< - React.ElementRef, - Omit & { - asChild?: boolean; - onPress?: - | ((event: GestureResponderEvent) => void) - | ((event: GestureResponderEvent) => Promise); - } + React.ElementRef, + Omit & { + asChild?: boolean; + onPress?: + | ((event: GestureResponderEvent) => void) + | ((event: GestureResponderEvent) => Promise); + } >(({ onPress, asChild, ...props }, ref) => { - const { setVisible } = useAlertDialogContext(); - async function onPressAction(ev: GestureResponderEvent) { - await onPress?.(ev); - setVisible(false); - } + const { setVisible } = useAlertDialogContext(); + async function onPressAction(ev: GestureResponderEvent) { + await onPress?.(ev); + setVisible(false); + } - const Trigger = asChild ? Slot.Pressable : Button; - return ; + const Trigger = asChild ? Slot.Pressable : Button; + return ; }); -AlertDialogAction.displayName = 'AlertDialogAction'; +AlertDialogAction.displayName = "AlertDialogAction"; export { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, - AlertDialogTrigger, + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, }; const styles = StyleSheet.create({ - shadowLight: { - shadowColor: '#000000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.1, - shadowRadius: 8, - elevation: 5, - }, - shadowDark: { - shadowColor: '#000000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.25, - shadowRadius: 8, - elevation: 5, - }, + shadowLight: { + shadowColor: "#000000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.1, + shadowRadius: 8, + elevation: 5, + }, + shadowDark: { + shadowColor: "#000000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 8, + elevation: 5, + }, }); diff --git a/apps/native/src/components/ui/alert.tsx b/apps/native/src/components/ui/alert.tsx index c402304..2bebcc3 100644 --- a/apps/native/src/components/ui/alert.tsx +++ b/apps/native/src/components/ui/alert.tsx @@ -1,129 +1,129 @@ -import * as React from 'react'; -import { cva, type VariantProps } from 'class-variance-authority'; +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from '~/lib/utils'; -import { View, Text, StyleSheet, ViewStyle } from 'react-native'; -import * as LucideIcon from 'lucide-react-native'; -import { useColorScheme } from 'nativewind'; +import { cn } from "~/lib/utils"; +import { View, Text, StyleSheet, ViewStyle } from "react-native"; +import * as LucideIcon from "lucide-react-native"; +import { useColorScheme } from "nativewind"; const alertVariants = cva( - 'bg-background relative w-full rounded-lg border p-5', - { - variants: { - variant: { - default: 'border-muted-foreground', - destructive: 'border-destructive', - success: 'border-emerald-500', - }, - }, - defaultVariants: { - variant: 'default', - }, - } + "bg-background relative w-full rounded-lg border p-5", + { + variants: { + variant: { + default: "border-muted-foreground", + destructive: "border-destructive", + success: "border-emerald-500", + }, + }, + defaultVariants: { + variant: "default", + }, + }, ); const Alert = React.forwardRef< - React.ElementRef, - Omit, 'style'> & - VariantProps & { - icon?: keyof typeof LucideIcon; - style?: ViewStyle; - } + React.ElementRef, + Omit, "style"> & + VariantProps & { + icon?: keyof typeof LucideIcon; + style?: ViewStyle; + } >(({ children, icon, className, variant, style: styleProp, ...props }, ref) => { - const { colorScheme } = useColorScheme(); - const [style, setStyle] = React.useState( - StyleSheet.flatten(styleProp) - ); + const { colorScheme } = useColorScheme(); + const [style, setStyle] = React.useState( + StyleSheet.flatten(styleProp), + ); - React.useEffect(() => { - setStyle( - StyleSheet.flatten([ - colorScheme === 'dark' ? styles.shadowDark : styles.shadowLight, - styleProp, - ]) - ); - }, [styleProp, colorScheme]); + React.useEffect(() => { + setStyle( + StyleSheet.flatten([ + colorScheme === "dark" ? styles.shadowDark : styles.shadowLight, + styleProp, + ]), + ); + }, [styleProp, colorScheme]); - const Icon = LucideIcon[icon ?? 'AlertTriangle'] as LucideIcon.Icon; - return ( - - {icon && ( - - )} - {children} - - ); + const Icon = LucideIcon[icon ?? "AlertTriangle"] as LucideIcon.Icon; + return ( + + {icon && ( + + )} + {children} + + ); }); -Alert.displayName = 'Alert'; +Alert.displayName = "Alert"; const AlertTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -AlertTitle.displayName = 'AlertTitle'; +AlertTitle.displayName = "AlertTitle"; const AlertDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -AlertDescription.displayName = 'AlertDescription'; +AlertDescription.displayName = "AlertDescription"; export { Alert, AlertTitle, AlertDescription }; const styles = StyleSheet.create({ - shadowLight: { - shadowColor: '#000000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.1, - shadowRadius: 8, - elevation: 2, - }, - shadowDark: { - shadowColor: '#FFFFFF', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.05, - shadowRadius: 8, - elevation: 1, - }, + shadowLight: { + shadowColor: "#000000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.1, + shadowRadius: 8, + elevation: 2, + }, + shadowDark: { + shadowColor: "#FFFFFF", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.05, + shadowRadius: 8, + elevation: 1, + }, }); diff --git a/apps/native/src/components/ui/avatar.tsx b/apps/native/src/components/ui/avatar.tsx index 84599b2..afad104 100644 --- a/apps/native/src/components/ui/avatar.tsx +++ b/apps/native/src/components/ui/avatar.tsx @@ -1,69 +1,69 @@ -import React from 'react'; +import React from "react"; import { - Image, - ImageErrorEventData, - NativeSyntheticEvent, - Text, - View, -} from 'react-native'; + Image, + ImageErrorEventData, + NativeSyntheticEvent, + Text, + View, +} from "react-native"; -import { cn } from '~/lib/utils'; +import { cn } from "~/lib/utils"; const Avatar = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -Avatar.displayName = 'Avatar'; +Avatar.displayName = "Avatar"; const AvatarImage = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - const [hasError, setHasError] = React.useState(false); + const [hasError, setHasError] = React.useState(false); - function onError(error: NativeSyntheticEvent) { - setHasError(!!error); - } + function onError(error: NativeSyntheticEvent) { + setHasError(!!error); + } - if (hasError) { - return null; - } - return ( - - ); + if (hasError) { + return null; + } + return ( + + ); }); -AvatarImage.displayName = 'AvatarImage'; +AvatarImage.displayName = "AvatarImage"; const AvatarFallback = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { textClass?: string } + React.ElementRef, + React.ComponentPropsWithoutRef & { textClass?: string } >(({ children, textClass, className, ...props }, ref) => ( - - {children} - + + {children} + )); -AvatarFallback.displayName = 'AvatarFallback'; +AvatarFallback.displayName = "AvatarFallback"; export { Avatar, AvatarImage, AvatarFallback }; diff --git a/apps/native/src/components/ui/badge.tsx b/apps/native/src/components/ui/badge.tsx index 6ffbe33..9ce3580 100644 --- a/apps/native/src/components/ui/badge.tsx +++ b/apps/native/src/components/ui/badge.tsx @@ -1,62 +1,62 @@ -import { cva, type VariantProps } from 'class-variance-authority'; -import React from 'react'; -import { Text, View } from 'react-native'; +import { cva, type VariantProps } from "class-variance-authority"; +import React from "react"; +import { Text, View } from "react-native"; const badgeRootVariants = cva( - 'items-center rounded-full border px-2.5 py-0.5', - { - variants: { - variant: { - default: 'border-transparent bg-primary ', - secondary: 'border-transparent bg-secondary ', - destructive: 'border-transparent bg-destructive ', - outline: 'border-border', - }, - }, - defaultVariants: { - variant: 'default', - }, - } + "items-center rounded-full border px-2.5 py-0.5", + { + variants: { + variant: { + default: "border-transparent bg-primary ", + secondary: "border-transparent bg-secondary ", + destructive: "border-transparent bg-destructive ", + outline: "border-border", + }, + }, + defaultVariants: { + variant: "default", + }, + }, ); -const badgeTextVariants = cva('font-semibold', { - variants: { - variant: { - default: 'text-primary-foreground', - secondary: 'text-secondary-foreground', - destructive: 'text-destructive-foreground', - outline: 'text-foreground', - }, - size: { - sm: 'text-xs native:text-sm', - md: 'text-sm native:text-base', - lg: 'text-base native:text-lg', - }, - }, - defaultVariants: { - variant: 'default', - size: 'md', - }, +const badgeTextVariants = cva("font-semibold", { + variants: { + variant: { + default: "text-primary-foreground", + secondary: "text-secondary-foreground", + destructive: "text-destructive-foreground", + outline: "text-foreground", + }, + size: { + sm: "text-xs native:text-sm", + md: "text-sm native:text-base", + lg: "text-base native:text-lg", + }, + }, + defaultVariants: { + variant: "default", + size: "md", + }, }); const Badge = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps & { textClass?: string } + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps & { textClass?: string } >(({ className, children, textClass, variant, size, ...props }, ref) => { - return ( - - - {children} - - - ); + return ( + + + {children} + + + ); }); export { Badge, badgeRootVariants, badgeTextVariants }; diff --git a/apps/native/src/components/ui/bottom-sheet.native.tsx b/apps/native/src/components/ui/bottom-sheet.native.tsx index c9c7022..1a8fd39 100644 --- a/apps/native/src/components/ui/bottom-sheet.native.tsx +++ b/apps/native/src/components/ui/bottom-sheet.native.tsx @@ -1,62 +1,62 @@ import type { - BottomSheetBackdropProps, - BottomSheetFooterProps as GBottomSheetFooterProps, -} from '@gorhom/bottom-sheet'; + BottomSheetBackdropProps, + BottomSheetFooterProps as GBottomSheetFooterProps, +} from "@gorhom/bottom-sheet"; import { - BottomSheetBackdrop, - BottomSheetModal, - BottomSheetFlatList as GBottomSheetFlatList, - BottomSheetFooter as GBottomSheetFooter, - BottomSheetTextInput as GBottomSheetTextInput, - BottomSheetView as GBottomSheetView, - useBottomSheetModal, -} from '@gorhom/bottom-sheet'; -import type { BottomSheetModalMethods } from '@gorhom/bottom-sheet/lib/typescript/types'; -import { X } from 'lucide-react-native'; -import { useColorScheme } from 'nativewind'; -import React, { useCallback, useImperativeHandle } from 'react'; + BottomSheetBackdrop, + BottomSheetModal, + BottomSheetFlatList as GBottomSheetFlatList, + BottomSheetFooter as GBottomSheetFooter, + BottomSheetTextInput as GBottomSheetTextInput, + BottomSheetView as GBottomSheetView, + useBottomSheetModal, +} from "@gorhom/bottom-sheet"; +import type { BottomSheetModalMethods } from "@gorhom/bottom-sheet/lib/typescript/types"; +import { X } from "lucide-react-native"; +import { useColorScheme } from "nativewind"; +import React, { useCallback, useImperativeHandle } from "react"; import { - GestureResponderEvent, - Keyboard, - Pressable, - View, - ViewStyle, -} from 'react-native'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { Button } from '~/components/ui/button'; -import { NAV_THEME } from '~/lib/constants'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; -import { cn } from '~/lib/utils'; + GestureResponderEvent, + Keyboard, + Pressable, + View, + ViewStyle, +} from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { Button } from "~/components/ui/button"; +import { NAV_THEME } from "~/lib/constants"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; +import { cn } from "~/lib/utils"; type BottomSheetRef = React.ElementRef; type BottomSheetProps = React.ComponentPropsWithoutRef; interface BottomSheetContext { - sheetRef: React.RefObject; + sheetRef: React.RefObject; } const BottomSheetContext = React.createContext({} as BottomSheetContext); const BottomSheet = React.forwardRef( - ({ ...props }, ref) => { - const sheetRef = React.useRef(null); + ({ ...props }, ref) => { + const sheetRef = React.useRef(null); - return ( - - - - ); - } + return ( + + + + ); + }, ); function useBottomSheetContext() { - const context = React.useContext(BottomSheetContext); - if (!context) { - throw new Error( - 'BottomSheet compound components cannot be rendered outside the BottomSheet component' - ); - } - return context; + const context = React.useContext(BottomSheetContext); + if (!context) { + throw new Error( + "BottomSheet compound components cannot be rendered outside the BottomSheet component", + ); + } + return context; } const CLOSED_INDEX = -1; @@ -64,293 +64,293 @@ const CLOSED_INDEX = -1; type BottomSheetContentRef = React.ElementRef; type BottomSheetContentProps = Omit< - React.ComponentPropsWithoutRef, - 'backdropComponent' + React.ComponentPropsWithoutRef, + "backdropComponent" > & { - backdropProps?: Partial< - React.ComponentPropsWithoutRef - >; + backdropProps?: Partial< + React.ComponentPropsWithoutRef + >; }; const BottomSheetContent = React.forwardRef< - BottomSheetContentRef, - BottomSheetContentProps + BottomSheetContentRef, + BottomSheetContentProps >( - ( - { - enablePanDownToClose = true, - enableDynamicSizing = true, - index = 0, - backdropProps, - backgroundStyle, - android_keyboardInputMode = 'adjustResize', - ...props - }, - ref - ) => { - const insets = useSafeAreaInsets(); - const { colorScheme } = useColorScheme(); - const { sheetRef } = useBottomSheetContext(); + ( + { + enablePanDownToClose = true, + enableDynamicSizing = true, + index = 0, + backdropProps, + backgroundStyle, + android_keyboardInputMode = "adjustResize", + ...props + }, + ref, + ) => { + const insets = useSafeAreaInsets(); + const { colorScheme } = useColorScheme(); + const { sheetRef } = useBottomSheetContext(); - useImperativeHandle( - ref, - () => { - if (!sheetRef.current) { - return {} as BottomSheetModalMethods; - } - return sheetRef.current; - }, - [sheetRef.current] - ); + useImperativeHandle( + ref, + () => { + if (!sheetRef.current) { + return {} as BottomSheetModalMethods; + } + return sheetRef.current; + }, + [sheetRef.current], + ); - const renderBackdrop = useCallback( - (props: BottomSheetBackdropProps) => { - const { - pressBehavior = 'close', - opacity = colorScheme === 'dark' ? 0.3 : 0.7, - disappearsOnIndex = CLOSED_INDEX, - style, - onPress, - ...rest - } = { - ...props, - ...backdropProps, - }; - return ( - { - if (Keyboard.isVisible()) { - Keyboard.dismiss(); - } - onPress?.(); - }} - {...rest} - /> - ); - }, - [backdropProps, colorScheme] - ); + const renderBackdrop = useCallback( + (props: BottomSheetBackdropProps) => { + const { + pressBehavior = "close", + opacity = colorScheme === "dark" ? 0.3 : 0.7, + disappearsOnIndex = CLOSED_INDEX, + style, + onPress, + ...rest + } = { + ...props, + ...backdropProps, + }; + return ( + { + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + onPress?.(); + }} + {...rest} + /> + ); + }, + [backdropProps, colorScheme], + ); - return ( - - ); - } + return ( + + ); + }, ); const BottomSheetOpenTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } >(({ onPress, asChild = false, ...props }, ref) => { - const { sheetRef } = useBottomSheetContext(); - function handleOnPress(ev: GestureResponderEvent) { - sheetRef.current?.present(); - onPress?.(ev); - } - const Trigger = asChild ? Slot.Pressable : Pressable; - return ; + const { sheetRef } = useBottomSheetContext(); + function handleOnPress(ev: GestureResponderEvent) { + sheetRef.current?.present(); + onPress?.(ev); + } + const Trigger = asChild ? Slot.Pressable : Pressable; + return ; }); const BottomSheetCloseTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } >(({ onPress, asChild = false, ...props }, ref) => { - const { dismiss } = useBottomSheetModal(); - function handleOnPress(ev: GestureResponderEvent) { - dismiss(); - if (Keyboard.isVisible()) { - Keyboard.dismiss(); - } - onPress?.(ev); - } - const Trigger = asChild ? Slot.Pressable : Pressable; - return ; + const { dismiss } = useBottomSheetModal(); + function handleOnPress(ev: GestureResponderEvent) { + dismiss(); + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + onPress?.(ev); + } + const Trigger = asChild ? Slot.Pressable : Pressable; + return ; }); const BOTTOM_SHEET_HEADER_HEIGHT = 60; // BottomSheetHeader height type BottomSheetViewProps = Omit< - React.ComponentPropsWithoutRef, - 'style' + React.ComponentPropsWithoutRef, + "style" > & { - hadHeader?: boolean; - style?: ViewStyle; + hadHeader?: boolean; + style?: ViewStyle; }; function BottomSheetView({ - className, - children, - hadHeader = true, - style, - ...props + className, + children, + hadHeader = true, + style, + ...props }: BottomSheetViewProps) { - const insets = useSafeAreaInsets(); - return ( - - {children} - - ); + const insets = useSafeAreaInsets(); + return ( + + {children} + + ); } type BottomSheetTextInputRef = React.ElementRef; type BottomSheetTextInputProps = React.ComponentPropsWithoutRef< - typeof GBottomSheetTextInput + typeof GBottomSheetTextInput >; const BottomSheetTextInput = React.forwardRef< - BottomSheetTextInputRef, - BottomSheetTextInputProps + BottomSheetTextInputRef, + BottomSheetTextInputProps >(({ className, placeholderClassName, ...props }, ref) => { - return ( - - ); + return ( + + ); }); type BottomSheetFlatListRef = React.ElementRef; type BottomSheetFlatListProps = React.ComponentPropsWithoutRef< - typeof GBottomSheetFlatList + typeof GBottomSheetFlatList >; const BottomSheetFlatList = React.forwardRef< - BottomSheetFlatListRef, - BottomSheetFlatListProps + BottomSheetFlatListRef, + BottomSheetFlatListProps >(({ className, ...props }, ref) => { - const insets = useSafeAreaInsets(); - return ( - - ); + const insets = useSafeAreaInsets(); + return ( + + ); }); type BottomSheetHeaderRef = React.ElementRef; type BottomSheetHeaderProps = React.ComponentPropsWithoutRef; const BottomSheetHeader = React.forwardRef< - BottomSheetHeaderRef, - BottomSheetHeaderProps + BottomSheetHeaderRef, + BottomSheetHeaderProps >(({ className, children, ...props }, ref) => { - const { dismiss } = useBottomSheetModal(); - function close() { - if (Keyboard.isVisible()) { - Keyboard.dismiss(); - } - dismiss(); - } - return ( - - {children} - - - ); + const { dismiss } = useBottomSheetModal(); + function close() { + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + dismiss(); + } + return ( + + {children} + + + ); }); type BottomSheetFooterRef = React.ElementRef; type BottomSheetFooterProps = Omit< - React.ComponentPropsWithoutRef, - 'style' + React.ComponentPropsWithoutRef, + "style" > & { - bottomSheetFooterProps: GBottomSheetFooterProps; - children?: React.ReactNode; - style?: ViewStyle; + bottomSheetFooterProps: GBottomSheetFooterProps; + children?: React.ReactNode; + style?: ViewStyle; }; /** * To be used in a useCallback function as a props to BottomSheetContent */ const BottomSheetFooter = React.forwardRef< - BottomSheetFooterRef, - BottomSheetFooterProps + BottomSheetFooterRef, + BottomSheetFooterProps >(({ bottomSheetFooterProps, children, className, style, ...props }, ref) => { - const insets = useSafeAreaInsets(); - return ( - - - {children} - - - ); + const insets = useSafeAreaInsets(); + return ( + + + {children} + + + ); }); function useBottomSheet() { - const ref = React.useRef(null); + const ref = React.useRef(null); - const open = useCallback(() => { - ref.current?.present(); - }, []); + const open = useCallback(() => { + ref.current?.present(); + }, []); - const close = useCallback(() => { - ref.current?.dismiss(); - }, []); + const close = useCallback(() => { + ref.current?.dismiss(); + }, []); - return { ref, open, close }; + return { ref, open, close }; } export { - BottomSheet, - BottomSheetCloseTrigger, - BottomSheetContent, - BottomSheetFlatList, - BottomSheetFooter, - BottomSheetHeader, - BottomSheetOpenTrigger, - BottomSheetTextInput, - BottomSheetView, - useBottomSheet, + BottomSheet, + BottomSheetCloseTrigger, + BottomSheetContent, + BottomSheetFlatList, + BottomSheetFooter, + BottomSheetHeader, + BottomSheetOpenTrigger, + BottomSheetTextInput, + BottomSheetView, + useBottomSheet, }; diff --git a/apps/native/src/components/ui/bottom-sheet.tsx b/apps/native/src/components/ui/bottom-sheet.tsx index 59dd9ed..7a4a5c8 100644 --- a/apps/native/src/components/ui/bottom-sheet.tsx +++ b/apps/native/src/components/ui/bottom-sheet.tsx @@ -1,26 +1,26 @@ -import type { BottomSheetFooterProps as GBottomSheetFooterProps } from '@gorhom/bottom-sheet'; +import type { BottomSheetFooterProps as GBottomSheetFooterProps } from "@gorhom/bottom-sheet"; import { - BottomSheetBackdrop, - BottomSheetModal, - BottomSheetFlatList as GBottomSheetFlatList, - BottomSheetFooter as GBottomSheetFooter, - BottomSheetTextInput as GBottomSheetTextInput, - BottomSheetView as GBottomSheetView, - useBottomSheetModal, -} from '@gorhom/bottom-sheet'; -import { X } from 'lucide-react-native'; -import React, { useCallback } from 'react'; + BottomSheetBackdrop, + BottomSheetModal, + BottomSheetFlatList as GBottomSheetFlatList, + BottomSheetFooter as GBottomSheetFooter, + BottomSheetTextInput as GBottomSheetTextInput, + BottomSheetView as GBottomSheetView, + useBottomSheetModal, +} from "@gorhom/bottom-sheet"; +import { X } from "lucide-react-native"; +import React, { useCallback } from "react"; import { - GestureResponderEvent, - Keyboard, - Pressable, - View, - ViewStyle, -} from 'react-native'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; -import { Button } from '~/components/ui/button'; -import { cn } from '~/lib/utils'; + GestureResponderEvent, + Keyboard, + Pressable, + View, + ViewStyle, +} from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; +import { Button } from "~/components/ui/button"; +import { cn } from "~/lib/utils"; // !IMPORTANT: This file is only for web. BottomSheet is not available for web yet. // Should be available in v5 which is in alpha: components/ui/bottom-sheet.tsx @@ -29,229 +29,229 @@ type BottomSheetRef = React.ElementRef; type BottomSheetProps = React.ComponentPropsWithoutRef; interface BottomSheetContext { - sheetRef: React.RefObject; + sheetRef: React.RefObject; } const BottomSheetContext = React.createContext({} as BottomSheetContext); const BottomSheet = React.forwardRef( - ({ ...props }, ref) => { - return ; - } + ({ ...props }, ref) => { + return ; + }, ); type BottomSheetContentRef = React.ElementRef; type BottomSheetContentProps = Omit< - React.ComponentPropsWithoutRef, - 'backdropComponent' + React.ComponentPropsWithoutRef, + "backdropComponent" > & { - backdropProps?: Partial< - React.ComponentPropsWithoutRef - >; + backdropProps?: Partial< + React.ComponentPropsWithoutRef + >; }; const BottomSheetContent = React.forwardRef< - BottomSheetContentRef, - BottomSheetContentProps + BottomSheetContentRef, + BottomSheetContentProps >(() => { - return null; + return null; }); const BottomSheetOpenTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } >(({ onPress, asChild = false, ...props }, ref) => { - function handleOnPress() { - window.alert( - 'Not implemented for web yet. Check `bottom-sheet.tsx` for more info.' - ); - } - const Trigger = asChild ? Slot.Pressable : Pressable; - return ; + function handleOnPress() { + window.alert( + "Not implemented for web yet. Check `bottom-sheet.tsx` for more info.", + ); + } + const Trigger = asChild ? Slot.Pressable : Pressable; + return ; }); const BottomSheetCloseTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } >(({ onPress, asChild = false, ...props }, ref) => { - const { dismiss } = useBottomSheetModal(); - function handleOnPress(ev: GestureResponderEvent) { - dismiss(); - if (Keyboard.isVisible()) { - Keyboard.dismiss(); - } - onPress?.(ev); - } - const Trigger = asChild ? Slot.Pressable : Pressable; - return ; + const { dismiss } = useBottomSheetModal(); + function handleOnPress(ev: GestureResponderEvent) { + dismiss(); + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + onPress?.(ev); + } + const Trigger = asChild ? Slot.Pressable : Pressable; + return ; }); const BOTTOM_SHEET_HEADER_HEIGHT = 60; // BottomSheetHeader height type BottomSheetViewProps = Omit< - React.ComponentPropsWithoutRef, - 'style' + React.ComponentPropsWithoutRef, + "style" > & { - hadHeader?: boolean; - style?: ViewStyle; + hadHeader?: boolean; + style?: ViewStyle; }; function BottomSheetView({ - className, - children, - hadHeader = true, - style, - ...props + className, + children, + hadHeader = true, + style, + ...props }: BottomSheetViewProps) { - const insets = useSafeAreaInsets(); - return ( - - {children} - - ); + const insets = useSafeAreaInsets(); + return ( + + {children} + + ); } type BottomSheetTextInputRef = React.ElementRef; type BottomSheetTextInputProps = React.ComponentPropsWithoutRef< - typeof GBottomSheetTextInput + typeof GBottomSheetTextInput >; const BottomSheetTextInput = React.forwardRef< - BottomSheetTextInputRef, - BottomSheetTextInputProps + BottomSheetTextInputRef, + BottomSheetTextInputProps >(({ className, placeholderClassName, ...props }, ref) => { - return ( - - ); + return ( + + ); }); type BottomSheetFlatListRef = React.ElementRef; type BottomSheetFlatListProps = React.ComponentPropsWithoutRef< - typeof GBottomSheetFlatList + typeof GBottomSheetFlatList >; const BottomSheetFlatList = React.forwardRef< - BottomSheetFlatListRef, - BottomSheetFlatListProps + BottomSheetFlatListRef, + BottomSheetFlatListProps >(({ className, ...props }, ref) => { - const insets = useSafeAreaInsets(); - return ( - - ); + const insets = useSafeAreaInsets(); + return ( + + ); }); type BottomSheetHeaderRef = React.ElementRef; type BottomSheetHeaderProps = React.ComponentPropsWithoutRef; const BottomSheetHeader = React.forwardRef< - BottomSheetHeaderRef, - BottomSheetHeaderProps + BottomSheetHeaderRef, + BottomSheetHeaderProps >(({ className, children, ...props }, ref) => { - const { dismiss } = useBottomSheetModal(); - function close() { - if (Keyboard.isVisible()) { - Keyboard.dismiss(); - } - dismiss(); - } - return ( - - {children} - - - ); + const { dismiss } = useBottomSheetModal(); + function close() { + if (Keyboard.isVisible()) { + Keyboard.dismiss(); + } + dismiss(); + } + return ( + + {children} + + + ); }); type BottomSheetFooterRef = React.ElementRef; type BottomSheetFooterProps = Omit< - React.ComponentPropsWithoutRef, - 'style' + React.ComponentPropsWithoutRef, + "style" > & { - bottomSheetFooterProps: GBottomSheetFooterProps; - children?: React.ReactNode; - style?: ViewStyle; + bottomSheetFooterProps: GBottomSheetFooterProps; + children?: React.ReactNode; + style?: ViewStyle; }; /** * To be used in a useCallback function as a props to BottomSheetContent */ const BottomSheetFooter = React.forwardRef< - BottomSheetFooterRef, - BottomSheetFooterProps + BottomSheetFooterRef, + BottomSheetFooterProps >(({ bottomSheetFooterProps, children, className, style, ...props }, ref) => { - const insets = useSafeAreaInsets(); - return ( - - - {children} - - - ); + const insets = useSafeAreaInsets(); + return ( + + + {children} + + + ); }); function useBottomSheet() { - const ref = React.useRef(null); + const ref = React.useRef(null); - const open = useCallback(() => { - ref.current?.present(); - }, []); + const open = useCallback(() => { + ref.current?.present(); + }, []); - const close = useCallback(() => { - ref.current?.dismiss(); - }, []); + const close = useCallback(() => { + ref.current?.dismiss(); + }, []); - return { ref, open, close }; + return { ref, open, close }; } export { - BottomSheet, - BottomSheetCloseTrigger, - BottomSheetContent, - BottomSheetFlatList, - BottomSheetFooter, - BottomSheetHeader, - BottomSheetOpenTrigger, - BottomSheetTextInput, - BottomSheetView, - useBottomSheet, + BottomSheet, + BottomSheetCloseTrigger, + BottomSheetContent, + BottomSheetFlatList, + BottomSheetFooter, + BottomSheetHeader, + BottomSheetOpenTrigger, + BottomSheetTextInput, + BottomSheetView, + useBottomSheet, }; diff --git a/apps/native/src/components/ui/button.tsx b/apps/native/src/components/ui/button.tsx index 1948bce..42c57fd 100644 --- a/apps/native/src/components/ui/button.tsx +++ b/apps/native/src/components/ui/button.tsx @@ -1,139 +1,139 @@ -import { cva } from 'class-variance-authority'; -import type { VariantProps } from 'class-variance-authority'; -import * as React from 'react'; +import { cva } from "class-variance-authority"; +import type { VariantProps } from "class-variance-authority"; +import * as React from "react"; -import { useColorScheme } from 'nativewind'; -import { Platform, Pressable, Text, View } from 'react-native'; -import { cn, isTextChildren } from '~/lib/utils'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; +import { useColorScheme } from "nativewind"; +import { Platform, Pressable, Text, View } from "react-native"; +import { cn, isTextChildren } from "~/lib/utils"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; const buttonVariants = cva( - 'flex-row items-center justify-center rounded-lg web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2', - { - variants: { - variant: { - default: 'bg-primary', - destructive: 'bg-destructive', - outline: 'border border-input bg-background', - secondary: 'bg-secondary', - ghost: '', - link: '', - }, - size: { - default: 'px-4 py-2 native:px-6 native:py-3.5', - sm: 'px-3 py-1 native:py-2', - lg: 'px-8 py-1.5 native:py-4', - }, - }, - defaultVariants: { - variant: 'default', - size: 'default', - }, - } + "flex-row items-center justify-center rounded-lg web:ring-offset-background web:transition-colors web:focus-visible:outline-none web:focus-visible:ring-2 web:focus-visible:ring-ring web:focus-visible:ring-offset-2", + { + variants: { + variant: { + default: "bg-primary", + destructive: "bg-destructive", + outline: "border border-input bg-background", + secondary: "bg-secondary", + ghost: "", + link: "", + }, + size: { + default: "px-4 py-2 native:px-6 native:py-3.5", + sm: "px-3 py-1 native:py-2", + lg: "px-8 py-1.5 native:py-4", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, ); -const buttonTextVariants = cva('font-medium', { - variants: { - variant: { - default: 'text-primary-foreground', - destructive: 'text-destructive-foreground', - outline: 'text-foreground', - secondary: 'text-secondary-foreground', - ghost: 'text-foreground', - link: 'text-primary underline', - }, - size: { - default: 'text-sm native:text-xl', - sm: 'text-xs native:text-lg', - lg: 'text-base native:text-2xl', - }, - }, - defaultVariants: { - variant: 'default', - size: 'default', - }, +const buttonTextVariants = cva("font-medium", { + variants: { + variant: { + default: "text-primary-foreground", + destructive: "text-destructive-foreground", + outline: "text-foreground", + secondary: "text-secondary-foreground", + ghost: "text-foreground", + link: "text-primary underline", + }, + size: { + default: "text-sm native:text-xl", + sm: "text-xs native:text-lg", + lg: "text-base native:text-2xl", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, }); const rippleColor = (isThemeDark: boolean) => { - const secondary = isThemeDark ? 'hsl(240 4% 16%)' : 'hsl(240 5% 96%)'; - return { - default: isThemeDark ? '#d4d4d8' : '#3f3f46', - destructive: isThemeDark ? '#b91c1c' : '#f87171', - outline: secondary, - secondary: isThemeDark ? '#3f3f46' : '#e4e4e7', - ghost: secondary, - link: secondary, - }; + const secondary = isThemeDark ? "hsl(240 4% 16%)" : "hsl(240 5% 96%)"; + return { + default: isThemeDark ? "#d4d4d8" : "#3f3f46", + destructive: isThemeDark ? "#b91c1c" : "#f87171", + outline: secondary, + secondary: isThemeDark ? "#3f3f46" : "#e4e4e7", + ghost: secondary, + link: secondary, + }; }; const Button = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps & { - textClass?: string; - androidRootClass?: string; - } + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps & { + textClass?: string; + androidRootClass?: string; + } >( - ( - { - className, - textClass, - variant = 'default', - size, - children, - androidRootClass, - disabled, - ...props - }, - ref - ) => { - const { colorScheme } = useColorScheme(); - const Root = Platform.OS === 'android' ? View : Slot.Pressable; - return ( - - - {isTextChildren(children) - ? ({ pressed, hovered }) => ( - - {children as string | string[]} - - ) - : children} - - - ); - } + ( + { + className, + textClass, + variant = "default", + size, + children, + androidRootClass, + disabled, + ...props + }, + ref, + ) => { + const { colorScheme } = useColorScheme(); + const Root = Platform.OS === "android" ? View : Slot.Pressable; + return ( + + + {isTextChildren(children) + ? ({ pressed, hovered }) => ( + + {children as string | string[]} + + ) + : children} + + + ); + }, ); -Button.displayName = 'Button'; +Button.displayName = "Button"; export { Button, buttonTextVariants, buttonVariants }; diff --git a/apps/native/src/components/ui/calendar.tsx b/apps/native/src/components/ui/calendar.tsx index 2d02028..e4133b6 100644 --- a/apps/native/src/components/ui/calendar.tsx +++ b/apps/native/src/components/ui/calendar.tsx @@ -1,147 +1,147 @@ -import { useColorScheme } from 'nativewind'; -import React from 'react'; -import { Calendar as RNCalendar, LocaleConfig } from 'react-native-calendars'; -import { NAV_THEME } from '~/lib/constants'; +import { useColorScheme } from "nativewind"; +import React from "react"; +import { Calendar as RNCalendar, LocaleConfig } from "react-native-calendars"; +import { NAV_THEME } from "~/lib/constants"; /** * @docs https://github.com/wix/react-native-calendars */ function Calendar({ - theme, - ...props + theme, + ...props }: React.ComponentProps) { - const { colorScheme } = useColorScheme(); - const id = React.useId(); + const { colorScheme } = useColorScheme(); + const id = React.useId(); - return ( - - ); + return ( + + ); } -const SKY_500 = '#0ea5e9'; -const SKY_600 = '#0284c7'; +const SKY_500 = "#0ea5e9"; +const SKY_600 = "#0284c7"; function getTheme( - isThemeDark: boolean, - customTheme?: React.ComponentProps['theme'] -): React.ComponentProps['theme'] { - if (isThemeDark) { - return { - backgroundColor: NAV_THEME.dark.background, - calendarBackground: NAV_THEME.dark.card, - textSectionTitleColor: NAV_THEME.dark.text, - selectedDayBackgroundColor: SKY_500, - selectedDayTextColor: '#000000', - todayTextColor: SKY_500, - dayTextColor: NAV_THEME.dark.text, - textDisabledColor: '#ffffff30', - monthTextColor: NAV_THEME.dark.text, - textMonthFontWeight: '500', - arrowColor: SKY_500, - ...customTheme, - }; - } - return { - backgroundColor: NAV_THEME.light.background, - calendarBackground: NAV_THEME.light.card, - textSectionTitleColor: NAV_THEME.light.text, - selectedDayBackgroundColor: SKY_600, - selectedDayTextColor: '#ffffff', - todayTextColor: SKY_600, - dayTextColor: '#2d4150', - monthTextColor: NAV_THEME.light.text, - textMonthFontWeight: '500', - arrowColor: SKY_600, - ...customTheme, - }; + isThemeDark: boolean, + customTheme?: React.ComponentProps["theme"], +): React.ComponentProps["theme"] { + if (isThemeDark) { + return { + backgroundColor: NAV_THEME.dark.background, + calendarBackground: NAV_THEME.dark.card, + textSectionTitleColor: NAV_THEME.dark.text, + selectedDayBackgroundColor: SKY_500, + selectedDayTextColor: "#000000", + todayTextColor: SKY_500, + dayTextColor: NAV_THEME.dark.text, + textDisabledColor: "#ffffff30", + monthTextColor: NAV_THEME.dark.text, + textMonthFontWeight: "500", + arrowColor: SKY_500, + ...customTheme, + }; + } + return { + backgroundColor: NAV_THEME.light.background, + calendarBackground: NAV_THEME.light.card, + textSectionTitleColor: NAV_THEME.light.text, + selectedDayBackgroundColor: SKY_600, + selectedDayTextColor: "#ffffff", + todayTextColor: SKY_600, + dayTextColor: "#2d4150", + monthTextColor: NAV_THEME.light.text, + textMonthFontWeight: "500", + arrowColor: SKY_600, + ...customTheme, + }; } -LocaleConfig.locales['en'] = { - monthNames: [ - 'January', - 'Febuary', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'Septemeber', - 'October', - 'November', - 'December', - ], - monthNamesShort: [ - 'Jan', - 'Feb', - 'Mar', - 'Apr', - 'May', - 'Jun', - 'Jul', - 'Aug', - 'Sept', - 'Oct', - 'Nov', - 'Dec', - ], - dayNames: [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ], - dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'], - today: 'Today', +LocaleConfig.locales["en"] = { + monthNames: [ + "January", + "Febuary", + "March", + "April", + "May", + "June", + "July", + "August", + "Septemeber", + "October", + "November", + "December", + ], + monthNamesShort: [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sept", + "Oct", + "Nov", + "Dec", + ], + dayNames: [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + ], + dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"], + today: "Today", }; -LocaleConfig.locales['fr'] = { - monthNames: [ - 'Janvier', - 'Février', - 'Mars', - 'Avril', - 'Mai', - 'Juin', - 'Juillet', - 'Août', - 'Septembre', - 'Octobre', - 'Novembre', - 'Décembre', - ], - monthNamesShort: [ - 'Janv.', - 'Févr.', - 'Mars', - 'Avril', - 'Mai', - 'Juin', - 'Juil.', - 'Août', - 'Sept.', - 'Oct.', - 'Nov.', - 'Déc.', - ], - dayNames: [ - 'Dimanche', - 'Lundi', - 'Mardi', - 'Mercredi', - 'Jeudi', - 'Vendredi', - 'Samedi', - ], - dayNamesShort: ['Dim.', 'Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.'], - today: "Aujourd'hui", +LocaleConfig.locales["fr"] = { + monthNames: [ + "Janvier", + "Février", + "Mars", + "Avril", + "Mai", + "Juin", + "Juillet", + "Août", + "Septembre", + "Octobre", + "Novembre", + "Décembre", + ], + monthNamesShort: [ + "Janv.", + "Févr.", + "Mars", + "Avril", + "Mai", + "Juin", + "Juil.", + "Août", + "Sept.", + "Oct.", + "Nov.", + "Déc.", + ], + dayNames: [ + "Dimanche", + "Lundi", + "Mardi", + "Mercredi", + "Jeudi", + "Vendredi", + "Samedi", + ], + dayNamesShort: ["Dim.", "Lun.", "Mar.", "Mer.", "Jeu.", "Ven.", "Sam."], + today: "Aujourd'hui", }; export { Calendar, LocaleConfig }; diff --git a/apps/native/src/components/ui/card.tsx b/apps/native/src/components/ui/card.tsx index 2660fa6..a15a8ae 100644 --- a/apps/native/src/components/ui/card.tsx +++ b/apps/native/src/components/ui/card.tsx @@ -1,126 +1,126 @@ -import { useColorScheme } from 'nativewind'; -import React from 'react'; -import type { ViewStyle } from 'react-native'; -import { Text, View, StyleSheet } from 'react-native'; +import { useColorScheme } from "nativewind"; +import React from "react"; +import type { ViewStyle } from "react-native"; +import { Text, View, StyleSheet } from "react-native"; -import { cn } from '~/lib/utils'; +import { cn } from "~/lib/utils"; const Card = React.forwardRef< - React.ElementRef, - Omit, 'style'> & { - style?: ViewStyle; - } + React.ElementRef, + Omit, "style"> & { + style?: ViewStyle; + } >(({ className, style: styleProp, ...props }, ref) => { - const { colorScheme } = useColorScheme(); - const [style, setStyle] = React.useState(styleProp ?? {}); + const { colorScheme } = useColorScheme(); + const [style, setStyle] = React.useState(styleProp ?? {}); - React.useEffect(() => { - setStyle( - StyleSheet.flatten([ - colorScheme === 'dark' ? styles.shadowDark : styles.shadowLight, - styleProp, - ]) - ); - }, [styleProp, colorScheme]); + React.useEffect(() => { + setStyle( + StyleSheet.flatten([ + colorScheme === "dark" ? styles.shadowDark : styles.shadowLight, + styleProp, + ]), + ); + }, [styleProp, colorScheme]); - return ( - - ); + return ( + + ); }); -Card.displayName = 'Card'; +Card.displayName = "Card"; const CardHeader = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -CardHeader.displayName = 'CardHeader'; +CardHeader.displayName = "CardHeader"; const CardTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -CardTitle.displayName = 'CardTitle'; +CardTitle.displayName = "CardTitle"; const CardDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -CardDescription.displayName = 'CardDescription'; +CardDescription.displayName = "CardDescription"; const CardContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -CardContent.displayName = 'CardContent'; +CardContent.displayName = "CardContent"; const CardFooter = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); -CardFooter.displayName = 'CardFooter'; +CardFooter.displayName = "CardFooter"; export { - Card, - CardHeader, - CardFooter, - CardTitle, - CardDescription, - CardContent, + Card, + CardHeader, + CardFooter, + CardTitle, + CardDescription, + CardContent, }; const styles = StyleSheet.create({ - shadowLight: { - shadowColor: '#000000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.05, - shadowRadius: 8, - elevation: 2, - }, - shadowDark: { - shadowColor: '#FFFFFF', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.03, - shadowRadius: 8, - elevation: 1, - }, + shadowLight: { + shadowColor: "#000000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.05, + shadowRadius: 8, + elevation: 2, + }, + shadowDark: { + shadowColor: "#FFFFFF", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.03, + shadowRadius: 8, + elevation: 1, + }, }); diff --git a/apps/native/src/components/ui/checkbox.tsx b/apps/native/src/components/ui/checkbox.tsx index f0f9d40..5138a58 100644 --- a/apps/native/src/components/ui/checkbox.tsx +++ b/apps/native/src/components/ui/checkbox.tsx @@ -1,51 +1,51 @@ -import React from 'react'; -import { Check } from 'lucide-react-native'; +import React from "react"; +import { Check } from "lucide-react-native"; -import { cn } from '~/lib/utils'; -import { Pressable, View } from 'react-native'; -import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'; +import { cn } from "~/lib/utils"; +import { Pressable, View } from "react-native"; +import Animated, { FadeIn, FadeOut } from "react-native-reanimated"; interface CheckboxProps { - value: boolean; - onChange: (checked: boolean) => void; - iconClass?: string; - iconSize?: number; + value: boolean; + onChange: (checked: boolean) => void; + iconClass?: string; + iconSize?: number; } const AnimatedCheck = Animated.createAnimatedComponent(Check); const Checkbox = React.forwardRef< - React.ElementRef, - Omit, 'onPress'> & - CheckboxProps + React.ElementRef, + Omit, "onPress"> & + CheckboxProps >(({ className, value, onChange, iconClass, iconSize = 16, ...props }, ref) => { - return ( - { - onChange(!value); - }} - {...props} - > - - {value && ( - - )} - - ); + return ( + { + onChange(!value); + }} + {...props} + > + + {value && ( + + )} + + ); }); -Checkbox.displayName = 'Checkbox'; +Checkbox.displayName = "Checkbox"; export { Checkbox }; diff --git a/apps/native/src/components/ui/collapsible.tsx b/apps/native/src/components/ui/collapsible.tsx index 5b0f280..7c8cdda 100644 --- a/apps/native/src/components/ui/collapsible.tsx +++ b/apps/native/src/components/ui/collapsible.tsx @@ -1,150 +1,150 @@ -import { VariantProps } from 'class-variance-authority'; -import React from 'react'; -import { GestureResponderEvent, Pressable, View } from 'react-native'; -import Animated, { FadeInDown, FadeOutUp } from 'react-native-reanimated'; -import { buttonVariants } from '~/components/ui/button'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; -import { cn } from '~/lib/utils'; +import { VariantProps } from "class-variance-authority"; +import React from "react"; +import { GestureResponderEvent, Pressable, View } from "react-native"; +import Animated, { FadeInDown, FadeOutUp } from "react-native-reanimated"; +import { buttonVariants } from "~/components/ui/button"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; +import { cn } from "~/lib/utils"; interface CollapsibleProps { - open?: boolean; - setOpen?: React.Dispatch>; - defaultOpen?: boolean; - disabled?: boolean; + open?: boolean; + setOpen?: React.Dispatch>; + defaultOpen?: boolean; + disabled?: boolean; } interface CollapsibleContext { - visible: boolean; - setVisible: React.Dispatch>; - nativeID: string; - disabled: boolean; + visible: boolean; + setVisible: React.Dispatch>; + nativeID: string; + disabled: boolean; } const CollapsibleContext = React.createContext({} as CollapsibleContext); const Collapsible = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & CollapsibleProps + React.ElementRef, + React.ComponentPropsWithoutRef & CollapsibleProps >( - ( - { open, setOpen, defaultOpen, className, disabled = false, ...props }, - ref - ) => { - const [visible, setVisible] = React.useState(defaultOpen ?? false); - const nativeID = React.useId(); + ( + { open, setOpen, defaultOpen, className, disabled = false, ...props }, + ref, + ) => { + const [visible, setVisible] = React.useState(defaultOpen ?? false); + const nativeID = React.useId(); - return ( - - - - ); - } + return ( + + + + ); + }, ); function useCollapsibleContext() { - const context = React.useContext(CollapsibleContext); - if (!context) { - throw new Error( - 'Collapsible compound components cannot be rendered outside the Collapsible component' - ); - } - return context; + const context = React.useContext(CollapsibleContext); + if (!context) { + throw new Error( + "Collapsible compound components cannot be rendered outside the Collapsible component", + ); + } + return context; } const CollapsibleHeader = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); const CollapsibleTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & - VariantProps & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps & { + asChild?: boolean; + } >( - ( - { - className, - onPress, - variant = 'outline', - size = 'sm', - asChild = false, - ...props - }, - ref - ) => { - const { nativeID, visible, setVisible, disabled } = useCollapsibleContext(); + ( + { + className, + onPress, + variant = "outline", + size = "sm", + asChild = false, + ...props + }, + ref, + ) => { + const { nativeID, visible, setVisible, disabled } = useCollapsibleContext(); - function handleOnPress(event: GestureResponderEvent) { - setVisible((prev) => !prev); - onPress?.(event); - } + function handleOnPress(event: GestureResponderEvent) { + setVisible((prev) => !prev); + onPress?.(event); + } - const Trigger = asChild ? Slot.Pressable : Pressable; - return ( - - ); - } + const Trigger = asChild ? Slot.Pressable : Pressable; + return ( + + ); + }, ); const CollapsibleContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - const { nativeID, visible } = useCollapsibleContext(); + const { nativeID, visible } = useCollapsibleContext(); - if (!visible) return null; - return ( - - ); + if (!visible) return null; + return ( + + ); }); export { - Collapsible, - CollapsibleContent, - CollapsibleHeader, - CollapsibleTrigger, + Collapsible, + CollapsibleContent, + CollapsibleHeader, + CollapsibleTrigger, }; diff --git a/apps/native/src/components/ui/combobox.tsx b/apps/native/src/components/ui/combobox.tsx index 8bb5fea..61a7e7e 100644 --- a/apps/native/src/components/ui/combobox.tsx +++ b/apps/native/src/components/ui/combobox.tsx @@ -1,229 +1,229 @@ -import { Check, ChevronsUpDown, Search } from 'lucide-react-native'; -import React from 'react'; -import { ListRenderItemInfo, Text, View } from 'react-native'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { Check, ChevronsUpDown, Search } from "lucide-react-native"; +import React from "react"; +import { ListRenderItemInfo, Text, View } from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; import { - BottomSheet, - BottomSheetContent, - BottomSheetFlatList, - BottomSheetHeader, - BottomSheetOpenTrigger, - BottomSheetTextInput, - useBottomSheet, -} from '~/components/ui/bottom-sheet'; + BottomSheet, + BottomSheetContent, + BottomSheetFlatList, + BottomSheetHeader, + BottomSheetOpenTrigger, + BottomSheetTextInput, + useBottomSheet, +} from "~/components/ui/bottom-sheet"; import { - Button, - buttonTextVariants, - buttonVariants, -} from '~/components/ui/button'; -import { cn } from '~/lib/utils'; + Button, + buttonTextVariants, + buttonVariants, +} from "~/components/ui/button"; +import { cn } from "~/lib/utils"; // TODO: Fix bottom sheet content UI - Too big/too much space const HEADER_HEIGHT = 130; interface ComboboxOption { - label: string; - value: string; + label: string; + value: string; } const Combobox = React.forwardRef< - React.ElementRef, - Omit, 'children'> & { - items: ComboboxOption[]; - placeholder?: string; - inputProps?: React.ComponentPropsWithoutRef; - emptyText?: string; - defaultSelectedItem?: ComboboxOption | null; - selectedItem?: ComboboxOption | null; - onSelectedItemChange?: (option: ComboboxOption | null) => void; - } + React.ElementRef, + Omit, "children"> & { + items: ComboboxOption[]; + placeholder?: string; + inputProps?: React.ComponentPropsWithoutRef; + emptyText?: string; + defaultSelectedItem?: ComboboxOption | null; + selectedItem?: ComboboxOption | null; + onSelectedItemChange?: (option: ComboboxOption | null) => void; + } >( - ( - { - className, - textClass, - variant = 'outline', - size = 'sm', - inputProps, - placeholder, - items, - emptyText = 'Nothing found...', - defaultSelectedItem = null, - selectedItem: selectedItemProp, - onSelectedItemChange, - ...props - }, - ref - ) => { - const insets = useSafeAreaInsets(); - const [search, setSearch] = React.useState(''); - const [selectedItem, setSelectedItem] = - React.useState(defaultSelectedItem); - const bottomSheet = useBottomSheet(); - const inputRef = - React.useRef>(null); + ( + { + className, + textClass, + variant = "outline", + size = "sm", + inputProps, + placeholder, + items, + emptyText = "Nothing found...", + defaultSelectedItem = null, + selectedItem: selectedItemProp, + onSelectedItemChange, + ...props + }, + ref, + ) => { + const insets = useSafeAreaInsets(); + const [search, setSearch] = React.useState(""); + const [selectedItem, setSelectedItem] = + React.useState(defaultSelectedItem); + const bottomSheet = useBottomSheet(); + const inputRef = + React.useRef>(null); - const listItems = React.useMemo(() => { - return search - ? items.filter((item) => { - return item.label - .toLocaleLowerCase() - .includes(search.toLocaleLowerCase()); - }) - : items; - }, [items, search]); + const listItems = React.useMemo(() => { + return search + ? items.filter((item) => { + return item.label + .toLocaleLowerCase() + .includes(search.toLocaleLowerCase()); + }) + : items; + }, [items, search]); - function onItemChange(listItem: ComboboxOption) { - if (selectedItemProp?.value === listItem.value) { - return null; - } - setSearch(''); - bottomSheet.close(); - return listItem; - } + function onItemChange(listItem: ComboboxOption) { + if (selectedItemProp?.value === listItem.value) { + return null; + } + setSearch(""); + bottomSheet.close(); + return listItem; + } - const renderItem = React.useCallback( - ({ item }: ListRenderItemInfo) => { - const listItem = item as ComboboxOption; - const isSelected = onSelectedItemChange - ? selectedItemProp?.value === listItem.value - : selectedItem?.value === listItem.value; - return ( - - ); - }, - [selectedItem, selectedItemProp] - ); + const renderItem = React.useCallback( + ({ item }: ListRenderItemInfo) => { + const listItem = item as ComboboxOption; + const isSelected = onSelectedItemChange + ? selectedItemProp?.value === listItem.value + : selectedItem?.value === listItem.value; + return ( + + ); + }, + [selectedItem, selectedItemProp], + ); - function onSubmitEditing() { - const firstItem = listItems[0]; - if (!firstItem) return; - if (onSelectedItemChange) { - onSelectedItemChange(firstItem); - } else { - setSelectedItem(firstItem); - } - bottomSheet.close(); - } + function onSubmitEditing() { + const firstItem = listItems[0]; + if (!firstItem) return; + if (onSelectedItemChange) { + onSelectedItemChange(firstItem); + } else { + setSelectedItem(firstItem); + } + bottomSheet.close(); + } - function onSearchIconPress() { - if (!inputRef.current) return; - const input = inputRef.current; - if (input && 'focus' in input && typeof input.focus === 'function') { - input.focus(); - } - } + function onSearchIconPress() { + if (!inputRef.current) return; + const input = inputRef.current; + if (input && "focus" in input && typeof input.focus === "function") { + input.focus(); + } + } - const itemSelected = onSelectedItemChange ? selectedItemProp : selectedItem; + const itemSelected = onSelectedItemChange ? selectedItemProp : selectedItem; - return ( - - - - - {itemSelected ? itemSelected.label : placeholder ?? ''} - - - - - { - setSearch(''); - }} - > - - - {placeholder} - - - - - - - (item as ComboboxOption).value} - className={'px-4'} - keyboardShouldPersistTaps='handled' - ListEmptyComponent={() => { - return ( - - - {emptyText} - - - ); - }} - /> - - - ); - } + return ( + + + + + {itemSelected ? itemSelected.label : placeholder ?? ""} + + + + + { + setSearch(""); + }} + > + + + {placeholder} + + + + + + + (item as ComboboxOption).value} + className={"px-4"} + keyboardShouldPersistTaps="handled" + ListEmptyComponent={() => { + return ( + + + {emptyText} + + + ); + }} + /> + + + ); + }, ); -Combobox.displayName = 'Combobox'; +Combobox.displayName = "Combobox"; export { Combobox, type ComboboxOption }; diff --git a/apps/native/src/components/ui/command.tsx b/apps/native/src/components/ui/command.tsx index 256f4f3..3f948b8 100644 --- a/apps/native/src/components/ui/command.tsx +++ b/apps/native/src/components/ui/command.tsx @@ -1,444 +1,446 @@ -import { type ListRenderItemInfo } from '@shopify/flash-list'; -import { Search, X } from 'lucide-react-native'; -import React, { useImperativeHandle } from 'react'; +import { type ListRenderItemInfo } from "@shopify/flash-list"; +import { Search, X } from "lucide-react-native"; +import React, { useImperativeHandle } from "react"; import { - GestureResponderEvent, - Modal, - Pressable, - Text, - View, -} from 'react-native'; -import Animated, { FadeInUp, SlideInUp } from 'react-native-reanimated'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { useKeyboard } from '~/lib/keyboard'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; -import { cn, isTextChildren } from '~/lib/utils'; -import { Button } from './button'; -import { Input } from './input'; -import { SectionList } from './section-list'; + GestureResponderEvent, + Modal, + Pressable, + Text, + View, +} from "react-native"; +import Animated, { FadeInUp, SlideInUp } from "react-native-reanimated"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; +import { useKeyboard } from "~/lib/keyboard"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; +import { cn, isTextChildren } from "~/lib/utils"; +import { Button } from "./button"; +import { Input } from "./input"; +import { SectionList } from "./section-list"; type Data = Record | string; interface CommandProps { - data: T[]; - onItemSelected: (item: Exclude) => void; - filterFn: (search: string, item: Exclude) => boolean; - defaultOpen?: boolean; - onOpenChange?: (isOpen: boolean) => void; - onSearch?: (search: string) => void; + data: T[]; + onItemSelected: (item: Exclude) => void; + filterFn: (search: string, item: Exclude) => boolean; + defaultOpen?: boolean; + onOpenChange?: (isOpen: boolean) => void; + onSearch?: (search: string) => void; } interface CommandContext { - data: T[]; - onItemSelected: (item: Exclude) => void; - isOpen: boolean; - toggleIsOpen: () => void; - search: string; - handleOnSearch: (search: string) => void; + data: T[]; + onItemSelected: (item: Exclude) => void; + isOpen: boolean; + toggleIsOpen: () => void; + search: string; + handleOnSearch: (search: string) => void; } const CommandContext = React.createContext>( - {} as CommandContext + {} as CommandContext, ); type CommandWrapperProps = React.ComponentPropsWithoutRef< - typeof View + typeof View > & - CommandProps; + CommandProps; function CommandWrapper( - { - data: dataFromProps, - defaultOpen = false, - onOpenChange, - onSearch, - onItemSelected, - filterFn, - ...props - }: CommandWrapperProps, - ref?: React.ForwardedRef + { + data: dataFromProps, + defaultOpen = false, + onOpenChange, + onSearch, + onItemSelected, + filterFn, + ...props + }: CommandWrapperProps, + ref?: React.ForwardedRef, ) { - const [isOpen, setIsOpen] = React.useState(defaultOpen); - const [search, setSearch] = React.useState(''); - - const data = React.useMemo(() => { - const items = dataFromProps.filter((item) => { - if (typeof item === 'string') return true; - return filterFn(search, item as Exclude); - }); - return items.filter((item, index) => { - if (typeof item === 'string') { - const nextItem = items[index + 1]; - return nextItem && typeof nextItem !== 'string'; - } - return true; - }); - }, [search, dataFromProps, filterFn]); - - function toggleIsOpen() { - setIsOpen((prev) => { - const newVal = !prev; - onOpenChange?.(newVal); - return newVal; - }); - if (search) { - setSearch(''); - } - } - - function handleOnSearch(search: string) { - setSearch(search); - onSearch?.(search); - } - - return ( - - - - ); + const [isOpen, setIsOpen] = React.useState(defaultOpen); + const [search, setSearch] = React.useState(""); + + const data = React.useMemo(() => { + const items = dataFromProps.filter((item) => { + if (typeof item === "string") return true; + return filterFn(search, item as Exclude); + }); + return items.filter((item, index) => { + if (typeof item === "string") { + const nextItem = items[index + 1]; + return nextItem && typeof nextItem !== "string"; + } + return true; + }); + }, [search, dataFromProps, filterFn]); + + function toggleIsOpen() { + setIsOpen((prev) => { + const newVal = !prev; + onOpenChange?.(newVal); + return newVal; + }); + if (search) { + setSearch(""); + } + } + + function handleOnSearch(search: string) { + setSearch(search); + onSearch?.(search); + } + + return ( + + + + ); } interface WithForwardRefCommand extends React.FC> { - (props: CommandWrapperProps): ReturnType< - React.FC> - >; + ( + props: CommandWrapperProps, + ): ReturnType>>; } const Command: WithForwardRefCommand = React.forwardRef(CommandWrapper); -Command.displayName = 'Command'; +Command.displayName = "Command"; function useCommandContext() { - const context = React.useContext>(CommandContext); - if (!context) { - throw new Error( - 'Command compound components cannot be rendered outside the Command component' - ); - } - return context; + const context = React.useContext>(CommandContext); + if (!context) { + throw new Error( + "Command compound components cannot be rendered outside the Command component", + ); + } + return context; } function CommandPressable( - { - onPress, - asChild = false, - ...props - }: React.ComponentPropsWithoutRef & { - asChild?: boolean; - }, - ref: React.ForwardedRef> + { + onPress, + asChild = false, + ...props + }: React.ComponentPropsWithoutRef & { + asChild?: boolean; + }, + ref: React.ForwardedRef>, ) { - const { toggleIsOpen } = useCommandContext(); + const { toggleIsOpen } = useCommandContext(); - function handleOnPress(event: GestureResponderEvent) { - toggleIsOpen(); - onPress?.(event); - } + function handleOnPress(event: GestureResponderEvent) { + toggleIsOpen(); + onPress?.(event); + } - const Trigger = asChild ? Slot.Pressable : Pressable; - return ; + const Trigger = asChild ? Slot.Pressable : Pressable; + return ; } const CommandTrigger = React.forwardRef(CommandPressable); -CommandTrigger.displayName = 'CommandTrigger'; +CommandTrigger.displayName = "CommandTrigger"; function CommandModal( - { - className, - children, - animationType = 'fade', - overlayClass, - style, - ...props - }: React.ComponentPropsWithoutRef & { - overlayClass?: string; - }, - ref: React.ForwardedRef> + { + className, + children, + animationType = "fade", + overlayClass, + style, + ...props + }: React.ComponentPropsWithoutRef & { + overlayClass?: string; + }, + ref: React.ForwardedRef>, ) { - const insets = useSafeAreaInsets(); - const { keyboardHeight } = useKeyboard(); - const { toggleIsOpen, isOpen } = useCommandContext(); - - return ( - - - - - {children} - - - - - - ); + const insets = useSafeAreaInsets(); + const { keyboardHeight } = useKeyboard(); + const { toggleIsOpen, isOpen } = useCommandContext(); + + return ( + + + + + {children} + + + + + + ); } const CommandContent = React.forwardRef(CommandModal); -CommandContent.displayName = 'CommandContent'; +CommandContent.displayName = "CommandContent"; function CommandTextInput( - { - className, - placeholderClassName, - ...props - }: React.ComponentPropsWithoutRef, - ref: React.ForwardedRef> + { + className, + placeholderClassName, + ...props + }: React.ComponentPropsWithoutRef, + ref: React.ForwardedRef>, ) { - const inputRef = React.useRef>(null); - const { search, handleOnSearch, data, onItemSelected, toggleIsOpen } = - useCommandContext(); - - useImperativeHandle( - ref, - () => { - if (!inputRef.current) { - return {} as React.ComponentRef; - } - return inputRef.current; - }, - [inputRef.current] - ); - - function onSubmitEditing() { - const firstItem = data.find((item) => typeof item !== 'string'); - if (firstItem && typeof firstItem !== 'string') { - onItemSelected(firstItem as Exclude); - } - toggleIsOpen(); - } - - function onSearchIconPress() { - inputRef.current?.focus(); - } - - return ( - - - - - - ); + const inputRef = React.useRef>(null); + const { search, handleOnSearch, data, onItemSelected, toggleIsOpen } = + useCommandContext(); + + useImperativeHandle( + ref, + () => { + if (!inputRef.current) { + return {} as React.ComponentRef; + } + return inputRef.current; + }, + [inputRef.current], + ); + + function onSubmitEditing() { + const firstItem = data.find((item) => typeof item !== "string"); + if (firstItem && typeof firstItem !== "string") { + onItemSelected(firstItem as Exclude); + } + toggleIsOpen(); + } + + function onSearchIconPress() { + inputRef.current?.focus(); + } + + return ( + + + + + + ); } const CommandInput = React.forwardRef(CommandTextInput); -CommandInput.displayName = 'CommandInput'; +CommandInput.displayName = "CommandInput"; type CommandSectionListProps = Omit< - React.ComponentPropsWithoutRef>, - 'data' + React.ComponentPropsWithoutRef>, + "data" > & { - headerHeight?: number; - itemHeight?: number; + headerHeight?: number; + itemHeight?: number; }; function CommandSectionList( - { - headerHeight = 43, - itemHeight = 57, - className, - extraData, - ...props - }: CommandSectionListProps, - ref: React.ForwardedRef>> + { + headerHeight = 43, + itemHeight = 57, + className, + extraData, + ...props + }: CommandSectionListProps, + ref: React.ForwardedRef>>, ) { - const { data, search } = useCommandContext(); - - function overrideItemLayout(layout: any, item: any) { - if (typeof item === 'string') { - layout.size = headerHeight; - } - layout.size = itemHeight; - } - - return ( - - - - ref={ref} - data={data} - extraData={[search, extraData]} - estimatedItemSize={itemHeight} - overrideItemLayout={overrideItemLayout} - keyboardShouldPersistTaps='handled' - role='menu' - {...props} - /> - - ); + const { data, search } = useCommandContext(); + + function overrideItemLayout(layout: any, item: any) { + if (typeof item === "string") { + layout.size = headerHeight; + } + layout.size = itemHeight; + } + + return ( + + + + ref={ref} + data={data} + extraData={[search, extraData]} + estimatedItemSize={itemHeight} + overrideItemLayout={overrideItemLayout} + keyboardShouldPersistTaps="handled" + role="menu" + {...props} + /> + + ); } interface WithForwardRefCommandList - extends React.FC> { - (props: CommandSectionListProps): ReturnType< - React.FC< - Omit>, 'data'> & { - headerHeight?: number; - itemHeight?: number; - } - > - >; + extends React.FC> { + ( + props: CommandSectionListProps, + ): ReturnType< + React.FC< + Omit>, "data"> & { + headerHeight?: number; + itemHeight?: number; + } + > + >; } const CommandList: WithForwardRefCommandList = - React.forwardRef(CommandSectionList); -CommandList.displayName = 'CommandList'; + React.forwardRef(CommandSectionList); +CommandList.displayName = "CommandList"; const CommandListHeader = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { textClass?: string } + React.ElementRef, + React.ComponentPropsWithoutRef & { textClass?: string } >(({ className, textClass, children, ...props }, ref) => { - return ( - - {isTextChildren(children) ? ( - - {children} - - ) : ( - children - )} - - ); + return ( + + {isTextChildren(children) ? ( + + {children} + + ) : ( + children + )} + + ); }); type CommandListHeaderProps = ListRenderItemInfo; -CommandListHeader.displayName = 'CommandListHeader'; +CommandListHeader.displayName = "CommandListHeader"; function CommandSectionListItem( - { - className, - index, - containnerClass, - onPress, - children, - ...props - }: React.ComponentPropsWithoutRef & { - index: number; - containnerClass?: string; - }, - ref: React.ForwardedRef> + { + className, + index, + containnerClass, + onPress, + children, + ...props + }: React.ComponentPropsWithoutRef & { + index: number; + containnerClass?: string; + }, + ref: React.ForwardedRef>, ) { - const { data, onItemSelected, toggleIsOpen } = useCommandContext(); - - function handleOnPress(event: GestureResponderEvent) { - const item = data[index]; - if (typeof item === 'string' || !item) return; - onItemSelected(item as Exclude); - onPress?.(event); - toggleIsOpen(); - } - - return ( - - - - ); + const { data, onItemSelected, toggleIsOpen } = useCommandContext(); + + function handleOnPress(event: GestureResponderEvent) { + const item = data[index]; + if (typeof item === "string" || !item) return; + onItemSelected(item as Exclude); + onPress?.(event); + toggleIsOpen(); + } + + return ( + + + + ); } type CommandListItemProps = ListRenderItemInfo; const CommandListItem = React.forwardRef(CommandSectionListItem); -CommandListItem.displayName = 'CommandListItem'; +CommandListItem.displayName = "CommandListItem"; export { - Command, - CommandContent, - CommandInput, - CommandList, - CommandListHeader, - CommandListItem, - CommandTrigger, - type CommandListHeaderProps, - type CommandListItemProps, + Command, + CommandContent, + CommandInput, + CommandList, + CommandListHeader, + CommandListItem, + CommandTrigger, + type CommandListHeaderProps, + type CommandListItemProps, }; diff --git a/apps/native/src/components/ui/context-menu.tsx b/apps/native/src/components/ui/context-menu.tsx index 341da19..c57b434 100644 --- a/apps/native/src/components/ui/context-menu.tsx +++ b/apps/native/src/components/ui/context-menu.tsx @@ -1,5 +1,5 @@ -import { Text } from 'react-native'; +import { Text } from "react-native"; export function ContextMenu() { - return Context Menu (soon); + return Context Menu (soon); } diff --git a/apps/native/src/components/ui/data-table.tsx b/apps/native/src/components/ui/data-table.tsx index 5b6be2f..ebe9f2f 100644 --- a/apps/native/src/components/ui/data-table.tsx +++ b/apps/native/src/components/ui/data-table.tsx @@ -1,36 +1,36 @@ import { - ColumnDef, - Row, - SortingState, - flexRender, - getCoreRowModel, - getSortedRowModel, - useReactTable, -} from '@tanstack/react-table'; -import React from 'react'; -import { ActivityIndicator, Dimensions, RefreshControl } from 'react-native'; -import Animated, { FadeInUp, FadeOutUp } from 'react-native-reanimated'; -import { cn } from '~/lib/utils'; + ColumnDef, + Row, + SortingState, + flexRender, + getCoreRowModel, + getSortedRowModel, + useReactTable, +} from "@tanstack/react-table"; +import React from "react"; +import { ActivityIndicator, Dimensions, RefreshControl } from "react-native"; +import Animated, { FadeInUp, FadeOutUp } from "react-native-reanimated"; +import { cn } from "~/lib/utils"; import { - Table, - TableBody, - TableCell, - TableHead, - TableHeader, - TableRow, - TableRowsFlashListProps, - TableRowsList, -} from './table'; + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, + TableRowsFlashListProps, + TableRowsList, +} from "./table"; interface DataTableProps { - columns: ColumnDef[]; - data: TData[]; - onRowPress?: (row: Row) => void; - estimatedItemSize?: number; - ListEmptyComponent?: TableRowsFlashListProps['ListEmptyComponent']; - ListFooterComponent?: TableRowsFlashListProps['ListFooterComponent']; - isRefreshing?: boolean; - onRefresh?: () => void; + columns: ColumnDef[]; + data: TData[]; + onRowPress?: (row: Row) => void; + estimatedItemSize?: number; + ListEmptyComponent?: TableRowsFlashListProps["ListEmptyComponent"]; + ListFooterComponent?: TableRowsFlashListProps["ListFooterComponent"]; + isRefreshing?: boolean; + onRefresh?: () => void; } /** @@ -38,115 +38,115 @@ interface DataTableProps { */ export function DataTable({ - columns, - data, - onRowPress, - estimatedItemSize = 45, - ListEmptyComponent, - ListFooterComponent, - isRefreshing = false, - onRefresh, + columns, + data, + onRowPress, + estimatedItemSize = 45, + ListEmptyComponent, + ListFooterComponent, + isRefreshing = false, + onRefresh, }: DataTableProps) { - const [sorting, setSorting] = React.useState([]); - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - onSortingChange: setSorting, - getSortedRowModel: getSortedRowModel(), - state: { - sorting, - }, - }); + const [sorting, setSorting] = React.useState([]); + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + onSortingChange: setSorting, + getSortedRowModel: getSortedRowModel(), + state: { + sorting, + }, + }); - return ( - <> - {isRefreshing && ( - - - - )} - - - {table.getHeaderGroups().map((headerGroup) => ( - - {headerGroup.headers.map((header) => { - return ( - - {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext() - )} - - ); - })} - - ))} - - - - } - renderItem={({ item: row, index }) => { - return ( - { - onRowPress(row); - } - : undefined - } - > - {row.getVisibleCells().map((cell) => ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext() - )} - - ))} - - ); - }} - /> - -
- - ); + return ( + <> + {isRefreshing && ( + + + + )} + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + + } + renderItem={({ item: row, index }) => { + return ( + { + onRowPress(row); + } + : undefined + } + > + {row.getVisibleCells().map((cell) => ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ))} + + ); + }} + /> + +
+ + ); } -const { width } = Dimensions.get('window'); +const { width } = Dimensions.get("window"); function getColumnWidth(size: number, length: number) { - const evenWidth = width / length; - return evenWidth > size ? evenWidth : size; + const evenWidth = width / length; + return evenWidth > size ? evenWidth : size; } diff --git a/apps/native/src/components/ui/dialog.tsx b/apps/native/src/components/ui/dialog.tsx index 28875d3..679c24c 100644 --- a/apps/native/src/components/ui/dialog.tsx +++ b/apps/native/src/components/ui/dialog.tsx @@ -1,276 +1,276 @@ -import { useColorScheme } from 'nativewind'; -import React from 'react'; +import { useColorScheme } from "nativewind"; +import React from "react"; import { - GestureResponderEvent, - Modal, - Pressable, - StyleSheet, - Text, - View, - ViewStyle, -} from 'react-native'; -import * as Slot from '~/lib/rn-primitives/slot/slot-native'; -import { cn } from '~/lib/utils'; -import { Button } from './button'; + GestureResponderEvent, + Modal, + Pressable, + StyleSheet, + Text, + View, + ViewStyle, +} from "react-native"; +import * as Slot from "~/lib/rn-primitives/slot/slot-native"; +import { cn } from "~/lib/utils"; +import { Button } from "./button"; interface DialogProps { - children: React.ReactNode; - closeOnOverlayPress?: boolean; - defaultOpen?: boolean; - open?: boolean; - setOpen?: React.Dispatch>; + children: React.ReactNode; + closeOnOverlayPress?: boolean; + defaultOpen?: boolean; + open?: boolean; + setOpen?: React.Dispatch>; } interface DialogContext { - visible: boolean; - setVisible: React.Dispatch>; - closeOnOverlayPress: boolean; + visible: boolean; + setVisible: React.Dispatch>; + closeOnOverlayPress: boolean; } const DialogContext = React.createContext({} as DialogContext); const Dialog = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & DialogProps + React.ElementRef, + React.ComponentPropsWithoutRef & DialogProps >( - ( - { - open, - setOpen, - closeOnOverlayPress = true, - defaultOpen = false, - ...props - }, - ref - ) => { - const [visible, setVisible] = React.useState(defaultOpen ?? false); - return ( - - - - ); - } + ( + { + open, + setOpen, + closeOnOverlayPress = true, + defaultOpen = false, + ...props + }, + ref, + ) => { + const [visible, setVisible] = React.useState(defaultOpen ?? false); + return ( + + + + ); + }, ); -Dialog.displayName = 'Dialog'; +Dialog.displayName = "Dialog"; function useDialogContext() { - const context = React.useContext(DialogContext); - if (!context) { - throw new Error( - 'Dialog compound components cannot be rendered outside the Dialog component' - ); - } - return context; + const context = React.useContext(DialogContext); + if (!context) { + throw new Error( + "Dialog compound components cannot be rendered outside the Dialog component", + ); + } + return context; } const DialogTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } >(({ onPress, asChild = false, ...props }, ref) => { - const { setVisible } = useDialogContext(); - function handleOnPress(event: GestureResponderEvent) { - setVisible(true); - onPress?.(event); - } + const { setVisible } = useDialogContext(); + function handleOnPress(event: GestureResponderEvent) { + setVisible(true); + onPress?.(event); + } - const Trigger = asChild ? Slot.Pressable : Button; - return ; + const Trigger = asChild ? Slot.Pressable : Button; + return ; }); -DialogTrigger.displayName = 'DialogTrigger'; +DialogTrigger.displayName = "DialogTrigger"; const DialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { overlayClass?: string } + React.ElementRef, + React.ComponentPropsWithoutRef & { overlayClass?: string } >( - ( - { - className, - children, - animationType = 'fade', - style: styleProp, - overlayClass, - ...props - }, - ref - ) => { - const { colorScheme } = useColorScheme(); - const { visible, setVisible, closeOnOverlayPress } = useDialogContext(); - const [style, setStyle] = React.useState( - StyleSheet.flatten(styleProp) - ); + ( + { + className, + children, + animationType = "fade", + style: styleProp, + overlayClass, + ...props + }, + ref, + ) => { + const { colorScheme } = useColorScheme(); + const { visible, setVisible, closeOnOverlayPress } = useDialogContext(); + const [style, setStyle] = React.useState( + StyleSheet.flatten(styleProp), + ); - React.useEffect(() => { - setStyle( - StyleSheet.flatten([ - colorScheme === 'dark' ? styles.shadowDark : styles.shadowLight, - styleProp, - ]) - ); - }, [styleProp, colorScheme]); + React.useEffect(() => { + setStyle( + StyleSheet.flatten([ + colorScheme === "dark" ? styles.shadowDark : styles.shadowLight, + styleProp, + ]), + ); + }, [styleProp, colorScheme]); - return ( - { - setVisible((prev) => !prev); - }} - statusBarTranslucent - {...props} - > - { - setVisible(false); - } - : undefined - } - className={cn( - 'flex-1 justify-center items-center p-2', - animationType !== 'slide' && 'bg-zinc-50/80 dark:bg-zinc-900/80', - overlayClass - )} - > - - {children} - - - - ); - } + return ( + { + setVisible((prev) => !prev); + }} + statusBarTranslucent + {...props} + > + { + setVisible(false); + } + : undefined + } + className={cn( + "flex-1 justify-center items-center p-2", + animationType !== "slide" && "bg-zinc-50/80 dark:bg-zinc-900/80", + overlayClass, + )} + > + + {children} + + + + ); + }, ); -DialogContent.displayName = 'DialogContent'; +DialogContent.displayName = "DialogContent"; const DialogHeader = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ; + return ; }); -DialogHeader.displayName = 'DialogHeader'; +DialogHeader.displayName = "DialogHeader"; const DialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); -DialogTitle.displayName = 'DialogTitle'; +DialogTitle.displayName = "DialogTitle"; const DialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); -DialogDescription.displayName = 'DialogDescription'; +DialogDescription.displayName = "DialogDescription"; const DialogFooter = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return ( - - ); + return ( + + ); }); -DialogFooter.displayName = 'DialogFooter'; +DialogFooter.displayName = "DialogFooter"; const DialogClose = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - asChild?: boolean; - } ->(({ variant = 'outline', asChild, ...props }, ref) => { - const { setVisible } = useDialogContext(); - const Trigger = asChild ? Slot.Pressable : Button; - return ( - { - setVisible(false); - }} - ref={ref} - {...props} - /> - ); + React.ElementRef, + React.ComponentPropsWithoutRef & { + asChild?: boolean; + } +>(({ variant = "outline", asChild, ...props }, ref) => { + const { setVisible } = useDialogContext(); + const Trigger = asChild ? Slot.Pressable : Button; + return ( + { + setVisible(false); + }} + ref={ref} + {...props} + /> + ); }); -DialogClose.displayName = 'DialogClose'; +DialogClose.displayName = "DialogClose"; export { - Dialog, - DialogClose, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger, + Dialog, + DialogClose, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, }; const styles = StyleSheet.create({ - shadowLight: { - shadowColor: '#000000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.1, - shadowRadius: 8, - elevation: 5, - }, - shadowDark: { - shadowColor: '#000000', - shadowOffset: { - width: 0, - height: 2, - }, - shadowOpacity: 0.25, - shadowRadius: 8, - elevation: 5, - }, + shadowLight: { + shadowColor: "#000000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.1, + shadowRadius: 8, + elevation: 5, + }, + shadowDark: { + shadowColor: "#000000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 8, + elevation: 5, + }, }); diff --git a/apps/native/src/components/ui/dropdown-menu.tsx b/apps/native/src/components/ui/dropdown-menu.tsx index 36c4cac..1316008 100644 --- a/apps/native/src/components/ui/dropdown-menu.tsx +++ b/apps/native/src/components/ui/dropdown-menu.tsx @@ -1,5 +1,5 @@ -import { Text } from 'react-native'; +import { Text } from "react-native"; export function DropdownMenu() { - return Dropdown Menu (soon); + return Dropdown Menu (soon); } diff --git a/apps/native/src/components/ui/form.tsx b/apps/native/src/components/ui/form.tsx index 39fe8c5..c82c86a 100644 --- a/apps/native/src/components/ui/form.tsx +++ b/apps/native/src/components/ui/form.tsx @@ -2,683 +2,683 @@ // The code is licensed under the MIT License. // https://github.com/shadcn-ui/ui -import { CalendarIcon, X } from 'lucide-react-native'; -import React from 'react'; +import { CalendarIcon, X } from "lucide-react-native"; +import React from "react"; import { - Controller, - ControllerProps, - FieldPath, - FieldValues, - FormProvider, - Noop, - useFormContext, -} from 'react-hook-form'; -import { Text, View } from 'react-native'; -import Animated, { FadeInDown, FadeOut } from 'react-native-reanimated'; + Controller, + ControllerProps, + FieldPath, + FieldValues, + FormProvider, + Noop, + useFormContext, +} from "react-hook-form"; +import { Text, View } from "react-native"; +import Animated, { FadeInDown, FadeOut } from "react-native-reanimated"; import { - BottomSheet, - BottomSheetCloseTrigger, - BottomSheetContent, - BottomSheetOpenTrigger, - BottomSheetView, -} from '~/components/ui/bottom-sheet'; -import { Button, buttonTextVariants } from '~/components/ui/button'; -import { Calendar } from '~/components/ui/calendar'; -import { Combobox, ComboboxOption } from '~/components/ui/combobox'; -import { Input } from '~/components/ui/input'; -import { Label } from '~/components/ui/label'; -import { RadioGroup } from '~/components/ui/radio-group'; + BottomSheet, + BottomSheetCloseTrigger, + BottomSheetContent, + BottomSheetOpenTrigger, + BottomSheetView, +} from "~/components/ui/bottom-sheet"; +import { Button, buttonTextVariants } from "~/components/ui/button"; +import { Calendar } from "~/components/ui/calendar"; +import { Combobox, ComboboxOption } from "~/components/ui/combobox"; +import { Input } from "~/components/ui/input"; +import { Label } from "~/components/ui/label"; +import { RadioGroup } from "~/components/ui/radio-group"; import { - RenderSelectItem, - Select, - SelectItem, - SelectList, - SelectOption, - SelectTrigger, -} from '~/components/ui/select'; -import { Switch } from '~/components/ui/switch'; -import { Textarea } from '~/components/ui/textarea'; -import { cn } from '~/lib/utils'; -import { Checkbox } from './checkbox'; + RenderSelectItem, + Select, + SelectItem, + SelectList, + SelectOption, + SelectTrigger, +} from "~/components/ui/select"; +import { Switch } from "~/components/ui/switch"; +import { Textarea } from "~/components/ui/textarea"; +import { cn } from "~/lib/utils"; +import { Checkbox } from "./checkbox"; const Form = FormProvider; type FormFieldContextValue< - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, > = { - name: TName; + name: TName; }; const FormFieldContext = React.createContext( - {} as FormFieldContextValue + {} as FormFieldContextValue, ); const FormField = < - TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, >({ - ...props + ...props }: ControllerProps) => { - return ( - - - - ); + return ( + + + + ); }; const useFormField = () => { - const fieldContext = React.useContext(FormFieldContext); - const itemContext = React.useContext(FormItemContext); - const { getFieldState, formState, handleSubmit } = useFormContext(); - - const fieldState = getFieldState(fieldContext.name, formState); - - if (!fieldContext) { - throw new Error('useFormField should be used within '); - } - - const { nativeID } = itemContext; - - return { - nativeID, - name: fieldContext.name, - formItemNativeID: `${nativeID}-form-item`, - formDescriptionNativeID: `${nativeID}-form-item-description`, - formMessageNativeID: `${nativeID}-form-item-message`, - handleSubmit, - ...fieldState, - }; + const fieldContext = React.useContext(FormFieldContext); + const itemContext = React.useContext(FormItemContext); + const { getFieldState, formState, handleSubmit } = useFormContext(); + + const fieldState = getFieldState(fieldContext.name, formState); + + if (!fieldContext) { + throw new Error("useFormField should be used within "); + } + + const { nativeID } = itemContext; + + return { + nativeID, + name: fieldContext.name, + formItemNativeID: `${nativeID}-form-item`, + formDescriptionNativeID: `${nativeID}-form-item-description`, + formMessageNativeID: `${nativeID}-form-item-message`, + handleSubmit, + ...fieldState, + }; }; type FormItemContextValue = { - nativeID: string; + nativeID: string; }; const FormItemContext = React.createContext( - {} as FormItemContextValue + {} as FormItemContextValue, ); const FormItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - const nativeID = React.useId(); + const nativeID = React.useId(); - return ( - - - - ); + return ( + + + + ); }); -FormItem.displayName = 'FormItem'; +FormItem.displayName = "FormItem"; const FormLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - const { error, formItemNativeID } = useFormField(); - - return ( -