diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValue.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValue.cs new file mode 100644 index 0000000000..16f09199d0 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValue.cs @@ -0,0 +1,44 @@ +namespace Bit.BlazorUI; + +/// +/// The cascading value to be provided using the component. +/// +public class BitCascadingValue +{ + /// + /// The optional name of the cascading value. + /// + public string? Name { get; set; } + + /// + /// The value to be provided. + /// + public object? Value { get; set; } + + /// + /// If true, indicates that will not change. + /// + public bool IsFixed { get; set; } + + + + public BitCascadingValue() { } + public BitCascadingValue(object? value, string? name = null) : this(value, name, false) { } + public BitCascadingValue(object? value, bool isFixed) : this(value, null, isFixed) { } + public BitCascadingValue(object? value, string? name, bool isFixed) + { + Value = value; + Name = name; + IsFixed = isFixed; + } + + + + public static implicit operator BitCascadingValue(int value) => new(value); + public static implicit operator BitCascadingValue(int? value) => new(value); + public static implicit operator BitCascadingValue(bool value) => new(value); + public static implicit operator BitCascadingValue(bool? value) => new(value); + public static implicit operator BitCascadingValue(string value) => new(value); + public static implicit operator BitCascadingValue(BitDir? value) => new(value); + public static implicit operator BitCascadingValue(RouteData value) => new(value); +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValueProvider.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValueProvider.cs new file mode 100644 index 0000000000..4dc929cf99 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitCascadingValueProvider.cs @@ -0,0 +1,69 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Bit.BlazorUI; + +/// +/// A component that provides a list of cascading values to all descendant components. +/// +public class BitCascadingValueProvider : ComponentBase +{ + /// + /// The content to which the values should be provided. + /// + [Parameter] public RenderFragment? ChildContent { get; set; } + + /// + /// The cascading values to be provided for the children. + /// + [Parameter] public IEnumerable? Values { get; set; } + + + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] + private Type _cascadingValueType = typeof(CascadingValue<>); + + + + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitCascadingValue))] + protected override void BuildRenderTree(RenderTreeBuilder builder) + { + var seq = 0; + RenderFragment? rf = ChildContent; + + foreach (var value in Values ?? []) + { + if (value.Value is null) continue; + + var r = rf; + var s = seq; + var v = value; + + rf = b => { CreateCascadingValue(b, s, v.Name, v.Value, v.IsFixed, r); }; + + seq += v.Name.HasValue() ? 5 : 4; + } + + builder.AddContent(seq, rf); + } + + + private void CreateCascadingValue(RenderTreeBuilder builder, + int seq, + string? name, + object value, + bool isFixed, + RenderFragment? childContent) + { +#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) + { + builder.AddComponentParameter(++seq, "Name", name); + } + builder.AddComponentParameter(++seq, "Value", value); + builder.AddComponentParameter(++seq, "IsFixed", isFixed); + builder.AddComponentParameter(++seq, "ChildContent", childContent); + builder.CloseComponent(); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor new file mode 100644 index 0000000000..0b25c15ac0 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor @@ -0,0 +1,23 @@ +@namespace Bit.BlazorUI +@inherits BitComponentBase + +
+
+
+
+
+ + @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/ProLayout/BitProLayout.razor.cs new file mode 100644 index 0000000000..af75a24d4a --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.razor.cs @@ -0,0 +1,38 @@ +namespace Bit.BlazorUI; + +public partial class BitProLayout : BitComponentBase +{ + /// + /// The cascading values to be provided for the children of the layout. + /// + [Parameter] public IEnumerable? CascadingValues { get; set; } + + /// + /// The content of the layout. + /// + [Parameter] public RenderFragment? ChildContent { get; set; } + + /// + /// Custom CSS classes for different parts of the layout. + /// + [Parameter] public BitProLayoutClassStyles? Classes { get; set; } + + /// + /// Custom CSS styles for different parts of the layout. + /// + [Parameter] public BitProLayoutClassStyles? Styles { get; set; } + + + + protected override string RootElementClass => "bit-ply"; + + protected override void RegisterCssClasses() + { + ClassBuilder.Register(() => Classes?.Root); + } + + protected override void RegisterCssStyles() + { + StyleBuilder.Register(() => Styles?.Root); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.scss new file mode 100644 index 0000000000..81b2fa70d4 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayout.scss @@ -0,0 +1,54 @@ +@import '../../Styles/extra-variables.scss'; +@import '../../../Bit.BlazorUI/Styles/functions.scss'; + +.bit-ply { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background-color: $clr-bg-pri; +} + +.bit-ply-top { + width: 100%; + z-index: 999999; + height: $bit-env-inset-top; + background-color: $clr-bg-pri; +} + +.bit-ply-bottom { + width: 100%; + z-index: 999999; + height: $bit-env-inset-bottom; + background-color: $clr-bg-pri; +} + +.bit-ply-center { + width: 100%; + display: flex; + height: calc(100% - $bit-env-inset-top - $bit-env-inset-bottom); +} + +.bit-ply-main { + height: 100%; + display: flex; + overflow: auto; + position: relative; + scroll-behavior: smooth; + overscroll-behavior: none; + width: calc(100% - $bit-env-inset-left - $bit-env-inset-right); +} + +.bit-ply-left { + height: 100%; + z-index: 999999; + width: $bit-env-inset-left; + background-color: $clr-bg-pri; +} + +.bit-ply-right { + height: 100%; + z-index: 999999; + width: $bit-env-inset-right; + background-color: $clr-bg-pri; +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayoutClassStyles.cs b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayoutClassStyles.cs new file mode 100644 index 0000000000..6793afc5ca --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/ProLayout/BitProLayoutClassStyles.cs @@ -0,0 +1,39 @@ +namespace Bit.BlazorUI; + +public class BitProLayoutClassStyles +{ + /// + /// Custom CSS classes/styles for the root of the BitProLayout. + /// + public string? Root { get; set; } + + /// + /// Custom CSS classes/styles for the top area of the BitProLayout. + /// + public string? Top { get; set; } + + /// + /// Custom CSS classes/styles for the center area of the BitProLayout. + /// + public string? Center { get; set; } + + /// + /// Custom CSS classes/styles for the left area of the BitProLayout. + /// + public string? Left { get; set; } + + /// + /// Custom CSS classes/styles for the main area of the BitProLayout. + /// + public string? Main { get; set; } + + /// + /// Custom CSS classes/styles for the right area of the BitProLayout. + /// + public string? Right { get; set; } + + /// + /// Custom CSS classes/styles for the bottom area of the BitProLayout. + /// + public string? Bottom { get; set; } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Scripts/general.ts b/src/BlazorUI/Bit.BlazorUI.Extras/Scripts/general.ts new file mode 100644 index 0000000000..d19e62953b --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Scripts/general.ts @@ -0,0 +1,4 @@ +window.addEventListener('load', () => { + document.documentElement.style.setProperty('--bit-env-win-width', `${window.innerWidth}px`); + document.documentElement.style.setProperty('--bit-env-win-height', `${window.innerHeight}px`); +}); \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss index 4d58f1782c..eb02b8b603 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/bit.blazorui.extras.scss @@ -1,2 +1,3 @@ -@import "components.scss"; +@import "general.scss"; +@import "components.scss"; @import "fabric.mdl2.bit.blazoui.extras.scss"; diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss index ca46bd9aef..7dcba98b06 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/components.scss @@ -2,3 +2,4 @@ @import "../Components/DataGrid/Pagination/BitDataGridPaginator.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/extra-variables.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-variables.scss new file mode 100644 index 0000000000..8f09e8a4e9 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/extra-variables.scss @@ -0,0 +1,17 @@ +$bit-env-inset-top: var(--bit-env-inset-top); +$bit-env-inset-left: var(--bit-env-inset-left); +$bit-env-inset-right: var(--bit-env-inset-right); +$bit-env-inset-bottom: var(--bit-env-inset-bottom); +//-- +$bit-env-width-vw: var(--bit-env-width-vw); +$bit-env-height-vh: var(--bit-env-height-vh); +$bit-env-width-percent: var(--bit-env-width-per); +$bit-env-height-percent: var(--bit-env-height-per); +$bit-env-width-available: var(--bit-env-width-avl); +$bit-env-height-available: var(--bit-env-height-avl); +//-- +$bit-env-inset-inline-start: var(--bit-env-inset-inline-start); +$bit-env-inset-inline-end: var(--bit-env-inset-inline-end); +//-- +$bit-env-window-width: var(--bit-env-win-width); +$bit-env-window-height: var(--bit-env-win-height); diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Styles/general.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/general.scss new file mode 100644 index 0000000000..d77e2b499d --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Styles/general.scss @@ -0,0 +1,21 @@ +:root { + --bit-env-inset-top: env(safe-area-inset-top, 0px); + --bit-env-inset-left: env(safe-area-inset-left, 0px); + --bit-env-inset-right: env(safe-area-inset-right, 0px); + --bit-env-inset-bottom: env(safe-area-inset-bottom, 0px); + //-- + --bit-env-width-vw: calc(100vw - var(--bit-env-inset-left) - var(--bit-env-inset-right)); + --bit-env-height-vh: calc(100vh - var(--bit-env-inset-top) - var(--bit-env-inset-bottom)); + --bit-env-width-per: calc(100% - var(--bit-env-inset-left) - var(--bit-env-inset-right)); + --bit-env-height-per: calc(100% - var(--bit-env-inset-top) - var(--bit-env-inset-bottom)); + --bit-env-width-avl: calc(var(--bit-env-win-width) - var(--bit-env-inset-left) - var(--bit-env-inset-right)); + --bit-env-height-avl: calc(var(--bit-env-win-height) - var(--bit-env-inset-top) - var(--bit-env-inset-bottom)); + //-- + --bit-env-inset-inline-start: var(--bit-env-inset-left); + --bit-env-inset-inline-end: var(--bit-env-inset-right); + + [dir="rtl"] { + --bit-env-inset-inline-start: var(--bit-env-inset-right); + --bit-env-inset-inline-end: var(--bit-env-inset-left); + } +} diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/ComponentExampleBox.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/ComponentExampleBox.razor index dd473865ca..f8a69fc59a 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/ComponentExampleBox.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Components/ComponentExampleBox.razor @@ -3,25 +3,28 @@
@Title -
- - @(showCode ? "Hide code" : "Show code") - - - @if (isLinkCopied) - { - @copyLinkMessage - } - -
+ @if (RazorCode is not null || CsharpCode is not null) + { +
+ + @(showCode ? "Hide code" : "Show code") + + + @if (isLinkCopied) + { + @copyLinkMessage + } + +
+ }
@@ -39,14 +42,18 @@
-                @RazorCode.Trim()
+                
+                
+                    @RazorCode?.Trim()
+                
 
                 @if (CsharpCode.HasValue())
                 {
                     
 @code {
-     @CsharpCode.Trim().Replace("\n", "\n     ")
-}
+    @CsharpCode?.Trim().Replace("\n", "\n     ")
+}
+                    
                 }
             
} 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/ProLayout/BitProLayoutDemo.razor new file mode 100644 index 0000000000..c8f12f1d69 --- /dev/null +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor @@ -0,0 +1,24 @@ +@page "/components/prolayout" + +@inherits AppComponentBase + + + + + + +
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. +
+
+
+
\ No newline at end of file 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/ProLayout/BitProLayoutDemo.razor.cs new file mode 100644 index 0000000000..714dbf8819 --- /dev/null +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Extras/ProLayout/BitProLayoutDemo.razor.cs @@ -0,0 +1,133 @@ +namespace Bit.BlazorUI.Demo.Client.Core.Pages.Components.Extras.ProLayout; + +public partial class BitProLayoutDemo +{ + private readonly List componentParameters = + [ + new() + { + Name = "CascadingValues", + Type = "IEnumerable?", + DefaultValue = "null", + Description = "The cascading values to be provided for the children of the layout.", + LinkType = LinkType.Link, + Href = "#cascading-value" + }, + new() + { + Name = "ChildContent", + Type = "RenderFragment?", + DefaultValue = "null", + Description = "The content of the layout.", + }, + new() + { + Name = "Classes", + Type = "BitProLayoutClassStyles?", + DefaultValue = "null", + Description = "Custom CSS classes for different parts of the layout.", + LinkType = LinkType.Link, + Href = "#class-styles" + }, + new() + { + Name = "Styles", + Type = "BitProLayoutClassStyles?", + DefaultValue = "null", + Description = "Custom CSS styles for different parts of the layout.", + LinkType = LinkType.Link, + Href = "#class-styles" + }, + ]; + + private readonly List componentSubClasses = + [new() + { + Id = "cascading-value", + Title = "BitCascadingValue", + Description = "The cascading value to be provided using the BitCascadingValueProvider component.", + Parameters = + [ + new() + { + Name = "Name", + Type = "string?", + DefaultValue = "null", + Description = "The optional name of the cascading value.", + }, + new() + { + Name = "Value", + Type = "object?", + DefaultValue = "null", + Description = "The value to be provided.", + }, + new() + { + Name = "IsFixed", + Type = "bool", + DefaultValue = "null", + Description = "If true, indicates that Value will not change.", + } + ] + }, + new() + { + Id = "class-styles", + Title = "BitProLayoutClassStyles", + Parameters = + [ + new() + { + Name = "Root", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the root of the BitProLayout.", + }, + new() + { + Name = "Top", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the top area of the BitProLayout.", + }, + new() + { + Name = "Center", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the top center of the BitProLayout.", + }, + new() + { + Name = "Left", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the top left of the BitProLayout.", + }, + new() + { + Name = "Main", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the main area of the BitProLayout.", + }, + new() + { + Name = "Right", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the right area of the BitProLayout.", + }, + new() + { + Name = "Bottom", + Type = "string?", + DefaultValue = "null", + Description = "Custom CSS classes/styles for the bottom area of the BitProLayout.", + }, + ] + } + ]; + +} 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/ProLayout/BitProLayoutDemo.razor.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor index b3e28e6a15..79f9ec0e34 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Home/ComponentsSection.razor @@ -253,6 +253,9 @@ PdfReader + + ProLayout + ProPanel diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/NavMenu.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/NavMenu.razor.cs index 84b6f10f89..88e59091ab 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/NavMenu.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Shared/NavMenu.razor.cs @@ -156,6 +156,7 @@ public partial class NavMenu : IDisposable new() { Text = "DataGrid", Url = "/components/datagrid", AdditionalUrls = ["/components/data-grid"] }, new() { Text = "Chart", Url = "/components/chart" }, new() { Text = "PdfReader", Url = "/components/pdfreader" }, + new() { Text = "ProLayout", Url = "/components/prolayout" }, new() { Text = "ProPanel", Url = "/components/propanel" }, new() {