721 lines
14 KiB
Markdown
721 lines
14 KiB
Markdown
# Retail POS App - Widget Documentation
|
|
|
|
## Overview
|
|
This document provides a comprehensive overview of all custom Material 3 widgets created for the Retail POS application.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
1. [Core Widgets](#core-widgets)
|
|
2. [Shared Widgets](#shared-widgets)
|
|
3. [Product Widgets](#product-widgets)
|
|
4. [Category Widgets](#category-widgets)
|
|
5. [Cart/Home Widgets](#carthome-widgets)
|
|
6. [Theme Configuration](#theme-configuration)
|
|
|
|
---
|
|
|
|
## Core Widgets
|
|
|
|
### 1. LoadingIndicator
|
|
**Location:** `/lib/core/widgets/loading_indicator.dart`
|
|
|
|
A Material 3 loading indicator with optional message.
|
|
|
|
**Features:**
|
|
- Customizable size and color
|
|
- Optional loading message
|
|
- Shimmer loading effect for skeleton screens
|
|
- Overlay loading indicator
|
|
|
|
**Usage:**
|
|
```dart
|
|
LoadingIndicator(
|
|
size: 40.0,
|
|
message: 'Loading products...',
|
|
)
|
|
|
|
// Shimmer effect
|
|
ShimmerLoading(
|
|
width: 200,
|
|
height: 20,
|
|
borderRadius: BorderRadius.circular(8),
|
|
)
|
|
|
|
// Overlay loading
|
|
OverlayLoadingIndicator(
|
|
isLoading: true,
|
|
message: 'Processing...',
|
|
child: YourWidget(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 2. EmptyState
|
|
**Location:** `/lib/core/widgets/empty_state.dart`
|
|
|
|
Display empty state with icon, message, and optional action button.
|
|
|
|
**Features:**
|
|
- Customizable icon and messages
|
|
- Optional action button
|
|
- Specialized variants for common scenarios
|
|
|
|
**Variants:**
|
|
- `EmptyProductsState` - For empty product lists
|
|
- `EmptyCategoriesState` - For empty category lists
|
|
- `EmptyCartState` - For empty shopping cart
|
|
- `EmptySearchState` - For no search results
|
|
|
|
**Usage:**
|
|
```dart
|
|
EmptyState(
|
|
icon: Icons.inventory_2_outlined,
|
|
title: 'No Products Found',
|
|
message: 'There are no products available.',
|
|
actionLabel: 'Refresh',
|
|
onAction: () => refreshProducts(),
|
|
)
|
|
|
|
// Or use specialized variants
|
|
EmptyProductsState(onRefresh: () => refresh())
|
|
```
|
|
|
|
---
|
|
|
|
### 3. CustomErrorWidget
|
|
**Location:** `/lib/core/widgets/error_widget.dart`
|
|
|
|
Error display widget with retry functionality.
|
|
|
|
**Features:**
|
|
- Customizable error messages
|
|
- Retry button
|
|
- Different error types
|
|
|
|
**Variants:**
|
|
- `NetworkErrorWidget` - For network errors
|
|
- `ServerErrorWidget` - For server errors
|
|
- `DataErrorWidget` - For data errors
|
|
|
|
**Usage:**
|
|
```dart
|
|
CustomErrorWidget(
|
|
title: 'Something went wrong',
|
|
message: 'Please try again',
|
|
onRetry: () => retryOperation(),
|
|
)
|
|
|
|
// Or use specialized variants
|
|
NetworkErrorWidget(onRetry: () => retry())
|
|
```
|
|
|
|
---
|
|
|
|
### 4. CustomButton
|
|
**Location:** `/lib/core/widgets/custom_button.dart`
|
|
|
|
Material 3 button with loading state support.
|
|
|
|
**Features:**
|
|
- Multiple button types (primary, secondary, outlined, text)
|
|
- Loading state
|
|
- Optional icon
|
|
- Full width option
|
|
|
|
**Usage:**
|
|
```dart
|
|
CustomButton(
|
|
label: 'Add to Cart',
|
|
icon: Icons.shopping_cart,
|
|
onPressed: () => addToCart(),
|
|
isLoading: false,
|
|
isFullWidth: true,
|
|
type: ButtonType.primary,
|
|
)
|
|
|
|
// FAB with badge
|
|
CustomFAB(
|
|
icon: Icons.shopping_cart,
|
|
onPressed: () => viewCart(),
|
|
badgeCount: 5,
|
|
tooltip: 'View cart',
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Shared Widgets
|
|
|
|
### 5. PriceDisplay
|
|
**Location:** `/lib/shared/widgets/price_display.dart`
|
|
|
|
Display formatted prices with currency symbols.
|
|
|
|
**Features:**
|
|
- Currency symbol customization
|
|
- Decimal control
|
|
- Custom styling
|
|
- Strike-through variant for discounts
|
|
|
|
**Usage:**
|
|
```dart
|
|
PriceDisplay(
|
|
price: 99.99,
|
|
currencySymbol: '\$',
|
|
showDecimals: true,
|
|
color: Colors.blue,
|
|
)
|
|
|
|
// Strike-through price
|
|
StrikeThroughPrice(
|
|
price: 129.99,
|
|
currencySymbol: '\$',
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 6. AppBottomNav
|
|
**Location:** `/lib/shared/widgets/app_bottom_nav.dart`
|
|
|
|
Material 3 bottom navigation bar with badge support.
|
|
|
|
**Features:**
|
|
- 4 tabs: POS, Products, Categories, Settings
|
|
- Cart item count badge
|
|
- Navigation rail for larger screens
|
|
- Responsive navigation wrapper
|
|
|
|
**Usage:**
|
|
```dart
|
|
AppBottomNav(
|
|
currentIndex: 0,
|
|
onTabChanged: (index) => handleTabChange(index),
|
|
cartItemCount: 3,
|
|
)
|
|
|
|
// Navigation rail for tablets
|
|
AppNavigationRail(
|
|
currentIndex: 0,
|
|
onTabChanged: (index) => handleTabChange(index),
|
|
cartItemCount: 3,
|
|
extended: true,
|
|
)
|
|
|
|
// Responsive wrapper
|
|
ResponsiveNavigation(
|
|
currentIndex: 0,
|
|
onTabChanged: (index) => handleTabChange(index),
|
|
cartItemCount: 3,
|
|
child: YourContent(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 7. CustomAppBar
|
|
**Location:** `/lib/shared/widgets/custom_app_bar.dart`
|
|
|
|
Customizable Material 3 app bar.
|
|
|
|
**Variants:**
|
|
- `CustomAppBar` - Standard app bar
|
|
- `SearchAppBar` - App bar with search functionality
|
|
- `ModalAppBar` - Compact app bar for modals
|
|
- `AppBarActionWithBadge` - Action button with badge
|
|
|
|
**Usage:**
|
|
```dart
|
|
CustomAppBar(
|
|
title: 'Products',
|
|
actions: [
|
|
IconButton(icon: Icon(Icons.filter_list), onPressed: () {}),
|
|
],
|
|
)
|
|
|
|
// Search app bar
|
|
SearchAppBar(
|
|
title: 'Products',
|
|
searchHint: 'Search products...',
|
|
onSearchChanged: (query) => search(query),
|
|
)
|
|
|
|
// App bar action with badge
|
|
AppBarActionWithBadge(
|
|
icon: Icons.shopping_cart,
|
|
onPressed: () => viewCart(),
|
|
badgeCount: 5,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 8. BadgeWidget
|
|
**Location:** `/lib/shared/widgets/badge_widget.dart`
|
|
|
|
Material 3 badges for various purposes.
|
|
|
|
**Variants:**
|
|
- `BadgeWidget` - General purpose badge
|
|
- `StatusBadge` - Status indicators (success, warning, error, info, neutral)
|
|
- `CountBadge` - Number display badge
|
|
- `NotificationBadge` - Simple dot badge
|
|
|
|
**Usage:**
|
|
```dart
|
|
BadgeWidget(
|
|
count: 5,
|
|
child: Icon(Icons.notifications),
|
|
)
|
|
|
|
StatusBadge(
|
|
label: 'Low Stock',
|
|
type: StatusBadgeType.warning,
|
|
icon: Icons.warning,
|
|
)
|
|
|
|
CountBadge(count: 10)
|
|
|
|
NotificationBadge(
|
|
show: true,
|
|
child: Icon(Icons.notifications),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Product Widgets
|
|
|
|
### 9. ProductCard
|
|
**Location:** `/lib/features/products/presentation/widgets/product_card.dart`
|
|
|
|
Material 3 product card for grid display.
|
|
|
|
**Features:**
|
|
- Product image with caching
|
|
- Product name (2 lines max with ellipsis)
|
|
- Price display with currency
|
|
- Stock status badge (low stock/out of stock)
|
|
- Category badge
|
|
- Add to cart button
|
|
- Ripple effect
|
|
- Responsive sizing
|
|
|
|
**Usage:**
|
|
```dart
|
|
ProductCard(
|
|
id: '1',
|
|
name: 'Premium Coffee Beans',
|
|
price: 24.99,
|
|
imageUrl: 'https://example.com/image.jpg',
|
|
categoryName: 'Beverages',
|
|
stockQuantity: 5,
|
|
isAvailable: true,
|
|
onTap: () => viewProduct(),
|
|
onAddToCart: () => addToCart(),
|
|
currencySymbol: '\$',
|
|
)
|
|
|
|
// Compact variant
|
|
CompactProductCard(
|
|
id: '1',
|
|
name: 'Premium Coffee Beans',
|
|
price: 24.99,
|
|
imageUrl: 'https://example.com/image.jpg',
|
|
onTap: () => viewProduct(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 10. ProductGrid
|
|
**Location:** `/lib/features/products/presentation/widgets/product_grid.dart`
|
|
|
|
Responsive grid layout for products.
|
|
|
|
**Features:**
|
|
- Adaptive column count (2-5 columns)
|
|
- RepaintBoundary for performance
|
|
- Customizable spacing
|
|
- Pull-to-refresh variant
|
|
- Sliver variant for CustomScrollView
|
|
|
|
**Responsive Breakpoints:**
|
|
- Mobile portrait: 2 columns
|
|
- Mobile landscape: 3 columns
|
|
- Tablet portrait: 3-4 columns
|
|
- Tablet landscape/Desktop: 4-5 columns
|
|
|
|
**Usage:**
|
|
```dart
|
|
ProductGrid(
|
|
products: productWidgets,
|
|
childAspectRatio: 0.75,
|
|
crossAxisSpacing: 12,
|
|
mainAxisSpacing: 12,
|
|
)
|
|
|
|
// With pull-to-refresh
|
|
RefreshableProductGrid(
|
|
products: productWidgets,
|
|
onRefresh: () => refreshProducts(),
|
|
)
|
|
|
|
// Sliver variant
|
|
SliverProductGrid(
|
|
products: productWidgets,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 11. ProductSearchBar
|
|
**Location:** `/lib/features/products/presentation/widgets/product_search_bar.dart`
|
|
|
|
Search bar with debouncing.
|
|
|
|
**Features:**
|
|
- 300ms debouncing
|
|
- Clear button
|
|
- Optional filter button
|
|
- Customizable hint text
|
|
|
|
**Usage:**
|
|
```dart
|
|
ProductSearchBar(
|
|
initialQuery: '',
|
|
onSearchChanged: (query) => search(query),
|
|
hintText: 'Search products...',
|
|
debounceDuration: Duration(milliseconds: 300),
|
|
)
|
|
|
|
// With filter
|
|
ProductSearchBarWithFilter(
|
|
onSearchChanged: (query) => search(query),
|
|
onFilterTap: () => showFilters(),
|
|
hasActiveFilters: true,
|
|
)
|
|
|
|
// Compact variant
|
|
CompactSearchField(
|
|
onSearchChanged: (query) => search(query),
|
|
hintText: 'Search...',
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Category Widgets
|
|
|
|
### 12. CategoryCard
|
|
**Location:** `/lib/features/categories/presentation/widgets/category_card.dart`
|
|
|
|
Material 3 category card with custom colors.
|
|
|
|
**Features:**
|
|
- Category icon/image
|
|
- Category name
|
|
- Product count badge
|
|
- Custom background color
|
|
- Selection state
|
|
- Hero animation ready
|
|
- Contrasting text color calculation
|
|
|
|
**Usage:**
|
|
```dart
|
|
CategoryCard(
|
|
id: '1',
|
|
name: 'Electronics',
|
|
productCount: 45,
|
|
imageUrl: 'https://example.com/image.jpg',
|
|
iconPath: 'electronics',
|
|
backgroundColor: Colors.blue,
|
|
isSelected: false,
|
|
onTap: () => selectCategory(),
|
|
)
|
|
|
|
// Category chip
|
|
CategoryChip(
|
|
id: '1',
|
|
name: 'Electronics',
|
|
isSelected: true,
|
|
onTap: () => selectCategory(),
|
|
)
|
|
|
|
// Horizontal chip list
|
|
CategoryChipList(
|
|
categories: categoryData,
|
|
selectedCategoryId: '1',
|
|
onCategorySelected: (id) => selectCategory(id),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 13. CategoryGrid
|
|
**Location:** `/lib/features/categories/presentation/widgets/category_grid.dart`
|
|
|
|
Responsive grid layout for categories.
|
|
|
|
**Features:**
|
|
- Adaptive column count (2-5 columns)
|
|
- Square aspect ratio (1:1)
|
|
- Pull-to-refresh variant
|
|
- Sliver variant
|
|
|
|
**Usage:**
|
|
```dart
|
|
CategoryGrid(
|
|
categories: categoryWidgets,
|
|
childAspectRatio: 1.0,
|
|
)
|
|
|
|
// With pull-to-refresh
|
|
RefreshableCategoryGrid(
|
|
categories: categoryWidgets,
|
|
onRefresh: () => refreshCategories(),
|
|
)
|
|
|
|
// Sliver variant
|
|
SliverCategoryGrid(
|
|
categories: categoryWidgets,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Cart/Home Widgets
|
|
|
|
### 14. CartItemCard
|
|
**Location:** `/lib/features/home/presentation/widgets/cart_item_card.dart`
|
|
|
|
Cart item with quantity controls and swipe-to-delete.
|
|
|
|
**Features:**
|
|
- Product thumbnail (60x60)
|
|
- Product name and unit price
|
|
- Quantity controls (+/-)
|
|
- Line total calculation
|
|
- Remove button
|
|
- Swipe-to-delete gesture
|
|
- Max quantity validation
|
|
|
|
**Usage:**
|
|
```dart
|
|
CartItemCard(
|
|
productId: '1',
|
|
productName: 'Premium Coffee Beans',
|
|
price: 24.99,
|
|
quantity: 2,
|
|
imageUrl: 'https://example.com/image.jpg',
|
|
onIncrement: () => incrementQuantity(),
|
|
onDecrement: () => decrementQuantity(),
|
|
onRemove: () => removeFromCart(),
|
|
maxQuantity: 10,
|
|
currencySymbol: '\$',
|
|
)
|
|
|
|
// Compact variant
|
|
CompactCartItem(
|
|
productName: 'Premium Coffee Beans',
|
|
price: 24.99,
|
|
quantity: 2,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
### 15. CartSummary
|
|
**Location:** `/lib/features/home/presentation/widgets/cart_summary.dart`
|
|
|
|
Order summary with checkout button.
|
|
|
|
**Features:**
|
|
- Subtotal display
|
|
- Tax calculation
|
|
- Discount display
|
|
- Total calculation (bold, larger)
|
|
- Checkout button (full width)
|
|
- Loading state support
|
|
|
|
**Usage:**
|
|
```dart
|
|
CartSummary(
|
|
subtotal: 99.99,
|
|
tax: 8.50,
|
|
discount: 10.00,
|
|
currencySymbol: '\$',
|
|
onCheckout: () => processCheckout(),
|
|
isCheckoutEnabled: true,
|
|
isLoading: false,
|
|
)
|
|
|
|
// Compact variant
|
|
CompactCartSummary(
|
|
itemCount: 3,
|
|
total: 98.49,
|
|
onTap: () => viewCart(),
|
|
)
|
|
|
|
// Summary row (reusable component)
|
|
SummaryRow(
|
|
label: 'Subtotal',
|
|
value: '\$99.99',
|
|
isBold: false,
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Theme Configuration
|
|
|
|
### AppTheme
|
|
**Location:** `/lib/core/theme/app_theme.dart`
|
|
|
|
Material 3 theme configuration.
|
|
|
|
**Features:**
|
|
- Light and dark themes
|
|
- Custom color schemes
|
|
- Consistent typography
|
|
- Card styling
|
|
- Button styling
|
|
- Input decoration
|
|
|
|
**Colors:**
|
|
- Primary: `#6750A4`
|
|
- Secondary: `#625B71`
|
|
- Tertiary: `#7D5260`
|
|
- Error: `#B3261E`
|
|
- Success: `#4CAF50`
|
|
- Warning: `#FF9800`
|
|
|
|
**Usage:**
|
|
```dart
|
|
MaterialApp(
|
|
theme: AppTheme.lightTheme,
|
|
darkTheme: AppTheme.darkTheme,
|
|
themeMode: ThemeMode.system,
|
|
home: HomePage(),
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Widget Best Practices
|
|
|
|
### Performance Optimization
|
|
1. **Use const constructors** wherever possible
|
|
2. **RepaintBoundary** around grid items
|
|
3. **Cached network images** for all product/category images
|
|
4. **Debouncing** for search inputs (300ms)
|
|
5. **ListView.builder/GridView.builder** for long lists
|
|
|
|
### Accessibility
|
|
1. All widgets include **semanticsLabel** for screen readers
|
|
2. Proper **tooltip** attributes on buttons
|
|
3. Sufficient **color contrast** for text
|
|
4. **Touch target sizes** meet minimum 48x48 dp
|
|
|
|
### Responsive Design
|
|
1. Adaptive column counts based on screen width
|
|
2. Navigation rail for tablets/desktop
|
|
3. Bottom navigation for mobile
|
|
4. Flexible layouts with Expanded/Flexible
|
|
|
|
### Material 3 Compliance
|
|
1. Uses Material 3 components (NavigationBar, SearchBar, etc.)
|
|
2. Proper elevation and shadows
|
|
3. Rounded corners (8-12px border radius)
|
|
4. Ripple effects on interactive elements
|
|
5. Theme-aware colors
|
|
|
|
---
|
|
|
|
## Import Shortcuts
|
|
|
|
For easier imports, use the barrel exports:
|
|
|
|
```dart
|
|
// Core widgets
|
|
import 'package:retail/core/widgets/widgets.dart';
|
|
|
|
// Shared widgets
|
|
import 'package:retail/shared/widgets/widgets.dart';
|
|
|
|
// Product widgets
|
|
import 'package:retail/features/products/presentation/widgets/widgets.dart';
|
|
|
|
// Category widgets
|
|
import 'package:retail/features/categories/presentation/widgets/widgets.dart';
|
|
|
|
// Cart widgets
|
|
import 'package:retail/features/home/presentation/widgets/widgets.dart';
|
|
```
|
|
|
|
---
|
|
|
|
## Widget Checklist
|
|
|
|
### Core Widgets (4/4)
|
|
- [x] LoadingIndicator (with shimmer and overlay variants)
|
|
- [x] EmptyState (with specialized variants)
|
|
- [x] CustomErrorWidget (with specialized variants)
|
|
- [x] CustomButton (with FAB variant)
|
|
|
|
### Shared Widgets (4/4)
|
|
- [x] PriceDisplay (with strike-through variant)
|
|
- [x] AppBottomNav (with navigation rail and responsive wrapper)
|
|
- [x] CustomAppBar (with search and modal variants)
|
|
- [x] BadgeWidget (with status, count, and notification variants)
|
|
|
|
### Product Widgets (3/3)
|
|
- [x] ProductCard (with compact variant)
|
|
- [x] ProductGrid (with sliver and refreshable variants)
|
|
- [x] ProductSearchBar (with filter and compact variants)
|
|
|
|
### Category Widgets (2/2)
|
|
- [x] CategoryCard (with chip and chip list variants)
|
|
- [x] CategoryGrid (with sliver and refreshable variants)
|
|
|
|
### Cart Widgets (2/2)
|
|
- [x] CartItemCard (with compact variant)
|
|
- [x] CartSummary (with compact variant and summary row)
|
|
|
|
### Theme (1/1)
|
|
- [x] AppTheme (light and dark themes)
|
|
|
|
**Total: 16 main widget components with 30+ variants**
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
To use these widgets in your app:
|
|
|
|
1. **Install dependencies** (already added to pubspec.yaml):
|
|
- cached_network_image
|
|
- flutter_riverpod
|
|
- intl
|
|
|
|
2. **Initialize Hive** for offline storage
|
|
|
|
3. **Create domain models** for Product, Category, CartItem
|
|
|
|
4. **Set up Riverpod providers** for state management
|
|
|
|
5. **Build feature pages** using these widgets
|
|
|
|
6. **Test widgets** with different data states
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
For questions or issues with these widgets, please refer to:
|
|
- Material 3 Guidelines: https://m3.material.io/
|
|
- Flutter Widget Catalog: https://docs.flutter.dev/ui/widgets
|
|
- Cached Network Image: https://pub.dev/packages/cached_network_image
|