Responsive Debugging
TachUI provides comprehensive debugging tools to help you understand, inspect, and troubleshoot responsive behavior in your applications.
Development Tools Overview
The responsive debugging system includes:
- Visual Debug Overlay: Real-time breakpoint and responsive information
- Element Highlighting: Visual identification of responsive elements
- Responsive Inspector: Detailed analysis of responsive values
- Performance Monitoring: Track responsive system performance
- Browser Compatibility Testing: Validate across different browsers
- Console Logging: Detailed responsive state information
Visual Debug Overlay
Enable Debug Overlay
The debug overlay provides real-time information about the current responsive state:
import { ResponsiveDevTools } from '@tachui/core'
// Enable debug overlay in development
if (process.env.NODE_ENV === 'development') {
ResponsiveDevTools.enable({
showOverlay: true, // Show debug overlay
showBreakpoints: true, // Show breakpoint information
showPerformance: true, // Show performance metrics
position: 'top-right', // Overlay position
highlightResponsiveElements: true // Highlight responsive elements
})
}Overlay Information
The debug overlay displays:
- Current Breakpoint: Active breakpoint name and viewport size
- Breakpoint Ranges: All available breakpoints and their values
- Media Query Results: Status of common media queries
- Performance Metrics: CSS cache statistics and generation times
- Element Count: Number of responsive elements on the page
Customizing the Overlay
ResponsiveDevTools.enable({
showOverlay: true,
position: 'bottom-left', // Position in any corner
logLevel: 'debug', // Control console output
refreshRate: 100, // Update frequency in ms
showAnimations: true, // Animate breakpoint changes
customStyles: { // Custom overlay styling
backgroundColor: 'rgba(0, 0, 0, 0.9)',
color: '#ffffff',
fontSize: '12px',
borderRadius: '8px'
}
})Element Highlighting
Visual Element Identification
Highlight responsive elements to understand layout structure:
// Enable element highlighting
ResponsiveDevTools.enable({
highlightResponsiveElements: true,
highlightStyles: {
outline: '2px dashed #007bff', // Highlight style
outlineOffset: '2px',
backgroundColor: 'rgba(0, 123, 255, 0.1)'
}
})Element Information Display
Highlighted elements show additional information:
// Configure element information display
ResponsiveDevTools.enable({
highlightResponsiveElements: true,
showElementInfo: true,
elementInfo: {
showBreakpoints: true, // Show which breakpoints affect element
showResolvedValues: true, // Show current resolved values
showPerformanceMetrics: true, // Show element-specific performance
position: 'top-left' // Info tooltip position
}
})Responsive Inspector
Inspect Responsive Values
Use the responsive inspector to analyze responsive value resolution:
import { useResponsiveInspector } from '@tachui/core'
const DebuggableComponent = () => {
const responsiveValue = {
base: 16,
md: 20,
lg: 24,
xl: 28
}
// Inspect responsive value behavior
const inspector = useResponsiveInspector(responsiveValue, 'Font Size')
const info = inspector()
// Inspector provides detailed information
console.log('Resolved Value:', info.resolvedValue) // 20 (at md breakpoint)
console.log('Active Breakpoint:', info.activeBreakpoint) // 'md'
console.log('All Values:', info.allValues) // Full responsive object
console.log('Is Responsive:', info.isResponsive) // true
return Text("Inspected Text")
.modifier
.fontSize(responsiveValue)
.build()
}Manual Value Inspection
Inspect any responsive value manually:
// Inspect responsive values in console
ResponsiveDevTools.inspectResponsiveValue(
{ base: 16, md: 20, lg: 24 },
'Custom Font Size'
)
// Output:
// 🔍 Responsive Value - Custom Font Size
// Responsive object: { base: 16, md: 20, lg: 24 }
// Resolved value (md): 20
// Defined breakpoints:
// base: 16
// → md: 20 (current)
// lg: 24Batch Inspection
Inspect multiple responsive values:
const debugValues = {
fontSize: { base: 16, md: 20, lg: 24 },
padding: { base: 8, md: 12, lg: 16 },
margin: { base: 4, md: 8, lg: 12 }
}
Object.entries(debugValues).forEach(([name, value]) => {
ResponsiveDevTools.inspectResponsiveValue(value, name)
})Console Logging
Responsive State Logging
Log comprehensive responsive state information:
// Log current responsive state
ResponsiveDevTools.logResponsiveState()
// Output:
// 🔍 TachUI Responsive State
// Current breakpoint: md
// Viewport: 1024×768
// Configuration: { base: '0px', sm: '640px', md: '768px', ... }
// Media Query Results:
// Mobile: false
// Tablet: true
// Desktop: false
// Touch Device: false
// Dark Mode: false
// Reduced Motion: falseCustom Logging
Configure detailed logging for debugging:
ResponsiveDevTools.enable({
logLevel: 'debug', // Log level: error, warn, info, debug
logBreakpointChanges: true, // Log when breakpoints change
logValueResolution: true, // Log responsive value resolution
logPerformanceWarnings: true, // Log performance issues
logCacheStatistics: true // Log cache hit/miss information
})Structured Logging
Create structured logs for analysis:
// Custom logging function
const logResponsiveDebug = (component: string, data: any) => {
if (process.env.NODE_ENV === 'development') {
console.group(`🔧 Responsive Debug: ${component}`)
console.log('Timestamp:', new Date().toISOString())
console.log('Current Breakpoint:', getCurrentBreakpoint()())
console.log('Viewport:', getViewportDimensions())
console.log('Data:', data)
console.groupEnd()
}
}
// Usage in components
const MyComponent = () => {
const responsiveValue = { base: 16, md: 20 }
logResponsiveDebug('MyComponent', {
responsiveValue,
resolvedValue: useResponsiveValue(responsiveValue)()
})
return Text("Logged component").build()
}Performance Debugging
Performance Monitoring
Monitor responsive system performance:
import { ResponsivePerformanceMonitor } from '@tachui/core'
// Enable performance monitoring
ResponsivePerformanceMonitor.enable({
trackCSSGeneration: true,
trackBreakpointChanges: true,
trackMemoryUsage: true,
alertThreshold: 5 // Alert if operations take > 5ms
})
// Monitor in real-time
setInterval(() => {
const stats = ResponsivePerformanceMonitor.getStats()
if (stats.cssGeneration.average > 3) {
console.warn('Slow CSS generation detected:', stats.cssGeneration)
}
if (stats.memoryUsage.current > 10) {
console.warn('High memory usage:', stats.memoryUsage)
}
}, 5000)Performance Profiling
Profile specific responsive operations:
// Profile component rendering
const profileComponentRender = (componentName: string, renderFn: () => any) => {
const startTime = performance.now()
const startMemory = performance.memory?.usedJSHeapSize || 0
const result = renderFn()
const endTime = performance.now()
const endMemory = performance.memory?.usedJSHeapSize || 0
console.log(`📊 Performance Profile: ${componentName}`)
console.log(` Render Time: ${(endTime - startTime).toFixed(2)}ms`)
console.log(` Memory Delta: ${((endMemory - startMemory) / 1024 / 1024).toFixed(2)}MB`)
return result
}
// Usage
const MyComponent = () => {
return profileComponentRender('MyComponent', () => {
return Text("Profiled component")
.modifier
.responsive({
fontSize: { base: 16, md: 20, lg: 24 },
padding: { base: 8, md: 12, lg: 16 }
})
.build()
})
}Breakpoint Testing
Test at Specific Breakpoints
Test component behavior at different breakpoints:
import { testAtBreakpoint } from '@tachui/core/testing'
// Test component at mobile breakpoint
testAtBreakpoint('base', () => {
const component = render(<ResponsiveComponent />)
expect(component.getByText('Mobile Layout')).toBeInTheDocument()
})
// Test component at tablet breakpoint
testAtBreakpoint('md', () => {
const component = render(<ResponsiveComponent />)
expect(component.getByText('Tablet Layout')).toBeInTheDocument()
})
// Test component at desktop breakpoint
testAtBreakpoint('lg', () => {
const component = render(<ResponsiveComponent />)
expect(component.getByText('Desktop Layout')).toBeInTheDocument()
})Simulate Viewport Changes
Simulate viewport changes for testing:
// Simulate different viewport sizes
const simulateViewport = (width: number, height: number) => {
// Mock window dimensions
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: width
})
Object.defineProperty(window, 'innerHeight', {
writable: true,
configurable: true,
value: height
})
// Trigger resize event
window.dispatchEvent(new Event('resize'))
}
// Test different viewport sizes
describe('Responsive Behavior', () => {
test('adapts to mobile viewport', () => {
simulateViewport(375, 667) // iPhone size
const component = render(<ResponsiveComponent />)
expect(component).toHaveStyle('font-size: 16px')
})
test('adapts to tablet viewport', () => {
simulateViewport(768, 1024) // iPad size
const component = render(<ResponsiveComponent />)
expect(component).toHaveStyle('font-size: 20px')
})
test('adapts to desktop viewport', () => {
simulateViewport(1920, 1080) // Desktop size
const component = render(<ResponsiveComponent />)
expect(component).toHaveStyle('font-size: 24px')
})
})Browser Compatibility Testing
Cross-Browser Testing
Test responsive behavior across different browsers:
import { BrowserCompatibility } from '@tachui/core'
// Test CSS features support
const testBrowserSupport = () => {
const features = BrowserCompatibility.testCSSFeatures()
console.log('Browser Support:', features)
// {
// cssGrid: true,
// flexbox: true,
// customProperties: true,
// viewportUnits: true,
// mediaQueries: true,
// containerQueries: false
// }
if (!features.cssGrid) {
console.warn('CSS Grid not supported, falling back to flexbox')
}
if (!features.containerQueries) {
console.info('Container queries not supported, using media queries')
}
}
// Run browser compatibility check
testBrowserSupport()Feature Detection
Implement graceful degradation based on browser capabilities:
const ResponsiveBrowserComponent = () => {
const features = BrowserCompatibility.testCSSFeatures()
return VStack([
Text("Browser Compatibility")
.modifier
.fontSize({ base: 16, md: 20 })
.build(),
// Use grid if supported, fallback to flexbox
...(features.cssGrid ? [
GridComponent()
] : [
FlexboxFallbackComponent()
])
])
.modifier
.responsive({
base: { padding: 16 },
md: { padding: 24 }
})
.build()
}Debug Configuration Export
Export Configuration for Analysis
Export complete responsive configuration for external analysis:
// Export comprehensive configuration
const debugConfig = ResponsiveDevTools.exportConfiguration()
console.log('Debug Configuration:', debugConfig)
// {
// breakpoints: { base: '0px', sm: '640px', md: '768px', ... },
// currentContext: { current: 'md', width: 1024, height: 768 },
// performance: {
// cache: { size: 247, hitRate: 0.847 },
// timings: { cssGeneration: { average: 0.3 } }
// },
// mediaQueries: {
// Mobile: false,
// Tablet: true,
// Desktop: false,
// 'Dark Mode': false
// }
// }
// Save configuration to file for analysis
const saveDebugConfig = () => {
const config = ResponsiveDevTools.exportConfiguration()
const blob = new Blob([JSON.stringify(config, null, 2)], {
type: 'application/json'
})
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `responsive-debug-${Date.now()}.json`
a.click()
URL.revokeObjectURL(url)
}Common Debugging Scenarios
Debugging Layout Issues
// Debug layout that doesn't respond as expected
const debugLayout = (elementSelector: string) => {
const element = document.querySelector(elementSelector)
if (!element) {
console.error('Element not found:', elementSelector)
return
}
console.group('🔍 Layout Debug:', elementSelector)
// Check computed styles
const computedStyle = getComputedStyle(element)
console.log('Display:', computedStyle.display)
console.log('Position:', computedStyle.position)
console.log('Width:', computedStyle.width)
console.log('Height:', computedStyle.height)
// Check responsive classes
const responsiveClasses = Array.from(element.classList)
.filter(cls => cls.includes('responsive') || cls.includes('tachui'))
console.log('Responsive Classes:', responsiveClasses)
// Check media query matches
const mediaQueries = [
'(max-width: 767px)',
'(min-width: 768px)',
'(min-width: 1024px)'
]
mediaQueries.forEach(query => {
const matches = window.matchMedia(query).matches
console.log(`${query}: ${matches}`)
})
console.groupEnd()
}
// Usage
debugLayout('.my-responsive-component')Debugging Value Resolution
// Debug why a responsive value isn't resolving correctly
const debugValueResolution = <T>(
value: ResponsiveValue<T>,
expectedValue: T,
label: string
) => {
const currentBp = getCurrentBreakpoint()()
const resolved = useResponsiveValue(value)()
console.group(`🔧 Value Resolution Debug: ${label}`)
console.log('Input Value:', value)
console.log('Current Breakpoint:', currentBp)
console.log('Resolved Value:', resolved)
console.log('Expected Value:', expectedValue)
console.log('Match:', resolved === expectedValue ? '✅' : '❌')
if (isResponsiveValue(value)) {
const responsiveObj = value as Partial<Record<BreakpointKey, T>>
console.log('Resolution Path:')
const breakpointOrder: BreakpointKey[] = ['base', 'sm', 'md', 'lg', 'xl', '2xl']
const currentIndex = breakpointOrder.indexOf(currentBp)
for (let i = currentIndex; i >= 0; i--) {
const bp = breakpointOrder[i]
if (responsiveObj[bp] !== undefined) {
console.log(` Found at ${bp}:`, responsiveObj[bp])
break
} else {
console.log(` ${bp}: undefined`)
}
}
}
console.groupEnd()
}
// Usage
const fontSize = { base: 16, md: 20, lg: 24 }
debugValueResolution(fontSize, 20, 'Font Size')Debugging Performance Issues
// Debug slow responsive operations
const debugPerformanceIssue = () => {
const monitor = ResponsivePerformanceMonitor.getStats()
console.group('⚡ Performance Debug')
// Check CSS generation performance
if (monitor.cssGeneration.average > 5) {
console.warn('Slow CSS generation detected')
console.log('Average time:', monitor.cssGeneration.average.toFixed(2), 'ms')
console.log('Max time:', monitor.cssGeneration.max.toFixed(2), 'ms')
// Check cache performance
const cacheStats = cssRuleCache.getStats()
console.log('Cache hit rate:', (cacheStats.hitRate * 100).toFixed(1), '%')
if (cacheStats.hitRate < 0.8) {
console.warn('Low cache hit rate - consider optimizing CSS generation')
}
}
// Check memory usage
if (monitor.memoryUsage.current > 10) {
console.warn('High memory usage detected')
console.log('Current:', monitor.memoryUsage.current.toFixed(2), 'MB')
console.log('Peak:', monitor.memoryUsage.peak.toFixed(2), 'MB')
}
// Check breakpoint change frequency
if (monitor.breakpointChanges.count > 20) {
console.warn('High breakpoint change frequency')
console.log('Changes:', monitor.breakpointChanges.count)
console.log('Average time:', monitor.breakpointChanges.average.toFixed(2), 'ms')
}
console.groupEnd()
}
// Run performance debug
debugPerformanceIssue()Production Debugging
Safe Production Debugging
Enable minimal debugging in production environments:
// Production-safe debugging
if (process.env.NODE_ENV === 'production' && process.env.DEBUG_MODE === 'true') {
ResponsiveDevTools.enable({
showOverlay: false, // No visual overlay in production
logLevel: 'error', // Only log errors
showPerformance: true, // Monitor performance
highlightResponsiveElements: false
})
}Remote Debugging
Set up remote debugging capabilities:
// Send debug information to remote service
const sendDebugInfo = async () => {
if (process.env.NODE_ENV === 'production') {
const debugInfo = ResponsiveDevTools.exportConfiguration()
try {
await fetch('/api/debug/responsive', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
timestamp: new Date().toISOString(),
userAgent: navigator.userAgent,
viewport: {
width: window.innerWidth,
height: window.innerHeight
},
debugInfo
})
})
} catch (error) {
console.error('Failed to send debug info:', error)
}
}
}
// Send debug info when issues are detected
window.addEventListener('error', sendDebugInfo)These debugging tools and techniques will help you quickly identify and resolve responsive design issues, ensuring your TachUI applications work flawlessly across all devices and screen sizes.
Related Guides
- Responsive Design - Core responsive design concepts
- Performance Optimization - Optimize responsive performance
- API Reference - Complete API documentation
- Real-World Examples - Production examples