flutter_indian_utils 0.1.1
flutter_indian_utils: ^0.1.1 copied to clipboard
A comprehensive utility package for Indian developers. Includes validators, formatters, and converters for PAN, Aadhaar, GSTIN, mobile numbers, currency, and more.
import 'package:flutter/material.dart';
import 'package:flutter_indian_utils/flutter_indian_utils.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Indian Utils Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const DemoPage(),
);
}
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
final _panController = TextEditingController();
final _mobileController = TextEditingController();
final _amountController = TextEditingController();
final _vehicleController = TextEditingController();
String _panResult = '';
String _mobileResult = '';
String _formattedAmount = '';
String _amountInWords = '';
String _vehicleResult = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Indian Utils Demo'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
// PAN Validator
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'PAN Validator',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
TextField(
controller: _panController,
decoration: const InputDecoration(
labelText: 'Enter PAN',
hintText: 'ABCDE1234F',
border: OutlineInputBorder(),
),
textCapitalization: TextCapitalization.characters,
onChanged: (value) {
setState(() {
final isValid = IndianValidators.validatePAN(value);
_panResult = isValid
? '✅ Valid PAN\nFormatted: ${IndianFormatters.formatPAN(value)}'
: '❌ Invalid PAN';
});
},
),
const SizedBox(height: 8),
Text(
_panResult,
style: TextStyle(
color: _panResult.startsWith('✅') ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
const SizedBox(height: 16),
// Mobile Validator & Formatter
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Mobile Number',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
TextField(
controller: _mobileController,
decoration: const InputDecoration(
labelText: 'Enter Mobile',
hintText: '9876543210',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.phone,
onChanged: (value) {
setState(() {
final isValid = IndianValidators.validateMobile(value);
_mobileResult = isValid
? '✅ Valid Mobile\nFormatted: ${IndianFormatters.formatMobile(value)}'
: '❌ Invalid Mobile';
});
},
),
const SizedBox(height: 8),
Text(
_mobileResult,
style: TextStyle(
color: _mobileResult.startsWith('✅') ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
const SizedBox(height: 16),
// Currency Formatter
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Currency Formatter',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
TextField(
controller: _amountController,
decoration: const InputDecoration(
labelText: 'Enter Amount',
hintText: '150000',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
onChanged: (value) {
final amount = double.tryParse(value);
setState(() {
if (amount != null) {
_formattedAmount = IndianFormatters.formatCurrency(amount);
_amountInWords = IndianFormatters.amountToWords(amount);
} else {
_formattedAmount = '';
_amountInWords = '';
}
});
},
),
const SizedBox(height: 12),
if (_formattedAmount.isNotEmpty) ...[
Text(
'Formatted: $_formattedAmount',
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text(
'In Words: $_amountInWords',
style: const TextStyle(fontSize: 14, fontStyle: FontStyle.italic),
),
],
],
),
),
),
const SizedBox(height: 16),
// Vehicle Number
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Vehicle Number',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
TextField(
controller: _vehicleController,
decoration: const InputDecoration(
labelText: 'Enter Vehicle Number',
hintText: 'MH12AB1234',
border: OutlineInputBorder(),
),
textCapitalization: TextCapitalization.characters,
onChanged: (value) {
setState(() {
final isValid = IndianValidators.validateVehicleNumber(value);
_vehicleResult = isValid
? '✅ Valid Vehicle Number\nFormatted: ${IndianFormatters.formatVehicleNumber(value)}'
: '❌ Invalid Vehicle Number';
});
},
),
const SizedBox(height: 8),
Text(
_vehicleResult,
style: TextStyle(
color: _vehicleResult.startsWith('✅') ? Colors.green : Colors.red,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
const SizedBox(height: 16),
// State Selector
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Indian States',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
DropdownButtonFormField<String>(
decoration: const InputDecoration(
labelText: 'Select State',
border: OutlineInputBorder(),
),
items: IndianConstants.stateCodes.map((code) {
return DropdownMenuItem(
value: code,
child: Text('$code - ${IndianConstants.getStateName(code)}'),
);
}).toList(),
onChanged: (value) {},
),
],
),
),
),
const SizedBox(height: 16),
// Quick Examples
Card(
color: Colors.blue.shade50,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Quick Examples',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
_buildExample('PAN Formatting',
IndianFormatters.formatPAN('ABCDE1234F')),
_buildExample('Aadhaar Formatting',
IndianFormatters.formatAadhaar('123456789012')),
_buildExample('Number to Words',
IndianFormatters.numberToWords(1234567)),
_buildExample('State from Code',
IndianConstants.getStateName('MH') ?? 'N/A'),
_buildExample('Date Formatting',
IndianFormatters.formatDateIndian(DateTime.now())),
_buildExample('Time Formatting',
IndianFormatters.formatTimeIndian(DateTime.now())),
],
),
),
),
],
),
);
}
Widget _buildExample(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Expanded(
flex: 2,
child: Text(
'$label:',
style: const TextStyle(fontWeight: FontWeight.w500),
),
),
Expanded(
flex: 3,
child: Text(
value,
style: const TextStyle(color: Colors.blue),
),
),
],
),
);
}
@override
void dispose() {
_panController.dispose();
_mobileController.dispose();
_amountController.dispose();
_vehicleController.dispose();
super.dispose();
}
}