405 lines
7.2 KiB
Markdown
405 lines
7.2 KiB
Markdown
# UI Components Library
|
|
|
|
Koleksi komponen UI yang reusable untuk aplikasi HydroNutrify.
|
|
|
|
## 📁 Struktur
|
|
|
|
```
|
|
ui/shared/components/
|
|
├── custom_button.dart # Button components
|
|
├── custom_textfield.dart # Text input components
|
|
├── custom_card.dart # Card & container components
|
|
├── custom_dialog.dart # Dialog & bottom sheet
|
|
├── custom_switch.dart # Switch, checkbox, radio
|
|
├── custom_appbar.dart # AppBar components
|
|
├── loading_indicator.dart # Loading states
|
|
├── empty_state.dart # Empty states
|
|
├── error_widget.dart # Error handling
|
|
├── status_badge.dart # Status & notification badges
|
|
├── section_header.dart # Section headers & dividers
|
|
└── components.dart # Barrel export file
|
|
```
|
|
|
|
## 🎨 Komponen
|
|
|
|
### 1. **CustomButton**
|
|
Button dengan berbagai jenis dan ukuran.
|
|
|
|
```dart
|
|
// Primary Button
|
|
CustomButton(
|
|
text: 'Login',
|
|
onPressed: () {},
|
|
isLoading: false,
|
|
type: ButtonType.primary,
|
|
size: ButtonSize.medium,
|
|
)
|
|
|
|
// Secondary Button with Icon
|
|
CustomButton(
|
|
text: 'Save',
|
|
icon: Icons.save,
|
|
type: ButtonType.secondary,
|
|
onPressed: () {},
|
|
)
|
|
|
|
// Danger Button
|
|
CustomButton(
|
|
text: 'Delete',
|
|
type: ButtonType.danger,
|
|
onPressed: () {},
|
|
)
|
|
```
|
|
|
|
**ButtonType**: `primary`, `secondary`, `text`, `danger`
|
|
**ButtonSize**: `small`, `medium`, `large`
|
|
|
|
---
|
|
|
|
### 2. **CustomTextField**
|
|
Text input field dengan fitur lengkap.
|
|
|
|
```dart
|
|
CustomTextField(
|
|
controller: emailController,
|
|
labelText: 'Email',
|
|
hintText: 'Enter your email',
|
|
prefixIcon: Icons.email,
|
|
keyboardType: TextInputType.emailAddress,
|
|
validator: (value) => value?.isEmpty == true ? 'Required' : null,
|
|
)
|
|
|
|
// Password Field dengan toggle
|
|
CustomTextField(
|
|
controller: passwordController,
|
|
labelText: 'Password',
|
|
obscureText: true,
|
|
showPasswordToggle: true,
|
|
prefixIcon: Icons.lock,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 3. **CustomCard**
|
|
Card container yang fleksibel.
|
|
|
|
```dart
|
|
// Basic Card
|
|
CustomCard(
|
|
child: Text('Content'),
|
|
padding: EdgeInsets.all(16),
|
|
elevation: 2,
|
|
)
|
|
|
|
// Stat Card
|
|
StatCard(
|
|
title: 'Total Users',
|
|
value: '1,234',
|
|
subtitle: '+12% from last month',
|
|
icon: Icons.people,
|
|
iconColor: AppColors.primary,
|
|
)
|
|
|
|
// Info Card
|
|
InfoCard(
|
|
title: 'Update Available',
|
|
description: 'Version 2.0 is ready to install',
|
|
icon: Icons.system_update,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 4. **LoadingIndicator**
|
|
Loading states dengan berbagai variasi.
|
|
|
|
```dart
|
|
// Simple Loading
|
|
LoadingIndicator(
|
|
size: 40,
|
|
message: 'Loading...',
|
|
)
|
|
|
|
// Overlay Loading
|
|
OverlayLoading(
|
|
message: 'Processing...',
|
|
)
|
|
|
|
// Shimmer Loading
|
|
ShimmerLoading(
|
|
width: 200,
|
|
height: 20,
|
|
borderRadius: BorderRadius.circular(8),
|
|
)
|
|
|
|
// Linear Progress
|
|
CustomLinearProgress(
|
|
value: 0.6,
|
|
height: 4,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 5. **EmptyState**
|
|
Widget untuk menampilkan empty state.
|
|
|
|
```dart
|
|
// Custom Empty State
|
|
EmptyState(
|
|
title: 'No Data Found',
|
|
message: 'Try adding some items first',
|
|
icon: Icons.inbox_outlined,
|
|
actionText: 'Add Item',
|
|
onAction: () {},
|
|
)
|
|
|
|
// No Data Widget
|
|
NoDataWidget(
|
|
message: 'No records available',
|
|
)
|
|
|
|
// No Connection Widget
|
|
NoConnectionWidget(
|
|
onRetry: () {},
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 6. **CustomErrorWidget**
|
|
Error handling dan display.
|
|
|
|
```dart
|
|
// Error Widget
|
|
CustomErrorWidget(
|
|
title: 'Something went wrong',
|
|
message: 'Please try again later',
|
|
type: ErrorType.general,
|
|
actionText: 'Retry',
|
|
onAction: () {},
|
|
)
|
|
|
|
// Error Snackbar
|
|
ErrorSnackbar.show(
|
|
context,
|
|
'Failed to load data',
|
|
type: ErrorType.network,
|
|
)
|
|
|
|
// Success Snackbar
|
|
SuccessSnackbar.show(
|
|
context,
|
|
'Data saved successfully',
|
|
)
|
|
```
|
|
|
|
**ErrorType**: `general`, `network`, `notFound`, `permission`, `timeout`
|
|
|
|
---
|
|
|
|
### 7. **CustomDialog**
|
|
Dialog dan bottom sheet.
|
|
|
|
```dart
|
|
// Confirmation Dialog
|
|
final result = await CustomDialog.showConfirmation(
|
|
context: context,
|
|
title: 'Delete Item',
|
|
message: 'Are you sure?',
|
|
confirmText: 'Delete',
|
|
isDangerous: true,
|
|
);
|
|
|
|
// Info Dialog
|
|
await CustomDialog.showInfo(
|
|
context: context,
|
|
title: 'Information',
|
|
message: 'Operation completed successfully',
|
|
);
|
|
|
|
// Loading Dialog
|
|
CustomDialog.showLoading(context, message: 'Saving...');
|
|
Navigator.pop(context); // Close when done
|
|
|
|
// Bottom Sheet
|
|
await CustomBottomSheet.show(
|
|
context: context,
|
|
title: 'Select Option',
|
|
child: YourWidget(),
|
|
height: 300,
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
### 8. **Form Controls**
|
|
Switch, checkbox, dan radio buttons.
|
|
|
|
```dart
|
|
// Custom Switch
|
|
CustomSwitch(
|
|
value: isEnabled,
|
|
onChanged: (value) {},
|
|
)
|
|
|
|
// Labeled Switch
|
|
LabeledSwitch(
|
|
label: 'Enable Notifications',
|
|
description: 'Receive updates and alerts',
|
|
value: isEnabled,
|
|
icon: Icons.notifications,
|
|
onChanged: (value) {},
|
|
)
|
|
|
|
// Labeled Checkbox
|
|
LabeledCheckbox(
|
|
label: 'I agree to terms',
|
|
value: isAgreed,
|
|
onChanged: (value) {},
|
|
)
|
|
|
|
// Labeled Radio
|
|
LabeledRadio<String>(
|
|
label: 'Option 1',
|
|
value: 'option1',
|
|
initialGroupValue: selectedOption,
|
|
onChanged: (value) {},
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 9. **StatusBadge**
|
|
Status dan notification badges.
|
|
|
|
```dart
|
|
// Success Badge
|
|
StatusBadge.success('Active')
|
|
|
|
// Warning Badge
|
|
StatusBadge.warning('Pending')
|
|
|
|
// Error Badge
|
|
StatusBadge.error('Failed')
|
|
|
|
// Info Badge
|
|
StatusBadge.info('New')
|
|
|
|
// Notification Badge
|
|
NotificationBadge(count: 5)
|
|
|
|
// Dot Badge
|
|
DotBadge(color: AppColors.error)
|
|
```
|
|
|
|
**BadgeSize**: `small`, `medium`, `large`
|
|
|
|
---
|
|
|
|
### 10. **SectionHeader**
|
|
Headers untuk section.
|
|
|
|
```dart
|
|
// Section Header
|
|
SectionHeader(
|
|
title: 'Recent Activity',
|
|
subtitle: 'Last 7 days',
|
|
trailingText: 'See All',
|
|
onTrailingTap: () {},
|
|
showDivider: true,
|
|
)
|
|
|
|
// Simple Section Header
|
|
SimpleSectionHeader(
|
|
title: 'Personal Information',
|
|
)
|
|
|
|
// Icon Section Header
|
|
IconSectionHeader(
|
|
title: 'Settings',
|
|
icon: Icons.settings,
|
|
onTap: () {},
|
|
)
|
|
|
|
// Divider with Text
|
|
DividerWithText(text: 'OR')
|
|
```
|
|
|
|
---
|
|
|
|
### 11. **CustomAppBar**
|
|
AppBar components.
|
|
|
|
```dart
|
|
// Custom AppBar
|
|
CustomAppBar(
|
|
title: 'Home',
|
|
actions: [
|
|
IconButton(
|
|
icon: Icon(Icons.search),
|
|
onPressed: () {},
|
|
),
|
|
],
|
|
)
|
|
|
|
// Custom Tab Bar
|
|
CustomTabBar(
|
|
tabs: [
|
|
Tab(text: 'Tab 1'),
|
|
Tab(text: 'Tab 2'),
|
|
],
|
|
)
|
|
|
|
// Sliver AppBar
|
|
CustomSliverAppBar(
|
|
title: 'Profile',
|
|
expandedHeight: 200,
|
|
flexibleSpace: YourWidget(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## 📦 Cara Penggunaan
|
|
|
|
Import dari barrel file untuk menggunakan semua komponen:
|
|
|
|
```dart
|
|
import 'package:mobile_monitoring/ui/shared/components/components.dart';
|
|
```
|
|
|
|
Atau import spesifik:
|
|
|
|
```dart
|
|
import 'package:mobile_monitoring/ui/shared/components/custom_button.dart';
|
|
import 'package:mobile_monitoring/ui/shared/components/custom_textfield.dart';
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Keuntungan
|
|
|
|
✅ **Konsisten** - Semua komponen menggunakan theme dan colors yang sama
|
|
✅ **Reusable** - Mudah digunakan di seluruh aplikasi
|
|
✅ **Maintainable** - Update sekali, berpengaruh di semua tempat
|
|
✅ **Customizable** - Banyak parameter untuk customisasi
|
|
✅ **Type-safe** - Menggunakan enums untuk parameter
|
|
|
|
---
|
|
|
|
## 🔧 Refactoring yang Sudah Dilakukan
|
|
|
|
1. ✅ **login_form.dart** - Menggunakan CustomTextField, CustomButton, CustomCard
|
|
2. ✅ **register_form.dart** - Menggunakan CustomTextField, CustomButton, CustomCard
|
|
|
|
---
|
|
|
|
## 📝 Todo
|
|
|
|
- [ ] Refactor file-file lain untuk menggunakan komponen baru
|
|
- [ ] Tambah animasi pada komponen
|
|
- [ ] Tambah dark mode support
|
|
- [ ] Tambah accessibility features
|