Svelte – menus and changing urls

We set up the menu in Svelte, highlight the current page and create url to links in the address bar.

I’ve already built the menu on ready-made solutions like svelte-tabs. Here I will show you how to make it with your own efforts. Plus, let’s add transitions from the browser line to specific Svelte pages.

The idea with url transitions is taken from here:
github.com/bluwy/svelte-url

This is a small url.js file that you need to put in your place.

Index.svelte

Entrance page Index.svelte… In it we load our menu. It is always unchanged and will not reload when you click on links. Then we add processing of url requests to the same page (which is also the main one). Specifies the transition page depending on the link. The same pages are indicated in the menu Nav.svelte

<script>
import url from ‘./assets/js/url’
import Nav from “./Nav.svelte”;
import Main from ‘./pages/Main.svelte’;
import Page1 from ‘./pages/Page1.svelte’;
import Page2 from ‘./pages/Page2.svelte’;
script>

<Nav/>

Go from URL to pages ->
{#if $ url.hash === || $ url.hash === ‘# /’}
<Main/>
{:else if $ url.hash === ‘# / Page1’}
<Page1/>
{:else if $ url.hash === ‘# / Page2’}
<Page2/>
{:else}
<h1>404h1>
{/if}

Nav.svelte

A page with a menu and highlighting the current link to Svelte.

We collect our menu from the pages we need:

<script>
import url from ‘./assets/js/url’

let menu = 0;
let links = [
        {
            ‘page’: ‘#/Main’,
            ‘name’: ‘Главная’
        },
        {
            ‘page’: ‘#/Page1’,
            ‘name’: ‘Название ссылки страницы 1’
        },
        {
            ‘page’: ‘Page2’,
            ‘name’: ‘Название ссылки страницы 2’
        },
    ]

// Selected page
let current = ;
let selected;
script>

We display the menu on the site:

<ul class=“menu”>
{#each links as link, id}
<li>
{#if link.page === ‘Main’}
<a href=“/ #”
class:selected=“{$ url.hash === ”}”
on:click=“{() => current = id}”
on:click={() => menu = id}
>
{link.name}
a>
{:else}
<a href=“# / {link.page}”
class:selected=“{$ url.hash === link.page}”
on:click=“{() => current = id}”
on:click={() => menu = id}
>
{link.name}
a>
{/if}
li>
{/each}
ul>

Add scss styles to Svelte:

<style lang=“scss”>
// @ import ‘assets / scss / app’;

menu {
display: flex;
justifycontent: spaceevenly;
flexwrap: wrap;
borderbottom: 1px solid #CCCCCC;
margin: 0;
padding: 0;

li {
liststyle: none;
display: inline;
}

a {
padding: 0.5em 0.75em;
borderbottom: 2px solid transparent;
cursor: pointer;
liststyle: none;
display: inlineblock;

&selected {
borderbottom: 2px solid # 4F81E5;
color: # 4F81E5;
}

&:hover {
textdecoration: none;
color: darkred;
}
}
}
style>

These sections are responsible for highlighting the current link (page):

// Selected page
let current = ;
let selected;

class:selected=“{$ url.hash === ‘# /’ + link.page}”
on:click=“{() => current = id}”
on:click={() => menu = id}

Nav.svelte with icons

Slightly modified version for icons.

JS:

<script>
import url from ‘./assets/js/url’

let menu = 0;
let links = [
        {
            // ‘name’: ‘Графики’,
            ‘link’: ‘#/Charts’,
            ‘hash’: ‘#/Charts’,
            ‘class’: ‘icon-chart’,
        },
        {
            // ‘name’: ‘Главная’,
            ‘link’: ‘/#’,
            ‘hash’: ,
            ‘class’: ‘icon-add’,
        },
        {
            // ‘name’: ‘Админка’,
            ‘link’: ‘/admin/’,
            ‘class’: ‘icon-settings’
        }
    ]

// Selected page
let current = ;
let selected;
script>

Main code:

<ul class=“menu”>
{#each links as item, id}
<li class=“menu-container js-menu-container”>
<a href=“{item.link}”
class:selected=“{$ url.hash === item.hash}”
on:click=“{() => current = id}”
on:click={() => menu = id}>
<div class=“icon-menu {item.class}”> div>
a>
li>
{/each}
ul>

Styles:

lang=“scss”>
// @ import ‘assets / scss / app’;

.menu {
display: flex;
justify-content: space-evenly;
flex-wrap: wrap;
position: fixed;
z-index: 99;
width: 100%;
margin: 0;
left: 0;
bottom: 0;
background-color: # cdd5e2;
align-items: baseline;
overflow: hidden;
padding: 0;

li {
list-style: none;
display: inline;
}

a {
border-bottom: 2px solid transparent;
cursor: pointer;
list-style: none;
display: inline-block;
padding: 0.5em 0.75em;
color: # 000;

&.selected {
border-bottom: 2px solid # 4F81E5;
color: # 4F81E5;
}

&:hover {
text-decoration: none;
color: darkred;
}
}

.icon-menu {
height: 30px;
width: 30px;
padding: 5px;
cursor: pointer;
}

.icon-chart {
background-color: black;
mask-image: url(“”);

&:hover {
background-color: red;
}
}

.icon-add {
background-color: black;
mask-image: url(“”);
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;

&:hover {
background-color: red;
}
}

.icon-settings {
background-color: black;
mask-image: url(“”);
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;

&:hover {
background-color: red;
}
}
}
>

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *