This is a quick reference guide for the most commonly used properties of native template elements. For complete API documentation, see the API Reference.
// Layout & Sizing
width={200} // or "50%" or "auto"
height={100} // or "50%" or "auto"
minWidth={50}
maxWidth={500}
aspectRatio={1.5} // width/height ratio
// Positioning
position="absolute" // or "relative" (default)
top={10}
left={10}
right={10}
bottom={10}
// Spacing
margin={10} // or "10 20 10 20" or "10"
padding={10}
marginTop={5}
paddingLeft={10}
// Flexbox
flexDirection="row" // or "column" (default), "row-reverse", "column-reverse"
justifyContent="center" // or "flex-start", "flex-end", "space-between", "space-around"
alignItems="center" // or "stretch" (default), "flex-start", "flex-end", "baseline"
flexGrow={1}
flexShrink={1}
flexWrap="wrap"
// Lifecycle
onLayout={this.handleLayout}
onVisibilityChanged={this.handleVisibilityChanged}
ref={myElementRef}
key="unique-key"
id="global-id"
// Performance
lazy={true} // Shorthand for lazyLayout + limitToViewport
lazyLayout={true}
limitToViewport={true}
// Accessibility
accessibilityLabel="Tap to continue"
accessibilityHint="Opens the next screen"
accessibilityCategory="button"Use for: Invisible containers that don't need native views (best performance).
<layout
width="100%"
height={200}
flexDirection="row"
justifyContent="space-between"
padding={10}
>
{/* children */}
</layout>Use for: Visible containers that need background, borders, or gesture handling.
<view
backgroundColor="#ffffff"
borderRadius={8}
borderWidth={1}
borderColor="#dddddd"
opacity={0.9}
boxShadow="0 2 10 rgba(0,0,0,0.1)"
// Gestures
onTap={this.handleTap}
onLongPress={this.handleLongPress}
onDrag={this.handleDrag}
touchEnabled={true}
// Transform
scaleX={1.2}
scaleY={1.2}
rotation={0.5} // radians
translationX={10}
translationY={10}
>
{/* children */}
</view>Use for: Scrollable containers.
<scroll
horizontal={false} // true for horizontal scrolling
height={400}
width="100%"
// Scroll events
onScroll={this.handleScroll}
onScrollEnd={this.handleScrollEnd}
onDragStart={this.handleDragStart}
// Behavior
bounces={true}
pagingEnabled={false}
scrollEnabled={true}
showsVerticalScrollIndicator={true}
dismissKeyboardOnDrag={false}
// Viewport extensions (for preloading)
viewportExtensionTop={100}
viewportExtensionBottom={100}
>
{/* scrollable children */}
</scroll>
// Programmatic scrolling (via ref):
myScrollRef.setAttribute('contentOffsetY', 500);
myScrollRef.setAttribute('contentOffsetAnimated', true);Use for: Displaying images from assets or URLs.
<image
src={res.myImage} // or "https://example.com/image.png"
width={200}
height={200}
// Display
objectFit="cover" // or "fill", "contain", "none"
tint="#ff0000"
flipOnRtl={false}
// Transform
contentScaleX={1}
contentScaleY={1}
contentRotation={0} // radians
// Callbacks
onAssetLoad={this.handleAssetLoad}
onImageDecoded={this.handleImageDecoded}
// Filters
filter={myImageFilter}
/>Use for: Video playback.
<video
src="https://example.com/video.mp4"
width={400}
height={300}
// Playback control
volume={0.8} // 0.0 to 1.0
playbackRate={1} // 0=paused, 1=playing
seekToTime={5000} // milliseconds
// Callbacks
onVideoLoaded={this.handleVideoLoaded}
onBeginPlaying={this.handleBeginPlaying}
onError={this.handleError}
onCompleted={this.handleCompleted}
onProgressUpdated={this.handleProgressUpdated}
/>Use for: Displaying text.
<label
value="Hello World" // or attributedText
// Text styling
font="AvenirNext-Bold 16 unscaled 16"
color="#000000"
textGradient="linear-gradient(#ff0000, #0000ff)"
textShadow="rgba(0,0,0,0.1) 1 1 1 1"
// Layout
numberOfLines={2} // 0 = unlimited
textAlign="left" // or "center", "right", "justified"
textDecoration="none" // or "underline", "strikethrough"
lineHeight={1.2} // ratio of font height
letterSpacing={0} // points
textOverflow="ellipsis" // or "clip"
// Auto-sizing
adjustsFontSizeToFitWidth={false}
minimumScaleFactor={0.5}
/>Use for: Single-line text input.
<textfield
value={this.state.text}
placeholder="Enter text..."
placeholderColor="#999999"
// Keyboard
contentType="default" // or "email", "phoneNumber", "password", "number"
returnKeyText="done" // or "go", "join", "next", "search", "send"
autocapitalization="sentences"
autocorrection="default"
keyboardAppearance="default"
// Behavior
enabled={true}
textAlign="left"
characterLimit={50}
selectTextOnFocus={false}
closesWhenReturnKeyPressed={true}
// Callbacks
onChange={this.handleChange}
onEditBegin={this.handleEditBegin}
onEditEnd={this.handleEditEnd}
onReturn={this.handleReturn}
onWillDelete={this.handleWillDelete}
onSelectionChange={this.handleSelectionChange}
/>
// Programmatic focus (via ref):
myTextFieldRef.setAttribute('focused', true);Use for: Multi-line text input.
<textview
value={this.state.text}
placeholder="Enter text..."
// Similar to textfield, plus:
returnType="linereturn" // or any TextFieldReturnKeyText
textGravity="top" // or "center", "bottom"
closesWhenReturnKeyPressed={false}
// Background effect
backgroundEffectColor="#ffffff"
backgroundEffectBorderRadius={4}
backgroundEffectPadding={2}
onChange={this.handleChange}
/>Use for: Blur effects (iOS primarily).
<blur
blurStyle="systemMaterial" // Many options available
width={300}
height={300}
>
{/* children rendered on top of blur */}
</blur>Use for: Loading indicators.
<spinner
color="#007AFF"
width={40}
height={40}
/>Use for: Custom vector shapes.
<shape
path={myGeometricPath}
width={100}
height={100}
// Stroke
strokeWidth={2}
strokeColor="#000000"
strokeCap="round" // or "butt", "square"
strokeJoin="round" // or "bevel", "miter"
strokeStart={0} // 0 to 1, animatable
strokeEnd={1} // 0 to 1, animatable
// Fill
fillColor="#ff0000"
/>Use for: Lottie animations and animated images.
<animatedimage
src={res.myLottie}
width={200}
height={200}
// Animation control
loop={true}
advanceRate={1} // 0=paused, 1=normal, -1=reverse
currentTime={0} // seconds
animationStartTime={0} // seconds
animationEndTime={5} // seconds
// Display
objectFit="contain" // or "fill", "cover", "none"
// Fonts
fontProvider={myFontProvider}
// Callbacks
onAssetLoad={this.handleAssetLoad}
onImageDecoded={this.handleImageDecoded}
onProgress={this.handleProgress}
/>Use for: Content projection in components.
// In component:
<layout>
<slot name="header" />
<slot /> {/* default slot */}
<slot name="footer" />
</layout>
// When using component:
<MyComponent>
<layout slot="header">Header content</layout>
<layout>Default content</layout>
<layout slot="footer">Footer content</layout>
</MyComponent>Never use inline anonymous functions in TSX. Always define event handlers as component methods.
❌ DON'T do this:
class MyComponent extends Component {
onRender() {
<view onTap={() => {
// This creates a new function on every render!
console.log('tapped');
}} />
}
}✅ DO this instead:
class MyComponent extends Component {
onRender() {
<view onTap={this.handleTap} />
}
private handleTap = () => {
console.log('tapped');
}
}Why? Inline functions create a new function instance on every render, which:
- Causes unnecessary re-renders and performance issues
- Breaks the diff algorithm's ability to detect unchanged callbacks
- Triggers updates to the backing native view on every render
See also: Performance Optimization for more details.
<layout width="100%" height="100%" justifyContent="center" alignItems="center">
<label value="Centered!" />
</layout><view
backgroundColor="#ffffff"
borderRadius={12}
boxShadow="0 4 20 rgba(0,0,0,0.15)"
padding={16}
margin={16}
>
{/* card content */}
</view><scroll horizontal={true} height={200} width="100%">
<layout flexDirection="row">
{items.map(item => (
<view key={item.id} width={150} height={150} margin={10}>
{/* item content */}
</view>
))}
</layout>
</scroll>class EmailForm extends Component {
onRender() {
<layout padding={20}>
<label value="Email" marginBottom={8} />
<textfield
contentType="email"
placeholder="your@email.com"
backgroundColor="#f5f5f5"
borderRadius={8}
padding={12}
onChange={this.handleEmailChange}
/>
</layout>
}
private handleEmailChange = (event) => {
this.setState({ email: event.text });
}
}import { TouchEvent, DragEvent, ScrollEvent } from 'valdi_tsx/src/GestureEvents';
import { ElementFrame } from 'valdi_tsx/src/Geometry';
import { EditTextEvent, EditTextEndEvent } from 'valdi_tsx/src/NativeTemplateElements';import { IRenderedElementHolder } from 'valdi_tsx/src/IRenderedElementHolder';
private myViewRef = new IRenderedElementHolder<View>();
// In render:
<view ref={this.myViewRef} />
// Later:
const element = this.myViewRef.getElement();
if (element) {
element.setAttribute('backgroundColor', '#ff0000');
}- Complete API Reference - Full documentation with all properties
- Core Views Guide - Layout and view best practices
- Core Flexbox - Understanding flexbox layout
- Core Images - Working with images
- Core Scrolls - ScrollView patterns
- Core Text - Text and input components