Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
94ebc58
feat(InputNumber):增强数字格式化显示
Tony-ST0754 Sep 5, 2026
c451346
test:补充单元测试完善代码覆盖率
Tony-ST0754 Sep 5, 2026
d955dc9
Revert "test:补充单元测试完善代码覆盖率"
Tony-ST0754 Sep 6, 2026
082cec6
Revert "feat(InputNumber):增强数字格式化显示"
Tony-ST0754 Sep 6, 2026
270cd53
feat:新增InputCurrency组件
Tony-ST0754 Sep 6, 2026
1ec833f
refactor(InputCurrency):重构数据清洗标准化逻辑
Tony-ST0754 Sep 6, 2026
46f90fa
Merge branch 'main' into test-InputNumber-Support-currency-format
ArgoZhang Sep 7, 2026
fe20827
doc:补全文档路径
Tony-ST0754 Sep 8, 2026
560858d
doc:文档示例错误修正
Tony-ST0754 Sep 8, 2026
c96f9c9
refactor: 更改示例文件名称
ArgoZhang Sep 7, 2026
31cb328
refactor: 增加 IsClearable 支持
ArgoZhang Sep 7, 2026
c8f2e7d
refactor: 重新设计 CultureInfo 默认值为 null 使用当前 UI 文化信息
ArgoZhang Sep 7, 2026
9e950f0
refactor: 重新设计组件
ArgoZhang Sep 8, 2026
735a0e5
chore: 增加 scss 源码
ArgoZhang Sep 8, 2026
0858339
doc: 更新示例
ArgoZhang Sep 8, 2026
a668516
refactor: 移除 style 位置
ArgoZhang Sep 8, 2026
c095f8a
refactor(InputCurrency):重构组件输入及格式化显示逻辑
Tony-ST0754 Sep 9, 2026
1b7d41f
refactor: 重构组件
ArgoZhang Sep 10, 2026
a6a43b6
doc: 增加示例
ArgoZhang Sep 10, 2026
c1347da
doc: 更新资源文件
ArgoZhang Sep 10, 2026
1891173
doc: 更新示例
ArgoZhang Sep 10, 2026
2bd93fe
doc:文档一处标记错误纠正
Tony-ST0754 Sep 10, 2026
5deee4d
doc: 更新示例
ArgoZhang Sep 11, 2026
d57c1e5
refactor: 增加脚本过滤非数字字符
ArgoZhang Sep 11, 2026
0920e4f
test: 更新单元测试
ArgoZhang Sep 11, 2026
d03a0a8
revert: 撤销更改
ArgoZhang Sep 11, 2026
fbd393a
refactor: 增加文化缓存提高性能
ArgoZhang Sep 11, 2026
a2ad6e3
test: 增加无地区文化单元测试
ArgoZhang Sep 11, 2026
88ba737
Merge branch 'main' into test-InputNumber-Support-currency-format
ArgoZhang Sep 11, 2026
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
3 changes: 3 additions & 0 deletions localization/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "Das Feld {0} muss eine Zahl sein."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "Das Feld {0} muss eine Zahl sein."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Ja",
"ButtonNoText": "Nein",
Expand Down
3 changes: 3 additions & 0 deletions localization/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "El campo {0} debe ser un número."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "El campo {0} debe ser un número."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Sí",
"ButtonNoText": "No",
Expand Down
3 changes: 3 additions & 0 deletions localization/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "Il campo {0} deve essere un numero."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "Il campo {0} deve essere un numero."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Sì",
"ButtonNoText": "No",
Expand Down
3 changes: 3 additions & 0 deletions localization/km-KH.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "ទិន្នន័យ {0} ត្រូវ​តែ​ជា​លេខ។"
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "ទិន្នន័យ {0} ត្រូវ​តែ​ជា​លេខ។"
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "បាទ/ចាស៎",
"ButtonNoText": "ទេ",
Expand Down
3 changes: 3 additions & 0 deletions localization/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "O campo {0} deve ser um número."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "O campo {0} deve ser um número."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Sim",
"ButtonNoText": "Não",
Expand Down
3 changes: 3 additions & 0 deletions localization/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "O campo {0} deve ser um número."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "O campo {0} deve ser um número."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Sim",
"ButtonNoText": "Não",
Expand Down
3 changes: 3 additions & 0 deletions localization/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "Поле {0} должно быть числом."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "Поле {0} должно быть числом."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Да",
"ButtonNoText": "Нет",
Expand Down
3 changes: 3 additions & 0 deletions localization/th-TH.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "ฟิลด์ {0} ต้องเป็นตัวเลข"
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "ฟิลด์ {0} ต้องเป็นตัวเลข"
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "ใช่",
"ButtonNoText": "ไม่ใช่",
Expand Down
3 changes: 3 additions & 0 deletions localization/uk-UA.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "Поле {0} має бути числом."
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "Поле {0} має бути числом."
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "Так",
"ButtonNoText": "Ні",
Expand Down
3 changes: 3 additions & 0 deletions localization/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
"BootstrapBlazor.Components.BootstrapInputNumber": {
"ParsingErrorMessage": "{0}欄位值必須為 Number 類型"
},
"BootstrapBlazor.Components.BootstrapInputCurrency": {
"ParsingErrorMessage": "{0}欄位值必須為 Number 類型"
},
"BootstrapBlazor.Components.ResultDialogOption": {
"ButtonYesText": "確認",
"ButtonNoText": "取消",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
@page "/input-currency"

@inject IStringLocalizer<InputCurrencies> Localizer

<h3>@Localizer["InputCurrencyTitle"]</h3>
<h4>@Localizer["InputCurrencyDescription"]</h4>
<h4>@((MarkupString)Localizer["InputCurrencyMemo"].Value)</h4>

<DemoBlock Title="@Localizer["InputCurrencyNormalTitle"]"
Introduction="@Localizer["InputCurrencyNormalIntro"]"
Name="Normal">
<section ignore>
<div class="form-inline row g-2">
<div class="col-12 col-sm-6">
<Switch @bind-Value="@_showIsoCurrencySymbol" ShowLabel="true" DisplayText="Iso"></Switch>
</div>
<div class="col-12 col-sm-6">
<Switch @bind-Value="@_showClearIcon" ShowLabel="true" DisplayText="Cleable"></Switch>
</div>
</div>
</section>
<div class="demo-input-currency">
<BootstrapInputCurrency @bind-Value="@_value" style="width: 160px;"
ShowIsoCurrencySymbol="@_showIsoCurrencySymbol" IsClearable="@_showClearIcon">
</BootstrapInputCurrency>
</div>
</DemoBlock>

<DemoBlock Title="@Localizer["InputCurrencyCultureTitle"]"
Introduction="@Localizer["InputCurrencyCultureIntro"]"
Name="CultureName">
<section ignore>@((MarkupString)Localizer["InputCurrencyCultureDesc"].Value)</section>
<div class="row g-2">
<div class="col-12 col-sm-6">
<BootstrapInputCurrency Value="@_value" ShowLabel="true" DisplayText="人民币" CultureName="zh-CN" Decimals="3" />
</div>
<div class="col-12 col-sm-6">
<BootstrapInputCurrency Value="@_value" ShowLabel="true" DisplayText="葡萄牙货币" CultureName="pt-BR" />
</div>
</div>
</DemoBlock>

<DemoBlock Title="货币符号模板"
Introduction="通过设置 <code>SymbolTemplate</code> 自定义货币显示内容"
Name="SymbolTemplate">
<BootstrapInputCurrency Value="@_value" style="width: 160px;">
<SymbolTemplate>
<span class="fa-solid fa-flag"></span>
</SymbolTemplate>
</BootstrapInputCurrency>
</DemoBlock>

<DemoBlock Title="@Localizer["InputCurrencyRangeTitle"]"
Introduction="@Localizer["InputCurrencyRangeIntro"]"
Name="Range">
<BootstrapInputCurrency Value="@_value2" Max="10" Min="1" style="width: 160px;" />
</DemoBlock>

<AttributeTable Type="typeof(BootstrapInputCurrency)" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone

namespace BootstrapBlazor.Server.Components.Samples;

/// <summary>
/// <para lang="zh">InputCurrencies 组件</para>
/// <para lang="en">InputCurrencies component</para>
/// </summary>
public partial class InputCurrencies
{
private decimal _value = 1234.56m;

private decimal _value2 = 2m;

private bool _showIsoCurrencySymbol;
private bool _showClearIcon;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,11 @@ void AddForm(DemoMenuItem item)
Url = "input-number"
},
new()
{
Text = Localizer["BootstrapInputCurrency"],
Url = "input-currency"
},
new()
{
Text = Localizer["BootstrapInputGroup"],
Url = "input-group"
Expand Down
18 changes: 17 additions & 1 deletion src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
"BootstrapInput": "BootstrapInput",
"BootstrapInputGroup": "BootstrapInputGroup",
"BootstrapInputNumber": "BootstrapInputNumber",
"BootstrapInputCurrency": "BootstrapInputCurrency",
"BootstrapLabel": "Labels",
"Breadcrumb": "Breadcrumb",
"Breakpoints": "Breakpoints",
Expand Down Expand Up @@ -2771,6 +2772,22 @@
"IntersectionObserverIntro": "By setting <code>IsIntersectionObserver=\"true\"</code> to enable lazy loading, the image will not be loaded when it is in the invisible area, and will be loaded only when it is about to be visible.",
"IntersectionObserverTitle": "Intersection Observer"
},
"BootstrapBlazor.Server.Components.Samples.InputCurrencies": {
"InputCurrencyCultureDesc": "Specify Brazilian Portuguese, for example: <code>pt-BR</code>; note that the thousand separator is a <code>dot</code> and the decimal separator is a <code>comma</code>; you can specify the number of decimal places using the <code>Decimals</code> parameter",
"InputCurrencyCultureIntro": "Specify culture information, for example: <code>en-US, zh-CN</code>",
"InputCurrencyCultureTitle": "Specify culture name",
"InputCurrencyCustomizeIntro": "Use the <code>Formatter</code> callback to achieve custom format usage",
"InputCurrencyCustomizeTitle": "Custom format usage",
"InputCurrencyDescription": "Only allows standard numeric values and provides formatting capabilities, for example: entering 12345.78 displays as 12,345.78 with thousand separators; as ¥12,345.78 for currency; and as 12,345.78% for percentage.",
"InputCurrencyMemo": "This component is actually an extension of the <code>InputNumbers</code> component, designed to meet the need to display formatted numeric values such as currency and percentages in the <code>UI</code>.",
"InputCurrencyNormalIntro": "<code>Number</code> numeric type displays a text box, automatically bringing up the numeric keyboard on mobile devices",
"InputCurrencyNormalTitle": "Basic usage",
"InputCurrencyPercentIntro": "You can use <code>Formatter</code> or <code>FormatString</code> to achieve percentage display",
"InputCurrencyPercentTitle": "Percentage usage",
"InputCurrencyRangeIntro": "Set <code>Max</code> and <code>Min</code> to control the numeric range 1-10",
"InputCurrencyRangeTitle": "Range limitation usage",
"InputCurrencyTitle": "InputCurrency"
},
"BootstrapBlazor.Server.Components.Samples.InputGroups": {
"InputGroupsCheckboxIntro": "Add <code>Checkbox</code> or <code>CheckboxList</code> to the <code>InputGroup</code>",
"InputGroupsCheckboxTitle": "Checkbox",
Expand Down Expand Up @@ -6067,7 +6084,6 @@
"Picture.Required": "{0} is required"
},
"BootstrapBlazor.Server.Components.Samples.ValidateForms": {
"AsyncValidationError": "The user name already exists.",
"AsyncValidationUserName": "User name",
"ChangeButtonText": "Change",
"CustomValidationFormComment1": "Add mailbox validation rules",
Expand Down
18 changes: 17 additions & 1 deletion src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
"BootstrapInput": "输入框 BootstrapInput",
"BootstrapInputGroup": "输入组 BootstrapInputGroup",
"BootstrapInputNumber": "数字框 BootstrapInputNumber",
"BootstrapInputCurrency": "货币框 BootstrapInputCurrency",
"BootstrapLabel": "表单标签",
"Breadcrumb": "面包屑 Breadcrumb",
"Breakpoints": "断点阈值",
Expand Down Expand Up @@ -2771,6 +2772,22 @@
"IntersectionObserverIntro": "通过设置 <code>IsIntersectionObserver=\"true\"</code> 开启懒加载特性,当图片在不可见区域时不加载图片,当图片即将可见时才开始加载图片",
"IntersectionObserverTitle": "懒加载"
},
"BootstrapBlazor.Server.Components.Samples.InputCurrencies": {
"InputCurrencyCultureDesc": "指定巴西葡萄牙语,例如:<code>pt-BR</code>;注意千分符为 <code>点号</code>,小数点符号为 <code>逗号</code>;可以通过 <code>Decimals</code> 指定小数位数",
"InputCurrencyCultureIntro": "自行指定文化信息,例如:<code>en-US、zh-CN</code>",
"InputCurrencyCultureTitle": "指定文化名称",
"InputCurrencyCustomizeIntro": "使用 <code>Formatter</code> 回调来实现自定义格式用法",
"InputCurrencyCustomizeTitle": "自定义格式用法",
"InputCurrencyDescription": "仅允许输入标准的数字值,并提供格式化功能,例如:输入12345.78,千分位显示:12,345.78;货币显示:¥12,345.78;百分比显示:12,345.78%",
"InputCurrencyMemo": "本组件,实际上是 <code>InputNumbers</code> 组件的扩展,以满足有需要在 <code>UI</code> 中显示货币、百分比等格式化数值的需求",
"InputCurrencyNormalIntro": "<code>Number</code> 数值类型显示文本框,移动端自动弹出数字键盘",
"InputCurrencyNormalTitle": "基础用法",
"InputCurrencyPercentIntro": "可使用 <code>Formatter</code> 或 <code>FormatString</code> 来实现百分比显示",
"InputCurrencyPercentTitle": "百分比用法",
"InputCurrencyRangeIntro": "设置 <code>Max</code> <code>Min</code> 来控制数值区间范围 1-10",
"InputCurrencyRangeTitle": "区间限制用法",
"InputCurrencyTitle": "InputCurrency 组件"
},
"BootstrapBlazor.Server.Components.Samples.InputGroups": {
"InputGroupsCheckboxIntro": "往 <code>InputGroup</code> 里面增加 <code>Checkbox</code> 或者 <code>CheckboxList</code>",
"InputGroupsCheckboxTitle": "复选框组合",
Expand Down Expand Up @@ -6067,7 +6084,6 @@
"Picture.Required": "上传文件不能为空"
},
"BootstrapBlazor.Server.Components.Samples.ValidateForms": {
"AsyncValidationError": "用户名已存在",
"AsyncValidationUserName": "用户名",
"ChangeButtonText": "更改组件",
"CustomValidationFormComment1": "增加邮箱验证规则",
Expand Down
2 changes: 2 additions & 0 deletions src/BootstrapBlazor.Server/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"iframe": "IFrames",
"image-viewer": "ImageViewers",
"input-number": "InputNumbers",
"input-currency": "InputCurrencies",
"input": "Inputs",
"input-group": "InputGroups",
"ip": "Ips",
Expand Down Expand Up @@ -406,6 +407,7 @@
"BootstrapInputEventBase",
"BootstrapInputGroup",
"BootstrapInputGroupIcon",
"BootstrapInputCurrency",
"BootstrapInputNumber",
"BootstrapInputNumberBase",
"Button",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@namespace BootstrapBlazor.Components
@inherits BootstrapInputBase<decimal>

@if (IsShowLabel)
{
<BootstrapLabel required="@Required" for="@Id" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText" />
}

<div @attributes="AdditionalAttributes" class="bb-input-currency input-group" id="@Id">
<div class="input-group-text">
@if (SymbolTemplate != null)
{
@SymbolTemplate
}
else
{
@_currencySymbol
}
</div>
@if (IsClearable && !IsDisabled && !Readonly)
{
<div class="bb-clearable-input">
@RenderInput
<i class="@ClearableIconString" @onclick="OnClickClear"></i>
</div>
}
else
{
@RenderInput
}
</div>

@code {
RenderFragment RenderInput =>
@<input type="text" inputmode="decimal" id="@InputId"
placeholder="@PlaceHolder" class="@InputClassString"
readonly="@ReadonlyString" disabled="@Disabled"
@bind="@CurrentValueAsString" @onblur="@OnBlur" />;
}
Loading
Loading