parent
fb3f632c61
commit
9695854b49
File diff suppressed because it is too large
Load Diff
@ -1,39 +1,39 @@ |
||||
{ |
||||
"name": "expo-project", |
||||
"version": "1.0.0", |
||||
"main": "index.ts", |
||||
"scripts": { |
||||
"start": "expo start", |
||||
"android": "expo start --android", |
||||
"ios": "expo start --ios", |
||||
"web": "expo start --web" |
||||
}, |
||||
"dependencies": { |
||||
"@expo/html-elements": "^0.10.1", |
||||
"@gluestack-ui/core": "^3.0.0", |
||||
"@gluestack-ui/utils": "^3.0.0", |
||||
"@legendapp/motion": "^2.4.0", |
||||
"babel-plugin-module-resolver": "^5.0.2", |
||||
"expo": "~53.0.22", |
||||
"expo-status-bar": "~2.2.3", |
||||
"lucide-react-native": "^0.543.0", |
||||
"nativewind": "^4.1.23", |
||||
"react": "19.0.0", |
||||
"react-aria": "^3.33.0", |
||||
"react-dom": "^19.0.0", |
||||
"react-native": "^0.79.5", |
||||
"react-native-reanimated": "^3.17.4", |
||||
"react-native-safe-area-context": "^5.4.0", |
||||
"react-native-svg": "^15.11.2", |
||||
"react-native-worklets": "^0.5.0", |
||||
"react-stately": "^3.39.0", |
||||
"tailwind-variants": "^0.1.20", |
||||
"tailwindcss": "^3.4.17" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.25.2", |
||||
"@types/react": "~19.0.10", |
||||
"typescript": "~5.8.3" |
||||
}, |
||||
"private": true |
||||
} |
||||
{ |
||||
"name": "expo-project", |
||||
"version": "1.0.0", |
||||
"main": "index.ts", |
||||
"scripts": { |
||||
"start": "expo start", |
||||
"android": "expo start --android", |
||||
"ios": "expo start --ios", |
||||
"web": "expo start --web" |
||||
}, |
||||
"dependencies": { |
||||
"@expo/html-elements": "^0.10.1", |
||||
"@gluestack-ui/core": "^3.0.0", |
||||
"@gluestack-ui/utils": "^3.0.0", |
||||
"@legendapp/motion": "^2.4.0", |
||||
"babel-plugin-module-resolver": "^5.0.2", |
||||
"expo": "^54.0.7", |
||||
"expo-status-bar": "~3.0.8", |
||||
"lucide-react-native": "^0.543.0", |
||||
"nativewind": "^4.1.23", |
||||
"react": "19.1.0", |
||||
"react-aria": "^3.33.0", |
||||
"react-dom": "19.1.0", |
||||
"react-native": "0.81.4", |
||||
"react-native-reanimated": "~4.1.0", |
||||
"react-native-safe-area-context": "^5.4.0", |
||||
"react-native-svg": "15.12.1", |
||||
"react-native-worklets": "^0.5.0", |
||||
"react-stately": "^3.39.0", |
||||
"tailwind-variants": "^0.1.20", |
||||
"tailwindcss": "^3.4.17" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.25.2", |
||||
"@types/react": "~19.1.10", |
||||
"typescript": "~5.9.2" |
||||
}, |
||||
"private": true |
||||
} |
||||
|
@ -0,0 +1,22 @@ |
||||
import { View, ViewProps } from 'react-native'; |
||||
import React from 'react'; |
||||
import { centerStyle } from './styles'; |
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
type ICenterProps = ViewProps & VariantProps<typeof centerStyle>; |
||||
|
||||
const Center = React.forwardRef<React.ComponentRef<typeof View>, ICenterProps>( |
||||
function Center({ className, ...props }, ref) { |
||||
return ( |
||||
<View |
||||
className={centerStyle({ class: className })} |
||||
{...props} |
||||
ref={ref} |
||||
/> |
||||
); |
||||
} |
||||
); |
||||
|
||||
Center.displayName = 'Center'; |
||||
|
||||
export { Center }; |
@ -0,0 +1,20 @@ |
||||
import React from 'react'; |
||||
import { centerStyle } from './styles'; |
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
type ICenterProps = React.ComponentPropsWithoutRef<'div'> & |
||||
VariantProps<typeof centerStyle>; |
||||
|
||||
const Center = React.forwardRef<HTMLDivElement, ICenterProps>(function Center( |
||||
{ className, ...props }, |
||||
ref |
||||
) { |
||||
return ( |
||||
<div className={centerStyle({ class: className })} {...props} ref={ref} /> |
||||
); |
||||
}); |
||||
|
||||
Center.displayName = 'Center'; |
||||
|
||||
export { Center }; |
@ -0,0 +1,8 @@ |
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils'; |
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
const baseStyle = isWeb ? 'flex flex-col relative z-0' : ''; |
||||
|
||||
export const centerStyle = tva({ |
||||
base: `justify-center items-center ${baseStyle}`, |
||||
}); |
File diff suppressed because it is too large
Load Diff
@ -1,39 +1,39 @@ |
||||
{ |
||||
"name": "expo.project", |
||||
"version": "1.0.0", |
||||
"main": "index.ts", |
||||
"scripts": { |
||||
"start": "expo start", |
||||
"android": "expo start --android", |
||||
"ios": "expo start --ios", |
||||
"web": "expo start --web" |
||||
}, |
||||
"dependencies": { |
||||
"@expo/html-elements": "^0.10.1", |
||||
"@gluestack-ui/core": "^3.0.0", |
||||
"@gluestack-ui/utils": "^3.0.0", |
||||
"@legendapp/motion": "^2.4.0", |
||||
"babel-plugin-module-resolver": "^5.0.2", |
||||
"expo": "~53.0.22", |
||||
"expo-status-bar": "~2.2.3", |
||||
"lucide-react-native": "^0.543.0", |
||||
"nativewind": "^4.1.23", |
||||
"react": "19.0.0", |
||||
"react-aria": "^3.33.0", |
||||
"react-dom": "^19.1.1", |
||||
"react-native": "0.79.6", |
||||
"react-native-reanimated": "^4.1.0", |
||||
"react-native-safe-area-context": "^5.6.1", |
||||
"react-native-svg": "^15.2.0", |
||||
"react-native-worklets": "^0.5.0", |
||||
"react-stately": "^3.39.0", |
||||
"tailwind-variants": "^0.1.20", |
||||
"tailwindcss": "^3.4.17" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.25.2", |
||||
"@types/react": "~19.0.10", |
||||
"typescript": "~5.8.3" |
||||
}, |
||||
"private": true |
||||
} |
||||
{ |
||||
"name": "expo.project", |
||||
"version": "1.0.0", |
||||
"main": "index.ts", |
||||
"scripts": { |
||||
"start": "expo start", |
||||
"android": "expo start --android", |
||||
"ios": "expo start --ios", |
||||
"web": "expo start --web" |
||||
}, |
||||
"dependencies": { |
||||
"@expo/html-elements": "^0.10.1", |
||||
"@gluestack-ui/core": "^3.0.0", |
||||
"@gluestack-ui/utils": "^3.0.0", |
||||
"@legendapp/motion": "^2.4.0", |
||||
"babel-plugin-module-resolver": "^5.0.2", |
||||
"expo": "^54.0.7", |
||||
"expo-status-bar": "~3.0.8", |
||||
"lucide-react-native": "^0.543.0", |
||||
"nativewind": "^4.1.23", |
||||
"react": "19.1.0", |
||||
"react-aria": "^3.33.0", |
||||
"react-dom": "19.1.0", |
||||
"react-native": "0.81.4", |
||||
"react-native-reanimated": "^4.1.0", |
||||
"react-native-safe-area-context": "^5.6.1", |
||||
"react-native-svg": "15.12.1", |
||||
"react-native-worklets": "0.5.1", |
||||
"react-stately": "^3.39.0", |
||||
"tailwind-variants": "^0.1.20", |
||||
"tailwindcss": "^3.4.17" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.25.2", |
||||
"@types/react": "~19.1.10", |
||||
"typescript": "~5.9.2" |
||||
}, |
||||
"private": true |
||||
} |
||||
|
@ -0,0 +1,28 @@ |
||||
import { Box } from '@/components/ui/box'; |
||||
import { Button, ButtonText } from '@/components/ui/button'; |
||||
import { Center } from '@/components/ui/center'; |
||||
import { HStack } from '@/components/ui/hstack'; |
||||
import { Text } from '@/components/ui/text'; |
||||
import { VStack } from '@/components/ui/vstack'; |
||||
import { useCounterDispatch, useCounterState } from '@/states/ConterProvider'; |
||||
|
||||
export default function IndexPage() { |
||||
const state = useCounterState(); |
||||
const dispatch = useCounterDispatch(); |
||||
|
||||
return ( |
||||
<Box className="flex-1 justify-center items-center"> |
||||
<Center style={{ width: '50%', height: '30%' }} className="p-3 bg-secondary-500 h-1/2 w-1/2"> |
||||
<Text className="text-lg font-semibold">Count: {state.count}</Text> |
||||
<HStack className="gap-2"> |
||||
<Button className="w-[200px]" onPress={() => dispatch({ type: 'INCREMENT' })}> |
||||
<ButtonText>+</ButtonText> |
||||
</Button> |
||||
<Button className="w-[150px]" onPress={() => dispatch({ type: 'DECREMENT' })}> |
||||
<ButtonText>-</ButtonText> |
||||
</Button> |
||||
</HStack> |
||||
</Center> |
||||
</Box> |
||||
); |
||||
} |
@ -0,0 +1,45 @@ |
||||
import { createContext, Dispatch, ReactNode, useContext, useReducer } from 'react'; |
||||
|
||||
type State = { count: number }; |
||||
type Action = { type: 'INCREMENT' | 'DECREMENT' }; |
||||
|
||||
const initialState: State = { count: 0 }; |
||||
|
||||
function counterReducer(state: State, action: Action): State { |
||||
switch (action.type) { |
||||
case 'INCREMENT': |
||||
return { count: state.count + 1 }; |
||||
case 'DECREMENT': |
||||
return { count: state.count - 1 }; |
||||
default: |
||||
throw new Error('Unhandled action'); |
||||
} |
||||
} |
||||
|
||||
const CounterStateContext = createContext<State | undefined>(undefined); |
||||
const CounterDispatchContext = createContext<Dispatch<Action> | undefined>(undefined); |
||||
|
||||
export function CounterProvider({ children }: { children: ReactNode }) { |
||||
const [state, dispatch] = useReducer(counterReducer, initialState); |
||||
return ( |
||||
<CounterStateContext.Provider value={state}> |
||||
<CounterDispatchContext.Provider value={dispatch}>{children}</CounterDispatchContext.Provider> |
||||
</CounterStateContext.Provider> |
||||
); |
||||
} |
||||
|
||||
export function useCounterState() { |
||||
const context = useContext(CounterStateContext); |
||||
if (context === undefined) |
||||
throw new Error('useCounterState must be used within a CounterProvider'); |
||||
|
||||
return context; |
||||
} |
||||
|
||||
export function useCounterDispatch() { |
||||
const context = useContext(CounterDispatchContext); |
||||
if (context === undefined) |
||||
throw new Error('useCounterDispatch must be used within a CounterProvider'); |
||||
|
||||
return context; |
||||
} |
Loading…
Reference in new issue