Skip to content

Commit a0fc459

Browse files
ArgoZhangice6github-actions[bot]
authored
feat(TextArea): add UseShiftEnter parameter (#5351)
* feat: 增加 OnKeyUpAsync 参数 * refactor: 精简代码 * refactor: 重构代码 * doc: 更新示例 * refactor: 移除不需要的 OnKeyDownAsync 回调 * doc: 更新示例文档 * doc: 增加参数说明文档 * doc: 精简代码 * test: 更新单元测试 Co-Authored-By: ice6 <[email protected]> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 7b78b81 commit a0fc459

File tree

9 files changed

+89
-28
lines changed

9 files changed

+89
-28
lines changed

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

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,59 +9,60 @@
99
<DemoBlock Title="@Localizer["TextAreaNormalTitle"]"
1010
Introduction="@Localizer["TextAreaNormalIntro"]"
1111
Name="Normal">
12-
<label class="form-label mb-3">@Localizer["TextAreaLabel"]</label>
1312
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" />
1413
</DemoBlock>
1514

1615
<DemoBlock Title="@Localizer["TextAreaDisableTitle"]"
1716
Introduction="@Localizer["TextAreaDisableIntro"]"
1817
Name="IsDisabled">
19-
<label class="form-label mb-3">@Localizer["TextAreaLabel"]</label>
2018
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" IsDisabled="true" />
2119
</DemoBlock>
2220

2321
<DemoBlock Title="@Localizer["TextAreaReadOnlyTitle"]"
2422
Introduction="@Localizer["TextAreaReadOnlyIntro"]"
2523
Name="ReadOnly">
26-
<label class="form-label mb-3">@Localizer["TextAreaLabel"]</label>
27-
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" readonly />
24+
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" readonly />
2825
</DemoBlock>
2926

3027
<DemoBlock Title="@Localizer["TextAreaHeightTitle"]"
3128
Introduction="@Localizer["TextAreaHeightIntro"]"
3229
Name="Rows">
33-
<label class="form-label mb-3">@Localizer["TextAreaLabel"]</label>
34-
35-
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" />
30+
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" />
3631
</DemoBlock>
3732

3833
<DemoBlock Title="@Localizer["TextAreaBindWayTitle"]"
3934
Introduction="@Localizer["TextAreaBindWayIntro"]"
4035
Name="BindValue">
41-
<div class="row g-3">
42-
<div class="col-12">
43-
<label class="form-label">@Localizer["TextAreaLabel"]</label>
44-
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" @bind-Value="@Text"></Textarea>
45-
</div>
36+
<Textarea PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="4" @bind-Value="@Text"></Textarea>
37+
<section ignore class="row g-3">
4638
<div class="col-12">
4739
<label class="form-label">@Localizer["TextAreaBindWayBindValue"]</label>
4840
<div class="form-control textarea-demo">@Text</div>
4941
</div>
50-
</div>
42+
</section>
5143
</DemoBlock>
5244

5345
<DemoBlock Title="@Localizer["TextAreaScrollTitle"]"
5446
Introduction="@Localizer["TextAreaScrollIntro"]"
5547
Name="IsAutoScroll">
5648
<Textarea class="mb-3" PlaceHolder="@Localizer["TextAreaPlaceHolder"]" rows="10" @ref="TextareaElement" @bind-Value="@ChatText" IsAutoScroll="IsAutoScroll" />
49+
<section ignore>
50+
<BootstrapInputGroup>
51+
<Button Text="@Localizer[ChatLocalizerName]" OnClick="MockChat" Icon="fa-fw fas fa-comments" />
52+
<Button Text="@Localizer["TextAreaScrollToTop"]" OnClick="ScrollToTop" />
53+
<Button Text="@Localizer["TextAreaScrollToBottom"]" OnClick="ScrollToBottom" />
54+
<Button Text="@Localizer["TextAreaScrollTo"]" OnClick="ScrollTo20" />
55+
<Button Text="@($"{Localizer["TextAreaAutoScroll"]}{(IsAutoScroll ? " On":" Off")}" )" OnClick="SwitchAutoScroll" />
56+
</BootstrapInputGroup>
57+
</section>
58+
</DemoBlock>
5759

58-
<BootstrapInputGroup>
59-
<Button Text="@Localizer[ChatLocalizerName]" OnClick="MockChat" Icon="fa-fw fas fa-comments" />
60-
<Button Text="@Localizer["TextAreaScrollToTop"]" OnClick="ScrollToTop" />
61-
<Button Text="@Localizer["TextAreaScrollToBottom"]" OnClick="ScrollToBottom" />
62-
<Button Text="@Localizer["TextAreaScrollTo"]" OnClick="ScrollTo20" />
63-
<Button Text="@($"{Localizer["TextAreaAutoScroll"]}{(IsAutoScroll ? " On":" Off")}" )" OnClick="SwitchAutoScroll" />
64-
</BootstrapInputGroup>
60+
<DemoBlock Title="@Localizer["TextAreaUseShiftEnterTitle"]"
61+
Introduction="@Localizer["TextAreaUseShiftEnterIntro"]"
62+
Name="UseShiftEnter">
63+
<Textarea rows="4" autocomplete="off" autocorrect="off" spellcheck="false"
64+
UseInputEvent="true" UseShiftEnter="true" PlaceHolder="@Localizer["TextAreaUseShiftEnterPlaceHolder"]"
65+
@bind-Value="@KeyText"></Textarea>
6566
</DemoBlock>
6667

6768
<AttributeTable Items="@GetAttributes()" />

src/BootstrapBlazor.Server/Components/Samples/TextAreas.razor.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public partial class TextAreas
1515

1616
private string? Text { get; set; }
1717

18+
private string? KeyText { get; set; }
19+
1820
private string? ChatText { get; set; }
1921

2022
private int ScrollValue { get; set; }
@@ -163,11 +165,19 @@ private AttributeItem[] GetAttributes() =>
163165
},
164166
new()
165167
{
166-
Name = nameof(BootstrapBlazor.Components.Textarea.IsAutoScroll),
168+
Name = nameof(Textarea.IsAutoScroll),
167169
Description = Localizer["TextAreaAutoScroll"],
168170
Type = "bool",
169171
ValueList = "true|false",
170172
DefaultValue = "false"
173+
},
174+
new()
175+
{
176+
Name = nameof(Textarea.UseShiftEnter),
177+
Description = Localizer["TextAreaUseShiftEnter"],
178+
Type = "bool",
179+
ValueList = "true|false",
180+
DefaultValue = "false"
171181
}
172182
];
173183
}

src/BootstrapBlazor.Server/Locales/en-US.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3280,7 +3280,11 @@
32803280
"TextAreaScrollToBottom": "Scroll to bottom",
32813281
"TextAreaScrollToTop": "Scroll to top",
32823282
"TextAreaScrollTo": "Scroll +20",
3283-
"TextAreaAutoScroll": "Automatic scrolling"
3283+
"TextAreaAutoScroll": "Automatic scrolling",
3284+
"TextAreaUseShiftEnterTitle": "Shift Enter",
3285+
"TextAreaUseShiftEnterIntro": "By setting <code>UseShiftEnter=\"true\"</code> you can start using <kbd>Shift</kbd> + <kbd>Enter</kbd> for line breaks, which is suitable for dialog applications.",
3286+
"TextAreaUseShiftEnterPlaceHolder": "Please enter some text, Enter sends Shift + Enter line break",
3287+
"TextAreaUseShiftEnter": "Whether to use Shift + Enter instead of the original Enter key behavior"
32843288
},
32853289
"BootstrapBlazor.Server.Components.Samples.Toggles": {
32863290
"TogglesOnText": "On",

src/BootstrapBlazor.Server/Locales/zh-CN.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3280,7 +3280,11 @@
32803280
"TextAreaScrollToBottom": "滚动到底部",
32813281
"TextAreaScrollToTop": "滚动到顶部",
32823282
"TextAreaScrollTo": "滚动+20",
3283-
"TextAreaAutoScroll": "自动滚屏"
3283+
"TextAreaAutoScroll": "自动滚屏",
3284+
"TextAreaUseShiftEnterTitle": "Shift Enter",
3285+
"TextAreaUseShiftEnterIntro": "通过设置 <code>UseShiftEnter=\"true\"</code> 开始使用 <kbd>Shift</kbd> + <kbd>Enter</kbd> 进行换行操作,适用于对话框类应用",
3286+
"TextAreaUseShiftEnterPlaceHolder": "请输入一些文字,Enter 发送 Shift + Enter 换行",
3287+
"TextAreaUseShiftEnter": "是否使用 Shift + Enter 代替原回车按键行为"
32843288
},
32853289
"BootstrapBlazor.Server.Components.Samples.Toggles": {
32863290
"TogglesOnText": "开启",

src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { debounce, getHeight } from "../../modules/utility.js"
1+
import { debounce } from "../../modules/utility.js"
22
import { handleKeyUp, select, selectAllByFocus, selectAllByEnter } from "../Input/BootstrapInput.razor.js"
33
import Data from "../../modules/data.js"
44
import EventHandler from "../../modules/event-handler.js"

src/BootstrapBlazor/Components/Textarea/Textarea.razor

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
{
77
<BootstrapLabel required="@Required" for="@Id" ShowLabelTooltip="ShowLabelTooltip" Value="@DisplayText" />
88
}
9-
<textarea @attributes="AdditionalAttributes" placeholder="@PlaceHolder" id="@Id" class="@ClassName" disabled="@Disabled" @bind-value="@CurrentValueAsString" @bind-value:event="@EventString" @onblur="OnBlur" data-bb-scroll="@AutoScrollString" @ref="FocusElement"></textarea>
9+
<textarea @attributes="AdditionalAttributes" placeholder="@PlaceHolder" id="@Id" class="@ClassName" disabled="@Disabled"
10+
@bind-value="CurrentValueAsString" @bind-value:event="@EventString" @onblur="@OnBlur"
11+
data-bb-shift-enter="@_shiftEnterString" data-bb-scroll="@AutoScrollString" @ref="FocusElement"></textarea>

src/BootstrapBlazor/Components/Textarea/Textarea.razor.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,19 @@ public partial class Textarea
3434
[Parameter]
3535
public bool IsAutoScroll { get; set; }
3636

37+
/// <summary>
38+
/// 获得/设置 是否使用 Shift + Enter 代替原回车按键行为 默认为 false
39+
/// </summary>
40+
[Parameter]
41+
public bool UseShiftEnter { get; set; }
42+
3743
/// <summary>
3844
/// 获得 客户端是否自动滚屏标识
3945
/// </summary>
4046
private string? AutoScrollString => IsAutoScroll ? "auto" : null;
4147

48+
private string? _shiftEnterString => UseShiftEnter ? "true" : null;
49+
4250
/// <summary>
4351
/// <inheritdoc/>
4452
/// </summary>

src/BootstrapBlazor/Components/Textarea/Textarea.razor.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
import { select, handleKeyUp, selectAllByFocus, selectAllByEnter } from "../Input/BootstrapInput.razor.js"
22
import Data from "../../modules/data.js"
3+
import EventHandler from "../../modules/event-handler.js"
34

45
export function init(id) {
6+
var el = document.getElementById(id);
57
const text = {
68
prevMethod: '',
7-
element: document.getElementById(id)
9+
element: el
810
}
911

10-
Data.set(id, text)
12+
Data.set(id, text);
13+
EventHandler.on(el, 'keydown', e => {
14+
if (e.key === "Enter" || e.key === "NumpadEnter") {
15+
const useShiftEnter = el.getAttribute('data-bb-shift-enter') === 'true';
16+
const shiftKey = e.shiftKey;
17+
if (!shiftKey || !useShiftEnter) {
18+
e.preventDefault();
19+
}
20+
}
21+
});
1122
}
1223

1324
export function execute(id, method, position) {
@@ -36,7 +47,12 @@ export function execute(id, method, position) {
3647
}
3748

3849
export function dispose(id) {
39-
Data.remove(id)
50+
const text = Data.get(id);
51+
Data.remove(id);
52+
53+
if (text) {
54+
EventHandler.off(text.element);
55+
}
4056
}
4157

4258
export { select, handleKeyUp, selectAllByFocus, selectAllByEnter }

test/UnitTest/Components/TextareaTest.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,20 @@ public async Task OnBlurAsync_Ok()
7676
await cut.InvokeAsync(() => { input.Blur(); });
7777
Assert.True(blur);
7878
}
79+
80+
[Fact]
81+
public void UseShiftEnter_Ok()
82+
{
83+
var cut = Context.RenderComponent<Textarea>(builder =>
84+
{
85+
builder.Add(a => a.UseShiftEnter, true);
86+
});
87+
cut.Contains("data-bb-shift-enter=\"true\"");
88+
89+
cut.SetParametersAndRender(pb =>
90+
{
91+
pb.Add(a => a.UseShiftEnter, false);
92+
});
93+
cut.DoesNotContain("data-bb-shift-enter=\"true\"");
94+
}
7995
}

0 commit comments

Comments
 (0)