Available in Uniwind 1.9.0+ (Free) and 1.4.0+ (Pro)
Overview
LayoutDirection lets you force right-to-left or left-to-right layout for a specific subtree without changing the global device RTL state. This is useful for previews, mixed-direction layouts (for example, an RTL chat bubble inside an LTR app), and testing RTL designs side by side.
The nearest LayoutDirection wins, so nested scopes work naturally.
LayoutDirection is a runtime direction boundary. The rtl: and ltr: variants, hooks, and withUniwind wrapped components inside the boundary resolve against the scoped direction instead of the global RTL state.
Usage
Basic Example
import { LayoutDirection } from 'uniwind'
import { Text , View } from 'react-native'
export function Example () {
return (
< View className = "gap-3" >
< Text className = "ltr:text-left rtl:text-right" >
Uses the global RTL state
</ Text >
< LayoutDirection rtl >
< Text className = "ltr:text-left rtl:text-right" >
Forced RTL subtree
</ Text >
</ LayoutDirection >
< LayoutDirection rtl = { false } >
< Text className = "ltr:text-left rtl:text-right" >
Forced LTR subtree
</ Text >
</ LayoutDirection >
</ View >
)
}
Common Patterns
Side-by-Side Direction Previews
import { LayoutDirection } from 'uniwind'
import { Text , View } from 'react-native'
export function DirectionPreviewRow () {
return (
< View className = "flex-row gap-3" >
< LayoutDirection rtl = { false } >
< View className = "flex-1 p-4 bg-base rounded-2xl gap-2" >
< Text className = "text-default font-bold ltr:text-left rtl:text-right" > LTR </ Text >
< Text className = "text-default/60 text-xs ltr:text-left rtl:text-right" >
Scoped to left-to-right
</ Text >
</ View >
</ LayoutDirection >
< LayoutDirection rtl >
< View className = "flex-1 p-4 bg-base rounded-2xl gap-2" >
< Text className = "text-default font-bold ltr:text-left rtl:text-right" > RTL </ Text >
< Text className = "text-default/60 text-xs ltr:text-left rtl:text-right" >
Scoped to right-to-left
</ Text >
</ View >
</ LayoutDirection >
</ View >
)
}
Nested Scopes
import { LayoutDirection } from 'uniwind'
import { Text , View } from 'react-native'
export function NestedScopes () {
return (
< LayoutDirection rtl >
< View className = "w-full p-4 bg-base rounded-2xl gap-3" >
< Text className = "text-default font-bold ltr:text-left rtl:text-right" >
RTL (outer)
</ Text >
< LayoutDirection rtl = { false } >
< View className = "w-full p-3 bg-base rounded-lg gap-2" >
< Text className = "text-default font-bold ltr:text-left rtl:text-right" >
LTR (inner)
</ Text >
</ View >
</ LayoutDirection >
</ View >
</ LayoutDirection >
)
}
Omit the rtl prop to inherit the direction from the nearest parent LayoutDirection. Outside of any scope, it falls back to the global RTL state.
Hooks and withUniwind in a Layout Direction Scope
Hooks and HOCs resolve against the closest LayoutDirection boundary:
useResolveClassNames() resolves rtl:/ltr: variants using the scoped direction
withUniwind() mappings use values resolved from the scoped direction
API Reference
Component Signature
import { LayoutDirection } from 'uniwind'
< LayoutDirection rtl >
{ /* direction-scoped subtree */ }
</ LayoutDirection >
Props
true forces right-to-left, false forces left-to-right. When omitted, the subtree inherits the direction from the nearest parent LayoutDirection, or the global RTL state if there is none.
React children rendered inside the layout direction boundary.
Behavior Notes
LayoutDirection affects only its descendants
It does not change the global RTL state (I18nManager on native, the document dir on web)
Nested scopes override parent scopes for their own subtree
The wrapper renders with display: contents, so it does not affect your layout
Prefer LayoutDirection over inline style={{ direction: 'rtl' }} - only the component scopes the rtl:/ltr: variants
Class Names All supported variants, including rtl: and ltr:
Scoped Themes Apply a different theme to a subtree
useResolveClassNames Resolve class names into style objects at runtime
withUniwind Add className support to third-party components