You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

6.9 KiB

React Native AI Context - shadcn/ui x NativeWind

React Native 应用的 AI 上下文指南,结合 shadcn/ui 设计理念和 NativeWind 工具类。

概述

这是 React Native 应用的 AI 开发上下文,使用 NativeWind (Tailwind CSS for React Native) 作为样式解决方案,遵循 shadcn/ui 的设计理念。

核心技术栈

基础框架

shadcn/ui 设计原则

  1. Open Code - 代码完全可定制
  2. Composition - 组件可组合
  3. Distribution - 易于分发和安装
  4. Beautiful Defaults - 美观的默认样式
  5. AI-Ready - 支持AI开发

安装

# 初始化 Expo 项目
npx create-expo-app myapp --template expo-template-blank-typescript
cd myapp

# 安装 NativeWind
npm install --save-dev tailwindcss
npm install nativewind
npm install -D @types/react-native

# 配置 NativeWind
npx tailwindcss init

配置

tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./App.{js,jsx,ts,tsx}",
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  presets: [require("nativewind/preset")],
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
    },
  },
  plugins: [],
}

nativewind-env.d.ts

/// <reference types="nativewind/types" />

babel.config.js

module.exports = function (api) {
  api.cache(true);
  return {
    presets: [['babel-preset-expo', { jsxImportSource: 'nativewind' }]],
    plugins: [
      'react-native-reanimated/plugin',
      'nativewind/babel',
    ],
  };
}

核心组件

Button 组件

import { Text, Pressable, PressableProps, ViewProps, TextProps } from 'react-native';
import { cn } from '@/lib/utils';

interface ButtonProps extends PressableProps {
  variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost';
  size?: 'default' | 'sm' | 'lg';
  className?: string;
  children: React.ReactNode;
}

const Button = React.forwardRef<Pressable, ButtonProps>(
  ({ className, variant = 'default', size = 'default', children, ...props }, ref) => {
    const variants = {
      default: 'bg-primary text-primary-foreground hover:bg-primary/90',
      destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
      outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
      secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
      ghost: 'hover:bg-accent hover:text-accent-foreground',
    };

    const sizes = {
      default: 'h-10 px-4 py-2',
      sm: 'h-9 rounded-md px-3',
      lg: 'h-11 rounded-md px-8',
    };

    return (
      <Pressable
        ref={ref}
        className={cn(
          'rounded-md text-sm font-medium flex items-center justify-center',
          variants[variant],
          sizes[size],
          className
        )}
        {...props}
      >
        <Text className="font-medium">{children}</Text>
      </Pressable>
    );
  }
);

Card 组件

import { View, ViewProps, Text, TextProps } from 'react-native';
import { cn } from '@/lib/utils';

interface CardProps extends ViewProps {
  className?: string;
}

const Card = React.forwardRef<View, CardProps>(({ className, ...props }, ref) => (
  <View ref={ref} className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)} {...props} />
));

const CardHeader = React.forwardRef<View, ViewProps>(({ className, ...props }, ref) => (
  <View ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
));

const CardTitle = React.forwardRef<Text, TextProps>(({ className, ...props }, ref) => (
  <Text ref={ref} className={cn("text-2xl font-semibold leading-none tracking-tight", className)} {...props} />
));

const CardContent = React.forwardRef<View, ViewProps>(({ className, ...props }, ref) => (
  <View ref={ref} className={cn("p-6 pt-0", className)} {...props} />
));

设计令牌

颜色系统

// 使用 CSS 变量定义颜色
// 在 tailwind.config.js 中配置

字体系统

// NativeWind 中的字体设置
// 使用 Tailwind 的字体工具类
text-sm // 小号文本
text-base // 基础文本
text-lg // 大号文本
font-medium // 中等字重
font-bold // 粗体

开发规范

组件结构

src/
├── components/
│   ├── ui/              # 基础 UI 组件
│   │   ├── button.tsx
│   │   ├── card.tsx
│   │   └── ...
│   └── features/        # 功能组件
├── lib/
│   └── utils.ts         # 工具函数
├── hooks/              # 自定义 hooks
└── screens/            # 屏幕组件

命名约定

  • 组件使用 PascalCase: Button.tsx
  • 文件使用 kebab-case: user-profile.tsx
  • 样式类使用 camelCase 或 Tailwind 工具类

与 React Web shadcn/ui 对应

React Web React Native
<Button> <Pressable> with styling
<Card> <View> with border and shadow
<Input> <TextInput> with styling
<Dialog> <Modal> or <Modal> from react-native-modal
<Toast> Toast from react-native-toast-message
<Avatar> <Image> with circular styling

相关资源

MCP 集成

使用 AI 工具:

npx shadcn@latest mcp

最佳实践

  1. 使用 NativeWind 进行样式管理
  2. 遵循 shadcn/ui 的组件设计原则
  3. 组件应该是可组合和可定制的
  4. 使用 TypeScript 保证类型安全
  5. 使用 Expo Router 进行导航