Drawer, DrwerContainer, DrawerHeader - rework

features/nuget_autobuild
stm 2 years ago
parent d042b55ac6
commit 63a84810f5

@ -3,7 +3,7 @@
"isRoot": true, "isRoot": true,
"tools": { "tools": {
"excubo.webcompiler": { "excubo.webcompiler": {
"version": "3.5.0", "version": "3.5.10",
"commands": [ "commands": [
"webcompiler" "webcompiler"
] ]

@ -1,11 +1,25 @@
@namespace Connected.Components @namespace Connected.Components
@inherits UIComponent @inherits UIComponent
<aside @onmouseenter="OnMouseEnter" @onmouseleave="OnMouseLeave" @attributes="CustomAttributes" class="@Classname" style="@Stylename"> <p>@_screenBreakpoint.ToString()</p>
@if (_screenBreakpoint.ToString().ToLower() != "xs")
{
<p>Drawer</p>
<aside @onmouseenter="OnMouseEnter" @onmouseleave="OnMouseLeave" @attributes="CustomAttributes" class="@CompiledClassList.Build()" style="@CompiledStyleList.Build()">
<div @ref="_contentRef" class="drawer-content"> <div @ref="_contentRef" class="drawer-content">
<CascadingValue Value="this" IsFixed="true"> <CascadingValue Value="this" IsFixed="true">
@ChildContent @ChildContent
</CascadingValue> </CascadingValue>
</div> </div>
</aside>
<Overlay Visible="@OverlayVisible" OnClick="@CloseDrawer" Class="@OverlayClass" DarkBackground="true" LockScroll=false /> </aside>
<Overlay Visible="@OverlayVisible" OnClick="@CloseDrawer" Class="@CompiledOverlayClass.Build()" DarkBackground="true" LockScroll=false />
} else {
<p>Tabs</p>
<Tabs>
<CascadingValue Value="this" IsFixed="true">
@ChildContent
</CascadingValue>
</Tabs>
}

@ -3,6 +3,7 @@ using Connected.Extensions;
using Connected.Services; using Connected.Services;
using Connected.Utilities; using Connected.Utilities;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using System.ComponentModel;
namespace Connected.Components; namespace Connected.Components;
@ -12,54 +13,192 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver
private ElementReference _contentRef; private ElementReference _contentRef;
private DrawerClipMode _clipMode; private DrawerClipMode _clipMode;
private bool? _isOpenWhenLarge = null; private bool? _isOpenWhenLarge = null;
private bool _open, _rtl, _isRendered, _initial = true, _keepInitialState, _fixed = true; private bool _open;
private Breakpoint _breakpoint = Breakpoint.Md, _screenBreakpoint = Breakpoint.None; 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 Guid _breakpointListenerSubscriptionId;
private bool OverlayVisible => _open && !DisableOverlay && #region EventCallbacks
(Variant == DrawerVariant.Temporary ||
(_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Mini) ||
(_screenBreakpoint < Breakpoint && Variant == DrawerVariant.Responsive));
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<bool> 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
/// <summary>
/// Child content of component.
/// </summary>
[Parameter]
public RenderFragment ChildContent { get; set; }
[CascadingParameter] DrawerContainer DrawerContainer { get; set; } [CascadingParameter] DrawerContainer DrawerContainer { get; set; }
[Inject] public IBreakpointService Breakpointistener { get; set; }
[CascadingParameter(Name = "RightToLeft")] [CascadingParameter(Name = "RightToLeft")]
bool 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);
}
}
/// <summary>
/// A space separated list of class names, added on top of the default class list.
/// </summary>
[Parameter]
public string? ClassList { get; set; }
/// <summary>
/// A space separated list of class names, added on top of the default class list.
/// </summary>
[Parameter]
public string? StyleList { get; set; }
/// <summary> /// <summary>
/// If true, drawer position will be fixed. (CSS position: fixed;) /// If true, drawer position will be fixed. (CSS position: fixed;)
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public bool Fixed public bool Fixed
{ {
get => _fixed && DrawerContainer is Layout; 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. /// The higher the number, the heavier the drop-shadow. 0 for no shadow.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Appearance)]
public int Elevation { set; get; } = 1; public int Elevation { set; get; } = 1;
/// <summary> /// <summary>
/// Side from which the drawer will appear. /// Side from which the drawer will appear.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public Anchor Anchor { get; set; } = Anchor.Start; public Anchor Anchor { get; set; } = Anchor.Start;
/*
/// <summary> /// <summary>
/// The color of the component. It supports the theme colors. /// The color of the component. It supports the theme colors.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Appearance)]
public ThemeColor Color { get; set; } = ThemeColor.Default; public ThemeColor Color { get; set; } = ThemeColor.Default;
*/
/// <summary> /// <summary>
/// Variant of the drawer. It specifies how the drawer will be displayed. /// Variant of the drawer. It specifies how the drawer will be displayed.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public DrawerVariant Variant { get; set; } = DrawerVariant.Responsive; public DrawerVariant Variant { get; set; } = DrawerVariant.Responsive;
/// <summary>
/// Child content of component.
/// </summary>
[Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public RenderFragment ChildContent { get; set; }
/// <summary> /// <summary>
/// Show overlay for responsive and temporary drawers. /// Show overlay for responsive and temporary drawers.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public bool DisableOverlay { get; set; } = false; public bool DisableOverlay { get; set; } = false;
/// <summary> /// <summary>
/// Preserve open state for responsive drawer when window resized above <see cref="Breakpoint" />. /// Preserve open state for responsive drawer when window resized above <see cref="Breakpoint" />.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public bool PreserveOpenState { get; set; } = false; public bool PreserveOpenState { get; set; } = false;
/// <summary> /// <summary>
/// Open drawer automatically on mouse enter when <see cref="Variant" /> parameter is set to <see cref="DrawerVariant.Mini" />. /// Open drawer automatically on mouse enter when <see cref="Variant" /> parameter is set to <see cref="DrawerVariant.Mini" />.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public bool OpenMiniOnHover { get; set; } public bool OpenMiniOnHover { get; set; }
/// <summary>
/// Specify how the drawer should behave inside a MudLayout. It affects the position relative to <b>MudAppbar</b>
/// </summary>
[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));
/// <summary> /// <summary>
/// Switching point for responsive drawers /// Switching point for responsive drawers
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public Breakpoint Breakpoint public Breakpoint Breakpoint
{ {
get => _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. /// Sets the opened state on the drawer. Can be used with two-way binding to close itself on navigation.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public bool Open public bool Open
{ {
get => _open; get => _open;
@ -192,121 +407,15 @@ public partial class Drawer : UIComponent, IDisposable, INavigationEventReceiver
{ {
_keepInitialState = false; _keepInitialState = false;
} }
if (_isRendered && value && (Anchor == Anchor.Top || Anchor == Anchor.Bottom)) /*if (_isRendered && value && (Anchor == Anchor.Top || Anchor == Anchor.Bottom))
{ {
_ = UpdateHeight(); _ = UpdateHeight();
} }*/
DrawerContainer?.FireDrawersChanged(); DrawerContainer?.FireDrawersChanged();
OpenChanged.InvokeAsync(_open); OpenChanged.InvokeAsync(_open);
} }
} }
[Parameter] public EventCallback<bool> OpenChanged { get; set; }
/// <summary>
/// Width of left/right drawer. Only for non-fixed drawers.
/// </summary>
[Parameter]
[Category(CategoryTypes.Drawer.Appearance)]
public string Width { get; set; }
/// <summary>
/// Width of left/right drawer. Only for non-fixed drawers.
/// </summary>
[Parameter]
[Category(CategoryTypes.Drawer.Appearance)]
public string MiniWidth { get; set; }
/// <summary>
/// Height of top/bottom temporary drawer
/// </summary>
[Parameter]
[Category(CategoryTypes.Drawer.Appearance)]
public string Height { get; set; }
/// <summary>
/// Specify how the drawer should behave inside a MudLayout. It affects the position relative to <b>MudAppbar</b>
/// </summary>
[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() private void CloseDrawer()
{ {
if (Open) 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)) #endregion
{
_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;
}
}
_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);
}
}
} }

@ -1,7 +1,7 @@
@namespace Connected.Components @namespace Connected.Components
@inherits UIComponent @inherits UIComponent
<div @attributes="CustomAttributes" style="@Stylename" class="@Classname"> <div @attributes="CustomAttributes" style="@CompiledStyleList.Build()" class="@CompiledClassList.Build()">
<CascadingValue Value="this" IsFixed="true"> <CascadingValue Value="this" IsFixed="true">
@ChildContent @ChildContent
</CascadingValue> </CascadingValue>

@ -10,44 +10,19 @@ public partial class DrawerContainer : UIComponent
protected bool Fixed { get; set; } = false; protected bool Fixed { get; set; } = false;
private List<Drawer> _drawers = new(); private List<Drawer> _drawers = new();
protected virtual string Classname => #region Event callbacks
new CssBuilder()
.AddClass(GetDrawerClass(FindLeftDrawer()))
.AddClass(GetDrawerClass(FindRightDrawer()))
.AddClass(AdditionalClassList)
.Build();
protected string Stylename => internal void FireDrawersChanged() => StateHasChanged();
new StyleBuilder()
.AddStyle("--mud-drawer-width-left", GetDrawerWidth(FindLeftDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindLeftDrawer()))) #endregion
.AddStyle("--mud-drawer-width-right", GetDrawerWidth(FindRightDrawer()), !string.IsNullOrEmpty(GetDrawerWidth(FindRightDrawer())))
.AddStyle("--mud-drawer-width-mini-left", GetMiniDrawerWidth(FindLeftMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindLeftMiniDrawer()))) #region Content placeholders
.AddStyle("--mud-drawer-width-mini-right", GetMiniDrawerWidth(FindRightMiniDrawer()), !string.IsNullOrEmpty(GetMiniDrawerWidth(FindRightMiniDrawer())))
.Build();
[CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; } [CascadingParameter(Name = "RightToLeft")] public bool RightToLeft { get; set; }
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public RenderFragment ChildContent { get; set; } 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) private string GetDrawerClass(Drawer drawer)
{ {
if (drawer == null) if (drawer == null)
@ -65,22 +40,6 @@ public partial class DrawerContainer : UIComponent
return className; 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() private Drawer FindLeftDrawer()
{ {
var anchor = RightToLeft ? Anchor.End : Anchor.Start; var anchor = RightToLeft ? Anchor.End : Anchor.Start;
@ -104,4 +63,79 @@ public partial class DrawerContainer : UIComponent
var anchor = RightToLeft ? Anchor.Start : Anchor.End; var anchor = RightToLeft ? Anchor.Start : Anchor.End;
return _drawers.FirstOrDefault(d => d.Variant == DrawerVariant.Mini && (d.Anchor == anchor || d.Anchor == Anchor.Right)); 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));
}
}
/// <summary>
/// A space separated list of class names, added on top of the default class list.
/// </summary>
[Parameter]
public string? ClassList { get; set; }
/// <summary>
/// A space separated list of class names, added on top of the default class list.
/// </summary>
[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();
}
} }

@ -3,13 +3,13 @@
@if (LinkToIndex) @if (LinkToIndex)
{ {
<a @attributes="CustomAttributes" class="@Classname" href="/"> <a @attributes="CustomAttributes" class="@CompiledClassList.Build()" href="/">
@ChildContent @ChildContent
</a> </a>
} }
else else
{ {
<div @attributes="CustomAttributes" class="@Classname"> <div @attributes="CustomAttributes" class="@CompiledClassList.Build()">
@ChildContent @ChildContent
</div> </div>
} }

@ -1,34 +1,58 @@
using Connected.Annotations; using Connected.Utilities;
using Connected.Utilities;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace Connected.Components; namespace Connected.Components;
public partial class DrawerHeader : UIComponent public partial class DrawerHeader : UIComponent
{ {
protected string Classname => #region Event callbacks
new CssBuilder("drawer-header") #endregion
.AddClass($"drawer-header-dense", Dense)
.AddClass(AdditionalClassList) #region Content placeholders
.Build();
/// <summary> /// <summary>
/// If true, compact padding will be used, same as the Appbar. /// If true, compact padding will be used, same as the Appbar.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Appearance)]
public bool Dense { get; set; } public bool Dense { get; set; }
/// <summary> /// <summary>
/// Child content of component. /// Child content of component.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; }
/// <summary> /// <summary>
/// If true, the component will link to index page with an a element instead of div. /// If true, the component will link to index page with an a element instead of div.
/// </summary> /// </summary>
[Parameter] [Parameter]
[Category(CategoryTypes.Drawer.Behavior)]
public bool LinkToIndex { get; set; } public bool LinkToIndex { get; set; }
#endregion
#region Styling properties
/// <summary>
/// A space separated list of class names, added on top of the default class list.
/// </summary>
[Parameter]
public string? ClassList { get; set; }
/// <summary>
/// A space separated list of class names, added on top of the default class list.
/// </summary>
[Parameter]
public string? StyleList { get; set; }
#endregion
protected virtual CssBuilder CompiledClassList
{
get
{
return new CssBuilder("drawer-header")
.AddClass($"drawer-header-dense", Dense)
.AddClass(ClassList);
}
}
} }

@ -1,7 +1,7 @@
@namespace Connected.Components @namespace Connected.Components
@inherits DrawerContainer @inherits DrawerContainer
<div @attributes="CustomAttributes" class="@Classname" style="@Stylename"> <div @attributes="CustomAttributes" class="@CompiledClassList.Build()" style="@CompiledStyleList.Build()">
<CascadingValue IsFixed="true" Value="@this"> <CascadingValue IsFixed="true" Value="@this">
@ChildContent @ChildContent
</CascadingValue> </CascadingValue>

@ -1,13 +1,33 @@
using Connected.Utilities; using Connected.Utilities;
using System.Net;
namespace Connected.Components; namespace Connected.Components;
public partial class Layout : DrawerContainer public partial class Layout : DrawerContainer
{ {
protected override string Classname => protected virtual CssBuilder CompiledClassList
new CssBuilder("layout") {
.AddClass(base.Classname) get
.Build(); {
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() public Layout()
{ {

@ -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<string> _backPages;
private List<string> _forwardPages;
public Navigation(NavigationManager navigationManager)
{
_navigationManager = navigationManager;
_backPages = new List<string>();
_forwardPages = new List<string>();
}
/// <summary>
/// Navigates to the specified url.
/// </summary>
/// <param name="url">The destination url (relative or absolute).</param>
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());
}
}
/// <summary>
/// Returns true if it is possible to navigate to the previous url.
/// </summary>
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);
}
}
/// <summary>
/// Navigates to the previous url if possible or does nothing if it is not.
/// </summary>
public void Back()
{
if (!CanNavigateBack()) return;
var backPageUrl = GetFromBackPageList();
UpdateForwardPageList();
NavigateTo(backPageUrl);
}
/// <summary>
/// Navigates to the forward url if possible or does nothing if it is not.
/// </summary>
public void Forward()
{
if (!CanNavigateForward()) return;
var forwardPageUrl = GetFromForwardPageList();
UpdateBackPageList();
NavigateTo(forwardPageUrl);
}
}
enum Target
{
_self,
_blank,
_parent,
_top
}
Loading…
Cancel
Save