slogan3

Maak een Aangepaste Flutter Widget Bibliotheek voor Herbruikbare UI Componenten

description

Met deze prompt kun je een schaalbare en onderhoudbare Flutter widget bibliotheek creëren die ontwerpconsistentie en herbruikbaarheid over meerdere projecten afdwingt. Het helpt bij het aanpakken van uitdagingen in UI-standaardisatie en ontwikkelings-efficiëntie door je te begeleiden bij best practices in widgetontwerp, thematisering en documentatie. In tegenstelling tot algemene Flutter tutorials richt deze prompt zich op het bouwen van een gecentraliseerde componentbibliotheek die is afgestemd op jouw unieke ontwerpbehoeften, waardoor je tijd bespaart in toekomstige projecten.

prompt

Help me een aangepaste Flutter widget bibliotheek te maken die herbruikbare UI-componenten bevat voor mijn projecten. Ik wil widgets opnemen zoals <lijst met belangrijke widgets of componenttypes> die voldoen aan mijn ontwerp systeem richtlijnen: <beschrijf ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een overzicht en een voorbeeld van hoe je een aangepaste Flutter widget bibliotheek kunt structureren, inclusief voorbeelden voor knoppen, tekstinvoer en navigatiebalken, die voldoen aan jouw ontwerp systeem. --- ### 1. Structuur van de bibliotheek **Projectstructuur:** ``` my_ui_library/ ├── lib/ │ ├── src/ │ │ ├── buttons.dart │ │ ├── input_fields.dart │ │ ├── navigation_bars.dart │ │ ├── themes.dart │ │ └── widgets.dart │ └── my_ui_library.dart ├── pubspec.yaml └── README.md ``` **Uitleg:** - `my_ui_library.dart`: Exporteert alle componenten. - `src/`: Bevat de implementatiebestanden. - `themes.dart`: Beheert de thematische styling en kleuren. --- ### 2. Thematische ondersteuning Gebruik een `ThemeData`-extensie of een eigen `AppTheme` class om consistente kleuren en stijl te garanderen: ```dart // lib/src/themes.dart import 'package:flutter/material.dart'; class AppColors { static const Color primaryBlue = Color(0xFF1565C0); // primaire blauwe kleur static const Color background = Colors.white; static const Color text = Colors.black87; } class AppTheme { static ThemeData get theme { return ThemeData( primaryColor: AppColors.primaryBlue, colorScheme: ColorScheme.fromSwatch( primarySwatch: Colors.blue, ).copyWith( primary: AppColors.primaryBlue, ), buttonTheme: ButtonThemeData( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), // afgeronde hoeken ), buttonColor: AppColors.primaryBlue, textTheme: ButtonTextTheme.primary, ), inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), ), ); } } ``` --- ### 3. Reusable widgets maken #### a) Button (Knop) ```dart // lib/src/buttons.dart import 'package:flutter/material.dart'; import 'themes.dart'; class CustomButton extends StatelessWidget { final String label; final VoidCallback onPressed; const CustomButton({ Key? key, required this.label, required this.onPressed, }) : super(key: key); @override Widget build(BuildContext context) { return ElevatedButton( style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), primary: AppColors.primaryBlue, padding: EdgeInsets.symmetric(horizontal: 24, vertical: 12), ), onPressed: onPressed, child: Text(label, style: TextStyle(color: Colors.white)), ); } } ``` #### b) Tekstinvoer ```dart // lib/src/input_fields.dart import 'package:flutter/material.dart'; class CustomTextField extends StatelessWidget { final String hintText; final TextEditingController controller; const CustomTextField({ Key? key, required this.hintText, required this.controller, }) : super(key: key); @override Widget build(BuildContext context) { return TextField( controller: controller, decoration: InputDecoration( hintText: hintText, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), ), ); } } ``` #### c) Navigatiebalk ```dart // lib/src/navigation_bars.dart import 'package:flutter/material.dart'; class CustomNavigationBar extends StatelessWidget { final int currentIndex; final Function(int) onTap; const CustomNavigationBar({ Key? key, required this.currentIndex, required this.onTap, }) : super(key: key); @override Widget build(BuildContext context) { return BottomNavigationBar( currentIndex: currentIndex, onTap: onTap, backgroundColor: Colors.white, selectedItemColor: AppColors.primaryBlue, unselectedItemColor: Colors.grey, items: const [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Icon(Icons.search), label: 'Zoeken', ), BottomNavigationBarItem( icon: Icon(Icons.person), label: 'Profiel', ), ], ); } } ``` --- ### 4. Exporteer alle widgets ```dart // lib/my_ui_library.dart library my_ui_library; export 'src/themes.dart'; export 'src/buttons.dart'; export 'src/input_fields.dart'; export 'src/navigation_bars.dart'; ``` --- ### 5. Gebruik in je app ```dart import 'package:flutter/material.dart'; import 'package:my_ui_library/my_ui_library.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( theme: AppTheme.theme, home: HomePage(), ); } } class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int _currentIndex = 0; final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('Mijn App')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ CustomTextField( hintText: 'Voer tekst in', controller: _controller, ), SizedBox(height: 16), CustomButton( label: 'Klik mij', onPressed: () { // actie }, ), ], ), ), bottomNavigationBar: CustomNavigationBar( currentIndex: _currentIndex, onTap: (index) { setState(() { _currentIndex = index; }); }, ), ); } } ``` --- ### 6. Beste praktijken voor documentatie - Voeg een `README.md` toe waarin je de doelen, installatie-instructies en voorbeelden beschrijft. - Documenteer elke widget met docstrings (`///`) die uitleg geven over parameters en gebruik. - Gebruik consistent naamgeving en commentaar. - Overweeg om een voorbeeldproject toe te voegen dat laat zien hoe je de bibliotheek gebruikt. --- ### Samenvatting Door je componenten goed te structureren, thematische ondersteuning te bieden via `ThemeData`, en duidelijke documentatie te schrijven, maak je een onderhoudbare, herbruikbare Flutter bibliotheek die in meerdere projecten makkelijk te integreren is. Wil je dat ik een complete voorbeeldmapje opstel of verdere hulp bij specifieke widgets?
provider: deepseek
model: deepseek-chat
Zeker! Ik help je bij het opzetten van een aangepaste Flutter widgetbibliotheek. Hier is een complete handleiding: ## 📁 Bibliotheekstructuur ``` custom_ui_library/ ├── lib/ │ ├── src/ │ │ ├── widgets/ │ │ │ ├── buttons/ │ │ │ ├── inputs/ │ │ │ ├── navigation/ │ │ │ └── base/ │ │ ├── theme/ │ │ │ ├── app_theme.dart │ │ │ └── color_palette.dart │ │ └── utils/ │ ├── custom_ui_library.dart │ └── example/ ├── pubspec.yaml └── README.md ``` ## 🎨 Thema Definitie **lib/src/theme/color_palette.dart** ```dart class CustomColors { static const Color primaryBlue = Color(0xFF2196F3); static const Color primaryDark = Color(0xFF1976D2); static const Color primaryLight = Color(0xFFBBDEFB); static const Color secondary = Color(0xFF757575); static const Color background = Color(0xFFFAFAFA); } ``` **lib/src/theme/app_theme.dart** ```dart import 'package:flutter/material.dart'; import 'color_palette.dart'; class CustomTheme { static ThemeData get lightTheme { return ThemeData.light().copyWith( primaryColor: CustomColors.primaryBlue, colorScheme: ColorScheme.light( primary: CustomColors.primaryBlue, secondary: CustomColors.secondary, ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: CustomColors.primaryBlue, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), ), ), inputDecorationTheme: InputDecorationTheme( border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide(color: Colors.grey.shade400), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), borderSide: BorderSide(color: CustomColors.primaryBlue, width: 2), ), ), ); } } ``` ## 🔘 Basis Widget Klasse **lib/src/widgets/base/custom_base_widget.dart** ```dart import 'package:flutter/material.dart'; abstract class CustomBaseWidget extends StatelessWidget { const CustomBaseWidget({Key? key}) : super(key: key); // Gemeenschappelijke eigenschappen BorderRadius get defaultBorderRadius => BorderRadius.circular(8.0); EdgeInsets get defaultPadding => const EdgeInsets.all(16.0); @override Widget build(BuildContext context) { return buildWidget(context); } Widget buildWidget(BuildContext context); } ``` ## 🎯 Aangepaste Knoppen **lib/src/widgets/buttons/custom_button.dart** ```dart import 'package:flutter/material.dart'; import '../base/custom_base_widget.dart'; class CustomButton extends CustomBaseWidget { final String text; final VoidCallback? onPressed; final ButtonType type; final bool isLoading; final IconData? icon; const CustomButton({ Key? key, required this.text, required this.onPressed, this.type = ButtonType.primary, this.isLoading = false, this.icon, }) : super(key: key); @override Widget buildWidget(BuildContext context) { final theme = Theme.of(context); return ElevatedButton( onPressed: isLoading ? null : onPressed, style: _getButtonStyle(theme), child: isLoading ? SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(theme.colorScheme.onPrimary), ), ) : Row( mainAxisSize: MainAxisSize.min, children: [ if (icon != null) ...[ Icon(icon, size: 18), const SizedBox(width: 8), ], Text( text, style: theme.textTheme.labelLarge?.copyWith( fontWeight: FontWeight.w600, ), ), ], ), ); } ButtonStyle _getButtonStyle(ThemeData theme) { switch (type) { case ButtonType.primary: return ElevatedButton.styleFrom( backgroundColor: theme.primaryColor, shape: RoundedRectangleBorder(borderRadius: defaultBorderRadius), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), ); case ButtonType.secondary: return ElevatedButton.styleFrom( backgroundColor: Colors.transparent, foregroundColor: theme.primaryColor, shape: RoundedRectangleBorder( borderRadius: defaultBorderRadius, side: BorderSide(color: theme.primaryColor), ), padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), ); } } } enum ButtonType { primary, secondary } ``` ## 📝 Tekst Invoer Widget **lib/src/widgets/inputs/custom_text_field.dart** ```dart import 'package:flutter/material.dart'; import '../base/custom_base_widget.dart'; class CustomTextField extends CustomBaseWidget { final String label; final String? hintText; final TextEditingController? controller; final bool obscureText; final TextInputType keyboardType; final String? errorText; final Widget? suffixIcon; final ValueChanged<String>? onChanged; const CustomTextField({ Key? key, required this.label, this.hintText, this.controller, this.obscureText = false, this.keyboardType = TextInputType.text, this.errorText, this.suffixIcon, this.onChanged, }) : super(key: key); @override Widget buildWidget(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), TextField( controller: controller, obscureText: obscureText, keyboardType: keyboardType, onChanged: onChanged, decoration: InputDecoration( hintText: hintText, errorText: errorText, suffixIcon: suffixIcon, border: OutlineInputBorder( borderRadius: defaultBorderRadius, ), ), ), ], ); } } ``` ## 🧭 Navigatie Balk **lib/src/widgets/navigation/custom_bottom_nav_bar.dart** ```dart import 'package:flutter/material.dart'; import '../base/custom_base_widget.dart'; class CustomBottomNavBar extends CustomBaseWidget { final int currentIndex; final ValueChanged<int> onTap; final List<BottomNavItem> items; const CustomBottomNavBar({ Key? key, required this.currentIndex, required this.onTap, required this.items, }) : super(key: key); @override Widget buildWidget(BuildContext context) { return Container( decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: const Offset(0, -2), ), ], ), child: ClipRRect( borderRadius: const BorderRadius.only( topLeft: Radius.circular(16), topRight: Radius.circular(16), ), child: BottomNavigationBar( currentIndex: currentIndex, onTap: onTap, items: items.map((item) => item.toBottomNavigationBarItem()).toList(), type: BottomNavigationBarType.fixed, selectedItemColor: Theme.of(context).primaryColor, unselectedItemColor: Colors.grey.shade600, ), ), ); } } class BottomNavItem { final String label; final IconData icon; final IconData? activeIcon; const BottomNavItem({ required this.label, required this.icon, this.activeIcon, }); BottomNavigationBarItem toBottomNavigationBarItem() { return BottomNavigationBarItem( icon: Icon(icon), activeIcon: Icon(activeIcon ?? icon), label: label, ); } } ``` ## 📦 Hoofd Export Bestand **lib/custom_ui_library.dart** ```dart library custom_ui_library; // Thema export 'src/theme/app_theme.dart'; export 'src/theme/color_palette.dart'; // Widgets export 'src/widgets/buttons/custom_button.dart'; export 'src/widgets/inputs/custom_text_field.dart'; export 'src/widgets/navigation/custom_bottom_nav_bar.dart'; // Utils export 'src/utils/widget_utils.dart'; ``` ## 📋 Pubspec.yaml ```yaml name: custom_ui_library description: Een herbruikbare UI component bibliotheek voor Flutter apps version: 1.0.0 environment: sdk: ">=2.18.0 <4.0.0" flutter: ">=3.0.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 flutter: ``` ## 💡 Gebruik in je App ```dart import 'package:flutter/material.dart'; import 'package:custom_ui_library/custom_ui_library.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Mijn App', theme: CustomTheme.lightTheme, home: const HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Home')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ CustomTextField( label: 'Email', hintText: 'Voer je email in', onChanged: (value) => print(value), ), const SizedBox(height: 20), CustomButton( text: 'Inloggen', onPressed: () => print('Knop geklikt'), icon: Icons.login, ), ], ), ), bottomNavigationBar: CustomBottomNavBar( currentIndex: 0, onTap: (index) => print('Tab: $index'), items: const [ BottomNavItem(label: 'Home', icon: Icons.home), BottomNavItem(label: 'Profiel', icon: Icons.person), ], ), ); } } ``` ## 📚 Documentatie Best Practices **1. Widget Documentatie Voorbeeld:** ```dart /// Een aangepaste knop widget die het Material Design volgt /// met primaire blauwe kleur en afgeronde hoeken. /// /// ## Gebruik /// ```dart /// CustomButton( /// text: 'Klik mij', /// onPressed: () => print('Geklikt!'), /// type: ButtonType.primary, /// ) /// ``` /// /// ## Parameters /// - [text]: De tekst die op de knop wordt weergegeven /// - [onPressed]: Callback functie wanneer de knop wordt ingedrukt /// - [type]: Het type knop (primair of secundair) /// - [isLoading]: Toont een laadindicator wanneer true class CustomButton extends CustomBaseWidget { // ... implementatie } ``` **2. README.md Template:** ```markdown # Custom UI Library Een herbruikbare Flutter widget bibliotheek met Material Design componenten. ## Installatie Voeg toe aan je `pubspec.yaml`: ```yaml dependencies: custom_ui_library: git: url: https://github.com/jouw-username/custom_ui_library ``` ## Gebruik Importeer de bibliotheek: ```dart import 'package:custom_ui_library/custom_ui_library.dart'; ``` ## Beschikbare Widgets - `CustomButton` - Aanpasbare knoppen - `CustomTextField` - Tekst invoer velden - `CustomBottomNavBar` - Navigatie balk ``` ## 🔧 Onderhoud Tips 1. **Versiebeheer**: Gebruik semantische versienummers 2. **Testing**: Schrijf unit tests voor alle widgets 3. **Documentatie**: Houd documentatie up-to-date 4. **Breaking Changes**: Gebruik `deprecated` annotatie voor wijzigingen 5. **Voorbeelden**: Zorg voor een uitgebreid voorbeeld project Deze structuur zorgt voor een schaalbare, onderhoudbare bibliotheek die eenvoudig in meerdere projecten kan worden geïntegreerd!
error: Generation failed [deepseek] prompt_id=4902 locale=en err=DeepSeek connection/timeout | Generation failed [deepseek] prompt_id=4902 locale=es err=DeepSeek connection/timeout