Skip to content

Commit 1645384

Browse files
committed
Reworked the sidenav example.
1. Updated to .NET 8 2. Fixed bug when routing with trailing slash. 3. Added AppBar to open/close UI
1 parent ffc2fd0 commit 1645384

26 files changed

+393
-413
lines changed

drawer/sidenav/App.razor

Lines changed: 0 additions & 9 deletions
This file was deleted.

drawer/sidenav/Components/App.razor

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<base href="/" />
8+
<link rel="stylesheet" href="_content/Telerik.UI.for.Blazor/css/kendo-theme-default/all.css" />
9+
<link rel="stylesheet" href="app.css" />
10+
<link rel="stylesheet" href="sidenav.styles.css" />
11+
<script src="_content/Telerik.UI.for.Blazor/js/telerik-blazor.js"></script>
12+
<HeadOutlet @rendermode="InteractiveServer" />
13+
</head>
14+
15+
<body class="k-m-0">
16+
<Routes @rendermode="InteractiveServer" />
17+
<script src="_framework/blazor.web.js"></script>
18+
</body>
19+
20+
</html>
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
@inherits LayoutComponentBase
2+
@inject NavigationManager _navMan
3+
4+
<style>
5+
/* the size of the containers will fill up their parents up to the viewport */
6+
html, body {
7+
width: 100%;
8+
height: 100%;
9+
max-height: 100%;
10+
}
11+
body {
12+
margin: 0;
13+
display: flex;
14+
flex-direction: column;
15+
}
16+
17+
/* vertical scroll should happen in the main portion of the content - where the Body is
18+
This keeps the header sticky at the top */
19+
.main {
20+
padding: var(--kendo-spacing-4, 1rem);
21+
overflow: auto;
22+
}
23+
24+
.k-drawer-container {
25+
flex:1;
26+
overflow:auto;
27+
}
28+
29+
/* horizontal scroll happens in the drawer content to keep the drawer on the left side of the screen */
30+
.k-drawer-content {
31+
height:100%;
32+
overflow-x: auto;
33+
}
34+
35+
</style>
36+
37+
<TelerikRootComponent>
38+
<TelerikAppBar ThemeColor="@(ThemeConstants.AppBar.ThemeColor.Tertiary)" >
39+
<AppBarSection>
40+
<TelerikButton FillMode="flat"
41+
Icon="@SvgIcon.Menu"
42+
OnClick="@(() => DrawerRef.ToggleAsync())"/>
43+
</AppBarSection>
44+
<AppBarSpacer Size="var(--kendo-spacing-1)" />
45+
<AppBarSection>
46+
<h1>ML Dashboard</h1>
47+
</AppBarSection>
48+
</TelerikAppBar>
49+
<TelerikDrawer Data="@NavigablePages"
50+
@bind-Expanded="@DrawerExpanded"
51+
MiniMode="true"
52+
Mode="@DrawerMode.Push"
53+
@ref="@DrawerRef"
54+
@bind-SelectedItem="@SelectedItem">
55+
<DrawerContent>
56+
@* This layout is now in the drawer Content, and is very similar to the default template layout *@
57+
<div class="main">
58+
@Body
59+
</div>
60+
</DrawerContent>
61+
</TelerikDrawer>
62+
63+
</TelerikRootComponent>
64+
65+
<div id="blazor-error-ui">
66+
An unhandled error has occurred.
67+
<a href="" class="reload">Reload</a>
68+
<a class="dismiss">🗙</a>
69+
</div>
70+
71+
@code {
72+
bool DrawerExpanded { get; set; } = true; // drawer expanded by default
73+
DrawerItem SelectedItem { get; set; } = DrawerItem.None(); // set in OnInitialized
74+
TelerikDrawer<DrawerItem> DrawerRef { get; set; } = default!; // set by framework
75+
76+
// in this sample we hardcode the existing pages, in your case you can
77+
// create the list based on your business logic (e.g., based on user roles/access)
78+
List<DrawerItem> NavigablePages { get; set; } = new List<DrawerItem>
79+
{
80+
new DrawerItem { Text = "Home", Url = "/", Icon = SvgIcon.Home.Name },
81+
new DrawerItem { Separator = true },
82+
new DrawerItem { Text = "Counter", Url = "counter", Icon = SvgIcon.Plus.Name },
83+
new DrawerItem { Text = "Weather", Url = "weather", Icon = SvgIcon.Cloud.Name },
84+
};
85+
86+
protected override void OnInitialized()
87+
{
88+
// pre-select the page the user lands on
89+
// as the user clicks items, the DOM changes only in the Body and so the selected item stays active
90+
SelectedItem = NavigablePages.Where(hasUrlEqualToPageRoute).FirstOrDefault(DrawerItem.None());
91+
92+
base.OnInitialized();
93+
}
94+
95+
bool hasUrlEqualToPageRoute(DrawerItem item) {
96+
if(item.Url is null) return false;
97+
98+
string navItemAsAbsoluteUri = _navMan.ToAbsoluteUri(item.Url).AbsoluteUri;
99+
if (string.Equals(_navMan.Uri, navItemAsAbsoluteUri, StringComparison.OrdinalIgnoreCase))
100+
{
101+
return true;
102+
}
103+
// Special case: highlight links to http://host/path/ even if you're
104+
// at http://host/path (with no trailing slash)
105+
//
106+
// This is because the router accepts an absolute URI value of "same
107+
// as base URI but without trailing slash" as equivalent to "base URI",
108+
// which in turn is because it's common for servers to return the same page
109+
// for http://host/vdir as they do for host://host/vdir/ as it's no
110+
// good to display a blank page in that case.
111+
bool isNotRoot = item.Url != "/";
112+
bool hasTrailingSlash = _navMan.Uri[_navMan.Uri.Length - 1] == '/';
113+
if(isNotRoot && hasTrailingSlash &&
114+
_navMan.Uri.StartsWith(navItemAsAbsoluteUri, StringComparison.OrdinalIgnoreCase))
115+
{
116+
return true;
117+
}
118+
return false;
119+
}
120+
121+
// generally, this should go into its own file, but it is here to keep all the drawer-related code in one place
122+
public class DrawerItem
123+
{
124+
public string Text { get; set; } = "";
125+
public string? Url { get; set; }
126+
public string? Icon { get; set; }
127+
public bool Separator { get; set; }
128+
public static DrawerItem None() => new();
129+
}
130+
}
131+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#blazor-error-ui {
2+
background: lightyellow;
3+
bottom: 0;
4+
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
5+
display: none;
6+
left: 0;
7+
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
8+
position: fixed;
9+
width: 100%;
10+
z-index: 1000;
11+
}
12+
13+
#blazor-error-ui .dismiss {
14+
cursor: pointer;
15+
position: absolute;
16+
right: 0.75rem;
17+
top: 0.5rem;
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@page "/counter"
2+
<PageTitle>Counter</PageTitle>
3+
4+
<h1>Counter</h1>
5+
6+
<p>Current count: @currentCount</p>
7+
8+
<TelerikButton ThemeColor="@(ThemeConstants.Button.ThemeColor.Primary)"
9+
Icon="SvgIcon.PlusCircle"
10+
OnClick="IncrementCount">Click me</TelerikButton>
11+
12+
@code {
13+
int currentCount = 0;
14+
15+
void IncrementCount()
16+
{
17+
currentCount++;
18+
}
19+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@page "/Error"
2+
@using System.Diagnostics
3+
4+
<PageTitle>Error</PageTitle>
5+
6+
<h1 class="text-danger">Error.</h1>
7+
<h2 class="text-danger">An error occurred while processing your request.</h2>
8+
9+
@if (ShowRequestId)
10+
{
11+
<p>
12+
<strong>Request ID:</strong> <code>@RequestId</code>
13+
</p>
14+
}
15+
16+
<h3>Development Mode</h3>
17+
<p>
18+
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
19+
</p>
20+
<p>
21+
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
22+
It can result in displaying sensitive information from exceptions to end users.
23+
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
24+
and restarting the app.
25+
</p>
26+
27+
@code{
28+
[CascadingParameter]
29+
private HttpContext? HttpContext { get; set; }
30+
31+
private string? RequestId { get; set; }
32+
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
33+
34+
protected override void OnInitialized() =>
35+
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
36+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@page "/"
2+
3+
<PageTitle>Home</PageTitle>
4+
5+
<h1>Hello, world!</h1>
6+
7+
Welcome to your new app.
8+
<div style="height: 2000px; width: 2000px; background: yellow;">
9+
<p>This box represents content that overflows the page.</p>
10+
<p>Scroll on the X & Y axis, notice the navigation is sticky.</p>
11+
</div>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
@page "/counter/weather"
2+
3+
<PageTitle>Weather</PageTitle>
4+
5+
<h1>Weather</h1>
6+
7+
<p>This component demonstrates showing data.</p>
8+
9+
<TelerikGrid Data="forecasts" AutoGenerateColumns="true"/>
10+
11+
@code {
12+
private WeatherForecast[]? forecasts;
13+
14+
protected override void OnInitialized()
15+
{
16+
17+
var startDate = DateOnly.FromDateTime(DateTime.Now);
18+
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
19+
forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
20+
{
21+
Date = startDate.AddDays(index),
22+
TemperatureC = Random.Shared.Next(-20, 55),
23+
Summary = summaries[Random.Shared.Next(summaries.Length)]
24+
}).ToArray();
25+
}
26+
27+
private class WeatherForecast
28+
{
29+
public DateOnly Date { get; set; }
30+
public int TemperatureC { get; set; }
31+
public string? Summary { get; set; }
32+
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
33+
}
34+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Router AppAssembly="typeof(Program).Assembly">
2+
<Found Context="routeData">
3+
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
4+
<FocusOnNavigate RouteData="routeData" Selector="h1" />
5+
</Found>
6+
</Router>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
@using System.Net.Http
2+
@using System.Net.Http.Json
3+
@using Microsoft.AspNetCore.Components.Forms
4+
@using Microsoft.AspNetCore.Components.Routing
5+
@using Microsoft.AspNetCore.Components.Web
6+
@using static Microsoft.AspNetCore.Components.Web.RenderMode
7+
@using Microsoft.AspNetCore.Components.Web.Virtualization
8+
@using Microsoft.JSInterop
9+
@using sidenav
10+
@using sidenav.Components
11+
@using Telerik.Blazor
12+
@using Telerik.Blazor.Components
13+
@using Telerik.SvgIcons
14+
@using Telerik.FontIcons

drawer/sidenav/Data/WeatherForecast.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

drawer/sidenav/Data/WeatherForecastService.cs

Lines changed: 0 additions & 25 deletions
This file was deleted.

drawer/sidenav/Pages/Counter.razor

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)