Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 7.5.25
- Added the `firstDay` and `lastDay` parameters to `ThemedCalendar` to allow setting a date range for the picker, preventing selection of dates outside the specified range.
- The `firstDay` and `lastDay` parameters are now supported in `ThemedDateRangePicker`, `ThemedDatePicker`, `ThemedDateTimeRangePicker`, `ThemedDateTimeSteppedPicker` and `ThemedDateTimePicker`.

## 7.5.24

- Fixed `ThemedTable2` silent update loss for mid-list edits: reverted `didUpdateWidget` heuristic back to `DeepCollectionEquality` — the heuristic (identical + length + first element) missed edits to non-first elements in same-length lists; with Freezed value-equality objects the O(n) cost is negligible in practice (~4 of 170 telemetry updates actually triggered a reload in production profiling).
Expand Down
2 changes: 2 additions & 0 deletions example/lib/views/inputs/src/selectors/datetime.dart
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ class _DateTimePickersViewState extends State<DateTimePickersView> {
ThemedDateTimeSteppedPicker(
labelText: "Example label",
value: _selectedDateTime,
firstDay: DateTime.now().subtract(const Duration(days: 10)),
lastDay: DateTime.now(),
onChanged: (val) {
_selectedTime = TimeOfDay(hour: val.hour, minute: val.minute);
setState(() => _selectedDateTime = val);
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ packages:
path: ".."
relative: true
source: path
version: "7.5.23"
version: "7.5.25"
leak_tracker:
dependency: transitive
description:
Expand Down
10 changes: 10 additions & 0 deletions lib/src/inputs/src/pickers/date/range.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ class ThemedDateRangePicker extends StatefulWidget {
/// [emptyListText] is the text to be displayed when the list is empty.
final EdgeInsets? padding;

/// [lastDay] any datetime after this day will be disabled. If null, the calendar will not have a limit.
final DateTime? lastDay;

/// [firstDay] any datetime before this day will be disabled. If null, the calendar will not have a limit.
final DateTime? firstDay;

/// [ThemedDateRangePicker] is a date picker input. It is a wrapper of [ThemedTextInput] with a date picker.
const ThemedDateRangePicker({
super.key,
Expand Down Expand Up @@ -112,6 +118,8 @@ class ThemedDateRangePicker extends StatefulWidget {
this.errors = const [],
this.hideDetails = false,
this.padding,
this.firstDay,
this.lastDay,
}) : assert((label == null && labelText != null) || (label != null && labelText == null)),
assert(value.length == 0 || value.length == 2);

Expand Down Expand Up @@ -220,6 +228,8 @@ class _ThemedDateRangePickerState extends State<ThemedDateRangePicker> {
smallWeekdays: true,
todayIndicator: false,
todayButton: false,
firstDay: widget.firstDay,
lastDay: widget.lastDay,
onDayTap: (day) {
if (tempDate == null) {
tempDate = day;
Expand Down
10 changes: 10 additions & 0 deletions lib/src/inputs/src/pickers/date/single.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ class ThemedDatePicker extends StatefulWidget {
/// [emptyListText] is the text to be displayed when the list is empty.
final EdgeInsets? padding;

/// [lastDay] any datetime after this day will be disabled. If null, the calendar will not have a limit.
final DateTime? lastDay;

/// [firstDay] any datetime before this day will be disabled. If null, the calendar will not have a limit.
final DateTime? firstDay;

/// [ThemedDatePicker] is a date picker input. It is a wrapper of [ThemedTextInput] with a date picker.
const ThemedDatePicker({
super.key,
Expand Down Expand Up @@ -116,6 +122,8 @@ class ThemedDatePicker extends StatefulWidget {
this.errors = const [],
this.hideDetails = false,
this.padding,
this.firstDay,
this.lastDay,
}) : assert((label == null && labelText != null) || (label != null && labelText == null));

@override
Expand Down Expand Up @@ -199,6 +207,8 @@ class _ThemedDatePickerState extends State<ThemedDatePicker> {
showEntries: false,
smallWeekdays: true,
disabledDays: widget.disabledDays,
firstDay: widget.firstDay,
lastDay: widget.lastDay,
onDayTap: (day) {
Navigator.of(context).pop(day);
},
Expand Down
16 changes: 16 additions & 0 deletions lib/src/inputs/src/pickers/datetime/range.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ class ThemedDateTimeRangePicker extends StatefulWidget {
/// [emptyListText] is the text to be displayed when the list is empty.
final EdgeInsets? padding;

/// [lastDay] any datetime after this day will be disabled. If null, the calendar will not have a limit.
final DateTime? lastDay;

/// [firstDay] any datetime before this day will be disabled. If null, the calendar will not have a limit.
final DateTime? firstDay;

/// [ThemedDateTimeRangePicker] is a date time picker input. It is a wrapper of [ThemedTextInput]
/// with a date time picker.
const ThemedDateTimeRangePicker({
Expand Down Expand Up @@ -148,6 +154,8 @@ class ThemedDateTimeRangePicker extends StatefulWidget {
this.errors = const [],
this.hideDetails = false,
this.padding,
this.firstDay,
this.lastDay,
}) : assert((label == null && labelText != null) || (label != null && labelText == null)),
assert(value.length == 0 || value.length == 2);

Expand Down Expand Up @@ -245,6 +253,8 @@ class _ThemedDateTimeRangePickerState extends State<ThemedDateTimeRangePicker> w
translations: widget.translations,
overridesLayrzTranslations: widget.overridesLayrzTranslations,
use24HourFormat: widget.use24HourFormat,
firstDay: widget.firstDay,
lastDay: widget.lastDay,
),
);

Expand Down Expand Up @@ -276,6 +286,8 @@ class ThemedDateTimeRangeDialog extends StatefulWidget {
final List<DateTime> disabledDays;
final Map<String, String> translations;
final bool overridesLayrzTranslations;
final DateTime? firstDay;
final DateTime? lastDay;
final bool use24HourFormat;

const ThemedDateTimeRangeDialog({
Expand All @@ -286,6 +298,8 @@ class ThemedDateTimeRangeDialog extends StatefulWidget {
this.translations = const {},
this.overridesLayrzTranslations = false,
this.use24HourFormat = false,
this.firstDay,
this.lastDay,
});

@override
Expand Down Expand Up @@ -383,6 +397,8 @@ class _ThemedDateTimeRangeDialogState extends State<ThemedDateTimeRangeDialog> w
controller: _tabController,
children: [
ThemedCalendar(
firstDay: widget.firstDay,
lastDay: widget.lastDay,
focusDay: tempDate,
focusOnHighlightedDays: tempDate == null,
showEntries: false,
Expand Down
10 changes: 10 additions & 0 deletions lib/src/inputs/src/pickers/datetime/single.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ class ThemedDateTimePicker extends StatefulWidget {
/// [emptyListText] is the text to be displayed when the list is empty.
final EdgeInsets? padding;

/// [lastDay] any datetime after this day will be disabled. If null, the calendar will not have a limit.
final DateTime? lastDay;

/// [firstDay] any datetime before this day will be disabled. If null, the calendar will not have a limit.
final DateTime? firstDay;

/// [ThemedDateTimePicker] is a date time picker input. It is a wrapper of [ThemedTextInput] with a date time picker.
const ThemedDateTimePicker({
super.key,
Expand Down Expand Up @@ -147,6 +153,8 @@ class ThemedDateTimePicker extends StatefulWidget {
this.errors = const [],
this.hideDetails = false,
this.padding,
this.firstDay,
this.lastDay,
}) : assert((label == null && labelText != null) || (label != null && labelText == null));

@override
Expand Down Expand Up @@ -304,6 +312,8 @@ class _ThemedDateTimePickerState extends State<ThemedDateTimePicker> with Single
disabledDays: widget.disabledDays,
translations: widget.translations,
overridesLayrzTranslations: widget.overridesLayrzTranslations,
firstDay: widget.firstDay,
lastDay: widget.lastDay,
onDayTap: (newDate) => setState(() => date = newDate),
),
Column(
Expand Down
10 changes: 10 additions & 0 deletions lib/src/inputs/src/pickers/datetime/single_stepped.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ class ThemedDateTimeSteppedPicker extends StatefulWidget {

final bool disableTimePickerBlink;

/// [lastDay] any datetime after this day will be disabled. If null, the calendar will not have a limit.
final DateTime? lastDay;

/// [firstDay] any datetime before this day will be disabled. If null, the calendar will not have a limit.
final DateTime? firstDay;

/// [ThemedDateTimeSteppedPicker] is a date time stepped picker input. It is a wrapper of [ThemedTextInput] with a date time stepped picker.
const ThemedDateTimeSteppedPicker({
super.key,
Expand Down Expand Up @@ -150,6 +156,8 @@ class ThemedDateTimeSteppedPicker extends StatefulWidget {
this.hideDetails = false,
this.padding,
this.disableTimePickerBlink = false,
this.firstDay,
this.lastDay,
}) : assert((label == null && labelText != null) || (label != null && labelText == null));

@override
Expand Down Expand Up @@ -241,6 +249,8 @@ class _ThemedDateTimeSteppedPickerState extends State<ThemedDateTimeSteppedPicke
showEntries: false,
smallWeekdays: true,
disabledDays: widget.disabledDays,
lastDay: widget.lastDay,
firstDay: widget.firstDay,
onDayTap: (day) {
Navigator.of(context).pop(day);
},
Expand Down
37 changes: 34 additions & 3 deletions lib/src/widgets/src/calendar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ class ThemedCalendar extends StatefulWidget {
/// [focusOnHighlightedDays] allows to focus the calendar in a day between the highlighted days.
final bool focusOnHighlightedDays;

/// [lastDay] any datetime after this day will be disabled. If null, the calendar will not have a limit.
final DateTime? lastDay;

/// [firstDay] any datetime before this day will be disabled. If null, the calendar will not have a limit.
final DateTime? firstDay;

const ThemedCalendar({
super.key,
this.focusDay,
Expand Down Expand Up @@ -152,6 +158,8 @@ class ThemedCalendar extends StatefulWidget {
this.todayButton = true,
this.aditionalButtons = const [],
this.focusOnHighlightedDays = false,
this.lastDay,
this.firstDay,
});

@override
Expand Down Expand Up @@ -626,10 +634,33 @@ class _ThemedCalendarState extends State<ThemedCalendar> {
})
.contains(now);

if (widget.isHighlightDaysAsRange) {
isFocusDay = false;
isDisabled = false;
if (widget.firstDay != null) {
isDisabled =
isDisabled ||
now.isBefore(
DateTime(
widget.firstDay!.year,
widget.firstDay!.month,
widget.firstDay!.day,
),
);
}
if (widget.lastDay != null) {
isDisabled =
isDisabled ||
now.isAfter(
DateTime(
widget.lastDay!.year,
widget.lastDay!.month,
widget.lastDay!.day,
),
);
}

// if (widget.isHighlightDaysAsRange) {
// isFocusDay = false;
// isDisabled = false;
// }

bool isCurrentMonth = day.month == _dayGenerator.month;

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: layrz_theme
description: Layrz standard styling library for Flutter. Widget library following the Material Design 3 guidelines, with a focus on reliavility and functionality.
version: "7.5.24"
version: "7.5.25"
homepage: https://theme.layrz.com
repository: https://github.com/goldenm-software/layrz_theme

Expand Down
Loading