Skip to content

Commit 54f416c

Browse files
authored
feat(DateTimePicker): add PickTimeMode parameter (#6670)
* refactor: 代码格式化 * style: 微调日历数字字体大小 * doc: 代码格式化 * refactor: 结束时间精确到毫秒 * refactor: 代码格式化 * refactor: 私有属性改为变量 * feat: 增加时间选择器 * style: 调整间隙 * feat: 增加选择时间方式枚举参数 * refactor: 增加切换视图时关闭时间选择器逻辑 * feat: 增加秒针控制 * doc: 更新示例 * chore: bump version 9.10.0-beta01 * feat: 增加 PickTimeMode 参数 * test: 增加单元测试
1 parent d54014e commit 54f416c

File tree

11 files changed

+170
-27
lines changed

11 files changed

+170
-27
lines changed

src/BootstrapBlazor.Server/Components/Samples/DateTimePickers.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<h4>@Localizer["Description"]</h4>
66

77
<DemoBlock Title="@Localizer["DateTimePickerTitle"]" Introduction="@Localizer["DateTimePickerIntro"]" Name="DateTimePicker">
8-
<DateTimePicker ViewMode="DatePickerViewMode.DateTime"
8+
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" TimeFormat="hh\:mm"
99
Value="@DateTimePickerValue" OnValueChanged="@TimePickerValueChanged">
1010
<TimePickerSetting ShowClockScale="true" IsAutoSwitch="false" />
1111
</DateTimePicker>

src/BootstrapBlazor/BootstrapBlazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.9.3</Version>
4+
<Version>9.10.0-beta01</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<div class="@HeaderLabelString">
4141
<span role="button" class="picker-panel-header-label" @onclick="() => SwitchView(DatePickerViewMode.Year)">@YearString</span>
4242
<span role="button" class="@CurrentMonthViewClassName" @onclick="() => SwitchView(DatePickerViewMode.Month)">@MonthString</span>
43-
@if (IsDateTimeMode)
43+
@if (IsDateTimeMode && PickTimeMode == PickTimeMode.Clock)
4444
{
4545
<span role="button" class="picker-panel-header-label" @onclick="SwitchTimeView">@CurrentTime.ToString(TimeFormat)</span>
4646
}
@@ -80,12 +80,12 @@
8080
else if (IsDisabled(day))
8181
{
8282
<span class="cell">
83-
@if(ShowLunar)
83+
@if (ShowLunar)
8484
{
8585
<span>@text</span>
8686
<span class="bb-picker-body-lunar-text">@GetLunarText(day)</span>
8787
}
88-
else if(DayDisabledTemplate != null)
88+
else if (DayDisabledTemplate != null)
8989
{
9090
@DayDisabledTemplate(day)
9191
}
@@ -155,7 +155,8 @@
155155
@ChildContent
156156
</CascadingValue>
157157
<CascadingValue Value="this" IsFixed="true">
158-
<ClockPicker Value="CurrentTime" OnValueChanged="OnTimeChanged" @ref="TimePickerPanel" class="clock-panel-body"
158+
<ClockPicker @ref="TimePickerPanel" class="clock-panel-body"
159+
Value="CurrentTime" OnValueChanged="OnTimeChanged"
159160
ShowClockScale="TimePickerOption.ShowClockScale" IsAutoSwitch="TimePickerOption.IsAutoSwitch"
160161
ShowMinute="TimePickerOption.ShowMinute" ShowSecond="TimePickerOption.ShowSecond">
161162
</ClockPicker>
@@ -164,6 +165,18 @@
164165
</div>
165166
</div>
166167
</div>
168+
@if (IsDateTimeMode && PickTimeMode == PickTimeMode.Dropdown)
169+
{
170+
<div class="@TimePickerClassString">
171+
<span>@TimePlaceHolder</span>
172+
<input type="text" autocomplete="off" readonly class="form-control"
173+
value="@CurrentTime.ToString(TimeFormat)"
174+
@onclick="@OnShowTimePicker" />
175+
<TimePicker Value="CurrentTime" HasSeconds="HasSeconds"
176+
ShowRequired="false" ShowLabel="false" SkipValidate="true"
177+
OnClose="OnCloseTime" OnConfirm="OnConfirmTime"></TimePicker>
178+
</div>
179+
}
167180
@if (ShowFooter)
168181
{
169182
<div class="picker-panel-footer">

src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor.cs

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@ private DateTime StartDate
4545
/// </summary>
4646
private DateTime SelectValue { get; set; }
4747

48-
/// <summary>
49-
/// 获得/设置 是否显示时刻选择框
50-
/// </summary>
51-
private bool ShowTimePicker { get; set; }
48+
private bool _showClockPicker;
5249

5350
private string? ClassString => CssBuilder.Default("picker-panel")
5451
.AddClass("is-sidebar", ShowSidebar)
@@ -71,7 +68,7 @@ private DateTime StartDate
7168
.Build();
7269

7370
private string? WrapperClassString => CssBuilder.Default("picker-panel-body-main-wrapper")
74-
.AddClass("is-open", ShowTimePicker)
71+
.AddClass("is-open", _showClockPicker)
7572
.Build();
7673

7774
private bool IsDisabled(DateTime day) => day < MinValue || day > MaxValue || IsDisableDay(day);
@@ -394,6 +391,12 @@ public bool AllowNull
394391
[Parameter]
395392
public DayOfWeek FirstDayOfWeek { get; set; } = DayOfWeek.Sunday;
396393

394+
/// <summary>
395+
/// 获得/设置 选择时间方式 默认使用 <see cref="PickTimeMode.Dropdown"/>
396+
/// </summary>
397+
[Parameter]
398+
public PickTimeMode PickTimeMode { get; set; } = PickTimeMode.Dropdown;
399+
397400
[Inject]
398401
[NotNull]
399402
private ICalendarFestivals? CalendarFestivals { get; set; }
@@ -594,6 +597,7 @@ private async Task OnValueChanged()
594597
/// </summary>
595598
private async Task OnClickPrevYear()
596599
{
600+
_showTimePicker = false;
597601
CurrentDate = CurrentViewMode == DatePickerViewMode.Year
598602
? GetSafeYearDateTime(CurrentDate, -20)
599603
: GetSafeYearDateTime(CurrentDate, -1);
@@ -613,6 +617,7 @@ private async Task OnClickPrevYear()
613617
/// </summary>
614618
private async Task OnClickPrevMonth()
615619
{
620+
_showTimePicker = false;
616621
CurrentDate = CurrentDate.GetSafeMonthDateTime(-1);
617622

618623
_render = false;
@@ -630,6 +635,7 @@ private async Task OnClickPrevMonth()
630635
/// </summary>
631636
private async Task OnClickNextYear()
632637
{
638+
_showTimePicker = false;
633639
CurrentDate = CurrentViewMode == DatePickerViewMode.Year
634640
? GetSafeYearDateTime(CurrentDate, 20)
635641
: GetSafeYearDateTime(CurrentDate, 1);
@@ -649,6 +655,7 @@ private async Task OnClickNextYear()
649655
/// </summary>
650656
private async Task OnClickNextMonth()
651657
{
658+
_showTimePicker = false;
652659
CurrentDate = CurrentDate.GetSafeMonthDateTime(1);
653660

654661
_render = false;
@@ -694,6 +701,35 @@ private async Task OnTimeChanged(TimeSpan time)
694701
}
695702
}
696703

704+
private string? TimePickerClassString => CssBuilder.Default("picker-panel-time")
705+
.AddClass("show", _showTimePicker)
706+
.Build();
707+
708+
private bool _showTimePicker;
709+
710+
private Task OnConfirmTime(TimeSpan time)
711+
{
712+
_showTimePicker = false;
713+
CurrentTime = time;
714+
StateHasChanged();
715+
return Task.CompletedTask;
716+
}
717+
718+
private Task OnCloseTime()
719+
{
720+
_showTimePicker = false;
721+
StateHasChanged();
722+
return Task.CompletedTask;
723+
}
724+
725+
private void OnShowTimePicker()
726+
{
727+
_showTimePicker = true;
728+
StateHasChanged();
729+
}
730+
731+
private bool HasSeconds => TimeFormat.Contains('s');
732+
697733
private bool ShouldConfirm => !IsDateTimeMode && (AutoClose || ShowFooter == false);
698734

699735
/// <summary>
@@ -702,6 +738,7 @@ private async Task OnTimeChanged(TimeSpan time)
702738
/// <param name="view"></param>
703739
private async Task SwitchView(DatePickerViewMode view)
704740
{
741+
_showTimePicker = false;
705742
if (AllowSwitchModes[ViewMode].Contains(view))
706743
{
707744
CurrentViewMode = view;
@@ -720,12 +757,13 @@ private async Task SwitchView(DatePickerViewMode view)
720757

721758
private void SwitchTimeView()
722759
{
723-
ShowTimePicker = true;
760+
_showClockPicker = true;
724761
}
725762

726763
internal void SwitchDateView()
727764
{
728-
ShowTimePicker = false;
765+
_showClockPicker = false;
766+
_showTimePicker = false;
729767
StateHasChanged();
730768
}
731769

@@ -851,7 +889,8 @@ private async Task ClickConfirmButton()
851889
private async Task ClickClearButton()
852890
{
853891
// 关闭 TimerPicker
854-
ShowTimePicker = false;
892+
_showClockPicker = false;
893+
_showTimePicker = false;
855894

856895
CurrentDate = DateTime.MinValue;
857896
CurrentTime = TimeSpan.Zero;
@@ -876,7 +915,8 @@ private async Task OnClickSidebarButton(DateTime d)
876915
private void ResetTimePickerPanel()
877916
{
878917
// 关闭 TimerPicker
879-
ShowTimePicker = false;
918+
_showClockPicker = false;
919+
_showTimePicker = false;
880920

881921
TimePickerPanel?.Reset();
882922
}

src/BootstrapBlazor/Components/DateTimePicker/DatePickerBody.razor.scss

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,12 @@
9191
table {
9292
table-layout: fixed;
9393
width: 100%;
94-
font-size: 12px;
9594
user-select: none;
9695

96+
.date-table-row {
97+
font-size: 12px;
98+
}
99+
97100
td {
98101
text-align: center;
99102

@@ -319,6 +322,33 @@
319322
}
320323
}
321324

325+
.picker-panel-time {
326+
display: flex;
327+
justify-content: space-between;
328+
flex-wrap: nowrap;
329+
padding: 4px 1rem;
330+
border-top: var(--bs-border-width) solid var(--bs-border-color);
331+
position: relative;
332+
333+
.form-control {
334+
font-size: 14px;
335+
width: 178px;
336+
cursor: pointer;
337+
padding: 3px 8px;
338+
text-align: center;
339+
}
340+
341+
.bb-time-picker {
342+
position: absolute;
343+
bottom: 2.5rem;
344+
right: 1rem;
345+
}
346+
347+
&:not(.show) .bb-time-picker {
348+
display: none;
349+
}
350+
}
351+
322352
.picker-panel-footer {
323353
border-top: var(--bs-border-width) solid var(--bs-border-color);
324354
padding: 4px;

src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
<BootstrapLabel required="@Required" for="@Id" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText" />
99
}
1010
<div @attributes="@AdditionalAttributes" tabindex="@TabIndexString" id="@Id" class="@ClassString" data-bb-dropdown=".picker-panel">
11-
<input readonly="@ReadonlyString" class="@InputClassName" @bind="@CurrentValueAsString" placeholder="@PlaceholderString" disabled="@Disabled" data-bs-toggle="@Constants.DropdownToggleString" data-bs-placement="@PlacementString" data-bs-custom-class="@CustomClassString" @onblur="OnBlur" />
11+
<input readonly="@ReadonlyString" class="@InputClassName" @bind="@CurrentValueAsString" placeholder="@PlaceholderString"
12+
disabled="@Disabled" data-bs-toggle="@Constants.DropdownToggleString" data-bs-placement="@PlacementString"
13+
data-bs-custom-class="@CustomClassString" @onblur="OnBlur" />
1214
@if (ShowIcon)
1315
{
1416
<i class="@DateTimePickerIconClassString"></i>
@@ -19,7 +21,7 @@
1921
ShowLunar="ShowLunar" ShowSolarTerm="ShowSolarTerm" ShowFestivals="ShowFestivals" ShowHolidays="ShowHolidays"
2022
OnConfirm="OnConfirm" OnClear="OnClear" MinValue="MinValue" MaxValue="MaxValue"
2123
AutoClose="AutoClose" ViewMode="ViewMode" DayTemplate="DayTemplate!" DayDisabledTemplate="DayDisabledTemplate!"
22-
OnGetDisabledDaysCallback="OnGetDisabledDaysCallback!"
24+
PickTimeMode="PickTimeMode" OnGetDisabledDaysCallback="OnGetDisabledDaysCallback!"
2325
EnableDisabledDaysCache="EnableDisabledDaysCache">
2426
@ChildContent
2527
</DatePickerBody>

src/BootstrapBlazor/Components/DateTimePicker/DateTimePicker.razor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ public string? Format
118118
[Parameter]
119119
public DatePickerViewMode ViewMode { get; set; } = DatePickerViewMode.Date;
120120

121+
/// <summary>
122+
/// 获得/设置 选择时间方式 默认使用 <see cref="PickTimeMode.Dropdown"/>
123+
/// </summary>
124+
[Parameter]
125+
public PickTimeMode PickTimeMode { get; set; } = PickTimeMode.Dropdown;
126+
121127
/// <summary>
122128
/// 获得/设置 是否显示快捷侧边栏 默认不显示
123129
/// </summary>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the Apache 2.0 License
3+
// See the LICENSE file in the project root for more information.
4+
// Maintainer: Argo Zhang([email protected]) Website: https://www.blazor.zone
5+
6+
namespace BootstrapBlazor.Components;
7+
8+
/// <summary>
9+
/// <see cref="DateTimePicker{TValue}"/> 组件选择时间方式枚举
10+
/// </summary>
11+
public enum PickTimeMode
12+
{
13+
/// <summary>
14+
/// 使用 Dropdown 下拉方式选择时间
15+
/// </summary>
16+
Dropdown,
17+
18+
/// <summary>
19+
/// 使用 Clock 拖拽指针方式选择时间
20+
/// </summary>
21+
Clock
22+
}

src/BootstrapBlazor/Components/DateTimeRange/DateTimeRange.razor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,10 @@ protected override void OnParametersSet()
322322

323323
SidebarItems ??=
324324
[
325-
new() { Text = Localizer["Last7Days"], StartDateTime = DateTime.Today.AddDays(-7), EndDateTime = DateTime.Today.AddDays(1).AddSeconds(-1) },
326-
new() { Text = Localizer["Last30Days"], StartDateTime = DateTime.Today.AddDays(-30), EndDateTime = DateTime.Today.AddDays(1).AddSeconds(-1) },
327-
new() { Text = Localizer["ThisMonth"], StartDateTime = DateTime.Today.AddDays(1 - DateTime.Today.Day), EndDateTime = DateTime.Today.AddDays(1 - DateTime.Today.Day).AddMonths(1).AddSeconds(-1) },
328-
new() { Text = Localizer["LastMonth"], StartDateTime = DateTime.Today.AddDays(1- DateTime.Today.Day).AddMonths(-1), EndDateTime = DateTime.Today.AddDays(1- DateTime.Today.Day).AddSeconds(-1) },
325+
new() { Text = Localizer["Last7Days"], StartDateTime = DateTime.Today.AddDays(-7), EndDateTime = DateTime.Today.AddDays(1).AddMilliseconds(-1) },
326+
new() { Text = Localizer["Last30Days"], StartDateTime = DateTime.Today.AddDays(-30), EndDateTime = DateTime.Today.AddDays(1).AddMilliseconds(-1) },
327+
new() { Text = Localizer["ThisMonth"], StartDateTime = DateTime.Today.AddDays(1 - DateTime.Today.Day), EndDateTime = DateTime.Today.AddDays(1 - DateTime.Today.Day).AddMonths(1).AddMilliseconds(-1) },
328+
new() { Text = Localizer["LastMonth"], StartDateTime = DateTime.Today.AddDays(1- DateTime.Today.Day).AddMonths(-1), EndDateTime = DateTime.Today.AddDays(1- DateTime.Today.Day).AddMilliseconds(-1) },
329329
];
330330

331331
ResetBodyValue();
@@ -478,7 +478,7 @@ private async Task UpdateValue(DateTime d)
478478
// 结束时间为空
479479
if (d < SelectedValue.Start)
480480
{
481-
SelectedValue.End = SelectedValue.Start;
481+
SelectedValue.End = SelectedValue.Start.AddDays(1).AddMilliseconds(-1);
482482
SelectedValue.Start = d;
483483
}
484484
else

src/BootstrapBlazor/Components/TimePicker/TimePicker.razor

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,3 @@
1515
<button type="button" class="btn time-panel-btn confirm" @onclick="@OnClickConfirm">@ConfirmButtonText</button>
1616
</div>
1717
</div>
18-
19-
@code {
20-
21-
}

0 commit comments

Comments
 (0)