diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index 785c9b8e82..45fdf8cdac 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -95,6 +95,12 @@ Gets or sets the content to be rendered inside the component. + + + + + + @@ -224,6 +230,12 @@ + + + + + + Prompts the user to save the linked URL. See a element for more information. @@ -290,6 +302,9 @@ + + + @@ -796,6 +811,9 @@ Gets or sets the content to be rendered inside the component. + + + @@ -956,6 +974,9 @@ Gets or sets the content to be rendered inside the component. + + + @@ -1712,6 +1733,9 @@ The type of data represented by each row in the grid. + + + Gets or sets a queryable source of data for the grid. @@ -2946,6 +2970,12 @@ Gets or sets the content to be rendered inside the component. + + + + + + @@ -3829,6 +3859,12 @@ An event that will be invoked when showing a dialog with a custom component + + + + + + Gets or sets the role of the element. @@ -4194,6 +4230,9 @@ that are used for specific screen sizes. + + + @@ -4354,6 +4393,12 @@ If true, highlights the text until the next regex boundary. + + + + + + Gets or sets the scroll speed in pixels per second. @@ -4583,6 +4628,9 @@ + + + @@ -4833,6 +4881,9 @@ Prevent multiple KeyDown events. + + + @@ -5108,6 +5159,9 @@ Private KeyCodeListener + + + @@ -5216,6 +5270,9 @@ Initializes a new instance of the class. + + + @@ -5409,6 +5466,9 @@ + + + @@ -5597,6 +5657,9 @@ + + + @@ -5835,6 +5898,9 @@ + + + @@ -6876,6 +6942,9 @@ + + + Gets or sets the content to display. @@ -7487,6 +7556,9 @@ + + + Gets or sets the direction to pull the . @@ -7736,6 +7808,9 @@ + + + @@ -7859,6 +7934,9 @@ The value to format. A string representation of the value. + + + @@ -7888,6 +7966,12 @@ + + + + + + Gets or sets the template to be used to define each sortable item in the list. @@ -7979,6 +8063,15 @@ Gets or sets the width of the spacer (in pixels). + + + + + + + + + Gets or sets the child content. @@ -8030,12 +8123,6 @@ - - - - - - Adds the pane. @@ -8334,6 +8421,9 @@ + + + @@ -8438,6 +8528,9 @@ + + + @@ -8587,6 +8680,9 @@ Gets or sets the content to be rendered inside the component. + + + @@ -9616,6 +9712,9 @@ + + + Gets the name of this design token @@ -14498,6 +14597,11 @@ Defines the global Fluent UI Blazor component library services configuration + + + Gets the assembly version formatted as a string. + + Gets or sets a value indicating whether the library should use the TooltipServiceProvider. @@ -14522,6 +14626,16 @@ Default is true. + + + Gets or sets the function that formats the URL of the collocated JavaScript file, + adding the return value as a query string parameter. + By default, the function adds a query string parameter with the version of the assembly: `v=[AssemblyVersion]`. + + + + + A strongly-typed resource class, for looking up localized strings, etc. diff --git a/src/Core/Components/Anchor/FluentAnchor.razor.cs b/src/Core/Components/Anchor/FluentAnchor.razor.cs index c706d1bda1..4d3d70ef00 100644 --- a/src/Core/Components/Anchor/FluentAnchor.razor.cs +++ b/src/Core/Components/Anchor/FluentAnchor.razor.cs @@ -1,17 +1,24 @@ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; public partial class FluentAnchor : FluentComponentBase, IAsyncDisposable { + private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Anchor/FluentAnchor.razor.js"; private IJSObjectReference _jsModule = default!; private string? _targetId = null; private bool _preventDefault = false; + /// [Inject] - protected IJSRuntime JSRuntime { get; set; } = default!; + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// + [Inject] + private IJSRuntime JSRuntime { get; set; } = default!; /// /// Prompts the user to save the linked URL. See a element for more information. @@ -123,8 +130,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule = await JSRuntime.InvokeAsync("import", - "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Anchor/FluentAnchor.razor.js"); + _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); } } diff --git a/src/Core/Components/AnchoredRegion/FluentAnchoredRegion.razor.cs b/src/Core/Components/AnchoredRegion/FluentAnchoredRegion.razor.cs index 7a60e950c2..cabea0cd47 100644 --- a/src/Core/Components/AnchoredRegion/FluentAnchoredRegion.razor.cs +++ b/src/Core/Components/AnchoredRegion/FluentAnchoredRegion.razor.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -7,6 +8,11 @@ public partial class FluentAnchoredRegion : FluentComponentBase { private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/AnchoredRegion/FluentAnchoredRegion.razor.js"; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -161,7 +167,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); // Go to the first Focusable element (after a delay of 100ms, to allow the DOM to render the Web Components) if (AutoFocus) diff --git a/src/Core/Components/AppBar/FluentAppBar.razor.cs b/src/Core/Components/AppBar/FluentAppBar.razor.cs index 50570749db..fc77f4bc3a 100644 --- a/src/Core/Components/AppBar/FluentAppBar.razor.cs +++ b/src/Core/Components/AppBar/FluentAppBar.razor.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; using System.Text.Json; @@ -23,6 +24,10 @@ public partial class FluentAppBar : FluentComponentBase // ToDo: Implement focus on popup //private FluentSearch? _appSearch; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -77,7 +82,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { _dotNetHelper = DotNetObjectReference.Create(this); // Overflow - _jsModuleOverflow = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModuleOverflow = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await _jsModuleOverflow.InvokeVoidAsync("fluentOverflowInitialize", _dotNetHelper, Id, false, OVERFLOW_SELECTOR); } diff --git a/src/Core/Components/Button/FluentButton.razor.cs b/src/Core/Components/Button/FluentButton.razor.cs index ef4a476bbb..a52ecebef4 100644 --- a/src/Core/Components/Button/FluentButton.razor.cs +++ b/src/Core/Components/Button/FluentButton.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -11,6 +12,10 @@ public partial class FluentButton : FluentComponentBase, IAsyncDisposable private readonly RenderFragment _renderButton; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -180,7 +185,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && Id is not null && Type != ButtonType.Button) { - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await _jsModule.InvokeVoidAsync("updateProxy", Id); } } diff --git a/src/Core/Components/Checkbox/FluentCheckbox.razor.cs b/src/Core/Components/Checkbox/FluentCheckbox.razor.cs index b53f032063..0911e08b4b 100644 --- a/src/Core/Components/Checkbox/FluentCheckbox.razor.cs +++ b/src/Core/Components/Checkbox/FluentCheckbox.razor.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -17,6 +18,10 @@ public FluentCheckbox() Id = Identifier.NewId(); } + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -122,7 +127,7 @@ private async Task SetIntermediateAsync(bool intermediate) { // Force the Indeterminate state to be set. // Each time the user clicks the checkbox, the Indeterminate state is reset to false. - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("setFluentCheckBoxIndeterminate", Id, intermediate, Value); _intermediate = intermediate; diff --git a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs index 83b5c2d984..90178a26dd 100644 --- a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs +++ b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web.Virtualization; using Microsoft.FluentUI.AspNetCore.Components.DataGrid.Infrastructure; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Infrastructure; using Microsoft.JSInterop; using System.Diagnostics.CodeAnalysis; @@ -19,6 +20,20 @@ namespace Microsoft.FluentUI.AspNetCore.Components; public partial class FluentDataGrid : FluentComponentBase, IHandleEvent, IAsyncDisposable { private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/DataGrid/FluentDataGrid.razor.js"; + + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + [Inject] + private IServiceProvider Services { get; set; } = default!; + + [Inject] + private IJSRuntime JSRuntime { get; set; } = default!; + + [Inject] + private IKeyCodeService KeyCodeService { get; set; } = default!; + /// /// Gets or sets a queryable source of data for the grid. /// @@ -28,20 +43,23 @@ public partial class FluentDataGrid : FluentComponentBase, IHandleEve /// /// You should supply either or , but not both. /// - [Parameter] public IQueryable? Items { get; set; } + [Parameter] + public IQueryable? Items { get; set; } /// /// Gets or sets a callback that supplies data for the rid. /// /// You should supply either or , but not both. /// - [Parameter] public GridItemsProvider? ItemsProvider { get; set; } + [Parameter] + public GridItemsProvider? ItemsProvider { get; set; } /// /// Gets or sets the child components of this instance. For example, you may define columns by adding /// components derived from the base class. /// - [Parameter] public RenderFragment? ChildContent { get; set; } + [Parameter] + public RenderFragment? ChildContent { get; set; } /// /// If true, the grid will be rendered with virtualization. This is normally used in conjunction with @@ -54,20 +72,23 @@ public partial class FluentDataGrid : FluentComponentBase, IHandleEve /// Generally it's preferable not to use if the amount of data being rendered /// is small or if you are using pagination. /// - [Parameter] public bool Virtualize { get; set; } + [Parameter] + public bool Virtualize { get; set; } /// /// This is applicable only when using . It defines an expected height in pixels for /// each row, allowing the virtualization mechanism to fetch the correct number of items to match the display /// size and to ensure accurate scrolling. /// - [Parameter] public float ItemSize { get; set; } = 32; + [Parameter] + public float ItemSize { get; set; } = 32; /// /// If true, renders draggable handles around the column headers, allowing the user to resize the columns /// manually. Size changes are not persisted. /// - [Parameter] public bool ResizableColumns { get; set; } + [Parameter] + public bool ResizableColumns { get; set; } /// /// To comply with WCAG 2.2, a one-click option should be offered to change column widths. We provide such an option through the @@ -91,7 +112,8 @@ public partial class FluentDataGrid : FluentComponentBase, IHandleEve /// /// If not set, the @key will be the instance itself. /// - [Parameter] public Func ItemKey { get; set; } = x => x!; + [Parameter] + public Func ItemKey { get; set; } = x => x!; /// /// Optionally links this instance with a model, @@ -100,7 +122,8 @@ public partial class FluentDataGrid : FluentComponentBase, IHandleEve /// This is normally used in conjunction with a component or some other UI logic /// that displays and updates the supplied instance. /// - [Parameter] public PaginationState? Pagination { get; set; } + [Parameter] + public PaginationState? Pagination { get; set; } /// /// Gets or sets a value indicating whether the component will not add itself to the tab queue. @@ -157,38 +180,40 @@ public partial class FluentDataGrid : FluentComponentBase, IHandleEve /// /// Optionally defines a class to be applied to a rendered row. /// - [Parameter] public Func? RowClass { get; set; } + [Parameter] + public Func? RowClass { get; set; } /// /// Optionally defines a style to be applied to a rendered row. /// Do not use to dynamically update a row style after rendering as this will interfere with the script that use this attribute. Use instead. /// - [Parameter] public Func? RowStyle { get; set; } + [Parameter] + public Func? RowStyle { get; set; } /// /// Gets or sets a value indicating whether the grid should show a hover effect on rows. /// - [Parameter] public bool ShowHover { get; set; } + [Parameter] + public bool ShowHover { get; set; } /// /// If specified, grids render this fragment when there is no content. /// - [Parameter] public RenderFragment? EmptyContent { get; set; } + [Parameter] + public RenderFragment? EmptyContent { get; set; } /// /// Gets or sets a value indicating whether the grid is in a loading data state. /// - [Parameter] public bool Loading { get; set; } + [Parameter] + public bool Loading { get; set; } /// /// Gets or sets the content to render when is true. /// A default fragment is used if loading content is not specified. /// - [Parameter] public RenderFragment? LoadingContent { get; set; } - - [Inject] private IServiceProvider Services { get; set; } = default!; - [Inject] private IJSRuntime JSRuntime { get; set; } = default!; - [Inject] private IKeyCodeService KeyCodeService { get; set; } = default!; + [Parameter] + public RenderFragment? LoadingContent { get; set; } private ElementReference? _gridReference; private Virtualize<(int, TGridItem)>? _virtualizeComponent; @@ -299,7 +324,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && _gridReference is not null) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); try { _jsEventDisposable = await Module.InvokeAsync("init", _gridReference); diff --git a/src/Core/Components/DesignSystemProvider/FluentDesignTheme.razor.cs b/src/Core/Components/DesignSystemProvider/FluentDesignTheme.razor.cs index b68b7cd709..cdadb36c4a 100644 --- a/src/Core/Components/DesignSystemProvider/FluentDesignTheme.razor.cs +++ b/src/Core/Components/DesignSystemProvider/FluentDesignTheme.razor.cs @@ -16,6 +16,11 @@ public partial class FluentDesignTheme : ComponentBase PropertyNameCaseInsensitive = true, }; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// [Inject] private GlobalState GlobalDesign { get; set; } = default!; @@ -174,7 +179,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); _dotNetHelper = DotNetObjectReference.Create(this); var dir = await Module.InvokeAsync("GetDirection"); @@ -210,7 +215,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) /// public async Task ClearLocalStorageAsync() { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("ClearLocalStorage", Id); } diff --git a/src/Core/Components/Divider/FluentDivider.razor.cs b/src/Core/Components/Divider/FluentDivider.razor.cs index e10660db04..3ca9f962d1 100644 --- a/src/Core/Components/Divider/FluentDivider.razor.cs +++ b/src/Core/Components/Divider/FluentDivider.razor.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; @@ -9,6 +10,11 @@ public partial class FluentDivider : FluentComponentBase, IAsyncDisposable private IJSObjectReference _jsModule = default!; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// [Inject] protected IJSRuntime JSRuntime { get; set; } = default!; @@ -34,7 +40,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await _jsModule.InvokeVoidAsync("setDividerAriaOrientation"); } } diff --git a/src/Core/Components/Grid/FluentGrid.razor.cs b/src/Core/Components/Grid/FluentGrid.razor.cs index cff5be38f6..cfc18e0156 100644 --- a/src/Core/Components/Grid/FluentGrid.razor.cs +++ b/src/Core/Components/Grid/FluentGrid.razor.cs @@ -2,6 +2,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // -------------------------------------------------------------- using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -21,6 +22,10 @@ public FluentGrid() Id = Identifier.NewId(); } + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -75,7 +80,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) { if (firstRender && OnBreakpointEnter.HasDelegate) { - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); DotNetObjectReference dotNetHelper = DotNetObjectReference.Create(this); await _jsModule.InvokeVoidAsync("FluentGridInitialize", Id, dotNetHelper); } diff --git a/src/Core/Components/HorizontalScroll/FluentHorizontalScroll.razor.cs b/src/Core/Components/HorizontalScroll/FluentHorizontalScroll.razor.cs index 87e91a9e9a..277d092313 100644 --- a/src/Core/Components/HorizontalScroll/FluentHorizontalScroll.razor.cs +++ b/src/Core/Components/HorizontalScroll/FluentHorizontalScroll.razor.cs @@ -1,11 +1,24 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; public partial class FluentHorizontalScroll : FluentComponentBase, IAsyncDisposable { + private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/HorizontalScroll/FluentHorizontalScroll.razor.js"; + + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// + [Inject] + private IJSRuntime JSRuntime { get; set; } = default!; + + private IJSObjectReference? _jsModule; + /// /// Gets or sets the scroll speed in pixels per second. /// @@ -42,10 +55,6 @@ public partial class FluentHorizontalScroll : FluentComponentBase, IAsyncDisposa [Parameter] public RenderFragment? ChildContent { get; set; } - [Inject] private IJSRuntime JSRuntime { get; set; } = default!; - - private IJSObjectReference? _jsModule; - [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(HorizontalScrollEventArgs))] public FluentHorizontalScroll() @@ -56,7 +65,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule = await JSRuntime.InvokeAsync("import", "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/HorizontalScroll/FluentHorizontalScroll.razor.js"); + _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); } } diff --git a/src/Core/Components/InputFile/FluentInputFile.razor.cs b/src/Core/Components/InputFile/FluentInputFile.razor.cs index 5510f39371..7a02ecb001 100644 --- a/src/Core/Components/InputFile/FluentInputFile.razor.cs +++ b/src/Core/Components/InputFile/FluentInputFile.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -21,6 +22,10 @@ public FluentInputFile() Id = Identifier.NewId(); } + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -180,7 +185,7 @@ public FluentInputFile() /// public async Task ShowFilesDialogAsync() { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("raiseFluentInputFile", Id); } @@ -190,7 +195,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && !string.IsNullOrEmpty(AnchorId)) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("attachClickHandler", AnchorId, Id); } diff --git a/src/Core/Components/KeyCode/FluentKeyCode.razor.cs b/src/Core/Components/KeyCode/FluentKeyCode.razor.cs index eea3d11981..a8b20a3313 100644 --- a/src/Core/Components/KeyCode/FluentKeyCode.razor.cs +++ b/src/Core/Components/KeyCode/FluentKeyCode.razor.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; @@ -19,6 +20,10 @@ public partial class FluentKeyCode : IAsyncDisposable /// public static bool PreventMultipleKeyDown = false; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -114,7 +119,7 @@ protected async override Task OnAfterRenderAsync(bool firstRender) throw new ArgumentNullException(Anchor, $"The {nameof(Anchor)} parameter must be set to the ID of an element. Or the {nameof(ChildContent)} must be set to apply the KeyCode engine to this content."); } - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); _dotNetHelper = DotNetObjectReference.Create(this); var eventNames = string.Join(";", new[] diff --git a/src/Core/Components/Label/FluentInputLabel.razor b/src/Core/Components/Label/FluentInputLabel.razor index f5d076dbea..3453463105 100644 --- a/src/Core/Components/Label/FluentInputLabel.razor +++ b/src/Core/Components/Label/FluentInputLabel.razor @@ -1,6 +1,4 @@ @namespace Microsoft.FluentUI.AspNetCore.Components -@inject LibraryConfiguration LibraryConfiguration - @if (!string.IsNullOrEmpty(Label) || ChildContent is not null) { diff --git a/src/Core/Components/Label/FluentInputLabel.razor.cs b/src/Core/Components/Label/FluentInputLabel.razor.cs index af5980f01d..403eebd146 100644 --- a/src/Core/Components/Label/FluentInputLabel.razor.cs +++ b/src/Core/Components/Label/FluentInputLabel.razor.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; @@ -11,6 +12,10 @@ public partial class FluentInputLabel { public const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Label/FluentInputLabel.razor.js"; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -72,7 +77,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender && ShouldRenderAriaLabel) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("setInputAriaLabel", ForId, string.IsNullOrWhiteSpace(AriaLabel) ? Label : AriaLabel); } } diff --git a/src/Core/Components/List/FluentAutocomplete.razor.cs b/src/Core/Components/List/FluentAutocomplete.razor.cs index 9d7f08728d..e5155e0788 100644 --- a/src/Core/Components/List/FluentAutocomplete.razor.cs +++ b/src/Core/Components/List/FluentAutocomplete.razor.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web.Virtualization; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -29,6 +30,10 @@ public FluentAutocomplete() Id = Identifier.NewId(); } + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JS { get; set; } = default!; @@ -487,7 +492,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - Module = await JS.InvokeAsync("import", JAVASCRIPT_FILE); + Module = await JS.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); } } diff --git a/src/Core/Components/List/FluentCombobox.razor.cs b/src/Core/Components/List/FluentCombobox.razor.cs index 360ccc259e..6caeb553e4 100644 --- a/src/Core/Components/List/FluentCombobox.razor.cs +++ b/src/Core/Components/List/FluentCombobox.razor.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -13,6 +14,10 @@ public partial class FluentCombobox : ListComponentBase where { private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/List/FluentCombobox.razor.js"; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -57,7 +62,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (!string.IsNullOrEmpty(Id)) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("setControlAttribute", Id, "autocomplete", "off"); } } diff --git a/src/Core/Components/List/ListComponentBase.razor.cs b/src/Core/Components/List/ListComponentBase.razor.cs index 993739c062..a1bf82e3df 100644 --- a/src/Core/Components/List/ListComponentBase.razor.cs +++ b/src/Core/Components/List/ListComponentBase.razor.cs @@ -26,6 +26,10 @@ public abstract partial class ListComponentBase : FluentInputBase + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + private IJSObjectReference? _jsModule { get; set; } [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -38,7 +42,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); } } diff --git a/src/Core/Components/Menu/FluentMenu.razor.cs b/src/Core/Components/Menu/FluentMenu.razor.cs index f570966de3..ff5ea9822e 100644 --- a/src/Core/Components/Menu/FluentMenu.razor.cs +++ b/src/Core/Components/Menu/FluentMenu.razor.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Drawing; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -8,6 +9,8 @@ namespace Microsoft.FluentUI.AspNetCore.Components; public partial class FluentMenu : FluentComponentBase, IDisposable { + private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Menu/FluentMenu.razor.js"; + private DotNetObjectReference? _dotNetHelper = null; private Point _clickedPoint = default; private bool _contextMenu = false; @@ -33,6 +36,10 @@ public partial class FluentMenu : FluentComponentBase, IDisposable .AddStyle("top", $"{_clickedPoint.Y}px", () => !Anchored && _clickedPoint.Y != 0) .Build(); + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -134,8 +141,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (Trigger != MouseButton.None) { - _jsModule = await JSRuntime.InvokeAsync("import", - "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Menu/FluentMenu.razor.js"); + _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); _dotNetHelper = DotNetObjectReference.Create(this); diff --git a/src/Core/Components/Overflow/FluentOverflow.razor.cs b/src/Core/Components/Overflow/FluentOverflow.razor.cs index e8ccf4119c..076c422795 100644 --- a/src/Core/Components/Overflow/FluentOverflow.razor.cs +++ b/src/Core/Components/Overflow/FluentOverflow.razor.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; using System.Text.Json; @@ -27,6 +28,10 @@ public partial class FluentOverflow : FluentComponentBase, IAsyncDisposable .AddStyle("visibility", "hidden", VisibleOnLoad == false) .Build(); + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + [Inject] protected IJSRuntime JSRuntime { get; set; } = default!; @@ -93,7 +98,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); _dotNetHelper = DotNetObjectReference.Create(this); await _jsModule.InvokeVoidAsync("fluentOverflowInitialize", _dotNetHelper, Id, IsHorizontal, Selectors); VisibleOnLoad = true; diff --git a/src/Core/Components/PullToRefresh/FluentPullToRefresh.razor.cs b/src/Core/Components/PullToRefresh/FluentPullToRefresh.razor.cs index dd9f6641d1..3265bc6d87 100644 --- a/src/Core/Components/PullToRefresh/FluentPullToRefresh.razor.cs +++ b/src/Core/Components/PullToRefresh/FluentPullToRefresh.razor.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -30,6 +31,10 @@ public partial class FluentPullToRefresh : FluentComponentBase protected string? StyleValue => new StyleBuilder(Style) .Build(); + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + [Inject] protected IJSRuntime JSRuntime { get; set; } = default!; @@ -171,7 +176,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && EmulateTouch) { - _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await _jsModule.InvokeVoidAsync("initTouchEmulator"); } diff --git a/src/Core/Components/Search/FluentSearch.razor.cs b/src/Core/Components/Search/FluentSearch.razor.cs index 1f06b76cb3..a901901fc8 100644 --- a/src/Core/Components/Search/FluentSearch.razor.cs +++ b/src/Core/Components/Search/FluentSearch.razor.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; @@ -8,6 +9,10 @@ public partial class FluentSearch : FluentInputBase { private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Search/FluentSearch.razor.js"; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -76,7 +81,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { //if (!string.IsNullOrEmpty(Id)) //{ - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("addAriaHidden", Id); //} } diff --git a/src/Core/Components/Slider/FluentSliderLabel.razor.cs b/src/Core/Components/Slider/FluentSliderLabel.razor.cs index 0ab768aa82..53c6d18b31 100644 --- a/src/Core/Components/Slider/FluentSliderLabel.razor.cs +++ b/src/Core/Components/Slider/FluentSliderLabel.razor.cs @@ -1,5 +1,6 @@ using System.Globalization; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; @@ -13,6 +14,10 @@ public FluentSliderLabel() Id = Identifier.NewId(); } + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -65,7 +70,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await _jsModule.InvokeVoidAsync("updateSliderLabel", Id); } } diff --git a/src/Core/Components/SortableList/FluentSortableList.razor.cs b/src/Core/Components/SortableList/FluentSortableList.razor.cs index 09b4f3a59a..5dd737c058 100644 --- a/src/Core/Components/SortableList/FluentSortableList.razor.cs +++ b/src/Core/Components/SortableList/FluentSortableList.razor.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -10,6 +11,14 @@ public partial class FluentSortableList : FluentComponentBase private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/SortableList/FluentSortableList.razor.js"; private DotNetObjectReference>? _selfReference; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// + [Inject] + private IJSRuntime JSRuntime { get; set; } = default!; + /// /// Gets or sets the template to be used to define each sortable item in the list. /// Use the @context parameter to access the item and its properties. @@ -91,9 +100,6 @@ public partial class FluentSortableList : FluentComponentBase private string Filter => Items.Any(GetItemFiltered) ? ".filtered" : string.Empty; - [Inject] - private IJSRuntime JSRuntime { get; set; } = default!; - protected override async Task OnAfterRenderAsync(bool firstRender) { try @@ -101,7 +107,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender) { _selfReference = DotNetObjectReference.Create(this); - IJSObjectReference? module = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + IJSObjectReference? module = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await module.InvokeAsync("init", Element, Group, Clone ? "clone" : null, Drop, Sort, Handle ? ".sortable-grab" : null, Filter, Fallback, _selfReference); } } diff --git a/src/Core/Components/Splitter/FluentMultiSplitter.razor.cs b/src/Core/Components/Splitter/FluentMultiSplitter.razor.cs index df37ce7601..08afd1ef95 100644 --- a/src/Core/Components/Splitter/FluentMultiSplitter.razor.cs +++ b/src/Core/Components/Splitter/FluentMultiSplitter.razor.cs @@ -5,6 +5,7 @@ using System.Globalization; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -15,6 +16,17 @@ public partial class FluentMultiSplitter : FluentComponentBase private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Splitter/FluentMultiSplitter.razor.js"; private DotNetObjectReference? _objRef = null; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + + /// + [Inject] + private IJSRuntime JS { get; set; } = default!; + + /// + private IJSObjectReference Module { get; set; } = default!; + internal List Panes { get; } = new(); /// @@ -82,13 +94,6 @@ public partial class FluentMultiSplitter : FluentComponentBase .AddStyle("--fluent-multi-splitter-bar-size", BarSize, () => !string.IsNullOrEmpty(BarSize)) .Build(); - /// - [Inject] - private IJSRuntime JS { get; set; } = default!; - - /// - private IJSObjectReference Module { get; set; } = default!; - /// /// Adds the pane. /// @@ -335,7 +340,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - Module = await JS.InvokeAsync("import", JAVASCRIPT_FILE); + Module = await JS.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); _objRef = DotNetObjectReference.Create(this); } } diff --git a/src/Core/Components/Tabs/FluentTab.razor.cs b/src/Core/Components/Tabs/FluentTab.razor.cs index da611a65f9..b3dc049763 100644 --- a/src/Core/Components/Tabs/FluentTab.razor.cs +++ b/src/Core/Components/Tabs/FluentTab.razor.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; @@ -6,6 +7,7 @@ namespace Microsoft.FluentUI.AspNetCore.Components; public partial class FluentTab : FluentComponentBase { + private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Tabs/FluentTab.razor.js"; private DotNetObjectReference? _dotNetHelper = null; private IJSObjectReference _jsModule = default!; @@ -18,6 +20,10 @@ public partial class FluentTab : FluentComponentBase .AddStyle("height", $"calc({Owner?.Height} - 40px); overflow-y: auto", () => !string.IsNullOrEmpty(Owner?.Height)) .Build(); + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -131,8 +137,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - _jsModule = await JSRuntime.InvokeAsync("import", - "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Tabs/FluentTab.razor.js"); + _jsModule = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); _dotNetHelper = DotNetObjectReference.Create(this); await _jsModule.InvokeVoidAsync("TabEditable_Changed", _dotNetHelper, $"#{Id} span[contenteditable='true']", Id); diff --git a/src/Core/Components/Tabs/FluentTabs.razor.cs b/src/Core/Components/Tabs/FluentTabs.razor.cs index eb376395eb..92034b9400 100644 --- a/src/Core/Components/Tabs/FluentTabs.razor.cs +++ b/src/Core/Components/Tabs/FluentTabs.razor.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.FluentUI.AspNetCore.Components.Utilities; using Microsoft.JSInterop; using System.Diagnostics.CodeAnalysis; @@ -12,6 +13,8 @@ namespace Microsoft.FluentUI.AspNetCore.Components; public partial class FluentTabs : FluentComponentBase { + private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Overflow/FluentOverflow.razor.js"; + private const string FLUENT_TAB_TAG = "fluent-tab"; private readonly Dictionary _tabs = []; //private string _activeId = string.Empty; @@ -39,6 +42,10 @@ public partial class FluentTabs : FluentComponentBase .AddStyle("display", "none", () => !TabsOverflow.Any()) .Build(); + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -144,8 +151,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { _dotNetHelper = DotNetObjectReference.Create(this); // Overflow - _jsModuleOverflow = await JSRuntime.InvokeAsync("import", - "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Overflow/FluentOverflow.razor.js"); + _jsModuleOverflow = await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); var horizontal = Orientation == Orientation.Horizontal; await _jsModuleOverflow.InvokeVoidAsync("fluentOverflowInitialize", _dotNetHelper, Id, horizontal, FLUENT_TAB_TAG); diff --git a/src/Core/Components/TextField/FluentTextField.razor.cs b/src/Core/Components/TextField/FluentTextField.razor.cs index 860f8b7d7d..ae44adf6f8 100644 --- a/src/Core/Components/TextField/FluentTextField.razor.cs +++ b/src/Core/Components/TextField/FluentTextField.razor.cs @@ -9,6 +9,10 @@ public partial class FluentTextField : FluentInputBase { private const string JAVASCRIPT_FILE = "./_content/Microsoft.FluentUI.AspNetCore.Components/Components/TextField/FluentTextField.razor.js"; + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + /// [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -98,20 +102,20 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (AutoComplete != null && !string.IsNullOrEmpty(Id)) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("setControlAttribute", Id, "autocomplete", AutoComplete); } if (InputMode != null && !string.IsNullOrEmpty(Id)) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("setControlAttribute", Id, "inputmode", InputMode.ToAttributeValue()); } } if (DataList != null && !string.IsNullOrEmpty(Id)) { - Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + Module ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await Module.InvokeVoidAsync("setDataList", Id, DataList); } diff --git a/src/Core/Components/Tooltip/FluentTooltip.razor.cs b/src/Core/Components/Tooltip/FluentTooltip.razor.cs index 79a67a50c1..93ddb78d39 100644 --- a/src/Core/Components/Tooltip/FluentTooltip.razor.cs +++ b/src/Core/Components/Tooltip/FluentTooltip.razor.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.Extensions.DependencyInjection; using Microsoft.FluentUI.AspNetCore.Components.Components.Tooltip; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components; @@ -17,7 +18,7 @@ public partial class FluentTooltip : FluentComponentBase, IDisposable private IJSRuntime JSRuntime { get; set; } = default!; [Inject] - private LibraryConfiguration? LibraryConfiguration { get; set; } + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; /// /// Gets or sets a reference to the list of registered services. @@ -158,7 +159,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender && !string.IsNullOrEmpty(Anchor) && HideTooltipOnCursorLeave == true) { - JSModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + JSModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); await JSModule.InvokeVoidAsync("tooltipHideOnCursorLeave", Anchor); } } diff --git a/src/Core/DesignTokens/DesignToken.razor.cs b/src/Core/DesignTokens/DesignToken.razor.cs index 2b4d03ff4d..b06b05e2d2 100644 --- a/src/Core/DesignTokens/DesignToken.razor.cs +++ b/src/Core/DesignTokens/DesignToken.razor.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components.Extensions; using Microsoft.JSInterop; namespace Microsoft.FluentUI.AspNetCore.Components.DesignTokens; @@ -11,6 +12,10 @@ public partial class DesignToken : ComponentBase, IDesignToken, IAsyncDisp private Reference Target { get; set; } = new(); + /// + [Inject] + private LibraryConfiguration LibraryConfiguration { get; set; } = default!; + [Inject] private IJSRuntime JSRuntime { get; set; } = default!; @@ -68,7 +73,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) private async Task InitJSReferenceAsync() { - _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE); + _jsModule ??= await JSRuntime.InvokeAsync("import", JAVASCRIPT_FILE.FormatCollocatedUrl(LibraryConfiguration)); } #pragma warning disable VSTHRD200 // Use "Async" suffix for async methods diff --git a/src/Core/Extensions/UrlFormatterExtensions.cs b/src/Core/Extensions/UrlFormatterExtensions.cs new file mode 100644 index 0000000000..a233734c2d --- /dev/null +++ b/src/Core/Extensions/UrlFormatterExtensions.cs @@ -0,0 +1,17 @@ +namespace Microsoft.FluentUI.AspNetCore.Components.Extensions; + +internal static class UrlFormatterExtensions +{ + internal static string FormatCollocatedUrl(this string url, LibraryConfiguration configuration) + { + if (configuration.CollocatedJavaScriptQueryString == null) + { + return url; + } + + var queryString = configuration.CollocatedJavaScriptQueryString(url); + + return string.IsNullOrEmpty(queryString) ? url : $"{url}?{queryString}"; + } + +} diff --git a/src/Core/Infrastructure/LibraryConfiguration.cs b/src/Core/Infrastructure/LibraryConfiguration.cs index 6547a2b168..f039f0a921 100644 --- a/src/Core/Infrastructure/LibraryConfiguration.cs +++ b/src/Core/Infrastructure/LibraryConfiguration.cs @@ -9,6 +9,11 @@ namespace Microsoft.FluentUI.AspNetCore.Components; /// public class LibraryConfiguration { + /// + /// Gets the assembly version formatted as a string. + /// + internal static readonly string? AssemblyVersion = typeof(LibraryConfiguration).Assembly.GetName().Version?.ToString(); + /// /// Gets or sets a value indicating whether the library should use the TooltipServiceProvider. /// If set to true, add the FluentTooltipProvider component at end of the MainLayout.razor page. @@ -40,7 +45,21 @@ public bool ValidateClassNames set => Utilities.CssBuilder.ValidateClassNames = value; } + /// + /// Gets or sets the function that formats the URL of the collocated JavaScript file, + /// adding the return value as a query string parameter. + /// By default, the function adds a query string parameter with the version of the assembly: `v=[AssemblyVersion]`. + /// + public Func? CollocatedJavaScriptQueryString { get; set; } = (url) + => string.IsNullOrEmpty(AssemblyVersion) ? string.Empty : $"v={AssemblyVersion}"; + public LibraryConfiguration() { } + + /// + internal static LibraryConfiguration ForUnitTests => new() + { + CollocatedJavaScriptQueryString = null, + }; } diff --git a/tests/Core/Anchor/FluentAnchorTests.cs b/tests/Core/Anchor/FluentAnchorTests.cs index 7efae88f7e..88d868038e 100644 --- a/tests/Core/Anchor/FluentAnchorTests.cs +++ b/tests/Core/Anchor/FluentAnchorTests.cs @@ -1,5 +1,6 @@ using Bunit; using FluentAssertions; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Anchor; @@ -11,6 +12,7 @@ public partial class FluentAnchorTests : TestContext public FluentAnchorTests() { JSInterop.SetupModule(FluentAnchorRazorJs); + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/AnchoredRegion/FluentAnchoredRegionTests.cs b/tests/Core/AnchoredRegion/FluentAnchoredRegionTests.cs index cd95f10bfc..a2eb4d405e 100644 --- a/tests/Core/AnchoredRegion/FluentAnchoredRegionTests.cs +++ b/tests/Core/AnchoredRegion/FluentAnchoredRegionTests.cs @@ -1,4 +1,5 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.AnchoredRegion; @@ -8,6 +9,7 @@ public class FluentAnchoredRegionTests : TestBase public FluentAnchoredRegionTests() { TestContext.JSInterop.Mode = JSRuntimeMode.Loose; + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/AppBar/FluentAppBarItemTests.razor b/tests/Core/AppBar/FluentAppBarItemTests.razor index 096f5e0cad..34499effeb 100644 --- a/tests/Core/AppBar/FluentAppBarItemTests.razor +++ b/tests/Core/AppBar/FluentAppBarItemTests.razor @@ -13,6 +13,7 @@ JSInterop.Mode = JSRuntimeMode.Loose; Services.AddSingleton(GlobalState); + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/AppBar/FluentAppBarTests.razor b/tests/Core/AppBar/FluentAppBarTests.razor index cdf97ed80f..d35d6b0782 100644 --- a/tests/Core/AppBar/FluentAppBarTests.razor +++ b/tests/Core/AppBar/FluentAppBarTests.razor @@ -12,6 +12,7 @@ { JSInterop.Mode = JSRuntimeMode.Loose; Services.AddSingleton(GlobalState); + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/Button/FluentButtonTests.cs b/tests/Core/Button/FluentButtonTests.cs index 2b547f0fc4..f2b165df00 100644 --- a/tests/Core/Button/FluentButtonTests.cs +++ b/tests/Core/Button/FluentButtonTests.cs @@ -1,5 +1,6 @@ using Bunit; using FluentAssertions; +using Microsoft.Extensions.DependencyInjection; using Microsoft.FluentUI.AspNetCore.Components.Tests.Extensions; using Xunit; @@ -7,11 +8,10 @@ namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Button; public partial class FluentButtonTests : TestContext { - private static TestContext TestContext => new(); // TODO: To remove and to use the `RenderComponent` inherited method. - public FluentButtonTests() { - TestContext.JSInterop.Mode = JSRuntimeMode.Loose; + JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] @@ -21,7 +21,7 @@ public void FluentButton_Default() using var id = Identifier.SequentialContext(); // Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.AddChildContent("fluent-button"); }); @@ -34,7 +34,7 @@ public void FluentButton_Default() public void FluentButton_AutofocusAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.AddChildContent("fluent-button"); parameters.Add(p => p.Autofocus, true); @@ -52,7 +52,7 @@ public void FluentButton_AutofocusAttribute() public void FluentButton_FormIdAttribute(string? formId) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.FormId, formId); parameters.AddChildContent("fluent-button"); @@ -70,7 +70,7 @@ public void FluentButton_FormIdAttribute(string? formId) public void FluentButton_FormActionAttribute(string? formAction) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Action, formAction); parameters.AddChildContent("fluent-button"); @@ -88,7 +88,7 @@ public void FluentButton_FormActionAttribute(string? formAction) public void FluentButton_FormEnctypeAttribute(string? formEnctype) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Enctype, formEnctype); parameters.AddChildContent("fluent-button"); @@ -106,7 +106,7 @@ public void FluentButton_FormEnctypeAttribute(string? formEnctype) public void FluentButton_FormMethodAttribute(string? formMethod) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Method, formMethod); parameters.AddChildContent("fluent-button"); @@ -120,7 +120,7 @@ public void FluentButton_FormMethodAttribute(string? formMethod) public void FluentButton_FormNovalidateAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.NoValidate, true); parameters.AddChildContent("fluent-button"); @@ -139,7 +139,7 @@ public void FluentButton_FormNovalidateAttribute() public void FluentButton_FormTargetAttribute(string? formTarget) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Target, formTarget); parameters.AddChildContent("fluent-button"); @@ -157,7 +157,7 @@ public void Throw_ArgumentException_When_FormTargetAttribute_IsInvalid(string? f // Arrange && Act Action action = () => { - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Target, formTarget); parameters.AddChildContent("fluent-button"); @@ -175,7 +175,7 @@ public void Throw_ArgumentException_When_FormTargetAttribute_IsInvalid(string? f public void FluentButton_TypeAttribute(ButtonType buttonType) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Type, buttonType); parameters.AddChildContent("fluent-button"); @@ -193,7 +193,7 @@ public void FluentButton_TypeAttribute(ButtonType buttonType) public void FluentButton_IdAttribute(string? id) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Id, id); parameters.AddChildContent("fluent-button"); @@ -211,7 +211,7 @@ public void FluentButton_IdAttribute(string? id) public void FluentButton_ValueAttribute(string? value) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Value, value); parameters.AddChildContent("fluent-button"); @@ -229,7 +229,7 @@ public void FluentButton_ValueAttribute(string? value) public void FluentButton_CurrentValueAttribute(string? currentValue) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.CurrentValue, currentValue); parameters.AddChildContent("fluent-button"); @@ -243,7 +243,7 @@ public void FluentButton_CurrentValueAttribute(string? currentValue) public void FluentButton_DisabledAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Disabled, true); parameters.AddChildContent("fluent-button"); @@ -257,7 +257,7 @@ public void FluentButton_DisabledAttribute() public void FluentButton_NameAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Name, "name-value"); parameters.AddChildContent("fluent-button"); @@ -271,7 +271,7 @@ public void FluentButton_NameAttribute() public void FluentButton_RequiredAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Required, true); parameters.AddChildContent("fluent-button"); @@ -290,7 +290,7 @@ public void FluentButton_RequiredAttribute() public void FluentButton_AppearanceAttribute(Appearance appearance) { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Appearance, appearance); parameters.AddChildContent("fluent-button"); @@ -304,7 +304,7 @@ public void FluentButton_AppearanceAttribute(Appearance appearance) public void FluentButton_ClassAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Class, "additional-class"); parameters.AddChildContent("fluent-button"); @@ -318,7 +318,7 @@ public void FluentButton_ClassAttribute() public void FluentButton_StyleAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Style, "background-color: green;"); parameters.AddChildContent("fluent-button"); @@ -332,7 +332,7 @@ public void FluentButton_StyleAttribute() public void FluentButton_AdditionalAttribute() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.AddUnmatched("additional-attribute-name", "additional-attribute-value"); parameters.AddChildContent("fluent-button"); @@ -346,7 +346,7 @@ public void FluentButton_AdditionalAttribute() public void FluentButton_AdditionalAttributes() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.AddUnmatched("additional-attribute1-name", "additional-attribute1-value"); parameters.AddUnmatched("additional-attribute2-name", "additional-attribute2-value"); @@ -361,7 +361,7 @@ public void FluentButton_AdditionalAttributes() public void FluentButton_IconStart() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.IconStart, SampleIcons.Info); parameters.AddChildContent("My button"); @@ -375,7 +375,7 @@ public void FluentButton_IconStart() public void FluentButton_IconEnd() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.IconEnd, SampleIcons.Info); parameters.AddChildContent("My button"); @@ -389,7 +389,7 @@ public void FluentButton_IconEnd() public void FluentButton_IconNoContent() { // Arrange && Act - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.IconEnd, SampleIcons.Info); }); @@ -404,7 +404,7 @@ public void FluentButton_OnClick_Disabled() var clicked = false; // Arrange - var cut = TestContext.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.OnClick, (e) => { clicked = true; }); parameters.AddChildContent("My button"); diff --git a/tests/Core/Checkbox/FluentCheckboxTests.cs b/tests/Core/Checkbox/FluentCheckboxTests.cs index 69df3693e3..8e040bc426 100644 --- a/tests/Core/Checkbox/FluentCheckboxTests.cs +++ b/tests/Core/Checkbox/FluentCheckboxTests.cs @@ -1,10 +1,16 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Checkbox; public class FluentCheckboxTests : TestBase { + public FluentCheckboxTests() + { + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Theory] [InlineData(true)] [InlineData(false)] diff --git a/tests/Core/Checkbox/FluentCheckboxThreeStatesTests.razor b/tests/Core/Checkbox/FluentCheckboxThreeStatesTests.razor index 7b55a68e53..e59058f3fa 100644 --- a/tests/Core/Checkbox/FluentCheckboxThreeStatesTests.razor +++ b/tests/Core/Checkbox/FluentCheckboxThreeStatesTests.razor @@ -1,15 +1,19 @@ -@using Xunit; +@using Xunit; @inherits TestContext @code { + public FluentCheckboxThreeStatesTests() + { + JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Theory] [InlineData(false, true, true)] // Unchecked => Checked [InlineData(true, null, false)] // Checked => Indeterminate [InlineData(null, false, false)] // Indeterminate => Unchecked public void FluentCheckbox_ThreeStates(bool? initialState, bool? assertState, bool assertValue) { - this.JSInterop.Mode = JSRuntimeMode.Loose; - bool myValue = initialState ?? false; bool? myState = initialState; @@ -33,8 +37,6 @@ [InlineData(true, false, false)] // Checked => Unchecked public void FluentCheckbox_ThreeStates_InverseOrder(bool? initialState, bool? assertState, bool assertValue) { - this.JSInterop.Mode = JSRuntimeMode.Loose; - bool myValue = initialState ?? false; bool? myState = initialState; @@ -56,8 +58,6 @@ [Fact] public void FluentCheckbox_ThreeStates_ShowIntermediateFalse() { - this.JSInterop.Mode = JSRuntimeMode.Loose; - // Start Intermediate bool? myState = null; @@ -86,8 +86,6 @@ [InlineData(false, true)] // Checked => Unchecked public void FluentCheckbox_ThreeStatesFalse(bool initialValue, bool assertValue) { - this.JSInterop.Mode = JSRuntimeMode.Loose; - bool myValue = initialValue; // Arrange && Act @@ -106,12 +104,9 @@ [Fact] public void FluentCheckbox_Labels() { - this.JSInterop.Mode = JSRuntimeMode.Loose; - - // Arrange var cut = Render(@My customized content); cut.Verify(); } -} \ No newline at end of file +} diff --git a/tests/Core/DataGrid/DataGridSortByTests.razor b/tests/Core/DataGrid/DataGridSortByTests.razor index a7798c7063..34bbaaf837 100644 --- a/tests/Core/DataGrid/DataGridSortByTests.razor +++ b/tests/Core/DataGrid/DataGridSortByTests.razor @@ -9,6 +9,7 @@ public DataGridSortByTests() { JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); // Register Service var keycodeService = new KeyCodeService(); diff --git a/tests/Core/DataGrid/FluentDataGridColumSelectTests.razor.cs b/tests/Core/DataGrid/FluentDataGridColumSelectTests.razor.cs index 42f2901c4d..5c866db616 100644 --- a/tests/Core/DataGrid/FluentDataGridColumSelectTests.razor.cs +++ b/tests/Core/DataGrid/FluentDataGridColumSelectTests.razor.cs @@ -12,6 +12,7 @@ public partial class FluentDataGridColumSelectTests public FluentDataGridColumSelectTests() { JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); // Register Service var keycodeService = new KeyCodeService(); diff --git a/tests/Core/Divider/FluentDividerTests.razor b/tests/Core/Divider/FluentDividerTests.razor index 8eda80ab1f..fc43f8a25c 100644 --- a/tests/Core/Divider/FluentDividerTests.razor +++ b/tests/Core/Divider/FluentDividerTests.razor @@ -1,13 +1,16 @@ -@using Xunit; +@using Xunit; @inherits TestContext @code { - [Fact] - public void FluentDivider_Default() + public FluentDividerTests() { - // Arrange JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Fact] + public void FluentDivider_Default() + { // Act var cut = Render(@); @@ -18,9 +21,6 @@ [Fact] public void FluentDivider_Separator() { - // Arrange - JSInterop.Mode = JSRuntimeMode.Loose; - // Act var cut = Render(@); @@ -35,13 +35,10 @@ [InlineData(DividerRole.Presentation, Orientation.Vertical)] public void FluentDivider_RoleOrientation(DividerRole role, Orientation orientation) { - // Arrange - JSInterop.Mode = JSRuntimeMode.Loose; - // Act var cut = Render(@My content); // Assert cut.Verify(memberName: $"{nameof(FluentDivider_RoleOrientation)}_{role}_{orientation}"); } -} \ No newline at end of file +} diff --git a/tests/Core/Grid/FluentGridTests.razor b/tests/Core/Grid/FluentGridTests.razor index 88c4da259b..1ba4cb7a30 100644 --- a/tests/Core/Grid/FluentGridTests.razor +++ b/tests/Core/Grid/FluentGridTests.razor @@ -4,7 +4,8 @@ { public FluentGridTests() { - this.JSInterop.Mode = JSRuntimeMode.Loose; + JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/Icons/FluentIconTests.razor b/tests/Core/Icons/FluentIconTests.razor index 200cebcf8a..d7e554a577 100644 --- a/tests/Core/Icons/FluentIconTests.razor +++ b/tests/Core/Icons/FluentIconTests.razor @@ -3,6 +3,11 @@ @inherits TestContext @code { + public FluentIconTests() + { + Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Fact] public void FluentIcon_Default() { diff --git a/tests/Core/InputFile/FluentInputFileTests.razor b/tests/Core/InputFile/FluentInputFileTests.razor index 645e4c23f5..e0f3ea3f2f 100644 --- a/tests/Core/InputFile/FluentInputFileTests.razor +++ b/tests/Core/InputFile/FluentInputFileTests.razor @@ -1,7 +1,12 @@ -@using Xunit; +@using Xunit; @inherits TestContext @code { + public FluentInputFileTests() + { + Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Fact] public void FluentInputFile_Default() { diff --git a/tests/Core/KeyCodeProvider/FluentKeyCodeTests.razor b/tests/Core/KeyCodeProvider/FluentKeyCodeTests.razor index a2c57e166e..d76d026f51 100644 --- a/tests/Core/KeyCodeProvider/FluentKeyCodeTests.razor +++ b/tests/Core/KeyCodeProvider/FluentKeyCodeTests.razor @@ -2,11 +2,15 @@ @inherits TestContext @code { - [Fact] - public async Task FluentKeyCode_KeyA() + public FluentKeyCodeTests() { JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Fact] + public async Task FluentKeyCode_KeyA() + { FluentKeyCodeEventArgs pressed = new(); // Arrange && Act @@ -28,8 +32,6 @@ [Fact] public async Task FluentKeyCode_KeyDown_KeyA() { - JSInterop.Mode = JSRuntimeMode.Loose; - FluentKeyCodeEventArgs pressed = new(); // Arrange && Act @@ -44,8 +46,6 @@ [Fact] public async Task FluentKeyCode_ChildContent() { - JSInterop.Mode = JSRuntimeMode.Loose; - FluentKeyCodeEventArgs pressed = new(); // Arrange && Act @@ -67,8 +67,6 @@ [Fact] public async Task FluentKeyCode_CtrlShiftAltMeta() { - JSInterop.Mode = JSRuntimeMode.Loose; - FluentKeyCodeEventArgs pressed = new(); // Arrange && Act @@ -96,8 +94,6 @@ [InlineData(true, true, true, true, "Ctrl + Shift + Alt + Meta + A")] public async Task FluentKeyCode_KeyA_ToString(bool ctrlKey, bool shiftKey, bool altKey, bool metaKey, string expected) { - JSInterop.Mode = JSRuntimeMode.Loose; - FluentKeyCodeEventArgs pressed = new(); // Arrange && Act @@ -112,7 +108,6 @@ [Fact] public async Task FluentKeyCode_Provider_Function() { - JSInterop.Mode = JSRuntimeMode.Loose; FluentKeyCodeEventArgs pressed = new(); // Register Service @@ -146,7 +141,6 @@ [Fact] public async Task FluentKeyCode_Provider_Interface() { - JSInterop.Mode = JSRuntimeMode.Loose; FluentKeyCodeEventArgs pressed = new(); // Register Service @@ -177,8 +171,6 @@ [Fact] public async Task FluentKeyCode_AnchorOrChildContent_Required() { - JSInterop.Mode = JSRuntimeMode.Loose; - FluentKeyCodeEventArgs pressed = new(); // Arrange && Act diff --git a/tests/Core/NavMenu/FluentNavGroupTests.cs b/tests/Core/NavMenu/FluentNavGroupTests.cs index 2fa7cda68b..8cb13cbb69 100644 --- a/tests/Core/NavMenu/FluentNavGroupTests.cs +++ b/tests/Core/NavMenu/FluentNavGroupTests.cs @@ -1,4 +1,5 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Microsoft.FluentUI.AspNetCore.Components.Tests.Extensions; using Xunit; @@ -9,6 +10,7 @@ public class FluentNavGroupTests : TestBase public FluentNavGroupTests() { TestContext.JSInterop.Mode = JSRuntimeMode.Loose; + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/NavMenu/FluentNavMenuTests.cs b/tests/Core/NavMenu/FluentNavMenuTests.cs index 93f0a7fb30..ac29ed0a2e 100644 --- a/tests/Core/NavMenu/FluentNavMenuTests.cs +++ b/tests/Core/NavMenu/FluentNavMenuTests.cs @@ -1,4 +1,5 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.NavMenu; @@ -8,6 +9,7 @@ public class FluentNavMenuTests : TestBase public FluentNavMenuTests() { TestContext.JSInterop.Mode = JSRuntimeMode.Loose; + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/ProfileMenu/FluentProfileMenuTests.razor b/tests/Core/ProfileMenu/FluentProfileMenuTests.razor index baedcc8ced..5b38beb057 100644 --- a/tests/Core/ProfileMenu/FluentProfileMenuTests.razor +++ b/tests/Core/ProfileMenu/FluentProfileMenuTests.razor @@ -7,6 +7,7 @@ public FluentProfileMenuTests() { this.Services.AddScoped(); + this.Services.AddSingleton(LibraryConfiguration.ForUnitTests); this.JSInterop.Mode = JSRuntimeMode.Loose; } diff --git a/tests/Core/PullToRefresh/FluentPullToRefreshTests.razor b/tests/Core/PullToRefresh/FluentPullToRefreshTests.razor index a36805e764..56e36e2bb7 100644 --- a/tests/Core/PullToRefresh/FluentPullToRefreshTests.razor +++ b/tests/Core/PullToRefresh/FluentPullToRefreshTests.razor @@ -5,6 +5,7 @@ public FluentPullToRefreshTests() { this.JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } // write some unit tests here diff --git a/tests/Core/Slider/FluentSliderLaberTests.cs b/tests/Core/Slider/FluentSliderLaberTests.cs index e1c3232d16..661ede5fd5 100644 --- a/tests/Core/Slider/FluentSliderLaberTests.cs +++ b/tests/Core/Slider/FluentSliderLaberTests.cs @@ -1,6 +1,7 @@ namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Slider; using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; public class FluentSliderLabelTests : TestBase @@ -8,6 +9,7 @@ public class FluentSliderLabelTests : TestBase public FluentSliderLabelTests() { TestContext.JSInterop.Mode = JSRuntimeMode.Loose; + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/SortableList/FluentSortableListTests.razor b/tests/Core/SortableList/FluentSortableListTests.razor index 14c623a166..006ffb587b 100644 --- a/tests/Core/SortableList/FluentSortableListTests.razor +++ b/tests/Core/SortableList/FluentSortableListTests.razor @@ -7,7 +7,6 @@ { public int Id { get; set; } public string Name { get; set; } = ""; - public bool Disabled { get; set; } = false; } @@ -16,8 +15,7 @@ public FluentSortableListTests() { JSInterop.Mode = JSRuntimeMode.Loose; - //JSInterop.SetupModule("./_content/Microsoft.FluentUI.AspNetCore.Components/Components/SortableList/FluentSortableList.razor.js"); - //JSInterop.Setup("init", _ => true); + Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/Splitter/FluentMultiSplitterTests.razor b/tests/Core/Splitter/FluentMultiSplitterTests.razor index 030899e312..fde29441a5 100644 --- a/tests/Core/Splitter/FluentMultiSplitterTests.razor +++ b/tests/Core/Splitter/FluentMultiSplitterTests.razor @@ -3,14 +3,17 @@ @code { + public FluentMultiSplitterTests() + { + JSInterop.Mode = JSRuntimeMode.Loose; + Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Fact] public void FluentMultiSplitter_Horizontal_Basic() { // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Orientation, Orientation.Horizontal); parameters.AddChildContent(pane => @@ -31,10 +34,7 @@ public void FluentMultiSplitter_Vertical_Basic() { // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.Orientation, Orientation.Vertical); parameters.AddChildContent(pane => @@ -55,10 +55,7 @@ public void FluentMultiSplitter_PaneCollapsible() { // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.AddChildContent(pane => { @@ -82,10 +79,7 @@ bool eventCalled = false; // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.OnResize, (e) => eventCalled = true); parameters.AddChildContent(pane => @@ -110,10 +104,7 @@ public void FluentMultiSplitter_PaneResizedReceived() { // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.AddChildContent(pane => { @@ -139,10 +130,7 @@ public async Task FluentMultiSplitter_PaneResizeCanceled() { // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.OnResize, (e) => e.Cancel = true); parameters.AddChildContent(pane => @@ -172,8 +160,6 @@ public void FluentMultiSplitter_Size_Fixed() { // Arrange - JSInterop.Mode = JSRuntimeMode.Loose; - var cut = Render( @ Pane A @@ -201,10 +187,7 @@ bool eventCalled = false; // Arrange - using var ctx = new Bunit.TestContext(); - ctx.JSInterop.Mode = JSRuntimeMode.Loose; - - var cut = ctx.RenderComponent(parameters => + var cut = RenderComponent(parameters => { parameters.Add(p => p.OnExpand, (e) => eventCalled = true); parameters.Add(p => p.OnCollapse, (e) => eventCalled = true); diff --git a/tests/Core/Utilities/JSModuleTests.cs b/tests/Core/Utilities/JSModuleTests.cs deleted file mode 100644 index caee9adceb..0000000000 --- a/tests/Core/Utilities/JSModuleTests.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Utilities; - -public class JSModuleTests -{ - //[Fact] - //public async Task InvokeVoidAsync_InvokesMethod() - //{ - // // Arrange - // var jsRuntime = new MockJSRuntime(); - // var module = new TestJSModule(jsRuntime, "test.js"); - - // // Act - // await module.InvokeVoidAsync("testMethod"); - - // // Assert - // Assert.True(jsRuntime.InvokedMethods.Contains(("import", new object[] { "test.js" }))); - // Assert.True(jsRuntime.InvokedMethods.Contains(("testMethod", null))); - //} - - //[Fact] - //public async Task InvokeAsync_InvokesMethod() - //{ - // // Arrange - // var jsRuntime = new MockJSRuntime(); - // var module = new TestJSModule(jsRuntime, "test.js"); - - // // Act - // var result = await module.InvokeAsync("testMethod"); - - // // Assert - // Assert.True(jsRuntime.InvokedMethods.Contains(("import", new object[] { "test.js" }))); - // Assert.True(jsRuntime.InvokedMethods.Contains(("testMethod", null))); - // Assert.Equal("testResult", result); - //} - - //[Fact] - //public async Task DisposeAsync_DisposesModule() - //{ - // // Arrange - // var jsRuntime = new MockJSRuntime(); - // var module = new TestJSModule(jsRuntime, "test.js"); - - // // Act - // await module.DisposeAsync(); - - // // Assert - // Assert.True(jsRuntime.InvokedMethods.Contains(("import", new object[] { "test.js" }))); - // Assert.True(jsRuntime.InvokedMethods.Contains(("dispose", null))); - //} - - //private class TestJSModule : JSModule - //{ - // public TestJSModule(IJSRuntime js, string moduleUrl) : base(js, moduleUrl) - // { - // } - - // public async Task InvokeVoidAsync(string method) - // { - // await Task.Delay(100); - - // } - - // public new ValueTask DisposeAsync() - // { - // return base.DisposeAsync(); - // } - //} - - //public class MockJSRuntime : IJSRuntime - //{ - // public ValueTask InvokeAsync(string identifier, object?[]? args) - // { - // return default; - // } - - // public ValueTask InvokeAsync(string identifier, CancellationToken cancellationToken, object?[]? args) - // { - // return default; - // } - //} -} diff --git a/tests/Core/_ToDo/HorizontalScroll/FluentHorizontalScrollTests.cs b/tests/Core/_ToDo/HorizontalScroll/FluentHorizontalScrollTests.cs index c9ee5d1738..33db9c4702 100644 --- a/tests/Core/_ToDo/HorizontalScroll/FluentHorizontalScrollTests.cs +++ b/tests/Core/_ToDo/HorizontalScroll/FluentHorizontalScrollTests.cs @@ -1,4 +1,5 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.HorizontalScroll; @@ -7,7 +8,9 @@ public class FluentHorizontalScrollTests : TestBase public FluentHorizontalScrollTests() { TestContext.JSInterop.SetupModule("./_content/Microsoft.FluentUI.AspNetCore.Components/Components/HorizontalScroll/FluentHorizontalScroll.razor.js"); + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } + [Fact] public void FluentHorizontalScroll_Default() { diff --git a/tests/Core/_ToDo/MainLayout/FluentMainLayoutTests.cs b/tests/Core/_ToDo/MainLayout/FluentMainLayoutTests.cs index 8c7f344cd8..a18a99e611 100644 --- a/tests/Core/_ToDo/MainLayout/FluentMainLayoutTests.cs +++ b/tests/Core/_ToDo/MainLayout/FluentMainLayoutTests.cs @@ -1,4 +1,5 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.MainLayout; @@ -7,6 +8,7 @@ public class FluentMainLayoutTests : TestBase public FluentMainLayoutTests() { TestContext.JSInterop.Mode = JSRuntimeMode.Loose; + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/_ToDo/Menu/FluentMenuTests.cs b/tests/Core/_ToDo/Menu/FluentMenuTests.cs index 0a9202b95e..0d70cf6637 100644 --- a/tests/Core/_ToDo/Menu/FluentMenuTests.cs +++ b/tests/Core/_ToDo/Menu/FluentMenuTests.cs @@ -1,4 +1,5 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.Menu; @@ -7,6 +8,7 @@ public class FluentMenuTests : TestBase public FluentMenuTests() { TestContext.JSInterop.SetupModule("./_content/Microsoft.FluentUI.AspNetCore.Components/Components/Menu/FluentMenu.razor.js"); + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); } [Fact] diff --git a/tests/Core/_ToDo/MenuButton/FluentMenuButtonTests.cs b/tests/Core/_ToDo/MenuButton/FluentMenuButtonTests.cs index 66ade92692..ac3895b4e4 100644 --- a/tests/Core/_ToDo/MenuButton/FluentMenuButtonTests.cs +++ b/tests/Core/_ToDo/MenuButton/FluentMenuButtonTests.cs @@ -1,9 +1,16 @@ using Bunit; +using Microsoft.Extensions.DependencyInjection; using Xunit; namespace Microsoft.FluentUI.AspNetCore.Components.Tests.MenuButton; + public class FluentMenuButtonTests : TestBase { + public FluentMenuButtonTests() + { + TestContext.Services.AddSingleton(LibraryConfiguration.ForUnitTests); + } + [Fact] public void FluentMenuButton_Default() {