Skip to main content

uniwind

Uniwind — Tailwind CSS v4 styling for React Native. Use when adding, building, or styling components in a React Native project that uses Tailwind with className.

Informations de source

Dépôt
CherryHQ/cherry-studio-app
Dernière activité de la source
15 septembre 2026 à 11:43
Langue détectée de SKILL.md
anglais
Étoiles
4 002
Forks
312

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
uniwind
description
Uniwind — Tailwind CSS v4 styling for React Native. Use when adding, building, or styling components in a React Native project that uses Tailwind with className.
# Uniwind — Complete Reference > Uniwind 1.6.0+ / Tailwind CSS v4 / React Native 0.81+ / Expo SDK 54+ If user has lower version, recommend updating to 1.6.0+ for best experience. Uniwind brings Tailwind CSS v4 to React Native. All core React Native components support the `className` prop out of the box. Styles are compiled at build time — no runtime overhead. ## Critical Rules 1. **Tailwind v4 only** — Use `@import 'tailwindcss'` not `@tailwind base`. Tailwind v3 is not supported. 2. **Never construct classNames dynamically** — Tailwind scans at build time. `bg-${color}-500` will NOT work. Use complete string literals, mapping objects, or ternaries. 3. **Never use `cssInterop` or `remapProps`** — Those are NativeWind APIs. Uniwind does not override global components. 4. **No `tailwind.config.js`** — All config goes in `global.css` via `@theme` and `@layer theme`. 5. **No ThemeProvider required** — Use `Uniwind.setTheme()` directly. 6. **`withUniwindConfig` must be the outermost** Metro config wrapper. 7. **NEVER wrap `react-native` or `react-native-reanimated` components with `withUniwind`** — `View`, `Text`, `Pressable`, `Image`, `TextInput`, `ScrollView`, `FlatList`, `Switch`, `Modal`, `Animated.View`, `Animated.Text`, etc. already have full `className` support built in. Wrapping them with `withUniwind` will break behavior. Only use `withUniwind` for **third-party** components (e.g., `expo-image`, `expo-blur`, `moti`). 8. **Font families: single font only** — React Native doesn't support fallbacks. Use `--font-sans: 'Roboto-Regular'` not `'Roboto', sans-serif`. 9. **All theme variants must define the same set of CSS variables** — If `light` defines `--color-primary`, then `dark` and every custom theme must too. Mismatched variables cause runtime errors. 10. **`accent-` prefix is REQUIRED for non-style color props** — This is crucial. Props like `color` (Button, ActivityIndicator), `tintColor` (Image), `thumbColor` (Switch), `placeholderTextColor` (TextInput) are NOT part of the `style` object. You MUST use the corresponding `{propName}ClassName` prop with `accent-` prefixed classes. Example: `<ActivityIndicator colorClassName="accent-blue-500" />` NOT `<ActivityIndicator className="text-blue-500" />`. Regular Tailwind color classes (like `text-blue-500`) only work on `className` (which maps to `style`). For non-style color props, always use `accent-`. 11. **rem default is 16px** — NativeWind used 14px. Set `polyfills: { rem: 14 }` in metro config if migrating. 12. **`cssEntryFile` must be a relative path string** — Use `'./global.css'` not `path.resolve(__dirname, 'global.css')`. 13. **Deduplicate with `cn()` when mixing custom CSS classes and Tailwind** — Uniwind does NOT auto-deduplicate. If a custom CSS class (`.card { padding: 16px }`) and a Tailwind utility (`p-6`) set the same property, both apply with unpredictable results. Always wrap with `cn('card', 'p-6')` when there's overlap. 14. **Important utilities are supported** — Tailwind important modifier works in classNames with `!` at the end: `bg-red-500!`, `active:bg-red-500!`, `ios:pt-12!`. Leading `!bg-red-500` syntax is deprecated. Important utilities override non-important utilities for the same style property, but inline `style` still overrides className. ## Setup ### Installation ```bash # or other package manager bun install uniwind tailwindcss ``` Requires **Tailwind CSS v4+**. ### global.css Create a CSS entry file: ```css @import 'tailwindcss'; @import 'uniwind'; ``` Import in your **App component** (e.g., `App.tsx` or `app/_layout.tsx`), **NOT** in `index.ts`/`index.js` — importing there breaks hot reload: ```tsx // app/_layout.tsx or App.tsx import './global.css'; ``` The directory containing `global.css` is the app root — Tailwind scans for classNames starting from this directory. ### Metro Configuration ```js const { getDefaultConfig } = require('expo/metro-config'); // Bare RN: const { getDefaultConfig } = require('@react-native/metro-config'); const { withUniwindConfig } = require('uniwind/metro'); const config = getDefaultConfig(__dirname); // withUniwindConfig MUST be the OUTERMOST wrapper module.exports = withUniwindConfig(config, { cssEntryFile: './global.css', // Required — relative path from project root polyfills: { rem: 16 }, // Optional — base rem value (default 16) extraThemes: ['ocean', 'sunset'], // Optional — custom themes beyond light/dark dtsFile: './uniwind-types.d.ts', // Optional — TypeScript types output path debug: true, // Optional — log unsupported CSS in dev isTV: false, // Optional — enable TV platform support }); ``` For most flows, keep defaults, only provide `cssEntryFile`. Wrapper order — Uniwind must wrap everything else: ```js // CORRECT module.exports = withUniwindConfig(withOtherConfig(config, opts), { cssEntryFile: './global.css' }); // WRONG — Uniwind is NOT outermost module.exports = withOtherConfig(withUniwindConfig(config, { cssEntryFile: './global.css' }), opts); ``` ### Vite Configuration (v1.2.0+) If user has storybook setup, add extra vite config: ```ts import tailwindcss from '@tailwindcss/vite'; import { uniwind } from 'uniwind/vite'; import { defineConfig } from 'vite'; export default defineConfig({ plugins: [ tailwindcss(), uniwind({ cssEntryFile: './src/global.css', dtsFile: './src/uniwind-types.d.ts', }), ], }); ``` ### TypeScript Uniwind auto-generates a `.d.ts` file (default: `./uniwind-types.d.ts`) after running Metro. Place it in `src/` or `app/` for auto-inclusion, or add to `tsconfig.json`: ```json { "include": ["./uniwind-types.d.ts"] } ``` If user has some typescript errors related to classNames, just run metro server to build the d.ts file. ### Expo Router Placement ```text project/ ├── app/_layout.tsx ← import '../global.css' here ├── components/ ├── global.css ← project root (best location) └── metro.config.js ← cssEntryFile: './global.css' ``` If `global.css` is in `app/` dir, add `@source` for sibling directories: ```css @import 'tailwindcss'; @import 'uniwind'; @source '../components'; ``` ### Tailwind IntelliSense (VS Code / Cursor / Windsurf) ```json { "tailwindCSS.classAttributes": [ "class", "className", "headerClassName", "contentContainerClassName", "columnWrapperClassName", "endFillColorClassName", "imageClassName", "tintColorClassName", "ios_backgroundColorClassName", "thumbColorClassName", "trackColorOnClassName", "trackColorOffClassName", "selectionColorClassName", "cursorColorClassName", "underlineColorAndroidClassName", "placeholderTextColorClassName", "selectionHandleColorClassName", "colorsClassName", "progressBackgroundColorClassName", "titleColorClassName", "underlayColorClassName", "colorClassName", "backdropColorClassName", "backgroundColorClassName", "statusBarBackgroundColorClassName", "drawerBackgroundColorClassName", "ListFooterComponentClassName", "ListHeaderComponentClassName" ], "tailwindCSS.classFunctions": ["useResolveClassNames"] } ``` ### Monorepo Support Add `@source` directives in `global.css` for packages outside the CSS entry file's directory: ```css @import 'tailwindcss'; @import 'uniwind'; @source "../../packages/ui/src"; @source "../../packages/shared/src"; ``` Also needed for `node_modules` packages that contain Uniwind classes (e.g., shared UI libraries). ## Component Bindings All core React Native components support `className` out of the box. Some have additional className props for sub-styles (like `contentContainerClassName`) and non-style color props (requiring `accent-` prefix). ### Complete Reference **Legend**: Props marked with ⚡ require the `accent-` prefix. Props in parentheses are platform-specific. #### View | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | #### Text | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `selectionColorClassName` | `selectionColor` | ⚡ `accent-` | #### Pressable | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | Supports `active:`, `disabled:`, `focus:` state selectors. #### Image | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `tintColorClassName` | `tintColor` | ⚡ `accent-` | #### TextInput | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `cursorColorClassName` | `cursorColor` | ⚡ `accent-` | | `selectionColorClassName` | `selectionColor` | ⚡ `accent-` | | `placeholderTextColorClassName` | `placeholderTextColor` | ⚡ `accent-` | | `selectionHandleColorClassName` | `selectionHandleColor` | ⚡ `accent-` | | `underlineColorAndroidClassName` | `underlineColorAndroid` (Android) | ⚡ `accent-` | Supports `focus:`, `active:`, `disabled:` state selectors. #### ScrollView | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `contentContainerClassName` | `contentContainerStyle` | — | | `endFillColorClassName` | `endFillColor` | ⚡ `accent-` | #### FlatList | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `contentContainerClassName` | `contentContainerStyle` | — | | `columnWrapperClassName` | `columnWrapperStyle` | — | | `ListHeaderComponentClassName` | `ListHeaderComponentStyle` | — | | `ListFooterComponentClassName` | `ListFooterComponentStyle` | — | | `endFillColorClassName` | `endFillColor` | ⚡ `accent-` | #### SectionList | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `contentContainerClassName` | `contentContainerStyle` | — | | `ListHeaderComponentClassName` | `ListHeaderComponentStyle` | — | | `ListFooterComponentClassName` | `ListFooterComponentStyle` | — | | `endFillColorClassName` | `endFillColor` | ⚡ `accent-` | #### VirtualizedList | Prop | Maps to | Prefix | |------|---------|--------| | `className` | `style` | — | | `contentContainerClassName` | `contentContainerStyle` | — | | `ListHeaderComponentClassName` | `ListHeaderComponentStyle` | — | | `ListFooterComponentClassName` | `ListFooterComponentStyle` | — | | `endFillColorClassName` | `endFillColor` | ⚡ `accent-` | #### Switch | Prop | Maps to | Prefix | |------|---------|--------| | `thumbColorClassName` | `thumbColor` | ⚡ `accent-` |
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub