From 63a84810f56796466e4c827011e2e66436438702 Mon Sep 17 00:00:00 2001 From: stm Date: Mon, 9 Jan 2023 14:51:00 +0100 Subject: [PATCH] Drawer, DrwerContainer, DrawerHeader - rework --- .../.config/dotnet-tools.json | 2 +- .../Components/Drawer/Drawer.razor | 20 +- .../Components/Drawer/Drawer.razor.cs | 533 +++++++++--------- .../Components/Drawer/DrawerContainer.razor | 2 +- .../Drawer/DrawerContainer.razor.cs | 128 +++-- .../Components/Drawer/DrawerHeader.razor | 4 +- .../Components/Drawer/DrawerHeader.razor.cs | 44 +- .../Components/Layout/Layout.razor | 2 +- .../Components/Layout/Layout.razor.cs | 28 +- src/Connected.Components/Navigation.cs | 119 ++++ 10 files changed, 556 insertions(+), 326 deletions(-) create mode 100644 src/Connected.Components/Navigation.cs diff --git a/src/Connected.Components/.config/dotnet-tools.json b/src/Connected.Components/.config/dotnet-tools.json index 3700f37..271e0bc 100644 --- a/src/Connected.Components/.config/dotnet-tools.json +++ b/src/Connected.Components/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "excubo.webcompiler": { - "version": "3.5.0", + "version": "3.5.10", "commands": [ "webcompiler" ] diff --git a/src/Connected.Components/Components/Drawer/Drawer.razor b/src/Connected.Components/Components/Drawer/Drawer.razor index 1963c24..55f08bf 100644 --- a/src/Connected.Components/Components/Drawer/Drawer.razor +++ b/src/Connected.Components/Components/Drawer/Drawer.razor @@ -1,11 +1,25 @@ @namespace Connected.Components @inherits UIComponent - + +} else { +

Tabs

+ + + @ChildContent + + + +} \ No newline at end of file diff --git a/src/Connected.Components/Components/Drawer/Drawer.razor.cs b/src/Connected.Components/Components/Drawer/Drawer.razor.cs index 1b31040..713d52c 100644 --- a/src/Connected.Components/Components/Drawer/Drawer.razor.cs +++ b/src/Connected.Components/Components/Drawer/Drawer.razor.cs @@ -3,6 +3,7 @@ using Connected.Extensions; using Connected.Services; using Connected.Utilities; using Microsoft.AspNetCore.Components; +using System.ComponentModel; namespace Connected.Components; @@ -12,54 +13,192 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver private ElementReference _contentRef; private DrawerClipMode _clipMode; private bool? _isOpenWhenLarge = null; - private bool _open, _rtl, _isRendered, _initial = true, _keepInitialState, _fixed = true; - private Breakpoint _breakpoint = Breakpoint.Md, _screenBreakpoint = Breakpoint.None; + private bool _open; + private bool _rtl; + private bool _isRendered; + private bool _initial = true; + private bool _keepInitialState; + private bool _fixed = true; + private Breakpoint _breakpoint = Breakpoint.Md; + private Breakpoint _screenBreakpoint = Breakpoint.None; private Guid _breakpointListenerSubscriptionId; - private bool OverlayVisible => _open && !DisableOverlay && - (Variant == DrawerVariant.Temporary || - (_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Mini) || - (_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Responsive)); + #region EventCallbacks - protected string Classname => - new CssBuilder("drawer") - .AddClass($"drawer-fixed", Fixed) - .AddClass($"drawer-pos-{GetPosition()}") - .AddClass($"drawer--open", Open) - .AddClass($"drawer--closed", !Open) - .AddClass($"drawer--initial", _initial) - .AddClass($"drawer-{Breakpoint.ToDescription()}") - .AddClass($"drawer-clipped-{_clipMode.ToDescription()}") - .AddClass($"theme-{Color.ToDescription()}", Color != ThemeColor.Default) - .AddClass($"elevation-{Elevation}") - .AddClass($"drawer-{Variant.ToDescription()}") - .AddClass(AdditionalClassList) - .Build(); - - protected string OverlayClass => - new CssBuilder("drawer-overlay mud-overlay-drawer") - .AddClass($"drawer-pos-{GetPosition()}") - .AddClass($"drawer-overlay--open", Open) - .AddClass($"drawer-overlay-{Variant.ToDescription()}") - .AddClass($"drawer-overlay-{Breakpoint.ToDescription()}") - .AddClass($"drawer-overlay--initial", _initial) - .Build(); - - protected string Stylename => - new StyleBuilder() - //.AddStyle("width", Width, !string.IsNullOrWhiteSpace(Width) && !Fixed) - .AddStyle("--mud-drawer-width", Width, !string.IsNullOrWhiteSpace(Width) && (!Fixed || Variant == DrawerVariant.Temporary)) - .AddStyle("height", Height, !string.IsNullOrWhiteSpace(Height)) - .AddStyle("--mud-drawer-content-height", - string.IsNullOrWhiteSpace(Height) ? _height.ToPx() : Height, - Anchor == Anchor.Bottom || Anchor == Anchor.Top) - .AddStyle("visibility", "hidden", string.IsNullOrWhiteSpace(Height) && _height == 0 && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)) - .Build(); - [Inject] public IBreakpointService Breakpointistener { get; set; } + [Parameter] public EventCallback OpenChanged { get; set; } + + public async Task OnNavigation() + { + if (Variant == DrawerVariant.Temporary || + (Variant == DrawerVariant.Responsive && await Breakpointistener.GetBreakpoint() < Breakpoint)) + { + await OpenChanged.InvokeAsync(false); + } + } + + private void ResizeListener_OnBreakpointChanged(object sender, Breakpoint breakpoint) + { + if (!_isRendered) + return; + + InvokeAsync(() => UpdateBreakpointState(breakpoint)); + } + + private async void UpdateBreakpointState(Breakpoint breakpoint) + { + var isStateChanged = false; + if (breakpoint == Breakpoint.None) + { + breakpoint = await Breakpointistener.GetBreakpoint(); + } + + if (breakpoint < Breakpoint && _screenBreakpoint >= Breakpoint && (Variant == DrawerVariant.Responsive || Variant == DrawerVariant.Mini)) + { + _isOpenWhenLarge = Open; + + await OpenChanged.InvokeAsync(false); + isStateChanged = true; + } + else if (breakpoint >= Breakpoint && _screenBreakpoint < Breakpoint && (Variant == DrawerVariant.Responsive || Variant == DrawerVariant.Mini)) + { + if (Open && PreserveOpenState) + { + DrawerContainer?.FireDrawersChanged(); + isStateChanged = true; + } + else if (_isOpenWhenLarge != null) + { + await OpenChanged.InvokeAsync(_isOpenWhenLarge.Value); + _isOpenWhenLarge = null; + isStateChanged = true; + } + } + + if (_breakpoint != _screenBreakpoint) + { + isStateChanged = true; + } + _screenBreakpoint = breakpoint; + + if (isStateChanged) + { + StateHasChanged(); + } + } + + internal string GetPosition() + { + switch (Anchor) + { + case Anchor.Start: + return RightToLeft ? "right" : "left"; + case Anchor.End: + return RightToLeft ? "left" : "right"; + default: break; + } + + return Anchor.ToDescription(); + } + + + private bool closeOnMouseLeave = false; + + public async void OnMouseEnter() + { + if (Variant == DrawerVariant.Mini && !Open && OpenMiniOnHover) + { + closeOnMouseLeave = true; + await OpenChanged.InvokeAsync(true); + } + } + + public async void OnMouseLeave() + { + if (Variant == DrawerVariant.Mini && Open && closeOnMouseLeave) + { + closeOnMouseLeave = false; + await OpenChanged.InvokeAsync(false); + } + } + + protected override void OnInitialized() + { + if (Variant != DrawerVariant.Temporary) + { + DrawerContainer?.Add(this); + } + base.OnInitialized(); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + //await UpdateHeight(); + var result = await Breakpointistener.Subscribe(UpdateBreakpointState); + //var currentBreakpoint = result.Breakpoint; + + _breakpointListenerSubscriptionId = result.SubscriptionId; + + var refresh = false; + + if (_screenBreakpoint != result.Breakpoint) refresh = true; + _screenBreakpoint = result.Breakpoint; + if (_screenBreakpoint < Breakpoint && _open) + { + _keepInitialState = true; + await OpenChanged.InvokeAsync(false); + } + + _isRendered = true; + if (Anchor == Anchor.Bottom || Anchor == Anchor.Top || _screenBreakpoint == Breakpoint.None) + { + refresh = true; + } + if (refresh) StateHasChanged(); + } + + await base.OnAfterRenderAsync(firstRender); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + int _disposeCount; + public virtual void Dispose(bool disposing) + { + if (Interlocked.Increment(ref _disposeCount) == 1) + { + if (disposing) + { + DrawerContainer?.Remove(this); + + if (_breakpointListenerSubscriptionId != default) + { + Breakpointistener.Unsubscribe(_breakpointListenerSubscriptionId).AndForget(); + } + } + } + } + + #endregion + + #region Content placeholders + + /// + /// Child content of component. + /// + [Parameter] + public RenderFragment ChildContent { get; set; } [CascadingParameter] DrawerContainer DrawerContainer { get; set; } + [Inject] public IBreakpointService Breakpointistener { get; set; } + [CascadingParameter(Name = "RightToLeft")] bool RightToLeft { @@ -74,11 +213,73 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver } } + #endregion + + #region Styling properties + + private CssBuilder CompiledClassList + { + get + { + return new CssBuilder("drawer") + .AddClass($"drawer-fixed", Fixed) + .AddClass($"drawer-pos-{GetPosition()}") + .AddClass($"drawer--open", Open) + .AddClass($"drawer--closed", !Open) + .AddClass($"drawer--initial", _initial) + .AddClass($"drawer-{Breakpoint.ToDescription()}") + .AddClass($"drawer-clipped-{_clipMode.ToDescription()}") + //.AddClass($"theme-{Color.ToDescription()}", Color != ThemeColor.Default) + .AddClass($"elevation-{Elevation}") + .AddClass($"drawer-{Variant.ToDescription()}") + .AddClass(ClassList); + } + } + + protected StyleBuilder CompiledStyleList + { + get + { + return new StyleBuilder() + .AddStyle(StyleList); + //.AddStyle("width", Width, !string.IsNullOrWhiteSpace(Width) && !Fixed) + //.AddStyle("--mud-drawer-width", Width, !string.IsNullOrWhiteSpace(Width) && (!Fixed || Variant == DrawerVariant.Temporary)) + //.AddStyle("height", Height, !string.IsNullOrWhiteSpace(Height)) + //.AddStyle("--mud-drawer-content-height",string.IsNullOrWhiteSpace(Height) ? _height.ToPx() : Height,Anchor == Anchor.Bottom || Anchor == Anchor.Top) + //.AddStyle("visibility", "hidden", string.IsNullOrWhiteSpace(Height) && _height == 0 && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)); + + } + } + + protected CssBuilder CompiledOverlayClass + { + get + { + return new CssBuilder("drawer-overlay mud-overlay-drawer") + .AddClass($"drawer-pos-{GetPosition()}") + .AddClass($"drawer-overlay--open", Open) + .AddClass($"drawer-overlay-{Variant.ToDescription()}") + .AddClass($"drawer-overlay-{Breakpoint.ToDescription()}") + .AddClass($"drawer-overlay--initial", _initial); + } + } + + /// + /// A space separated list of class names, added on top of the default class list. + /// + [Parameter] + public string? ClassList { get; set; } + + /// + /// A space separated list of class names, added on top of the default class list. + /// + [Parameter] + public string? StyleList { get; set; } + /// /// If true, drawer position will be fixed. (CSS position: fixed;) /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public bool Fixed { get => _fixed && DrawerContainer is Layout; @@ -94,63 +295,78 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver /// The higher the number, the heavier the drop-shadow. 0 for no shadow. /// [Parameter] - [Category(CategoryTypes.Drawer.Appearance)] public int Elevation { set; get; } = 1; /// /// Side from which the drawer will appear. /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public Anchor Anchor { get; set; } = Anchor.Start; + /* /// /// The color of the component. It supports the theme colors. /// [Parameter] - [Category(CategoryTypes.Drawer.Appearance)] public ThemeColor Color { get; set; } = ThemeColor.Default; + */ /// /// Variant of the drawer. It specifies how the drawer will be displayed. /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public DrawerVariant Variant { get; set; } = DrawerVariant.Responsive; - /// - /// Child content of component. - /// - [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] - public RenderFragment ChildContent { get; set; } - + /// /// Show overlay for responsive and temporary drawers. /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public bool DisableOverlay { get; set; } = false; /// /// Preserve open state for responsive drawer when window resized above . /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public bool PreserveOpenState { get; set; } = false; /// /// Open drawer automatically on mouse enter when parameter is set to . /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public bool OpenMiniOnHover { get; set; } + /// + /// Specify how the drawer should behave inside a MudLayout. It affects the position relative to MudAppbar + /// + [Parameter] + public DrawerClipMode ClipMode + { + get => _clipMode; + set + { + if (_clipMode == value) + { + return; + } + _clipMode = value; + if (Fixed) + { + DrawerContainer?.FireDrawersChanged(); + } + StateHasChanged(); + } + } + + private bool OverlayVisible => _open && !DisableOverlay && + (Variant == DrawerVariant.Temporary || + (_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Mini) || + (_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Responsive)); + /// /// Switching point for responsive drawers /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public Breakpoint Breakpoint { get => _breakpoint; @@ -173,7 +389,6 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver /// Sets the opened state on the drawer. Can be used with two-way binding to close itself on navigation. /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public bool Open { get => _open; @@ -192,121 +407,15 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver { _keepInitialState = false; } - if (_isRendered && value && (Anchor == Anchor.Top || Anchor == Anchor.Bottom)) + /*if (_isRendered && value && (Anchor == Anchor.Top || Anchor == Anchor.Bottom)) { _ = UpdateHeight(); - } + }*/ DrawerContainer?.FireDrawersChanged(); OpenChanged.InvokeAsync(_open); } } - - [Parameter] public EventCallback OpenChanged { get; set; } - - /// - /// Width of left/right drawer. Only for non-fixed drawers. - /// - [Parameter] - [Category(CategoryTypes.Drawer.Appearance)] - public string Width { get; set; } - - /// - /// Width of left/right drawer. Only for non-fixed drawers. - /// - [Parameter] - [Category(CategoryTypes.Drawer.Appearance)] - public string MiniWidth { get; set; } - - /// - /// Height of top/bottom temporary drawer - /// - [Parameter] - [Category(CategoryTypes.Drawer.Appearance)] - public string Height { get; set; } - - /// - /// Specify how the drawer should behave inside a MudLayout. It affects the position relative to MudAppbar - /// - [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] - public DrawerClipMode ClipMode - { - get => _clipMode; - set - { - if (_clipMode == value) - { - return; - } - _clipMode = value; - if (Fixed) - { - DrawerContainer?.FireDrawersChanged(); - } - StateHasChanged(); - } - } - - protected override void OnInitialized() - { - if (Variant != DrawerVariant.Temporary) - { - DrawerContainer?.Add(this); - } - base.OnInitialized(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await UpdateHeight(); - var result = await Breakpointistener.Subscribe(UpdateBreakpointState); - var currentBreakpoint = result.Breakpoint; - - _breakpointListenerSubscriptionId = result.SubscriptionId; - - _screenBreakpoint = result.Breakpoint; - if (_screenBreakpoint < Breakpoint && _open) - { - _keepInitialState = true; - await OpenChanged.InvokeAsync(false); - } - - _isRendered = true; - if (string.IsNullOrWhiteSpace(Height) && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)) - { - StateHasChanged(); - } - } - - await base.OnAfterRenderAsync(firstRender); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - int _disposeCount; - public virtual void Dispose(bool disposing) - { - if (Interlocked.Increment(ref _disposeCount) == 1) - { - if (disposing) - { - DrawerContainer?.Remove(this); - - if (_breakpointListenerSubscriptionId != default) - { - Breakpointistener.Unsubscribe(_breakpointListenerSubscriptionId).AndForget(); - } - } - } - } - private void CloseDrawer() { if (Open) @@ -315,97 +424,7 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver } } - public async Task OnNavigation() - { - if (Variant == DrawerVariant.Temporary || - (Variant == DrawerVariant.Responsive && await Breakpointistener.GetBreakpoint() < Breakpoint)) - { - await OpenChanged.InvokeAsync(false); - } - } - - private void ResizeListener_OnBreakpointChanged(object sender, Breakpoint breakpoint) - { - if (!_isRendered) - return; - - InvokeAsync(() => UpdateBreakpointState(breakpoint)); - } - - private async Task UpdateHeight() - { - _height = (await _contentRef.MudGetBoundingClientRectAsync())?.Height ?? 0; - } - - private async void UpdateBreakpointState(Breakpoint breakpoint) - { - var isStateChanged = false; - if (breakpoint == Breakpoint.None) - { - breakpoint = await Breakpointistener.GetBreakpoint(); - } - if (breakpoint < Breakpoint && _screenBreakpoint >= Breakpoint && (Variant == DrawerVariant.Responsive || Variant == DrawerVariant.Mini)) - { - _isOpenWhenLarge = Open; + #endregion - await OpenChanged.InvokeAsync(false); - isStateChanged = true; - } - else if (breakpoint >= Breakpoint && _screenBreakpoint < Breakpoint && (Variant == DrawerVariant.Responsive || Variant == DrawerVariant.Mini)) - { - if (Open && PreserveOpenState) - { - DrawerContainer?.FireDrawersChanged(); - isStateChanged = true; - } - else if (_isOpenWhenLarge != null) - { - await OpenChanged.InvokeAsync(_isOpenWhenLarge.Value); - _isOpenWhenLarge = null; - isStateChanged = true; - } - } - - _screenBreakpoint = breakpoint; - if (isStateChanged) - { - StateHasChanged(); - } - } - - internal string GetPosition() - { - switch (Anchor) - { - case Anchor.Start: - return RightToLeft ? "right" : "left"; - case Anchor.End: - return RightToLeft ? "left" : "right"; - default: break; - } - - return Anchor.ToDescription(); - } - - - private bool closeOnMouseLeave = false; - - public async void OnMouseEnter() - { - if (Variant == DrawerVariant.Mini && !Open && OpenMiniOnHover) - { - closeOnMouseLeave = true; - await OpenChanged.InvokeAsync(true); - } - } - - public async void OnMouseLeave() - { - if (Variant == DrawerVariant.Mini && Open && closeOnMouseLeave) - { - closeOnMouseLeave = false; - await OpenChanged.InvokeAsync(false); - } - } } diff --git a/src/Connected.Components/Components/Drawer/DrawerContainer.razor b/src/Connected.Components/Components/Drawer/DrawerContainer.razor index c5868e6..4dec4c6 100644 --- a/src/Connected.Components/Components/Drawer/DrawerContainer.razor +++ b/src/Connected.Components/Components/Drawer/DrawerContainer.razor @@ -1,7 +1,7 @@ @namespace Connected.Components @inherits UIComponent -
+
@ChildContent diff --git a/src/Connected.Components/Components/Drawer/DrawerContainer.razor.cs b/src/Connected.Components/Components/Drawer/DrawerContainer.razor.cs index 72f8fdc..f385dfb 100644 --- a/src/Connected.Components/Components/Drawer/DrawerContainer.razor.cs +++ b/src/Connected.Components/Components/Drawer/DrawerContainer.razor.cs @@ -10,44 +10,19 @@ public partial class DrawerContainer : UIComponent protected bool Fixed { get; set; } = false; private List _drawers = new(); - protected virtual string Classname => - new CssBuilder() - .AddClass(GetDrawerClass(FindLeftDrawer())) - .AddClass(GetDrawerClass(FindRightDrawer())) - .AddClass(AdditionalClassList) - .Build(); + #region Event callbacks - protected string Stylename => - new StyleBuilder() - .AddStyle("--mud-drawer-width-left", GetDrawerWidth(FindLeftDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindLeftDrawer()))) - .AddStyle("--mud-drawer-width-right", GetDrawerWidth(FindRightDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindRightDrawer()))) - .AddStyle("--mud-drawer-width-mini-left", GetMiniDrawerWidth(FindLeftMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindLeftMiniDrawer()))) - .AddStyle("--mud-drawer-width-mini-right", GetMiniDrawerWidth(FindRightMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindRightMiniDrawer()))) - .Build(); + internal void FireDrawersChanged() => StateHasChanged(); + + #endregion + + #region Content placeholders [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public RenderFragment ChildContent { get; set; } - internal void FireDrawersChanged() => StateHasChanged(); - - internal void Add(Drawer drawer) - { - if (Fixed && !drawer.Fixed) - return; - - _drawers.Add(drawer); - StateHasChanged(); - } - - internal void Remove(Drawer drawer) - { - _drawers.Remove(drawer); - StateHasChanged(); - } - private string GetDrawerClass(Drawer drawer) { if (drawer == null) @@ -65,22 +40,6 @@ public partial class DrawerContainer : UIComponent return className; } - private string GetDrawerWidth(Drawer drawer) - { - if (drawer == null) - return string.Empty; - - return drawer.Width; - } - - private string GetMiniDrawerWidth(Drawer drawer) - { - if (drawer == null) - return string.Empty; - - return drawer.MiniWidth; - } - private Drawer FindLeftDrawer() { var anchor = RightToLeft ? Anchor.End : Anchor.Start; @@ -104,4 +63,79 @@ public partial class DrawerContainer : UIComponent var anchor = RightToLeft ? Anchor.Start : Anchor.End; return _drawers.FirstOrDefault(d => d.Variant == DrawerVariant.Mini && (d.Anchor == anchor || d.Anchor == Anchor.Right)); } + + #endregion + + #region Styling properties + + protected virtual CssBuilder CompiledClassList + { + get + { + return new CssBuilder() + .AddClass(ClassList); + } + } + + /* + protected virtual string Classname => + new CssBuilder() + /*.AddClass(GetDrawerClass(FindLeftDrawer())) + .AddClass(GetDrawerClass(FindRightDrawer())) + .AddClass(ClassList) + .Build(); + + protected string Stylename => + new StyleBuilder() + .AddStyle(StyleList) + .AddStyle("--mud-drawer-width-left", GetDrawerWidth(FindLeftDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindLeftDrawer()))) + .AddStyle("--mud-drawer-width-right", GetDrawerWidth(FindRightDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindRightDrawer()))) + .AddStyle("--mud-drawer-width-mini-left", GetMiniDrawerWidth(FindLeftMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindLeftMiniDrawer()))) + .AddStyle("--mud-drawer-width-mini-right", GetMiniDrawerWidth(FindRightMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindRightMiniDrawer()))) + .Build();*/ + + protected StyleBuilder CompiledStyleList + { + get + { + return new StyleBuilder() + .AddStyle(StyleList); + //.AddStyle("width", Width, !string.IsNullOrWhiteSpace(Width) && !Fixed) + //.AddStyle("--mud-drawer-width", Width, !string.IsNullOrWhiteSpace(Width) && (!Fixed || Variant == DrawerVariant.Temporary)) + //.AddStyle("height", Height, !string.IsNullOrWhiteSpace(Height)) + //.AddStyle("--mud-drawer-content-height",string.IsNullOrWhiteSpace(Height) ? _height.ToPx() : Height,Anchor == Anchor.Bottom || Anchor == Anchor.Top) + //.AddStyle("visibility", "hidden", string.IsNullOrWhiteSpace(Height) && _height == 0 && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)); + + } + } + + /// + /// A space separated list of class names, added on top of the default class list. + /// + [Parameter] + public string? ClassList { get; set; } + + /// + /// A space separated list of class names, added on top of the default class list. + /// + [Parameter] + public string? StyleList { get; set; } + + #endregion + + + internal void Add(Drawer drawer) + { + if (Fixed && !drawer.Fixed) + return; + + _drawers.Add(drawer); + StateHasChanged(); + } + + internal void Remove(Drawer drawer) + { + _drawers.Remove(drawer); + StateHasChanged(); + } } diff --git a/src/Connected.Components/Components/Drawer/DrawerHeader.razor b/src/Connected.Components/Components/Drawer/DrawerHeader.razor index 7dadc9d..8586ab6 100644 --- a/src/Connected.Components/Components/Drawer/DrawerHeader.razor +++ b/src/Connected.Components/Components/Drawer/DrawerHeader.razor @@ -3,13 +3,13 @@ @if (LinkToIndex) { - + @ChildContent } else { -
+
@ChildContent
} diff --git a/src/Connected.Components/Components/Drawer/DrawerHeader.razor.cs b/src/Connected.Components/Components/Drawer/DrawerHeader.razor.cs index f600f53..58216f5 100644 --- a/src/Connected.Components/Components/Drawer/DrawerHeader.razor.cs +++ b/src/Connected.Components/Components/Drawer/DrawerHeader.razor.cs @@ -1,34 +1,58 @@ -using Connected.Annotations; -using Connected.Utilities; +using Connected.Utilities; using Microsoft.AspNetCore.Components; namespace Connected.Components; public partial class DrawerHeader : UIComponent { - protected string Classname => - new CssBuilder("drawer-header") - .AddClass($"drawer-header-dense", Dense) - .AddClass(AdditionalClassList) - .Build(); + #region Event callbacks + #endregion + + #region Content placeholders /// /// If true, compact padding will be used, same as the Appbar. /// [Parameter] - [Category(CategoryTypes.Drawer.Appearance)] public bool Dense { get; set; } /// /// Child content of component. /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public RenderFragment ChildContent { get; set; } /// /// If true, the component will link to index page with an a element instead of div. /// [Parameter] - [Category(CategoryTypes.Drawer.Behavior)] public bool LinkToIndex { get; set; } + + #endregion + + #region Styling properties + + /// + /// A space separated list of class names, added on top of the default class list. + /// + [Parameter] + public string? ClassList { get; set; } + + /// + /// A space separated list of class names, added on top of the default class list. + /// + [Parameter] + public string? StyleList { get; set; } + + #endregion + + protected virtual CssBuilder CompiledClassList + { + get + { + return new CssBuilder("drawer-header") + .AddClass($"drawer-header-dense", Dense) + .AddClass(ClassList); + } + } + } diff --git a/src/Connected.Components/Components/Layout/Layout.razor b/src/Connected.Components/Components/Layout/Layout.razor index b10b31c..40db62b 100644 --- a/src/Connected.Components/Components/Layout/Layout.razor +++ b/src/Connected.Components/Components/Layout/Layout.razor @@ -1,7 +1,7 @@ @namespace Connected.Components @inherits DrawerContainer -
+
@ChildContent diff --git a/src/Connected.Components/Components/Layout/Layout.razor.cs b/src/Connected.Components/Components/Layout/Layout.razor.cs index e9afeb6..917832b 100644 --- a/src/Connected.Components/Components/Layout/Layout.razor.cs +++ b/src/Connected.Components/Components/Layout/Layout.razor.cs @@ -1,13 +1,33 @@ using Connected.Utilities; +using System.Net; namespace Connected.Components; public partial class Layout : DrawerContainer { - protected override string Classname => - new CssBuilder("layout") - .AddClass(base.Classname) - .Build(); + protected virtual CssBuilder CompiledClassList + { + get + { + return new CssBuilder("layout") + .AddClass(base.ClassList); + } + } + + protected StyleBuilder CompiledStyleList + { + get + { + return new StyleBuilder() + .AddStyle(base.StyleList); + //.AddStyle("width", Width, !string.IsNullOrWhiteSpace(Width) && !Fixed) + //.AddStyle("--mud-drawer-width", Width, !string.IsNullOrWhiteSpace(Width) && (!Fixed || Variant == DrawerVariant.Temporary)) + //.AddStyle("height", Height, !string.IsNullOrWhiteSpace(Height)) + //.AddStyle("--mud-drawer-content-height",string.IsNullOrWhiteSpace(Height) ? _height.ToPx() : Height,Anchor == Anchor.Bottom || Anchor == Anchor.Top) + //.AddStyle("visibility", "hidden", string.IsNullOrWhiteSpace(Height) && _height == 0 && (Anchor == Anchor.Bottom || Anchor == Anchor.Top)); + + } + } public Layout() { diff --git a/src/Connected.Components/Navigation.cs b/src/Connected.Components/Navigation.cs new file mode 100644 index 0000000..2c5ec49 --- /dev/null +++ b/src/Connected.Components/Navigation.cs @@ -0,0 +1,119 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace Connected; +internal class Navigation +{ + private const int MaxPagesOnList = 256; + private readonly NavigationManager _navigationManager; + + [Inject] + private IJSRuntime JS { get; set; } + + private List _backPages; + private List _forwardPages; + + public Navigation(NavigationManager navigationManager) + { + _navigationManager = navigationManager; + _backPages = new List(); + _forwardPages = new List(); + } + + /// + /// Navigates to the specified url. + /// + /// The destination url (relative or absolute). + public async Task NavigateTo(string url, Target target=Target._self) + { + if (!target.Equals("_self")) + { + if (!url.Equals(_navigationManager.Uri)) + _backPages.Add(_navigationManager.Uri); + _navigationManager.NavigateTo(url); + } else + { + if (JS is not null) + await JS.InvokeVoidAsync("open", url, target.ToString()); + } + } + + /// + /// Returns true if it is possible to navigate to the previous url. + /// + private bool CanNavigateBack() + { + return (_backPages.Count > 1); + } + + private bool CanNavigateForward() + { + return (_forwardPages.Count > 1); + } + + private void UpdateBackPageList() + { + string url = _navigationManager.Uri; + _backPages.Add(url); + if (_backPages.Count() > MaxPagesOnList) + { + _backPages.RemoveAt(0); + } + } + + private string GetFromBackPageList() + { + string result = _backPages.Last(); + _backPages.RemoveAt(_backPages.Count()-1); + return result; + } + + private string GetFromForwardPageList() + { + string result = _forwardPages.Last(); + _forwardPages.RemoveAt(_forwardPages.Count() - 1); + return result; + } + + private void UpdateForwardPageList() + { + string url = _navigationManager.Uri; + _forwardPages.Add(url); + if (_forwardPages.Count() > MaxPagesOnList) + { + _forwardPages.RemoveAt(0); + } + } + + /// + /// Navigates to the previous url if possible or does nothing if it is not. + /// + public void Back() + { + if (!CanNavigateBack()) return; + var backPageUrl = GetFromBackPageList(); + UpdateForwardPageList(); + + NavigateTo(backPageUrl); + } + + /// + /// Navigates to the forward url if possible or does nothing if it is not. + /// + public void Forward() + { + if (!CanNavigateForward()) return; + var forwardPageUrl = GetFromForwardPageList(); + UpdateBackPageList(); + + NavigateTo(forwardPageUrl); + } +} + +enum Target +{ + _self, + _blank, + _parent, + _top +}