diff --git a/skills/uniwind/SKILL.md b/skills/uniwind/SKILL.md index e6723cc8..f56c370d 100644 --- a/skills/uniwind/SKILL.md +++ b/skills/uniwind/SKILL.md @@ -11,7 +11,7 @@ description: > cover NativeWind migration. --- -# Uniwind — Complete Reference +# Uniwind > Uniwind 1.7.0+ / Uniwind Pro 1.2.1+ / Tailwind CSS v4 / React Native 0.81+ / Expo SDK 54+ @@ -38,2193 +38,27 @@ Uniwind brings Tailwind CSS v4 to React Native. All core React Native components 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 +## Reference Routing -### Installation +Read only relevant bundled reference files under `references/` after identifying the user's task: -```bash -# or other package manager -bun install uniwind tailwindcss -``` +- Setup/config install issues: `references/setup.md` +- React Native component className props, accent color props, or component examples: `references/component-bindings.md` +- Third-party components, `withUniwind`, dynamic class names, `tailwind-variants`, `cn`, or important utilities: `references/styling-patterns.md` +- Themes, CSS variables, `ScopedTheme`, `LayoutDirection`, color spaces, or runtime variable APIs: `references/theming.md` +- Platform, data, state, responsive, or safe-area utilities: `references/variants-and-selectors.md` +- CSS functions, custom CSS, `@utility`, `@theme`, fonts, or gradients: `references/css-and-utilities.md` +- React Navigation, UI kits, support matrix, or unsupported classes: `references/integrations.md` +- Uniwind Pro installation, animations, diagnostics, group variants, default styles, native insets, or theme transitions: `references/pro.md` +- Broken styles, setup diagnostics, errors, cache issues, FAQ answers, MCP, or related skills: `references/troubleshooting.md` -Requires **Tailwind CSS v4+**. +## Workflow -### 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-` | -| `trackColorOnClassName` | `trackColor.true` (on) | ⚡ `accent-` | -| `trackColorOffClassName` | `trackColor.false` (off) | ⚡ `accent-` | -| `ios_backgroundColorClassName` | `ios_backgroundColor` (iOS) | ⚡ `accent-` | - -Note: Switch does NOT support `className` (`className?: never` in types). Use only the color-specific className props above. Supports `disabled:` state selector. - -#### ActivityIndicator - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `colorClassName` | `color` | ⚡ `accent-` | - -#### Button - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `colorClassName` | `color` | ⚡ `accent-` | - -Note: Button does not support `className` (no `style` prop on RN Button). - -#### Modal - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `backdropColorClassName` | `backdropColor` | ⚡ `accent-` | - -#### RefreshControl - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `colorsClassName` | `colors` (Android) | ⚡ `accent-` | -| `tintColorClassName` | `tintColor` (iOS) | ⚡ `accent-` | -| `titleColorClassName` | `titleColor` (iOS) | ⚡ `accent-` | -| `progressBackgroundColorClassName` | `progressBackgroundColor` (Android) | ⚡ `accent-` | - -#### ImageBackground - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `imageClassName` | `imageStyle` | — | -| `tintColorClassName` | `tintColor` | ⚡ `accent-` | - -#### SafeAreaView - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | - -#### KeyboardAvoidingView - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `contentContainerClassName` | `contentContainerStyle` | — | - -#### InputAccessoryView - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `backgroundColorClassName` | `backgroundColor` | ⚡ `accent-` | - -#### TouchableHighlight - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | -| `underlayColorClassName` | `underlayColor` | ⚡ `accent-` | - -Supports `active:`, `disabled:` state selectors. - -#### TouchableOpacity - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | - -Supports `active:`, `disabled:` state selectors. - -#### TouchableNativeFeedback - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | - -Supports `active:`, `disabled:` state selectors. - -#### TouchableWithoutFeedback - -| Prop | Maps to | Prefix | -|------|---------|--------| -| `className` | `style` | — | - -Supports `active:`, `disabled:` state selectors. - -### Usage Examples - -```tsx -import { View, Text, Pressable, TextInput, ScrollView, FlatList, Switch, Image, ActivityIndicator, Modal, RefreshControl, Button } from 'react-native'; - -// View — basic layout - - Title - - -// Pressable — with press/focus states - - Press Me - - -// TextInput — with focus state and accent- color props - - -// ScrollView — with content container - - {/* content */} - - -// FlatList — with all sub-style props - } -/> - -// Switch — no className support, use color-specific props only - - -// Image — tint color - - -// ActivityIndicator - - -// Button — only colorClassName (no className) -