From 0c64cb68ceff9de851504faf5de24e2f3b7b01e4 Mon Sep 17 00:00:00 2001 From: Ksan Date: Thu, 6 Nov 2025 21:15:55 +0100 Subject: [PATCH] Just did some random stuff tbh --- .gitignore | 2 + app/(tabs)/_layout.tsx | 35 -- app/(tabs)/explore.tsx | 112 ---- app/(tabs)/index.tsx | 98 ---- app/_layout.tsx | 24 +- app/globals.css | 3 + app/index.tsx | 60 ++ app/modal.tsx | 29 - assets/images/color-wheel-icon.png | Bin 0 -> 46084 bytes babel.config.js | 10 + components/DragAndDropObject.tsx | 71 +++ components/MyColorPicker.tsx | 66 +++ components/external-link.tsx | 25 - components/haptic-tab.tsx | 18 - components/hello-wave.tsx | 19 - components/parallax-scroll-view.tsx | 79 --- components/themed-text.tsx | 60 -- components/themed-view.tsx | 14 - components/ui/collapsible.tsx | 45 -- components/ui/icon-symbol.ios.tsx | 32 -- components/ui/icon-symbol.tsx | 41 -- constants/icons.ts | 6 + constants/theme.ts | 53 -- hooks/use-color-scheme.ts | 1 - hooks/use-color-scheme.web.ts | 21 - hooks/use-theme-color.ts | 21 - metro.config.js | 6 + nativewind-env.d.ts | 1 + package-lock.json | 841 +++++++++++++++++++++++++++- package.json | 16 +- scripts/reset-project.js | 112 ---- tailwind.config.js | 25 + tsconfig.json | 6 +- 33 files changed, 1094 insertions(+), 858 deletions(-) delete mode 100644 app/(tabs)/_layout.tsx delete mode 100644 app/(tabs)/explore.tsx delete mode 100644 app/(tabs)/index.tsx create mode 100644 app/globals.css create mode 100644 app/index.tsx delete mode 100644 app/modal.tsx create mode 100644 assets/images/color-wheel-icon.png create mode 100644 babel.config.js create mode 100644 components/DragAndDropObject.tsx create mode 100644 components/MyColorPicker.tsx delete mode 100644 components/external-link.tsx delete mode 100644 components/haptic-tab.tsx delete mode 100644 components/hello-wave.tsx delete mode 100644 components/parallax-scroll-view.tsx delete mode 100644 components/themed-text.tsx delete mode 100644 components/themed-view.tsx delete mode 100644 components/ui/collapsible.tsx delete mode 100644 components/ui/icon-symbol.ios.tsx delete mode 100644 components/ui/icon-symbol.tsx create mode 100644 constants/icons.ts delete mode 100644 constants/theme.ts delete mode 100644 hooks/use-color-scheme.ts delete mode 100644 hooks/use-color-scheme.web.ts delete mode 100644 hooks/use-theme-color.ts create mode 100644 metro.config.js create mode 100644 nativewind-env.d.ts delete mode 100755 scripts/reset-project.js create mode 100644 tailwind.config.js diff --git a/.gitignore b/.gitignore index f8c6c2e..7f765db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files +.idea/ # dependencies node_modules/ @@ -41,3 +42,4 @@ app-example # generated native folders /ios /android + diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx deleted file mode 100644 index 54e11d0..0000000 --- a/app/(tabs)/_layout.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Tabs } from 'expo-router'; -import React from 'react'; - -import { HapticTab } from '@/components/haptic-tab'; -import { IconSymbol } from '@/components/ui/icon-symbol'; -import { Colors } from '@/constants/theme'; -import { useColorScheme } from '@/hooks/use-color-scheme'; - -export default function TabLayout() { - const colorScheme = useColorScheme(); - - return ( - - , - }} - /> - , - }} - /> - - ); -} diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx deleted file mode 100644 index 71518f9..0000000 --- a/app/(tabs)/explore.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import { Image } from 'expo-image'; -import { Platform, StyleSheet } from 'react-native'; - -import { Collapsible } from '@/components/ui/collapsible'; -import { ExternalLink } from '@/components/external-link'; -import ParallaxScrollView from '@/components/parallax-scroll-view'; -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { IconSymbol } from '@/components/ui/icon-symbol'; -import { Fonts } from '@/constants/theme'; - -export default function TabTwoScreen() { - return ( - - }> - - - Explore - - - This app includes example code to help you get started. - - - This app has two screens:{' '} - app/(tabs)/index.tsx and{' '} - app/(tabs)/explore.tsx - - - The layout file in app/(tabs)/_layout.tsx{' '} - sets up the tab navigator. - - - Learn more - - - - - You can open this project on Android, iOS, and the web. To open the web version, press{' '} - w in the terminal running this project. - - - - - For static images, you can use the @2x and{' '} - @3x suffixes to provide files for - different screen densities - - - - Learn more - - - - - This template has light and dark mode support. The{' '} - useColorScheme() hook lets you inspect - what the user's current color scheme is, and so you can adjust UI colors accordingly. - - - Learn more - - - - - This template includes an example of an animated component. The{' '} - components/HelloWave.tsx component uses - the powerful{' '} - - react-native-reanimated - {' '} - library to create a waving hand animation. - - {Platform.select({ - ios: ( - - The components/ParallaxScrollView.tsx{' '} - component provides a parallax effect for the header image. - - ), - })} - - - ); -} - -const styles = StyleSheet.create({ - headerImage: { - color: '#808080', - bottom: -90, - left: -35, - position: 'absolute', - }, - titleContainer: { - flexDirection: 'row', - gap: 8, - }, -}); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx deleted file mode 100644 index 786b736..0000000 --- a/app/(tabs)/index.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { Image } from 'expo-image'; -import { Platform, StyleSheet } from 'react-native'; - -import { HelloWave } from '@/components/hello-wave'; -import ParallaxScrollView from '@/components/parallax-scroll-view'; -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { Link } from 'expo-router'; - -export default function HomeScreen() { - return ( - - }> - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{' '} - - {Platform.select({ - ios: 'cmd + d', - android: 'cmd + m', - web: 'F12', - })} - {' '} - to open developer tools. - - - - - - Step 2: Explore - - - - alert('Action pressed')} /> - alert('Share pressed')} - /> - - alert('Delete pressed')} - /> - - - - - - {`Tap the Explore tab to learn more about what's included in this starter app.`} - - - - Step 3: Get a fresh start - - {`When you're ready, run `} - npm run reset-project to get a fresh{' '} - app directory. This will move the current{' '} - app to{' '} - app-example. - - - - ); -} - -const styles = StyleSheet.create({ - titleContainer: { - flexDirection: 'row', - alignItems: 'center', - gap: 8, - }, - stepContainer: { - gap: 8, - marginBottom: 8, - }, - reactLogo: { - height: 178, - width: 290, - bottom: 0, - left: 0, - position: 'absolute', - }, -}); diff --git a/app/_layout.tsx b/app/_layout.tsx index f518c9b..730dd00 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,24 +1,6 @@ -import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; -import { Stack } from 'expo-router'; -import { StatusBar } from 'expo-status-bar'; -import 'react-native-reanimated'; - -import { useColorScheme } from '@/hooks/use-color-scheme'; - -export const unstable_settings = { - anchor: '(tabs)', -}; +import { Stack } from "expo-router"; +import './globals.css' export default function RootLayout() { - const colorScheme = useColorScheme(); - - return ( - - - - - - - - ); + return ; } diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..bd6213e --- /dev/null +++ b/app/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/app/index.tsx b/app/index.tsx new file mode 100644 index 0000000..1255d06 --- /dev/null +++ b/app/index.tsx @@ -0,0 +1,60 @@ +import {useEffect, useRef, useState} from "react"; + +import { + Animated, + Button, + Image, + Modal, + PanResponder, + Platform, + Text, + TextInput, + TouchableOpacity, + View +} from "react-native"; +import {Gesture, GestureDetector, GestureHandlerRootView, ScrollView} from 'react-native-gesture-handler'; +// eslint-disable-next-line import/namespace +import MyColorPicker from "@/components/MyColorPicker"; +// @ts-ignore +import DragAndDropObject from "@/components/DragAndDropObject"; +export default function Index() { + + const [heading="", setHeading] = useState(); + const [paragraph="", setParagraph] = useState(); + + const[ selectedColor = "#FFFFFF", setSelectedColor ] = useState(); + + + const handleButtonPress = (): void => { + console.log('Input: ', heading); + console.log('Color', selectedColor); + } + + + + + + + + return ( + + + + + + + + + + setSelectedColor(color)} /> + + + + + + ); +} diff --git a/app/modal.tsx b/app/modal.tsx deleted file mode 100644 index 6dfbc1a..0000000 --- a/app/modal.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { Link } from 'expo-router'; -import { StyleSheet } from 'react-native'; - -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; - -export default function ModalScreen() { - return ( - - This is a modal - - Go to home screen - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - padding: 20, - }, - link: { - marginTop: 15, - paddingVertical: 15, - }, -}); diff --git a/assets/images/color-wheel-icon.png b/assets/images/color-wheel-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..212745c4fb82a7537556142f17c28ba4b8351eda GIT binary patch literal 46084 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 M#@0p^2Cgyx2dE#^6aWAK literal 0 HcmV?d00001 diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..8b9c254 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,10 @@ +module.exports = function(api) { + api.cache(true); + return { + presets: [ + ["babel-preset-expo", { jsxImportSource: "nativewind" }], + "nativewind/babel", + ], + plugins: ['react-native-reanimated/plugin'], + }; +}; diff --git a/components/DragAndDropObject.tsx b/components/DragAndDropObject.tsx new file mode 100644 index 0000000..cb21f4b --- /dev/null +++ b/components/DragAndDropObject.tsx @@ -0,0 +1,71 @@ +// DragAndDropCard.tsx +import React, { useEffect, useRef } from 'react'; +import {Text, TextInput} from 'react-native'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withSpring, +} from 'react-native-reanimated'; +import { Gesture, GestureDetector } from 'react-native-gesture-handler'; +import {AnimatedView} from "react-native-reanimated/src/component/View"; + + +interface DragAndDropCardObject { + heading: string; + paragraph: string; + color: string; +} + +const DragAndDropCard: React.FC = ({ heading, paragraph, color }) => { + const translateX = useSharedValue(0); + const translateY = useSharedValue(0); + + const isMounted = useRef(true); + useEffect(() => { + return () => { + isMounted.current = false; + }; + }, []); + + // Gesture configuration + const panGesture = Gesture.Pan() + .onUpdate((event) => { + translateX.value = event.translationX; + translateY.value = event.translationY; + }) + .onEnd(() => { + if (isMounted.current) { + translateX.value = withSpring(0); + translateY.value = withSpring(0); + } + }); + + // Animated styles + const animatedStyle = useAnimatedStyle(() => ({ + transform: [ + { translateX: translateX.value }, + { translateY: translateY.value }, + ], + })); + + return ( + + + + + + + + ); +}; + +export default DragAndDropCard; diff --git a/components/MyColorPicker.tsx b/components/MyColorPicker.tsx new file mode 100644 index 0000000..613b38c --- /dev/null +++ b/components/MyColorPicker.tsx @@ -0,0 +1,66 @@ +import React, { useState } from 'react'; +import {Button, Image, Modal, Platform, TouchableOpacity, TouchableWithoutFeedback, View} from 'react-native'; +import { icons } from "@/constants/icons" +import ColorPicker, {HueSlider, OpacitySlider, Panel1, Preview, Swatches} from "reanimated-color-picker"; + +// @ts-ignore +export default function MyColorPicker({ onColorSelected }: { onColorSelected: (color: string) => void }) { + + const [showModal, setShowModal] = useState(false); + const [bgColor, setBgColor] = useState('gray'); + + const onSelectColor = ({ hex }: { hex: string }): void => { + setBgColor(hex); + + if (onColorSelected) { + onColorSelected(hex); + } + }; + + const toggleModal = () => { + setShowModal(prevState => !prevState); + }; + + return ( + + + {Platform.OS === 'web' ? ( + + ) : ( + + )} + + + + + + + + + + + + + + + + + + + + + + ); +} \ No newline at end of file diff --git a/components/external-link.tsx b/components/external-link.tsx deleted file mode 100644 index 883e515..0000000 --- a/components/external-link.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { Href, Link } from 'expo-router'; -import { openBrowserAsync, WebBrowserPresentationStyle } from 'expo-web-browser'; -import { type ComponentProps } from 'react'; - -type Props = Omit, 'href'> & { href: Href & string }; - -export function ExternalLink({ href, ...rest }: Props) { - return ( - { - if (process.env.EXPO_OS !== 'web') { - // Prevent the default behavior of linking to the default browser on native. - event.preventDefault(); - // Open the link in an in-app browser. - await openBrowserAsync(href, { - presentationStyle: WebBrowserPresentationStyle.AUTOMATIC, - }); - } - }} - /> - ); -} diff --git a/components/haptic-tab.tsx b/components/haptic-tab.tsx deleted file mode 100644 index 7f3981c..0000000 --- a/components/haptic-tab.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs'; -import { PlatformPressable } from '@react-navigation/elements'; -import * as Haptics from 'expo-haptics'; - -export function HapticTab(props: BottomTabBarButtonProps) { - return ( - { - if (process.env.EXPO_OS === 'ios') { - // Add a soft haptic feedback when pressing down on the tabs. - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); - } - props.onPressIn?.(ev); - }} - /> - ); -} diff --git a/components/hello-wave.tsx b/components/hello-wave.tsx deleted file mode 100644 index 5def547..0000000 --- a/components/hello-wave.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import Animated from 'react-native-reanimated'; - -export function HelloWave() { - return ( - - šŸ‘‹ - - ); -} diff --git a/components/parallax-scroll-view.tsx b/components/parallax-scroll-view.tsx deleted file mode 100644 index 6f674a7..0000000 --- a/components/parallax-scroll-view.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import type { PropsWithChildren, ReactElement } from 'react'; -import { StyleSheet } from 'react-native'; -import Animated, { - interpolate, - useAnimatedRef, - useAnimatedStyle, - useScrollOffset, -} from 'react-native-reanimated'; - -import { ThemedView } from '@/components/themed-view'; -import { useColorScheme } from '@/hooks/use-color-scheme'; -import { useThemeColor } from '@/hooks/use-theme-color'; - -const HEADER_HEIGHT = 250; - -type Props = PropsWithChildren<{ - headerImage: ReactElement; - headerBackgroundColor: { dark: string; light: string }; -}>; - -export default function ParallaxScrollView({ - children, - headerImage, - headerBackgroundColor, -}: Props) { - const backgroundColor = useThemeColor({}, 'background'); - const colorScheme = useColorScheme() ?? 'light'; - const scrollRef = useAnimatedRef(); - const scrollOffset = useScrollOffset(scrollRef); - const headerAnimatedStyle = useAnimatedStyle(() => { - return { - transform: [ - { - translateY: interpolate( - scrollOffset.value, - [-HEADER_HEIGHT, 0, HEADER_HEIGHT], - [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75] - ), - }, - { - scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]), - }, - ], - }; - }); - - return ( - - - {headerImage} - - {children} - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - }, - header: { - height: HEADER_HEIGHT, - overflow: 'hidden', - }, - content: { - flex: 1, - padding: 32, - gap: 16, - overflow: 'hidden', - }, -}); diff --git a/components/themed-text.tsx b/components/themed-text.tsx deleted file mode 100644 index d79d0a1..0000000 --- a/components/themed-text.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { StyleSheet, Text, type TextProps } from 'react-native'; - -import { useThemeColor } from '@/hooks/use-theme-color'; - -export type ThemedTextProps = TextProps & { - lightColor?: string; - darkColor?: string; - type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link'; -}; - -export function ThemedText({ - style, - lightColor, - darkColor, - type = 'default', - ...rest -}: ThemedTextProps) { - const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text'); - - return ( - - ); -} - -const styles = StyleSheet.create({ - default: { - fontSize: 16, - lineHeight: 24, - }, - defaultSemiBold: { - fontSize: 16, - lineHeight: 24, - fontWeight: '600', - }, - title: { - fontSize: 32, - fontWeight: 'bold', - lineHeight: 32, - }, - subtitle: { - fontSize: 20, - fontWeight: 'bold', - }, - link: { - lineHeight: 30, - fontSize: 16, - color: '#0a7ea4', - }, -}); diff --git a/components/themed-view.tsx b/components/themed-view.tsx deleted file mode 100644 index 6f181d8..0000000 --- a/components/themed-view.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { View, type ViewProps } from 'react-native'; - -import { useThemeColor } from '@/hooks/use-theme-color'; - -export type ThemedViewProps = ViewProps & { - lightColor?: string; - darkColor?: string; -}; - -export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) { - const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); - - return ; -} diff --git a/components/ui/collapsible.tsx b/components/ui/collapsible.tsx deleted file mode 100644 index 6345fde..0000000 --- a/components/ui/collapsible.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { PropsWithChildren, useState } from 'react'; -import { StyleSheet, TouchableOpacity } from 'react-native'; - -import { ThemedText } from '@/components/themed-text'; -import { ThemedView } from '@/components/themed-view'; -import { IconSymbol } from '@/components/ui/icon-symbol'; -import { Colors } from '@/constants/theme'; -import { useColorScheme } from '@/hooks/use-color-scheme'; - -export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { - const [isOpen, setIsOpen] = useState(false); - const theme = useColorScheme() ?? 'light'; - - return ( - - setIsOpen((value) => !value)} - activeOpacity={0.8}> - - - {title} - - {isOpen && {children}} - - ); -} - -const styles = StyleSheet.create({ - heading: { - flexDirection: 'row', - alignItems: 'center', - gap: 6, - }, - content: { - marginTop: 6, - marginLeft: 24, - }, -}); diff --git a/components/ui/icon-symbol.ios.tsx b/components/ui/icon-symbol.ios.tsx deleted file mode 100644 index 9177f4d..0000000 --- a/components/ui/icon-symbol.ios.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols'; -import { StyleProp, ViewStyle } from 'react-native'; - -export function IconSymbol({ - name, - size = 24, - color, - style, - weight = 'regular', -}: { - name: SymbolViewProps['name']; - size?: number; - color: string; - style?: StyleProp; - weight?: SymbolWeight; -}) { - return ( - - ); -} diff --git a/components/ui/icon-symbol.tsx b/components/ui/icon-symbol.tsx deleted file mode 100644 index b7ece6b..0000000 --- a/components/ui/icon-symbol.tsx +++ /dev/null @@ -1,41 +0,0 @@ -// Fallback for using MaterialIcons on Android and web. - -import MaterialIcons from '@expo/vector-icons/MaterialIcons'; -import { SymbolWeight, SymbolViewProps } from 'expo-symbols'; -import { ComponentProps } from 'react'; -import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native'; - -type IconMapping = Record['name']>; -type IconSymbolName = keyof typeof MAPPING; - -/** - * Add your SF Symbols to Material Icons mappings here. - * - see Material Icons in the [Icons Directory](https://icons.expo.fyi). - * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app. - */ -const MAPPING = { - 'house.fill': 'home', - 'paperplane.fill': 'send', - 'chevron.left.forwardslash.chevron.right': 'code', - 'chevron.right': 'chevron-right', -} as IconMapping; - -/** - * An icon component that uses native SF Symbols on iOS, and Material Icons on Android and web. - * This ensures a consistent look across platforms, and optimal resource usage. - * Icon `name`s are based on SF Symbols and require manual mapping to Material Icons. - */ -export function IconSymbol({ - name, - size = 24, - color, - style, -}: { - name: IconSymbolName; - size?: number; - color: string | OpaqueColorValue; - style?: StyleProp; - weight?: SymbolWeight; -}) { - return ; -} diff --git a/constants/icons.ts b/constants/icons.ts new file mode 100644 index 0000000..759f305 --- /dev/null +++ b/constants/icons.ts @@ -0,0 +1,6 @@ +// @ts-ignore +import colorP from "@/assets/images/color-wheel-icon.png"; + +export const icons = { + colorP +} \ No newline at end of file diff --git a/constants/theme.ts b/constants/theme.ts deleted file mode 100644 index f06facd..0000000 --- a/constants/theme.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Below are the colors that are used in the app. The colors are defined in the light and dark mode. - * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc. - */ - -import { Platform } from 'react-native'; - -const tintColorLight = '#0a7ea4'; -const tintColorDark = '#fff'; - -export const Colors = { - light: { - text: '#11181C', - background: '#fff', - tint: tintColorLight, - icon: '#687076', - tabIconDefault: '#687076', - tabIconSelected: tintColorLight, - }, - dark: { - text: '#ECEDEE', - background: '#151718', - tint: tintColorDark, - icon: '#9BA1A6', - tabIconDefault: '#9BA1A6', - tabIconSelected: tintColorDark, - }, -}; - -export const Fonts = Platform.select({ - ios: { - /** iOS `UIFontDescriptorSystemDesignDefault` */ - sans: 'system-ui', - /** iOS `UIFontDescriptorSystemDesignSerif` */ - serif: 'ui-serif', - /** iOS `UIFontDescriptorSystemDesignRounded` */ - rounded: 'ui-rounded', - /** iOS `UIFontDescriptorSystemDesignMonospaced` */ - mono: 'ui-monospace', - }, - default: { - sans: 'normal', - serif: 'serif', - rounded: 'normal', - mono: 'monospace', - }, - web: { - sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif", - serif: "Georgia, 'Times New Roman', serif", - rounded: "'SF Pro Rounded', 'Hiragino Maru Gothic ProN', Meiryo, 'MS PGothic', sans-serif", - mono: "SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", - }, -}); diff --git a/hooks/use-color-scheme.ts b/hooks/use-color-scheme.ts deleted file mode 100644 index 17e3c63..0000000 --- a/hooks/use-color-scheme.ts +++ /dev/null @@ -1 +0,0 @@ -export { useColorScheme } from 'react-native'; diff --git a/hooks/use-color-scheme.web.ts b/hooks/use-color-scheme.web.ts deleted file mode 100644 index 7eb1c1b..0000000 --- a/hooks/use-color-scheme.web.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useEffect, useState } from 'react'; -import { useColorScheme as useRNColorScheme } from 'react-native'; - -/** - * To support static rendering, this value needs to be re-calculated on the client side for web - */ -export function useColorScheme() { - const [hasHydrated, setHasHydrated] = useState(false); - - useEffect(() => { - setHasHydrated(true); - }, []); - - const colorScheme = useRNColorScheme(); - - if (hasHydrated) { - return colorScheme; - } - - return 'light'; -} diff --git a/hooks/use-theme-color.ts b/hooks/use-theme-color.ts deleted file mode 100644 index 0cbc3a6..0000000 --- a/hooks/use-theme-color.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Learn more about light and dark modes: - * https://docs.expo.dev/guides/color-schemes/ - */ - -import { Colors } from '@/constants/theme'; -import { useColorScheme } from '@/hooks/use-color-scheme'; - -export function useThemeColor( - props: { light?: string; dark?: string }, - colorName: keyof typeof Colors.light & keyof typeof Colors.dark -) { - const theme = useColorScheme() ?? 'light'; - const colorFromProps = props[theme]; - - if (colorFromProps) { - return colorFromProps; - } else { - return Colors[theme][colorName]; - } -} diff --git a/metro.config.js b/metro.config.js new file mode 100644 index 0000000..698605c --- /dev/null +++ b/metro.config.js @@ -0,0 +1,6 @@ +const { getDefaultConfig } = require("expo/metro-config"); +const { withNativeWind } = require('nativewind/metro'); + +const config = getDefaultConfig(__dirname) + +module.exports = withNativeWind(config, { input: './app/globals.css' }) diff --git a/nativewind-env.d.ts b/nativewind-env.d.ts new file mode 100644 index 0000000..fbca8c7 --- /dev/null +++ b/nativewind-env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c301188..8b7b6bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "dependencies": { "@expo/vector-icons": "^15.0.3", + "@react-native-community/slider": "^5.1.0", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/elements": "^2.6.3", "@react-navigation/native": "^7.1.8", @@ -24,15 +25,22 @@ "expo-symbols": "~1.0.7", "expo-system-ui": "~6.0.8", "expo-web-browser": "~15.0.9", + "nativewind": "^4.2.1", + "prettier-plugin-tailwindcss": "^0.5.14", "react": "19.1.0", + "react-colorful": "^5.6.1", "react-dom": "19.1.0", "react-native": "0.81.5", + "react-native-color-picker": "^0.6.0", "react-native-gesture-handler": "~2.28.0", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", "react-native-web": "~0.21.0", - "react-native-worklets": "0.5.1" + "react-native-wheel-color-picker": "^1.3.1", + "react-native-worklets": "0.5.1", + "reanimated-color-picker": "^4.1.1", + "tailwindcss": "^3.4.18" }, "devDependencies": { "@types/react": "~19.1.0", @@ -55,6 +63,18 @@ } } }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -1465,7 +1485,6 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -2632,7 +2651,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -2646,7 +2664,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -2656,7 +2673,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -2873,6 +2889,12 @@ } } }, + "node_modules/@react-native-community/slider": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@react-native-community/slider/-/slider-5.1.0.tgz", + "integrity": "sha512-79nzA7eXPgM6UMo5ZZ/rrJu8Gai0aRctN6stBHneQYh5Qst98hYD3piY+RQHJhDuCCrpQL85YwGVU4FdDOE3cA==", + "license": "MIT" + }, "node_modules/@react-native/assets-registry": { "version": "0.81.5", "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.81.5.tgz", @@ -4185,6 +4207,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "license": "MIT" + }, "node_modules/array.prototype.findlast": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", @@ -4625,6 +4653,18 @@ "node": ">=0.6" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bplist-creator": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz", @@ -4822,6 +4862,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001753", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", @@ -4858,6 +4907,42 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/chownr": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", @@ -5057,6 +5142,20 @@ "node": ">= 10" } }, + "node_modules/comment-json": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz", + "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==", + "license": "MIT", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -5166,6 +5265,12 @@ "url": "https://opencollective.com/core-js" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cross-fetch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", @@ -5207,6 +5312,18 @@ "hyphenate-style-name": "^1.0.3" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -5410,6 +5527,18 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -5923,6 +6052,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -6911,7 +7041,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -6928,7 +7057,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -6954,7 +7082,6 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -7374,7 +7501,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -7855,6 +7981,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -7977,7 +8115,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8032,7 +8169,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -8500,6 +8636,16 @@ "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==", "license": "MIT" }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "peer": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8910,6 +9056,18 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -9095,7 +9253,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -9560,6 +9717,23 @@ "url": "https://opencollective.com/napi-postinstall" } }, + "node_modules/nativewind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.1.tgz", + "integrity": "sha512-10uUB2Dlli3MH3NDL5nMHqJHz1A3e/E6mzjTj6cl7hHECClJ7HpE6v+xZL+GXdbwQSnWE+UWMIMsNz7yOQkAJQ==", + "license": "MIT", + "dependencies": { + "comment-json": "^4.2.5", + "debug": "^4.3.7", + "react-native-css-interop": "0.2.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "tailwindcss": ">3.3.0" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -9686,6 +9860,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -10154,6 +10337,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", @@ -10215,6 +10407,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", @@ -10224,6 +10417,128 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -10240,6 +10555,96 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "license": "MIT", + "peer": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.14.tgz", + "integrity": "sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==", + "license": "MIT", + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "@zackad/prettier-plugin-twig-melody": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-sort-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "@zackad/prettier-plugin-twig-melody": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + } + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -10328,7 +10733,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -10340,7 +10744,6 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, "node_modules/punycode": { @@ -10391,7 +10794,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -10451,6 +10853,16 @@ "node": ">=0.10.0" } }, + "node_modules/react-colorful": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/react-colorful/-/react-colorful-5.6.1.tgz", + "integrity": "sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/react-devtools-core": { "version": "6.1.5", "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz", @@ -10556,6 +10968,305 @@ } } }, + "node_modules/react-native-color-picker": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/react-native-color-picker/-/react-native-color-picker-0.6.0.tgz", + "integrity": "sha512-CptAssfTEGww97ev5GfaGTwu3IMBbBFi9ZDai1fgYRurQ7oQTcDp00lOoFIgLXr/acHNME2PjL7Ks/c+leVKFg==", + "license": "Apache-2.0", + "dependencies": { + "prop-types": "^15.5.10", + "tinycolor2": "^1.4.1" + } + }, + "node_modules/react-native-css-interop": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.1.tgz", + "integrity": "sha512-B88f5rIymJXmy1sNC/MhTkb3xxBej1KkuAt7TiT9iM7oXz3RM8Bn+7GUrfR02TvSgKm4cg2XiSuLEKYfKwNsjA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.3.7", + "lightningcss": "~1.27.0", + "semver": "^7.6.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": ">=18", + "react-native": "*", + "react-native-reanimated": ">=3.6.2", + "tailwindcss": "~3" + }, + "peerDependenciesMeta": { + "react-native-safe-area-context": { + "optional": true + }, + "react-native-svg": { + "optional": true + } + } + }, + "node_modules/react-native-css-interop/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz", + "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.27.0", + "lightningcss-darwin-x64": "1.27.0", + "lightningcss-freebsd-x64": "1.27.0", + "lightningcss-linux-arm-gnueabihf": "1.27.0", + "lightningcss-linux-arm64-gnu": "1.27.0", + "lightningcss-linux-arm64-musl": "1.27.0", + "lightningcss-linux-x64-gnu": "1.27.0", + "lightningcss-linux-x64-musl": "1.27.0", + "lightningcss-win32-arm64-msvc": "1.27.0", + "lightningcss-win32-x64-msvc": "1.27.0" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-arm64": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz", + "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-x64": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz", + "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-freebsd-x64": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz", + "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz", + "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz", + "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz", + "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz", + "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-musl": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz", + "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz", + "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz", + "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/react-native-css-interop/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-native-elevation": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/react-native-elevation/-/react-native-elevation-1.0.0.tgz", + "integrity": "sha512-BWIKcEYtzjRV6GpkX0Km5/w2E7fgIcywiQOT7JZTc5NSbv/YI9kpFinB9lRFsOoRVGmiqq/O3VfP/oH2clIiBA==", + "license": "MIT" + }, "node_modules/react-native-gesture-handler": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.28.0.tgz", @@ -10671,6 +11382,15 @@ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", "license": "MIT" }, + "node_modules/react-native-wheel-color-picker": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-native-wheel-color-picker/-/react-native-wheel-color-picker-1.3.1.tgz", + "integrity": "sha512-ojuajzwEkgIHa4Iw94K9FlwA1iifslMo+HDrOFQMBTMCXm1HaFhtQpDZ5upV9y8vujviDko3hDkVqB7/eV0dzg==", + "license": "MIT", + "dependencies": { + "react-native-elevation": "^1.0.0" + } + }, "node_modules/react-native-worklets": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.5.1.tgz", @@ -10860,6 +11580,45 @@ } } }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reanimated-color-picker": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/reanimated-color-picker/-/reanimated-color-picker-4.1.1.tgz", + "integrity": "sha512-WtjOj3KYkxaTjkKnlNV/DNcR9IXBQ9CUUtUMQXzRqvlbzwM3AdQ4YpJxchx4L6lpJnDZjEaGJLq/x0ZJ3MKxnA==", + "license": "MIT", + "peerDependencies": { + "expo": ">=44.0.0", + "react": "*", + "react-native": "*", + "react-native-gesture-handler": ">=2.0.0", + "react-native-reanimated": ">=2.0.0" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + } + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -11092,7 +11851,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -11140,7 +11898,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -12026,6 +12783,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwindcss": { + "version": "3.4.18", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz", + "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tar": { "version": "7.5.2", "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", @@ -12162,6 +12957,12 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "license": "MIT" }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -12676,6 +13477,12 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", diff --git a/package.json b/package.json index 60055a0..3718b48 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ }, "dependencies": { "@expo/vector-icons": "^15.0.3", + "@react-native-community/slider": "^5.1.0", "@react-navigation/bottom-tabs": "^7.4.0", "@react-navigation/elements": "^2.6.3", "@react-navigation/native": "^7.1.8", @@ -27,21 +28,28 @@ "expo-symbols": "~1.0.7", "expo-system-ui": "~6.0.8", "expo-web-browser": "~15.0.9", + "nativewind": "^4.2.1", + "prettier-plugin-tailwindcss": "^0.5.14", "react": "19.1.0", + "react-colorful": "^5.6.1", "react-dom": "19.1.0", "react-native": "0.81.5", + "react-native-color-picker": "^0.6.0", "react-native-gesture-handler": "~2.28.0", - "react-native-worklets": "0.5.1", "react-native-reanimated": "~4.1.1", "react-native-safe-area-context": "~5.6.0", "react-native-screens": "~4.16.0", - "react-native-web": "~0.21.0" + "react-native-web": "~0.21.0", + "react-native-wheel-color-picker": "^1.3.1", + "react-native-worklets": "0.5.1", + "reanimated-color-picker": "^4.1.1", + "tailwindcss": "^3.4.18" }, "devDependencies": { "@types/react": "~19.1.0", - "typescript": "~5.9.2", "eslint": "^9.25.0", - "eslint-config-expo": "~10.0.0" + "eslint-config-expo": "~10.0.0", + "typescript": "~5.9.2" }, "private": true } diff --git a/scripts/reset-project.js b/scripts/reset-project.js deleted file mode 100755 index 51dff15..0000000 --- a/scripts/reset-project.js +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env node - -/** - * This script is used to reset the project to a blank state. - * It deletes or moves the /app, /components, /hooks, /scripts, and /constants directories to /app-example based on user input and creates a new /app directory with an index.tsx and _layout.tsx file. - * You can remove the `reset-project` script from package.json and safely delete this file after running it. - */ - -const fs = require("fs"); -const path = require("path"); -const readline = require("readline"); - -const root = process.cwd(); -const oldDirs = ["app", "components", "hooks", "constants", "scripts"]; -const exampleDir = "app-example"; -const newAppDir = "app"; -const exampleDirPath = path.join(root, exampleDir); - -const indexContent = `import { Text, View } from "react-native"; - -export default function Index() { - return ( - - Edit app/index.tsx to edit this screen. - - ); -} -`; - -const layoutContent = `import { Stack } from "expo-router"; - -export default function RootLayout() { - return ; -} -`; - -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, -}); - -const moveDirectories = async (userInput) => { - try { - if (userInput === "y") { - // Create the app-example directory - await fs.promises.mkdir(exampleDirPath, { recursive: true }); - console.log(`šŸ“ /${exampleDir} directory created.`); - } - - // Move old directories to new app-example directory or delete them - for (const dir of oldDirs) { - const oldDirPath = path.join(root, dir); - if (fs.existsSync(oldDirPath)) { - if (userInput === "y") { - const newDirPath = path.join(root, exampleDir, dir); - await fs.promises.rename(oldDirPath, newDirPath); - console.log(`āž”ļø /${dir} moved to /${exampleDir}/${dir}.`); - } else { - await fs.promises.rm(oldDirPath, { recursive: true, force: true }); - console.log(`āŒ /${dir} deleted.`); - } - } else { - console.log(`āž”ļø /${dir} does not exist, skipping.`); - } - } - - // Create new /app directory - const newAppDirPath = path.join(root, newAppDir); - await fs.promises.mkdir(newAppDirPath, { recursive: true }); - console.log("\nšŸ“ New /app directory created."); - - // Create index.tsx - const indexPath = path.join(newAppDirPath, "index.tsx"); - await fs.promises.writeFile(indexPath, indexContent); - console.log("šŸ“„ app/index.tsx created."); - - // Create _layout.tsx - const layoutPath = path.join(newAppDirPath, "_layout.tsx"); - await fs.promises.writeFile(layoutPath, layoutContent); - console.log("šŸ“„ app/_layout.tsx created."); - - console.log("\nāœ… Project reset complete. Next steps:"); - console.log( - `1. Run \`npx expo start\` to start a development server.\n2. Edit app/index.tsx to edit the main screen.${ - userInput === "y" - ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.` - : "" - }` - ); - } catch (error) { - console.error(`āŒ Error during script execution: ${error.message}`); - } -}; - -rl.question( - "Do you want to move existing files to /app-example instead of deleting them? (Y/n): ", - (answer) => { - const userInput = answer.trim().toLowerCase() || "y"; - if (userInput === "y" || userInput === "n") { - moveDirectories(userInput).finally(() => rl.close()); - } else { - console.log("āŒ Invalid input. Please enter 'Y' or 'N'."); - rl.close(); - } - } -); diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..228b0d0 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,25 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + // NOTE: Update this to include the paths to all files that contain Nativewind classes. + content: ["./app/**/*.{js,jsx,ts,tsx}", "./constants/**/*.{js,jsx,ts,tsx}"], + presets: [require("nativewind/preset")], + theme: { + extend: { + colors: { + primary: '#180a49d9', + secondary: '#31273aff', + light: { + 100: '', + 200: '', + 300: '' + }, + dark: { + 100: '', + 200: '', + 300: '' + } + } + }, + }, + plugins: [], +} diff --git a/tsconfig.json b/tsconfig.json index 909e901..a57e4d5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, + "baseUrl": ".", "paths": { "@/*": [ "./*" @@ -12,6 +13,9 @@ "**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", - "expo-env.d.ts" + "expo-env.d.ts", + "app/_layout.tsx", + "nativewind-env.d.ts", + "types/**/*.d.ts" ] }