mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-12-05 05:27:37 +08:00
feat(module: timepicker): add 12-hour time support (#2501)
* feat(module: datepicker): add 12-hour time support * fix(module: datepicker): revert 24-hour time format * fix(module: datepicker): AM/PM not localized in the date input component * fix(module: datepicker): AM/PM in the selection panel are not localized * Update components/date-picker/internal/DatePickerDatetimePanel.razor Co-authored-by: James Yeung <shunjiey@hotmail.com> * fix(module: datepicker). AM/PM switches toggling incorrectly * fix(module: datepicker): 24-hour format in DatePicker when Use12Hours * fix(module: datepicker): time format in docs * refactor(module: datepicker): code cleanup * feat(module: datepicker): add 12-hour format to en-US locale
This commit is contained in:
parent
1659aef02d
commit
acb6c892b5
@ -271,6 +271,9 @@ namespace AntDesign
|
||||
CurrentValue = DefaultValue;
|
||||
else
|
||||
CurrentValue = default;
|
||||
|
||||
PickerValues[0] = _pickerValuesAfterInit;
|
||||
|
||||
if (closeDropdown)
|
||||
Close();
|
||||
if (OnClearClick.HasDelegate)
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@ -125,7 +125,7 @@ namespace AntDesign
|
||||
}
|
||||
|
||||
public bool IsShowTime { get; protected set; }
|
||||
public string ShowTimeFormat { get; protected set; } = "HH:mm:ss";
|
||||
public string ShowTimeFormat { get; protected set; }
|
||||
protected OneOf<bool, string> _showTime = null;
|
||||
|
||||
private bool _timeFormatProvided;
|
||||
@ -244,9 +244,12 @@ namespace AntDesign
|
||||
[Parameter]
|
||||
public Func<DateTime, RenderFragment> MonthCellRender { get; set; }
|
||||
|
||||
public DateTime CurrentDate { get; set; } = DateTime.Now;
|
||||
[Parameter]
|
||||
public bool Use12Hours { get; set; }
|
||||
|
||||
protected DateTime[] PickerValues { get; } = new DateTime[] { DateTime.Now, DateTime.Now };
|
||||
public DateTime CurrentDate { get; set; } = DateTime.Today;
|
||||
|
||||
protected DateTime[] PickerValues { get; } = new DateTime[] { DateTime.Today, DateTime.Today };
|
||||
|
||||
public bool IsRange { get; set; }
|
||||
|
||||
@ -298,6 +301,11 @@ namespace AntDesign
|
||||
{
|
||||
_needRefresh = true;
|
||||
|
||||
if (!_timeFormatProvided || string.IsNullOrEmpty(ShowTimeFormat))
|
||||
{
|
||||
ShowTimeFormat = Use12Hours ? Locale.Lang.TimeFormat12Hour : Locale.Lang.TimeFormat;
|
||||
}
|
||||
|
||||
return base.SetParametersAsync(parameters);
|
||||
}
|
||||
|
||||
@ -658,6 +666,7 @@ namespace AntDesign
|
||||
DatePickerType.Date => GetTimeFormat(),
|
||||
DatePickerType.Month => Locale.Lang.YearMonthFormat,
|
||||
DatePickerType.Year => Locale.Lang.YearFormat,
|
||||
DatePickerType.Time when Use12Hours => Locale.Lang.TimeFormat12Hour,
|
||||
DatePickerType.Time => Locale.Lang.TimeFormat,
|
||||
DatePickerType.Week => $"{Locale.Lang.YearFormat}-0{Locale.Lang.Week}",
|
||||
DatePickerType.Quarter => $"{Locale.Lang.YearFormat}-Q0",
|
||||
@ -676,7 +685,7 @@ namespace AntDesign
|
||||
{
|
||||
return $"{Locale.Lang.DateFormat} {ShowTimeFormat}";
|
||||
}
|
||||
return Locale.Lang.DateTimeFormat;
|
||||
return Use12Hours ? Locale.Lang.DateTimeFormat12Hour : Locale.Lang.DateTimeFormat;
|
||||
}
|
||||
return Locale.Lang.DateFormat;
|
||||
}
|
||||
@ -696,7 +705,7 @@ namespace AntDesign
|
||||
};
|
||||
else
|
||||
format = InternalFormat;
|
||||
return value.ToString(format, CultureInfo.InvariantCulture);
|
||||
return value.ToString(format, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,4 +1,4 @@
|
||||
@namespace AntDesign.Internal
|
||||
@namespace AntDesign.Internal
|
||||
@typeparam TValue
|
||||
@inherits DatePickerPanelBase<TValue>
|
||||
|
||||
@ -71,23 +71,25 @@
|
||||
timeFormat = Format;
|
||||
}
|
||||
|
||||
var use12Hours = Use12Hours || timeFormat.ToLower().Contains("t");
|
||||
var isPM = use12Hours && Value?.Hour >= 12;
|
||||
DatePickerDisabledTime disabledTime = GetDisabledTime();
|
||||
bool isValueNull = Value is null;
|
||||
Func<int, int?, string> selected;
|
||||
string localValue;
|
||||
if (Value is null)
|
||||
{
|
||||
localValue = "";
|
||||
selected = (_, _) => "";
|
||||
}
|
||||
else
|
||||
{
|
||||
localValue = Value.Value.ToString(timeFormat);
|
||||
selected = (viewTime, valueTime) => viewTime == valueTime ? $"{PrefixCls}-time-panel-cell-selected" : "";
|
||||
}
|
||||
bool isValueNull = Value is null;
|
||||
Func<int, int?, string> selected;
|
||||
string localValue;
|
||||
if (Value is null)
|
||||
{
|
||||
localValue = "";
|
||||
selected = (_, _) => "";
|
||||
}
|
||||
else
|
||||
{
|
||||
localValue = Value.Value.ToString(timeFormat);
|
||||
selected = (viewTime, valueTime) => viewTime == valueTime ? $"{PrefixCls}-time-panel-cell-selected" : "";
|
||||
}
|
||||
}
|
||||
<div class="@(PrefixCls)-time-panel">
|
||||
@if(Picker == DatePickerType.Date)
|
||||
@if (Picker == DatePickerType.Date)
|
||||
{
|
||||
<div class="@(PrefixCls)-header">
|
||||
<div class="@(PrefixCls)-header-view">
|
||||
@ -99,21 +101,31 @@
|
||||
<div class="@(PrefixCls)-content">
|
||||
@if (timeFormat.ToLower().Contains("hh"))
|
||||
{
|
||||
var selectFirstHour = Value is not null && disabledTime._disabledHours.Contains(Value.Value.Hour);
|
||||
var hoursOffset = isPM ? 12 : 0;
|
||||
<ul class="@(PrefixCls)-time-panel-column" style="position: relative;">
|
||||
@for (int hour = 0; hour < 24; hour++)
|
||||
|
||||
@for (int hour = 0; hour < (use12Hours ? 12 : 24); hour++)
|
||||
{
|
||||
var viewTime = startTime;
|
||||
bool disabled = disabledTime._disabledHours.Contains(hour);
|
||||
string isSelectedCls = selected(viewTime.Hour, Value?.Hour);
|
||||
|
||||
bool disabled = disabledTime._disabledHours.Contains(hour + hoursOffset);
|
||||
string isSelectedCls = selected(viewTime.Hour + hoursOffset, Value?.Hour);
|
||||
string disabledCls = disabled ? $"{PrefixCls}-time-panel-cell-disabled" : "";
|
||||
|
||||
<li class="@(PrefixCls)-time-panel-cell @isSelectedCls @disabledCls">
|
||||
<div class="@(PrefixCls)-time-panel-cell-inner"
|
||||
@onclick="e => { if (!disabled) OnSelectHour(viewTime); }">
|
||||
@hour
|
||||
@onclick="e => { if (!disabled) OnSelectHour(viewTime.AddHours(hoursOffset)); }">
|
||||
@(use12Hours && hour==0? 12 : hour)
|
||||
</div>
|
||||
</li>
|
||||
|
||||
if (!disabled && selectFirstHour)
|
||||
{
|
||||
OnSelectHour(viewTime.AddHours(hoursOffset));
|
||||
selectFirstHour = false;
|
||||
}
|
||||
|
||||
startTime = startTime.AddHours(1);
|
||||
}
|
||||
</ul>
|
||||
@ -160,6 +172,33 @@
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
@if (use12Hours)
|
||||
{
|
||||
<ul class="@(PrefixCls)-time-panel-column" style="position: relative; overflow: hidden;">
|
||||
@{
|
||||
string isAmSelectedCls = isPM || isValueNull ? "" : $"{PrefixCls}-time-panel-cell-selected";
|
||||
string isPmSelectedCls = isPM ? $"{PrefixCls}-time-panel-cell-selected" : "";
|
||||
bool disabled = false;
|
||||
string disabledCls = disabled ? $"{PrefixCls}-time-panel-cell-disabled" : "";
|
||||
|
||||
<li class="@(PrefixCls)-time-panel-cell @isAmSelectedCls @disabledCls">
|
||||
<div class="@(PrefixCls)-time-panel-cell-inner"
|
||||
@onclick="e => {if (!disabled && (isPM || Value is null)) if(Value is not null) OnSelectHour(Value.Value.AddHours(-12));
|
||||
else OnSelectTime(DateTime.Today); }">
|
||||
@System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.AMDesignator
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="@(PrefixCls)-time-panel-cell @isPmSelectedCls @disabledCls">
|
||||
<div class="@(PrefixCls)-time-panel-cell-inner"
|
||||
@onclick="e => {if (!disabled && (!isPM || Value is null)) if(Value is not null) OnSelectHour(Value.Value.AddHours(12));
|
||||
else OnSelectTime(DateTime.Today.AddHours(12)); }">
|
||||
@System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.PMDesignator
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -36,22 +36,21 @@ namespace AntDesign.Internal
|
||||
List<int> disabledMinutes = new List<int>();
|
||||
List<int> disabledSeconds = new List<int>();
|
||||
DatePickerDisabledTime userDisabledTime = null;
|
||||
if (Value is not null)
|
||||
|
||||
if (DisabledHours is not null)
|
||||
{
|
||||
if (DisabledHours is not null)
|
||||
{
|
||||
disabledHours.AddRange(DisabledHours(Value.Value));
|
||||
}
|
||||
if (DisabledMinutes is not null)
|
||||
{
|
||||
disabledMinutes.AddRange(DisabledMinutes(Value.Value));
|
||||
}
|
||||
if (DisabledSeconds is not null)
|
||||
{
|
||||
disabledSeconds.AddRange(DisabledSeconds(Value.Value));
|
||||
}
|
||||
userDisabledTime = DisabledTime?.Invoke(Value ?? DateTime.Now);
|
||||
disabledHours.AddRange(DisabledHours(Value ?? DateTime.Now));
|
||||
}
|
||||
if (DisabledMinutes is not null)
|
||||
{
|
||||
disabledMinutes.AddRange(DisabledMinutes(Value ?? DateTime.Now));
|
||||
}
|
||||
if (DisabledSeconds is not null)
|
||||
{
|
||||
disabledSeconds.AddRange(DisabledSeconds(Value ?? DateTime.Now));
|
||||
}
|
||||
|
||||
userDisabledTime = DisabledTime?.Invoke(Value ?? DateTime.Now);
|
||||
|
||||
if (userDisabledTime != null)
|
||||
{
|
||||
|
@ -86,6 +86,9 @@ namespace AntDesign
|
||||
[Parameter]
|
||||
public RenderFragment RenderExtraFooter { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool Use12Hours { get; set; }
|
||||
|
||||
protected Dictionary<string, object> GetAttributes()
|
||||
{
|
||||
return new Dictionary<string, object>()
|
||||
|
@ -49,7 +49,7 @@
|
||||
{
|
||||
@if (DatePicker.IsShowTime)
|
||||
{
|
||||
<DatePickerDatetimePanel TValue="TValue" IsShowTime="@DatePicker.IsShowTime" OnOkClick="DatePicker.OnOkClick" @attributes="dateTimeAttributes" />
|
||||
<DatePickerDatetimePanel TValue="TValue" IsShowTime="@DatePicker.IsShowTime" Use12Hours="DatePicker.Use12Hours" OnOkClick="DatePicker.OnOkClick" @attributes="dateTimeAttributes" />
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -78,6 +78,6 @@
|
||||
}
|
||||
else if (IsShowTimePanel())
|
||||
{
|
||||
<DatePickerDatetimePanel TValue="TValue" @attributes="dateTimeAttributes" />
|
||||
<DatePickerDatetimePanel TValue="TValue" Use12Hours="DatePicker.Use12Hours" OnOkClick="DatePicker.OnOkClick" @attributes="dateTimeAttributes" />
|
||||
}
|
||||
</CascadingValue>
|
@ -65,5 +65,7 @@ namespace AntDesign
|
||||
public string QuarterSelect { get; set; } = "Select quarter";
|
||||
public string Week { get; set; } = "Week";
|
||||
public string[] ShortWeekDays { get; set; } = new string[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" };
|
||||
public string TimeFormat12Hour { get; set; } = "hh:mm:ss tt";
|
||||
public string DateTimeFormat12Hour { get; set; } = "yyyy-MM-dd hh:mm:ss tt";
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,8 @@
|
||||
"dateFormat": "yyyy-MM-dd",
|
||||
"dayFormat": "d",
|
||||
"dateTimeFormat": "yyyy-MM-dd HH:mm:ss",
|
||||
"dateTimeFormat12Hour": "M/d/yyyy hh:mm:ss tt",
|
||||
"timeFormat12Hour": "hh:mm:ss tt",
|
||||
"monthBeforeYear": true,
|
||||
"previousMonth": "Previous month (PageUp)",
|
||||
"nextMonth": "Next month (PageDown)",
|
||||
@ -104,6 +106,8 @@
|
||||
"dateFormat": "M/d/yyyy",
|
||||
"dayFormat": "d",
|
||||
"dateTimeFormat": "M/d/yyyy HH:mm:ss",
|
||||
"dateTimeFormat12Hour": "M/d/yyyy hh:mm:ss tt",
|
||||
"timeFormat12Hour": "hh:mm:ss tt",
|
||||
"monthBeforeYear": true,
|
||||
"previousMonth": "Previous month (PageUp)",
|
||||
"nextMonth": "Next month (PageDown)",
|
||||
|
@ -1,3 +1,3 @@
|
||||
<div>
|
||||
TODO
|
||||
<TimePicker TValue="DateTime?" Use12Hours/>
|
||||
</div>
|
@ -7,9 +7,9 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
12 小时制的时间选择器,默认的 format 为 `h:mm:ss a`。
|
||||
12 小时制的时间选择器,默认的 format 为 `hh:mm:ss tt`。
|
||||
|
||||
## en-US
|
||||
|
||||
TimePicker of 12 hours format, with default format `h:mm:ss a`.
|
||||
TimePicker of 12 hours format, with default format `hh:mm:ss tt`.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user