smart_datetime_input 0.0.1 copy "smart_datetime_input: ^0.0.1" to clipboard
smart_datetime_input: ^0.0.1 copied to clipboard

A smart, segmented, and editable text field for handling Date, Time, and DateTime input in Flutter. Supports validation, auto-jump, pasting, and custom localization.

DateTime Field #

pub package License: MIT

[Demo]

A highly customizable, segmented, and editable text field for Date, Time, and DateTime input in Flutter.

Instead of forcing users to scroll through picker dialogs only, datetime_field lets them type the value directly with a smooth experience (auto-jump between segments, backspace navigation, validation, and smart paste) while still supporting the standard Material date/time pickers.


✨ Features #

  • Three Modes in One Widget

    • DateTimeMode.date → date only (day, month, year).
    • DateTimeMode.time → time only (hour, minute).
    • DateTimeMode.dateTime → combined date & time.
  • Segmented Input UX

    • Separate fields for day/month/year/hour/minute.
    • Auto-focus to next segment once the value is complete or clearly determined.
    • Backspace in an empty segment automatically jumps to the previous segment.
  • Smart Typing & Auto-Jump

    • Auto zero-padding for single digits when appropriate (e.g. typing 4 in day can become 04 and jump to the next segment).
    • Configurable dateOrder (dmy, mdy, ymd).
    • Logical jump limits per segment (days, months, hours, minutes).
  • Smart Paste

    • Paste complete date strings (e.g. 2023/10/20, 20-10-2023, 2023.10.20) directly into any segment.
    • Paste time strings (e.g. 14:30, 2:45) to fill hour and minute automatically.
    • Accepts "/", "-", ".", and ":" as separators.
    • Validates the pasted value before applying it.
  • Built-in Validation

    • Prevents obviously invalid values (e.g. month 13, day 32, negative hours).
    • Returns null for incomplete or invalid combinations.
    • Respects optional firstDate and lastDate constraints.
  • Integrated Pickers

    • Uses showDatePicker for dates.
    • Uses showTimePicker for times.
    • In dateTime mode, shows date picker then time picker in sequence.
    • Always keeps text segments in sync with the last picked value.
  • Localization & Theming

    • DateTimeLabels for full control over hints and tooltips.
    • Default English labels.
    • Built-in DateTimeLabels.arabic() factory for Arabic.
    • DateTimeFieldTheme (InheritedWidget) for app-wide configuration.
  • Flexible Layout & Styling

    • Custom dateSeparator (e.g. /, -) and timeSeparator (e.g. :).
    • Segment width is dynamically calculated based on hint text and text style.
    • Supports style and segmentHintStyle for fine-grained control.
    • Honors InputDecoration.isDense for compact layouts.
  • Form-Friendly

    • Extends FormField<DateTime>, integrates cleanly with Flutter forms.
    • Supports validator, initialValue, and autovalidateMode.
    • Exposes onChanged with the current DateTime? value.
  • Control Over Editing

    • editable → allow manual typing or force picker-only behavior.
    • readOnly → visually enabled but not editable.
    • clearable → optional clear (X) icon to reset the value.
    • showPickerIcon → toggle calendar/clock icon visibility.

📦 Installation #

Add this to your pubspec.yaml:

dependencies:
  datetime_field: ^0.0.1

Then run:

flutter pub get

🚀 Quick Start #

Basic Date Field #

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Date Field Example')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: DateTimeField(
          mode: DateTimeMode.date, // date, time, or dateTime
          decoration: const InputDecoration(
            labelText: 'Enter Date',
            border: OutlineInputBorder(),
          ),
          onChanged: (DateTime? value) {
            debugPrint('Selected date: $value');
          },
        ),
      ),
    );
  }
}

🧭 Modes #

1. Date Only #

DateTimeField(
  mode: DateTimeMode.date,
  decoration: const InputDecoration(
    labelText: 'Date',
    border: OutlineInputBorder(),
  ),
);
  • Shows Day / Month / Year segments.
  • Uses the configured dateOrder and dateSeparator.

2. Time Only #

DateTimeField(
  mode: DateTimeMode.time,
  decoration: const InputDecoration(
    labelText: 'Time',
    border: OutlineInputBorder(),
  ),
);
  • Shows Hour : Minute segments.
  • Under the hood, a DateTime is returned with today’s date and the selected time.

3. Date & Time #

DateTimeField(
  mode: DateTimeMode.dateTime,
  decoration: const InputDecoration(
    labelText: 'Date & Time',
    border: OutlineInputBorder(),
  ),
);
  • Combines the date segments, a spacer, and the time segments.
  • Picker icon will show date picker first, then time picker.

✅ Validation #

DateTimeField is a FormField<DateTime>, so you can use it with Form and FormState like any other field.

Required Field Example #

DateTimeField(
  mode: DateTimeMode.dateTime,
  autovalidateMode: AutovalidateMode.onUserInteraction,
  validator: (value) {
    if (value == null) {
      return 'Please enter a valid date and time';
    }
    return null;
  },
);

Using firstDate and lastDate #

DateTimeField(
  mode: DateTimeMode.date,
  firstDate: DateTime(2020, 1, 1),
  lastDate: DateTime(2030, 12, 31),
  validator: (value) {
    if (value == null) {
      return 'Date is required';
    }
    return null;
  },
);

If the user types or pastes a date outside this range, the value is treated as invalid (null in the form field).


🌍 Localization & Global Theming #

Using Built-in Arabic Labels Globally #

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

  @override
  Widget build(BuildContext context) {
    return DateTimeFieldTheme(
      labels: const DateTimeLabels.arabic(),
      child: MaterialApp(
        home: Scaffold(
          body: Center(
            child: DateTimeField(
              mode: DateTimeMode.date,
              decoration: const InputDecoration(
                labelText: 'التاريخ',
                border: OutlineInputBorder(),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

All descendant DateTimeField widgets without explicit labels will use these Arabic labels.

Custom Labels for a Single Field #

DateTimeField(
  mode: DateTimeMode.time,
  labels: const DateTimeLabels(
    hintHour: 'HH',
    hintMinute: 'MM',
    tooltipPick: 'Pick a time',
    tooltipClear: 'Clear value',
  ),
  decoration: const InputDecoration(
    labelText: 'Time',
    border: OutlineInputBorder(),
  ),
);

DateTimeLabels Structure #

const DateTimeLabels({
  this.hintDay = 'DD',
  this.hintMonth = 'MM',
  this.hintYear = 'YYYY',
  this.hintHour = 'HH',
  this.hintMinute = 'mm',
  this.tooltipPick = 'Select Date/Time',
  this.tooltipClear = 'Clear',
});

🎨 Formatting, Layout & Styling #

Date Order & Separators #

DateTimeField(
  mode: DateTimeMode.date,
  dateOrder: DateFieldOrder.ymd, // ymd, mdy, or dmy
  dateSeparator: '-',            // e.g. 2023-10-20
  timeSeparator: ':',            // e.g. 14:30
  decoration: const InputDecoration(
    labelText: 'Custom Format',
    border: OutlineInputBorder(),
  ),
);

Text Style & Segment Hint Style #

DateTimeField(
  mode: DateTimeMode.dateTime,
  style: const TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.w500,
  ),
  segmentHintStyle: const TextStyle(
    color: Colors.grey,
    fontStyle: FontStyle.italic,
  ),
  decoration: const InputDecoration(
    labelText: 'Styled DateTime',
    border: OutlineInputBorder(),
  ),
);

Compact Layout (isDense) #

DateTimeField(
  mode: DateTimeMode.date,
  decoration: const InputDecoration(
    labelText: 'Compact',
    isDense: true,
    border: OutlineInputBorder(),
  ),
);

The widget adjusts segment width and padding based on the provided TextStyle and the decoration’s isDense flag.


⌨️ Typing & Clipboard Behavior #

Smart Typing #

  • Segments accept only numeric characters (plus separators for paste).

  • When a segment is logically complete, focus automatically moves to the next:

    • Day & Month jump when further digits would be invalid (e.g. starting day with 404).
    • Hours and minutes use similar rules based on valid ranges.
  • Single-digit entries can be auto-padded to two digits and auto-jump to the next segment.

Smart Paste #

The field accepts pasted content such as:

  • 2023/10/20
  • 20-10-2023
  • 2023.10.20
  • 14:30
  • 2:45

If the pasted value is valid:

  • Date segments (Y, M, D) are filled automatically.
  • Time segments (H, M) are filled automatically.
  • The internal DateTime value is updated, and the form is notified.

If the pasted value is invalid, the paste is rejected and the field is not updated.


🧩 Integration with Material Pickers #

By default, a picker icon is shown based on the selected DateTimeMode:

  • DateTimeMode.date → calendar icon.
  • DateTimeMode.time → clock icon.
  • DateTimeMode.dateTime → calendar+clock icon.
DateTimeField(
  mode: DateTimeMode.dateTime,
  showPickerIcon: true,
  clearable: true,
  decoration: const InputDecoration(
    labelText: 'With Picker & Clear',
    border: OutlineInputBorder(),
  ),
);

Behavior:

  • Tapping the picker icon opens:

    • A date picker (and then a time picker) in dateTime mode.
    • Only a date picker in date mode.
    • Only a time picker in time mode.
  • Tapping the clear icon resets all segments and the underlying DateTime value.

To disable manual typing and force users to use the picker:

DateTimeField(
  mode: DateTimeMode.dateTime,
  editable: false, // segments become readOnly, picker still works
);

⚙️ API Overview #

DateTimeField Constructor (Key Parameters) #

DateTimeField({
  Key? key,
  bool? enabled,
  FormFieldValidator<DateTime>? validator,
  DateTime? initialValue,
  required DateTimeMode mode,
  ValueChanged<DateTime?>? onChanged,
  InputDecoration? decoration,
  TextStyle? style,
  TextStyle? segmentHintStyle,
  bool readOnly = false,
  bool clearable = false,
  bool editable = true,
  bool showPickerIcon = true,
  DateTime? firstDate,
  DateTime? lastDate,
  DateFieldOrder dateOrder = DateFieldOrder.dmy,
  String dateSeparator = '/',
  String timeSeparator = ':',
  DateTimeLabels? labels,
  AutovalidateMode? autovalidateMode,
})

Parameter Summary #

Parameter Type Default Description
mode DateTimeMode required Controls whether the field shows date, time, or both.
initialValue DateTime? null Initial value for the field.
onChanged ValueChanged<DateTime?>? null Called whenever the internal DateTime? value changes.
validator FormFieldValidator<DateTime>? null Validation callback for use in forms.
enabled bool? null (inherits from FormField) Enables or disables the field.
decoration InputDecoration? InputDecoration() Standard Flutter InputDecoration.
style TextStyle? Theme.of(context).textTheme.bodyLarge Text style for segments.
segmentHintStyle TextStyle? derived from style Text style for segment hints (placeholders).
readOnly bool false If true, prevents edits and disables picker interaction.
editable bool true If false, segments are read-only but picker can still be used.
clearable bool false Shows a clear (X) button when a value is set.
showPickerIcon bool true Shows or hides the calendar/clock icon.
firstDate DateTime? null Minimum allowed date when parsing or picking.
lastDate DateTime? null Maximum allowed date when parsing or picking.
dateOrder DateFieldOrder DateFieldOrder.dmy Controls the visual order of date segments (DMY, MDY, or YMD).
dateSeparator String '/' Separator between date segments.
timeSeparator String ':' Separator between time segments.
labels DateTimeLabels? null Custom labels for hints and tooltips (fallback to theme or English).
autovalidateMode AutovalidateMode? AutovalidateMode.disabled Standard Flutter form autovalidation mode.

🤝 Contribution #

Contributions are welcome!

If you’d like to improve this package:

  1. Open an issue describing bugs, feature requests, or UX improvements.
  2. Submit a pull request with clear commits and, if possible, tests or examples.

When contributing, please:

  • Keep the segmented UX consistent and predictable.
  • Consider localization and accessibility.
  • Add documentation updates for any new public API.

1
likes
0
points
123
downloads

Publisher

unverified uploader

Weekly Downloads

A smart, segmented, and editable text field for handling Date, Time, and DateTime input in Flutter. Supports validation, auto-jump, pasting, and custom localization.

Repository (GitHub)
View/report issues

Topics

#date #time #input #form #widget

License

unknown (license)

Dependencies

flutter

More

Packages that depend on smart_datetime_input