Skip to main content

chronova_picker 1.0.2 copy "chronova_picker: ^1.0.2" to clipboard
chronova_picker: ^1.0.2 copied to clipboard

A premium, highly customizable date & time picker system for Flutter with a shared selection engine across all picker modes.

example/lib/main.dart

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)),
        ),
      );
}
1
likes
160
points
127
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A premium, highly customizable date & time picker system for Flutter with a shared selection engine across all picker modes.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on chronova_picker