import 'package:flutter/material.dart'; class DatePickerCanvas extends StatefulWidget { final DateTime? initialDate; const DatePickerCanvas({super.key, this.initialDate}); @override State createState() => _DatePickerCanvasState(); } class _DatePickerCanvasState extends State { late int selectedYear; late int selectedMonth; int? selectedDay; String _currentSelector = 'month'; final List months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]; late final List years; @override void initState() { super.initState(); DateTime now = widget.initialDate ?? DateTime.now(); selectedYear = now.year; selectedMonth = now.month; selectedDay = now.day; years = List.generate(100, (index) => DateTime.now().year - index); } List getCalendarDays() { final firstDay = DateTime(selectedYear, selectedMonth, 1); final lastDay = DateTime(selectedYear, selectedMonth + 1, 0); final daysInMonth = lastDay.day; List days = []; for (int i = 0; i < firstDay.weekday % 7; i++) { days.add(null); } for (int i = 1; i <= daysInMonth; i++) { days.add(DateTime(selectedYear, selectedMonth, i)); } return days; } Widget _buildSelectorWidget() { switch (_currentSelector) { case 'month': return _buildMonthSelector(); case 'year': return _buildYearSelector(); case 'day': return _buildDaySelector(); default: return Container(); } } Widget _buildMonthSelector() { return ListView.builder( itemCount: months.length, itemBuilder: (context, index) { final monthName = months[index]; final monthNumber = index + 1; final isSelected = monthNumber == selectedMonth; return Container( padding: EdgeInsets.only(left: isSelected ? 20 : 0), child: ListTile( leading: isSelected ? const Icon(Icons.check, color: Colors.black) : null, title: Text( monthName, style: const TextStyle(color: Colors.black, fontWeight: FontWeight.bold), ), onTap: () { setState(() { selectedMonth = monthNumber; _currentSelector = 'year'; }); }, ), ); }, ); } Widget _buildYearSelector() { return ListView.builder( itemCount: years.length, itemBuilder: (context, index) { final year = years[index]; final isSelected = year == selectedYear; return Container( padding: EdgeInsets.only(left: isSelected ? 20 : 0), child: ListTile( leading: isSelected ? const Icon(Icons.check, color: Colors.black) : null, title: Text( year.toString(), style: const TextStyle(color: Colors.black, fontWeight: FontWeight.bold), ), onTap: () { setState(() { selectedYear = year; _currentSelector = 'day'; }); }, ), ); }, ); } Widget _buildDaySelector() { final days = getCalendarDays(); final weekDays = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; return Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: weekDays .map((day) => Expanded( child: Center( child: Text( day, style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.black, ), ), ), )) .toList(), ), const SizedBox(height: 10), Expanded( child: GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 7, ), itemCount: days.length, itemBuilder: (context, index) { final date = days[index]; if (date == null) return Container(); final isSelected = date.day == selectedDay; return InkWell( onTap: () { Navigator.pop(context, DateTime(selectedYear, selectedMonth, date.day)); }, child: Container( margin: const EdgeInsets.all(4), decoration: BoxDecoration( color: isSelected ? Colors.blue : Colors.transparent, shape: BoxShape.circle, border: Border.all( color: isSelected ? Colors.blue : Colors.transparent, ), ), child: Center( child: Text( date.day.toString(), style: TextStyle( color: isSelected ? Colors.white : Colors.black, fontWeight: FontWeight.bold, ), ), ), ), ); }, ), ), ], ); } @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: const Color.fromARGB(255, 233, 245, 254), borderRadius: BorderRadius.circular(15), ), padding: const EdgeInsets.all(16), height: MediaQuery.of(context).size.height * 0.6, child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildSelectorButton( label: months[selectedMonth - 1], isActive: _currentSelector == 'month', onTap: () => setState(() => _currentSelector = 'month'), ), _buildSelectorButton( label: selectedYear.toString(), isActive: _currentSelector == 'year', onTap: () => setState(() => _currentSelector = 'year'), ), _buildSelectorButton( label: selectedDay?.toString() ?? 'Day', isActive: _currentSelector == 'day', onTap: () => setState(() => _currentSelector = 'day'), ), ], ), const Divider(color: Colors.grey, height: 32), Expanded(child: _buildSelectorWidget()), ], ), ); } Widget _buildSelectorButton({ required String label, required bool isActive, required VoidCallback onTap, }) { return TextButton( onPressed: onTap, style: TextButton.styleFrom( foregroundColor: Colors.black, ), child: Text( label, style: TextStyle( fontSize: 16, fontWeight: isActive ? FontWeight.bold : FontWeight.normal, color: Colors.black, ), ), ); } }