feat(DateTimePicker): add IsButton parameter (#6999)

* feat: 增加日期选择按钮

* refactor: 增加逻辑

* refactor: 移除 DateTimePickerButton 组件

* refactor: 重构脚本支持 Button 模式切换

* feat: 增加按钮元素

* doc: 增加多语言

* doc: 更新示例

* doc: 文档格式化

* test: 更新单元测试

* chore: bump version 9.11.5-beta05
This commit is contained in:
Argo Zhang
2025-10-24 21:13:33 +08:00
committed by GitHub
parent 7239ed0f1a
commit 37ab016e2b
17 changed files with 327 additions and 197 deletions

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "AutoScroll"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "wählen",
"DatePlaceHolder": "Datum auswählen",
"TimePlaceHolder": "Uhrzeit auswählen",
"DateTimePlaceHolderText": "Bitte auswählen ...",

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "AutoScroll"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "Seleccione",
"DatePlaceHolder": "Seleccione fecha",
"TimePlaceHolder": "Seleccione hora",
"DateTimePlaceHolderText": "Por favor seleccione ...",

View File

@@ -45,6 +45,7 @@
"AutoScrollText": "Scorrimento automatico"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "Seleziona",
"DatePlaceHolder": "Seleziona la data",
"TimePlaceHolder": "Seleziona l'ora",
"DateTimePlaceHolderText": "Per favore seleziona ...",

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "Rolagem automática"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "Selecione",
"DatePlaceHolder": "Selecione a data",
"TimePlaceHolder": "Selecione o horário",
"DateTimePlaceHolderText": "Por favor, selecione ...",

View File

@@ -1,4 +1,4 @@
{
{
"BootstrapBlazor.Components.AutoComplete": {
"NoDataTip": "Нет данных",
"PlaceHolder": "Пожалуйста, введите"
@@ -34,6 +34,7 @@
"AutoScrollText": "Автопрокрутка"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "Выберите",
"DatePlaceHolder": "Выберите дату",
"TimePlaceHolder": "Выберите время",
"DateTimePlaceHolderText": "Пожалуйста, выберите ...",

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "เลื่อนอัตโนมัติ"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "เลือก",
"DatePlaceHolder": "เลือกวันที่",
"TimePlaceHolder": "เลือกเวลา",
"DateTimePlaceHolderText": "กรุณาเลือก ...",

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "Автопрокрутка"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "Виберіть",
"DatePlaceHolder": "Виберіть дату",
"TimePlaceHolder": "Виберіть час",
"DateTimePlaceHolderText": "Будь ласка, виберіть ...",

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "自動滾屏"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "選擇",
"DatePlaceHolder": "選擇日期",
"TimePlaceHolder": "選擇時間",
"DateTimePlaceHolderText": "請選擇日期時間",

View File

@@ -5,221 +5,241 @@
<h4>@Localizer["Description"]</h4>
<DemoBlock Title="@Localizer["DateTimePickerTitle"]" Introduction="@Localizer["DateTimePickerIntro"]" Name="DateTimePicker">
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" TimeFormat="hh\:mm"
Value="@DateTimePickerValue" OnValueChanged="@TimePickerValueChanged">
<TimePickerSetting ShowClockScale="true" IsAutoSwitch="false" />
</DateTimePicker>
<ConsoleLogger @ref="TimePickerLogger" class="mt-3" />
<section ignore class="row g-3 mb-3">
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="IsButton"></BootstrapInputGroupLabel>
<Switch @bind-Value="_isButton"></Switch>
</BootstrapInputGroup>
</div>
</section>
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" TimeFormat="hh\:mm" IsButton="_isButton"
Value="@DateTimePickerValue" OnValueChanged="@TimePickerValueChanged">
<TimePickerSetting ShowClockScale="true" IsAutoSwitch="false" />
</DateTimePicker>
<ConsoleLogger @ref="TimePickerLogger" class="mt-3" />
</DemoBlock>
<DemoBlock Title="@Localizer["NormalTitle"]" Introduction="@Localizer["NormalIntro"]" Name="Normal">
<section ignore>
<GroupBox Title="@Localizer["Feature"]">
<div class="row g-3 form-inline text-end">
<div class="col-12 col-sm-3">
<Switch DisplayText="@Localizer["FeatureShowLunar"]" ShowLabel="true" @bind-Value="_showLunar" />
</div>
<div class="col-12 col-sm-3">
<Switch DisplayText="@Localizer["FeatureShowSolarTerm"]" ShowLabel="true" @bind-Value="_showSolarTerm" />
</div>
<div class="col-12 col-sm-3">
<Switch DisplayText="@Localizer["FeatureShowFestivals"]" ShowLabel="true" @bind-Value="_showFestivals" />
</div>
<div class="col-12 col-sm-3">
<Switch DisplayText="@Localizer["FeatureShowHolidays"]" ShowLabel="true" @bind-Value="_showHolidays" />
</div>
</div>
</GroupBox>
<div class="mt-3">
<Pre>builder.Services.AddBootstrapHolidayService();</Pre>
</div>
</section>
<DatePickerBody @bind-Value="Value" OnConfirm="@NormalOnConfirm" ShowFooter="false" ShowLunar="_showLunar" ShowSolarTerm="_showSolarTerm" ShowFestivals="_showFestivals" ShowHolidays="_showHolidays" />
<ConsoleLogger @ref="NormalLogger" class="mt-3" />
<section ignore>
<Tips class="mt-3">
<p>@((MarkupString)Localizer["FeatureIntro"].Value)</p>
<ul class="ul-demo mt-3">
<li>@((MarkupString)Localizer["FeatureShowLunarIntro"].Value)</li>
<li>@((MarkupString)Localizer["FeatureShowSolarTermIntro"].Value)</li>
<li>@((MarkupString)Localizer["FeatureShowFestivalsIntro"].Value)</li>
<li>@((MarkupString)Localizer["FeatureShowHolidaysIntro"].Value)</li>
</ul>
<div>@((MarkupString)Localizer["FeatureFestivalIntro"].Value)</div>
</Tips>
</section>
<section ignore>
<GroupBox Title="@Localizer["Feature"]">
<div class="row g-3 form-inline text-end">
<div class="col-12 col-sm-6 col-lg-3">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["FeatureShowLunar"]"></BootstrapInputGroupLabel>
<Switch @bind-Value="_showLunar" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6 col-lg-3">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["FeatureShowSolarTerm"]"></BootstrapInputGroupLabel>
<Switch @bind-Value="_showSolarTerm" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6 col-lg-3">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["FeatureShowFestivals"]"></BootstrapInputGroupLabel>
<Switch @bind-Value="_showFestivals" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6 col-lg-3">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["FeatureShowHolidays"]"></BootstrapInputGroupLabel>
<Switch @bind-Value="_showHolidays" />
</BootstrapInputGroup>
</div>
</div>
</GroupBox>
<div class="mt-3">
<Pre>builder.Services.AddBootstrapHolidayService();</Pre>
</div>
</section>
<DatePickerBody @bind-Value="Value" OnConfirm="@NormalOnConfirm" ShowFooter="false" ShowLunar="_showLunar" ShowSolarTerm="_showSolarTerm" ShowFestivals="_showFestivals" ShowHolidays="_showHolidays" />
<ConsoleLogger @ref="NormalLogger" class="mt-3" />
<section ignore>
<Tips class="mt-3">
<p>@((MarkupString)Localizer["FeatureIntro"].Value)</p>
<ul class="ul-demo mt-3">
<li>@((MarkupString)Localizer["FeatureShowLunarIntro"].Value)</li>
<li>@((MarkupString)Localizer["FeatureShowSolarTermIntro"].Value)</li>
<li>@((MarkupString)Localizer["FeatureShowFestivalsIntro"].Value)</li>
<li>@((MarkupString)Localizer["FeatureShowHolidaysIntro"].Value)</li>
</ul>
<div>@((MarkupString)Localizer["FeatureFestivalIntro"].Value)</div>
</Tips>
</section>
</DemoBlock>
<DemoBlock Title="@Localizer["ValidateFormTitle"]" Introduction="@Localizer["ValidateFormIntro"]" Name="ValidateForm">
<ValidateForm Model="this">
<div class="row g-3">
<div class="col-12 col-sm-auto">
<DateTimePicker @bind-Value="@ValidateFormValue" />
</div>
<div class="col-12 col-sm-auto align-self-end">
<Button ButtonType="ButtonType.Submit" Text="@Localizer["SubmitText"]" Icon="fa-solid fa-floppy-disk"></Button>
</div>
</div>
</ValidateForm>
<ValidateForm Model="this">
<div class="row g-3">
<div class="col-12 col-sm-auto">
<DateTimePicker @bind-Value="@ValidateFormValue" />
</div>
<div class="col-12 col-sm-auto align-self-end">
<Button ButtonType="ButtonType.Submit" Text="@Localizer["SubmitText"]" Icon="fa-solid fa-floppy-disk"></Button>
</div>
</div>
</ValidateForm>
</DemoBlock>
<DemoBlock Title="@Localizer["ShowIconTitle"]" Introduction="@Localizer["ShowIconIntro"]" Name="ShowIcon">
<DateTimePicker TValue="DateTimeOffset?" ShowIcon="false" />
<DateTimePicker TValue="DateTimeOffset ?" ShowIcon="false" />
</DemoBlock>
<DemoBlock Title="@Localizer["DateTimeOffsetTitle"]" Introduction="@Localizer["DateTimeOffsetIntro"]" Name="DateTimeOffset">
<DateTimePicker @bind-Value="DateTimeOffsetValue" />
<DateTimePicker @bind-Value="DateTimeOffsetValue" />
</DemoBlock>
<DemoBlock Title="@Localizer["BindValueTitle"]" Introduction="@Localizer["BindValueIntro"]" Name="BindValue">
<div class="row g-3">
<div class="col-sm-6">
<DateTimePicker @bind-Value="@BindValue" IsEditable="true" DateFormat="dd/MM/yyyy" />
</div>
<div class="col-sm-6">
<input class="form-control" @bind="@BindValueString" />
</div>
</div>
<div class="row g-3">
<div class="col-sm-6">
<DateTimePicker @bind-Value="@BindValue" IsEditable="true" DateFormat="dd/MM/yyyy" />
</div>
<div class="col-sm-6">
<input class="form-control" @bind="@BindValueString" />
</div>
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["IsEditableTitle"]" Introduction="@Localizer["IsEditableIntro"]" Name="IsEditable">
<div class="row g-3">
<div class="col-sm-6">
<DateTimePicker @bind-Value="@BindValue" IsEditable="true" DateFormat="yyyy-MM-dd" />
</div>
</div>
<div class="row g-3">
<div class="col-sm-6">
<DateTimePicker @bind-Value="@BindValue" IsEditable="true" DateFormat="yyyy-MM-dd" />
</div>
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["ViewModeTitle"]" Introduction="@Localizer["ViewModeIntro"]" Name="ViewMode">
<section ignore>@((MarkupString)Localizer["ViewModeTip"].Value)</section>
<div class="row g-3">
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="YearValue" ShowLabel="true" DisplayText="Year" ViewMode="DatePickerViewMode.Year" DateFormat="yyyy" />
</div>
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="MonthValue" ShowLabel="true" DisplayText="Month" ViewMode="DatePickerViewMode.Month" DateFormat="yyyy-MM" />
</div>
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="DateValue" ShowLabel="true" DisplayText="Date" ViewMode="DatePickerViewMode.Date" DateFormat="yyyy-MM-dd" />
</div>
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="DateTimeValue" ShowLabel="true" DisplayText="DateTime" ViewMode="DatePickerViewMode.DateTime" DateTimeFormat="yyyy-MM-dd HH:mm:ss" />
</div>
</div>
<section ignore>@((MarkupString)Localizer["ViewModeTip"].Value)</section>
<div class="row g-3">
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="YearValue" ShowLabel="true" DisplayText="Year" ViewMode="DatePickerViewMode.Year" DateFormat="yyyy" />
</div>
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="MonthValue" ShowLabel="true" DisplayText="Month" ViewMode="DatePickerViewMode.Month" DateFormat="yyyy-MM" />
</div>
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="DateValue" ShowLabel="true" DisplayText="Date" ViewMode="DatePickerViewMode.Date" DateFormat="yyyy-MM-dd" />
</div>
<div class="col-12 col-sm-6">
<DateTimePicker @bind-Value="DateTimeValue" ShowLabel="true" DisplayText="DateTime" ViewMode="DatePickerViewMode.DateTime" DateTimeFormat="yyyy-MM-dd HH:mm:ss" />
</div>
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["NullValueTitle"]" Introduction="@Localizer["NullValueIntro"]" Name="NullValue">
<section ignore>@((MarkupString)Localizer["NullValueTip"].Value)</section>
<div class="row g-3">
<div class="col-12 col-sm-8">
<DateTimePicker @bind-Value="@BindNullValue" />
</div>
<div class="col-12 col-sm-4">
<Display TValue="string" Value="@GetNullValueString" />
</div>
</div>
<section ignore>@((MarkupString)Localizer["NullValueTip"].Value)</section>
<div class="row g-3">
<div class="col-12 col-sm-8">
<DateTimePicker @bind-Value="@BindNullValue" />
</div>
<div class="col-12 col-sm-4">
<Display TValue="string" Value="@GetNullValueString" />
</div>
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["ShowLabelTitle"]" Introduction="@Localizer["ShowLabelIntro"]" Name="ShowLabel">
<section ignore class="mb-3">
@((MarkupString)Localizer["ShowLabelTip"].Value)
</section>
<DateTimePicker ShowLabel="true" DisplayText="@Localizer["DisplayText"]" @bind-Value="@ShowLabelValue" />
<section ignore class="mb-3">
@((MarkupString)Localizer["ShowLabelTip"].Value)
</section>
<DateTimePicker ShowLabel="true" DisplayText="@Localizer["DisplayText"]" @bind-Value="@ShowLabelValue" />
</DemoBlock>
<DemoBlock Title="@Localizer["DisabledTitle"]" Introduction="@Localizer["DisabledIntro"]" Name="IsDisabled">
<div class="row g-3">
<div class="col-12 col-sm-6">
<DateTimePicker IsDisabled="IsDisabled" Value="DateTime.Today" />
</div>
<div class="col-12 col-sm-6">
<Switch @bind-Value="@IsDisabled" />
</div>
</div>
<div class="row g-3">
<div class="col-12 col-sm-6">
<DateTimePicker IsDisabled="IsDisabled" Value="DateTime.Today" />
</div>
<div class="col-12 col-sm-6">
<Switch @bind-Value="@IsDisabled" />
</div>
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["ShowSidebarTitle"]" Introduction="@Localizer["ShowSidebarIntro"]" Name="ShowSidebar">
<DateTimePicker ShowSidebar="true" @bind-Value="SidebarValue" />
<DateTimePicker ShowSidebar="true" @bind-Value="SidebarValue" />
</DemoBlock>
<DemoBlock Title="@Localizer["MinValueTitle"]" Introduction="@Localizer["MinValueIntro"]" Name="MinValue">
<DateTimePicker @bind-Value="@AllowValue"
MinValue="@(DateTime.Today.AddDays(1 - DateTime.Today.Day))"
MaxValue="@(DateTime.Today.AddDays(46 - DateTime.Today.Day))" />
<DateTimePicker @bind-Value="@AllowValue"
MinValue="@(DateTime.Today.AddDays(1 - DateTime.Today.Day))"
MaxValue="@(DateTime.Today.AddDays(46 - DateTime.Today.Day))" />
</DemoBlock>
<DemoBlock Title="@Localizer["BlockAutoCloseTitle"]" Introduction="@Localizer["BlockAutoCloseIntro"]" Name="AutoClose">
<section ignore class="mb-3">
@((MarkupString)Localizer["BlockAutoCloseDesc"].Value)
</section>
<DateTimePicker @bind-Value="@AutoCloseValue" AutoClose="false" />
<section ignore class="mb-3">
@((MarkupString)Localizer["BlockAutoCloseDesc"].Value)
</section>
<DateTimePicker @bind-Value="@AutoCloseValue" AutoClose="false" />
</DemoBlock>
<DemoBlock Title="@Localizer["BlockGroupTitle"]" Introduction="@Localizer["BlockGroupIntro"]" Name="Group">
<div class="row g-3">
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupLabel"]" />
<DateTimePicker TValue="DateTime" ShowIcon="false" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<DateTimePicker TValue="DateTime" />
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupSuffixLabel"]" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupLabel"]" />
<DateTimePicker TValue="DateTime" ShowIcon="false" />
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupSuffixLabel"]" />
</BootstrapInputGroup>
</div>
</div>
<div class="row g-3">
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupLabel"]" />
<DateTimePicker TValue="DateTime" ShowIcon="false" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<DateTimePicker TValue="DateTime" />
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupSuffixLabel"]" />
</BootstrapInputGroup>
</div>
<div class="col-12 col-sm-6">
<BootstrapInputGroup>
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupLabel"]" />
<DateTimePicker TValue="DateTime" ShowIcon="false" />
<BootstrapInputGroupLabel DisplayText="@Localizer["BlockGroupSuffixLabel"]" />
</BootstrapInputGroup>
</div>
</div>
</DemoBlock>
<DemoBlock Title="@Localizer["DayTemplateTitle"]" Introduction="@Localizer["DayTemplateIntro"]" Name="DayTemplate">
<DateTimePicker TValue="DateTimeOffset?" CustomClass="custom-picker">
<DayTemplate>
<span class="custom-cell">
<span>@context.Day</span>
<span class="@GetMarkByDay(context)"></span>
</span>
</DayTemplate>
</DateTimePicker>
<DateTimePicker TValue="DateTimeOffset ?" CustomClass="custom-picker">
<DayTemplate>
<span class="custom-cell">
<span>@context.Day</span>
<span class="@GetMarkByDay(context)"></span>
</span>
</DayTemplate>
</DateTimePicker>
</DemoBlock>
<DemoBlock Title="@Localizer["DisableDayCallbackTitle"]" Introduction="@Localizer["DisableDayCallbackIntro"]" Name="OnDisabledDayCallback">
<section ignore>
<Tips>
@((MarkupString)Localizer["DisableDayCallbackTip"].Value)
</Tips>
<GroupBox Title="@Localizer["DisableOptions"]">
<div class="row g-3 form-inline text-end">
<div class="col-12 col-sm-6 col-md-auto">
<Switch DisplayText="@Localizer["DisableWeekend"]" ShowLabel="true" @bind-Value="_disableWeekend" OnValueChanged="OnDisabledDaysChanged" />
</div>
<div class="col-12 col-sm-6 col-md-auto">
<Switch DisplayText="@Localizer["DisableToday"]" ShowLabel="true" @bind-Value="_disableToday" OnValueChanged="OnDisabledDaysChanged" />
</div>
</div>
</GroupBox>
</section>
<div class="row form-inline g-3">
<div class="col-12 col-sm-6">
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" DisplayText="@Localizer["DisableDayCallbackAllowNullDisplayText"]"
ShowLabel="true" @bind-Value="@_disabledNullValue" @ref="_picker1"
OnGetDisabledDaysCallback="OnGetDisabledDaysCallback" DisplayDisabledDayAsEmpty="true">
</DateTimePicker>
</div>
<div class="col-12 col-sm-6">
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" DisplayText="@Localizer["DisableDayCallbackNotAllowNullDisplayText"]"
ShowLabel="true" @bind-Value="@_disabledValue" @ref="_picker2"
OnGetDisabledDaysCallback="OnGetDisabledDaysCallback">
</DateTimePicker>
</div>
</div>
<section ignore>
<Tips>
@((MarkupString)Localizer["DisableDayCallbackTip"].Value)
</Tips>
<GroupBox Title="@Localizer["DisableOptions"]">
<div class="row g-3 form-inline text-end">
<div class="col-12 col-sm-6 col-md-auto">
<Switch DisplayText="@Localizer["DisableWeekend"]" ShowLabel="true" @bind-Value="_disableWeekend" OnValueChanged="OnDisabledDaysChanged" />
</div>
<div class="col-12 col-sm-6 col-md-auto">
<Switch DisplayText="@Localizer["DisableToday"]" ShowLabel="true" @bind-Value="_disableToday" OnValueChanged="OnDisabledDaysChanged" />
</div>
</div>
</GroupBox>
</section>
<div class="row form-inline g-3">
<div class="col-12 col-sm-6">
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" DisplayText="@Localizer["DisableDayCallbackAllowNullDisplayText"]"
ShowLabel="true" @bind-Value="@_disabledNullValue" @ref="_picker1"
OnGetDisabledDaysCallback="OnGetDisabledDaysCallback" DisplayDisabledDayAsEmpty="true">
</DateTimePicker>
</div>
<div class="col-12 col-sm-6">
<DateTimePicker ViewMode="DatePickerViewMode.DateTime" DisplayText="@Localizer["DisableDayCallbackNotAllowNullDisplayText"]"
ShowLabel="true" @bind-Value="@_disabledValue" @ref="_picker2"
OnGetDisabledDaysCallback="OnGetDisabledDaysCallback">
</DateTimePicker>
</div>
</div>
</DemoBlock>
<AttributeTable Items="@GetAttributes()" />

View File

@@ -95,6 +95,7 @@ public sealed partial class DateTimePickers
private bool _disableToday = true;
private DateTime? _disabledNullValue = DateTime.Today;
private DateTime _disabledValue = DateTime.Today;
private bool _isButton = false;
private async Task<List<DateTime>> OnGetDisabledDaysCallback(DateTime start, DateTime end)
{

View File

@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '17.0'">
<Version>9.11.5-beta04</Version>
<Version>9.11.5-beta05</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '18.0'">
<Version>10.0.0-rc.2.1.3</Version>
<Version>10.0.0-rc.2.1.4</Version>
</PropertyGroup>
<ItemGroup>

View File

@@ -8,12 +8,21 @@
<BootstrapLabel required="@Required" for="@Id" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText" />
}
<div @attributes="@AdditionalAttributes" tabindex="@TabIndexString" id="@Id" class="@ClassString" data-bb-dropdown=".picker-panel">
<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" />
@if (ShowIcon)
@if(IsButton)
{
<i class="@DateTimePickerIconClassString"></i>
<button type="button" class="@ButtonClassString" disabled="@Disabled"
data-bs-toggle="@Constants.DropdownToggleString" data-bs-placement="@PlacementString"
data-bs-custom-class="@CustomClassString">@PickerButtonText</button>
}
else
{
<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" />
@if (ShowIcon)
{
<i class="@DateTimePickerIconClassString"></i>
}
}
<DatePickerBody @bind-Value="SelectedValue" @ref="_pickerBody" FirstDayOfWeek="FirstDayOfWeek"
ShowClearButton="AllowNull" ShowSidebar="ShowSidebar" SidebarTemplate="SidebarTemplate"

View File

@@ -31,6 +31,10 @@ public partial class DateTimePicker<TValue>
.AddClass(ValidCss)
.Build();
private string? ButtonClassString => CssBuilder.Default("btn dropdown-toggle")
.AddClass($"btn-{ButtonColor.ToDescriptionString()}", ButtonColor != Color.None)
.Build();
/// <summary>
/// 获得 组件小图标样式
/// </summary>
@@ -54,6 +58,24 @@ public partial class DateTimePicker<TValue>
/// </summary>
private bool AllowNull { get; set; }
/// <summary>
/// 获得/设置 是否显示为按钮样式 默认 false
/// </summary>
[Parameter]
public bool IsButton { get; set; }
/// <summary>
/// 获得/设置 选择按钮文本 默认 null 读取资源文件
/// </summary>
[Parameter]
public string? PickerButtonText { get; set; }
/// <summary>
/// 获得/设置 选择按钮颜色 默认 <see cref="Color.Primary"/>
/// </summary>
[Parameter]
public Color ButtonColor { get; set; } = Color.Primary;
/// <summary>
/// 获得/设置 时间格式化字符串 默认值为 null
/// </summary>
@@ -292,6 +314,7 @@ public partial class DateTimePicker<TValue>
DateTimeFormat ??= Localizer[nameof(DateTimeFormat)];
DateFormat ??= Localizer[nameof(DateFormat)];
TimeFormat ??= Localizer[nameof(TimeFormat)];
PickerButtonText ??= Localizer[nameof(PickerButtonText)];
Icon ??= IconTheme.GetIconByKey(ComponentIcons.DateTimePickerIcon);
@@ -371,6 +394,29 @@ public partial class DateTimePicker<TValue>
/// <returns></returns>
protected override bool ShouldRender() => _render;
private bool _isButton = false;
/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="firstRender"></param>
/// <returns></returns>
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
// 首次渲染时同步 IsButton 参数值
_isButton = IsButton;
}
if (_isButton != IsButton)
{
_isButton = IsButton;
await InvokeVoidAsync("reset", Id);
}
}
/// <summary>
/// 格式化数值方法
/// </summary>

View File

@@ -8,6 +8,12 @@ export function init(id, invoke, options) {
return
}
const popover = createPopover(el, invoke, options);
const input = handlerInput(el, popover);
Data.set(id, { el, input, invoke, options, popover });
}
const createPopover = (el, invoke, options) => {
const popover = Popover.init(el, {
dropdownSelector: el.getAttribute('data-bb-dropdown'),
isDisabled: () => {
@@ -19,27 +25,47 @@ export function init(id, invoke, options) {
}
}
});
const input = el.querySelector('.datetime-picker-input');
const dateTimePicker = {
input,
popover
}
Data.set(id, dateTimePicker);
return popover;
}
EventHandler.on(input, 'keydown', e => {
if (e.key === 'Tab' && popover.isShown()) {
popover.hide();
}
});
EventHandler.on(input, 'keyup', e => {
if (e.key === 'Escape') {
popover.hide();
input.blur();
}
else if (e.key === 'Tab') {
popover.show();
}
});
const handlerInput = (el, popover) => {
const input = el.querySelector('.datetime-picker-input');
if (input) {
EventHandler.on(input, 'keydown', e => {
if (e.key === 'Tab' && popover.isShown()) {
popover.hide();
}
});
EventHandler.on(input, 'keyup', e => {
if (e.key === 'Escape') {
popover.hide();
input.blur();
}
else if (e.key === 'Tab') {
popover.show();
}
});
}
return input;
}
const disposeInput = input => {
if (input) {
EventHandler.off(input, 'keydown');
EventHandler.off(input, 'keyup');
}
}
export function reset(id) {
const picker = Data.get(id);
if (picker) {
const { el, input, popover, invoke, options } = picker;
disposeInput(input);
Popover.dispose(popover);
picker.popover = createPopover(el, invoke, options);
picker.input = handlerInput(picker.el, picker.popover);
}
}
export function hide(id) {
@@ -55,8 +81,7 @@ export function dispose(id) {
if (data) {
const { input, popover } = data;
EventHandler.off(input, 'keydown');
EventHandler.off(input, 'keyup');
disposeInput(input);
Popover.dispose(popover)
}
}

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "AutoScroll"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "Picker ...",
"DatePlaceHolder": "Select date",
"TimePlaceHolder": "Select time",
"DateTimePlaceHolderText": "Please select ...",

View File

@@ -34,6 +34,7 @@
"AutoScrollText": "自动滚屏"
},
"BootstrapBlazor.Components.DateTimePicker": {
"PickerButtonText": "选择",
"DatePlaceHolder": "选择日期",
"TimePlaceHolder": "选择时间",
"DateTimePlaceHolderText": "请选择日期时间",

View File

@@ -388,6 +388,25 @@ public class DateTimePickerTest : BootstrapBlazorTestBase
pb.Add(a => a.TimeFormat, null);
});
}
[Fact]
public void IsButton_Ok()
{
var cut = Context.RenderComponent<DateTimePicker<DateTime>>(pb =>
{
pb.Add(a => a.IsButton, true);
pb.Add(a => a.ButtonColor, Color.Danger);
pb.Add(a => a.PickerButtonText, "Pick DateTime");
});
cut.Contains("btn dropdown-toggle btn-danger");
cut.SetParametersAndRender(pb =>
{
pb.Add(a => a.IsButton, false);
});
cut.DoesNotContain("btn dropdown-toggle btn-danger");
cut.Contains("dropdown-toggle form-control datetime-picker-input");
}
#endregion
#region DatePicker