docs/api/api-style-attributes.md
This document provides a comprehensive reference for all style attributes that can be used with the Style<T> object in Valdi. For usage patterns and best practices, see The Style<> Guide.
Valdi's layout system is powered by Yoga, Facebook's cross-platform flexbox layout engine. The available flexbox attributes and their behavior are determined by the Yoga version used.
Current Yoga Version:
0be0e9fc0148aa609afdc31cb9670524f07050cbthird-party/yoga/README.snapthird-party/yoga/Key Yoga Files:
third-party/yoga/src/yoga/YGEnums.hthird-party/yoga/src/yoga/YGStyle.hthird-party/yoga/src/yoga/Yoga.hImportant: When debugging layout issues or understanding flexbox behavior, refer to this specific Yoga version as behavior may differ from other Yoga versions or standard CSS flexbox implementations.
The Style<T> object allows you to group multiple attributes together for reuse and cleaner code. A style can contain any attribute that the element supports, except for the style property itself.
import { Style } from 'valdi_core/src/Style';
import { View } from 'valdi_tsx/src/NativeTemplateElements';
const myStyle = new Style<View>({
backgroundColor: '#ffffff',
padding: 16,
borderRadius: 8,
});
// Use in JSX:
<view style={myStyle} />
Key Points:
Style<View> can only be used on <view> elementsStyle.merge().extend()These attributes are available on all elements (Layout, View, ScrollView, etc.) as they control layout and positioning.
new Style<Layout>({
// Dimensions - support points, percentages, or 'auto'
width: 200, // number (points)
width: '50%', // string (percentage of parent width)
width: 'auto', // string (automatic sizing)
height: 100, // number (points)
height: '75%', // string (percentage of parent height)
height: 'auto', // string (automatic sizing)
// Size constraints - support points or percentages
minWidth: 50, // number (points)
minWidth: '20%', // string (percentage of parent width)
maxWidth: 500, // number (points)
maxWidth: '90%', // string (percentage of parent width)
minHeight: 50, // number (points)
minHeight: '10%', // string (percentage of parent height)
maxHeight: 500, // number (points)
maxHeight: '80%', // string (percentage of parent height)
// Aspect ratio - numeric ratio only (NOT a percentage)
aspectRatio: 1.5, // width/height ratio (1.5 means width is 1.5x height)
aspectRatio: 16/9, // common video aspect ratio
})
Percentage Calculation Examples:
// Parent container is 400pt wide x 600pt tall
// Child with width: '50%' will be 200pt wide (50% of 400pt)
// Child with height: '25%' will be 150pt tall (25% of 600pt)
// Child with margin: '10%' gets 10% of parent's width for horizontal margins (40pt)
// and 10% of parent's height for vertical margins (60pt)
new Style<Layout>({
// Position type
position: 'relative', // 'relative' | 'absolute'
// Position offsets - support points or percentages
top: 10, // number (points)
top: '5%', // string (percentage of parent height)
right: 10, // number (points)
right: '5%', // string (percentage of parent width)
bottom: 10, // number (points)
bottom: '5%', // string (percentage of parent height)
left: 10, // number (points)
left: '5%', // string (percentage of parent width)
})
Position Percentage Behavior:
left, right): Percentage is relative to parent's widthtop, bottom): Percentage is relative to parent's heightnew Style<Layout>({
// Margin (outside spacing) - supports points or percentages
margin: 10, // number (points, all sides)
margin: '5%', // string (percentage, all sides)
margin: '10 20', // string (top/bottom 10pt, left/right 20pt)
marginTop: 5, // number (points)
marginTop: '2%', // string (percentage of parent height)
marginRight: 5, // number (points)
marginRight: '3%', // string (percentage of parent width)
marginBottom: 5, // number (points)
marginBottom: '2%', // string (percentage of parent height)
marginLeft: 5, // number (points)
marginLeft: '3%', // string (percentage of parent width)
// Padding (inside spacing) - supports points or percentages
padding: 10, // number (points, all sides)
padding: '5%', // string (percentage, all sides)
padding: '10 20', // string (top/bottom 10pt, left/right 20pt)
paddingTop: 5, // number (points)
paddingTop: '2%', // string (percentage of parent height)
paddingRight: 5, // number (points)
paddingRight: '3%', // string (percentage of parent width)
paddingBottom: 5, // number (points)
paddingBottom: '2%', // string (percentage of parent height)
paddingLeft: 5, // number (points)
paddingLeft: '3%', // string (percentage of parent width)
})
Spacing Percentage Behavior:
marginLeft, marginRight, paddingLeft, paddingRight): Percentage is relative to parent's widthmarginTop, marginBottom, paddingTop, paddingBottom): Percentage is relative to parent's heightmargin: '5%' applies 5% to all sides (horizontal uses parent width, vertical uses parent height)These attributes are implemented using Yoga, which provides a flexbox layout engine that closely follows the CSS Flexible Box Layout specification with some additions.
new Style<Layout>({
// Display mode
display: 'flex', // 'flex' | 'none'
overflow: 'visible', // 'visible' | 'scroll' (Yoga also supports 'hidden')
// Direction and orientation
direction: 'inherit', // 'inherit' | 'ltr' | 'rtl'
flexDirection: 'column', // 'column' | 'column-reverse' | 'row' | 'row-reverse'
// Flex properties for this element
flexGrow: 1, // number >= 0 (dimensionless, NOT a percentage)
flexShrink: 0, // number >= 0 (dimensionless, NOT a percentage)
flexBasis: 'auto', // string (automatic)
flexBasis: 100, // number (points)
flexBasis: '50%', // string (percentage of parent's main axis dimension)
flexWrap: 'no-wrap', // 'no-wrap' | 'wrap' | 'wrap-reverse'
// Alignment (for children)
justifyContent: 'flex-start', // 'flex-start' | 'center' | 'flex-end' |
// 'space-between' | 'space-around' | 'space-evenly'
alignItems: 'stretch', // 'stretch' | 'flex-start' | 'flex-end' |
// 'center' | 'baseline'
alignContent: 'flex-start', // Same options as justifyContent plus 'stretch'
// Self alignment (override parent's alignItems)
alignSelf: 'auto', // 'auto' | 'flex-start' | 'flex-end' | 'center' |
// 'stretch' | 'baseline' | 'space-between' | 'space-around'
})
Aspect Ratio (Yoga Extension):
new Style<Layout>({
aspectRatio: 1.5, // number (width/height ratio)
// This is a Yoga-specific property, not in standard flexbox
})
Value Units: Yoga supports three types of values for dimensions and edges:
100)'50%')'auto')Where Percentages Are Supported: Percentage values are calculated relative to the parent element's corresponding dimension and are supported for:
width, height, minWidth, maxWidth, minHeight, maxHeightmargin*, padding* (all directional variants)top, right, bottom, leftflexBasisWhere Percentages Are NOT Supported:
borderWidth, borderRadius (points only)flexGrow, flexShrink (dimensionless numbers)aspectRatio (numeric ratio, not percentage)scaleX, scaleY, rotation, translationX, translationY (specific units)touchAreaExtension* (points only)Alignment Extensions:
Yoga extends the standard flexbox alignContent and alignSelf to support space-between and space-around, which are not in the CSS flexbox spec for these properties.
Default Values: Some Yoga defaults differ from CSS flexbox:
alignItems: stretch (same as CSS)justifyContent: flex-start (same as CSS)flexDirection: column (CSS default is row)position: relative (same as CSS)new Style<Layout>({
// Rendering control
zIndex: 1, // number (higher = on top)
animationsEnabled: true, // boolean
// Performance optimization
lazy: false, // boolean (shorthand for below)
lazyLayout: false, // boolean
limitToViewport: true, // boolean
// Viewport behavior
ignoreParentViewport: false, // boolean
extendViewportWithChildren: false, // boolean
// Estimated dimensions (for lazy layout)
estimatedWidth: 100, // number
estimatedHeight: 100, // number
})
new Style<Layout>({
// Accessibility category
accessibilityCategory: 'auto', // 'auto' | 'view' | 'text' | 'button' |
// 'image' | 'image-button' | 'input' |
// 'header' | 'link' | 'checkbox' | 'radio' |
// 'keyboard-key'
// Navigation behavior
accessibilityNavigation: 'auto', // 'auto' | 'passthrough' | 'leaf' |
// 'cover' | 'group' | 'ignored'
// Priority
accessibilityPriority: 0, // number
// Labels and hints
accessibilityLabel: 'Tap here', // string
accessibilityHint: 'Opens menu', // string
accessibilityValue: '50%', // string
// States
accessibilityStateDisabled: false, // boolean
accessibilityStateSelected: false, // boolean
accessibilityStateLiveRegion: false, // boolean
})
These attributes are available on all visible elements (View, ScrollView, ImageView, Label, etc.) as they control rendering and interaction.
new Style<View>({
// Background
background: 'linear-gradient(#ff0000, #0000ff)', // gradient string
backgroundColor: '#ffffff', // color string
opacity: 1.0, // number 0.0-1.0
// Border
border: '2 solid #000000', // shorthand string
borderWidth: 2, // number or string
borderColor: '#000000', // color string
borderRadius: 8, // number or string ('8 8 0 0' for corners)
// Shadow
boxShadow: '0 2 10 rgba(0,0,0,0.1)', // string: 'x y blur color'
// Clipping
slowClipping: false, // boolean (degrades performance)
})
new Style<View>({
// Touch control
touchEnabled: true, // boolean
// Gesture states (disabled flags)
onTapDisabled: false, // boolean
onDoubleTapDisabled: false, // boolean
onLongPressDisabled: false, // boolean
onDragDisabled: false, // boolean
onPinchDisabled: false, // boolean
onRotateDisabled: false, // boolean
// Gesture timing
onTouchDelayDuration: 0, // number (seconds)
longPressDuration: 0.5, // number (seconds)
// Touch area extension
touchAreaExtension: 10, // number (all sides)
touchAreaExtensionTop: 10, // number
touchAreaExtensionRight: 10, // number
touchAreaExtensionBottom: 10,// number
touchAreaExtensionLeft: 10, // number
})
new Style<View>({
// Scale
scaleX: 1.0, // number
scaleY: 1.0, // number
// Rotation
rotation: 0, // number (radians)
// Translation
translationX: 0, // number (points, flipped in RTL)
translationY: 0, // number (points)
})
new Style<View>({
maskOpacity: 1.0, // number 0.0-1.0
// Note: maskPath is GeometricPath, not styleable
})
new Style<View>({
// Accessibility
accessibilityId: 'my-button', // string (for testing)
// Scroll behavior
canAlwaysScrollHorizontal: false, // boolean
canAlwaysScrollVertical: false, // boolean
// Android-specific
filterTouchesWhenObscured: false, // boolean
})
new Style<View>({
// View reuse
allowReuse: true, // boolean
})
Style<Layout> can contain only layout-related attributes (size, position, spacing, flexbox, accessibility, lifecycle).
import { Layout } from 'valdi_tsx/src/NativeTemplateElements';
const layoutStyle = new Style<Layout>({
width: '100%',
height: 'auto',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 16,
// Cannot use: backgroundColor, borderRadius, etc. (View-only)
});
Available Attribute Groups:
Style<View> can contain all Layout attributes plus View-specific attributes (appearance, gestures, transforms).
import { View } from 'valdi_tsx/src/NativeTemplateElements';
const viewStyle = new Style<View>({
// All Layout attributes
width: 200,
height: 200,
padding: 16,
flexDirection: 'column',
// View-specific attributes
backgroundColor: '#ffffff',
borderRadius: 8,
borderWidth: 1,
borderColor: '#dddddd',
boxShadow: '0 2 10 rgba(0,0,0,0.1)',
opacity: 0.9,
// Gestures
touchEnabled: true,
onTapDisabled: false,
// Transforms
scaleX: 1.0,
scaleY: 1.0,
rotation: 0,
});
Available Attribute Groups:
Style<ScrollView> can contain all View attributes plus ScrollView-specific attributes.
import { ScrollView } from 'valdi_tsx/src/NativeTemplateElements';
const scrollStyle = new Style<ScrollView>({
// All View attributes
backgroundColor: '#f5f5f5',
padding: 16,
// ScrollView-specific attributes
horizontal: false,
bounces: true,
bouncesFromDragAtStart: true,
bouncesFromDragAtEnd: true,
bouncesVerticalWithSmallContent: false,
bouncesHorizontalWithSmallContent: false,
pagingEnabled: false,
scrollEnabled: true,
showsVerticalScrollIndicator: true,
showsHorizontalScrollIndicator: true,
cancelsTouchesOnScroll: true,
dismissKeyboardOnDrag: false,
dismissKeyboardOnDragMode: 'immediate',
fadingEdgeLength: 0,
decelerationRate: 'normal',
viewportExtensionTop: 0,
viewportExtensionRight: 0,
viewportExtensionBottom: 0,
viewportExtensionLeft: 0,
circularRatio: 0,
// Note: flexDirection is NOT available (use horizontal instead)
});
Available Attribute Groups:
flexDirection (use horizontal instead)Note: Programmatic properties like contentOffsetX, contentOffsetY, contentOffsetAnimated cannot be used in styles.
Style<ImageView> can contain all Layout and View attributes plus ImageView-specific attributes.
import { ImageView } from 'valdi_tsx/src/NativeTemplateElements';
const imageStyle = new Style<ImageView>({
// Layout attributes
width: 200,
height: 200,
// View attributes
backgroundColor: '#f5f5f5',
borderRadius: 8,
// ImageView-specific attributes
objectFit: 'cover', // 'fill' | 'contain' | 'cover' | 'none'
tint: '#007AFF', // color string
flipOnRtl: false, // boolean
// Content transform
contentScaleX: 1.0, // number
contentScaleY: 1.0, // number
contentRotation: 0, // number (radians)
// Note: src, filter, callbacks cannot be used in styles
});
Available Attribute Groups:
src (dynamic, use inline)filter (complex object)Style<VideoView> can contain all Layout and View attributes plus VideoView-specific attributes.
import { VideoView } from 'valdi_tsx/src/NativeTemplateElements';
const videoStyle = new Style<VideoView>({
// Layout attributes
width: 400,
height: 300,
// View attributes
backgroundColor: '#000000',
borderRadius: 8,
// VideoView-specific attributes
volume: 1.0, // number 0.0-1.0
playbackRate: 1, // 0=paused, 1=playing
// Note: src, seekToTime, callbacks cannot be used in styles
});
Available Attribute Groups:
src (dynamic, use inline)seekToTime (dynamic control)Style<Label> can contain all Layout and View attributes plus Label-specific text attributes.
import { Label } from 'valdi_tsx/src/NativeTemplateElements';
const labelStyle = new Style<Label>({
// Layout attributes
width: 200,
padding: 8,
// View attributes
backgroundColor: '#ffffff',
borderRadius: 4,
// Text styling
font: 'AvenirNext-Bold 16 unscaled 20',
color: '#000000',
textGradient: 'linear-gradient(#ff0000, #0000ff)',
textShadow: 'rgba(0,0,0,0.1) 1 1 1 1',
// Text layout
numberOfLines: 2, // number (0=unlimited)
textAlign: 'left', // 'left' | 'right' | 'center' | 'justified'
textDecoration: 'none', // 'none' | 'strikethrough' | 'underline'
lineHeight: 1.2, // number (ratio)
letterSpacing: 0, // number (points)
textOverflow: 'ellipsis',// 'ellipsis' | 'clip'
// Auto-sizing
adjustsFontSizeToFitWidth: false, // boolean
minimumScaleFactor: 0.5, // number
// Note: value cannot be used in styles (dynamic)
});
Available Attribute Groups:
value (dynamic content, use inline)Style<TextField> can contain all Label attributes plus TextField-specific input attributes.
import { TextField } from 'valdi_tsx/src/NativeTemplateElements';
const textFieldStyle = new Style<TextField>({
// All Label attributes
font: 'system 16',
color: '#000000',
padding: 12,
backgroundColor: '#f5f5f5',
borderRadius: 8,
borderWidth: 1,
borderColor: '#dddddd',
// TextField-specific attributes
placeholderColor: '#999999',
tintColor: '#007AFF', // iOS caret color
// Keyboard configuration
contentType: 'default', // 'default' | 'phoneNumber' | 'email' | 'password' |
// 'url' | 'number' | 'numberDecimal' | etc.
returnKeyText: 'done', // 'done' | 'go' | 'join' | 'next' | 'search' | 'send'
autocapitalization: 'sentences', // 'sentences' | 'words' | 'characters' | 'none'
autocorrection: 'default', // 'default' | 'none'
keyboardAppearance: 'default', // 'default' | 'dark' | 'light'
// Text editing behavior
textAlign: 'left', // 'left' | 'center' | 'right'
enabled: true, // boolean
characterLimit: 100, // number
selectTextOnFocus: false,// boolean
closesWhenReturnKeyPressed: true, // boolean
enableInlinePredictions: false, // boolean (iOS)
// Note: value, placeholder, selection, callbacks cannot be used in styles
});
Available Attribute Groups:
value, placeholder (dynamic, use inline)selection (dynamic state)focused (programmatic only)Style<TextView> can contain all TextField attributes plus TextView-specific attributes.
import { TextView } from 'valdi_tsx/src/NativeTemplateElements';
const textViewStyle = new Style<TextView>({
// All TextField attributes
font: 'system 16',
color: '#000000',
padding: 12,
backgroundColor: '#f5f5f5',
borderRadius: 8,
// TextView-specific attributes
returnType: 'linereturn', // 'linereturn' | TextFieldReturnKeyText
textGravity: 'top', // 'top' | 'center' | 'bottom'
closesWhenReturnKeyPressed: false, // typically false for multiline
// Background effect
backgroundEffectColor: '#ffffff',
backgroundEffectBorderRadius: 4,
backgroundEffectPadding: 2,
});
Available Attribute Groups:
value, placeholder (dynamic, use inline)focused (programmatic only)Style<BlurView> can contain all Layout and View attributes plus BlurView-specific attributes.
import { BlurView } from 'valdi_tsx/src/NativeTemplateElements';
const blurStyle = new Style<BlurView>({
// Layout attributes
width: 300,
height: 300,
// View attributes (limited)
opacity: 0.9,
borderRadius: 12,
// BlurView-specific attributes
blurStyle: 'systemMaterial', // Many options:
// 'light', 'dark', 'extraLight', 'regular', 'prominent'
// 'systemUltraThinMaterial', 'systemThinMaterial',
// 'systemMaterial', 'systemThickMaterial',
// 'systemChromeMaterial', 'systemUltraThinMaterialLight',
// etc.
});
Available Attribute Groups:
Style<SpinnerView> can contain all Layout and View attributes plus SpinnerView-specific attributes.
import { SpinnerView } from 'valdi_tsx/src/NativeTemplateElements';
const spinnerStyle = new Style<SpinnerView>({
// Layout attributes
width: 40,
height: 40,
// View attributes
opacity: 1.0,
// SpinnerView-specific attributes
color: '#007AFF', // color string
});
Available Attribute Groups:
Style<ShapeView> can contain all Layout and View attributes plus ShapeView-specific attributes.
import { ShapeView } from 'valdi_tsx/src/NativeTemplateElements';
const shapeStyle = new Style<ShapeView>({
// Layout attributes
width: 100,
height: 100,
// View attributes
backgroundColor: 'transparent',
// ShapeView-specific attributes
strokeWidth: 2, // number
strokeColor: '#000000', // color string
strokeCap: 'round', // 'butt' | 'round' | 'square'
strokeJoin: 'round', // 'bevel' | 'miter' | 'round'
strokeStart: 0, // number 0-1 (animatable)
strokeEnd: 1, // number 0-1 (animatable)
fillColor: '#ff0000', // color string
// Note: path is GeometricPath, cannot be used in styles (use inline)
});
Available Attribute Groups:
path (complex object, use inline)Style<AnimatedImage> can contain all Layout and View attributes plus AnimatedImage-specific attributes.
import { AnimatedImage } from 'valdi_tsx/src/NativeTemplateElements';
const animatedImageStyle = new Style<AnimatedImage>({
// Layout attributes
width: 200,
height: 200,
// View attributes
backgroundColor: 'transparent',
// AnimatedImage-specific attributes
loop: true, // boolean
advanceRate: 1, // number (0=paused, 1=normal, -1=reverse)
objectFit: 'contain', // 'fill' | 'contain' | 'cover' | 'none'
// Animation timing
currentTime: 0, // number (seconds)
animationStartTime: 0, // number (seconds)
animationEndTime: 5, // number (seconds)
// Note: src, fontProvider, callbacks cannot be used in styles
});
Available Attribute Groups:
src (dynamic, use inline)fontProvider (complex object)Combine multiple styles into one. Later styles override earlier ones.
const baseStyle = new Style<View>({
width: 100,
height: 100,
backgroundColor: 'red',
});
const roundedStyle = new Style<View>({
borderRadius: 8,
});
const shadowStyle = new Style<View>({
boxShadow: '0 2 10 rgba(0,0,0,0.1)',
});
// Merge all three
const cardStyle = Style.merge(baseStyle, roundedStyle, shadowStyle);
// Result: width: 100, height: 100, backgroundColor: 'red',
// borderRadius: 8, boxShadow: '0 2 10 rgba(0,0,0,0.1)'
Create a new style based on an existing one with modifications.
const baseStyle = new Style<View>({
width: 100,
height: 100,
backgroundColor: 'red',
});
const blueStyle = baseStyle.extend({
backgroundColor: 'blue', // Override
borderRadius: 8, // Add new
});
// Result: width: 100, height: 100, backgroundColor: 'blue', borderRadius: 8
Styles follow TypeScript's type system. A Style<View> can be used where a Style<Layout> is expected because View extends Layout.
const viewStyle = new Style<View>({
backgroundColor: 'red',
width: 100,
});
// ✅ Works - View extends Layout
<view style={viewStyle} />
// ✅ Works - can use on layout (but backgroundColor won't apply)
<layout style={viewStyle} />
// ❌ Type error - Label doesn't extend View directly
const labelStyle = new Style<Label>({ /* ... */ });
<view style={labelStyle} />
Pre-create styles and switch between them based on state.
const styles = {
normal: new Style<View>({
backgroundColor: '#ffffff',
borderColor: '#dddddd',
}),
selected: new Style<View>({
backgroundColor: '#007AFF',
borderColor: '#0051D5',
}),
disabled: new Style<View>({
backgroundColor: '#f5f5f5',
borderColor: '#cccccc',
opacity: 0.5,
}),
};
// In render:
<view style={
this.state.disabled ? styles.disabled :
this.state.selected ? styles.selected :
styles.normal
} />
// At module or component class level
const goodStyle = new Style<View>({
width: 100,
height: 100,
backgroundColor: 'red',
});
class MyComponent extends Component {
// Or as class property
private buttonStyle = new Style<View>({
padding: 12,
borderRadius: 8,
});
onRender() {
<view style={goodStyle} />
<view style={this.buttonStyle} />
}
}
class MyComponent extends Component {
onRender() {
// BAD - Creates new object every render
const badStyle = new Style<View>({
width: 100,
height: 100,
});
// BAD - Expensive operations during render
const merged = Style.merge(style1, style2);
const extended = style1.extend({ backgroundColor: 'red' });
<view style={badStyle} />
}
}
const staticStyle = new Style<View>({
width: 100,
height: 100,
borderRadius: 8,
});
class MyComponent extends Component {
onRender() {
// Good - Style is static, dynamic value is inline
<view
style={staticStyle}
backgroundColor={this.state.isActive ? 'blue' : 'gray'}
/>
}
}
const baseButton = new Style<View>({
padding: 12,
borderRadius: 8,
});
const styles = {
primary: baseButton.extend({ backgroundColor: '#007AFF' }),
secondary: baseButton.extend({ backgroundColor: '#5856D6' }),
danger: baseButton.extend({ backgroundColor: '#FF3B30' }),
};
// Use in render - no style creation happens
<view style={this.props.variant === 'primary' ? styles.primary : styles.secondary} />
Inline attributes always override style attributes.
const myStyle = new Style<View>({
backgroundColor: 'red',
width: 100,
});
// backgroundColor will be 'blue', width will be 100
<view style={myStyle} backgroundColor='blue' />
These properties cannot be included in styles and must be used inline:
onChange, onTap, onLayout, etc.path, filter, fontProvider, etc.value, src, placeholder (in most cases)ref propertyfocused, contentOffsetX, etc.width, height, minWidth, maxWidth, minHeight, maxHeight, aspectRatioposition, top, right, bottom, leftmargin*, padding*flexDirection, justifyContent, alignItems, alignContent, alignSelf, flexGrow, flexShrink, flexBasis, flexWrapdisplay, overflow, zIndexbackground, backgroundColor, opacityborder, borderWidth, borderColor, borderRadiusboxShadowslowClippingfont, color, textGradient, textShadownumberOfLines, textAlign, textDecoration, lineHeight, letterSpacing, textOverflowadjustsFontSizeToFitWidth, minimumScaleFactorplaceholderColor, tintColor, contentType, returnKeyText, autocapitalization, autocorrectiontouchEnabled, touchAreaExtension*onTapDisabled, onDoubleTapDisabled, onLongPressDisabled, onDragDisabled, onPinchDisabled, onRotateDisabledonTouchDelayDuration, longPressDurationscaleX, scaleYrotationtranslationX, translationYaccessibilityCategory, accessibilityNavigation, accessibilityPriorityaccessibilityLabel, accessibilityHint, accessibilityValueaccessibilityStateDisabled, accessibilityStateSelected, accessibilityStateLiveRegionaccessibilityIdlazy, lazyLayout, limitToViewportignoreParentViewport, extendViewportWithChildrenestimatedWidth, estimatedHeightanimationsEnabledconst styles = {
// Full-width container
container: new Style<View>({
width: '100%', // Takes full width of parent
padding: '5%', // 5% padding on all sides
backgroundColor: '#f5f5f5',
}),
// Two-column layout (side by side)
column: new Style<View>({
width: '48%', // Just under 50% to allow for gap
margin: '1%', // Creates spacing between columns
backgroundColor: '#ffffff',
}),
// Centered content with max width
content: new Style<Layout>({
width: '90%', // 90% of parent width
maxWidth: 600, // But never more than 600pt
marginLeft: '5%', // Center with left margin
marginRight: '5%', // Center with right margin
}),
// Card with percentage padding
card: new Style<View>({
width: '100%',
padding: '4%', // Responsive padding
borderRadius: 8,
boxShadow: '0 2 10 rgba(0,0,0,0.1)',
}),
// Absolutely positioned overlay
overlay: new Style<View>({
position: 'absolute',
top: '10%', // 10% from top
left: '10%', // 10% from left
width: '80%', // 80% of parent width
height: '80%', // 80% of parent height
backgroundColor: 'rgba(0,0,0,0.5)',
}),
};
const flexStyles = {
container: new Style<Layout>({
width: '100%',
flexDirection: 'row',
justifyContent: 'space-between',
}),
// Flexible items with percentage basis
sidebar: new Style<Layout>({
flexBasis: '30%', // Takes 30% of container width
flexGrow: 0, // Won't grow
flexShrink: 1, // Can shrink if needed
}),
mainContent: new Style<Layout>({
flexBasis: '65%', // Takes 65% of container width
flexGrow: 1, // Can grow to fill space
flexShrink: 1, // Can shrink if needed
}),
};
// ❌ WRONG - These don't support percentages
const wrongStyles = new Style<View>({
borderRadius: '50%', // ❌ borderRadius only accepts points
opacity: '50%', // ❌ opacity is 0.0-1.0, not percentage
scaleX: '150%', // ❌ scale is a number ratio, not percentage
rotation: '90%', // ❌ rotation is in radians
aspectRatio: '16/9', // ❌ aspectRatio is a number (16/9), not a string
});
// ✅ CORRECT - Proper usage
const correctStyles = new Style<View>({
borderRadius: 8, // ✅ Points only
opacity: 0.5, // ✅ 0.0-1.0 scale
scaleX: 1.5, // ✅ Numeric ratio (150% = 1.5)
rotation: Math.PI / 2, // ✅ Radians (90° = π/2)
aspectRatio: 16/9, // ✅ Numeric ratio
});
const mixedStyles = {
// Fixed header with percentage width
header: new Style<View>({
width: '100%', // Full width
height: 60, // Fixed height in points
paddingLeft: 20, // Fixed padding
paddingRight: 20, // Fixed padding
backgroundColor: '#ffffff',
}),
// Responsive grid items
gridItem: new Style<View>({
width: '31%', // Percentage width for 3 columns
height: 150, // Fixed height
margin: '1%', // Percentage margin for spacing
borderRadius: 8, // Fixed border radius
}),
// Combination for centering
centered: new Style<Layout>({
width: '80%', // Percentage width
maxWidth: 400, // Fixed maximum
marginLeft: '10%', // Percentage to center
marginRight: '10%', // Percentage to center
}),
};