chronova_picker 1.0.1
chronova_picker: ^1.0.1 copied to clipboard
A premium, highly customizable date & time picker system for Flutter with a shared selection engine across all picker modes.
import "package:chronova_picker/chronova_picker.dart";
import "package:flutter/material.dart";
void main() => runApp(const ChronovaExampleApp());
class ChronovaExampleApp extends StatelessWidget {
const ChronovaExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "chronova_picker example",
theme: ThemeData(colorSchemeSeed: const Color(0xFF3B5BFD), useMaterial3: true),
darkTheme: ThemeData(
colorSchemeSeed: const Color(0xFF3B5BFD),
brightness: Brightness.dark,
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool _darkMode = false;
String _status = "No selection yet.";
ChronovaThemeData get _chronovaTheme => ChronovaThemeData.fromSeed(
seedColor: const Color(0xFF3B5BFD),
brightness: _darkMode ? Brightness.dark : Brightness.light,
);
Future<void> _pickDate() async {
final ChronovaDateResult? result = await ChronovaPicker.pickDate(
context: context,
initialDate: DateTime.now(),
minimumDate: DateTime.now().subtract(const Duration(days: 365)),
maximumDate: DateTime.now().add(const Duration(days: 365 * 2)),
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked date: ${result.date}");
}
}
Future<void> _pickDateWheel() async {
final ChronovaDateResult? result = await ChronovaPicker.pickDate(
context: context,
style: ChronovaDatePickerStyle.wheel,
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked date (wheel): ${result.date}");
}
}
Future<void> _pickRange() async {
final ChronovaDateRangeResult? result = await ChronovaPicker.pickDateRange(
context: context,
minimumDate: DateTime.now(),
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked range: ${result.start} -> ${result.end}");
}
}
Future<void> _pickTimeClock() async {
final ChronovaTimeResult? result = await ChronovaPicker.pickTime(
context: context,
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked time: $result");
}
}
Future<void> _pickTimeWheel() async {
final ChronovaTimeResult? result = await ChronovaPicker.pickTime(
context: context,
style: ChronovaTimePickerStyle.wheel,
minuteInterval: 5,
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked time (wheel): $result");
}
}
Future<void> _pickDialog() async {
final ChronovaDateResult? result = await ChronovaPicker.pickDate(
context: context,
presentation: ChronovaPresentation.dialog,
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked (dialog): ${result.date}");
}
}
Future<void> _pickBottomSheet() async {
final ChronovaDateResult? result = await ChronovaPicker.pickDate(
context: context,
presentation: ChronovaPresentation.bottomSheet,
theme: _chronovaTheme,
);
if (result != null) {
setState(() => _status = "Picked (bottom sheet): ${result.date}");
}
}
@override
Widget build(BuildContext context) {
return Theme(
data: _darkMode ? ThemeData.dark(useMaterial3: true) : ThemeData.light(useMaterial3: true),
child: Scaffold(
appBar: AppBar(
title: const Text("chronova_picker"),
actions: <Widget>[
IconButton(
icon: Icon(_darkMode ? Icons.light_mode : Icons.dark_mode),
onPressed: () => setState(() => _darkMode = !_darkMode),
),
],
),
body: ListView(
padding: const EdgeInsets.all(16),
children: <Widget>[
Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(_status),
),
),
const SizedBox(height: 16),
const _SectionLabel("Date"),
_ActionButton(label: "Pick Date (calendar)", onPressed: _pickDate),
_ActionButton(label: "Pick Date (wheel)", onPressed: _pickDateWheel),
const SizedBox(height: 16),
const _SectionLabel("Date Range"),
_ActionButton(label: "Pick Date Range", onPressed: _pickRange),
const SizedBox(height: 16),
const _SectionLabel("Time"),
_ActionButton(label: "Pick Time (clock)", onPressed: _pickTimeClock),
_ActionButton(label: "Pick Time (wheel, 5 min)", onPressed: _pickTimeWheel),
const SizedBox(height: 16),
const _SectionLabel("Presentation modes"),
_ActionButton(label: "Force Dialog", onPressed: _pickDialog),
_ActionButton(label: "Force Bottom Sheet", onPressed: _pickBottomSheet),
const SizedBox(height: 16),
const _SectionLabel("Inline (embedded, no modal)"),
Card(
child: Padding(
padding: const EdgeInsets.all(12),
child: ChronovaTheme(
data: _chronovaTheme,
child: ChronovaDatePicker(
showActions: false,
onChanged: (ChronovaDateResult result) {
setState(() => _status = "Inline date: ${result.date}");
},
),
),
),
),
],
),
),
);
}
}
class _SectionLabel extends StatelessWidget {
const _SectionLabel(this.text);
final String text;
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(text, style: Theme.of(context).textTheme.titleMedium),
);
}
class _ActionButton extends StatelessWidget {
const _ActionButton({required this.label, required this.onPressed});
final String label;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.only(bottom: 8),
child: SizedBox(
width: double.infinity,
child: OutlinedButton(onPressed: onPressed, child: Text(label)),
),
);
}