tenzor 0.1.0
tenzor: ^0.1.0 copied to clipboard
A comprehensive Flutter utility & UI toolkit containing widgets, utilities, helpers, and integrations for rapid development.
example/lib/main.dart
import 'package:flutter/material.dart';
// Import individual Tenzor components
import 'package:tenzor/tenzor.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tenzor',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const HomePage(),
);
}
}
// Example 7: Chat View Example
class ChatExample extends StatefulWidget {
const ChatExample({super.key});
@override
State<ChatExample> createState() => _ChatExampleState();
}
class _ChatExampleState extends State<ChatExample> {
final TextEditingController _inputController = TextEditingController();
final List<TenzorChatMessage> _messages = [
TenzorChatMessage(
id: '1',
content: 'Hey! How are you doing?',
isSentByMe: false,
timestamp: DateTime.now().subtract(const Duration(minutes: 30)),
senderName: 'Alice',
senderAvatar: 'https://picsum.photos/250?image=9',
),
TenzorChatMessage(
id: '2',
content: 'I\'m doing great! Just working on some new Flutter projects.',
isSentByMe: true,
timestamp: DateTime.now().subtract(const Duration(minutes: 28)),
status: 'read',
),
TenzorChatMessage(
id: '3',
content: 'That sounds awesome! What kind of apps are you building?',
isSentByMe: false,
timestamp: DateTime.now().subtract(const Duration(minutes: 25)),
senderName: 'Alice',
senderAvatar: 'https://picsum.photos/250?image=9',
),
TenzorChatMessage(
id: '4',
content:
'I\'m working on a comprehensive UI toolkit called Tenzor that includes all kinds of widgets like this chat view! 🚀',
isSentByMe: true,
timestamp: DateTime.now().subtract(const Duration(minutes: 20)),
status: 'read',
),
TenzorChatMessage(
id: '5',
content: 'Wow, that\'s really impressive! Can\'t wait to try it out.',
isSentByMe: false,
timestamp: DateTime.now().subtract(const Duration(minutes: 15)),
senderName: 'Alice',
senderAvatar: 'https://picsum.photos/250?image=9',
),
TenzorChatMessage(
id: '6',
content: 'Check out this screenshot I took!',
isSentByMe: true,
timestamp: DateTime.now().subtract(const Duration(minutes: 10)),
attachmentUrl: 'https://picsum.photos/400/300?image=10',
attachmentType: 'image',
status: 'delivered',
),
];
void _handleSendMessage(String message) {
setState(() {
_messages.insert(
0,
TenzorChatMessage(
id: DateTime.now().millisecondsSinceEpoch.toString(),
content: message,
isSentByMe: true,
timestamp: DateTime.now(),
status: 'sending',
));
});
// Simulate message being sent
Future.delayed(const Duration(seconds: 1), () {
setState(() {
final index = _messages.indexWhere((m) => m.status == 'sending');
if (index != -1) {
_messages[index] = TenzorChatMessage(
id: _messages[index].id,
content: _messages[index].content,
isSentByMe: true,
timestamp: _messages[index].timestamp,
status: 'sent',
);
}
});
});
}
@override
Widget build(BuildContext context) {
return TenzorChatView(
messages: _messages,
inputController: _inputController,
onSendMessage: _handleSendMessage,
chatTitle: 'Alice Johnson',
chatSubtitle: 'Online',
chatAvatarUrl: 'https://picsum.photos/250?image=9',
showTypingIndicator: true,
typingUsers: const ['Alice'],
enableReactions: true,
enableReply: true,
enableSelection: true,
sentMessageColor: Colors.blue[700],
receivedMessageColor: Colors.grey[200],
showAvatarsInChat: true,
);
}
}
// Example 6: Splash Screen Example
class SplashExample extends StatelessWidget {
const SplashExample({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TenzorSplash'),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Original animations
const Text('Basic Animations:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 16),
// Scale animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'scale',
title: 'Scale Animation',
),
),
),
child: const Text('Scale Animation'),
),
const SizedBox(height: 12),
// Fade animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'fade',
title: 'Fade Animation',
),
),
),
child: const Text('Fade Animation'),
),
const SizedBox(height: 12),
// Slide animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'slide',
title: 'Slide Animation',
),
),
),
child: const Text('Slide Animation'),
),
const SizedBox(height: 12),
// Rotate animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'rotate',
title: 'Rotate Animation',
),
),
),
child: const Text('Rotate Animation'),
),
const SizedBox(height: 12),
// Bounce animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'bounce',
title: 'Bounce Animation',
),
),
),
child: const Text('Bounce Animation'),
),
const SizedBox(height: 32),
const Text('New Animation Types:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 16),
// Flip animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'flip',
title: 'Flip Animation',
),
),
),
child: const Text('Flip Animation'),
),
const SizedBox(height: 12),
// Pulse animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'pulse',
title: 'Pulse Animation (Looping)',
),
),
),
child: const Text('Pulse Animation'),
),
const SizedBox(height: 12),
// Zoom animation
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DemoSplashScreen(
animationType: 'zoom',
title: 'Zoom Animation',
),
),
),
child: const Text('Zoom Animation'),
),
const SizedBox(height: 32),
const Text('Factory Constructors:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 16),
// Minimalist splash
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MinimalSplashDemo()),
),
child: const Text('Minimalist Splash'),
),
const SizedBox(height: 12),
// Dark theme splash
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DarkSplashDemo()),
),
child: const Text('Dark Theme Splash'),
),
const SizedBox(height: 12),
// Professional splash
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ProfessionalSplashDemo()),
),
child: const Text('Professional Splash'),
),
const SizedBox(height: 12),
// Preloader splash
ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const PreloaderSplashDemo()),
),
child: const Text('Splash with Preloader'),
),
],
),
),
),
);
}
}
// Demo for Minimalist Splash
class MinimalSplashDemo extends StatelessWidget {
const MinimalSplashDemo({super.key});
@override
Widget build(BuildContext context) {
return TenzorSplash.minimal(
duration: const Duration(seconds: 2),
backgroundColor: Colors.white,
logoWidget: const Icon(Icons.flutter_dash, size: 120, color: Colors.blue),
logoAnimationType: 'fade',
onSplashComplete: () => Navigator.pop(context),
);
}
}
// Demo for Dark Theme Splash
class DarkSplashDemo extends StatelessWidget {
const DarkSplashDemo({super.key});
@override
Widget build(BuildContext context) {
return TenzorSplash.dark(
duration: const Duration(seconds: 3),
logoWidget:
const Icon(Icons.flutter_dash, size: 120, color: Colors.white),
logoAnimationType: 'scale',
footerText: 'Dark Theme Splash',
onSplashComplete: () => Navigator.pop(context),
);
}
}
// Demo for Professional Splash
class ProfessionalSplashDemo extends StatelessWidget {
const ProfessionalSplashDemo({super.key});
@override
Widget build(BuildContext context) {
return TenzorSplash.professional(
duration: const Duration(seconds: 4),
primaryColor: Colors.blue,
logoWidget: const Icon(Icons.flutter_dash, size: 150, color: Colors.blue),
versionText: 'Version 1.0.0',
footerCopyright: '© 2024 Tenzor UI. All rights reserved.',
logoAnimationType: 'zoom',
onSplashComplete: () => Navigator.pop(context),
);
}
}
// Demo for Splash with Preloader
class PreloaderSplashDemo extends StatelessWidget {
const PreloaderSplashDemo({super.key});
Future<void> _simulatePreload() async {
// Simulate app initialization tasks
await Future.delayed(const Duration(seconds: 4));
}
@override
Widget build(BuildContext context) {
return TenzorSplash.withPreloader(
minimumDuration: const Duration(seconds: 3),
backgroundColor: Colors.blue,
logoWidget:
const Icon(Icons.flutter_dash, size: 120, color: Colors.white),
preloadFunction: _simulatePreload,
footerText: 'Initializing app...',
onSplashComplete: () => Navigator.pop(context),
);
}
}
// Demo splash screen that shows different animation types
class DemoSplashScreen extends StatelessWidget {
final String title;
final String animationType;
const DemoSplashScreen({
super.key,
required this.title,
required this.animationType,
});
@override
Widget build(BuildContext context) {
return TenzorSplash(
duration: const Duration(seconds: 3),
backgroundGradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Colors.purple, Colors.blue],
),
logoWidget: const Icon(
Icons.flutter_dash,
size: 100,
color: Colors.white,
),
logoSize: const Size(100, 100),
animateLogo: true,
logoAnimationType: animationType,
loopAnimation: animationType == 'pulse', // Loop pulse animation
logoAnimationDuration: const Duration(milliseconds: 1500),
showLoader: true,
footerText: title,
footerTextStyle: const TextStyle(
fontSize: 16,
color: Colors.white70,
fontWeight: FontWeight.w500,
),
onSplashComplete: () {
// Navigate back after splash completes
if (context.mounted) {
Navigator.pop(context);
}
},
);
}
}
// Example 5: Shimmer Layout Example
class ShimmerExample extends StatefulWidget {
const ShimmerExample({super.key});
@override
State<ShimmerExample> createState() => _ShimmerExampleState();
}
class _ShimmerExampleState extends State<ShimmerExample> {
bool _isLoading = true;
void _toggleLoading() {
setState(() {
_isLoading = !_isLoading;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TenzorShimmerLayout'),
actions: [
IconButton(
icon: Icon(_isLoading ? Icons.toggle_on : Icons.toggle_off),
onPressed: _toggleLoading,
tooltip: 'Toggle loading state',
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'List Tile Shimmer',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
// List tile shimmers
TenzorShimmerLayout.listTile(isLoading: _isLoading),
TenzorShimmerLayout.listTile(isLoading: _isLoading),
TenzorShimmerLayout.listTile(isLoading: _isLoading),
const SizedBox(height: 30),
const Text(
'Card Shimmer',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
// Card shimmers
Row(
children: [
Expanded(
child: TenzorShimmerLayout.card(isLoading: _isLoading),
),
Expanded(
child: TenzorShimmerLayout.card(isLoading: _isLoading),
),
],
),
const SizedBox(height: 30),
const Text(
'Grid Item Shimmer',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
// Grid shimmers
GridView.count(
shrinkWrap: true,
crossAxisCount: 2,
children: [
TenzorShimmerLayout.gridItem(isLoading: _isLoading),
TenzorShimmerLayout.gridItem(isLoading: _isLoading),
TenzorShimmerLayout.gridItem(isLoading: _isLoading),
TenzorShimmerLayout.gridItem(isLoading: _isLoading),
],
),
const SizedBox(height: 30),
const Text(
'Custom Direction Shimmer',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
// Custom bottom-to-top shimmer
TenzorShimmerLayout(
isLoading: _isLoading,
direction: 'btt',
duration: const Duration(milliseconds: 2000),
baseColor: Colors.blue[200],
highlightColor: Colors.blue[50],
width: double.infinity,
height: 100,
borderRadius: BorderRadius.circular(12),
child: Container(
decoration: BoxDecoration(
color: Colors.blue[200],
borderRadius: BorderRadius.circular(12),
),
child: const Center(
child: Text('Bottom-to-top shimmer (Custom colors)'),
),
),
),
],
),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Tenzor')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const BottomNavExample()),
child: const Text('Bottom Navigation'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const TabBarExample()),
child: const Text('Tab Bar'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const VideoPlayerExample()),
child: const Text('Video Player'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const AnimatedNavExample()),
child: const Text('Animated Navigation'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const ShimmerExample()),
child: const Text('Shimmer Layout'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const SplashExample()),
child: const Text('Splash Screen'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () =>
TenzorNavigation.push(context, const ChatExample()),
child: const Text('Chat View'),
),
],
),
),
);
}
}
// Example 1: Bottom Navigation with Badges
class BottomNavExample extends StatelessWidget {
const BottomNavExample({super.key});
@override
Widget build(BuildContext context) {
return TenzorNavigationScaffold(
initialIndex: 0,
appBar: TenzorAppBar(
title: const Text('Bottom Navigation with Badges'),
),
items: [
TenzorNavigationItem(
icon: Icons.home,
label: 'Home',
page: const Center(child: Text('Home Page')),
),
TenzorNavigationItem(
icon: Icons.search,
label: 'Search',
page: const Center(child: Text('Search Page')),
),
TenzorNavigationItem(
icon: Icons.notifications,
label: 'Notifications',
page: const Center(child: Text('Notifications Page')),
showBadge: true,
badgeLabel: '3',
badgeColor: Colors.red,
),
TenzorNavigationItem(
icon: Icons.person,
label: 'Profile',
page: const Center(child: Text('Profile Page')),
),
],
selectedItemColor: Colors.blue,
unselectedItemColor: Colors.grey,
navigationBackgroundColor: Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
);
}
}
// Example 2: Tab Bar Example
class TabBarExample extends StatelessWidget {
const TabBarExample({super.key});
@override
Widget build(BuildContext context) {
return TenzorTabScaffold(
initialIndex: 0,
items: [
TenzorTabItem(
label: 'Chats',
icon: Icons.chat,
page: const Center(child: Text('Chats Page')),
showBadge: true,
badgeLabel: '5',
),
TenzorTabItem(
label: 'Calls',
icon: Icons.call,
page: const Center(child: Text('Calls Page')),
),
TenzorTabItem(
label: 'Settings',
icon: Icons.settings,
page: const Center(child: Text('Settings Page')),
),
],
labelColor: Colors.blue,
unselectedLabelColor: Colors.grey,
indicatorColor: Colors.blue,
);
}
}
// Example 3: Modern TenzorVideoPlayer Example
class VideoPlayerExample extends StatelessWidget {
const VideoPlayerExample({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('TenzorVideoPlayer')),
body: Center(
child: Column(
children: [
const SizedBox(height: 30),
// Modern TenzorVideoPlayer with all features
SizedBox(
height: 300,
child: TenzorVideoPlayer(
url:
'https://www.w3schools.com/html/mov_bbb.mp4', // Sample video
autoPlay: false,
looping: true,
showControls: true,
allowFullscreen: true,
allowPlaybackSpeed: true,
progressIndicatorColor: Colors.teal,
backgroundColor: Colors.black,
controlsBackgroundColor: Colors.black.withValues(alpha: 0.8),
playPauseIconColor: Colors.teal,
playPauseIconSize: 60,
durationTextColor: Colors.white70,
durationTextSize: 13,
fullscreenIconColor: Colors.white70,
speedTextColor: Colors.teal,
speedTextSize: 14,
speedSelectorActiveColor: Colors.teal,
speedSelectorInactiveColor: Colors.grey[800],
onCompleted: () {
TenzorSnackbar.success(context, 'Video completed!');
},
onError: () {
TenzorSnackbar.error(context, 'Error loading video');
},
onPlayStateChanged: (isPlaying) {
print('Video is playing: $isPlaying');
},
),
),
const SizedBox(height: 30),
const Text(
'Modern TenzorVideoPlayer Features:',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
const Text('• Fullscreen support'),
const Text('• Playback speed controls'),
const Text('• Customizable colors'),
const Text('• Error handling'),
const Text('• Callback support'),
],
),
),
);
}
}
// Example 4: Animated Navigation Example
class AnimatedNavExample extends StatelessWidget {
const AnimatedNavExample({super.key});
@override
Widget build(BuildContext context) {
return TenzorAnimatedNavigationScaffold(
initialIndex: 0,
appBar: TenzorAppBar(
title: const Text('Animated Navigation'),
),
items: [
TenzorAnimatedNavigationItem(
icon: Icons.home,
label: 'Home',
page: const Center(child: Text('Home Page - Slide Animation')),
),
TenzorAnimatedNavigationItem(
icon: Icons.explore,
label: 'Explore',
page: const Center(child: Text('Explore Page - Scale Animation')),
),
TenzorAnimatedNavigationItem(
icon: Icons.favorite,
label: 'Likes',
page: const Center(child: Text('Likes Page')),
showBadge: true,
badgeLabel: '12',
badgeColor: Colors.pink,
),
TenzorAnimatedNavigationItem(
icon: Icons.person,
label: 'Profile',
page: const Center(child: Text('Profile Page - Fade Animation')),
),
],
selectedItemColor: Colors.purple,
unselectedItemColor: Colors.grey,
navigationBackgroundColor: Colors.white,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(25),
topRight: Radius.circular(25),
),
pageTransitionDuration: const Duration(milliseconds: 400),
pageTransitionCurve: Curves.easeInOutCubic,
pageTransitionType:
'slide', // Try other types: 'fade', 'scale', 'rotate', 'size'
animateNavigationBar: true,
navigationBarAnimationDuration: const Duration(milliseconds: 250),
showSplashAnimation: true,
splashColor: Colors.purple,
);
}
}