Skip to main content

ujs_date_picker 0.1.0 copy "ujs_date_picker: ^0.1.0" to clipboard
ujs_date_picker: ^0.1.0 copied to clipboard

Custom date and time pickers. Dates use DD/MM/YYYY. Times use HH:mm.

example/lib/main.dart

import 'package:date_picker/date_picker.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const DatePickerExampleApp());
}

class DatePickerExampleApp extends StatelessWidget {
  const DatePickerExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Date picker example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF1F6B4A)),
        scaffoldBackgroundColor: const Color(0xFFF6F3EE),
      ),
      home: const DatePickerDemo(),
    );
  }
}

class DatePickerDemo extends StatefulWidget {
  const DatePickerDemo({super.key});

  @override
  State<DatePickerDemo> createState() => _DatePickerDemoState();
}

class _DatePickerDemoState extends State<DatePickerDemo> {
  final _formKey = GlobalKey<FormState>();
  var _type = DatePickerType.spin;
  var _timeType = TimePickerType.spin;
  var _use24Hour = true;
  var _theme = CustomDatePickerThemeData.minimal;
  DateTime? _date;
  DateTimeRange? _range;
  TimeOfDay? _time;

  bool get _minimal => _theme == CustomDatePickerThemeData.minimal;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Form(
          key: _formKey,
          child: ListView(
            padding: const EdgeInsets.fromLTRB(24, 28, 24, 24),
            children: [
              const Text(
                'Date picker',
                style: TextStyle(
                  fontSize: 28,
                  fontWeight: FontWeight.w700,
                  color: Color(0xFF1C2430),
                ),
              ),
              const SizedBox(height: 8),
              const Text(
                'Dates use DD/MM/YYYY. Times use HH:mm, on a 24-hour or 12-hour clock.',
                style: TextStyle(
                  fontSize: 15,
                  height: 1.4,
                  color: Color(0xFF5E6772),
                ),
              ),
              const SizedBox(height: 20),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: [
                  for (final type in DatePickerType.values)
                    ChoiceChip(
                      label: Text(type.name),
                      selected: _type == type,
                      onSelected: (_) {
                        setState(() {
                          _type = type;
                          _date = null;
                          _range = null;
                        });
                      },
                    ),
                ],
              ),
              const SizedBox(height: 12),
              Wrap(
                spacing: 8,
                children: [
                  ChoiceChip(
                    label: const Text('Minimal'),
                    selected: _minimal,
                    onSelected: (_) {
                      setState(() => _theme = CustomDatePickerThemeData.minimal);
                    },
                  ),
                  ChoiceChip(
                    label: const Text('Material'),
                    selected: !_minimal,
                    onSelected: (_) {
                      setState(() => _theme = CustomDatePickerThemeData.material);
                    },
                  ),
                ],
              ),
              const SizedBox(height: 24),
              if (_type == DatePickerType.range)
                CustomDateRangeField(
                  key: const ValueKey('range-field'),
                  theme: _theme,
                  onChanged: (value) => setState(() => _range = value),
                  validator: (value) => value == null ? 'Select a range' : null,
                )
              else
                CustomDateField(
                  key: ValueKey(_type),
                  type: _type,
                  theme: _theme,
                  onChanged: (value) => setState(() => _date = value),
                  validator: (value) => value == null ? 'Select a date' : null,
                ),
              const SizedBox(height: 20),
              _ResultCard(date: _date, range: _range, isRange: _type == DatePickerType.range),
              const SizedBox(height: 28),
              const Text(
                'Time',
                style: TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.w700,
                  color: Color(0xFF1C2430),
                ),
              ),
              const SizedBox(height: 12),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: [
                  for (final type in TimePickerType.values)
                    ChoiceChip(
                      label: Text(type.name),
                      selected: _timeType == type,
                      onSelected: (_) {
                        setState(() {
                          _timeType = type;
                          _time = null;
                        });
                      },
                    ),
                  ChoiceChip(
                    label: const Text('24-hour'),
                    selected: _use24Hour,
                    onSelected: (_) => setState(() => _use24Hour = true),
                  ),
                  ChoiceChip(
                    label: const Text('12-hour'),
                    selected: !_use24Hour,
                    onSelected: (_) => setState(() => _use24Hour = false),
                  ),
                ],
              ),
              const SizedBox(height: 16),
              CustomTimeField(
                key: ValueKey('time-${_timeType.name}-$_use24Hour'),
                initialValue: _time,
                type: _timeType,
                use24Hour: _use24Hour,
                theme: _theme,
                onChanged: (value) => setState(() => _time = value),
                validator: (value) => value == null ? 'Select a time' : null,
              ),
              const SizedBox(height: 20),
              _TimeResultCard(time: _time, use24Hour: _use24Hour),
              const SizedBox(height: 24),
              FilledButton(
                onPressed: () {
                  if (!_formKey.currentState!.validate()) return;
                  final dateText = _type == DatePickerType.range
                      ? '${formatDdMmYyyy(_range!.start)} – ${formatDdMmYyyy(_range!.end)}'
                      : formatDdMmYyyy(_date!);
                  final message =
                      'Saved $dateText  ${formatHhMm(_time!, use24Hour: _use24Hour)}';
                  ScaffoldMessenger.of(context)
                    ..hideCurrentSnackBar()
                    ..showSnackBar(SnackBar(content: Text(message)));
                },
                style: FilledButton.styleFrom(
                  backgroundColor: _theme.accent,
                  foregroundColor: _theme.onAccent,
                  minimumSize: const Size.fromHeight(52),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(14),
                  ),
                ),
                child: const Text('Save'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _TimeResultCard extends StatelessWidget {
  const _TimeResultCard({required this.time, required this.use24Hour});

  final TimeOfDay? time;
  final bool use24Hour;

  @override
  Widget build(BuildContext context) {
    final empty = time == null;
    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(18),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(18),
        border: Border.all(color: const Color(0xFFE6E1D8)),
      ),
      child: Text(
        empty ? 'No time selected' : formatHhMm(time!, use24Hour: use24Hour),
        style: TextStyle(
          color: empty ? const Color(0xFF8B93A1) : const Color(0xFF1C2430),
          fontSize: empty ? 15 : 28,
          fontWeight: FontWeight.w700,
        ),
      ),
    );
  }
}

class _ResultCard extends StatelessWidget {
  const _ResultCard({
    required this.date,
    required this.range,
    required this.isRange,
  });

  final DateTime? date;
  final DateTimeRange? range;
  final bool isRange;

  @override
  Widget build(BuildContext context) {
    final text = isRange
        ? (range == null
              ? 'No range selected'
              : '${formatDdMmYyyy(range!.start)}  –  ${formatDdMmYyyy(range!.end)}')
        : (date == null ? 'No date selected' : formatDdMmYyyy(date!));

    return Container(
      width: double.infinity,
      padding: const EdgeInsets.all(18),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(18),
        border: Border.all(color: const Color(0xFFE6E1D8)),
      ),
      child: Text(
        text,
        style: TextStyle(
          color: (isRange ? range == null : date == null)
              ? const Color(0xFF8B93A1)
              : const Color(0xFF1C2430),
          fontSize: (isRange ? range == null : date == null) ? 15 : 28,
          fontWeight: FontWeight.w700,
        ),
      ),
    );
  }
}
3
likes
150
points
185
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Custom date and time pickers. Dates use DD/MM/YYYY. Times use HH:mm.

License

MIT (license)

Dependencies

flutter

More

Packages that depend on ujs_date_picker