Peace 2 days ago
parent 0538ab746b
commit 8bced2e266
  1. 34
      expo-project/App.tsx
  2. 39
      expo-project/package.json
  3. 1
      expo.project/.npmrc
  4. 30
      expo.project/App.tsx
  5. 30
      expo.project/babel.config.js
  6. 19
      expo.project/components/ui/box/index.tsx
  7. 19
      expo.project/components/ui/box/index.web.tsx
  8. 10
      expo.project/components/ui/box/styles.tsx
  9. 439
      expo.project/components/ui/button/index.tsx
  10. 26
      expo.project/components/ui/card/index.tsx
  11. 23
      expo.project/components/ui/card/index.web.tsx
  12. 20
      expo.project/components/ui/card/styles.tsx
  13. 22
      expo.project/components/ui/center/index.tsx
  14. 20
      expo.project/components/ui/center/index.web.tsx
  15. 8
      expo.project/components/ui/center/styles.tsx
  16. 309
      expo.project/components/ui/gluestack-ui-provider/config.ts
  17. 87
      expo.project/components/ui/gluestack-ui-provider/index.next15.tsx
  18. 38
      expo.project/components/ui/gluestack-ui-provider/index.tsx
  19. 96
      expo.project/components/ui/gluestack-ui-provider/index.web.tsx
  20. 19
      expo.project/components/ui/gluestack-ui-provider/script.ts
  21. 19
      expo.project/components/ui/gluestack-ui-token.ts
  22. 27
      expo.project/components/ui/hstack/index.tsx
  23. 26
      expo.project/components/ui/hstack/index.web.tsx
  24. 25
      expo.project/components/ui/hstack/styles.tsx
  25. 48
      expo.project/components/ui/image/index.tsx
  26. 217
      expo.project/components/ui/input/index.tsx
  27. 40
      expo.project/components/ui/spinner/index.tsx
  28. 48
      expo.project/components/ui/text/index.tsx
  29. 45
      expo.project/components/ui/text/index.web.tsx
  30. 47
      expo.project/components/ui/text/styles.tsx
  31. 94
      expo.project/components/ui/textarea/index.tsx
  32. 240
      expo.project/components/ui/toast/index.tsx
  33. 28
      expo.project/components/ui/vstack/index.tsx
  34. 27
      expo.project/components/ui/vstack/index.web.tsx
  35. 25
      expo.project/components/ui/vstack/styles.tsx
  36. 28
      expo.project/screens/IndexPage.tsx
  37. 45
      expo.project/states/ConterProvider.tsx
  38. 206
      expo.project/tailwind.config.js
  39. 0
      gluestack-project/.gitignore
  40. 0
      gluestack-project/.npmrc
  41. 31
      gluestack-project/App.tsx
  42. 67
      gluestack-project/app.json
  43. 0
      gluestack-project/assets/adaptive-icon.png
  44. 0
      gluestack-project/assets/favicon.png
  45. 0
      gluestack-project/assets/icon.png
  46. 0
      gluestack-project/assets/splash-icon.png
  47. 0
      gluestack-project/babel.config.js
  48. 0
      gluestack-project/components/ui/box/index.tsx
  49. 0
      gluestack-project/components/ui/box/index.web.tsx
  50. 0
      gluestack-project/components/ui/box/styles.tsx
  51. 0
      gluestack-project/components/ui/button/index.tsx
  52. 0
      gluestack-project/components/ui/card/index.tsx
  53. 0
      gluestack-project/components/ui/card/index.web.tsx
  54. 0
      gluestack-project/components/ui/card/styles.tsx
  55. 0
      gluestack-project/components/ui/center/index.tsx
  56. 0
      gluestack-project/components/ui/center/index.web.tsx
  57. 0
      gluestack-project/components/ui/center/styles.tsx
  58. 0
      gluestack-project/components/ui/gluestack-ui-provider/config.ts
  59. 0
      gluestack-project/components/ui/gluestack-ui-provider/index.next15.tsx
  60. 0
      gluestack-project/components/ui/gluestack-ui-provider/index.tsx
  61. 0
      gluestack-project/components/ui/gluestack-ui-provider/index.web.tsx
  62. 0
      gluestack-project/components/ui/gluestack-ui-provider/script.ts
  63. 0
      gluestack-project/components/ui/gluestack-ui-token.ts
  64. 0
      gluestack-project/components/ui/hstack/index.tsx
  65. 0
      gluestack-project/components/ui/hstack/index.web.tsx
  66. 0
      gluestack-project/components/ui/hstack/styles.tsx
  67. 1600
      gluestack-project/components/ui/icon/index.tsx
  68. 1573
      gluestack-project/components/ui/icon/index.web.tsx
  69. 0
      gluestack-project/components/ui/image/index.tsx
  70. 0
      gluestack-project/components/ui/input/index.tsx
  71. 39
      gluestack-project/components/ui/pressable/index.tsx
  72. 0
      gluestack-project/components/ui/spinner/index.tsx
  73. 0
      gluestack-project/components/ui/text/index.tsx
  74. 0
      gluestack-project/components/ui/text/index.web.tsx
  75. 0
      gluestack-project/components/ui/text/styles.tsx
  76. 0
      gluestack-project/components/ui/textarea/index.tsx
  77. 0
      gluestack-project/components/ui/toast/index.tsx
  78. 0
      gluestack-project/components/ui/vstack/index.tsx
  79. 0
      gluestack-project/components/ui/vstack/index.web.tsx
  80. 0
      gluestack-project/components/ui/vstack/styles.tsx
  81. 0
      gluestack-project/global.css
  82. 0
      gluestack-project/index.ts
  83. 0
      gluestack-project/metro.config.js
  84. 0
      gluestack-project/nativewind-env.d.ts
  85. 3974
      gluestack-project/package-lock.json
  86. 19
      gluestack-project/package.json
  87. 0
      gluestack-project/prettier.config.js
  88. 2
      gluestack-project/screen/IndexPage.tsx
  89. 0
      gluestack-project/states/CounterProvider.tsx
  90. 0
      gluestack-project/tailwind.config.js
  91. 0
      gluestack-project/tsconfig.json
  92. 23
      my-expo-app/.gitignore
  93. 13
      my-expo-app/App.tsx
  94. 2
      my-expo-app/app-env.d.ts
  95. 38
      my-expo-app/app.json
  96. 0
      my-expo-app/assets/adaptive-icon.png
  97. 0
      my-expo-app/assets/favicon.png
  98. 0
      my-expo-app/assets/icon.png
  99. BIN
      my-expo-app/assets/splash.png
  100. 10
      my-expo-app/babel.config.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,34 +0,0 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, View } from 'react-native';
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider';
import '@/global.css';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { CounterProvider } from './states/ConterProvider';
import IndexPage from './screens/IndexPage';
import { HStack } from './components/ui/hstack';
import { Text } from './components/ui/text';
export default function App() {
return (
<CounterProvider>
<GluestackUIProvider mode="light">
<SafeAreaProvider>
<SafeAreaView style={{ flex: 1 }} className="m-2">
<StatusBar style="auto" />
<IndexPage />
</SafeAreaView>
</SafeAreaProvider>
</GluestackUIProvider>
</CounterProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

@ -1,39 +0,0 @@
{
"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
}

@ -1 +0,0 @@
legacy-peer-deps=true

@ -1,30 +0,0 @@
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider';
import '@/global.css';
import { SafeAreaView } from 'react-native-safe-area-context';
import { CounterProvider } from './states/ConterProvider';
import IndexPage from './screens/IndexPage';
export default function App() {
return (
<CounterProvider>
<GluestackUIProvider mode="light">
<SafeAreaView style={{ flex: 1 }} className="m-2">
<StatusBar style="auto" />
<IndexPage />
</SafeAreaView>
</GluestackUIProvider>
</CounterProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

@ -1,30 +0,0 @@
module.exports = function (api) {
api.cache(true);
return {
presets: [
[
'babel-preset-expo',
{
jsxImportSource: 'nativewind',
},
],
'nativewind/babel',
],
plugins: [
[
'module-resolver',
{
root: ['./'],
alias: {
'@': './',
'tailwind.config': './tailwind.config.js',
},
},
],
'react-native-reanimated/plugin',
],
};
};

@ -1,19 +0,0 @@
import React from 'react';
import { View, ViewProps } from 'react-native';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { boxStyle } from './styles';
type IBoxProps = ViewProps &
VariantProps<typeof boxStyle> & { className?: string };
const Box = React.forwardRef<React.ComponentRef<typeof View>, IBoxProps>(
function Box({ className, ...props }, ref) {
return (
<View ref={ref} {...props} className={boxStyle({ class: className })} />
);
}
);
Box.displayName = 'Box';
export { Box };

@ -1,19 +0,0 @@
import React from 'react';
import { boxStyle } from './styles';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
type IBoxProps = React.ComponentPropsWithoutRef<'div'> &
VariantProps<typeof boxStyle> & { className?: string };
const Box = React.forwardRef<HTMLDivElement, IBoxProps>(function Box(
{ className, ...props },
ref
) {
return (
<div ref={ref} className={boxStyle({ class: className })} {...props} />
);
});
Box.displayName = 'Box';
export { Box };

@ -1,10 +0,0 @@
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 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
: '';
export const boxStyle = tva({
base: baseStyle,
});

@ -1,439 +0,0 @@
'use client';
import React from 'react';
import { createButton } from '@gluestack-ui/core/button/creator';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/utils/nativewind-utils';
import { cssInterop } from 'nativewind';
import { ActivityIndicator, Pressable, Text, View } from 'react-native';
import type { VariantProps } from 'tailwind-variants';
import { PrimitiveIcon, UIIcon } from '@gluestack-ui/core/icon/creator';
const SCOPE = 'BUTTON';
const Root = withStyleContext(Pressable, SCOPE);
const UIButton = createButton({
Root: Root,
Text,
Group: View,
Spinner: ActivityIndicator,
Icon: UIIcon,
});
cssInterop(PrimitiveIcon, {
className: {
target: 'style',
nativeStyleToProp: {
height: true,
width: true,
fill: true,
color: 'classNameColor',
stroke: true,
},
},
});
const buttonStyle = tva({
base: 'group/button rounded bg-primary-500 flex-row items-center justify-center data-[focus-visible=true]:web:outline-none data-[focus-visible=true]:web:ring-2 data-[disabled=true]:opacity-40 gap-2',
variants: {
action: {
primary:
'bg-primary-500 data-[hover=true]:bg-primary-600 data-[active=true]:bg-primary-700 border-primary-300 data-[hover=true]:border-primary-400 data-[active=true]:border-primary-500 data-[focus-visible=true]:web:ring-indicator-info',
secondary:
'bg-secondary-500 border-secondary-300 data-[hover=true]:bg-secondary-600 data-[hover=true]:border-secondary-400 data-[active=true]:bg-secondary-700 data-[active=true]:border-secondary-700 data-[focus-visible=true]:web:ring-indicator-info',
positive:
'bg-success-500 border-success-300 data-[hover=true]:bg-success-600 data-[hover=true]:border-success-400 data-[active=true]:bg-success-700 data-[active=true]:border-success-500 data-[focus-visible=true]:web:ring-indicator-info',
negative:
'bg-error-500 border-error-300 data-[hover=true]:bg-error-600 data-[hover=true]:border-error-400 data-[active=true]:bg-error-700 data-[active=true]:border-error-500 data-[focus-visible=true]:web:ring-indicator-info',
default:
'bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent',
},
variant: {
link: 'px-0',
outline:
'bg-transparent border data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent',
solid: '',
},
size: {
xs: 'px-3.5 h-8',
sm: 'px-4 h-9',
md: 'px-5 h-10',
lg: 'px-6 h-11',
xl: 'px-7 h-12',
},
},
compoundVariants: [
{
action: 'primary',
variant: 'link',
class:
'px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent',
},
{
action: 'secondary',
variant: 'link',
class:
'px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent',
},
{
action: 'positive',
variant: 'link',
class:
'px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent',
},
{
action: 'negative',
variant: 'link',
class:
'px-0 bg-transparent data-[hover=true]:bg-transparent data-[active=true]:bg-transparent',
},
{
action: 'primary',
variant: 'outline',
class:
'bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent',
},
{
action: 'secondary',
variant: 'outline',
class:
'bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent',
},
{
action: 'positive',
variant: 'outline',
class:
'bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent',
},
{
action: 'negative',
variant: 'outline',
class:
'bg-transparent data-[hover=true]:bg-background-50 data-[active=true]:bg-transparent',
},
],
});
const buttonTextStyle = tva({
base: 'text-typography-0 font-semibold web:select-none',
parentVariants: {
action: {
primary:
'text-primary-600 data-[hover=true]:text-primary-600 data-[active=true]:text-primary-700',
secondary:
'text-typography-500 data-[hover=true]:text-typography-600 data-[active=true]:text-typography-700',
positive:
'text-success-600 data-[hover=true]:text-success-600 data-[active=true]:text-success-700',
negative:
'text-error-600 data-[hover=true]:text-error-600 data-[active=true]:text-error-700',
},
variant: {
link: 'data-[hover=true]:underline data-[active=true]:underline',
outline: '',
solid:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
size: {
xs: 'text-xs',
sm: 'text-sm',
md: 'text-base',
lg: 'text-lg',
xl: 'text-xl',
},
},
parentCompoundVariants: [
{
variant: 'solid',
action: 'primary',
class:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
{
variant: 'solid',
action: 'secondary',
class:
'text-typography-800 data-[hover=true]:text-typography-800 data-[active=true]:text-typography-800',
},
{
variant: 'solid',
action: 'positive',
class:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
{
variant: 'solid',
action: 'negative',
class:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
{
variant: 'outline',
action: 'primary',
class:
'text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500',
},
{
variant: 'outline',
action: 'secondary',
class:
'text-typography-500 data-[hover=true]:text-primary-600 data-[active=true]:text-typography-700',
},
{
variant: 'outline',
action: 'positive',
class:
'text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500',
},
{
variant: 'outline',
action: 'negative',
class:
'text-primary-500 data-[hover=true]:text-primary-500 data-[active=true]:text-primary-500',
},
],
});
const buttonIconStyle = tva({
base: 'fill-none',
parentVariants: {
variant: {
link: 'data-[hover=true]:underline data-[active=true]:underline',
outline: '',
solid:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
size: {
xs: 'h-3.5 w-3.5',
sm: 'h-4 w-4',
md: 'h-[18px] w-[18px]',
lg: 'h-[18px] w-[18px]',
xl: 'h-5 w-5',
},
action: {
primary:
'text-primary-600 data-[hover=true]:text-primary-600 data-[active=true]:text-primary-700',
secondary:
'text-typography-500 data-[hover=true]:text-typography-600 data-[active=true]:text-typography-700',
positive:
'text-success-600 data-[hover=true]:text-success-600 data-[active=true]:text-success-700',
negative:
'text-error-600 data-[hover=true]:text-error-600 data-[active=true]:text-error-700',
},
},
parentCompoundVariants: [
{
variant: 'solid',
action: 'primary',
class:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
{
variant: 'solid',
action: 'secondary',
class:
'text-typography-800 data-[hover=true]:text-typography-800 data-[active=true]:text-typography-800',
},
{
variant: 'solid',
action: 'positive',
class:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
{
variant: 'solid',
action: 'negative',
class:
'text-typography-0 data-[hover=true]:text-typography-0 data-[active=true]:text-typography-0',
},
],
});
const buttonGroupStyle = tva({
base: '',
variants: {
space: {
'xs': 'gap-1',
'sm': 'gap-2',
'md': 'gap-3',
'lg': 'gap-4',
'xl': 'gap-5',
'2xl': 'gap-6',
'3xl': 'gap-7',
'4xl': 'gap-8',
},
isAttached: {
true: 'gap-0',
},
flexDirection: {
'row': 'flex-row',
'column': 'flex-col',
'row-reverse': 'flex-row-reverse',
'column-reverse': 'flex-col-reverse',
},
},
});
type IButtonProps = Omit<
React.ComponentPropsWithoutRef<typeof UIButton>,
'context'
> &
VariantProps<typeof buttonStyle> & { className?: string };
const Button = React.forwardRef<
React.ElementRef<typeof UIButton>,
IButtonProps
>(
(
{ className, variant = 'solid', size = 'md', action = 'primary', ...props },
ref
) => {
return (
<UIButton
ref={ref}
{...props}
className={buttonStyle({ variant, size, action, class: className })}
context={{ variant, size, action }}
/>
);
}
);
type IButtonTextProps = React.ComponentPropsWithoutRef<typeof UIButton.Text> &
VariantProps<typeof buttonTextStyle> & { className?: string };
const ButtonText = React.forwardRef<
React.ElementRef<typeof UIButton.Text>,
IButtonTextProps
>(({ className, variant, size, action, ...props }, ref) => {
const {
variant: parentVariant,
size: parentSize,
action: parentAction,
} = useStyleContext(SCOPE);
return (
<UIButton.Text
ref={ref}
{...props}
className={buttonTextStyle({
parentVariants: {
variant: parentVariant,
size: parentSize,
action: parentAction,
},
variant: variant as 'link' | 'outline' | 'solid' | undefined,
size,
action: action as
| 'primary'
| 'secondary'
| 'positive'
| 'negative'
| undefined,
class: className,
})}
/>
);
});
const ButtonSpinner = UIButton.Spinner;
type IButtonIcon = React.ComponentPropsWithoutRef<typeof UIButton.Icon> &
VariantProps<typeof buttonIconStyle> & {
className?: string | undefined;
as?: React.ElementType;
height?: number;
width?: number;
};
const ButtonIcon = React.forwardRef<
React.ElementRef<typeof UIButton.Icon>,
IButtonIcon
>(({ className, size, ...props }, ref) => {
const {
variant: parentVariant,
size: parentSize,
action: parentAction,
} = useStyleContext(SCOPE);
if (typeof size === 'number') {
return (
<UIButton.Icon
ref={ref}
{...props}
className={buttonIconStyle({ class: className })}
size={size}
/>
);
} else if (
(props.height !== undefined || props.width !== undefined) &&
size === undefined
) {
return (
<UIButton.Icon
ref={ref}
{...props}
className={buttonIconStyle({ class: className })}
/>
);
}
return (
<UIButton.Icon
{...props}
className={buttonIconStyle({
parentVariants: {
size: parentSize,
variant: parentVariant,
action: parentAction,
},
size,
class: className,
})}
ref={ref}
/>
);
});
type IButtonGroupProps = React.ComponentPropsWithoutRef<typeof UIButton.Group> &
VariantProps<typeof buttonGroupStyle>;
const ButtonGroup = React.forwardRef<
React.ElementRef<typeof UIButton.Group>,
IButtonGroupProps
>(
(
{
className,
space = 'md',
isAttached = false,
flexDirection = 'column',
...props
},
ref
) => {
return (
<UIButton.Group
className={buttonGroupStyle({
class: className,
space,
isAttached: isAttached as boolean,
flexDirection: flexDirection as any,
})}
{...props}
ref={ref}
/>
);
}
);
Button.displayName = 'Button';
ButtonText.displayName = 'ButtonText';
ButtonSpinner.displayName = 'ButtonSpinner';
ButtonIcon.displayName = 'ButtonIcon';
ButtonGroup.displayName = 'ButtonGroup';
export { Button, ButtonText, ButtonSpinner, ButtonIcon, ButtonGroup };

@ -1,26 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { View, ViewProps } from 'react-native';
import { cardStyle } from './styles';
type ICardProps = ViewProps &
VariantProps<typeof cardStyle> & { className?: string };
const Card = React.forwardRef<React.ComponentRef<typeof View>, ICardProps>(
function Card(
{ className, size = 'md', variant = 'elevated', ...props },
ref
) {
return (
<View
className={cardStyle({ size, variant, class: className })}
{...props}
ref={ref}
/>
);
}
);
Card.displayName = 'Card';
export { Card };

@ -1,23 +0,0 @@
import React from 'react';
import { cardStyle } from './styles';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
type ICardProps = React.ComponentPropsWithoutRef<'div'> &
VariantProps<typeof cardStyle>;
const Card = React.forwardRef<HTMLDivElement, ICardProps>(function Card(
{ className, size = 'md', variant = 'elevated', ...props },
ref
) {
return (
<div
className={cardStyle({ size, variant, class: className })}
{...props}
ref={ref}
/>
);
});
Card.displayName = 'Card';
export { Card };

@ -1,20 +0,0 @@
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 cardStyle = tva({
base: baseStyle,
variants: {
size: {
sm: 'p-3 rounded',
md: 'p-4 rounded-md',
lg: 'p-6 rounded-xl',
},
variant: {
elevated: 'bg-background-0',
outline: 'border border-outline-200 ',
ghost: 'rounded-none',
filled: 'bg-background-50',
},
},
});

@ -1,22 +0,0 @@
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 };

@ -1,20 +0,0 @@
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 };

@ -1,8 +0,0 @@
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}`,
});

@ -1,309 +0,0 @@
'use client';
import { vars } from 'nativewind';
export const config = {
light: vars({
'--color-primary-0': '179 179 179',
'--color-primary-50': '153 153 153',
'--color-primary-100': '128 128 128',
'--color-primary-200': '115 115 115',
'--color-primary-300': '102 102 102',
'--color-primary-400': '82 82 82',
'--color-primary-500': '51 51 51',
'--color-primary-600': '41 41 41',
'--color-primary-700': '31 31 31',
'--color-primary-800': '13 13 13',
'--color-primary-900': '10 10 10',
'--color-primary-950': '8 8 8',
/* Secondary */
'--color-secondary-0': '253 253 253',
'--color-secondary-50': '251 251 251',
'--color-secondary-100': '246 246 246',
'--color-secondary-200': '242 242 242',
'--color-secondary-300': '237 237 237',
'--color-secondary-400': '230 230 231',
'--color-secondary-500': '217 217 219',
'--color-secondary-600': '198 199 199',
'--color-secondary-700': '189 189 189',
'--color-secondary-800': '177 177 177',
'--color-secondary-900': '165 164 164',
'--color-secondary-950': '157 157 157',
/* Tertiary */
'--color-tertiary-0': '255 250 245',
'--color-tertiary-50': '255 242 229',
'--color-tertiary-100': '255 233 213',
'--color-tertiary-200': '254 209 170',
'--color-tertiary-300': '253 180 116',
'--color-tertiary-400': '251 157 75',
'--color-tertiary-500': '231 129 40',
'--color-tertiary-600': '215 117 31',
'--color-tertiary-700': '180 98 26',
'--color-tertiary-800': '130 73 23',
'--color-tertiary-900': '108 61 19',
'--color-tertiary-950': '84 49 18',
/* Error */
'--color-error-0': '254 233 233',
'--color-error-50': '254 226 226',
'--color-error-100': '254 202 202',
'--color-error-200': '252 165 165',
'--color-error-300': '248 113 113',
'--color-error-400': '239 68 68',
'--color-error-500': '230 53 53',
'--color-error-600': '220 38 38',
'--color-error-700': '185 28 28',
'--color-error-800': '153 27 27',
'--color-error-900': '127 29 29',
'--color-error-950': '83 19 19',
/* Success */
'--color-success-0': '228 255 244',
'--color-success-50': '202 255 232',
'--color-success-100': '162 241 192',
'--color-success-200': '132 211 162',
'--color-success-300': '102 181 132',
'--color-success-400': '72 151 102',
'--color-success-500': '52 131 82',
'--color-success-600': '42 121 72',
'--color-success-700': '32 111 62',
'--color-success-800': '22 101 52',
'--color-success-900': '20 83 45',
'--color-success-950': '27 50 36',
/* Warning */
'--color-warning-0': '255 249 245',
'--color-warning-50': '255 244 236',
'--color-warning-100': '255 231 213',
'--color-warning-200': '254 205 170',
'--color-warning-300': '253 173 116',
'--color-warning-400': '251 149 75',
'--color-warning-500': '231 120 40',
'--color-warning-600': '215 108 31',
'--color-warning-700': '180 90 26',
'--color-warning-800': '130 68 23',
'--color-warning-900': '108 56 19',
'--color-warning-950': '84 45 18',
/* Info */
'--color-info-0': '236 248 254',
'--color-info-50': '199 235 252',
'--color-info-100': '162 221 250',
'--color-info-200': '124 207 248',
'--color-info-300': '87 194 246',
'--color-info-400': '50 180 244',
'--color-info-500': '13 166 242',
'--color-info-600': '11 141 205',
'--color-info-700': '9 115 168',
'--color-info-800': '7 90 131',
'--color-info-900': '5 64 93',
'--color-info-950': '3 38 56',
/* Typography */
'--color-typography-0': '254 254 255',
'--color-typography-50': '245 245 245',
'--color-typography-100': '229 229 229',
'--color-typography-200': '219 219 220',
'--color-typography-300': '212 212 212',
'--color-typography-400': '163 163 163',
'--color-typography-500': '140 140 140',
'--color-typography-600': '115 115 115',
'--color-typography-700': '82 82 82',
'--color-typography-800': '64 64 64',
'--color-typography-900': '38 38 39',
'--color-typography-950': '23 23 23',
/* Outline */
'--color-outline-0': '253 254 254',
'--color-outline-50': '243 243 243',
'--color-outline-100': '230 230 230',
'--color-outline-200': '221 220 219',
'--color-outline-300': '211 211 211',
'--color-outline-400': '165 163 163',
'--color-outline-500': '140 141 141',
'--color-outline-600': '115 116 116',
'--color-outline-700': '83 82 82',
'--color-outline-800': '65 65 65',
'--color-outline-900': '39 38 36',
'--color-outline-950': '26 23 23',
/* Background */
'--color-background-0': '255 255 255',
'--color-background-50': '246 246 246',
'--color-background-100': '242 241 241',
'--color-background-200': '220 219 219',
'--color-background-300': '213 212 212',
'--color-background-400': '162 163 163',
'--color-background-500': '142 142 142',
'--color-background-600': '116 116 116',
'--color-background-700': '83 82 82',
'--color-background-800': '65 64 64',
'--color-background-900': '39 38 37',
'--color-background-950': '18 18 18',
/* Background Special */
'--color-background-error': '254 241 241',
'--color-background-warning': '255 243 234',
'--color-background-success': '237 252 242',
'--color-background-muted': '247 248 247',
'--color-background-info': '235 248 254',
/* Focus Ring Indicator */
'--color-indicator-primary': '55 55 55',
'--color-indicator-info': '83 153 236',
'--color-indicator-error': '185 28 28',
}),
dark: vars({
'--color-primary-0': '166 166 166',
'--color-primary-50': '175 175 175',
'--color-primary-100': '186 186 186',
'--color-primary-200': '197 197 197',
'--color-primary-300': '212 212 212',
'--color-primary-400': '221 221 221',
'--color-primary-500': '230 230 230',
'--color-primary-600': '240 240 240',
'--color-primary-700': '250 250 250',
'--color-primary-800': '253 253 253',
'--color-primary-900': '254 249 249',
'--color-primary-950': '253 252 252',
/* Secondary */
'--color-secondary-0': '20 20 20',
'--color-secondary-50': '23 23 23',
'--color-secondary-100': '31 31 31',
'--color-secondary-200': '39 39 39',
'--color-secondary-300': '44 44 44',
'--color-secondary-400': '56 57 57',
'--color-secondary-500': '63 64 64',
'--color-secondary-600': '86 86 86',
'--color-secondary-700': '110 110 110',
'--color-secondary-800': '135 135 135',
'--color-secondary-900': '150 150 150',
'--color-secondary-950': '164 164 164',
/* Tertiary */
'--color-tertiary-0': '84 49 18',
'--color-tertiary-50': '108 61 19',
'--color-tertiary-100': '130 73 23',
'--color-tertiary-200': '180 98 26',
'--color-tertiary-300': '215 117 31',
'--color-tertiary-400': '231 129 40',
'--color-tertiary-500': '251 157 75',
'--color-tertiary-600': '253 180 116',
'--color-tertiary-700': '254 209 170',
'--color-tertiary-800': '255 233 213',
'--color-tertiary-900': '255 242 229',
'--color-tertiary-950': '255 250 245',
/* Error */
'--color-error-0': '83 19 19',
'--color-error-50': '127 29 29',
'--color-error-100': '153 27 27',
'--color-error-200': '185 28 28',
'--color-error-300': '220 38 38',
'--color-error-400': '230 53 53',
'--color-error-500': '239 68 68',
'--color-error-600': '249 97 96',
'--color-error-700': '229 91 90',
'--color-error-800': '254 202 202',
'--color-error-900': '254 226 226',
'--color-error-950': '254 233 233',
/* Success */
'--color-success-0': '27 50 36',
'--color-success-50': '20 83 45',
'--color-success-100': '22 101 52',
'--color-success-200': '32 111 62',
'--color-success-300': '42 121 72',
'--color-success-400': '52 131 82',
'--color-success-500': '72 151 102',
'--color-success-600': '102 181 132',
'--color-success-700': '132 211 162',
'--color-success-800': '162 241 192',
'--color-success-900': '202 255 232',
'--color-success-950': '228 255 244',
/* Warning */
'--color-warning-0': '84 45 18',
'--color-warning-50': '108 56 19',
'--color-warning-100': '130 68 23',
'--color-warning-200': '180 90 26',
'--color-warning-300': '215 108 31',
'--color-warning-400': '231 120 40',
'--color-warning-500': '251 149 75',
'--color-warning-600': '253 173 116',
'--color-warning-700': '254 205 170',
'--color-warning-800': '255 231 213',
'--color-warning-900': '255 244 237',
'--color-warning-950': '255 249 245',
/* Info */
'--color-info-0': '3 38 56',
'--color-info-50': '5 64 93',
'--color-info-100': '7 90 131',
'--color-info-200': '9 115 168',
'--color-info-300': '11 141 205',
'--color-info-400': '13 166 242',
'--color-info-500': '50 180 244',
'--color-info-600': '87 194 246',
'--color-info-700': '124 207 248',
'--color-info-800': '162 221 250',
'--color-info-900': '199 235 252',
'--color-info-950': '236 248 254',
/* Typography */
'--color-typography-0': '23 23 23',
'--color-typography-50': '38 38 39',
'--color-typography-100': '64 64 64',
'--color-typography-200': '82 82 82',
'--color-typography-300': '115 115 115',
'--color-typography-400': '140 140 140',
'--color-typography-500': '163 163 163',
'--color-typography-600': '212 212 212',
'--color-typography-700': '219 219 220',
'--color-typography-800': '229 229 229',
'--color-typography-900': '245 245 245',
'--color-typography-950': '254 254 255',
/* Outline */
'--color-outline-0': '26 23 23',
'--color-outline-50': '39 38 36',
'--color-outline-100': '65 65 65',
'--color-outline-200': '83 82 82',
'--color-outline-300': '115 116 116',
'--color-outline-400': '140 141 141',
'--color-outline-500': '165 163 163',
'--color-outline-600': '211 211 211',
'--color-outline-700': '221 220 219',
'--color-outline-800': '230 230 230',
'--color-outline-900': '243 243 243',
'--color-outline-950': '253 254 254',
/* Background */
'--color-background-0': '18 18 18',
'--color-background-50': '39 38 37',
'--color-background-100': '65 64 64',
'--color-background-200': '83 82 82',
'--color-background-300': '116 116 116',
'--color-background-400': '142 142 142',
'--color-background-500': '162 163 163',
'--color-background-600': '213 212 212',
'--color-background-700': '229 228 228',
'--color-background-800': '242 241 241',
'--color-background-900': '246 246 246',
'--color-background-950': '255 255 255',
/* Background Special */
'--color-background-error': '66 43 43',
'--color-background-warning': '65 47 35',
'--color-background-success': '28 43 33',
'--color-background-muted': '51 51 51',
'--color-background-info': '26 40 46',
/* Focus Ring Indicator */
'--color-indicator-primary': '247 247 247',
'--color-indicator-info': '161 199 245',
'--color-indicator-error': '232 70 69',
}),
};

@ -1,87 +0,0 @@
// This is a Next.js 15 compatible version of the GluestackUIProvider
'use client';
import React, { useEffect, useLayoutEffect } from 'react';
import { config } from './config';
import { OverlayProvider } from '@gluestack-ui/core/overlay/creator';
import { ToastProvider } from '@gluestack-ui/core/toast/creator';
import { setFlushStyles } from '@gluestack-ui/utils/nativewind-utils';
import { script } from './script';
const variableStyleTagId = 'nativewind-style';
const createStyle = (styleTagId: string) => {
const style = document.createElement('style');
style.id = styleTagId;
style.appendChild(document.createTextNode(''));
return style;
};
export const useSafeLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
export function GluestackUIProvider({
mode = 'light',
...props
}: {
mode?: 'light' | 'dark' | 'system';
children?: React.ReactNode;
}) {
let cssVariablesWithMode = ``;
Object.keys(config).forEach((configKey) => {
cssVariablesWithMode +=
configKey === 'dark' ? `\n .dark {\n ` : `\n:root {\n`;
const cssVariables = Object.keys(
config[configKey as keyof typeof config]
).reduce((acc: string, curr: string) => {
acc += `${curr}:${config[configKey as keyof typeof config][curr]}; `;
return acc;
}, '');
cssVariablesWithMode += `${cssVariables} \n}`;
});
setFlushStyles(cssVariablesWithMode);
const handleMediaQuery = React.useCallback((e: MediaQueryListEvent) => {
script(e.matches ? 'dark' : 'light');
}, []);
useSafeLayoutEffect(() => {
if (mode !== 'system') {
const documentElement = document.documentElement;
if (documentElement) {
documentElement.classList.add(mode);
documentElement.classList.remove(mode === 'light' ? 'dark' : 'light');
documentElement.style.colorScheme = mode;
}
}
}, [mode]);
useSafeLayoutEffect(() => {
if (mode !== 'system') return;
const media = window.matchMedia('(prefers-color-scheme: dark)');
media.addListener(handleMediaQuery);
return () => media.removeListener(handleMediaQuery);
}, [handleMediaQuery]);
useSafeLayoutEffect(() => {
if (typeof window !== 'undefined') {
const documentElement = document.documentElement;
if (documentElement) {
const head = documentElement.querySelector('head');
let style = head?.querySelector(`[id='${variableStyleTagId}']`);
if (!style) {
style = createStyle(variableStyleTagId);
style.innerHTML = cssVariablesWithMode;
if (head) head.appendChild(style);
}
}
}
}, []);
return (
<OverlayProvider>
<ToastProvider>{props.children}</ToastProvider>
</OverlayProvider>
);
}

@ -1,38 +0,0 @@
import React, { useEffect } from 'react';
import { config } from './config';
import { View, ViewProps } from 'react-native';
import { OverlayProvider } from '@gluestack-ui/core/overlay/creator';
import { ToastProvider } from '@gluestack-ui/core/toast/creator';
import { useColorScheme } from 'nativewind';
export type ModeType = 'light' | 'dark' | 'system';
export function GluestackUIProvider({
mode = 'light',
...props
}: {
mode?: ModeType;
children?: React.ReactNode;
style?: ViewProps['style'];
}) {
const { colorScheme, setColorScheme } = useColorScheme();
useEffect(() => {
setColorScheme(mode);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [mode]);
return (
<View
style={[
config[colorScheme!],
{ flex: 1, height: '100%', width: '100%' },
props.style,
]}
>
<OverlayProvider>
<ToastProvider>{props.children}</ToastProvider>
</OverlayProvider>
</View>
);
}

@ -1,96 +0,0 @@
'use client';
import React, { useEffect, useLayoutEffect } from 'react';
import { config } from './config';
import { OverlayProvider } from '@gluestack-ui/core/overlay/creator';
import { ToastProvider } from '@gluestack-ui/core/toast/creator';
import { setFlushStyles } from '@gluestack-ui/utils/nativewind-utils';
import { script } from './script';
export type ModeType = 'light' | 'dark' | 'system';
const variableStyleTagId = 'nativewind-style';
const createStyle = (styleTagId: string) => {
const style = document.createElement('style');
style.id = styleTagId;
style.appendChild(document.createTextNode(''));
return style;
};
export const useSafeLayoutEffect =
typeof window !== 'undefined' ? useLayoutEffect : useEffect;
export function GluestackUIProvider({
mode = 'light',
...props
}: {
mode?: ModeType;
children?: React.ReactNode;
}) {
let cssVariablesWithMode = ``;
Object.keys(config).forEach((configKey) => {
cssVariablesWithMode +=
configKey === 'dark' ? `\n .dark {\n ` : `\n:root {\n`;
const cssVariables = Object.keys(
config[configKey as keyof typeof config]
).reduce((acc: string, curr: string) => {
acc += `${curr}:${config[configKey as keyof typeof config][curr]}; `;
return acc;
}, '');
cssVariablesWithMode += `${cssVariables} \n}`;
});
setFlushStyles(cssVariablesWithMode);
const handleMediaQuery = React.useCallback((e: MediaQueryListEvent) => {
script(e.matches ? 'dark' : 'light');
}, []);
useSafeLayoutEffect(() => {
if (mode !== 'system') {
const documentElement = document.documentElement;
if (documentElement) {
documentElement.classList.add(mode);
documentElement.classList.remove(mode === 'light' ? 'dark' : 'light');
documentElement.style.colorScheme = mode;
}
}
}, [mode]);
useSafeLayoutEffect(() => {
if (mode !== 'system') return;
const media = window.matchMedia('(prefers-color-scheme: dark)');
media.addListener(handleMediaQuery);
return () => media.removeListener(handleMediaQuery);
}, [handleMediaQuery]);
useSafeLayoutEffect(() => {
if (typeof window !== 'undefined') {
const documentElement = document.documentElement;
if (documentElement) {
const head = documentElement.querySelector('head');
let style = head?.querySelector(`[id='${variableStyleTagId}']`);
if (!style) {
style = createStyle(variableStyleTagId);
style.innerHTML = cssVariablesWithMode;
if (head) head.appendChild(style);
}
}
}
}, []);
return (
<>
<script
suppressHydrationWarning
dangerouslySetInnerHTML={{
__html: `(${script.toString()})('${mode}')`,
}}
/>
<OverlayProvider>
<ToastProvider>{props.children}</ToastProvider>
</OverlayProvider>
</>
);
}

@ -1,19 +0,0 @@
export const script = (mode: string) => {
const documentElement = document.documentElement;
function getSystemColorMode() {
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
}
try {
const isSystem = mode === 'system';
const theme = isSystem ? getSystemColorMode() : mode;
documentElement.classList.remove(theme === 'light' ? 'dark' : 'light');
documentElement.classList.add(theme);
documentElement.style.colorScheme = theme;
} catch (e) {
console.error(e);
}
};

@ -1,19 +0,0 @@
export const GS = {
size: {
xs: "xs",
sm: "sm",
md: "md",
lg: "lg",
},
variant: {
solid: "solid",
outline: "outline",
link: "link",
},
action: {
primary: "primary",
secondary: "secondary",
positive: "positive",
negative: "negative",
},
} as const;

@ -1,27 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { View } from 'react-native';
import type { ViewProps } from 'react-native';
import { hstackStyle } from './styles';
type IHStackProps = ViewProps & VariantProps<typeof hstackStyle>;
const HStack = React.forwardRef<React.ComponentRef<typeof View>, IHStackProps>(
function HStack({ className, space, reversed, ...props }, ref) {
return (
<View
className={hstackStyle({
space,
reversed: reversed as boolean,
class: className,
})}
{...props}
ref={ref}
/>
);
}
);
HStack.displayName = 'HStack';
export { HStack };

@ -1,26 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { hstackStyle } from './styles';
type IHStackProps = React.ComponentPropsWithoutRef<'div'> &
VariantProps<typeof hstackStyle>;
const HStack = React.forwardRef<React.ComponentRef<'div'>, IHStackProps>(
function HStack({ className, space, reversed, ...props }, ref) {
return (
<div
className={hstackStyle({
space,
reversed: reversed as boolean,
class: className,
})}
{...props}
ref={ref}
/>
);
}
);
HStack.displayName = 'HStack';
export { HStack };

@ -1,25 +0,0 @@
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
const baseStyle = isWeb
? 'flex relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
: '';
export const hstackStyle = tva({
base: `flex-row ${baseStyle}`,
variants: {
space: {
'xs': 'gap-1',
'sm': 'gap-2',
'md': 'gap-3',
'lg': 'gap-4',
'xl': 'gap-5',
'2xl': 'gap-6',
'3xl': 'gap-7',
'4xl': 'gap-8',
},
reversed: {
true: 'flex-row-reverse',
},
},
});

@ -1,48 +0,0 @@
import React from 'react';
import { createImage } from '@gluestack-ui/core/image/creator';
import { Platform, Image as RNImage } from 'react-native';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
const imageStyle = tva({
base: 'max-w-full',
variants: {
size: {
'2xs': 'h-6 w-6',
'xs': 'h-10 w-10',
'sm': 'h-16 w-16',
'md': 'h-20 w-20',
'lg': 'h-24 w-24',
'xl': 'h-32 w-32',
'2xl': 'h-64 w-64',
'full': 'h-full w-full',
'none': '',
},
},
});
const UIImage = createImage({ Root: RNImage });
type ImageProps = VariantProps<typeof imageStyle> &
React.ComponentProps<typeof UIImage>;
const Image = React.forwardRef<
React.ComponentRef<typeof UIImage>,
ImageProps & { className?: string }
>(function Image({ size = 'md', className, ...props }, ref) {
return (
<UIImage
className={imageStyle({ size, class: className })}
{...props}
ref={ref}
// @ts-expect-error : web only
style={
Platform.OS === 'web'
? { height: 'revert-layer', width: 'revert-layer' }
: undefined
}
/>
);
});
Image.displayName = 'Image';
export { Image };

@ -1,217 +0,0 @@
'use client';
import React from 'react';
import { createInput } from '@gluestack-ui/core/input/creator';
import { View, Pressable, TextInput } from 'react-native';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/utils/nativewind-utils';
import { cssInterop } from 'nativewind';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { PrimitiveIcon, UIIcon } from '@gluestack-ui/core/icon/creator';
const SCOPE = 'INPUT';
const UIInput = createInput({
Root: withStyleContext(View, SCOPE),
Icon: UIIcon,
Slot: Pressable,
Input: TextInput,
});
cssInterop(PrimitiveIcon, {
className: {
target: 'style',
nativeStyleToProp: {
height: true,
width: true,
fill: true,
color: 'classNameColor',
stroke: true,
},
},
});
const inputStyle = tva({
base: 'border-background-300 flex-row overflow-hidden content-center data-[hover=true]:border-outline-400 data-[focus=true]:border-primary-700 data-[focus=true]:hover:border-primary-700 data-[disabled=true]:opacity-40 data-[disabled=true]:hover:border-background-300 items-center',
variants: {
size: {
xl: 'h-12',
lg: 'h-11',
md: 'h-10',
sm: 'h-9',
},
variant: {
underlined:
'rounded-none border-b data-[invalid=true]:border-b-2 data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700',
outline:
'rounded border data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[focus=true]:hover:web:ring-1 data-[invalid=true]:data-[focus=true]:hover:web:ring-inset data-[invalid=true]:data-[focus=true]:hover:web:ring-indicator-error data-[invalid=true]:data-[disabled=true]:hover:web:ring-1 data-[invalid=true]:data-[disabled=true]:hover:web:ring-inset data-[invalid=true]:data-[disabled=true]:hover:web:ring-indicator-error',
rounded:
'rounded-full border data-[invalid=true]:border-error-700 data-[invalid=true]:hover:border-error-700 data-[invalid=true]:data-[focus=true]:border-error-700 data-[invalid=true]:data-[focus=true]:hover:border-error-700 data-[invalid=true]:data-[disabled=true]:hover:border-error-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[focus=true]:hover:web:ring-1 data-[invalid=true]:data-[focus=true]:hover:web:ring-inset data-[invalid=true]:data-[focus=true]:hover:web:ring-indicator-error data-[invalid=true]:data-[disabled=true]:hover:web:ring-1 data-[invalid=true]:data-[disabled=true]:hover:web:ring-inset data-[invalid=true]:data-[disabled=true]:hover:web:ring-indicator-error',
},
},
});
const inputIconStyle = tva({
base: 'justify-center items-center text-typography-400 fill-none',
parentVariants: {
size: {
'2xs': 'h-3 w-3',
'xs': 'h-3.5 w-3.5',
'sm': 'h-4 w-4',
'md': 'h-[18px] w-[18px]',
'lg': 'h-5 w-5',
'xl': 'h-6 w-6',
},
},
});
const inputSlotStyle = tva({
base: 'justify-center items-center web:disabled:cursor-not-allowed',
});
const inputFieldStyle = tva({
base: 'flex-1 text-typography-900 py-0 px-3 placeholder:text-typography-500 h-full ios:leading-[0px] web:cursor-text web:data-[disabled=true]:cursor-not-allowed',
parentVariants: {
variant: {
underlined: 'web:outline-0 web:outline-none px-0',
outline: 'web:outline-0 web:outline-none',
rounded: 'web:outline-0 web:outline-none px-4',
},
size: {
'2xs': 'text-2xs',
'xs': 'text-xs',
'sm': 'text-sm',
'md': 'text-base',
'lg': 'text-lg',
'xl': 'text-xl',
'2xl': 'text-2xl',
'3xl': 'text-3xl',
'4xl': 'text-4xl',
'5xl': 'text-5xl',
'6xl': 'text-6xl',
},
},
});
type IInputProps = React.ComponentProps<typeof UIInput> &
VariantProps<typeof inputStyle> & { className?: string };
const Input = React.forwardRef<React.ComponentRef<typeof UIInput>, IInputProps>(
function Input(
{ className, variant = 'outline', size = 'md', ...props },
ref
) {
return (
<UIInput
ref={ref}
{...props}
className={inputStyle({ variant, size, class: className })}
context={{ variant, size }}
/>
);
}
);
type IInputIconProps = React.ComponentProps<typeof UIInput.Icon> &
VariantProps<typeof inputIconStyle> & {
className?: string;
height?: number;
width?: number;
};
const InputIcon = React.forwardRef<
React.ComponentRef<typeof UIInput.Icon>,
IInputIconProps
>(function InputIcon({ className, size, ...props }, ref) {
const { size: parentSize } = useStyleContext(SCOPE);
if (typeof size === 'number') {
return (
<UIInput.Icon
ref={ref}
{...props}
className={inputIconStyle({ class: className })}
size={size}
/>
);
} else if (
(props.height !== undefined || props.width !== undefined) &&
size === undefined
) {
return (
<UIInput.Icon
ref={ref}
{...props}
className={inputIconStyle({ class: className })}
/>
);
}
return (
<UIInput.Icon
ref={ref}
{...props}
className={inputIconStyle({
parentVariants: {
size: parentSize,
},
class: className,
})}
/>
);
});
type IInputSlotProps = React.ComponentProps<typeof UIInput.Slot> &
VariantProps<typeof inputSlotStyle> & { className?: string };
const InputSlot = React.forwardRef<
React.ComponentRef<typeof UIInput.Slot>,
IInputSlotProps
>(function InputSlot({ className, ...props }, ref) {
return (
<UIInput.Slot
ref={ref}
{...props}
className={inputSlotStyle({
class: className,
})}
/>
);
});
type IInputFieldProps = React.ComponentProps<typeof UIInput.Input> &
VariantProps<typeof inputFieldStyle> & { className?: string };
const InputField = React.forwardRef<
React.ComponentRef<typeof UIInput.Input>,
IInputFieldProps
>(function InputField({ className, ...props }, ref) {
const { variant: parentVariant, size: parentSize } = useStyleContext(SCOPE);
return (
<UIInput.Input
ref={ref}
{...props}
className={inputFieldStyle({
parentVariants: {
variant: parentVariant,
size: parentSize,
},
class: className,
})}
/>
);
});
Input.displayName = 'Input';
InputIcon.displayName = 'InputIcon';
InputSlot.displayName = 'InputSlot';
InputField.displayName = 'InputField';
export { Input, InputField, InputIcon, InputSlot };

@ -1,40 +0,0 @@
'use client';
import { ActivityIndicator } from 'react-native';
import React from 'react';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import { cssInterop } from 'nativewind';
cssInterop(ActivityIndicator, {
className: { target: 'style', nativeStyleToProp: { color: true } },
});
const spinnerStyle = tva({});
const Spinner = React.forwardRef<
React.ComponentRef<typeof ActivityIndicator>,
React.ComponentProps<typeof ActivityIndicator>
>(function Spinner(
{
className,
color,
focusable = false,
'aria-label': ariaLabel = 'loading',
...props
},
ref
) {
return (
<ActivityIndicator
ref={ref}
focusable={focusable}
aria-label={ariaLabel}
{...props}
color={color}
className={spinnerStyle({ class: className })}
/>
);
});
Spinner.displayName = 'Spinner';
export { Spinner };

@ -1,48 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { Text as RNText } from 'react-native';
import { textStyle } from './styles';
type ITextProps = React.ComponentProps<typeof RNText> &
VariantProps<typeof textStyle>;
const Text = React.forwardRef<React.ComponentRef<typeof RNText>, ITextProps>(
function Text(
{
className,
isTruncated,
bold,
underline,
strikeThrough,
size = 'md',
sub,
italic,
highlight,
...props
},
ref
) {
return (
<RNText
className={textStyle({
isTruncated: isTruncated as boolean,
bold: bold as boolean,
underline: underline as boolean,
strikeThrough: strikeThrough as boolean,
size,
sub: sub as boolean,
italic: italic as boolean,
highlight: highlight as boolean,
class: className,
})}
{...props}
ref={ref}
/>
);
}
);
Text.displayName = 'Text';
export { Text };

@ -1,45 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { textStyle } from './styles';
type ITextProps = React.ComponentProps<'span'> & VariantProps<typeof textStyle>;
const Text = React.forwardRef<React.ComponentRef<'span'>, ITextProps>(
function Text(
{
className,
isTruncated,
bold,
underline,
strikeThrough,
size = 'md',
sub,
italic,
highlight,
...props
}: { className?: string } & ITextProps,
ref
) {
return (
<span
className={textStyle({
isTruncated: isTruncated as boolean,
bold: bold as boolean,
underline: underline as boolean,
strikeThrough: strikeThrough as boolean,
size,
sub: sub as boolean,
italic: italic as boolean,
highlight: highlight as boolean,
class: className,
})}
{...props}
ref={ref}
/>
);
}
);
Text.displayName = 'Text';
export { Text };

@ -1,47 +0,0 @@
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
const baseStyle = isWeb
? 'font-sans tracking-sm my-0 bg-transparent border-0 box-border display-inline list-none margin-0 padding-0 position-relative text-start no-underline whitespace-pre-wrap word-wrap-break-word'
: '';
export const textStyle = tva({
base: `text-typography-700 font-body ${baseStyle}`,
variants: {
isTruncated: {
true: 'web:truncate',
},
bold: {
true: 'font-bold',
},
underline: {
true: 'underline',
},
strikeThrough: {
true: 'line-through',
},
size: {
'2xs': 'text-2xs',
'xs': 'text-xs',
'sm': 'text-sm',
'md': 'text-base',
'lg': 'text-lg',
'xl': 'text-xl',
'2xl': 'text-2xl',
'3xl': 'text-3xl',
'4xl': 'text-4xl',
'5xl': 'text-5xl',
'6xl': 'text-6xl',
},
sub: {
true: 'text-xs',
},
italic: {
true: 'italic',
},
highlight: {
true: 'bg-yellow-500',
},
},
});

@ -1,94 +0,0 @@
'use client';
import React from 'react';
import { createTextarea } from '@gluestack-ui/core/textarea/creator';
import { View, TextInput } from 'react-native';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/utils/nativewind-utils';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
const SCOPE = 'TEXTAREA';
const UITextarea = createTextarea({
Root: withStyleContext(View, SCOPE),
Input: TextInput,
});
const textareaStyle = tva({
base: 'w-full h-[100px] border border-background-300 rounded data-[hover=true]:border-outline-400 data-[focus=true]:border-primary-700 data-[focus=true]:data-[hover=true]:border-primary-700 data-[disabled=true]:opacity-40 data-[disabled=true]:bg-background-50 data-[disabled=true]:data-[hover=true]:border-background-300',
variants: {
variant: {
default:
'data-[focus=true]:border-primary-700 data-[focus=true]:web:ring-1 data-[focus=true]:web:ring-inset data-[focus=true]:web:ring-indicator-primary data-[invalid=true]:border-error-700 data-[invalid=true]:web:ring-1 data-[invalid=true]:web:ring-inset data-[invalid=true]:web:ring-indicator-error data-[invalid=true]:data-[hover=true]:border-error-700 data-[invalid=true]:data-[focus=true]:data-[hover=true]:border-primary-700 data-[invalid=true]:data-[focus=true]:data-[hover=true]:web:ring-1 data-[invalid=true]:data-[focus=true]:data-[hover=true]:web:ring-inset data-[invalid=true]:data-[focus=true]:data-[hover=true]:web:ring-indicator-primary data-[invalid=true]:data-[disabled=true]:data-[hover=true]:border-error-700 data-[invalid=true]:data-[disabled=true]:data-[hover=true]:web:ring-1 data-[invalid=true]:data-[disabled=true]:data-[hover=true]:web:ring-inset data-[invalid=true]:data-[disabled=true]:data-[hover=true]:web:ring-indicator-error ',
},
size: {
sm: '',
md: '',
lg: '',
xl: '',
},
},
});
const textareaInputStyle = tva({
base: 'p-2 web:outline-0 web:outline-none flex-1 color-typography-900 placeholder:text-typography-500 web:cursor-text web:data-[disabled=true]:cursor-not-allowed',
parentVariants: {
size: {
sm: 'text-sm',
md: 'text-base',
lg: 'text-lg',
xl: 'text-xl',
},
},
});
type ITextareaProps = React.ComponentProps<typeof UITextarea> &
VariantProps<typeof textareaStyle>;
const Textarea = React.forwardRef<
React.ComponentRef<typeof UITextarea>,
ITextareaProps
>(function Textarea(
{ className, variant = 'default', size = 'md', ...props },
ref
) {
return (
<UITextarea
ref={ref}
{...props}
className={textareaStyle({ variant, class: className })}
context={{ size }}
/>
);
});
type ITextareaInputProps = React.ComponentProps<typeof UITextarea.Input> &
VariantProps<typeof textareaInputStyle>;
const TextareaInput = React.forwardRef<
React.ComponentRef<typeof UITextarea.Input>,
ITextareaInputProps
>(function TextareaInput({ className, ...props }, ref) {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UITextarea.Input
ref={ref}
{...props}
textAlignVertical="top"
className={textareaInputStyle({
parentVariants: {
size: parentSize,
},
class: className,
})}
/>
);
});
Textarea.displayName = 'Textarea';
TextareaInput.displayName = 'TextareaInput';
export { Textarea, TextareaInput };

@ -1,240 +0,0 @@
'use client';
import React from 'react';
import { createToastHook } from '@gluestack-ui/core/toast/creator';
import { AccessibilityInfo, Text, View, ViewStyle } from 'react-native';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import { cssInterop } from 'nativewind';
import {
Motion,
AnimatePresence,
MotionComponentProps,
} from '@legendapp/motion';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/utils/nativewind-utils';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
type IMotionViewProps = React.ComponentProps<typeof View> &
MotionComponentProps<typeof View, ViewStyle, unknown, unknown, unknown>;
const MotionView = Motion.View as React.ComponentType<IMotionViewProps>;
const useToast = createToastHook(MotionView, AnimatePresence);
const SCOPE = 'TOAST';
cssInterop(MotionView, { className: 'style' });
const toastStyle = tva({
base: 'p-4 m-1 rounded-md gap-1 web:pointer-events-auto shadow-hard-5 border-outline-100',
variants: {
action: {
error: 'bg-error-800',
warning: 'bg-warning-700',
success: 'bg-success-700',
info: 'bg-info-700',
muted: 'bg-background-800',
},
variant: {
solid: '',
outline: 'border bg-background-0',
},
},
});
const toastTitleStyle = tva({
base: 'text-typography-0 font-medium font-body tracking-md text-left',
variants: {
isTruncated: {
true: '',
},
bold: {
true: 'font-bold',
},
underline: {
true: 'underline',
},
strikeThrough: {
true: 'line-through',
},
size: {
'2xs': 'text-2xs',
'xs': 'text-xs',
'sm': 'text-sm',
'md': 'text-base',
'lg': 'text-lg',
'xl': 'text-xl',
'2xl': 'text-2xl',
'3xl': 'text-3xl',
'4xl': 'text-4xl',
'5xl': 'text-5xl',
'6xl': 'text-6xl',
},
},
parentVariants: {
variant: {
solid: '',
outline: '',
},
action: {
error: '',
warning: '',
success: '',
info: '',
muted: '',
},
},
parentCompoundVariants: [
{
variant: 'outline',
action: 'error',
class: 'text-error-800',
},
{
variant: 'outline',
action: 'warning',
class: 'text-warning-800',
},
{
variant: 'outline',
action: 'success',
class: 'text-success-800',
},
{
variant: 'outline',
action: 'info',
class: 'text-info-800',
},
{
variant: 'outline',
action: 'muted',
class: 'text-background-800',
},
],
});
const toastDescriptionStyle = tva({
base: 'font-normal font-body tracking-md text-left',
variants: {
isTruncated: {
true: '',
},
bold: {
true: 'font-bold',
},
underline: {
true: 'underline',
},
strikeThrough: {
true: 'line-through',
},
size: {
'2xs': 'text-2xs',
'xs': 'text-xs',
'sm': 'text-sm',
'md': 'text-base',
'lg': 'text-lg',
'xl': 'text-xl',
'2xl': 'text-2xl',
'3xl': 'text-3xl',
'4xl': 'text-4xl',
'5xl': 'text-5xl',
'6xl': 'text-6xl',
},
},
parentVariants: {
variant: {
solid: 'text-typography-50',
outline: 'text-typography-900',
},
},
});
const Root = withStyleContext(View, SCOPE);
type IToastProps = React.ComponentProps<typeof Root> & {
className?: string;
} & VariantProps<typeof toastStyle>;
const Toast = React.forwardRef<React.ComponentRef<typeof Root>, IToastProps>(
function Toast(
{ className, variant = 'solid', action = 'muted', ...props },
ref
) {
return (
<Root
ref={ref}
className={toastStyle({ variant, action, class: className })}
context={{ variant, action }}
{...props}
/>
);
}
);
type IToastTitleProps = React.ComponentProps<typeof Text> & {
className?: string;
} & VariantProps<typeof toastTitleStyle>;
const ToastTitle = React.forwardRef<
React.ComponentRef<typeof Text>,
IToastTitleProps
>(function ToastTitle({ className, size = 'md', children, ...props }, ref) {
const { variant: parentVariant, action: parentAction } =
useStyleContext(SCOPE);
React.useEffect(() => {
// Issue from react-native side
// Hack for now, will fix this later
AccessibilityInfo.announceForAccessibility(children as string);
}, [children]);
return (
<Text
{...props}
ref={ref}
aria-live="assertive"
aria-atomic="true"
role="alert"
className={toastTitleStyle({
size,
class: className,
parentVariants: {
variant: parentVariant,
action: parentAction,
},
})}
>
{children}
</Text>
);
});
type IToastDescriptionProps = React.ComponentProps<typeof Text> & {
className?: string;
} & VariantProps<typeof toastDescriptionStyle>;
const ToastDescription = React.forwardRef<
React.ComponentRef<typeof Text>,
IToastDescriptionProps
>(function ToastDescription({ className, size = 'md', ...props }, ref) {
const { variant: parentVariant } = useStyleContext(SCOPE);
return (
<Text
ref={ref}
{...props}
className={toastDescriptionStyle({
size,
class: className,
parentVariants: {
variant: parentVariant,
},
})}
/>
);
});
Toast.displayName = 'Toast';
ToastTitle.displayName = 'ToastTitle';
ToastDescription.displayName = 'ToastDescription';
export { useToast, Toast, ToastTitle, ToastDescription };

@ -1,28 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { View } from 'react-native';
import { vstackStyle } from './styles';
type IVStackProps = React.ComponentProps<typeof View> &
VariantProps<typeof vstackStyle>;
const VStack = React.forwardRef<React.ComponentRef<typeof View>, IVStackProps>(
function VStack({ className, space, reversed, ...props }, ref) {
return (
<View
className={vstackStyle({
space,
reversed: reversed as boolean,
class: className,
})}
{...props}
ref={ref}
/>
);
}
);
VStack.displayName = 'VStack';
export { VStack };

@ -1,27 +0,0 @@
import React from 'react';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
import { vstackStyle } from './styles';
type IVStackProps = React.ComponentProps<'div'> &
VariantProps<typeof vstackStyle>;
const VStack = React.forwardRef<React.ComponentRef<'div'>, IVStackProps>(
function VStack({ className, space, reversed, ...props }, ref) {
return (
<div
className={vstackStyle({
space,
reversed: reversed as boolean,
class: className,
})}
{...props}
ref={ref}
/>
);
}
);
VStack.displayName = 'VStack';
export { VStack };

@ -1,25 +0,0 @@
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
const baseStyle = isWeb
? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
: '';
export const vstackStyle = tva({
base: `flex-col ${baseStyle}`,
variants: {
space: {
'xs': 'gap-1',
'sm': 'gap-2',
'md': 'gap-3',
'lg': 'gap-4',
'xl': 'gap-5',
'2xl': 'gap-6',
'3xl': 'gap-7',
'4xl': 'gap-8',
},
reversed: {
true: 'flex-col-reverse',
},
},
});

@ -1,28 +0,0 @@
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>
);
}

@ -1,45 +0,0 @@
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;
}

@ -1,206 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: process.env.DARK_MODE ? process.env.DARK_MODE : 'class',
content: [
'./app/**/*.{html,js,jsx,ts,tsx,mdx}',
'./components/**/*.{html,js,jsx,ts,tsx,mdx}',
'./utils/**/*.{html,js,jsx,ts,tsx,mdx}',
'./*.{html,js,jsx,ts,tsx,mdx}',
'./src/**/*.{html,js,jsx,ts,tsx,mdx}',
],
presets: [require('nativewind/preset')],
important: 'html',
safelist: [
{
pattern:
/(bg|border|text|stroke|fill)-(primary|secondary|tertiary|error|success|warning|info|typography|outline|background|indicator)-(0|50|100|200|300|400|500|600|700|800|900|950|white|gray|black|error|warning|muted|success|info|light|dark|primary)/,
},
],
theme: {
extend: {
colors: {
primary: {
0: 'rgb(var(--color-primary-0)/<alpha-value>)',
50: 'rgb(var(--color-primary-50)/<alpha-value>)',
100: 'rgb(var(--color-primary-100)/<alpha-value>)',
200: 'rgb(var(--color-primary-200)/<alpha-value>)',
300: 'rgb(var(--color-primary-300)/<alpha-value>)',
400: 'rgb(var(--color-primary-400)/<alpha-value>)',
500: 'rgb(var(--color-primary-500)/<alpha-value>)',
600: 'rgb(var(--color-primary-600)/<alpha-value>)',
700: 'rgb(var(--color-primary-700)/<alpha-value>)',
800: 'rgb(var(--color-primary-800)/<alpha-value>)',
900: 'rgb(var(--color-primary-900)/<alpha-value>)',
950: 'rgb(var(--color-primary-950)/<alpha-value>)',
},
secondary: {
0: 'rgb(var(--color-secondary-0)/<alpha-value>)',
50: 'rgb(var(--color-secondary-50)/<alpha-value>)',
100: 'rgb(var(--color-secondary-100)/<alpha-value>)',
200: 'rgb(var(--color-secondary-200)/<alpha-value>)',
300: 'rgb(var(--color-secondary-300)/<alpha-value>)',
400: 'rgb(var(--color-secondary-400)/<alpha-value>)',
500: 'rgb(var(--color-secondary-500)/<alpha-value>)',
600: 'rgb(var(--color-secondary-600)/<alpha-value>)',
700: 'rgb(var(--color-secondary-700)/<alpha-value>)',
800: 'rgb(var(--color-secondary-800)/<alpha-value>)',
900: 'rgb(var(--color-secondary-900)/<alpha-value>)',
950: 'rgb(var(--color-secondary-950)/<alpha-value>)',
},
tertiary: {
50: 'rgb(var(--color-tertiary-50)/<alpha-value>)',
100: 'rgb(var(--color-tertiary-100)/<alpha-value>)',
200: 'rgb(var(--color-tertiary-200)/<alpha-value>)',
300: 'rgb(var(--color-tertiary-300)/<alpha-value>)',
400: 'rgb(var(--color-tertiary-400)/<alpha-value>)',
500: 'rgb(var(--color-tertiary-500)/<alpha-value>)',
600: 'rgb(var(--color-tertiary-600)/<alpha-value>)',
700: 'rgb(var(--color-tertiary-700)/<alpha-value>)',
800: 'rgb(var(--color-tertiary-800)/<alpha-value>)',
900: 'rgb(var(--color-tertiary-900)/<alpha-value>)',
950: 'rgb(var(--color-tertiary-950)/<alpha-value>)',
},
error: {
0: 'rgb(var(--color-error-0)/<alpha-value>)',
50: 'rgb(var(--color-error-50)/<alpha-value>)',
100: 'rgb(var(--color-error-100)/<alpha-value>)',
200: 'rgb(var(--color-error-200)/<alpha-value>)',
300: 'rgb(var(--color-error-300)/<alpha-value>)',
400: 'rgb(var(--color-error-400)/<alpha-value>)',
500: 'rgb(var(--color-error-500)/<alpha-value>)',
600: 'rgb(var(--color-error-600)/<alpha-value>)',
700: 'rgb(var(--color-error-700)/<alpha-value>)',
800: 'rgb(var(--color-error-800)/<alpha-value>)',
900: 'rgb(var(--color-error-900)/<alpha-value>)',
950: 'rgb(var(--color-error-950)/<alpha-value>)',
},
success: {
0: 'rgb(var(--color-success-0)/<alpha-value>)',
50: 'rgb(var(--color-success-50)/<alpha-value>)',
100: 'rgb(var(--color-success-100)/<alpha-value>)',
200: 'rgb(var(--color-success-200)/<alpha-value>)',
300: 'rgb(var(--color-success-300)/<alpha-value>)',
400: 'rgb(var(--color-success-400)/<alpha-value>)',
500: 'rgb(var(--color-success-500)/<alpha-value>)',
600: 'rgb(var(--color-success-600)/<alpha-value>)',
700: 'rgb(var(--color-success-700)/<alpha-value>)',
800: 'rgb(var(--color-success-800)/<alpha-value>)',
900: 'rgb(var(--color-success-900)/<alpha-value>)',
950: 'rgb(var(--color-success-950)/<alpha-value>)',
},
warning: {
0: 'rgb(var(--color-warning-0)/<alpha-value>)',
50: 'rgb(var(--color-warning-50)/<alpha-value>)',
100: 'rgb(var(--color-warning-100)/<alpha-value>)',
200: 'rgb(var(--color-warning-200)/<alpha-value>)',
300: 'rgb(var(--color-warning-300)/<alpha-value>)',
400: 'rgb(var(--color-warning-400)/<alpha-value>)',
500: 'rgb(var(--color-warning-500)/<alpha-value>)',
600: 'rgb(var(--color-warning-600)/<alpha-value>)',
700: 'rgb(var(--color-warning-700)/<alpha-value>)',
800: 'rgb(var(--color-warning-800)/<alpha-value>)',
900: 'rgb(var(--color-warning-900)/<alpha-value>)',
950: 'rgb(var(--color-warning-950)/<alpha-value>)',
},
info: {
0: 'rgb(var(--color-info-0)/<alpha-value>)',
50: 'rgb(var(--color-info-50)/<alpha-value>)',
100: 'rgb(var(--color-info-100)/<alpha-value>)',
200: 'rgb(var(--color-info-200)/<alpha-value>)',
300: 'rgb(var(--color-info-300)/<alpha-value>)',
400: 'rgb(var(--color-info-400)/<alpha-value>)',
500: 'rgb(var(--color-info-500)/<alpha-value>)',
600: 'rgb(var(--color-info-600)/<alpha-value>)',
700: 'rgb(var(--color-info-700)/<alpha-value>)',
800: 'rgb(var(--color-info-800)/<alpha-value>)',
900: 'rgb(var(--color-info-900)/<alpha-value>)',
950: 'rgb(var(--color-info-950)/<alpha-value>)',
},
typography: {
0: 'rgb(var(--color-typography-0)/<alpha-value>)',
50: 'rgb(var(--color-typography-50)/<alpha-value>)',
100: 'rgb(var(--color-typography-100)/<alpha-value>)',
200: 'rgb(var(--color-typography-200)/<alpha-value>)',
300: 'rgb(var(--color-typography-300)/<alpha-value>)',
400: 'rgb(var(--color-typography-400)/<alpha-value>)',
500: 'rgb(var(--color-typography-500)/<alpha-value>)',
600: 'rgb(var(--color-typography-600)/<alpha-value>)',
700: 'rgb(var(--color-typography-700)/<alpha-value>)',
800: 'rgb(var(--color-typography-800)/<alpha-value>)',
900: 'rgb(var(--color-typography-900)/<alpha-value>)',
950: 'rgb(var(--color-typography-950)/<alpha-value>)',
white: '#FFFFFF',
gray: '#D4D4D4',
black: '#181718',
},
outline: {
0: 'rgb(var(--color-outline-0)/<alpha-value>)',
50: 'rgb(var(--color-outline-50)/<alpha-value>)',
100: 'rgb(var(--color-outline-100)/<alpha-value>)',
200: 'rgb(var(--color-outline-200)/<alpha-value>)',
300: 'rgb(var(--color-outline-300)/<alpha-value>)',
400: 'rgb(var(--color-outline-400)/<alpha-value>)',
500: 'rgb(var(--color-outline-500)/<alpha-value>)',
600: 'rgb(var(--color-outline-600)/<alpha-value>)',
700: 'rgb(var(--color-outline-700)/<alpha-value>)',
800: 'rgb(var(--color-outline-800)/<alpha-value>)',
900: 'rgb(var(--color-outline-900)/<alpha-value>)',
950: 'rgb(var(--color-outline-950)/<alpha-value>)',
},
background: {
0: 'rgb(var(--color-background-0)/<alpha-value>)',
50: 'rgb(var(--color-background-50)/<alpha-value>)',
100: 'rgb(var(--color-background-100)/<alpha-value>)',
200: 'rgb(var(--color-background-200)/<alpha-value>)',
300: 'rgb(var(--color-background-300)/<alpha-value>)',
400: 'rgb(var(--color-background-400)/<alpha-value>)',
500: 'rgb(var(--color-background-500)/<alpha-value>)',
600: 'rgb(var(--color-background-600)/<alpha-value>)',
700: 'rgb(var(--color-background-700)/<alpha-value>)',
800: 'rgb(var(--color-background-800)/<alpha-value>)',
900: 'rgb(var(--color-background-900)/<alpha-value>)',
950: 'rgb(var(--color-background-950)/<alpha-value>)',
error: 'rgb(var(--color-background-error)/<alpha-value>)',
warning: 'rgb(var(--color-background-warning)/<alpha-value>)',
muted: 'rgb(var(--color-background-muted)/<alpha-value>)',
success: 'rgb(var(--color-background-success)/<alpha-value>)',
info: 'rgb(var(--color-background-info)/<alpha-value>)',
light: '#FBFBFB',
dark: '#181719',
},
indicator: {
primary: 'rgb(var(--color-indicator-primary)/<alpha-value>)',
info: 'rgb(var(--color-indicator-info)/<alpha-value>)',
error: 'rgb(var(--color-indicator-error)/<alpha-value>)',
},
},
fontFamily: {
heading: undefined,
body: undefined,
mono: undefined,
jakarta: ['var(--font-plus-jakarta-sans)'],
roboto: ['var(--font-roboto)'],
code: ['var(--font-source-code-pro)'],
inter: ['var(--font-inter)'],
'space-mono': ['var(--font-space-mono)'],
},
fontWeight: {
extrablack: '950',
},
fontSize: {
'2xs': '10px',
},
boxShadow: {
'hard-1': '-2px 2px 8px 0px rgba(38, 38, 38, 0.20)',
'hard-2': '0px 3px 10px 0px rgba(38, 38, 38, 0.20)',
'hard-3': '2px 2px 8px 0px rgba(38, 38, 38, 0.20)',
'hard-4': '0px -3px 10px 0px rgba(38, 38, 38, 0.20)',
'hard-5': '0px 2px 10px 0px rgba(38, 38, 38, 0.10)',
'soft-1': '0px 0px 10px rgba(38, 38, 38, 0.1)',
'soft-2': '0px 0px 20px rgba(38, 38, 38, 0.2)',
'soft-3': '0px 0px 30px rgba(38, 38, 38, 0.1)',
'soft-4': '0px 0px 40px rgba(38, 38, 38, 0.1)',
},
},
},
};

@ -0,0 +1,31 @@
import { StatusBar } from 'expo-status-bar';
import { FlatList, Keyboard, Modal, Pressable, ScrollView, StyleSheet, View } from 'react-native';
import { SafeAreaProvider, SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider';
import IndexPage from './screen/IndexPage';
import { CounterProvider } from './states/CounterProvider';
import '@/global.css';
export default function App() {
return (
<GluestackUIProvider mode="light">
<SafeAreaProvider>
<SafeAreaView style={{ flex: 1 }}>
<CounterProvider>
<IndexPage />
</CounterProvider>
<StatusBar style="auto" />
</SafeAreaView>
</SafeAreaProvider>
</GluestackUIProvider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

@ -1,29 +1,38 @@
{ {
"expo": { "expo": {
"name": "expo-project", "name": "expo-project",
"slug": "expo-project", "slug": "expo-project",
"version": "1.0.0", "version": "1.0.0",
"orientation": "portrait", "orientation": "portrait",
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"userInterfaceStyle": "light", "userInterfaceStyle": "light",
"newArchEnabled": true, "newArchEnabled": true,
"splash": { "splash": {
"image": "./assets/splash-icon.png", "image": "./assets/splash-icon.png",
"resizeMode": "contain", "resizeMode": "contain",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"
}, },
"ios": { "ios": {
"supportsTablet": true "supportsTablet": true
}, },
"android": { "android": {
"adaptiveIcon": { "adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png", "foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"
}, },
"edgeToEdgeEnabled": true "edgeToEdgeEnabled": true,
}, "package": "com.peadorr.everyjapdict"
"web": { },
"favicon": "./assets/favicon.png" "web": {
} "favicon": "./assets/favicon.png"
} },
} "plugins": [
[
"react-native-google-mobile-ads",
{
"androidAppId": "ca-app-pub-7854988771210967~3806885931"
}
]
]
}
}

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,39 @@
'use client';
import React from 'react';
import { createPressable } from '@gluestack-ui/core/pressable/creator';
import { Pressable as RNPressable } from 'react-native';
import { tva } from '@gluestack-ui/utils/nativewind-utils';
import { withStyleContext } from '@gluestack-ui/utils/nativewind-utils';
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
const UIPressable = createPressable({
Root: withStyleContext(RNPressable),
});
const pressableStyle = tva({
base: 'data-[focus-visible=true]:outline-none data-[focus-visible=true]:ring-indicator-info data-[focus-visible=true]:ring-2 data-[disabled=true]:opacity-40',
});
type IPressableProps = Omit<
React.ComponentProps<typeof UIPressable>,
'context'
> &
VariantProps<typeof pressableStyle>;
const Pressable = React.forwardRef<
React.ComponentRef<typeof UIPressable>,
IPressableProps
>(function Pressable({ className, ...props }, ref) {
return (
<UIPressable
{...props}
ref={ref}
className={pressableStyle({
class: className,
})}
/>
);
});
Pressable.displayName = 'Pressable';
export { Pressable };

File diff suppressed because it is too large Load Diff

@ -1,30 +1,36 @@
{ {
"name": "expo.project", "name": "expo-project",
"version": "1.0.0", "version": "1.0.0",
"main": "index.ts", "main": "index.ts",
"scripts": { "scripts": {
"start": "expo start", "start": "expo start --offline",
"android": "expo start --android", "android": "expo start --android --offline",
"ios": "expo start --ios", "ios": "expo start --ios --offline",
"web": "expo start --web" "web": "expo start --web --offline"
}, },
"dependencies": { "dependencies": {
"@expo/html-elements": "^0.10.1", "@expo/html-elements": "^0.10.1",
"@gluestack-ui/core": "^3.0.0", "@gluestack-ui/core": "^3.0.0",
"@gluestack-ui/utils": "^3.0.0", "@gluestack-ui/utils": "^3.0.0",
"@legendapp/motion": "^2.4.0", "@legendapp/motion": "^2.4.0",
"@react-native-async-storage/async-storage": "2.2.0",
"babel-plugin-module-resolver": "^5.0.2", "babel-plugin-module-resolver": "^5.0.2",
"expo": "^54.0.7", "expo": "^54.0.7",
"expo-status-bar": "~3.0.8", "expo-status-bar": "~3.0.8",
"install": "^0.13.0",
"lucide-react-native": "^0.543.0", "lucide-react-native": "^0.543.0",
"nativewind": "^4.1.23", "nativewind": "^4.1.23",
"npm": "^11.6.0",
"react": "19.1.0", "react": "19.1.0",
"react-aria": "^3.33.0", "react-aria": "^3.33.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-native": "0.81.4", "react-native": "0.81.4",
"react-native-reanimated": "^4.1.0", "react-native-animatable": "^1.4.0",
"react-native-google-mobile-ads": "^15.7.0",
"react-native-reanimated": "~4.1.0",
"react-native-safe-area-context": "^5.6.1", "react-native-safe-area-context": "^5.6.1",
"react-native-svg": "15.12.1", "react-native-svg": "15.12.1",
"react-native-webview": "13.15.0",
"react-native-worklets": "0.5.1", "react-native-worklets": "0.5.1",
"react-stately": "^3.39.0", "react-stately": "^3.39.0",
"tailwind-variants": "^0.1.20", "tailwind-variants": "^0.1.20",
@ -32,6 +38,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.25.2", "@babel/core": "^7.25.2",
"@expo/config-plugins": "~54.0.1",
"@types/react": "~19.1.10", "@types/react": "~19.1.10",
"typescript": "~5.9.2" "typescript": "~5.9.2"
}, },

@ -4,7 +4,7 @@ import { Center } from '@/components/ui/center';
import { HStack } from '@/components/ui/hstack'; import { HStack } from '@/components/ui/hstack';
import { Text } from '@/components/ui/text'; import { Text } from '@/components/ui/text';
import { VStack } from '@/components/ui/vstack'; import { VStack } from '@/components/ui/vstack';
import { useCounterDispatch, useCounterState } from '@/states/ConterProvider'; import { useCounterDispatch, useCounterState } from '@/states/CounterProvider';
import { View } from 'react-native'; import { View } from 'react-native';
export default function IndexPage() { export default function IndexPage() {

@ -0,0 +1,23 @@
node_modules/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
ios
android
# macOS
.DS_Store
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*

@ -0,0 +1,13 @@
import { ScreenContent } from 'components/ScreenContent';
import { StatusBar } from 'expo-status-bar';
import './global.css';
export default function App() {
return (
<>
<ScreenContent title="Home" path="App.tsx"></ScreenContent>
<StatusBar style="auto" />
</>
);
}

@ -0,0 +1,2 @@
// @ts-ignore
/// <reference types="nativewind/types" />

@ -0,0 +1,38 @@
{
"expo": {
"name": "my-expo-app",
"slug": "my-expo-app",
"version": "1.0.0",
"web": {
"favicon": "./assets/favicon.png"
},
"experiments": {
"tsconfigPaths": true
},
"plugins": [],
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": ["**/*"],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
}
}
}

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

@ -0,0 +1,10 @@
module.exports = function (api) {
api.cache(true);
let plugins = [];
return {
presets: [['babel-preset-expo', { jsxImportSource: 'nativewind' }], 'nativewind/babel'],
plugins,
};
};

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save