Files
workspace/code/docusaurus/docs/coding/react-native/第三方库/03-gluestack-ui.md
T
2026-03-18 17:14:34 +08:00

13 KiB

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,
  }
})