Giter Site home page Giter Site logo

amirkian007 / vue-awesome-sidebar Goto Github PK

View Code? Open in Web Editor NEW
43.0 2.0 13.0 5.58 MB

A Modern and Fast sidebar Menu component for vue(3x) capable with vue-router.

Home Page: https://amirkian007.github.io/vasmenu/

License: MIT License

HTML 0.73% TypeScript 67.73% SCSS 31.54%
sidebar-component sidebar-menu sidebar-navigation vue vuecomponent

vue-awesome-sidebar's Introduction

Vue Awesome Sidebar

vue-wesome-sidebar

About

Vue Awesome Sidbar is a powerfull, fast vue js(3x) sidbar navigation library with a set of components and slots that are flexible and customizable using sass and css which is very easy to use.

Demo

Check out Live demo at amirkian007.github.io/vasmenu

Features

  • Built with typescript and vite with 0 dependants.
  • Support for vue.js (3x) and nuxt.js (3x).
  • Customization support for every component slots , CSS and SASS.
  • Capable with Vue-router.
  • Multiple Menu types(more will be added in the future).
  • Complete RTL support.
  • Dark and White mode support.
  • Responsive design.

Table of Contents

Installation

npm i vue-awesome-sidebar --save

or

yarn add vue-awesome-sidebar --save

Install the component globally.

Vue js 3:

//main.js
import { createApp } from 'vue'
import App from './App.vue'
import vueAwesomeSidebar from 'vue-awesome-sidebar'
import 'vue-awesome-sidebar/dist/vue-awesome-sidebar.css'

const app = createApp(App)
app.use(vueAwesomeSidebar)
app.mount("#app")

Nuxt js 3:

import vueAwesomeSidebar from "vue-awesome-sidebar";
import "vue-awesome-sidebar/dist/vue-awesome-sidebar.css";
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(vueAwesomeSidebar);
});

or Install the component loacally :

//App.vue
import vueAwesomeSidebar from 'vue-awesome-sidebar'
import 'vue-awesome-sidebar/dist/vue-awesome-sidebar.css'
export default {
  components: {
    vueAwesomeSidebar
  }
}

Basic Usage

a simple example would be like this : check out props for properites

NOTE : you have to load the icons separately like loading material-icons files with cdn

<template>
  <VueAwesomeSideBar
      v-model:miniMenu="miniMenu"
      v-model:collapsed="collapsed"
      :menu="testMenu"
      vueRouterEnabel
    ></VueAwesomeSideBar>
</template>

<script setup>
import { ref } from 'vue'

const collapsed = ref(false)
const miniMenu = ref(false)

const testMenu = [
  {
    name: 'Getting Started',
    icon: { text: 'home' , class: 'material-icons-outlined' },
    children: [
      {
        name: 'level 1.1',
        href: '/a',
        icon: { text: 'home' , class: 'material-icons-outlined'},
        children: [
          {
            href: '/b',
            name: 'level 1.1.1',
          },
        ]
      },
      {
        name: 'level 1.2'
      }
    ],
  },
  {
    header: 'Settings'
  },
  {
    name: 'Dashboard',
    icon: { class: 'material-icons-outlined', text: 'dashboard' },
    children: [
      {
        href: '/c',
        name: 'level 2.1',
      },
    ]
  },
  {
    name: 'close menu',
    icon: { text: 'settings', class: 'material-icons-outlined' },
  },
]
</script>

Api

Props

Prop Type Default Description
menu Array null required - Array list of item properties
menuType string simple style of the menu can be either "fully" or "simple"
collapsed Boolean false sets menus collapsed state - should be used with v-model
miniMenu boolean false sets mini menus state - should be used with v-model
width string 290px sets width for menu
widthMiniMenu string 65px sets width for miniMenu
autoCollapse number null adds event listner to collapse menu when the given value(in px) is lower than the viewport width
closeOnClickOutSide Boolean false Adds event listner to collapse Menu when outside is clicked
overLayerOnOpen Boolean false Adds overlayer under the Menu when the menu is open - usefull on mobile
childrenOpenAnimation Boolean true opens menu items children with animation
keepChildrenOpen Boolean flase keeps children items opened when parent item is closed
position string fixed sets menu positiong - by default menu is fixed on viewport
ChildrenOpenActiveRoute Boolean true opens meneitem children on page-load if an item with active "href" inside and miniActive class is applied
checkButtonActive Boolean true checks if menuitems href is active, if so activeClass is added to it and miniActive class to the parent
vueRouterEnabel Boolean true when a meueitem is clicked vue-router will pushe the route to the items "href" property
BottomMiniMenuBtn Boolean true Adds mini menu toggle bottom to bottom of menu
paddingTop String 0px Adds padding to top of menu - usefull when using with app bar with higher z-index
dark Boolean false makes the theme of menu dark - color can be customized with sass vars
rtl Boolean false Makes the entire menu right to left align
closeOpenMenuOnHrefPush Boolean false close MenuItems with children that are expanded on router/herf push

menu properties

interface MenuItem {
  href: string | object // vue-router Object
  name: string
  icon?: MenuItemIcon
  children?: Array< MenuItem | MenuHeaderItem >
  class?: string
  collapseOnClick?: boolean //collapses menu when clicked - this behavior can also be achieved with Events
  activeClass?: boolean
  miniActiveClass?: boolean
}

interface MenuItemIcon {
  text: string
  class?: string
  element?: string //defualt is <i>
  attributes?: object
}

interface MenuHeaderItem {
  title: string
  class?: string
  attributes?: object
}

interface MenuLine {
  LineShow: boolean
  class?: string
  attributes?: object
  element?: string
}

Events

Event Name Description
@item-click(MenuItem) fired when a menu item is clicked
@update:collapsed(isCollapsed) fired when menu collapse state changes - should be used with "v-model"
@update:miniMenu(isMiniMenu) fired when mini menu state changes - should be used with "v-model"

Slots

<!--menu items Append icon-->
<template #itemApendIcon="{ icon,isChildrenMenuOpen, active,miniActive }"></template>
<!--menu items label -->
<template #menuItemLabel="{labelName ,isChildrenMenuOpen, active,miniActive}"></template>
<!--menu items Preppend icon-->
<template #itemPrepandIcon="{ icon,isChildrenMenuOpen, active,miniActive }"></template>
<!--menu header item-->
<template #headerItem="{ header }"></template>
<!--menu header at the top of the menu-->
<template #header></template>
<!--menu footer -->
<template #footer></template>
<!--menus bottom toggle btn -->
<template #BottomMiniMenuBtn></template>

Styling

Sass varibles

to use sass varibles import the SCSS file insted of Css, then import custom varibles, example:

//style.scss
@import "custom-var.scss";
@import "vue-awesome-sidebar/src/scss/vue-awesome-sidebar.scss";
//main.js
import vueAwesomeSidebar from 'vue-awesome-sidebar'
//import 'vue-awesome-sidebar/dist/vue-awesome-sidebar.css'
import './style.scss'

Sass varibles:

//z-index of the menu components rage form 848-854

//<--BASE-->
$overlayer-bg-color: rgba(0, 0, 0, 0.6);
$toggle-mini-btn-height: 50px;
$menu-item-simpleType-icon-height: 35px;
$menu-item-fullyType-height: 44px;
$label-font-size: 16px;//may not work with slots
$label-icon-size: 20px;//may not work with slots
$scroll-bar-width: 13px;

//<--COLORS-->
//NOTE : the "-white" at the end of each var defines the theme, you can change it to "-dark" to set it for dark mode theme
//example :"$icon-color-dark : #000000 " for dark theme and "$icon-color-white : #fafafa " for white theme
//note : may not work with slots depending on how the slots is used

//Menu
$menu-back-ground-color-white: white; -dark: #0d1117; //==> $menu-back-ground-color-dark:#0d1117
$border-color-white: #cfcfcf; -dark: rgba(170, 170, 170, 0.329);
$scroll-bar-color-white: rgb(184, 184, 184); -dark: #686868;
$header-color-white: #213547; -dark: #ffffffde;

//Menu item prepend icon
$icon-color-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225);
$icon-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224);
$icon-mini-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224);
$icon-hover-color-white: ''; -dark: '';

//Menu item
$menu-item-bg-color-white: none; -dark: none;
$menu-item-hover-bg-white: rgb(242, 242, 242); -dark: hsla(0, 0%, 100%, 0.05);
$menu-item-active-bg-color-white: rgb(242, 242, 242); -dark: hsla(0, 0%, 100%, 0.05);
$mini-active-item-bg-color-white: none; -dark: none;

//Menu item label
$text-color-none-hover-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225);
$text-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224);
$text-mini-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224);
$text-hover-color-white: none; -dark: none;

//menu item append icon
$append-icon-color-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225);
$append-active-icon-color-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225);

//horizental line
$hr-line-color-white: rgba(211, 211, 211, 0.548); -dark: rgba(211, 211, 211, 0.548);

//bottomBtn for miniMenu
$bottomBtn-bg-color-white: white; -dark: #13161b;

Css class

//menu
.vas-menu{}
.menu-wraper{}//menu scroll wrapper
.miniCoolapseMenu{} //for mini menu
.compeleteCoolapseMenu{} //for collapsed menu
.dark-theme{}
.white-theme{}
.vas-footer{}
.bottomBtn{} // mini menutoggle button

//menu item
.menu-item-base{// wrapper for menu item ant children
  &.menuExpanded
}//apllayed to all menuitem
.menuExpanded{}
.label{
  .menu-icond{}
  .labelName{}
  .icons{}
  .postIconOpenAnima{}
}
.menuexpand{}
.activeClass{}
.miniActiveClass{}
.labelHoverClass{}

//container
.items-container{}
.topContainer{}

Contributing

$ pnpm i
# dev server
$ pnpm run dev

License

vue-awesome-sidebar is open-sourced software licensed under the MIT license.

vue-awesome-sidebar's People

Contributors

amirkian007 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vue-awesome-sidebar's Issues

Cannot read properties of null (reading 'isCE')

I just installed this library and imported to my Vue3 like what example presents. (import and app.use)
then I got this error.

That is stack:

TypeError: Cannot read properties of null (reading 'isCE')
    at renderSlot (runtime-core.esm-bundler.js:2966:34)
    at Proxy.ze (vue-awesome-sidebar.js:1:22054)
    at renderComponentRoot (runtime-core.esm-bundler.js:902:44)
    at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5615:57)
    at ReactiveEffect.run (reactivity.esm-bundler.js:187:25)
    at instance.update (runtime-core.esm-bundler.js:5729:56)
    at setupRenderEffect (runtime-core.esm-bundler.js:5743:9)
    at mountComponent (runtime-core.esm-bundler.js:5525:9)
    at processComponent (runtime-core.esm-bundler.js:5483:17)
    at patch (runtime-core.esm-bundler.js:5085:21)

Part of my code are as follows:

<template>
 <VueAwesomeSideBar v-model:collapsed="collapsed" :menu="testMenu" v-model:miniMenu="miniMenu" vueRouterEnabel></VueAwesomeSideBar>
</template>
  
<script lang="ts" setup>
const miniMenu = ref(false)
const props = defineProps<{
    collapsed: boolean
}>()

const testMenu: MenuItem[] = [
    {
        name: 'Dashboard',
        icon: { class: 'material-icons-outlined', text: 'dashboard' },
        children: [
            {
                href: '/c',
                name: 'level 2.1',
            },
        ]
    }
]
</script>

icons not showing

hi, first i have to comment that in the example the css required is called vue-awesome-sidebar but the file in vue-awesome-sideRbar

now, the problem is that icons not showing, is the css correct?

Router mode should use vue-router

I have read a tiny part of source of this project, then I found that it seems to just change hash to route. I suggest that use the useRouter to get the router instance and call router.push, so that this library can adapt to more routing methods such as memory and non-hash

how to programmatically decide if a menu item is selected or not

i am trying to make a menu show up as selected if the current location is equal to the href or if one of it's parts is.
so the item with href : /part1 should be selected if the current location is /part1 or /part1/part2.

currently this seems to not be possible as there is no way to use custom isCurrentURI functions or a regex based solution. is there another way of getting the desired outcome

Probled with closeOpenMenuOnHrefPush

How use new option closeOpenMenuOnHrefPush?
I updated to the latest version of the package and set :closeOpenMenuOnHrefPush="true", but the error still crashes.

[Vue warn]: Extraneous non-props attributes (closeOpenMenuOnHrefPush) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.
at <VasMenu key=0 width="300px" miniMenu=false ... >
at
at

menu attribute "width" doesn't seem to work

If you include it (see example below, modified in this project to test), it will simply ignore whatever number you put there and make the menu as small as the contents of the menu.

`<Menu
:menu="testmENU"
v-model:miniMenu="miniMenu"
v-model:collapsed="collapsed"
@item-click="hanc"
vueRouterEnabel
dark
width="300"
:autoCollapse="600"
menuType="fully"

`

Problem with menu closing after clicking on parent.

After clicking on an item, I need to close the menu. I can do this via the event @item-click. (set collapsed=true).
My parent menu items also contains href: '/...'. I use vueRouterEnabel.
And how do I make it so that when you click on the parent, you can:

  1. Use child menu items (i.e. expand the menu to view children) and be able to use the parent item as a link (href:'') to another page.
  2. It was possible to close the menu after clicking on the parent (meaning following the link href: '/...').

[Idea] Prop for for one open menu at a time

In my opinion, a nice addition would be the ability to specify that only one menu can be expanded at a time (I mean the values in the "children" parameter).
For example, on this project's documentation page:
When the "Styling" menu is expanded, the "example 1" menu collapses and vice versa

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.