Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 121 additions & 16 deletions skills/uniwind/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ description: >

# Uniwind — Complete Reference

> Uniwind 1.5.0+ / Tailwind CSS v4 / React Native 0.81+ / Expo SDK 54+
> Uniwind 1.6.0+ / Tailwind CSS v4 / React Native 0.81+ / Expo SDK 54+

If user has lower version, recommend updating to 1.5.0+ for best experience.
If user has lower version, recommend updating to 1.6.0+ for best experience.
Comment thread
jpudysz marked this conversation as resolved.

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.

Expand Down Expand Up @@ -996,6 +996,25 @@ Perceptually uniform color format — wider gamut, consistent lightness:
}
```

### Display P3 Colors support

Wide-gamut color format for devices that support the P3 color space (most modern iPhones and Macs). Uniwind parses `color(display-p3 ...)` values and converts them for native use:

```css
@layer theme {
:root {
@variant light {
--color-primary: color(display-p3 0.2 0.4 1);
--color-accent: color(display-p3 1 0.3 0.3);
}
@variant dark {
--color-primary: color(display-p3 0.3 0.5 1);
--color-accent: color(display-p3 1 0.4 0.4);
}
}
}
```
Comment thread
jpudysz marked this conversation as resolved.

## Platform Selectors

Apply platform-specific styles directly in className:
Expand Down Expand Up @@ -1543,6 +1562,22 @@ React Native uses the Yoga layout engine. Key differences from web CSS:
- **Flexbox by default** — all views use flexbox with `flexDirection: 'column'`
- **Limited CSS properties** — no floats, grid, pseudo-elements

### Built-in Extra Utilities

Uniwind provides additional utility classes for React Native features not covered by standard Tailwind:

| Class | Effect |
|-------|--------|
| `border-continuous` | Sets `borderCurve: 'continuous'` — smooth, superellipse corners (iOS) |
| `border-circular` | Sets `borderCurve: 'circular'` — standard circular corners (iOS default) |

```tsx
// Smooth iOS-style rounded corners (like SwiftUI's .continuous)
<View className="rounded-2xl border-continuous bg-card p-4">
<Text className="text-foreground">Smooth corners</Text>
</View>
```

### Supported (all standard Tailwind)

Layout, spacing, sizing, typography, colors, borders, effects, flexbox, positioning, transforms, interactive states.
Expand All @@ -1557,11 +1592,11 @@ Layout, spacing, sizing, typography, colors, borders, effects, flexbox, position

## Uniwind Pro

Paid upgrade with 100% API compatibility. Built on a 2nd-generation C++ engine for apps that demand the best performance. **$99/seat** (billed annually). Pricing and licensing: [https://uniwind.dev/pricing](https://uniwind.dev/pricing)
Paid upgrade with 100% API compatibility. Built on a 2nd-generation C++ engine for apps that demand the best performance. Graduated pricing (billed annually): **$99/seat** (1-3), **$49** (4-6), **$29** (7-15), **$1** (16+). Pricing and licensing: [https://uniwind.dev/pricing](https://uniwind.dev/pricing)

### Pricing & Licensing

- **$99/seat per year** (VAT excluded unless applicable)
- **Graduated per-seat pricing** (billed annually, VAT excluded unless applicable): $99 for seats 1-3, $49 for 4-6, $29 for 7-15, $1 for 16+
- **Individual License**: Personal Pro license per engineer
- **Team License**: Single key management — add or remove members instantly
- **CI/CD License**: Full support for automated and headless build environments
Expand All @@ -1578,13 +1613,13 @@ Paid upgrade with 100% API compatibility. Built on a 2nd-generation C++ engine f
- **Theme transitions**: Native animated transitions when switching themes (fade, slide, circle mask)
- **Priority support**: Don't let technical hurdles slow your team down

Package: `"uniwind": "npm:uniwind-pro@rc"` in `package.json`.
Package: `"uniwind": "npm:uniwind-pro@latest"` in `package.json`.

### Installation

1. Set dependency alias in `package.json`:
```json
{ "dependencies": { "uniwind": "npm:uniwind-pro@rc" } }
{ "dependencies": { "uniwind": "npm:uniwind-pro@latest" } }
```

2. Install peer dependencies:
Expand Down Expand Up @@ -1629,18 +1664,78 @@ Pro does **NOT** work with Expo Go. Requires native rebuild.
<View className="size-8 border-4 border-gray-200 border-t-blue-500 rounded-full animate-spin" />
```

Custom keyframe animations beyond Tailwind defaults:

| Class | Description |
|-------|-------------|
| `animate-wiggle` | Rotational wiggle |
| `animate-shake` | Horizontal shake |
| `animate-flash` | Opacity flash on/off |
| `animate-rubber-band` | Elastic scale stretch |
| `animate-swing` | Pendulum swing |
| `animate-tada` | Scale + rotate attention seeker |
| `animate-heartbeat` | Double-pulse heartbeat |
| `animate-jello` | Rotational jello wobble |
| `animate-float` | Gentle vertical float |
| `animate-breathe` | Subtle breathing scale |
| `animate-tilt` | Alternating tilt rotation |
| `animate-glitch` | Rapid horizontal jitter |

Components auto-swap to Animated versions when animation classes detected:

| Component | Animated Version |
|-----------|------------------|
| `View` | `Animated.View` |
| `Text` | `Animated.Text` (iOS only — no Android support from Reanimated) |
| `Text` | `Animated.Text` |
| `Image` | `Animated.Image` |
| `ImageBackground` | `Animated.ImageBackground` |
| `ScrollView` | `Animated.ScrollView` |
| `FlatList` | `Animated.FlatList` |
| `TextInput` | `Animated.TextInput` (iOS only) |
| `Pressable` | `Animated.View` wrapper |
| `TextInput` | `Animated.TextInput` |
| `Pressable` | `Animated.Pressable` |
Comment thread
jpudysz marked this conversation as resolved.

### Entering & Exiting Animations

Drive Reanimated's entering/exiting animations via className — no Reanimated imports needed. Components auto-upgrade when `uw-*` classes are detected.

```tsx
// Bounce in, bounce out
{visible && <View className="size-20 bg-primary rounded-xl uw-entering-bounce-in uw-exiting-bounce-out" />}

// Fade in slowly (1000ms)
{visible && <View className="size-20 bg-primary rounded-xl uw-entering-fade-in uw-entering-duration-1000 uw-exiting-fade-out" />}
```

**Entering presets**: `uw-entering-fade-in` `uw-entering-fade-in-right` `uw-entering-fade-in-left` `uw-entering-fade-in-up` `uw-entering-fade-in-down` `uw-entering-slide-in-right` `uw-entering-slide-in-left` `uw-entering-slide-in-up` `uw-entering-slide-in-down` `uw-entering-zoom-in` `uw-entering-zoom-in-rotate` `uw-entering-zoom-in-left` `uw-entering-zoom-in-right` `uw-entering-zoom-in-up` `uw-entering-zoom-in-down` `uw-entering-zoom-in-easy-up` `uw-entering-zoom-in-easy-down` `uw-entering-bounce-in` `uw-entering-bounce-in-down` `uw-entering-bounce-in-up` `uw-entering-bounce-in-left` `uw-entering-bounce-in-right` `uw-entering-flip-in-x-up` `uw-entering-flip-in-x-down` `uw-entering-flip-in-y-left` `uw-entering-flip-in-y-right` `uw-entering-flip-in-easy-x` `uw-entering-flip-in-easy-y` `uw-entering-stretch-in-x` `uw-entering-stretch-in-y` `uw-entering-rotate-in-down-left` `uw-entering-rotate-in-down-right` `uw-entering-rotate-in-up-left` `uw-entering-rotate-in-up-right` `uw-entering-roll-in-left` `uw-entering-roll-in-right` `uw-entering-pinwheel-in` `uw-entering-light-speed-in-right` `uw-entering-light-speed-in-left`

**Exiting presets**: `uw-exiting-fade-out` `uw-exiting-fade-out-right` `uw-exiting-fade-out-left` `uw-exiting-fade-out-up` `uw-exiting-fade-out-down` `uw-exiting-slide-out-right` `uw-exiting-slide-out-left` `uw-exiting-slide-out-up` `uw-exiting-slide-out-down` `uw-exiting-zoom-out` `uw-exiting-zoom-out-rotate` `uw-exiting-zoom-out-left` `uw-exiting-zoom-out-right` `uw-exiting-zoom-out-up` `uw-exiting-zoom-out-down` `uw-exiting-zoom-out-easy-up` `uw-exiting-zoom-out-easy-down` `uw-exiting-bounce-out` `uw-exiting-bounce-out-down` `uw-exiting-bounce-out-up` `uw-exiting-bounce-out-left` `uw-exiting-bounce-out-right` `uw-exiting-flip-out-x-up` `uw-exiting-flip-out-x-down` `uw-exiting-flip-out-y-left` `uw-exiting-flip-out-y-right` `uw-exiting-flip-out-easy-x` `uw-exiting-flip-out-easy-y` `uw-exiting-stretch-out-x` `uw-exiting-stretch-out-y` `uw-exiting-rotate-out-down-left` `uw-exiting-rotate-out-down-right` `uw-exiting-rotate-out-up-left` `uw-exiting-rotate-out-up-right` `uw-exiting-roll-out-left` `uw-exiting-roll-out-right` `uw-exiting-pinwheel-out` `uw-exiting-light-speed-out-right` `uw-exiting-light-speed-out-left`

**Animation modifiers** (pattern: `uw-{entering|exiting|layout}-{modifier}`):
- Duration: `uw-{type}-duration-75` `uw-{type}-duration-100` ... `uw-{type}-duration-1000` or arbitrary `uw-{type}-duration-{ms}`
- Delay: `uw-{type}-delay-75` ... `uw-{type}-delay-1000` or arbitrary `uw-{type}-delay-{ms}`
- Easing: `uw-{type}-ease-linear` `uw-{type}-ease-in` `uw-{type}-ease-out` `uw-{type}-ease-in-out` `uw-{type}-ease-bounce`
- Spring: `uw-{type}-springify` `uw-{type}-damping-{value}` `uw-{type}-stiffness-{value}` `uw-{type}-mass-{value}`

### Layout Transitions

Animate position/size changes when siblings are added or removed:

```tsx
<View className="w-full gap-2">
{items.map(item => (
<View key={item.id} className={`h-14 ${item.color} rounded-xl uw-entering-fade-in uw-exiting-fade-out uw-layout-linear-transition`} />
))}
</View>
```

| Class | Description |
|-------|-------------|
| `uw-layout-linear-transition` | Smooth linear repositioning |
| `uw-layout-fading-transition` | Fade during repositioning |
| `uw-layout-jumping-transition` | Bouncy jump to new position |
| `uw-layout-curved-transition` | Curved path repositioning |
| `uw-layout-sequenced-transition` | Sequenced repositioning |
| `uw-layout-entry-exit-transition` | Combined entry/exit during layout |
Comment thread
jpudysz marked this conversation as resolved.

### Transitions

Expand Down Expand Up @@ -1705,6 +1800,10 @@ import Animated, { FadeIn, FlipInXUp, LinearTransition } from 'react-native-rean

No code changes needed — props connect directly to C++ engine, eliminating re-renders automatically.

### Suspense Support

Components inside React `Suspense` boundaries are handled correctly. While a subtree is suspended, Uniwind keeps the C++ shadow entries alive so theme updates and runtime changes (dark mode, orientation, etc.) still reach suspended nodes. When the tree unsuspends, styles are already up to date — no flash of stale theme.

### Native Insets

Remove `SafeAreaListener` setup — insets injected from native layer:
Expand All @@ -1716,24 +1815,27 @@ Remove `SafeAreaListener` setup — insets injected from native layer:

### Theme Transitions (Pro)

Native animated transitions when switching themes. Import `ThemeTransitionPreset` and pass to `setTheme`:
Native animated transitions when switching themes. Supported on iOS, Android, and Web.

```tsx
import { Uniwind, ThemeTransitionPreset } from 'uniwind';

// Fade transition
Uniwind.setTheme('dark', ThemeTransitionPreset.Fade);
Uniwind.setTheme('dark', { preset: ThemeTransitionPreset.Fade });
Comment thread
Brentlok marked this conversation as resolved.

// Slide transitions
Uniwind.setTheme('dark', ThemeTransitionPreset.SlideRightToLeft);
Uniwind.setTheme('light', ThemeTransitionPreset.SlideLeftToRight);
Uniwind.setTheme('dark', { preset: ThemeTransitionPreset.SlideRightToLeft });
Uniwind.setTheme('light', { preset: ThemeTransitionPreset.SlideLeftToRight });

// Circle mask transitions (expand from a corner or center)
Uniwind.setTheme('ocean', ThemeTransitionPreset.CircleCenter);
Uniwind.setTheme('dark', ThemeTransitionPreset.CircleTopRight);
Uniwind.setTheme('ocean', { preset: ThemeTransitionPreset.CircleCenter });

// Blur transitions
Uniwind.setTheme('dark', { preset: ThemeTransitionPreset.Blur });
Uniwind.setTheme('dark', { preset: ThemeTransitionPreset.BlurRightToLeft });

// No animation
Uniwind.setTheme('light', ThemeTransitionPreset.None);
Uniwind.setTheme('light');
```

Available presets:
Expand All @@ -1749,6 +1851,9 @@ Available presets:
| `ThemeTransitionPreset.CircleBottomRight` | Circle mask expanding from bottom-right |
| `ThemeTransitionPreset.CircleBottomLeft` | Circle mask expanding from bottom-left |
| `ThemeTransitionPreset.CircleCenter` | Circle mask expanding from center |
| `ThemeTransitionPreset.Blur` | Blur out animation |
| `ThemeTransitionPreset.BlurRightToLeft` | Directional blur from right to left |
| `ThemeTransitionPreset.BlurLeftToRight` | Directional blur from left to right |
Comment thread
jpudysz marked this conversation as resolved.

## Setup Diagnostics

Expand Down