Modifiers API Reference
Comprehensive API reference for TachUI's modifier system. TachUI provides 100+ modifiers that enable SwiftUI-style declarative styling with full TypeScript support and reactive capabilities.
Table of Contents
- Quick Start
- Layout Modifiers
- SwiftUI-Style Modifiers
- Appearance Modifiers
- Interaction Modifiers
- Animation Modifiers
- Navigation Modifiers
- Content Modifiers
- Raw CSS Modifiers
- Reactive Modifiers
- Modifier Priority
Quick Start
All TachUI components support the fluent modifier API:
import { Text, createSignal } from '@tachui/core'
Text("Hello World")
.modifier
.foregroundColor('#007AFF')
.fontSize(18)
.fontWeight('bold')
.padding(16)
.backgroundColor('#F8F9FA')
.cornerRadius(8)
.shadow({ x: 0, y: 2, radius: 4, color: 'rgba(0,0,0,0.1)' })
.build()Layout Modifiers
Frame & Sizing
.frame(width?, height?)
Sets component dimensions with support for constraints.
// Basic frame
Text("Content").modifier.frame(200, 100).build()
// With constraints
VStack().modifier
.frame({ width: 300, maxHeight: 500, minWidth: 200 })
.build()
// Infinity support
HStack().modifier.frame({ width: Infinity, height: 50 }).build()Parameters:
width:number | string | typeof Infinity- Width valueheight:number | string | typeof Infinity- Height valueoptions:FrameOptions- Detailed configuration
FrameOptions:
interface FrameOptions {
width?: number | string | typeof Infinity
height?: number | string | typeof Infinity
minWidth?: number | string
maxWidth?: number | string | typeof Infinity
minHeight?: number | string
maxHeight?: number | string | typeof Infinity
flex?: number | string
}Size Shortcuts
// Individual dimensions
.width(200) // Set width
.height(100) // Set height
.maxWidth('100%') // Set maximum width
.minWidth(200) // Set minimum width
.maxHeight(400) // Set maximum height
.minHeight(100) // Set minimum heightPadding & Spacing
.padding(value)
Sets padding with multiple syntax options.
// All sides equal
.padding(16)
// Horizontal and vertical
.padding(16, 24) // vertical: 16, horizontal: 24
// All sides
.padding(8, 16, 12, 20) // top, right, bottom, left
// Object syntax
.padding({ all: 16 })
.padding({ horizontal: 20, vertical: 12 })
.padding({ top: 8, bottom: 16, left: 12, right: 12 })Padding Shortcuts
.paddingTop(8) // Top padding
.paddingBottom(12) // Bottom padding
.paddingLeft(10) // Left padding
.paddingRight(10) // Right padding
.paddingLeading(10) // Leading (LTR-aware)
.paddingTrailing(10) // Trailing (LTR-aware)
.paddingHorizontal(16) // Left + right
.paddingVertical(12) // Top + bottom.margin(value)
Sets margin with type-safe options.
// All sides equal
.margin(16)
// Symmetric spacing
.margin({ vertical: 12, horizontal: 8 })
// Individual sides
.margin({ top: 8, bottom: 16, left: 12, right: 12 })MarginOptions:
type MarginOptions =
| { all: number }
| { vertical: number; horizontal: number }
| { top?: number; right?: number; bottom?: number; left?: number; vertical?: number; horizontal?: number }Layout Priority
.layoutPriority(priority)
Sets layout priority for ZStack sizing calculations.
VStack().modifier.layoutPriority(1).build() // Higher priority
Text("Content").modifier.layoutPriority(0).build() // Lower prioritySwiftUI-Style Modifiers
Core Transform Modifiers
.scaleEffect(x, y?, anchor?) ✨ NEW
SwiftUI-compatible scaling with anchor point support.
// Uniform scaling
.scaleEffect(1.5) // Scale by 150%
// Non-uniform scaling
.scaleEffect(1.2, 0.8) // 120% width, 80% height
// With anchor point
.scaleEffect(1.1, undefined, 'topLeading') // Scale from top-left cornerAnchor Points:'center' | 'top' | 'bottom' | 'leading' | 'trailing' | 'topLeading' | 'topTrailing' | 'bottomLeading' | 'bottomTrailing'
.offset(x, y)
SwiftUI-style position offset with reactive support.
// Static offset
.offset(10, -5)
// Reactive offset with signals
const [isActive, setIsActive] = createSignal(false)
.offset(() => isActive() ? 20 : 0, () => isActive() ? -10 : 0).clipped()
Clips content overflow (sets overflow: hidden).
Image("/large-image.jpg")
.modifier
.frame(100, 100)
.clipped() // Hide overflow content
.build().rotationEffect(angle, anchor?)
Rotates element with 9 anchor point options.
// Basic rotation (center anchor)
.rotationEffect(45)
// With specific anchor
.rotationEffect(30, 'topLeading')
.rotationEffect(-15, 'bottomTrailing')Anchor Points:'center' | 'top' | 'bottom' | 'leading' | 'trailing' | 'topLeading' | 'topTrailing' | 'bottomLeading' | 'bottomTrailing'
Layout & Visual Modifiers
.aspectRatio(ratio?, contentMode?)
Maintains aspect ratio with fit/fill modes.
// 16:9 aspect ratio
.aspectRatio(16/9, 'fit')
.aspectRatio(1, 'fill') // Square
// From existing content
.aspectRatio(undefined, 'fit') // Preserve original ratioContent Modes:
'fit'- Scale to fit within bounds'fill'- Scale to fill bounds (may crop)
.fixedSize(horizontal?, vertical?)
Prevents element shrinking in layout.
.fixedSize() // Both axes
.fixedSize(true, false) // Horizontal only
.fixedSize(false, true) // Vertical only.clipShape(shape, parameters?)
Clips to custom shapes using CSS clip-path.
// Circle clipping
.clipShape('circle')
.clipShape('circle', { radius: '60%' })
// Ellipse clipping
.clipShape('ellipse', { radiusX: '50%', radiusY: '30%' })
// Rectangle with insets
.clipShape('rect', { inset: 10 })
// Polygon (triangle)
.clipShape('polygon', { points: '50% 0%, 0% 100%, 100% 100%' }).overlay(content, alignment?)
Overlays content with alignment options.
Image("/photo.jpg")
.modifier
.overlay(
Text("Caption").modifier.foregroundColor('white').build(),
'bottomTrailing'
)
.build()Alignment Options:'center' | 'top' | 'bottom' | 'leading' | 'trailing' | 'topLeading' | 'topTrailing' | 'bottomLeading' | 'bottomTrailing'
Appearance Modifiers
Colors
.foregroundColor(color)
Sets text/foreground color with Asset support.
.foregroundColor('#007AFF') // Hex color
.foregroundColor('rgb(0,122,255)') // RGB
.foregroundColor(Assets.primary) // Asset reference.backgroundColor(color)
Sets background color with Asset support.
.backgroundColor('#F8F9FA')
.backgroundColor(Assets.surface)
.backgroundColor(() => isDark() ? '#1A1A1A' : '#FFFFFF') // Reactive.opacity(value)
Sets element opacity (0-1).
.opacity(0.8)
.opacity(() => isVisible() ? 1 : 0) // ReactiveTypography
.font(options | size)
Complete font configuration or size shorthand.
// Size shorthand
.font(18)
// Complete configuration
.font({
family: 'Inter, sans-serif',
size: 18,
weight: '600',
style: 'italic'
})
// Asset fonts
.font({
family: Assets.bodyFont,
size: 16,
weight: '400'
})FontOptions:
interface FontOptions {
family?: string
size?: number | string
weight?: FontWeight
style?: 'normal' | 'italic' | 'oblique'
variant?: 'normal' | 'small-caps'
}
type FontWeight = 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'Typography Shortcuts
.fontSize(18) // Font size
.fontWeight('600') // Font weight
.textAlign('center') // Text alignment
.textCase('uppercase') // Text transformation
.letterSpacing('0.5px') // Letter spacing
.lineHeight(1.5) // Line heightBorders & Visual Effects
Border Modifiers
Comprehensive border styling with SwiftUI-inspired syntax, reactive Signal support, and advanced features.
.border(options) / .border(width, color?, style?)
Main border modifier with flexible API supporting simple shorthand or advanced object configuration.
Simple Usage:
.border(1) // 1px solid border
.border(2, '#007AFF') // Colored border
.border('2px', '#007AFF', 'dashed') // String width support
.border(1, '#E5E5E7', 'dashed') // Dashed borderAdvanced Object Configuration:
// Individual sides
.border({
top: { width: 2, color: '#007AFF', style: 'solid' },
right: { width: 1, color: '#FF3B30', style: 'dashed' },
bottom: { width: 3, color: '#34C759', style: 'dotted' },
left: { width: 1, color: '#FF9500' }
})
// SwiftUI terminology (LTR-aware)
.border({
leading: { width: 2, color: '#007AFF' }, // Maps to left
trailing: { width: 1, color: '#FF3B30' }, // Maps to right
top: { width: 1, color: '#34C759' }
})
// Shorthand properties
.border({
horizontal: { width: 2, color: '#007AFF' }, // Left + right
vertical: { width: 1, color: '#ddd' } // Top + bottom
})Advanced Features:
// Border images
.border({
width: 5,
image: 'linear-gradient(45deg, #007AFF, #FF3B30)',
style: 'solid'
})
// Integrated corner radius
.border({
width: 2,
color: '#007AFF',
style: 'solid',
radius: { topLeft: 8, topRight: 8 } // Corner radius with border
})
// Reactive values with Signals
.border({
width: () => isActive() ? 2 : 1,
color: () => theme().borderColor,
style: 'dashed'
})Border Direction Functions
Convenient functions for applying borders to specific sides.
.borderTop(2, '#007AFF', 'solid') // Top border only
.borderRight('1px', '#ddd') // Right border only
.borderBottom(1, '#e0e0e0', 'dotted') // Bottom border only
.borderLeft(3, '#34C759') // Left border only
// SwiftUI-style (LTR-aware)
.borderLeading(2, '#007AFF') // Leading border (maps to left)
.borderTrailing(1, '#ddd', 'dashed') // Trailing border (maps to right)
// Shorthand functions
.borderHorizontal(1, '#007AFF', 'solid') // Left + right borders
.borderVertical(2, '#e0e0e0') // Top + bottom bordersReactive Border Support
All border properties support reactive Signals and Asset integration.
// Signal integration
const [borderWidth, setBorderWidth] = createSignal(1)
const [borderColor, setBorderColor] = createSignal('#007AFF')
.border({
width: borderWidth, // Reactive width
color: borderColor, // Reactive color
style: () => isActive() ? 'solid' : 'dashed'
})
// Asset integration
import { Assets } from './assets'
.border(2, Assets.colors.primary, 'solid') // Automatically resolves AssetBorder Type Reference
interface BorderSide {
width?: number | string | Signal<number>
color?: string | Signal<string>
style?: BorderStyle
}
interface BorderOptions {
// Individual sides (CSS terminology)
top?: BorderSide
right?: BorderSide
bottom?: BorderSide
left?: BorderSide
all?: BorderSide
// SwiftUI terminology (aliases)
leading?: BorderSide // Maps to left
trailing?: BorderSide // Maps to right
// Shorthand properties
horizontal?: BorderSide // Left and right
vertical?: BorderSide // Top and bottom
// Convenience properties (applied if no specific sides)
width?: number | string | Signal<number>
color?: string | Signal<string>
style?: BorderStyle
// Advanced features
image?: string | Signal<string> // CSS border-image
radius?: CornerRadiusConfig | Signal<CornerRadiusConfig> // Integrated corner radius
}
type BorderStyle = 'none' | 'solid' | 'dashed' | 'dotted' | 'double' | 'groove' | 'ridge' | 'inset' | 'outset'.cornerRadius(radius)
Sets border radius for rounded corners.
.cornerRadius(8) // All corners
.cornerRadius(12) // More rounded.shadow(options)
Adds drop shadow with comprehensive options.
.shadow({ x: 0, y: 2, radius: 4, color: 'rgba(0,0,0,0.1)' })
.shadow({ x: 0, y: 8, radius: 16, color: 'rgba(0,0,0,0.15)', inset: false })ShadowOptions:
interface ShadowOptions {
x?: number // Horizontal offset
y?: number // Vertical offset
radius?: number // Blur radius
color?: string // Shadow color
inset?: boolean // Inset shadow
}Visual Effects
.backdropFilter(config, fallbackColor?)
Applies backdrop filter effects with automatic browser compatibility.
// Object configuration
.backdropFilter({ blur: 10, saturate: 1.3 })
// With fallback for unsupported browsers
.backdropFilter(
{ blur: 16, brightness: 1.1 },
'rgba(255, 255, 255, 0.85)' // Fallback color
)
// CSS string format
.backdropFilter('blur(20px) saturate(1.5) brightness(1.2)')
// With ColorAsset fallback
import { Colors } from './assets'
.backdropFilter(
{ blur: 12 },
Colors.glass.fallback
)
// Complex filters with drop shadow
.backdropFilter({
blur: 15,
brightness: 1.1,
contrast: 1.05,
dropShadow: {
x: 0, y: 4, blur: 6,
color: 'rgba(0, 0, 0, 0.2)'
}
})BackdropFilterConfig:
interface BackdropFilterConfig {
blur?: number // Blur radius in pixels
brightness?: number // Brightness multiplier (1.0 = normal)
contrast?: number // Contrast multiplier (1.0 = normal)
dropShadow?: { // Drop shadow configuration
x: number // Horizontal offset
y: number // Vertical offset
blur: number // Blur radius
color: string // Shadow color
} | string // Or CSS drop-shadow string
grayscale?: number // Grayscale amount (0-1)
hueRotate?: number // Hue rotation in degrees
invert?: number // Invert amount (0-1)
opacity?: number // Opacity multiplier
saturate?: number // Saturation multiplier (1.0 = normal)
sepia?: number // Sepia amount (0-1)
}.glassmorphism(intensity?, customFallback?)
Convenient glassmorphism presets with optimized parameters.
// Preset intensities
.glassmorphism('subtle') // blur: 3px, minimal enhancement
.glassmorphism('light') // blur: 8px, light enhancement
.glassmorphism('medium') // blur: 16px, balanced enhancement (default)
.glassmorphism('heavy') // blur: 24px, strong enhancement
// With custom fallback color
.glassmorphism('medium', 'rgba(0, 0, 0, 0.15)')
// With ColorAsset fallback
import { GlassColors } from './design-system'
.glassmorphism('light', GlassColors.primary.fallback)Glassmorphism Intensity Presets:
type GlassmorphismIntensity = 'subtle' | 'light' | 'medium' | 'heavy'
const PRESETS = {
subtle: { blur: 3, saturate: 1.05, brightness: 1.05 },
light: { blur: 8, saturate: 1.15, brightness: 1.1 },
medium: { blur: 16, saturate: 1.3, brightness: 1.15 },
heavy: { blur: 24, saturate: 1.5, brightness: 1.2 }
}Browser Support:
- Chrome 76+, Safari 14+, Firefox 103+, Edge 79+
- Automatic fallback color for unsupported browsers
- Vendor prefixes applied automatically (
-webkit-backdrop-filter) - Development warnings when using fallbacks
Standard Visual Effect Modifiers
// Individual filter effects
.blur(5) // Gaussian blur
.brightness(1.2) // Brightness adjustment
.contrast(1.3) // Contrast enhancement
.saturate(1.8) // Saturation control (CSS name)
.hueRotate('90deg') // Hue rotation (CSS name)
.grayscale(0.8) // Grayscale conversion (0-1)
.invert(1) // Color inversion (CSS name)SwiftUI-Compatible Visual Effects ✨ NEW
// SwiftUI naming for seamless migration
.saturation(1.8) // SwiftUI-style saturation control
.hueRotation('90deg') // SwiftUI-style hue rotation
.colorInvert() // SwiftUI-style color inversion (full invert)
// Direct equivalency:
.saturation(0.5) === .saturate(0.5) // Same behavior
.hueRotation('45deg') === .hueRotate('45deg') // Same behavior
.colorInvert() === .invert(1) // Same behaviorInteraction Modifiers
Mouse & Touch Events
.onTap(handler)
Click/tap event handler.
.onTap(() => console.log('Tapped!'))
.onTap((event) => {
event.preventDefault()
handleClick()
}).onHover(handler)
Hover state handler (enter/leave combined).
const [isHovered, setIsHovered] = createSignal(false)
.onHover((hovered) => {
setIsHovered(hovered) // true on enter, false on leave
})Individual Mouse Events
.onMouseEnter((event) => setHovered(true))
.onMouseLeave((event) => setHovered(false))
.onMouseDown((event) => setPressing(true))
.onMouseUp((event) => setPressing(false))Focus & Accessibility
.onFocus(handler)
Focus state handler.
.onFocus((focused) => {
if (focused) {
// Element gained focus
} else {
// Element lost focus
}
}).accessibilityLabel(label)
Sets accessibility label for screen readers.
.accessibilityLabel('Close dialog button')State Modifiers
.disabled(isDisabled?)
Sets disabled state.
.disabled(true) // Always disabled
.disabled(() => !isValid()) // Reactive disabled stateAnimation Modifiers
Transitions
.transition(options)
CSS transition configuration.
// Single property
.transition({ property: 'opacity', duration: 300 })
// Multiple properties
.transition({
property: 'all',
duration: 500,
easing: 'ease-out',
delay: 100
})TransitionOptions:
interface TransitionOptions {
property?: string // CSS property to animate
duration?: number // Duration in milliseconds
easing?: string // Timing function
delay?: number // Delay in milliseconds
}Animations
.animation(options)
CSS animation configuration.
.animation({
name: 'fadeIn',
duration: 1000,
iterationCount: 1,
fillMode: 'forwards'
})Common Animation Patterns
// Hover effect with smooth transition
const [isHovered, setIsHovered] = createSignal(false)
Button("Hover me")
.modifier
.backgroundColor(() => isHovered() ? '#0056b3' : '#007AFF')
.transform(() => isHovered() ? 'scale(1.05)' : 'scale(1)')
.transition({ property: 'all', duration: 200 })
.onHover(setIsHovered)
.build()Navigation Modifiers
Available with @tachui/navigation package:
Navigation Bar
.navigationTitle('Page Title')
.navigationBarTitleDisplayMode('large')
.navigationBarHidden(false)
.navigationBarItems({
leading: BackButton(),
trailing: MoreButton()
})Toolbar
.toolbarBackground('#007AFF')
.toolbarForegroundColor('#FFFFFF')Content Modifiers
Content modifiers control how component content is processed and rendered, with built-in security features for safe HTML rendering.
.asHTML(options?)
Text Components Only - Renders Text component content as HTML with built-in sanitization.
⚠️ Security Notice: This modifier can only be applied to Text components and includes basic XSS protection by default. For production applications handling untrusted HTML content, consider using a comprehensive sanitization library like DOMPurify.
Basic Usage
import { Text } from '@tachui/core'
// Safe HTML rendering with default sanitization
Text('<p>Hello <strong>world</strong>!</p>')
.modifier
.asHTML()
.build()
// Rich content example
Text(`
<article>
<h2>Article Title</h2>
<p>This paragraph contains <em>emphasized</em> and <strong>bold</strong> text.</p>
<ul>
<li>List item 1</li>
<li>List item 2</li>
</ul>
<blockquote>This is a quote</blockquote>
</article>
`)
.modifier
.asHTML()
.padding(20)
.backgroundColor('#F8F9FA')
.cornerRadius(8)
.build()Configuration Options
interface AsHTMLOptions {
// Skip basic sanitization (use with extreme caution)
skipSanitizer?: boolean
// Custom sanitization function
customSanitizer?: (html: string) => string
// Override allowed HTML tags
allowedTags?: string[]
// Override allowed attributes per tag
allowedAttributes?: Record<string, string[]>
// Custom dangerous patterns to remove
customPatterns?: RegExp[]
// Disable DOM validation for performance
validateDOM?: boolean
// Development-only options
__suppressWarnings?: boolean
}Custom Sanitization
// Using DOMPurify for comprehensive sanitization
import DOMPurify from 'dompurify'
Text(userGeneratedContent)
.modifier
.asHTML({
customSanitizer: (html: string) => DOMPurify.sanitize(html)
})
.build()
// Custom allowed tags and attributes
Text(articleContent)
.modifier
.asHTML({
allowedTags: ['p', 'strong', 'em', 'a', 'ul', 'li', 'blockquote'],
allowedAttributes: {
'*': ['class'],
'a': ['href', 'target', 'rel']
}
})
.build()
// Skip sanitization for trusted content (dangerous!)
Text(trustedServerTemplate)
.modifier
.asHTML({
skipSanitizer: true,
__suppressWarnings: true // Suppress development warnings
})
.build()Security Features
The asHTML modifier includes comprehensive security protection:
- Text Component Restriction: Only works on Text components to prevent misuse
- Pattern-based Sanitization: Removes 40+ common XSS attack vectors
- DOM Validation: Additional DOM-based cleaning of dangerous elements
- URL Sanitization: Validates and removes dangerous URLs in href/src attributes
- Development Warnings: Alerts developers to potentially dangerous content
- Attribute Cleaning: Removes event handlers and dangerous attributes
Blocked Content Examples:
// All of these dangerous patterns are automatically removed:
Text('<script>alert("xss")</script>').modifier.asHTML().build()
// Result: "" (script tags removed)
Text('<img src="x" onerror="alert(1)">').modifier.asHTML().build()
// Result: '<img src="x">' (event handlers removed)
Text('<a href="javascript:alert(1)">Link</a>').modifier.asHTML().build()
// Result: '<a>Link</a>' (dangerous URLs removed)Error Handling
// ❌ Throws runtime error - asHTML only works on Text components
Button("Click me")
.modifier
.asHTML() // Error: AsHTML modifier can only be applied to Text components
.build()
// ✅ Correct usage
Text("<button>Safe HTML Button</button>")
.modifier
.asHTML()
.build()Performance Considerations
- Non-reactive: HTML processing occurs once during creation for optimal performance
- Pattern-first: Fast pattern-based sanitization before DOM validation
- Configurable DOM validation: Can be disabled for performance in trusted environments
// Performance-optimized for trusted content
Text(trustedContent)
.modifier
.asHTML({
validateDOM: false, // Skip DOM validation
customPatterns: [] // Skip additional pattern checks
})
.build()Development Mode Features
In development mode, the modifier provides helpful warnings:
- Content Analysis: Warns about potentially dangerous patterns
- Security Recommendations: Suggests using comprehensive sanitization libraries
- Configuration Guidance: Alerts about disabled security features
// Development console output:
// 🔒 AsHTML Security Warnings
// Potentially dangerous content detected in asHTML:
// • Script tags detected
// • Event handlers detected
// Consider using a comprehensive sanitization solution like DOMPurifyRaw CSS Modifiers
.css(properties)
Apply raw CSS properties for advanced styling.
.css({
backdropFilter: 'blur(10px)',
clipPath: 'polygon(0 0, 100% 0, 80% 100%, 0% 100%)',
containerType: 'inline-size',
scrollBehavior: 'smooth'
}).cssProperty(property, value)
Set individual CSS property.
.cssProperty('backdrop-filter', 'blur(5px)')
.cssProperty('scroll-snap-type', 'y mandatory').cssVariable(name, value)
Set CSS custom properties.
.cssVariable('primary-color', '#007AFF')
.css({ color: 'var(--primary-color)' })Reactive Modifiers
All modifiers support reactive values using TachUI signals:
import { createSignal } from '@tachui/core'
const [count, setCount] = createSignal(0)
const [theme, setTheme] = createSignal<'light' | 'dark'>('light')
const [isActive, setIsActive] = createSignal(false)
Text(`Count: ${count()}`)
.modifier
// Reactive colors
.foregroundColor(() => theme() === 'dark' ? '#FFFFFF' : '#000000')
.backgroundColor(() => isActive() ? '#007AFF' : '#F8F9FA')
// Reactive dimensions
.padding(() => isActive() ? 20 : 16)
.fontSize(() => count() > 10 ? 20 : 16)
// Reactive transforms
.offset(() => count() * 2, 0)
.opacity(() => count() > 0 ? 1 : 0.5)
// Reactive styles
.css({
transform: () => `rotate(${count() * 10}deg)`,
filter: () => isActive() ? 'blur(0px)' : 'blur(2px)'
})
.build()Modifier Priority
Modifiers are applied in priority order to ensure predictable styling:
| Priority | Category | Examples |
|---|---|---|
| 600 | Lifecycle | .onAppear(), .task() |
| 500 | Interaction | .onTap(), .onHover(), .disabled() |
| 400 | Transform | .offset(), .rotationEffect() |
| 300 | Layout | .frame(), .padding(), .aspectRatio() |
| 200 | Appearance | .clipped(), .clipShape(), .overlay() |
| 100 | Style | .foregroundColor(), .backgroundColor(), .font() |
| 50 | Border | .border(), .cornerRadius(), .shadow() |
| 10 | Utility | .cursor(), .zIndex(), .overflow() |
| 5 | CSS | .css(), .cssProperty() |
Best Practices
Type Safety
// ✅ Type-safe usage
Text('Content')
.modifier
.textAlign('center') // Valid TextAlign value
.fontSize(16) // number type
.fontWeight('600') // Valid FontWeight
.build()
// ❌ TypeScript prevents errors
Text('Content')
.modifier
.textAlign('invalid') // Error: not a valid TextAlign
.fontSize('16px') // Error: must be number
.build()Performance
// ✅ Efficient reactive updates
const [theme, setTheme] = createSignal('light')
Text('Content')
.modifier
.foregroundColor(() => theme() === 'dark' ? '#FFF' : '#000') // Only updates when theme changes
.build()
// ❌ Avoid creating new objects in reactive contexts
Text('Content')
.modifier
.font(() => ({ size: 16, weight: '400' })) // Creates new object on every render
.build()Readable Modifier Chains
// ✅ Group related modifiers
Text('Title')
.modifier
// Typography
.fontSize(24)
.fontWeight('bold')
.textAlign('center')
// Colors
.foregroundColor('#1A1A1A')
.backgroundColor('#F8F9FA')
// Layout
.padding(16)
.cornerRadius(8)
// Effects
.shadow({ x: 0, y: 2, radius: 4, color: 'rgba(0,0,0,0.1)' })
.build()Examples
Interactive Card
const [isHovered, setIsHovered] = createSignal(false)
const [isPressed, setIsPressed] = createSignal(false)
VStack({
children: [
Text('Interactive Card'),
Text('Hover and click me')
]
})
.modifier
.backgroundColor(() => {
if (isPressed()) return '#E5F3FF'
if (isHovered()) return '#F0F8FF'
return '#FFFFFF'
})
.padding(20)
.cornerRadius(12)
.border(1, '#E5E5E7')
.shadow(() =>
isHovered()
? { x: 0, y: 8, radius: 16, color: 'rgba(0,0,0,0.15)' }
: { x: 0, y: 2, radius: 8, color: 'rgba(0,0,0,0.1)' }
)
.transition({ property: 'all', duration: 200 })
.onHover(setIsHovered)
.onMouseDown(() => setIsPressed(true))
.onMouseUp(() => setIsPressed(false))
.onTap(() => console.log('Card clicked!'))
.build()Responsive Layout
const [screenSize, setScreenSize] = createSignal<'mobile' | 'tablet' | 'desktop'>('desktop')
VStack()
.modifier
.padding(() => {
switch (screenSize()) {
case 'mobile': return { horizontal: 16, vertical: 20 }
case 'tablet': return { horizontal: 32, vertical: 28 }
case 'desktop': return { horizontal: 48, vertical: 36 }
}
})
.frame(() => ({
maxWidth: screenSize() === 'mobile' ? '100%' : 800,
width: screenSize() === 'mobile' ? '100%' : 'auto'
}))
.build()Complex Visual Effects
Image('/hero-image.jpg')
.modifier
.resizable()
.aspectRatio(16/9, 'fill')
.clipped()
.overlay(
VStack({
children: [
Text('Hero Title').modifier.fontSize(32).fontWeight('bold').build(),
Text('Subtitle').modifier.fontSize(18).build()
]
}).modifier.foregroundColor('#FFFFFF').textAlign('center').build(),
'center'
)
.css({
backgroundImage: 'linear-gradient(rgba(0,0,0,0.3), rgba(0,0,0,0.7))'
})
.build()Advanced Modifier System
TachUI achieves 96% SwiftUI modifier parity through the comprehensive advanced modifier system, with new SwiftUI-compatible functions added for seamless migration. For complete details including implementation examples, test coverage, and advanced gesture systems, see the Advanced Modifiers Documentation and SwiftUI Compatibility Guide.
Advanced Input/Gesture Modifiers
The latest addition includes sophisticated gesture recognition:
// Long press with configurable timing and distance constraints
Button("Hold for Action", () => {})
.modifier
.onLongPressGesture({
minimumDuration: 800, // 800ms minimum hold
maximumDistance: 15, // 15px maximum movement
perform: () => performAction(),
onPressingChanged: (pressing) => setIsPressed(pressing)
})
.keyboardShortcut('s', ['cmd'], () => save())
.focused(isFocused)
.onContinuousHover('local', (coords) => {
if (coords) setHoverPosition(coords)
})
.build()For more examples and patterns, see the Examples section.