Skip to Content
ExamplesAdvanced Patterns

Advanced Patterns

Explore advanced techniques for building complex, production-ready UIs with Primitive UI components.

Nested Layouts

Complex Form Layout

Complex Form Layout DemoOpen in new tab ↗
class ProfileForm extends StatefulWidget { @override State<ProfileForm> createState() => _ProfileFormState(); } class _ProfileFormState extends State<ProfileForm> { bool _emailNotifications = true; bool _pushNotifications = false; bool _smsNotifications = false; @override Widget build(BuildContext context) { return SingleChildScrollView( child: Padding( padding: EdgeInsets.all(16), child: VStack( spacing: 24.0, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Header Text( 'Profile Settings', style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold), ), // Personal Info Section _buildSection( title: 'Personal Information', children: [ TextField( decoration: InputDecoration(labelText: 'Name'), ), SizedBox(height: 16), TextField( decoration: InputDecoration(labelText: 'Email'), ), ], ), // Notification Preferences _buildSection( title: 'Notifications', children: [ _buildToggleRow( 'Email Notifications', _emailNotifications, (v) => setState(() => _emailNotifications = v), ), _buildToggleRow( 'Push Notifications', _pushNotifications, (v) => setState(() => _pushNotifications = v), ), _buildToggleRow( 'SMS Notifications', _smsNotifications, (v) => setState(() => _smsNotifications = v), ), ], ), // Actions ElevatedButton( onPressed: _saveSettings, style: ElevatedButton.styleFrom( minimumSize: Size(double.infinity, 48), ), child: Text('Save Changes'), ), ], ), ), ); } Widget _buildSection({ required String title, required List<Widget> children, }) { return PrimitiveCard( elevation: 2.0, child: VStack( spacing: 16.0, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( title, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ...children, ], ), ); } Widget _buildToggleRow( String label, bool value, ValueChanged<bool> onChanged, ) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label), PrimitiveToggleSwitch(value: value, onChanged: onChanged), ], ); } void _saveSettings() { // Save settings logic ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Settings saved!')), ); } }

Dynamic Content

Conditional Rendering

Conditional Rendering DemoOpen in new tab ↗
class DashboardView extends StatefulWidget { @override State<DashboardView> createState() => _DashboardViewState(); } class _DashboardViewState extends State<DashboardView> { bool _isLoading = false; bool _hasError = false; List<String> _items = ['Item 1', 'Item 2', 'Item 3']; @override Widget build(BuildContext context) { return VStack( spacing: 16.0, children: [ // Conditionally show loading state if (_isLoading) PrimitiveCard( child: Center( child: CircularProgressIndicator(), ), ), // Conditionally show error if (_hasError) PrimitiveCard( color: Color(0xFFFFEBEE), child: VStack( spacing: 8.0, children: [ Icon(Icons.error, color: Colors.red), Text('Error loading data'), ElevatedButton( onPressed: _retry, child: Text('Retry'), ), ], ), ), // Show items if not loading and no error if (!_isLoading && !_hasError) ..._items.map((item) => PrimitiveCard( child: Text(item), )), // Show empty state if (!_isLoading && !_hasError && _items.isEmpty) PrimitiveCard( child: VStack( spacing: 12.0, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.inbox, size: 64, color: Colors.grey), Text('No items yet'), ], ), ), ], ); } void _retry() { setState(() { _hasError = false; _isLoading = true; }); // Simulate loading Future.delayed(Duration(seconds: 2), () { setState(() => _isLoading = false); }); } }

Advanced Layering

Image Card with Overlay

Image Card with Overlay DemoOpen in new tab ↗
Widget buildImageCard({ required String imageUrl, required String title, required String subtitle, VoidCallback? onTap, }) { return GestureDetector( onTap: onTap, child: PrimitiveCard( padding: EdgeInsets.zero, child: ZStack( fit: ZStackFit.expand, children: [ // Background image ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( imageUrl, fit: BoxFit.cover, height: 200, ), ), // Gradient overlay Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.transparent, Colors.black.withOpacity(0.7), ], ), ), ), // Text content Positioned( bottom: 0, left: 0, right: 0, child: Padding( padding: EdgeInsets.all(16), child: VStack( spacing: 4.0, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), Text( subtitle, style: TextStyle( color: Colors.white70, fontSize: 14, ), ), ], ), ), ), ], ), ), ); }

Multi-Layer Status Indicator

Multi-Layer Status Indicator DemoOpen in new tab ↗
Widget buildStatusAvatar({ required String initials, required bool isOnline, required bool hasNotification, Color backgroundColor = Colors.blue, }) { return ZStack( children: [ // Main avatar Container( width: 64, height: 64, decoration: BoxDecoration( color: backgroundColor, shape: BoxShape.circle, ), child: Center(q child: Text( initials, style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), ), ), // Online status indicator if (isOnline) Positioned( right: 0, bottom: 0, child: Container( width: 18, height: 18, decoration: BoxDecoration( color: Colors.green, shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 2), ), ), ), // Notification badge if (hasNotification) Positioned( left: 0, top: 0, child: Container( width: 20, height: 20, decoration: BoxDecoration( color: Colors.red, shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 2), ), child: Center( child: Text( '!', style: TextStyle( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold, ), ), ), ), ), ], ); }

State Management Integration

With Provider

Provider State Management DemoOpen in new tab ↗
// Model class Settings { bool darkMode; bool notifications; Settings({ this.darkMode = false, this.notifications = true, }); } class SettingsNotifier extends ChangeNotifier { Settings _settings = Settings(); Settings get settings => _settings; void toggleDarkMode() { _settings.darkMode = !_settings.darkMode; notifyListeners(); } void toggleNotifications() { _settings.notifications = !_settings.notifications; notifyListeners(); } } // UI class SettingsView extends StatelessWidget { @override Widget build(BuildContext context) { return Consumer<SettingsNotifier>( builder: (context, notifier, child) { return VStack( spacing: 16.0, children: [ PrimitiveCard( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Dark Mode'), PrimitiveToggleSwitch( value: notifier.settings.darkMode, onChanged: (_) => notifier.toggleDarkMode(), ), ], ), ), PrimitiveCard( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Notifications'), PrimitiveToggleSwitch( value: notifier.settings.notifications, onChanged: (_) => notifier.toggleNotifications(), ), ], ), ), ], ); }, ); } }

Responsive Layouts

Adaptive Grid

Adaptive Grid DemoOpen in new tab ↗
class ResponsiveGrid extends StatelessWidget { final List<Widget> children; const ResponsiveGrid({required this.children}); @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { // Determine column count based on width int columns = 1; if (constraints.maxWidth > 600) columns = 2; if (constraints.maxWidth > 900) columns = 3; return GridView.count( crossAxisCount: columns, padding: EdgeInsets.all(16), mainAxisSpacing: 16, crossAxisSpacing: 16, children: children, ); }, ); } } // Usage ResponsiveGrid( children: List.generate( 12, (index) => PrimitiveCard( child: Center(child: Text('Card ${index + 1}')), ), ), )

Custom Themes

Themed Components

Themed Components DemoOpen in new tab ↗
class AppTheme { static const Color primaryColor = Color(0xFF2196F3); static const Color surfaceColor = Color(0xFFFFFFFF); static const Color errorColor = Color(0xFFF44336); static PrimitiveCard buildPrimaryCard({required Widget child}) { return PrimitiveCard( color: primaryColor, elevation: 4.0, borderRadius: 12.0, child: child, ); } static PrimitiveCard buildSurfaceCard({required Widget child}) { return PrimitiveCard( color: surfaceColor, elevation: 2.0, borderRadius: 8.0, child: child, ); } static PrimitiveToggleSwitch buildPrimaryToggle({ required bool value, required ValueChanged<bool> onChanged, }) { return PrimitiveToggleSwitch( value: value, onChanged: onChanged, activeColor: primaryColor, inactiveColor: Colors.grey[400]!, ); } } // Usage AppTheme.buildPrimaryCard( child: Text('Themed Card'), )

Performance Optimization

Efficient Lists with Keys

Optimized List DemoOpen in new tab ↗
class OptimizedList extends StatefulWidget { @override State<OptimizedList> createState() => _OptimizedListState(); } class _OptimizedListState extends State<OptimizedList> { List<String> _items = List.generate(100, (i) => 'Item $i'); @override Widget build(BuildContext context) { return ListView.builder( itemCount: _items.length, padding: EdgeInsets.all(16), itemBuilder: (context, index) { return Padding( key: ValueKey(_items[index]), // Important for performance padding: EdgeInsets.only(bottom: 16), child: PrimitiveCard( child: Text(_items[index]), ), ); }, ); } }

Graceful Error Display

Graceful Error Display DemoOpen in new tab ↗
class SafeCard extends StatelessWidget { final Widget? child; final String? errorMessage; const SafeCard({ this.child, this.errorMessage, }); @override Widget build(BuildContext context) { if (errorMessage != null) { return PrimitiveCard( color: Color(0xFFFFEBEE), child: VStack( spacing: 8.0, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(Icons.error_outline, color: Colors.red, size: 32), Text( 'Error', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.red, ), ), Text( errorMessage!, style: TextStyle(color: Colors.red[700]), textAlign: TextAlign.center, ), ], ), ); } return PrimitiveCard(child: child ?? SizedBox.shrink()); } }

Real-World Example

Complete Dashboard

Complete Dashboard DemoOpen in new tab ↗
class Dashboard extends StatefulWidget { @override State<Dashboard> createState() => _DashboardState(); } class _DashboardState extends State<Dashboard> { bool _autoRefresh = true; int _selectedTab = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Dashboard'), actions: [ IconButton( icon: Icon(Icons.settings), onPressed: () {}, ), ], ), body: SingleChildScrollView( child: Padding( padding: EdgeInsets.all(16), child: VStack( spacing: 24.0, children: [ // Stats row _buildStatsRow(), // Settings PrimitiveCard( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ VStack( spacing: 4.0, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Auto Refresh', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), Text( 'Refresh data every 30 seconds', style: TextStyle( fontSize: 12, color: Colors.grey[600], ), ), ], ), PrimitiveToggleSwitch( value: _autoRefresh, onChanged: (v) => setState(() => _autoRefresh = v), ), ], ), ), // Recent activity _buildRecentActivity(), ], ), ), ), ); } Widget _buildStatsRow() { return Row( children: [ Expanded(child: _buildStatCard('Users', '1,234', Icons.people)), SizedBox(width: 16), Expanded(child: _buildStatCard('Revenue', '$45K', Icons.attach_money)), ], ); } Widget _buildStatCard(String label, String value, IconData icon) { return PrimitiveCard( elevation: 3.0, child: VStack( spacing: 8.0, crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(icon, size: 32, color: Colors.blue), Text( value, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), Text( label, style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), ], ), ); } Widget _buildRecentActivity() { return VStack( spacing: 12.0, children: [ Text( 'Recent Activity', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), ...List.generate( 5, (i) => PrimitiveCard( child: Row( children: [ Icon(Icons.circle, size: 8, color: Colors.blue), SizedBox(width: 12), Expanded(child: Text('Activity item ${i + 1}')), Text( '${i + 1}m ago', style: TextStyle(color: Colors.grey[600], fontSize: 12), ), ], ), ), ), ], ); } }

Next Steps

Last updated on