diff --git a/CHANGELOG.md b/CHANGELOG.md index a844c590e..a6a3eb7f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## NEXT +* feat: Added `fieldFlex` to the DatePicker to control the width. + ## 4.8.6 * fix: Pop the menu flyout before than calling the close callback ([#1009](https://github.com/bdlukaa/fluent_ui/issues/1009)) diff --git a/example/lib/screens/forms/date_picker.dart b/example/lib/screens/forms/date_picker.dart index c353a727c..b1c9cb52e 100644 --- a/example/lib/screens/forms/date_picker.dart +++ b/example/lib/screens/forms/date_picker.dart @@ -12,6 +12,7 @@ class DatePickerPage extends StatefulWidget { class _DatePickerPageState extends State with PageMixin { DateTime? simpleTime; DateTime? hiddenTime; + DateTime? flexTime; bool showYear = true; bool showMonth = true; @@ -105,6 +106,24 @@ DatePicker( ), ), ), + subtitle(content: const Text('A DatePicker with flex layout')), + CardHighlight( + codeSnippet: '''DateTime? selected; + +DatePicker( + selected: selected, + fieldFlex: const [2, 3, 2], // Same order as fieldOrder + onChanged: (time) => setState(() => selected = time), +),''', + child: Align( + alignment: AlignmentDirectional.centerStart, + child: DatePicker( + selected: flexTime, + fieldFlex: const [2, 3, 2], + onChanged: (v) => setState(() => flexTime = v), + ), + ), + ), ], ); } diff --git a/lib/src/controls/form/pickers/date_picker.dart b/lib/src/controls/form/pickers/date_picker.dart index 8451ed580..594787803 100644 --- a/lib/src/controls/form/pickers/date_picker.dart +++ b/lib/src/controls/form/pickers/date_picker.dart @@ -68,8 +68,13 @@ class DatePicker extends StatefulWidget { this.autofocus = false, this.locale, this.fieldOrder, + this.fieldFlex, }) : startDate = startDate ?? DateTime.now().subtract(kYearDuration * 100), - endDate = endDate ?? DateTime.now().add(kYearDuration * 25); + endDate = endDate ?? DateTime.now().add(kYearDuration * 25), + assert( + fieldFlex == null || fieldFlex.length == 3, + 'fieldFlex must be null or have a length of 3', + ); /// The current date selected date. /// @@ -153,6 +158,16 @@ class DatePicker extends StatefulWidget { /// on the current locale final List? fieldOrder; + /// The flex of the fields. + /// + /// if null, the flex is base on the current locale. + /// + /// See also: + /// + /// * [getDateFlexFromLocale], which returns the flex of the fields based + /// on the current locale + final List? fieldFlex; + @override State createState() => _DatePickerState(); @@ -268,6 +283,7 @@ class _DatePickerState extends State { final locale = widget.locale ?? Localizations.maybeLocaleOf(context); final fieldOrder = widget.fieldOrder ?? getDateOrderFromLocale(locale); + final fieldFlex = widget.fieldFlex ?? getDateFlexFromLocale(locale); assert(fieldOrder.isNotEmpty); assert( fieldOrder.where((f) => f == DatePickerField.month).length <= 1, @@ -298,6 +314,7 @@ class _DatePickerState extends State { yearController: _yearController, locale: widget.locale, fieldOrder: fieldOrder, + fieldFlex: fieldFlex, ); }, pickerHeight: widget.popupHeight, @@ -326,7 +343,7 @@ class _DatePickerState extends State { final monthWidgets = [ Expanded( - flex: 2, + flex: fieldFlex[fieldOrder.indexOf(DatePickerField.month)], child: Padding( padding: widget.contentPadding, child: Text( @@ -343,6 +360,7 @@ class _DatePickerState extends State { final dayWidget = [ Expanded( + flex: fieldFlex[fieldOrder.indexOf(DatePickerField.day)], child: Text( widget.selected == null ? localizations.day @@ -358,6 +376,7 @@ class _DatePickerState extends State { final yearWidgets = [ Expanded( + flex: fieldFlex[fieldOrder.indexOf(DatePickerField.year)], child: Text( widget.selected == null ? localizations.year @@ -434,6 +453,7 @@ class _DatePickerContentPopUp extends StatefulWidget { required this.endDate, required this.locale, required this.fieldOrder, + required this.fieldFlex, }); final bool showMonth; @@ -449,6 +469,7 @@ class _DatePickerContentPopUp extends StatefulWidget { final DateTime endDate; final Locale? locale; final List fieldOrder; + final List fieldFlex; @override State<_DatePickerContentPopUp> createState() => @@ -510,7 +531,8 @@ class __DatePickerContentPopUpState extends State<_DatePickerContentPopUp> { final months = monthsInCurrentYear; final monthWidget = [ Expanded( - flex: 2, + flex: + widget.fieldFlex[widget.fieldOrder.indexOf(DatePickerField.month)], child: () { final formatter = DateFormat.MMMM(locale.toString()); // MONTH @@ -585,6 +607,7 @@ class __DatePickerContentPopUpState extends State<_DatePickerContentPopUp> { final dayWidget = [ Expanded( + flex: widget.fieldFlex[widget.fieldOrder.indexOf(DatePickerField.day)], child: () { // DAY final daysInMonth = _getDaysInMonth(localDate.month, localDate.year); @@ -661,6 +684,7 @@ class __DatePickerContentPopUpState extends State<_DatePickerContentPopUp> { final yearWidget = [ Expanded( + flex: widget.fieldFlex[widget.fieldOrder.indexOf(DatePickerField.year)], child: () { final years = widget.endDate.year - widget.startDate.year + 1; final formatter = DateFormat.y(locale.toString()); @@ -810,3 +834,14 @@ List getDateOrderFromLocale(Locale? locale) { return dmy; } + +/// Get the date flex based on the current locale. +/// The flex is used to determine the width of the fields. +List getDateFlexFromLocale(Locale? locale) { + final lang = locale?.languageCode; + if (locale?.countryCode?.toLowerCase() == 'us') return const [2, 1, 1]; + + if (['zh', 'ko'].contains(lang)) return const [1, 1, 1]; + + return [1, 2, 1]; +}