跳到主要内容

gluestack-ui

Gluestack UI UI 组件库

官网:https://gluestack.io/ui/docs/home/getting-started/installation

方式一:CLI

npx gluestack-ui init

方式二:Manual(推荐)

前置条件: 需要安装 nativewind

  1. 安装依赖:

    npx expo add @gluestack-ui/core @gluestack-ui/utils react-native-svg @gluestack/ui-next-adapter
  2. github 复制必须的组件到 @/components/ui/gluestack-ui-provider

  3. 修改 tailwind.config.js 文件:

    /** @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:
    // eslint-disable-next-line regexp/no-dupe-disjunctions
    /(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)',
    },
    },
    },
    }
  4. 使用 GluestackUIProvider 包括着整个组件:

    // App.tsx
    import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider'
    import '@/global.css' // Make sure this path is correct

    export default function App() {
    return (
    <GluestackUIProvider>{/* Add your app code here */}</GluestackUIProvider>
    )
    }

测试

下载对应组件:

npx gluestack-ui add button

引入使用:

import { StyleSheet, Text, View } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import { Button, ButtonText } from '@/components/ui/button'
import { GluestackUIProvider } from '@/components/ui/gluestack-ui-provider'
import '@/styles/global.css'

export default function Layout() {
return (
<GluestackUIProvider>
<SafeAreaView style={styles.container}>
<View className="flex-1 items-center justify-center bg-white">
<Text className="text-xl font-bold text-blue-500">
Welcome to Nativewind!
</Text>
<Button>
<ButtonText>你好</ButtonText>
</Button>
</View>
</SafeAreaView>
</GluestackUIProvider>

)
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
paddingHorizontal: 16,
}
})