Collapsible Menu (MatBlazor + Telerik)

3 posts, 0 answers
  1. James
    James avatar
    3 posts
    Member since:
    Aug 2019

    Posted 12 Sep 2019 Link to this post

    Hey guys, here is my MainLayout.razor page.

    The idea here is to have a side bar nav menu, which can be collapsed to give the user more screen real estate.

    I am using MatBlazors app bar and drawer components to have the "collapsing" feature. And then using the Telerik Menu with some custom styling to incorporate the nav links. 

    @inherits LayoutComponentBase
    
    @using Telerik.Blazor.Components.RootComponent
    @using MatBlazor;
    @using Telerik.Blazor.Components.Menu;
    @inject NavigationManager navigationManager
    @inject Blazored.LocalStorage.ILocalStorageService localStorage
    @using Newtonsoft.Json;
    @using System.Threading.Tasks;
    
    <head>
        <style>
            span.k-in.k-menu-link {
                display: flex;
            }
    
            .mdc-top-app-bar__row  {
                display:  flex;
                position:  relative;
                box-sizing:  border-box;
                width:  100%;
                height:  32px !important;
                background-color: #fafafa !important;
                top: 0px;
                position: fixed;
            }
    
            .mdc-top-app-bar--fixed-adjust {
                padding-top: 40px !important;
            }
    
    
            .mdc-drawer {
                z-index: 1;
                box-shadow: -4px 1px 14px 0px black !important;
            }
    
    
    
            /*MOBILE*/
            @@media (min-width: 320px) {
                .mdc-drawer__content {
                    overflow-y: auto;
                    -webkit-overflow-scrolling: touch;
                    margin-top: 8px;
                    background: #fafafa !important;
                    height: 88vh;
                }
    
                .mdc-drawer.mdc-drawer--open:not(.mdc-drawer--closing) + .mdc-drawer-app-content {
                    margin-left: 170px;
                    margin-right: 0;
                }
    
                .mdc-drawer {
                    width: 170px !important;
                }
    
                .Banner {
                    width: 100%;
                    background-color: #3f9d2f !important;
                    height: 110px;
                    margin-top: -2px;
                    box-shadow: -2px -7px 15px 7px black;
                    padding: 10px;
                }
    
                .UserIcon {
                    font-size: 50px !important;
                    color: #FFFFFF;
                    margin-left: 39%  !important;
                    cursor: pointer;
                    margin-top: -7px;
                }
    
                .WideScreenClass {
                    display: none;
                }
    
                .MobileClass{
                    display:block;
                }
    
                .BannerUsernameHeading{
                margin: auto;
                color: #FFFFFF;
                text-align: center;
                font-weight: 500;
                font-size:30px !important;
                        }
    
                .BannerCompanyNameHeading{
                    margin: auto;
                    color: #FFFFFF;
                    text-align: center;
                    font-size:15px !important;
                    margin-top: -9px;
                }
    
                .k-menu-group .k-item > .k-link, .k-menu-vertical .k-item > .k-link {
                color: black !important;
                margin-bottom: 2px !important;
                margin-top: 2px !important;
                line-height: 1.6 !important;
                font-family: Roboto !important;
                font-variant: all-petite-caps !important;
                font-size: larger !important;
            }
    
    
            }
    
    
    
    
    
    
            /*WIDE SCREEN*/
            @@media (min-width: 1280px) {
                .mdc-drawer__content {
                    height: 100%;
                    overflow-y: auto;
                    -webkit-overflow-scrolling: touch;
                    margin-top: 48px;
                    background: #fafafa !important;
                }
    
                .mdc-drawer.mdc-drawer--open:not(.mdc-drawer--closing) + .mdc-drawer-app-content {
                    margin-left: 256px;
                    margin-right: 0;
                }
    
                .mdc-drawer {
                    width: 256px !important;
                }
    
    
                .Banner {
                    width: 100%;
                    background-color: #3f9d2f !important;
                    height: 175px;
                    margin-top: -2px;
                    box-shadow: -2px -7px 15px 7px black;
                    padding: 10px;
                }
    
                .UserIcon {
                    font-size: 64px  !important;
                    color: #FFFFFF;
                    margin-left: 36%  !important;
                    cursor: pointer;
                }
    
                .main > div {
                    padding-left: 2rem !important;
                    padding-right: 1.5rem !important;
                    margin-top: 48px;
                }
    
                .MobileClass {
                    display: none;
                }
    
                .WideScreenClass{
                    display:block;
                }
    
                .BannerUsernameHeading{
                margin: auto;
                color: #FFFFFF;
                text-align: center;
                font-weight: 500;
                font-size:42px !important;
                        }
    
                .BannerCompanyNameHeading{
                    margin: auto;
                    color: #FFFFFF;
                    text-align: center;
                    font-size:18px !important;
                }
    
                .k-menu-group .k-item > .k-link, .k-menu-vertical .k-item > .k-link {
                color: black !important;
                margin-bottom: 2px !important;
                margin-top: 2px !important;
                line-height: 2 !important;
                font-family: Roboto !important;
                font-variant: all-petite-caps !important;
                font-size: larger !important;
            }
    
            }
    
    
    
    
    
    
    
    
            :not(.mdc-list--non-interactive) > :not(.mdc-list-item--disabled).mdc-list-item { /*material chips*/
                color: black;
            }
    
            .mdc-drawer .mdc-list-item { /*make text in side menu black*/
                color: black;
            }
    
            .Title {
                padding-left: 20%;
            }
    
            .mat-accordion .mat-expansion-panel__summary .after {
                color: black;
            }
    
            .mat-accordion .mdc-nav-menu .mat-expansion-panel__content .mdc-list-item {
                font-weight: 500;
            }
    
            div#matBlazor_id_8e6ee3bc-7b6e-41e2-854a-b965730195b1 {
                overflow: hidden;
            }
    
            div#matBlazor_id_e44a318f-9585-474c-9dca-8576f4594719 {
                overflow: hidden;
            }
    
            div#matBlazor_id_d3b57f8a-30d5-4bf2-894e-2527d97e6529 {
                overflow-y: hidden;
            }
    
            .material-icons {
                font-size: 56px;
                color: white;
            }
    
            .LogoutButton {
                width: 100% !important;
                background: #3f9d2f !important;
                border-radius: 25px;
                color: white;
                height: 50px;
            }
    
            .mdc-chip {
                background-color: #3f9d2f !important;
                color: rgb(255, 255, 255) !important;
            }
    
            .AnimationDiv {
                transition-property: all;
                transition-property: transform;
                transition-duration: 0.3s;
            }
        </style>
    
        <style>
            a { /*make links a certain way*/
                font-weight: 500 !important;
                color: black !important;
                line-height: 2 !important;
                font-variant: all-small-caps !important;
                font-family: Roboto !important;
                padding: 10px !important;
                font-size: larger !important;
            }
        </style>
    
    </head>
    
    
    
    <TelerikRootComponent>
        <MatAppBarContainer>
            <MatAppBar Fixed="false" Style="height:48px; background-color:#3f9d2f  !important; color:#FFFFFF !important;">
                <MatAppBarRow Style="height:48px; ">
                    <MatAppBarSection>
    
                        @if (Opened == true)
                        {
                            <div>
                                <MatIconButton OnClick="@((e) => ButtonClicked())"> <span class="fas fa-grip-lines"></span></MatIconButton>
                            </div>
                        }
                        else
                        {
                            <div>
                                <MatIconButton OnClick="@((e) => ButtonClicked())"> <span class="fas fa-grip-lines-vertical"></span></MatIconButton>
                            </div>
                        }
                        <MatAppBarTitle>
                            @ModuleName
                        </MatAppBarTitle>
                    </MatAppBarSection>
                </MatAppBarRow>
            </MatAppBar>
            <MatAppBarContent>
            </MatAppBarContent>
        </MatAppBarContainer>
    
        <MatDrawerContainer Style="width:100%; overflow-y:hidden; min-height:100vh">
            <MatDrawer @bind-Opened="@Opened" Mode="@MatDrawerMode.Dismissible">
                <div class="Banner">
                    <div>
                        <i class="fas fa-user-circle UserIcon"></i>
                        <MatH3 Class="BannerUsernameHeading">@Username</MatH3>
                        <MatH6 Class="BannerCompanyNameHeading">Company</MatH6>
                    </div>
                </div>
                <div class="WideScreenClass">
                    <br />
                    <br />
                    <TelerikMenu Data="@MenuItems" Orientation="Telerik.Blazor.MenuOrientation.Vertical"
                                 UrlField="@nameof(MenuItem.Page)"
                                 ItemsField="@nameof(MenuItem.SubSectionList)"
                                 TextField="@nameof(MenuItem.Section)"
                                 OnClick="@((MenuItem item) => OnClickHandler(item))">
    
                        <ItemTemplate Context="item">
                            @{
                                if (item.Section == "Site Access")
                                {
                                    <NavLink href="@item.Page">@item.Section</NavLink> <br />
                                    <MatChipSet>
                                        <MatChip Label="5"></MatChip>
                                    </MatChipSet>
                                }
                                else
                                {
                                    <NavLink href="@item.Page">@item.Section</NavLink> <br />
                                }
    
                            }
                        </ItemTemplate>
                    </TelerikMenu>
                    <div style="position:absolute; bottom:10px; width:100%; padding:10px;">
    
                        <img src="/images/CompanyLogo.png" style="width:200px; margin:auto; margin-left: 20px;" />
                        <br />
    
                        <Telerik.Blazor.Components.Button.TelerikButton Class="LogoutButton" OnClick="Logout">
                            LOGOUT
                        </Telerik.Blazor.Components.Button.TelerikButton>
    
                    </div>
                </div>
    
                <div class="MobileClass">
                    <TelerikMenu Data="@MobileMenuItems" Orientation="Telerik.Blazor.MenuOrientation.Vertical"
                                 UrlField="@nameof(MenuItem.Page)"
                                 ItemsField="@nameof(MenuItem.SubSectionList)"
                                 TextField="@nameof(MenuItem.Section)"
                                 OnClick="@((MenuItem item) => OnClickHandler(item))">
    
    
    
                    </TelerikMenu>
                </div>
            </MatDrawer>
            <MatDrawerContent Style="overflow-y:hidden;">
                <div class="main">
                    <div class="content px-4">
                        @Body
                    </div>
                </div>
            </MatDrawerContent>
    
        </MatDrawerContainer>
    </TelerikRootComponent>
    
    @code {
    
    
        public MenuItem ClickedItem { get; set; }
    
        protected void OnClickHandler(MenuItem item)
        {
            ClickedItem = item;
            ModuleName = item.Section.ToString();
            Console.WriteLine("Telerik menu item: " + item.Section.ToString());
            Opened = !Opened;
        }
    
        
        public List<MenuItem> MenuItems { get; set; }
    
        public class MenuItem
        {
            public string Section { get; set; }
            public string Page { get; set; }
            public List<MenuItem> SubSectionList { get; set; }
        }
    
        public List<MenuItem> MobileMenuItems { get; set; }
    
        protected override void OnInitialized()
        {
            MenuItems = new List<MenuItem>()
    {
                        new MenuItem()
                        {
                            Section = "Dashboard",
                            Page = "dashboard"
                        },
                        new MenuItem()
                        {
                            Section = "Site Access",
                            Page = "siteaccess"
                        },
                        new MenuItem()
                        {
                            Section = "History",
                            Page = "history"
                        },
                        new MenuItem()
                        {
                            Section = "Reports",
                            Page = "reports"
                        },
                        new MenuItem()
                        {
                            Section = "Settings",
                            Page = "settings"
                        },
                        new MenuItem()
                        {
                            Section = "Users",
                            Page = "users"
                        },
                        new MenuItem()
                        {
                            Section = "Vehicles",
                            Page = "vehicles"
                        },
                        new MenuItem()
                        {
                            Section = "Drivers",
                            Page = "drivers"
                        }
                    };
    
            MobileMenuItems = new List<MenuItem>()
            {
                    new MenuItem()
                    {
                        Section = "Dashboard",
                        Page = "dashboard"
                    },
                    new MenuItem()
                    {
                        Section = "Access Manager",
                        Page = "accessmanager"
                    },
                    new MenuItem()
                    {
                        Section = "Yard Manager",
                        Page = "yardmanager"
                    },
                    new MenuItem()
                    {
                        Section = "Vehicle Registration",
                        Page = "vehicleregistration"
                    },
                    new MenuItem()
                    {
                        Section = "LOGOUT",
                        Page = "/"
                    },
            };
    
    
        base.OnInitialized();
        }
     public void Logout()
        {
            UriHelper.NavigateTo("/");
        }
    
    
        public string ModuleName { get; set; } = "";
    
        bool Opened = true;
    
        string Name = "";
    
        public async Task GoToUsers()
        {
            ModuleName = "USERS";
            UriHelper.NavigateTo("/user");
        }
    
        public async Task CloseMenu(string name) //this method will close the menu, and set the page name as the module name at the top of the app bar
        {
            ModuleName = "";
            await Task.Delay(20);
            Opened = !Opened;
            await Task.Delay(20);
            ModuleName = name;
        }
    
        void ButtonClicked()
        {
            Opened = !Opened;
        }
    
        public string UserName { get; set; }
        public string UserID { get; set; }
    
        protected override async Task OnInitializedAsync()
        {
            
           
            UserID = await localStorage.GetItemAsync<string>("userID");
    
            ModuleName = "DASHBOARD";
           
            Username = await localStorage.GetItemAsync<string>("userName");
    
        }
    
        public string Username { get; set; }
        Modules modules = new Modules();
        GeneralConfiguration generalConfiguration = new GeneralConfiguration();
    
    }

  2. James
    James avatar
    3 posts
    Member since:
    Aug 2019

    Posted 12 Sep 2019 in reply to James Link to this post

    Oh, some more information, this is a responsive page. Meaning, I've included some media screen size breakpoints in CSS, that will basically just render some of the components a different way to show correctly on a small screen (320x420) 
  3. Marin Bratanov
    Admin
    Marin Bratanov avatar
    5063 posts

    Posted 12 Sep 2019 Link to this post

    Thank you for sharing your code, experience and solution with the community, James. You will find your Telerik points updated as a small "thank you".

     

    Regards,
    Marin Bratanov
    Progress Telerik

     UI for Blazor
Back to Top