npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-reactive-sidebar

v1.0.5

Published

SidebarMenu Vue.js component

Downloads

20

Readme

vue-reactive-sidebar

Ta Vue komponenta doda prilagodljiv stranski meni.

Namestitev

To komponento je mogoče namestiti z uporabo npm:

npm install vue-reactive-sidebar

Uporaba

Uvoz

Za prikaz stranskega menija uvozite komponento v projekt:

import Sidebar from "vue-reactive-sidebar";
// ...

export default {
    components: {
        Sidebar,
        //...
    },
    // ...
};

in jo nato uporabite v projektu. Primer uporabe:

<template>
    <Sidebar :mobile=false :items="exampleMenu" :itemsBottom="exampleMenuBottom">
        <template #header>
            <img src="./logo.png" alt="Logo" style="max-width: 50%; height: auto;" />
        </template>
        <template #footer>
            <img src="./logout.png" alt="Logout" />
        </template>
    </Sidebar>
    <!-- ... -->
</template>

Prilagajanje

Meni je lahko prikazan na levi strani (za večje zaslone) ali na vrhu (za mobilne telefone in manjše zaslone). Način prikaza menija se nadzoruje z vrednostjo lastnosti mobile. Če je :mobile=false bo meni prikazan na levi, sicer na vrhu (privzeto je :mobile=false).

Elemente, ki bodo v meniju, dodamo z lastnostima items in itemsBottom. Elementi v items bodo prikazani na vrhu, elementi v itemsBottom pa na dnu menija. Njuni vrednosti morata biti Javascript seznama v katerih so elementi, ki bodo prikazani v meniju. Elementi so objekti z lastnostmi:

  • label (string): Ime elementa v meniju.
  • url (string): Url strani na katero element preusmeri ob kliku. Če element ne preusmerja na drugo stran, naj ta lastnost ne bo nastavljena.
  • icon (string): Vsebuje HTML element, ki bo prikazan kot ikona v meniju, zapisan kot string.
  • children (list): Seznam enakih objektov, ki so podelementi tega elementa v meniju. Če element nima podelementov, naj ta lastnost ne bo nastavljena.

Primer menija:

export default {
    components: {
        Sidebar,
        //...
    },
    data() {
        return {
            exampleMenu: [
                {
                    label: "Item 1",
                    icon: '<img src="/item.png" alt="Icon" />',
                    children: [
                        {
                            label: "Item 1 Child 1",
                            url: "",
                            icon: '<img src="/item.png" alt="Icon" />',
                        },
                        {
                            label: "Item 1 Child 2",
                            url: "",
                            icon: '<img src="/item.png" alt="Icon" />',
                        },
                    ]
                },
                {
                    label: "Item 2",
                    url: "",
                    icon: '<img src="/item.png" alt="Icon" />',
                },
                {
                    label: "Item 3",
                    url: "",
                    icon: '<img src="/item.png" alt="Icon" />',
                },
            ],
            exampleMenuBottom: [
                {
                    label: "Item 1",
                    url: "",
                    icon: '<img src="/item.png" alt="Icon" />',
                },
            ],
            // ...
        }
    },
    // ...
};

Prikaz na levi

Za prikaz menija na levi nastavimo :mobile=false. Komponenta lahko zdaj vsebuje še:

  • <template #header>: prikazano na vrhu menija,
  • <template #footer>: prikazano na dnu menija.

Na dnu menija je gumb, ki zmanjša ali poveča meni. Gumb lahko odstranimo tako, da nastavimo lastnost :minimizable=false.

Prikaz na vrhu

Za prikaz menija na vrhu nastavimo :mobile=true. Komponenta lahko zdaj vsebuje še:

  • <template #mobile-left>: prikazano na vrhu menija na levi,
  • <template #mobile-header>: prikazano na vrhu menija na sredini,
  • <template #mobile-right>: prikazano na vrhu menija na desni,
  • <template #mobile-footer>: prikazano na dnu povečanega menija.

Delovanje komponente lahko nadzorujemo z lastnostma:

  • sticky (boolean): komponenta se bo premikala skupaj s stranjo,
  • mobileClickExit (boolean): ko je meni povečan, ga lahko zapustimo s klikom na ozadje.

Izgled

Izgled lahko spremenimo s spreminjanjem css-ja.

Povozimo lahko naslednje spremenljivke:

:root {
    --bg-color: #000000;
    --text-color: #ffffff;
    --mobile-menu-height: 50px;
    --hover-color: #333;
    --menu-width: 250px;
    --menu-width-collapsed: 50px;
    --menu-icon-text-space: 45px;
    --menu-padding-vertical: 10px;
    --menu-padding-horizontal: 12px;
    --menu-padding-horizontal-level: 10px;
    --menu-text-size: 16px;
    --menu-text-size-level: 2px;
}

Spreminjamo lahko tudi druge css lastnosti elementov, na primer:

.custom-sidebar-item {
    background-color: red;
}

Primeri uporabe

Meni na vrhu strani:

<template>
    <div>
        <Sidebar :mobile=true :items="exampleMenu" :mobileClickExit="false" 
        :itemsBottom="exampleMenuBottom">
            <template #mobile-left>
            </template>
            <template #mobile-header>
                <img src="./logo.png" alt="Logo" />
            </template>
            <template #mobile-right>
                <img src="./logout.png" alt="Logout" />
            </template>
            <template #mobile-footer>
            </template>
        </Sidebar>
        <main>
            VSEBINA STRANI
        </main>
    </div>
</template>

<script>
import Sidebar from "vue-reactive-sidebar";

export default {
    name: "App",
    components: { Sidebar },
    data() {
        return {
            exampleMenu: [
                {
                    label: "Item 1",
                    icon: '<img src="/item.png" alt="Icon" />',
                    children: [
                        {
                            label: "Item 1 Child 1",
                            url: "",
                            icon: '<img src="/item.png" alt="Icon" />',
                        },
                        {
                            label: "Item 1 Child 2",
                            url: "",
                            icon: '<img src="/item.png" alt="Icon" />',
                        },
                    ]
                },
                {
                    label: "Item 2",
                    url: "",
                    icon: '<img src="/item.png" alt="Icon" />',
                },
                {
                    label: "Item 3",
                    url: "",
                    icon: '<img src="/item.png" alt="Icon" />',
                },
            ],
            exampleMenuBottom: [
                {
                    label: "Item 1",
                    url: "",
                    icon: '<img src="/itemBelow.png" alt="Icon" />',
                },
            ],
        }
    },
}
</script>

<style>
:root {
    --bg-color: #000000;
    --text-color: #ffffff;
    --mobile-menu-height: 50px;
    --hover-color: #333;
    --menu-width: 250px;
    --menu-width-collapsed: 50px;
    --menu-icon-text-space: 45px;
    --menu-padding-vertical: 10px;
    --menu-padding-horizontal: 12px;
    --menu-padding-horizontal-level: 10px;
    --menu-text-size: 16px;
    --menu-text-size-level: 2px;
}
</style>

Meni s spremenjenim stilom elementov in avtomatskim prilagajanjem glede na velikost strani:

<template>
    <div>
        <Sidebar v-if="isDesktopView" :mobile=false :items="exampleMenu" 
        :itemsBottom="exampleMenuBottom">
            <template #header>
                <img src="./logo.png" alt="Logo" class="logo" />
                <hr class="menu-hr">
                <div class="search-container">
                    <i class="fas fa-search search-icon"></i>
                    <input type="search" class="menu-search" placeholder="Iskanje">
                </div>
            </template>
            <template #footer>
                <div class="circle-container">
                    <div class="circle">IP</div>
                    <p class="name-surname">Ime Priimek</p>
                    <i class="fa-solid fa-sign-out sign-out" />
                </div>
            </template>
        </Sidebar>
        <Sidebar v-else :mobile=true :items="exampleMenu" :itemsBottom="exampleMenuBottom">
            <template #mobile-left>
            </template>
            <template #mobile-header>
                <img src="./logo.png" alt="Logo" />
            </template>
            <template #mobile-right>
                <i class="fa-solid fa-sign-out" />
            </template>
            <template #mobile-footer>
            </template>
        </Sidebar>
        <main>
            VSEBINA STRANI
        </main>
    </div>
</template>

<script>
import Sidebar from "vue-reactive-sidebar";

export default {
    name: "App",
    components: { Sidebar },
    data() {
        return {
            isDesktopView: false,
            mobileSize: 600,
            exampleMenu: [
                {
                    label: "Item 1",
                    icon: '<i class="far fa-user" />',
                    children: [
                        {
                            label: "Item 1 Child 1",
                            url: "",
                            icon: '<i class="far fa-user" />',
                        },
                        {
                            label: "Item 1 Child 2",
                            url: "",
                            icon: '<i class="far fa-user" />',
                        },
                    ]
                },
                {
                    label: "Item 2",
                    url: "",
                    icon: '<i class="far fa-user" />',
                },
                {
                    label: "Item 3",
                    url: "",
                    icon: '<i class="far fa-user" />',
                },
            ],
            exampleMenuBottom: [
                {
                    label: "Item 1",
                    icon: '<i class="far fa-user" />',
                    children: [
                        {
                            label: "Item 1 Child 1",
                            url: "",
                            icon: '<i class="far fa-user" />',
                        },
                        {
                            label: "Item 1 Child 2",
                            url: "",
                            icon: '<i class="far fa-user" />',
                        },
                    ]
                },
            ],
        }
    },
    methods: {
        updateView() {
            this.isDesktopView = window.innerWidth >= this.mobileSize && window.innerHeight >= this.mobileSize;
        }
    },
    mounted() {
        this.isDesktopView = window.innerWidth >= this.mobileSize && window.innerHeight >= this.mobileSize;
        window.addEventListener("resize", this.updateView);
    },
    beforeUnmount() {
        window.removeEventListener("resize", this.updateView);
    }
}
</script>

<style>
.menu-hr {
    justify-content: center;
    width: 85%;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 5px;
}

.search-container {
    position: relative;
    display: inline-block;
}

.search-icon {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    font-size: 18px;
}

.menu-search {
    padding-left: 30px;
    width: 200px;
    height: 30px;
    font-size: 16px;
    background-color: var(--bg-color);
    border: none;
    color: var(--text-color);
}

.menu-search::placeholder {
    color: var(--text-color);
}

.menu-search:focus {
    outline: none;
}

.circle-container {
    display: flex;
    align-items: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 10px;
    margin-bottom: 10px;
}

.circle {
    min-width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: rgb(91, 91, 180);
    color: var(--text-color);
    font-size: 24px;
    text-align: center;
    line-height: 50px;
    margin-left: 30px;
}

.name-surname {
    position: relative;
    top: 8px;
    margin-left: 10px;
}

.sign-out {
    margin-left: 70px;
    transition: margin-left 0.3s ease;
}

:root {
    --bg-color: #000000;
    --grey-color: #424542;
    --text-color: #ffffff;
    --mobile-menu-height: 50px;
    --hover-color: #222324;
    --menu-width: 300px;
    --menu-width-collapsed: 50px;
    --menu-icon-text-space: 30px;
    --menu-padding-vertical: 10px;
    --menu-padding-horizontal: 5px;
    --menu-padding-horizontal-level: 10px;
    --menu-text-size: 16px;
    --menu-text-size-level: 2px;
}

.custom-sidebar-item {
    justify-content: center;
    background-color: var(--grey-color);
    margin-top: 15px;
    padding: 0;
    border-radius: 5px;
    height: 50px;
    overflow-y: hidden;
}

.custom-items-bottom .custom-sidebar-item {
    background-color: transparent;
}

.custom-items-bottom .custom-extended-box {
    background-color: var(--bg-color) !important;
}

.custom-items-bottom .custom-submenu {
    background-color: var(--bg-color) !important;
}

a:has(.custom-sidebar-item) + div > div > div > a > .custom-sidebar-item {
    margin-top: 0;
}

.custom-submenu .custom-sidebar-item {
    margin-top: 0px;
}

.custom-dropdown-icon {
    transform: translateX(-10px);
}

.custom-link {
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 85% !important;
}

.custom-items.collapsed .custom-link {
    width: 92.5% !important;
    margin-right: 0;
}

.custom-items-bottom.collapsed .custom-link {
    width: 92.5% !important;
    margin-right: 0;
}

.custom-submenu {
    background-color: var(--grey-color) !important;
    border-color: var(--grey-color) !important;
    border-radius: 5px;
}

.custom-extended-box {
    background-color: var(--grey-color) !important;
    border-radius: 5px;
    height: 50px;
}

.custom-items.collapsed .custom-link.custom-extended-box {
    width: auto !important;
}

.custom-items-bottom.collapsed .custom-link.custom-extended-box {
    width: auto !important;
}

.custom-header.collapsed .search-container {
    display: none;
}

.custom-header.collapsed .search-container {
    display: none;
}

.custom-header .logo {
    max-width: 90%;
    height: auto;
    transition: max-width 0.3s ease;
    padding: 5px 5px 0 0;
    box-sizing: border-box;
}

.custom-footer.collapsed .circle-container .circle {
    display: none;
}

.custom-footer.collapsed .circle-container .name-surname {
    display: none;
}

.custom-footer.collapsed .circle-container .sign-out {
    margin-left: 10px;
}

.collapsed .circle-container {
  padding-left: 5px;
}
</style>