diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor similarity index 56% rename from src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor rename to src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor index 0b25c15ac0..9ddbeb6157 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor @@ -7,17 +7,17 @@ style="@StyleBuilder.Value" class="@ClassBuilder.Value" dir="@Dir?.ToString().ToLower()"> -
+
-
-
+
+
@ChildContent
-
+
-
+
\ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs similarity index 63% rename from src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor.cs rename to src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs index af75a24d4a..2b65b7e6cb 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.razor.cs @@ -1,7 +1,14 @@ namespace Bit.BlazorUI; -public partial class BitProLayout : BitComponentBase +public partial class BitAppShell : BitComponentBase { + private ElementReference _containerRef = default!; + + + [Inject] private IJSRuntime _js { get; set; } = default!; + + + /// /// The cascading values to be provided for the children of the layout. /// @@ -15,16 +22,23 @@ public partial class BitProLayout : BitComponentBase /// /// Custom CSS classes for different parts of the layout. /// - [Parameter] public BitProLayoutClassStyles? Classes { get; set; } + [Parameter] public BitAppShellClassStyles? Classes { get; set; } /// /// Custom CSS styles for different parts of the layout. /// - [Parameter] public BitProLayoutClassStyles? Styles { get; set; } + [Parameter] public BitAppShellClassStyles? Styles { get; set; } + + + + public async Task GoToTop() + { + await _js.BitExtrasGoToTop(_containerRef); + } - protected override string RootElementClass => "bit-ply"; + protected override string RootElementClass => "bit-ash"; protected override void RegisterCssClasses() { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss similarity index 89% rename from src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.scss rename to src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss index 81b2fa70d4..f9aa459c37 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShell.scss @@ -1,7 +1,7 @@ @import '../../Styles/extra-variables.scss'; @import '../../../Bit.BlazorUI/Styles/functions.scss'; -.bit-ply { +.bit-ash { width: 100%; height: 100%; display: flex; @@ -9,27 +9,27 @@ background-color: $clr-bg-pri; } -.bit-ply-top { +.bit-ash-top { width: 100%; z-index: 999999; height: $bit-env-inset-top; background-color: $clr-bg-pri; } -.bit-ply-bottom { +.bit-ash-bottom { width: 100%; z-index: 999999; height: $bit-env-inset-bottom; background-color: $clr-bg-pri; } -.bit-ply-center { +.bit-ash-center { width: 100%; display: flex; height: calc(100% - $bit-env-inset-top - $bit-env-inset-bottom); } -.bit-ply-main { +.bit-ash-main { height: 100%; display: flex; overflow: auto; @@ -39,14 +39,14 @@ width: calc(100% - $bit-env-inset-left - $bit-env-inset-right); } -.bit-ply-left { +.bit-ash-left { height: 100%; z-index: 999999; width: $bit-env-inset-left; background-color: $clr-bg-pri; } -.bit-ply-right { +.bit-ash-right { height: 100%; z-index: 999999; width: $bit-env-inset-right; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayoutClassStyles.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs similarity index 62% rename from src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayoutClassStyles.cs rename to src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs index 6793afc5ca..703b86ce31 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayoutClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitAppShellClassStyles.cs @@ -1,39 +1,39 @@ namespace Bit.BlazorUI; -public class BitProLayoutClassStyles +public class BitAppShellClassStyles { /// - /// Custom CSS classes/styles for the root of the BitProLayout. + /// Custom CSS classes/styles for the root of the BitAppShell. /// public string? Root { get; set; } /// - /// Custom CSS classes/styles for the top area of the BitProLayout. + /// Custom CSS classes/styles for the top area of the BitAppShell. /// public string? Top { get; set; } /// - /// Custom CSS classes/styles for the center area of the BitProLayout. + /// Custom CSS classes/styles for the center area of the BitAppShell. /// public string? Center { get; set; } /// - /// Custom CSS classes/styles for the left area of the BitProLayout. + /// Custom CSS classes/styles for the left area of the BitAppShell. /// public string? Left { get; set; } /// - /// Custom CSS classes/styles for the main area of the BitProLayout. + /// Custom CSS classes/styles for the main area of the BitAppShell. /// public string? Main { get; set; } /// - /// Custom CSS classes/styles for the right area of the BitProLayout. + /// Custom CSS classes/styles for the right area of the BitAppShell. /// public string? Right { get; set; } /// - /// Custom CSS classes/styles for the bottom area of the BitProLayout. + /// Custom CSS classes/styles for the bottom area of the BitAppShell. /// public string? Bottom { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValue.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitCascadingValue.cs similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValue.cs rename to src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitCascadingValue.cs diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValueProvider.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitCascadingValueProvider.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValueProvider.cs rename to src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitCascadingValueProvider.cs index 4dc929cf99..dde4e2a9b8 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValueProvider.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/AppShell/BitCascadingValueProvider.cs @@ -57,7 +57,7 @@ private void CreateCascadingValue(RenderTreeBuilder builder, #pragma warning disable IL2055 // Either the type on which the MakeGenericType is called can't be statically determined, or the type parameters to be used for generic arguments can't be statically determined. builder.OpenComponent(seq, _cascadingValueType.MakeGenericType(value.GetType())); #pragma warning restore IL2055 // Either the type on which the MakeGenericType is called can't be statically determined, or the type parameters to be used for generic arguments can't be statically determined. - if (string.IsNullOrEmpty(name) is false) + if (name.HasValue()) { builder.AddComponentParameter(++seq, "Name", name); } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/JsInterop/BitChartJavascriptHandler.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/JsInterop/BitChartJavascriptHandler.cs index 7436279d0c..9a9dcdd886 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/JsInterop/BitChartJavascriptHandler.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/JsInterop/BitChartJavascriptHandler.cs @@ -25,7 +25,7 @@ public class BitChartJavascriptHandler : IBitChartMethodHandler /// The namespace and name of a JavaScript function (see for details). public BitChartJavascriptHandler(string methodName) { - if (string.IsNullOrWhiteSpace(methodName)) + if (methodName.HasNoValue()) throw new ArgumentException("The method name cannot be null or whitespace. It has to include the namespace and name of the js-function."); if (methodName.Length < 3 || methodName.Count(c => c == '.') > 1) diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Util/ExpandoObjectExtensions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Util/ExpandoObjectExtensions.cs index 4dff5d151b..e10abf7b69 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Util/ExpandoObjectExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/Util/ExpandoObjectExtensions.cs @@ -21,7 +21,7 @@ public static ExpandoObject EnsurePathExists(this ExpandoObject value, string pa { value ??= new ExpandoObject(); - if (string.IsNullOrWhiteSpace(path)) return value; + if (path.HasNoValue()) return value; string[] segments = path.Split('.'); IDictionary source = value; @@ -80,10 +80,10 @@ public static bool PathExists(this ExpandoObject value, string path, out object[ /// public static IEnumerable EnumeratePath(this ExpandoObject value, string path) { - if (value == null) + if (value is null) throw new ArgumentNullException(nameof(value)); - if (string.IsNullOrWhiteSpace(path)) + if (path.HasNoValue()) throw new ArgumentException("The path cannot be null or whitespace."); string[] segments = path.Split('.'); @@ -131,7 +131,7 @@ public static object GetValue(this ExpandoObject value, string path) /// public static ExpandoObject SetValue(this ExpandoObject expando, string path, object value) { - if (string.IsNullOrWhiteSpace(path)) + if (path.HasNoValue()) throw new ArgumentException("The path cannot be null or whitespace."); string[] segments = path.Split('.'); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss index e3cf74ab70..e2551fddd2 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss @@ -41,7 +41,7 @@ } .col-sort-desc .sort-indicator { - transform: scaleY(-1) translateY(2px); + transform: scaleY(-1) translateY(-2px); } /* Deep to make it easy for people adding a col-options-button element in a custom HeaderTemplate */ th .col-options-button { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Columns/BitDataGridPropertyColumn.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Columns/BitDataGridPropertyColumn.cs index 1a2886e7f4..3fe85ed0bc 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Columns/BitDataGridPropertyColumn.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Columns/BitDataGridPropertyColumn.cs @@ -37,7 +37,7 @@ protected override void OnParametersSet() _lastAssignedProperty = Property; var compiledPropertyExpression = Property.Compile(); - if (!string.IsNullOrEmpty(Format)) + if (Format.HasValue()) { if (typeof(IFormattable).IsAssignableFrom(typeof(TProp))) { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor new file mode 100644 index 0000000000..669093d062 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor @@ -0,0 +1,118 @@ +@namespace Bit.BlazorUI +@inherits BitComponentBase +@typeparam TItem + +@if (IsOpen) +{ +
+} + +@{ + var isToggled = Togglable && IsToggled; +} + +
+ +
+ @if (Header is not null) + { + @Header + } + else + { +
+ @if (IconUrl.HasValue()) + { + + } + +
+ + @if (Togglable) + { + + } +
+ } + + + + @if (isToggled) + { + + } + + @if (_filteredNavItems.Any() is false) + { + if (isToggled is false) + { + if (EmptyListTemplate is not null) + { + @EmptyListTemplate + } + else + { + + @(EmptyListMessage ?? "Nothing found!") + + } + } + } + else + { + + } + + + + @if (Footer is not null) + { + @Footer + } +
+ +
\ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs new file mode 100644 index 0000000000..9b3fb46972 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.razor.cs @@ -0,0 +1,255 @@ +namespace Bit.BlazorUI; + +public partial class BitNavPanel : BitComponentBase, IDisposable where TItem : class +{ + private bool _disposed; + private decimal diffXPanel; + private BitNav _bitNavRef = default!; + private IList _filteredNavItems = []; + private BitSearchBox _searchBoxRef = default!; + private IEnumerable _flatNavItemList = []; + + + [Inject] private IJSRuntime _js { get; set; } = default!; + + + + /// + /// Custom CSS classes for different parts of the nav panel. + /// + [Parameter] public BitNavPanelClassStyles? Classes { get; set; } + + /// + /// The custom template for when the search result is empty. + /// + [Parameter] public RenderFragment? EmptyListTemplate { get; set; } + + /// + /// The custom message for when the search result is empty. + /// + [Parameter] public string? EmptyListMessage { get; set; } + + /// + /// The custom template to render as the footer of the nav panel. + /// + [Parameter] public RenderFragment? Footer { get; set; } + + /// + /// The custom template to render as the header of the nav panel. + /// + [Parameter] public RenderFragment? Header { get; set; } + + /// + /// The icon url to show in the header of the nav panel. + /// + [Parameter] public string? IconUrl { get; set; } + + /// + /// Determines if the nav panel is open in small screens. + /// + [Parameter, TwoWayBound, ResetClassBuilder] + public bool IsOpen { get; set; } + + /// + /// Determines if the nav panel is in the toggled state. + /// + [Parameter, TwoWayBound] + public bool IsToggled { get; set; } + + /// + /// A collection of items to display in the nav panel. + /// + [Parameter] public IList Items { get; set; } = []; + + /// + /// Custom CSS classes for different parts of the nav component of the nav panel. + /// + [Parameter] public BitNavClassStyles? NavClasses { get; set; } + + /// + /// Custom CSS styles for different parts of the nav component of the nav panel. + /// + [Parameter] public BitNavClassStyles? NavStyles { get; set; } + + /// + /// Event fired up when an item is clicked. + /// + [Parameter] public EventCallback OnItemClick { get; set; } + + /// + /// Enables the padded mode of the nav panel. + /// + [Parameter, ResetClassBuilder] + public bool Padded { get; set; } + + /// + /// Custom CSS classes for different parts of the search box of the nav panel. + /// + [Parameter] public BitSearchBoxClassStyles? SearchBoxClasses { get; set; } + + /// + /// The placeholder of the input element of the search box of the nav panel. + /// + [Parameter] public string? SearchBoxPlaceholder { get; set; } + + /// + /// Custom CSS styles for different parts of the search box of the nav panel. + /// + [Parameter] public BitSearchBoxClassStyles? SearchBoxStyles { get; set; } + + /// + /// Custom CSS styles for different parts of the nav panel. + /// + [Parameter] public BitNavPanelClassStyles? Styles { get; set; } + + /// + /// Enables the toggle feature of the nav panel. + /// + [Parameter] public bool Togglable { get; set; } + + /// + /// The top CSS property value of the root element of the nav panel in px. + /// + [Parameter, ResetStyleBuilder] + public int Top { get; set; } + + + + protected override string RootElementClass => "bit-npn"; + + protected override void RegisterCssClasses() + { + ClassBuilder.Register(() => Classes?.Root); + ClassBuilder.Register(() => IsOpen ? string.Empty : "bit-npn-cls"); + ClassBuilder.Register(() => Padded ? "bit-npn-pad" : string.Empty); + } + + protected override void RegisterCssStyles() + { + StyleBuilder.Register(() => Styles?.Root); + StyleBuilder.Register(() => Top > 0 ? $"top:{Top}px;height:calc(var(--bit-env-height-avl) - {Top}px)" : string.Empty); + } + + protected override async Task OnInitializedAsync() + { + SearchNavItems(null); + } + + private async Task HandleNavItemClick(TItem item) + { + if (_bitNavRef.GetUrl(item).HasNoValue()) return; + + await OnItemClick.InvokeAsync(item); + + await _searchBoxRef.Clear(); + + _filteredNavItems = Items; + + await ClosePanel(); + } + + private async Task ClosePanel() + { + if (await AssignIsOpen(false)) return; + } + + private async Task ToggleNavPanel() + { + if (await AssignIsToggled(!IsToggled)) return; + + if (IsToggled) + { + SearchNavItems(null); + } + } + + private async Task ToggleForSearch() + { + if (await AssignIsToggled(false)) return; + + await Task.Delay(1); + await _searchBoxRef.FocusAsync(); + } + + private void SearchNavItems(string? searchText) + { + _filteredNavItems = Items; + if (searchText.HasNoValue()) return; + + _flatNavItemList = Items.Flatten(_bitNavRef.GetChildItems).Where(item => _bitNavRef.GetUrl(item).HasValue()); + + var mainItems = _flatNavItemList.Where(item => searchText!.Split(' ') + .Where(t => t.HasValue()) + .Any(t => $"{_bitNavRef.GetText(item)} {_bitNavRef.GetDescription(item)}" + .Contains(t, StringComparison.InvariantCultureIgnoreCase))); + + var subItems = _flatNavItemList.Where(item => searchText!.Split(' ') + .Where(t => t.HasValue()) + .Any(t => _bitNavRef.GetData(item)?.ToString()? + .Contains(t, StringComparison.InvariantCultureIgnoreCase) ?? false)); + + _filteredNavItems = [.. mainItems, .. subItems]; + } + + private decimal _oldDiffY = 0; + private void HandleOnSwipeMove(BitSwipeTrapEventArgs args) + { + if (IsOpen is false) return; + + if (Math.Abs(args.DiffX) > Math.Abs(args.DiffY)) + { + diffXPanel = args.DiffX; + StateHasChanged(); + } + else + { + var diff = args.DiffY - _oldDiffY; + _js.BitExtrasScrollBy(RootElement, 0, diff > 0 ? -10 : 10); + _oldDiffY = args.DiffY; + } + + } + private void HandleOnSwipeEnd(BitSwipeTrapEventArgs args) + { + if (IsOpen is false) return; + + diffXPanel = 0; + StateHasChanged(); + } + private async Task HandleOnSwipeTrigger(BitSwipeTrapTriggerArgs args) + { + if (IsOpen is false) return; + + if ((Dir != BitDir.Rtl && args.Direction == BitSwipeDirection.Left) || + (Dir == BitDir.Rtl && args.Direction == BitSwipeDirection.Right)) + { + diffXPanel = 0; + await ClosePanel(); + StateHasChanged(); + } + } + + private string? GetPanelStyle() + { + if (IsOpen is false) return StyleBuilder.Value; + + var translate = ((Dir != BitDir.Rtl && diffXPanel < 0) || (Dir == BitDir.Rtl && diffXPanel > 0)) + ? $"transform: translateX({diffXPanel}px)" + : string.Empty; + return $"{translate};{StyleBuilder.Value}".Trim(';'); + } + + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing is false || _disposed) return; + + _disposed = true; + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.scss new file mode 100644 index 0000000000..b726fef594 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanel.scss @@ -0,0 +1,115 @@ +@import "../../../Bit.BlazorUI/Styles/functions.scss"; +@import "../../../Bit.BlazorUI/Styles/media-queries.scss"; + +.bit-npn { + top: 0; + position: sticky; + min-width: 14rem; + max-width: 14rem; + overflow: hidden auto; + background-color: $clr-bg-pri; + height: var(--bit-env-height-avl); + + @include lt-md { + left: 0; + padding: 0; + opacity: 1; + position: fixed; + height: unset !important; + z-index: $zindex-callout; + bottom: var(--bit-env-inset-bottom); + top: var(--bit-env-inset-top) !important; + transition: transform 150ms ease-out, opacity 100ms ease-in; + + &.bit-rtl { + right: 0; + left: unset; + } + + &.bit-npn-cls { + opacity: 0; + transform: translateX(-100%); + + &.bit-rtl { + transform: translateX(100%); + } + } + } + + &.bit-npn-tgl { + min-width: 3rem; + max-width: 3rem; + + .bit-npn-cnt { + align-items: center; + } + + &.bit-npn-pad { + min-width: 6rem; + max-width: 6rem; + } + } + + &.bit-npn-pad { + padding: 1rem; + + .bit-npn-cnt { + padding: 0.5rem; + background-color: $clr-bg-sec; + } + } + + &::-webkit-scrollbar { + width: 0; + } + + .bit-srb, .bit-srb-cnt { + width: 100%; + } +} + +.bit-macos .bit-npn { + height: -webkit-fill-available; + + .bit-npn-cnt { + height: -webkit-fill-available; + } +} + +.bit-npn-ovl { + inset: 0; + width: 100%; + height: 100%; + position: fixed; + min-height: 100vh; + z-index: $zindex-overlay; + background-color: $clr-bg-overlay; + + @include gt-sm { + display: none; + } +} + +.bit-npn-cnt { + gap: 1rem; + width: auto; + display: flex; + min-height: 100%; + height: fit-content; + flex-direction: column; +} + +.bit-npn-hdr { + display: flex; + align-items: center; + justify-content: center; +} + +.bit-npn-img { + max-width: 38px; + max-height: 38px; +} + +.bit-npn-spc { + flex-grow: 1; +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanelClassStyles.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanelClassStyles.cs new file mode 100644 index 0000000000..581bb5d194 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/NavPanel/BitNavPanelClassStyles.cs @@ -0,0 +1,54 @@ +namespace Bit.BlazorUI; + +public class BitNavPanelClassStyles +{ + /// + /// Custom CSS classes/styles for the overlay of the BitNavPanel. + /// + public string? Overlay { get; set; } + + /// + /// Custom CSS classes/styles for the root element of the BitNavPanel. + /// + public string? Root { get; set; } + + /// + /// Custom CSS classes/styles for the container of the BitNavPanel. + /// + public string? Container { get; set; } + + /// + /// Custom CSS classes/styles for the header container of the BitNavPanel. + /// + public string? Header { get; set; } + + /// + /// Custom CSS classes/styles for the header icon of the BitNavPanel. + /// + public string? HeaderIcon { get; set; } + + /// + /// Custom CSS classes/styles for the toggle button of the BitNavPanel. + /// + public string? ToggleButton { get; set; } + + /// + /// Custom CSS classes/styles for the search box of the BitNavPanel. + /// + public string? SearchBox { get; set; } + + /// + /// Custom CSS classes/styles for the toggle search button of the BitNavPanel. + /// + public string? ToggleSearchButton { get; set; } + + /// + /// Custom CSS classes/styles for the text element of the empty list message of the BitNavPanel. + /// + public string? EmptyListMessage { get; set; } + + /// + /// Custom CSS classes/styles for the nav component of the BitNavPanel. + /// + public string? Nav { get; set; } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/IServiceCollectionExtensions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/IServiceCollectionExtensions.cs similarity index 89% rename from src/BlazorUI/Bit.BlazorUI.Extras/IServiceCollectionExtensions.cs rename to src/BlazorUI/Bit.BlazorUI.Extras/Extensions/IServiceCollectionExtensions.cs index 0ae549d8eb..ffc6573935 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/IServiceCollectionExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/IServiceCollectionExtensions.cs @@ -16,10 +16,12 @@ public static IServiceCollection AddBitBlazorUIExtrasServices(this IServiceColle if (trySingleton) { services.TryAddSingleton(); + services.TryAddSingleton(); } else { services.TryAddScoped(); + services.TryAddScoped(); } return services; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/JsInterop/BitExtrasJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/JsInterop/BitExtrasJsRuntimeExtensions.cs new file mode 100644 index 0000000000..7a55e2fc1a --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/JsInterop/BitExtrasJsRuntimeExtensions.cs @@ -0,0 +1,19 @@ +namespace Bit.BlazorUI; + +internal static class BitExtrasJsRuntimeExtensions +{ + internal static ValueTask BitExtrasApplyRootClasses(this IJSRuntime jsRuntime, List cssClasses, Dictionary cssVariables) + { + return jsRuntime.InvokeVoid("BitBlazorUI.BitExtras.applyRootClasses", cssClasses, cssVariables); + } + + internal static ValueTask BitExtrasGoToTop(this IJSRuntime jsRuntime, ElementReference element) + { + return jsRuntime.InvokeVoid("BitBlazorUI.BitExtras.goToTop", element); + } + + internal static ValueTask BitExtrasScrollBy(this IJSRuntime jsRuntime, ElementReference element, decimal x, decimal y) + { + return jsRuntime.InvokeVoid("BitBlazorUI.BitExtras.scrollBy", element, x, y); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/LinqExtensions.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/LinqExtensions.cs new file mode 100644 index 0000000000..4c953a5a96 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Extensions/LinqExtensions.cs @@ -0,0 +1,49 @@ +namespace Bit.BlazorUI; + +/// +/// https://www.codeproject.com/tips/375967/flatten-a-hierarchical-collection-of-objects-with +/// +public static class LinqExtensions +{ + /// + /// This method extends the LINQ methods to flatten a collection of + /// items that have a property of children of the same type. + /// + /// Item type. + /// Source collection. + /// + /// Child property selector delegate of each item. + /// IEnumerable'T' childPropertySelector(T itemBeingFlattened) + /// + /// Returns a one level list of elements of type T. + public static IEnumerable Flatten(this IEnumerable source, + Func> childPropertySelector) + { + return source + .Flatten((itemBeingFlattened, objectsBeingFlattened) => + childPropertySelector(itemBeingFlattened)); + } + + /// + /// This method extends the LINQ methods to flatten a collection of + /// items that have a property of children of the same type. + /// + /// Item type. + /// Source collection. + /// + /// Child property selector delegate of each item. + /// IEnumerable'T' childPropertySelector + /// (T itemBeingFlattened, IEnumerable'T' objectsBeingFlattened) + /// + /// Returns a one level list of elements of type T. + public static IEnumerable Flatten(this IEnumerable source, + Func, IEnumerable> childPropertySelector) + { + return source + .Concat(source + .Where(item => childPropertySelector(item, source) != null) + .SelectMany(itemBeingFlattened => + childPropertySelector(itemBeingFlattened, source) + .Flatten(childPropertySelector))); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Scripts/BitExtras.ts b/src/BlazorUI/Bit.BlazorUI.Extras/Scripts/BitExtras.ts new file mode 100644 index 0000000000..b2463e681f --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Scripts/BitExtras.ts @@ -0,0 +1,20 @@ +namespace BitBlazorUI { + export class BitExtras { + public static applyRootClasses(cssClasses: string[], cssVariables: any) { + cssClasses?.forEach(c => document.documentElement.classList.add(c)); + Object.keys(cssVariables).forEach(key => document.documentElement.style.setProperty(key, cssVariables[key])); + } + + public static goToTop(element: HTMLElement) { + if (!element) return; + + element.scrollTo({ top: 0 }); + } + + public static scrollBy(element: HTMLElement, x: number, y: number) { + if (!element) return; + + element.scrollBy(x, y); + } + } +} \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Services/BitExtraServices.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Services/BitExtraServices.cs new file mode 100644 index 0000000000..e0faef2997 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Services/BitExtraServices.cs @@ -0,0 +1,34 @@ +namespace Bit.BlazorUI; + +public class BitExtraServices(IJSRuntime js) +{ + public async Task AddRootCssClasses() + { + var cssClasses = new List(); + + if (OperatingSystem.IsBrowser()) + { + cssClasses.Add("bit-browser"); + } + else if (OperatingSystem.IsWindows()) + { + cssClasses.Add("bit-windows"); + } + else if (OperatingSystem.IsMacOS() || OperatingSystem.IsMacCatalyst()) + { + cssClasses.Add("bit-macos"); + } + else if (OperatingSystem.IsIOS() && OperatingSystem.IsMacCatalyst() is false) + { + cssClasses.Add("bit-ios"); + } + else if (OperatingSystem.IsAndroid()) + { + cssClasses.Add("bit-android"); + } + + var cssVariables = new Dictionary(); + + await js.BitExtrasApplyRootClasses(cssClasses, cssVariables); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss index 7dcba98b06..026cf642cb 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss @@ -1,5 +1,6 @@ -@import "../Components/DataGrid/BitDataGrid.scss"; +@import "../Components/AppShell/BitAppShell.scss"; +@import "../Components/DataGrid/BitDataGrid.scss"; @import "../Components/DataGrid/Pagination/BitDataGridPaginator.scss"; +@import "../Components/NavPanel/BitNavPanel.scss"; @import "../Components/PdfReader/BitPdfReader.scss"; @import "../Components/ProPanel/BitProPanel.scss"; -@import "../Components/ProLayout/BitProLayout.scss"; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/fabric.mdl2.bit.blazoui.extras.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/fabric.mdl2.bit.blazoui.extras.scss index e372997a9a..736da0b952 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/fabric.mdl2.bit.blazoui.extras.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/fabric.mdl2.bit.blazoui.extras.scss @@ -5,3 +5,15 @@ font-family: 'Fabric MDL2 bit BlazorUI Extras'; src: url('../fonts/FabMDL2.4.66.bit.BlazorUI.Extras.woff2') format("woff2"); } + +.bit-icon-ex { + font-style: normal; + font-weight: normal; + display: inline-block; + font-family: 'Fabric MDL2 bit BlazorUI Extras' !important; +} + +.bit-icon-ex--ChevronLeftEnd6:before { content: "\F371"; } +.bit-icon-ex--ChevronLeftSmall:before { content: "\E96F"; } +.bit-icon-ex--More:before { content: "\E712"; } +.bit-icon-ex--ColumnRightTwoThirds:before { content: "\F1D7"; } \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/fonts/FabMDL2.4.66.bit.BlazorUI.Extras.woff2 b/src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/fonts/FabMDL2.4.66.bit.BlazorUI.Extras.woff2 index ff70846337..d8cd1d72af 100644 Binary files a/src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/fonts/FabMDL2.4.66.bit.BlazorUI.Extras.woff2 and b/src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/fonts/FabMDL2.4.66.bit.BlazorUI.Extras.woff2 differ diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor.cs index cc40b5d490..fafd8262f2 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor.cs @@ -568,7 +568,7 @@ private async Task ToggleCallout() { if (IsEnabled is false) return; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, _Id, null, _calloutId, @@ -607,7 +607,7 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs index 651bbad092..5246874192 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor.cs @@ -944,14 +944,14 @@ private async Task HandleOnTimeHourFocus() { if (IsEnabled is false || ShowTimePicker is false) return; - await _js.SelectText(_inputTimeHourRef); + await _js.BitUtilsSelectText(_inputTimeHourRef); } private async Task HandleOnTimeMinuteFocus() { if (IsEnabled is false || ShowTimePicker is false) return; - await _js.SelectText(_inputTimeMinuteRef); + await _js.BitUtilsSelectText(_inputTimeMinuteRef); } private void ToggleAmPmTime() diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Checkbox/BitCheckbox.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Checkbox/BitCheckbox.razor.cs index ffd4a57f37..e9e5e00612 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Checkbox/BitCheckbox.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Checkbox/BitCheckbox.razor.cs @@ -170,7 +170,7 @@ protected override void Dispose(bool disposing) private async Task SetIndeterminate() { - await _js.SetProperty(InputElement, "indeterminate", Indeterminate); + await _js.BitUtilsSetProperty(InputElement, "indeterminate", Indeterminate); } private async Task HandleOnCheckboxClick(MouseEventArgs args) @@ -199,6 +199,6 @@ private async Task SetIndeterminate(bool value) { if (await AssignIndeterminate(value) is false) return; - await _js.SetProperty(InputElement, "indeterminate", value); + await _js.BitUtilsSetProperty(InputElement, "indeterminate", value); } } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs index f44e53b922..44691b0e09 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/ChoiceGroup/BitChoiceGroup.razor.cs @@ -215,7 +215,7 @@ private string GetItemContainerCssStyles(TItem item) { StringBuilder cssStyle = new(); - if (string.IsNullOrEmpty(GetStyle(item)) is false) + if (GetStyle(item).HasValue()) { cssStyle.Append(GetStyle(item)); } @@ -237,7 +237,7 @@ private string GetItemContainerCssClasses(TItem item) { StringBuilder cssClass = new("bit-chg-icn"); - if (string.IsNullOrEmpty(GetClass(item)) is false) + if (GetClass(item).HasValue()) { cssClass.Append(' ').Append(GetClass(item)); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Dropdown/BitDropdown.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Dropdown/BitDropdown.razor.cs index addc3d92be..e18a8ad2b3 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Dropdown/BitDropdown.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Dropdown/BitDropdown.razor.cs @@ -852,7 +852,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender is false) return; if (Responsive is false) return; - await _js.SwipesSetup(_calloutId, 0.25m, BitPanelPosition.End, Dir is BitDir.Rtl, _dotnetObj); + await _js.BitSwipesSetup(_calloutId, 0.25m, BitPanelPosition.End, Dir is BitDir.Rtl, _dotnetObj); } protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? parsingErrorMessage) @@ -1162,7 +1162,7 @@ private async Task ToggleCallout() { if (IsEnabled is false) return; - _isResponsiveMode = await _js.ToggleCallout(_dotnetObj, + _isResponsiveMode = await _js.BitCalloutToggleCallout(_dotnetObj, _dropdownId, null, _calloutId, @@ -1252,7 +1252,7 @@ private async Task HandleOnKeyDown(KeyboardEventArgs eventArgs) } else if (eventArgs.Key == "Enter") { - _searchText = await _js.GetProperty(_isResponsiveMode ? _comboBoxInputResponsiveRef : _comboBoxInputRef, "value"); + _searchText = await _js.BitUtilsGetProperty(_isResponsiveMode ? _comboBoxInputResponsiveRef : _comboBoxInputRef, "value"); await AddDynamicItem(); @@ -1473,8 +1473,8 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); - await _js.SwipesDispose(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); + await _js.BitSwipesDispose(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor.cs index f5c0574521..7eaaa3ed12 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/NumberField/BitNumberField.razor.cs @@ -353,7 +353,7 @@ private async Task HandleOnFocusIn(FocusEventArgs e) _hasFocus = true; ClassBuilder.Reset(); StyleBuilder.Reset(); - await _js.SelectText(InputElement); + await _js.BitUtilsSelectText(InputElement); await OnFocusIn.InvokeAsync(e); } @@ -374,7 +374,7 @@ private async Task HandleOnFocus(FocusEventArgs e) _hasFocus = true; ClassBuilder.Reset(); StyleBuilder.Reset(); - await _js.SelectText(InputElement); + await _js.BitUtilsSelectText(InputElement); await OnFocus.InvokeAsync(e); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SearchBox/BitSearchBox.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SearchBox/BitSearchBox.razor.cs index 0e4079ff72..55adccf395 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SearchBox/BitSearchBox.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SearchBox/BitSearchBox.razor.cs @@ -141,8 +141,19 @@ public partial class BitSearchBox : BitTextInputBase, IAsyncDisposable + /// + /// Clears the input element. + /// + public async Task Clear() + { + await SetCurrentValueAsync(null); + await _js.BitUtilsSetProperty(InputElement, "value", null); + } + + + [JSInvokable("CloseCallout")] - public void CloseCalloutBeforeAnotherCalloutIsOpened() + public void _CloseCalloutBeforeAnotherCalloutIsOpened() { if (IsEnabled is false) return; @@ -264,7 +275,7 @@ private async Task HandleOnKeyDown(KeyboardEventArgs eventArgs) } else if (eventArgs.Key == "Enter") { - CurrentValue = await _js.GetProperty(InputElement, "value"); + CurrentValue = await _js.BitUtilsGetProperty(InputElement, "value"); await CloseCallout(); await OnSearch.InvokeAsync(CurrentValue); } @@ -282,7 +293,7 @@ private async Task ToggleCallout() { if (IsEnabled is false) return; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, _Id, null, _calloutId, @@ -435,7 +446,7 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Slider/BitSlider.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Slider/BitSlider.razor.cs index 5a82e5b15e..05e80f4ff0 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Slider/BitSlider.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Slider/BitSlider.razor.cs @@ -343,7 +343,7 @@ private void OnSetValues() private async ValueTask GetClientHeight(ElementReference element) { - var height = await _js.GetProperty(element, "clientHeight"); + var height = await _js.BitUtilsGetProperty(element, "clientHeight"); return height.HasNoValue() ? 0 : int.Parse(height); diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SpinButton/BitSpinButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SpinButton/BitSpinButton.razor.cs index 3835a3b806..8483f7a7b0 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SpinButton/BitSpinButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/SpinButton/BitSpinButton.razor.cs @@ -440,7 +440,7 @@ private async Task HandleOnFocus(FocusEventArgs e) await OnFocus.InvokeAsync(e); - await _js.SelectText(InputElement); + await _js.BitUtilsSelectText(InputElement); } private void SetValue(double value) diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/CircularTimePicker/BitCircularTimePicker.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/CircularTimePicker/BitCircularTimePicker.razor.cs index 31936c2e66..dbe2bb9769 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/CircularTimePicker/BitCircularTimePicker.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/CircularTimePicker/BitCircularTimePicker.razor.cs @@ -307,7 +307,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender is false) return; - await _js.SwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); + await _js.BitSwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); _pointerUpAbortControllerId = await _js.BitCircularTimePickerRegisterPointerUp(_dotnetObj, nameof(_HandlePointerUp)); _pointerMoveAbortControllerId = await _js.BitCircularTimePickerRegisterPointerMove(_dotnetObj, nameof(_HandlePointerMove)); } @@ -523,7 +523,7 @@ private async Task ToggleCallout() if (Standalone) return; if (IsEnabled is false) return; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, _circularTimePickerId, null, _calloutId, @@ -543,7 +543,7 @@ private async Task UpdateTime(MouseEventArgs e) { if (IsEnabled is false || InvalidValueBinding()) return; - var rect = await _js.GetBoundingClientRect(_clockRef); + var rect = await _js.BitUtilsGetBoundingClientRect(_clockRef); var radius = rect.Width / 2; var centerX = radius; var centerY = radius; @@ -707,8 +707,8 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); - await _js.SwipesDispose(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); + await _js.BitSwipesDispose(_calloutId); await _js.BitCircularTimePickerAbort(_pointerUpAbortControllerId); await _js.BitCircularTimePickerAbort(_pointerMoveAbortControllerId); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/ColorPicker/BitColorPicker.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/ColorPicker/BitColorPicker.razor.cs index 593b27ce34..5ff76edc51 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/ColorPicker/BitColorPicker.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/ColorPicker/BitColorPicker.razor.cs @@ -132,7 +132,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) private async Task SetSaturationPickerThumbPositionAsync() { var (_, saturation, value) = _color.Hsv; - var saturationPickerRect = await _js.GetBoundingClientRect(_saturationPickerRef); + var saturationPickerRect = await _js.BitUtilsGetBoundingClientRect(_saturationPickerRef); var width = saturationPickerRect?.Width ?? 0; var height = saturationPickerRect?.Height ?? 0; @@ -152,7 +152,7 @@ private async Task UpdateColor(MouseEventArgs e) { if (ColorHasBeenSet && ColorChanged.HasDelegate is false) return; - var pickerRect = await _js.GetBoundingClientRect(_saturationPickerRef); + var pickerRect = await _js.BitUtilsGetBoundingClientRect(_saturationPickerRef); var left = e.ClientX < pickerRect.Left ? 0 : e.ClientX > pickerRect.Left + pickerRect.Width ? pickerRect.Width diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DatePicker/BitDatePicker.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DatePicker/BitDatePicker.razor.cs index 35b8b01462..1a1fc3bb62 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DatePicker/BitDatePicker.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DatePicker/BitDatePicker.razor.cs @@ -530,7 +530,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender is false) return; if (Responsive is false) return; - await _js.SwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); + await _js.BitSwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); } protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out DateTimeOffset? result, [NotNullWhen(false)] out string? validationErrorMessage) @@ -572,7 +572,7 @@ private async Task HandleOnClick() ResetPickersState(); - var bodyWidth = await _js.GetBodyWidth(); + var bodyWidth = await _js.BitUtilsGetBodyWidth(); var notEnoughWidthAvailable = bodyWidth < MAX_WIDTH; if (_showMonthPickerAsOverlayInternal is false) @@ -1279,14 +1279,14 @@ private async Task HandleOnTimeHourFocus() { if (IsEnabled is false || ShowTimePicker is false) return; - await _js.SelectText(_inputTimeHourRef); + await _js.BitUtilsSelectText(_inputTimeHourRef); } private async Task HandleOnTimeMinuteFocus() { if (IsEnabled is false || ShowTimePicker is false) return; - await _js.SelectText(_inputTimeMinuteRef); + await _js.BitUtilsSelectText(_inputTimeMinuteRef); } private void ToggleAmPmTime() @@ -1483,7 +1483,7 @@ private async Task ToggleCallout() if (Standalone) return false; if (IsEnabled is false) return false; - return await _js.ToggleCallout(_dotnetObj, + return await _js.BitCalloutToggleCallout(_dotnetObj, _datePickerId, null, _calloutId, @@ -1534,8 +1534,8 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); - await _js.SwipesDispose(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); + await _js.BitSwipesDispose(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DateRangePicker/BitDateRangePicker.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DateRangePicker/BitDateRangePicker.razor.cs index a64044a39c..09b6d848bc 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DateRangePicker/BitDateRangePicker.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/DateRangePicker/BitDateRangePicker.razor.cs @@ -593,7 +593,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender is false) return; if (Responsive is false) return; - await _js.SwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); + await _js.BitSwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); } protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out BitDateRangePickerValue? result, [NotNullWhen(false)] out string? validationErrorMessage) @@ -642,7 +642,7 @@ private async Task HandleOnClick() ResetPickersState(); - var bodyWidth = await _js.GetBodyWidth(); + var bodyWidth = await _js.BitUtilsGetBodyWidth(); var notEnoughWidthAvailable = bodyWidth < MAX_WIDTH; if (_showMonthPickerAsOverlayInternal is false) @@ -1629,14 +1629,14 @@ private async Task HandleOnHourInputFocus(bool isStartTime) { if (IsEnabled is false || ShowTimePicker is false) return; - await _js.SelectText(isStartTime ? _startTimeHourInputRef : _endTimeHourInputRef); + await _js.BitUtilsSelectText(isStartTime ? _startTimeHourInputRef : _endTimeHourInputRef); } private async Task HandleOnMinuteInputFocus(bool isStartTime) { if (IsEnabled is false || ShowTimePicker is false) return; - await _js.SelectText(isStartTime ? _startTimeMinuteInputRef : _endTimeMinuteInputRef); + await _js.BitUtilsSelectText(isStartTime ? _startTimeMinuteInputRef : _endTimeMinuteInputRef); } private void HandleOnAmClick(bool isStartTime) @@ -2025,7 +2025,7 @@ private async Task ToggleCallout() if (Standalone) return false; if (IsEnabled is false) return false; - return await _js.ToggleCallout(_dotnetObj, + return await _js.BitCalloutToggleCallout(_dotnetObj, _dateRangePickerId, null, _calloutId, @@ -2076,8 +2076,8 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); - await _js.SwipesDispose(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); + await _js.BitSwipesDispose(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/TimePicker/BitTimePicker.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/TimePicker/BitTimePicker.razor.cs index d554b0d9ee..bea8abb564 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/TimePicker/BitTimePicker.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/_Pickers/TimePicker/BitTimePicker.razor.cs @@ -345,7 +345,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender is false) return; if (Responsive is false) return; - await _js.SwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); + await _js.BitSwipesSetup(_calloutId, 0.25m, BitPanelPosition.Top, Dir is BitDir.Rtl, _dotnetObj); } protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TimeSpan? result, [NotNullWhen(false)] out string? validationErrorMessage) @@ -425,7 +425,7 @@ private async Task ToggleCallout() if (Standalone) return; if (IsEnabled is false) return; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, _timePickerId, null, _calloutId, @@ -512,14 +512,14 @@ private async Task HandleOnHourFocus() { if (IsEnabled is false) return; - await _js.SelectText(_inputHourRef); + await _js.BitUtilsSelectText(_inputHourRef); } private async Task HandleOnMinuteFocus() { if (IsEnabled is false) return; - await _js.SelectText(_inputMinuteRef); + await _js.BitUtilsSelectText(_inputMinuteRef); } private async Task ChangeHour(bool isNext) @@ -673,8 +673,8 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); - await _js.SwipesDispose(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); + await _js.BitSwipesDispose(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor index 508c8bccab..de2e15056e 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor @@ -1,55 +1,41 @@ @namespace Bit.BlazorUI @inherits BitComponentBase -
- - @{ - var headerHeight = HeaderHeight + StatusBarHeight; - var headerHeightStyle = $"{(headerHeight > 0 ? $"height:{headerHeight}px;" : "")}"; - var headerPaddingStyle = $"{(StatusBarHeight > 0 ? $"padding-top:{StatusBarHeight}px;" : "")}"; - var headerStyles = $"{headerHeightStyle}{headerPaddingStyle}{Styles?.Header}"; - var headerClasses = $"bit-lyt-hdr{(FixedHeader ? " bit-lyt-fhd" : "")} {Classes?.Header}"; - - var mainPaddingTopStyle = $"{(FixedHeader && headerHeight > 0 ? $"padding-top:{headerHeight}px;" : "")}"; - var mainPaddingBottomStyle = $"{(FixedFooter && FooterHeight > 0 ? $"padding-bottom:{FooterHeight}px;" : "")}"; - var mainStyles = $"{mainPaddingTopStyle}{mainPaddingBottomStyle}{Styles?.Main}"; - var mainClasses = $"bit-lyt-man {Classes?.Main}"; - - var footerHeightStyle = $"{(FooterHeight > 0 ? $"height:{FooterHeight}px;" : "")}"; - var footerStyles = $"{footerHeightStyle}{Styles?.Footer}"; - var footerClasses = $"bit-lyt-ftr{(FixedFooter ? " bit-lyt-fft" : "")} {Classes?.Footer}"; - } @if (Header is not null) { -
+
@Header
} -
- @if (NavMenu is not null && HideNavMenu is false) +
+ @if (showNavPanel) { -
- @NavMenu +
+ @NavPanel
} -
+
@Main
@if (Footer is not null) { -
+
@Footer -
+
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor.cs index e04cf8405a..d732083604 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.razor.cs @@ -7,55 +7,47 @@ public partial class BitLayout : BitComponentBase /// [Parameter] public BitLayoutClassStyles? Classes { get; set; } - /// - /// Enables fixed positioning of the header at the top of the viewport. - /// - [Parameter] public bool FixedHeader { get; set; } - - /// - /// Enables fixed positioning of the footer at the bottom of the viewport. - /// - [Parameter] public bool FixedFooter { get; set; } - /// /// The content of the footer section. /// [Parameter] public RenderFragment? Footer { get; set; } /// - /// The height of the footer in px to calculate heights and paddings. + /// The content of the header section. /// - [Parameter] public int FooterHeight { get; set; } + [Parameter] public RenderFragment? Header { get; set; } /// - /// The content of the header section. + /// Hides NavPanel content. /// - [Parameter] public RenderFragment? Header { get; set; } + [Parameter] public bool HideNavPanel { get; set; } /// - /// The height of the header in px to calculate heights and paddings. + /// The content of the main section. /// - [Parameter] public int HeaderHeight { get; set; } + [Parameter] public RenderFragment? Main { get; set; } /// - /// Hides NavMenu content when true. + /// The content of the nav panel section. /// - [Parameter] public bool HideNavMenu { get; set; } + [Parameter] public RenderFragment? NavPanel { get; set; } /// - /// The content of the main section. + /// The width of the nav panel section in px. /// - [Parameter] public RenderFragment? Main { get; set; } + [Parameter] public int NavPanelWidth { get; set; } /// - /// The content of the nav-menu section. + /// Enables sticky positioning of the footer at the bottom of the viewport. /// - [Parameter] public RenderFragment? NavMenu { get; set; } + [Parameter, ResetClassBuilder] + public bool StickyFooter { get; set; } /// - /// The height of the status bar on mobile devices to calculate heights and paddings. + /// Enables sticky positioning of the header at the top of the viewport. /// - [Parameter] public int StatusBarHeight { get; set; } + [Parameter, ResetClassBuilder] + public bool StickyHeader { get; set; } /// /// Custom CSS styles for different parts of the BitLayout. @@ -69,6 +61,9 @@ public partial class BitLayout : BitComponentBase protected override void RegisterCssClasses() { ClassBuilder.Register(() => Classes?.Root); + + ClassBuilder.Register(() => StickyHeader ? "bit-lyt-shd" : string.Empty); + ClassBuilder.Register(() => StickyFooter ? "bit-lyt-sft" : string.Empty); } protected override void RegisterCssStyles() diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.scss b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.scss index fba6a3e5e0..e9df24de51 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.scss +++ b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayout.scss @@ -15,20 +15,35 @@ } } +.bit-lyt-shd { + height: fit-content; + + > .bit-lyt-hdr { + top: 0; + position: sticky; + z-index: $zindex-base; + } +} + +.bit-lyt-sft { + height: fit-content; + + > .bit-lyt-ftr { + bottom: 0; + position: sticky; + z-index: $zindex-base; + } +} + .bit-lyt-hdr { width: 100%; box-sizing: border-box; } -.bit-lyt-fhd { - top: 0; - position: fixed; - z-index: $zindex-base; -} - .bit-lyt-man { flex-grow: 1; display: flex; + min-height: 100vh; box-sizing: border-box; } @@ -45,9 +60,3 @@ width: 100%; box-sizing: border-box; } - -.bit-lyt-fft { - bottom: 0; - position: fixed; - z-index: $zindex-base; -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayoutClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayoutClassStyles.cs index c484c6bbf0..56b62f46f0 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayoutClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Layouts/Layout/BitLayoutClassStyles.cs @@ -20,7 +20,7 @@ public class BitLayoutClassStyles /// /// Custom CSS classes/styles for the nav-menu section of the BitLayout. /// - public string? NavMenu { get; set; } + public string? NavPanel { get; set; } /// /// Custom CSS classes/styles for the main-content section of the BitLayout. diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Lists/Carousel/BitCarousel.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Lists/Carousel/BitCarousel.razor.cs index 58f76434b6..cb08373268 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Lists/Carousel/BitCarousel.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Lists/Carousel/BitCarousel.razor.cs @@ -176,7 +176,7 @@ private async Task ResetDimensionsAsync() _othersIndices = Enumerable.Range(0, _internalScrollItemsCount).ToArray(); var itemsCount = _allItems.Count; - var rect = await _js.GetBoundingClientRect(_carousel); + var rect = await _js.BitUtilsGetBoundingClientRect(_carousel); if (rect is null) return; var sign = Dir == BitDir.Rtl ? -1 : 1; for (int i = 0; i < itemsCount; i++) @@ -332,7 +332,7 @@ private async Task HandlePointerMove(MouseEventArgs e) if (Math.Abs(delta) <= 20) return; _isPointerDown = false; - await _js.SetStyle(_carousel, "cursor", ""); + await _js.BitUtilsSetStyle(_carousel, "cursor", ""); if (delta < 0) { @@ -348,14 +348,14 @@ private async Task HandlePointerDown(MouseEventArgs e) { _isPointerDown = true; _pointerX = e.ClientX; - await _js.SetStyle(_carousel, "cursor", "grabbing"); + await _js.BitUtilsSetStyle(_carousel, "cursor", "grabbing"); StateHasChanged(); } private async Task HandlePointerUp(MouseEventArgs e) { _isPointerDown = false; - await _js.SetStyle(_carousel, "cursor", ""); + await _js.BitUtilsSetStyle(_carousel, "cursor", ""); StateHasChanged(); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Lists/Swiper/BitSwiper.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Lists/Swiper/BitSwiper.razor.cs index 45fbf37d51..4afd8825bc 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Lists/Swiper/BitSwiper.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Lists/Swiper/BitSwiper.razor.cs @@ -104,7 +104,7 @@ public async Task HandlePointerLeave(double clientX) if (_isPointerDown is false) return; _isPointerDown = false; - await _js.SetStyle(_swiper, "cursor", ""); + await _js.BitUtilsSetStyle(_swiper, "cursor", ""); var time = (DateTime.Now.Ticks - _pointerDownTime) / 10_000; var distance = Math.Abs(clientX - _pointerDownX); @@ -114,7 +114,7 @@ public async Task HandlePointerLeave(double clientX) var swipeSpeed = distance / time; var transitionTime = swipeSpeed > 2 ? 300 : swipeSpeed > 1 ? 600 : 1000; - await _js.SetStyle(_swiper, "transitionDuration", FormattableString.Invariant($"{transitionTime}ms")); + await _js.BitUtilsSetStyle(_swiper, "transitionDuration", FormattableString.Invariant($"{transitionTime}ms")); var x = -(_lastDiffX / Math.Abs(_lastDiffX)) * (_swiperEffectiveWidth * swipeSpeed / 10) + _translateX; await Swipe(x); @@ -192,7 +192,7 @@ private void SetNavigationButtonsVisibility(double translateX) private async Task Go(bool isNext) { await GetDimensions(); - await _js.SetStyle(_swiper, "transitionDuration", ""); + await _js.BitUtilsSetStyle(_swiper, "transitionDuration", ""); var sign = isNext ? -1 : 1; var scrollX = _swiperWidth / _allItems.Count * _internalScrollItemsCount; @@ -235,8 +235,8 @@ private async Task HandlePointerDown(MouseEventArgs e) await GetDimensions(); - await _js.SetStyle(_swiper, "cursor", "grabbing"); - await _js.SetStyle(_swiper, "transitionDuration", ""); + await _js.BitUtilsSetStyle(_swiper, "cursor", "grabbing"); + await _js.BitUtilsSetStyle(_swiper, "transitionDuration", ""); } private async Task HandlePointerUp(MouseEventArgs e) => await HandlePointerLeave(e.ClientX); @@ -256,7 +256,7 @@ private async Task Swipe(double x) if (x < -_swiperEffectiveWidth) x = -_swiperEffectiveWidth; } - await _js.SetStyle(_swiper, "transform", FormattableString.Invariant($"translateX({x}px)")); + await _js.BitUtilsSetStyle(_swiper, "transform", FormattableString.Invariant($"translateX({x}px)")); SetNavigationButtonsVisibility(x); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Navs/Breadcrumb/BitBreadcrumb.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Navs/Breadcrumb/BitBreadcrumb.razor.cs index 21f874b915..d5011048b5 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Navs/Breadcrumb/BitBreadcrumb.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Navs/Breadcrumb/BitBreadcrumb.razor.cs @@ -597,7 +597,7 @@ private async Task ToggleCallout() { if (IsEnabled is false) return; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, _overflowAnchorId, null, _calloutId, @@ -636,7 +636,7 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Navs/DropMenu/BitDropMenu.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Navs/DropMenu/BitDropMenu.razor.cs index 48f83584e7..b998c9359d 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Navs/DropMenu/BitDropMenu.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Navs/DropMenu/BitDropMenu.razor.cs @@ -150,7 +150,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender is false) return; if (Responsive is false) return; - await _js.SwipesSetup(_calloutId, 0.25m, BitPanelPosition.End, Dir is BitDir.Rtl, _dotnetObj); + await _js.BitSwipesSetup(_calloutId, 0.25m, BitPanelPosition.End, Dir is BitDir.Rtl, _dotnetObj); } @@ -182,7 +182,7 @@ private async Task ToggleCallout() { if (IsEnabled is false) return; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, _Id, null, _calloutId, @@ -236,8 +236,8 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_calloutId); - await _js.SwipesDispose(_calloutId); + await _js.BitCalloutClearCallout(_calloutId); + await _js.BitSwipesDispose(_calloutId); } catch (JSDisconnectedException) { } // we can ignore this exception here diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Navs/Nav/BitNav.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Navs/Nav/BitNav.razor.cs index 70ca783961..7cc1a9bfa6 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Navs/Nav/BitNav.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Navs/Nav/BitNav.razor.cs @@ -94,7 +94,7 @@ public partial class BitNav : BitComponentBase, IDisposable where TItem : [Parameter] public int IndentReversedPadding { get; set; } = 4; /// - /// A collection of item to display in the navigation bar. + /// A collection of items to display in the BitNav component. /// [Parameter] [CallOnSet(nameof(OnSetParameters))] @@ -336,6 +336,28 @@ internal List GetChildItems(TItem item) return item.GetValueFromProperty(NameSelectors.CollapseAriaLabel.Name); } + internal object? GetData(TItem item) + { + if (item is BitNavItem navItem) + { + return navItem.Data; + } + + if (item is BitNavOption navOption) + { + return navOption.Data; + } + + if (NameSelectors is null) return null; + + if (NameSelectors.Data.Selector is not null) + { + return NameSelectors.Data.Selector!(item); + } + + return item.GetValueFromProperty(NameSelectors.Data.Name); + } + internal string? GetDescription(TItem item) { if (item is BitNavItem navItem) diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Callout/BitCallout.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Callout/BitCallout.razor.cs index 3322053a1d..5ebd497af5 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Callout/BitCallout.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Callout/BitCallout.razor.cs @@ -145,7 +145,7 @@ private async Task ToggleCallout() var id = Anchor is not null ? _anchorId : AnchorId ?? _Id; - await _js.ToggleCallout(_dotnetObj, + await _js.BitCalloutToggleCallout(_dotnetObj, id, AnchorEl is null ? null : AnchorEl(), _contentId, @@ -181,7 +181,7 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.ClearCallout(_contentId); + await _js.BitCalloutClearCallout(_contentId); } catch (JSDisconnectedException) { } // we can ignore this exception here } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Dialog/BitDialog.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Dialog/BitDialog.razor.cs index 5ae699aba7..0db768becd 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Dialog/BitDialog.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Dialog/BitDialog.razor.cs @@ -164,7 +164,7 @@ public partial class BitDialog : BitComponentBase, IAsyncDisposable { await InvokeAsync(async () => { - _ = _js.ToggleOverflow(ScrollerSelector, true); + _ = _js.BitUtilsToggleOverflow(ScrollerSelector, true); Result = null; @@ -233,7 +233,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (AutoToggleScroll is false) return; - _offsetTop = await _js.ToggleOverflow(ScrollerSelector, IsOpen); + _offsetTop = await _js.BitUtilsToggleOverflow(ScrollerSelector, IsOpen); if (AbsolutePosition is false) return; diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Modal/BitModal.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Modal/BitModal.razor.cs index c19d8f49bb..5726c19c14 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Modal/BitModal.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Modal/BitModal.razor.cs @@ -232,7 +232,7 @@ private async Task ToggleScroll(bool isOpen) { if (ModalParameters.AutoToggleScroll is false) return; - _offsetTop = await _js.ToggleOverflow(ModalParameters.ScrollerSelector ?? "body", isOpen); + _offsetTop = await _js.BitUtilsToggleOverflow(ModalParameters.ScrollerSelector ?? "body", isOpen); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Panel/BitPanel.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Panel/BitPanel.razor.cs index 6f6863e164..20607a18ae 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Panel/BitPanel.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Surfaces/Panel/BitPanel.razor.cs @@ -165,7 +165,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender) { var dotnetObj = DotNetObjectReference.Create(this); - await _js.SwipesSetup(_containerId, SwipeTrigger ?? 0.25m, Position ?? BitPanelPosition.End, Dir == BitDir.Rtl, dotnetObj, false); + await _js.BitSwipesSetup(_containerId, SwipeTrigger ?? 0.25m, Position ?? BitPanelPosition.End, Dir == BitDir.Rtl, dotnetObj, false); } if (_internalIsOpen == IsOpen) return; @@ -176,7 +176,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (AutoToggleScroll is false) return; - _offsetTop = await _js.ToggleOverflow(ScrollerSelector ?? "body", IsOpen); + _offsetTop = await _js.BitUtilsToggleOverflow(ScrollerSelector ?? "body", IsOpen); StyleBuilder.Reset(); StateHasChanged(); @@ -258,7 +258,7 @@ protected virtual async ValueTask DisposeAsync(bool disposing) try { - await _js.SwipesDispose(_containerId); + await _js.BitSwipesDispose(_containerId); } catch (JSDisconnectedException) { } // we can ignore this exception here diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Link/BitLink.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Link/BitLink.razor.cs index 3ffb63375f..4c5c02d762 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Link/BitLink.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Link/BitLink.razor.cs @@ -73,7 +73,7 @@ private async Task ScrollIntoView() { if (IsEnabled is false) return; - await _js.ScrollElementIntoView(Href![1..]); + await _js.BitUtilsScrollElementIntoView(Href![1..]); } private void OnSetHrefAndRel() diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs index 4e9212f319..0d5ab57b97 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/SwipeTrap/BitSwipeTrap.razor.cs @@ -93,7 +93,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender) { var dotnetObj = DotNetObjectReference.Create(this); - await _js.BitSwipeTrapSetup(UniqueId, RootElement, Trigger ?? 0.25m, Threshold ?? 0, Throttle ?? 10, dotnetObj); + await _js.BitSwipeTrapSetup(UniqueId, RootElement, Trigger ?? 0.25m, Threshold ?? 0, Throttle ?? 0, dotnetObj); } await base.OnAfterRenderAsync(firstRender); diff --git a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/CalloutsJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/CalloutsJsRuntimeExtensions.cs index 3ed0cf856a..3960864f3f 100644 --- a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/CalloutsJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/CalloutsJsRuntimeExtensions.cs @@ -4,7 +4,7 @@ namespace Bit.BlazorUI; internal static class CalloutsJsRuntimeExtensions { - internal static ValueTask ToggleCallout<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( + internal static ValueTask BitCalloutToggleCallout<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>( this IJSRuntime jsRuntime, DotNetObjectReference dotnetObj, string componentId, @@ -40,7 +40,7 @@ internal static class CalloutsJsRuntimeExtensions maxWidth); } - internal static ValueTask ClearCallout(this IJSRuntime jsRuntime, string calloutId) + internal static ValueTask BitCalloutClearCallout(this IJSRuntime jsRuntime, string calloutId) { return jsRuntime.InvokeVoid("BitBlazorUI.Callouts.clear", calloutId); } diff --git a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/SwipesJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/SwipesJsRuntimeExtensions.cs index d0dce6f787..9f5e1ec16d 100644 --- a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/SwipesJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/SwipesJsRuntimeExtensions.cs @@ -4,7 +4,7 @@ namespace Bit.BlazorUI; internal static class SwipesJsRuntimeExtensions { - internal static ValueTask SwipesSetup<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IJSRuntime js, + internal static ValueTask BitSwipesSetup<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>(this IJSRuntime js, string id, decimal trigger, BitPanelPosition position, @@ -15,7 +15,7 @@ internal static class SwipesJsRuntimeExtensions return js.InvokeVoid("BitBlazorUI.Swipes.setup", id, trigger, position, isRtl, dotnetObj, isResponsive); } - internal static ValueTask SwipesDispose(this IJSRuntime jsRuntime, string id) + internal static ValueTask BitSwipesDispose(this IJSRuntime jsRuntime, string id) { return jsRuntime.InvokeVoid("BitBlazorUI.Swipes.dispose", id); } diff --git a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/UtilsJsRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/UtilsJsRuntimeExtensions.cs index 8a430ff51d..30479a1428 100644 --- a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/UtilsJsRuntimeExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/UtilsJsRuntimeExtensions.cs @@ -2,49 +2,49 @@ internal static class UtilsJsRuntimeExtensions { - internal static ValueTask GetBodyWidth(this IJSRuntime jsRuntime) + internal static ValueTask BitUtilsGetBodyWidth(this IJSRuntime jsRuntime) { return jsRuntime.Invoke("BitBlazorUI.Utils.getBodyWidth"); } - internal static ValueTask SetProperty(this IJSRuntime jsRuntime, ElementReference element, string property, object value) + internal static ValueTask BitUtilsSetProperty(this IJSRuntime jsRuntime, ElementReference element, string property, object? value) { return jsRuntime.InvokeVoid("BitBlazorUI.Utils.setProperty", element, property, value); } - internal static ValueTask GetProperty(this IJSRuntime jsRuntime, ElementReference element, string property) + internal static ValueTask BitUtilsGetProperty(this IJSRuntime jsRuntime, ElementReference element, string property) { return jsRuntime.Invoke("BitBlazorUI.Utils.getProperty", element, property); } - internal static ValueTask GetBoundingClientRect(this IJSRuntime jsRuntime, ElementReference element) + internal static ValueTask BitUtilsGetBoundingClientRect(this IJSRuntime jsRuntime, ElementReference element) { return jsRuntime.Invoke("BitBlazorUI.Utils.getBoundingClientRect", element); } - internal static ValueTask ScrollElementIntoView(this IJSRuntime jsRuntime, string targetElementId) + internal static ValueTask BitUtilsScrollElementIntoView(this IJSRuntime jsRuntime, string targetElementId) { return jsRuntime.InvokeVoid("BitBlazorUI.Utils.scrollElementIntoView", targetElementId); } - internal static ValueTask SelectText(this IJSRuntime jsRuntime, ElementReference element) + internal static ValueTask BitUtilsSelectText(this IJSRuntime jsRuntime, ElementReference element) { return jsRuntime.InvokeVoid("BitBlazorUI.Utils.selectText", element); } - internal static ValueTask SetStyle(this IJSRuntime jsRuntime, ElementReference element, string key, string value) + internal static ValueTask BitUtilsSetStyle(this IJSRuntime jsRuntime, ElementReference element, string key, string value) { return jsRuntime.InvokeVoid("BitBlazorUI.Utils.setStyle", element, key, value); } - internal static ValueTask ToggleOverflow(this IJSRuntime jsRuntime, string scrollerSelector, bool isHidden) + internal static ValueTask BitUtilsToggleOverflow(this IJSRuntime jsRuntime, string scrollerSelector, bool isHidden) { return jsRuntime.Invoke("BitBlazorUI.Utils.toggleOverflow", scrollerSelector, isHidden); } diff --git a/src/BlazorUI/Bit.BlazorUI/Extensions/StringExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Extensions/StringExtensions.cs index 4fb33a2584..8dcc5ff61c 100644 --- a/src/BlazorUI/Bit.BlazorUI/Extensions/StringExtensions.cs +++ b/src/BlazorUI/Bit.BlazorUI/Extensions/StringExtensions.cs @@ -1,4 +1,5 @@ -namespace Bit.BlazorUI; +#nullable enable +namespace Bit.BlazorUI; internal static class StringExtensions { diff --git a/src/BlazorUI/Bit.BlazorUI/Styles/media-queries.scss b/src/BlazorUI/Bit.BlazorUI/Styles/media-queries.scss index b6f178a6c5..c1628fe3f8 100644 --- a/src/BlazorUI/Bit.BlazorUI/Styles/media-queries.scss +++ b/src/BlazorUI/Bit.BlazorUI/Styles/media-queries.scss @@ -1,3 +1,5 @@ +// https://github.com/Necromancerx/media-queries-scss-mixins + $brk-xs-max: 600px; $brk-sm-min: 601px; $brk-sm-max: 960px; diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor index 97d974449b..a67e1c5f7b 100644 --- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor +++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor @@ -13,8 +13,15 @@ - + + + + @@ -47,9 +54,9 @@ Microsoft Clarity --> + - diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IJSRuntimeExtensions.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IJSRuntimeExtensions.cs index 5037428723..288c56a267 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IJSRuntimeExtensions.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IJSRuntimeExtensions.cs @@ -2,11 +2,6 @@ public static class IJSRuntimeExtensions { - public static async Task ToggleBodyOverflow(this IJSRuntime jsRuntime, bool isNavOpen) - { - await jsRuntime.InvokeVoidAsync("toggleBodyOverflow", isNavOpen); - } - public static async Task ScrollToElement(this IJSRuntime jsRuntime, string targetElementId) { await jsRuntime.InvokeVoidAsync("scrollToElement", targetElementId); diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IServiceCollectionExtensions.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IServiceCollectionExtensions.cs index e0e28c4ada..f10c87d4b4 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IServiceCollectionExtensions.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Extensions/IServiceCollectionExtensions.cs @@ -21,7 +21,6 @@ public static IServiceCollection AddClientSharedServices(this IServiceCollection services.TryAddTransient(); services.TryAddTransient(); - services.TryAddScoped(); services.AddBitBlazorUIServices(); services.AddBitBlazorUIExtrasServices(trySingleton: AppRenderMode.IsBlazorHybrid); diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor index 8f134e5109..f7fbfdf567 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor @@ -239,27 +239,4 @@
- - -@code { - private bool formIsValidSubmit; - private ButtonValidationModel buttonValidationModel = new(); - - private async Task HandleValidSubmit() - { - formIsValidSubmit = true; - - await Task.Delay(2000); - - buttonValidationModel = new(); - - formIsValidSubmit = false; - - StateHasChanged(); - } - - private void HandleInvalidSubmit() - { - formIsValidSubmit = false; - } -} \ No newline at end of file + \ No newline at end of file diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor.cs index 9c4b43558f..302cb210aa 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/BitActionButtonDemo.razor.cs @@ -431,4 +431,27 @@ public partial class BitActionButtonDemo ] }, ]; + + + + private bool formIsValidSubmit; + private ButtonValidationModel buttonValidationModel = new(); + + private async Task HandleValidSubmit() + { + formIsValidSubmit = true; + + await Task.Delay(2000); + + buttonValidationModel = new(); + + formIsValidSubmit = false; + + StateHasChanged(); + } + + private void HandleInvalidSubmit() + { + formIsValidSubmit = false; + } } diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor similarity index 60% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor index c8f12f1d69..13f7921925 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor @@ -1,13 +1,13 @@ -@page "/components/prolayout" +@page "/components/appshell" @inherits AppComponentBase - + - @@ -16,8 +16,9 @@
Since this component is a base layout container, it is not possible to show its capabilities in a demo sample here.
You can always check our Boilerplate project template samples - (AdminPanel & Todo) - to see the BitProLayout in action. + (AdminPanel & + Todo) + to see the BitAppShell in action.
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor.cs similarity index 89% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor.cs rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor.cs index 714dbf8819..570afca29a 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor.cs @@ -1,6 +1,6 @@ -namespace Bit.BlazorUI.Demo.Client.Core.Pages.Components.Extras.ProLayout; +namespace Bit.BlazorUI.Demo.Client.Core.Pages.Components.Extras.AppShell; -public partial class BitProLayoutDemo +public partial class BitAppShellDemo { private readonly List componentParameters = [ @@ -23,7 +23,7 @@ public partial class BitProLayoutDemo new() { Name = "Classes", - Type = "BitProLayoutClassStyles?", + Type = "BitAppShellClassStyles?", DefaultValue = "null", Description = "Custom CSS classes for different parts of the layout.", LinkType = LinkType.Link, @@ -32,7 +32,7 @@ public partial class BitProLayoutDemo new() { Name = "Styles", - Type = "BitProLayoutClassStyles?", + Type = "BitAppShellClassStyles?", DefaultValue = "null", Description = "Custom CSS styles for different parts of the layout.", LinkType = LinkType.Link, @@ -74,7 +74,7 @@ public partial class BitProLayoutDemo new() { Id = "class-styles", - Title = "BitProLayoutClassStyles", + Title = "BitAppShellClassStyles", Parameters = [ new() @@ -82,49 +82,49 @@ public partial class BitProLayoutDemo Name = "Root", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the root of the BitProLayout.", + Description = "Custom CSS classes/styles for the root of the BitAppShell.", }, new() { Name = "Top", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the top area of the BitProLayout.", + Description = "Custom CSS classes/styles for the top area of the BitAppShell.", }, new() { Name = "Center", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the top center of the BitProLayout.", + Description = "Custom CSS classes/styles for the top center of the BitAppShell.", }, new() { Name = "Left", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the top left of the BitProLayout.", + Description = "Custom CSS classes/styles for the top left of the BitAppShell.", }, new() { Name = "Main", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the main area of the BitProLayout.", + Description = "Custom CSS classes/styles for the main area of the BitAppShell.", }, new() { Name = "Right", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the right area of the BitProLayout.", + Description = "Custom CSS classes/styles for the right area of the BitAppShell.", }, new() { Name = "Bottom", Type = "string?", DefaultValue = "null", - Description = "Custom CSS classes/styles for the bottom area of the BitProLayout.", + Description = "Custom CSS classes/styles for the bottom area of the BitAppShell.", }, ] } diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor.scss b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor.scss similarity index 100% rename from src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor.scss rename to src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/AppShell/BitAppShellDemo.razor.scss diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor new file mode 100644 index 0000000000..5c683b628e --- /dev/null +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor @@ -0,0 +1,31 @@ +@page "/components/navpanel" + +@inherits AppComponentBase + + + + + + +
+ +
+ +
+
+ + + +
+ +
+ +
+
+
\ No newline at end of file diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor.cs new file mode 100644 index 0000000000..3497c9812a --- /dev/null +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor.cs @@ -0,0 +1,394 @@ + +namespace Bit.BlazorUI.Demo.Client.Core.Pages.Components.Extras.NavPanel; + +public partial class BitNavPanelDemo +{ + private readonly List componentParameters = + [ + new() + { + Name = "Classes", + Type = "BitNavPanelClassStyles?", + DefaultValue = "null", + Description = "Custom CSS classes for different parts of the nav panel.", + Href = "#class-styles", + LinkType = LinkType.Link, + }, + new() + { + Name = "EmptyListTemplate", + Type = "RenderFragment?", + DefaultValue = "null", + Description = "The custom template for when the search result is empty.", + }, + new() + { + Name = "EmptyListMessage", + Type = "string?", + DefaultValue = "null", + Description = "The custom message for when the search result is empty.", + }, + new() + { + Name = "Footer", + Type = "RenderFragment?", + DefaultValue = "null", + Description = "The custom template to render as the footer of the nav panel.", + }, + new() + { + Name = "Header", + Type = "RenderFragment?", + DefaultValue = "null", + Description = "The custom template to render as the header of the nav panel.", + }, + new() + { + Name = "IconUrl", + Type = "string?", + DefaultValue = "null", + Description = "The icon url to show in the header of the nav panel.", + }, + new() + { + Name = "IsOpen", + Type = "bool", + DefaultValue = "false", + Description = "Determines if the nav panel is open in small screens.", + }, + new() + { + Name = "IsToggled", + Type = "bool", + DefaultValue = "false", + Description = "Determines if the nav panel is in the toggled state.", + }, + new() + { + Name = "Items", + Type = "IList", + DefaultValue = "[]", + Description = "A collection of items to display in the nav panel.", + }, + new() + { + Name = "NavClasses", + Type = "BitNavClassStyles?", + DefaultValue = "null", + Description = "Custom CSS classes for different parts of the nav component of the nav panel.", + }, + new() + { + Name = "NavStyles", + Type = "BitNavClassStyles?", + DefaultValue = "null", + Description = "Custom CSS styles for different parts of the nav component of the nav panel.", + }, + new() + { + Name = "OnItemClick", + Type = "EventCallback", + DefaultValue = "", + Description = "Event fired up when an item is clicked.", + }, + new() + { + Name = "SearchBoxClasses", + Type = "BitSearchBoxClassStyles?", + DefaultValue = "null", + Description = "Custom CSS classes for different parts of the search box of the nav panel.", + }, + new() + { + Name = "SearchBoxPlaceholder", + Type = "string?", + DefaultValue = "null", + Description = "The placeholder of the input element of the search box of the nav panel.", + }, + new() + { + Name = "SearchBoxStyles", + Type = "BitSearchBoxClassStyles?", + DefaultValue = "null", + Description = "Custom CSS styles for different parts of the search box of the nav panel.", + }, + new() + { + Name = "Styles", + Type = "BitNavPanelClassStyles?", + DefaultValue = "null", + Description = "Custom CSS styles for different parts of the nav panel.", + Href = "#class-styles", + LinkType = LinkType.Link, + }, + new() + { + Name = "Togglable", + Type = "bool", + DefaultValue = "false", + Description = "Enables the toggle feature of the nav panel.", + }, + new() + { + Name = "Top", + Type = "int", + DefaultValue = "0", + Description = "The top CSS property value of the root element of the nav panel in px.", + }, + ]; + + private readonly List componentSubClasses = + [ + new() + { + Id = "class-styles", + Title = "BitNavPanelClassStyles", + Parameters= + [ + new() + { + Name = "Overlay", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the overlay of the BitNavPanel.", + }, + new() + { + Name = "Root", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the root element of the BitNavPanel.", + }, + new() + { + Name = "Container", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the container of the BitNavPanel.", + }, + new() + { + Name = "Header", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the header container of the BitNavPanel.", + }, + new() + { + Name = "HeaderIcon", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the header icon of the BitNavPanel.", + }, + new() + { + Name = "ToggleButton", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the toggle button of the BitNavPanel.", + }, + new() + { + Name = "SearchBox", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the search box of the BitNavPanel.", + }, + new() + { + Name = "ToggleSearchButton", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the toggle search button of the BitNavPanel.", + }, + new() + { + Name = "EmptyListMessage", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the empty list message of the BitNavPanel.", + }, + new() + { + Name = "Nav", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the nav component of the BitNavPanel.", + }, + ] + } + ]; + + + + private bool basicIsOpen; + private bool rtlIsOpen; + private List basicNavItems = + [ + new() + { + Text = "Home", + IconName = BitIconName.Home, + Url = "HomePage", + }, + new() + { + Text = "AdminPanel", + IconName = BitIconName.Admin, + ChildItems = + [ + new() { + Text = "Dashboard", + IconName = BitIconName.BarChartVerticalFill, + Url = "DashboardPage", + }, + new() { + Text = "Categories", + IconName = BitIconName.BuildQueue, + Url = "CategoriesPage", + }, + new() { + Text = "Products", + IconName = BitIconName.Product, + Url = "ProductsPage", + } + ] + }, + new() + { + Text = "Todo", + IconName = BitIconName.ToDoLogoOutline, + Url = "TodoPage", + }, + new() + { + Text = "Settings", + IconName = BitIconName.Equalizer, + Url = "SettingsPage" + }, + new() + { + Text = "Terms", + IconName = BitIconName.EntityExtraction, + Url = "TermsPage", + } + ]; + + + + private readonly string example1RazorCode = @" + + +"; + private readonly string example1CsharpCode = @" +private bool basicIsOpen; + +private List basicNavItems = +[ + new() + { + Text = ""Home"", + IconName = BitIconName.Home, + Url = ""HomePage"", + }, + new() + { + Text = ""AdminPanel"", + IconName = BitIconName.Admin, + ChildItems = + [ + new() { + Text = ""Dashboard"", + IconName = BitIconName.BarChartVerticalFill, + Url = ""DashboardPage"", + }, + new() { + Text = ""Categories"", + IconName = BitIconName.BuildQueue, + Url = ""CategoriesPage"", + }, + new() { + Text = ""Products"", + IconName = BitIconName.Product, + Url = ""ProductsPage"", + } + ] + }, + new() + { + Text = ""Todo"", + IconName = BitIconName.ToDoLogoOutline, + Url = ""TodoPage"", + }, + new() + { + Text = ""Settings"", + IconName = BitIconName.Equalizer, + Url = ""SettingsPage"" + }, + new() + { + Text = ""Terms"", + IconName = BitIconName.EntityExtraction, + Url = ""TermsPage"", + } +];"; + + private readonly string example2RazorCode = @" + + +"; + private readonly string example2CsharpCode = @" +private bool rtlIsOpen; + +private List basicNavItems = +[ + new() + { + Text = ""Home"", + IconName = BitIconName.Home, + Url = ""HomePage"", + }, + new() + { + Text = ""AdminPanel"", + IconName = BitIconName.Admin, + ChildItems = + [ + new() { + Text = ""Dashboard"", + IconName = BitIconName.BarChartVerticalFill, + Url = ""DashboardPage"", + }, + new() { + Text = ""Categories"", + IconName = BitIconName.BuildQueue, + Url = ""CategoriesPage"", + }, + new() { + Text = ""Products"", + IconName = BitIconName.Product, + Url = ""ProductsPage"", + } + ] + }, + new() + { + Text = ""Todo"", + IconName = BitIconName.ToDoLogoOutline, + Url = ""TodoPage"", + }, + new() + { + Text = ""Settings"", + IconName = BitIconName.Equalizer, + Url = ""SettingsPage"" + }, + new() + { + Text = ""Terms"", + IconName = BitIconName.EntityExtraction, + Url = ""TermsPage"", + } +];"; +} diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor.scss b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/NavPanel/BitNavPanelDemo.razor.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor index 87c7bec1ef..5c6946ff4a 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor @@ -1,7 +1,7 @@ @page "/components/layout" - + - +
- +
Header
- - - + + +
Main
@@ -55,36 +55,11 @@
Header
- NavMenu -
Main
-
Footer
-
-
-
-
- - - -
- - -
-
-
- -
Header
- NavMenu + NavPanel
Main
Footer
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor.cs index 9762cf4716..1758c31bc0 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Layouts/Layout/BitLayoutDemo.razor.cs @@ -14,20 +14,6 @@ public partial class BitLayoutDemo Href = "#class-styles" }, new() - { - Name = "FixedHeader", - Type = "bool", - DefaultValue = "false", - Description = "Enables fixed positioning of the header at the top of the viewport.", - }, - new() - { - Name = "FixedFooter", - Type = "bool", - DefaultValue = "false", - Description = "Enables fixed positioning of the footer at the bottom of the viewport.", - }, - new() { Name = "Footer", Type = "RenderFragment?", @@ -35,13 +21,6 @@ public partial class BitLayoutDemo Description = "The content of the footer section.", }, new() - { - Name = "FooterHeight", - Type = "int", - DefaultValue = "0", - Description = "The height of the footer to calculate heights and paddings.", - }, - new() { Name = "Header", Type = "RenderFragment?", @@ -50,17 +29,10 @@ public partial class BitLayoutDemo }, new() { - Name = "HeaderHeight", - Type = "int", - DefaultValue = "0", - Description = "The height of the header to calculate heights and paddings.", - }, - new() - { - Name = "HideNavMenu", + Name = "HideNavPanel", Type = "bool", DefaultValue = "false", - Description = "Hides NavMenu content when true.", + Description = "Hides NavPanel content when true.", }, new() { @@ -71,17 +43,17 @@ public partial class BitLayoutDemo }, new() { - Name = "NavMenu", + Name = "NavPanel", Type = "RenderFragment?", DefaultValue = "null", - Description = "The content of the nav-menu section.", + Description = "The content of the nav panel section.", }, new() { - Name = "StatusBarHeight", + Name = "NavPanelWidth", Type = "int", DefaultValue = "0", - Description = "The height of the status bar on mobile devices to calculate heights and paddings.", + Description = "The width of the nav panel section in px.", }, new() { @@ -91,7 +63,21 @@ public partial class BitLayoutDemo Description = "Custom CSS styles for different parts of the BitLayout.", LinkType = LinkType.Link, Href = "#class-styles" - } + }, + new() + { + Name = "StickyFooter", + Type = "bool", + DefaultValue = "false", + Description = "Enables sticky positioning of the footer at the bottom of the viewport.", + }, + new() + { + Name = "StickyHeader", + Type = "bool", + DefaultValue = "false", + Description = "Enables sticky positioning of the header at the top of the viewport.", + }, ]; private readonly List componentSubClasses = @@ -125,7 +111,7 @@ public partial class BitLayoutDemo }, new() { - Name = "NavMenu", + Name = "NavPanel", Type = "string?", DefaultValue = "null", Description = "Custom CSS classes/styles for the nav-menu section of the BitLayout." @@ -150,10 +136,8 @@ public partial class BitLayoutDemo - private bool hideNavMenu; + private bool HideNavPanel; - private int headerHeight = 60; - private int footerHeight = 60; private readonly string example1RazorCode = @" @@ -217,15 +201,15 @@ public partial class BitLayoutDemo - + - +
Header
- -
NavMenu
-
+ +
NavPanel
+
Main
@@ -234,7 +218,7 @@ public partial class BitLayoutDemo
"; private readonly string example2CsharpCode = @" -private bool hideNavMenu;"; +private bool HideNavPanel;"; private readonly string example3RazorCode = @"