diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml
index f9c6c70614..fd33e4bec6 100644
--- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml
+++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml
@@ -9813,6 +9813,15 @@
Removes all queued toasts with toast intent Custom
+
+
+
+
+
+
+
+
+
Gets or sets the toolbar's orentation. See
@@ -9823,6 +9832,11 @@
Gets or sets the content to be rendered inside the component.
+
+
+ Gets or sets a value indicating whether arrow key navigation within text input fields is enabled. Default is false.
+
+
Gets or sets a reference to the list of registered services.
diff --git a/src/Core/Components/Toolbar/FluentToolbar.razor.cs b/src/Core/Components/Toolbar/FluentToolbar.razor.cs
index 618ac03e94..cb63ffdf1b 100644
--- a/src/Core/Components/Toolbar/FluentToolbar.razor.cs
+++ b/src/Core/Components/Toolbar/FluentToolbar.razor.cs
@@ -1,9 +1,24 @@
using Microsoft.AspNetCore.Components;
+using Microsoft.FluentUI.AspNetCore.Components.Extensions;
+using Microsoft.JSInterop;
namespace Microsoft.FluentUI.AspNetCore.Components;
-public partial class FluentToolbar : FluentComponentBase
+public partial class FluentToolbar : FluentComponentBase, IAsyncDisposable
{
+ private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Toolbar/FluentToolbar.razor.js";
+
+ ///
+ [Inject]
+ private LibraryConfiguration LibraryConfiguration { get; set; } = default!;
+
+ ///
+ [Inject]
+ private IJSRuntime JSRuntime { get; set; } = default!;
+
+ ///
+ private IJSObjectReference Module { get; set; } = default!;
+
///
/// Gets or sets the toolbar's orentation. See
///
@@ -15,4 +30,37 @@ public partial class FluentToolbar : FluentComponentBase
///
[Parameter]
public RenderFragment? ChildContent { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether arrow key navigation within text input fields is enabled. Default is false.
+ ///
+ [Parameter]
+ public bool? EnableArrowKeyTextNavigation { get; set; } = false;
+
+ public FluentToolbar()
+ {
+ Id = Identifier.NewId();
+ }
+
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration));
+
+ if (EnableArrowKeyTextNavigation ?? false)
+ {
+ await Module.InvokeVoidAsync("preventArrowKeyNavigation", Id);
+ }
+ }
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ if (Module is not null && !string.IsNullOrEmpty(Id))
+ {
+ await Module.InvokeVoidAsync("removePreventArrowKeyNavigation", Id);
+ await Module.DisposeAsync();
+ }
+ }
}
diff --git a/src/Core/Components/Toolbar/FluentToolbar.razor.js b/src/Core/Components/Toolbar/FluentToolbar.razor.js
new file mode 100644
index 0000000000..fc39c53e61
--- /dev/null
+++ b/src/Core/Components/Toolbar/FluentToolbar.razor.js
@@ -0,0 +1,39 @@
+// Prevent fluent-toolbar from overriding arrow key functionality in input fields
+const handlers = new Map();
+
+export function preventArrowKeyNavigation(id) {
+ const toolbar = document.querySelector("#" + id);
+ if (!toolbar) return;
+
+ const arrowKeyListener = (event) => {
+ if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
+ const activeElement = document.activeElement;
+ if (activeElement && (activeElement.tagName === 'FLUENT-SEARCH'
+ || activeElement.tagName === 'FLUENT-TEXT-FIELD'
+ || activeElement.tagName === 'FLUENT-NUMBER-FIELD'
+ || activeElement.tagName === 'FLUENT-TEXT-AREA')) {
+
+ const textLength = activeElement.value?.length || 0;
+ if (textLength > 0) {
+ event.stopPropagation();
+ }
+ }
+ }
+ };
+
+ toolbar.addEventListener('keydown', arrowKeyListener, true);
+ handlers.set(id, { toolbar, arrowKeyListener });
+}
+
+export function removePreventArrowKeyNavigation(id) {
+ const handler = handlers.get(id);
+ if (handler) {
+ const { toolbar, arrowKeyListener } = handler;
+
+ if (toolbar) {
+ toolbar.removeEventListener('keydown', arrowKeyListener, true);
+ }
+
+ handlers.delete(id);
+ }
+}
diff --git a/tests/Core/_ToDo/Toolbar/FluentToolbarTests.cs b/tests/Core/_ToDo/Toolbar/FluentToolbarTests.cs
index c98852c4bd..983a45fbaf 100644
--- a/tests/Core/_ToDo/Toolbar/FluentToolbarTests.cs
+++ b/tests/Core/_ToDo/Toolbar/FluentToolbarTests.cs
@@ -1,9 +1,20 @@
using Bunit;
+using Microsoft.AspNetCore.Components;
+using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Toolbar;
public class FluentToolbarTests : TestBase
{
+ [Inject]
+ private LibraryConfiguration LibraryConfiguration { get; set; } = new LibraryConfiguration();
+
+ public FluentToolbarTests()
+ {
+ TestContext.JSInterop.Mode = JSRuntimeMode.Loose;
+ TestContext.Services.AddSingleton(LibraryConfiguration);
+ }
+
[Fact]
public void FluentToolbar_Default()
{