├── .vscode └── extensions.json ├── assets └── demo.gif ├── .gitattributes ├── .prettierignore ├── tsconfig.node.json ├── src ├── vite-env.d.ts ├── scss │ ├── vue-awesome-sidebar.scss │ ├── menu-scrollbar.scss │ ├── types │ │ ├── _shared.scss │ │ ├── simple.scss │ │ └── fully.scss │ ├── menu-item.scss │ ├── _base.scss │ └── themes │ │ ├── dark-theme.scss │ │ └── white-theme.scss ├── VueAwesomeSidebar.ts ├── hooks │ ├── useAwsemoeItem.ts │ ├── useClickOutSide.ts │ ├── useAwsomeRouter.ts │ └── useAwseomeSideBar.ts ├── components │ ├── Menuline.vue │ ├── MenuItemIcon.vue │ ├── HeaderItem.vue │ ├── Menu.vue │ └── MenuItem.vue ├── main.ts └── App.vue ├── .gitignore ├── .prettierrc.json ├── index.html ├── vite.config.ts ├── tsconfig.json ├── LICENCE ├── types └── index.d.ts ├── package.json ├── README.md └── pnpm-lock.yaml /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/amirkian007/vue-awesome-sidebar/HEAD/assets/demo.gif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=TypeScript 2 | *.vue linguist-language=TypeScript 3 | * -text -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bin 3 | dist 4 | build 5 | pnpm-lock.yaml 6 | .vscode 7 | README.md -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | //"extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": ["node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue' 5 | const component: DefineComponent<{}, {}, any> 6 | export default component 7 | } 8 | -------------------------------------------------------------------------------- /src/scss/vue-awesome-sidebar.scss: -------------------------------------------------------------------------------- 1 | @import './menu-scrollbar'; 2 | @import './base'; 3 | //@use './types/shared'; 4 | @import './themes/white-theme.scss'; 5 | @import './themes/dark-theme.scss'; 6 | @import '../scss/menu-item.scss'; 7 | -------------------------------------------------------------------------------- /src/VueAwesomeSidebar.ts: -------------------------------------------------------------------------------- 1 | // This is where the package installs. 2 | import type { App } from 'vue' 3 | import VueAwesomeSideBar from './components/Menu.vue' 4 | 5 | export default { 6 | install: (app: App) => { 7 | app.component('VueAwesomeSideBar', VueAwesomeSideBar) 8 | } 9 | } 10 | 11 | export { VueAwesomeSideBar } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | *.tgz 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/hooks/useAwsemoeItem.ts: -------------------------------------------------------------------------------- 1 | import { onBeforeUnmount, ref, onMounted, watch } from 'vue' 2 | 3 | export function useAwsemoeItem(target: any, callBack: any, isCollapsed: any) { 4 | const currentRoute = ref( 5 | window.location.pathname + window.location.search + window.location.hash 6 | ) 7 | 8 | const itemShow = ref(false) 9 | const itemHover = ref(false) 10 | } 11 | -------------------------------------------------------------------------------- /src/components/Menuline.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 21 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "printWidth": 80, 6 | "trailingComma": "none", 7 | "overrides": [ 8 | { 9 | "files": ["*.json5"], 10 | "options": { 11 | "singleQuote": false, 12 | "quoteProps": "preserve" 13 | } 14 | }, 15 | { 16 | "files": ["*.yml"], 17 | "options": { 18 | "singleQuote": false 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/components/MenuItemIcon.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 23 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vue awesome sidebar 7 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/components/HeaderItem.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import { terser } from 'rollup-plugin-terser' 4 | import typescript2 from 'rollup-plugin-typescript2' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [vue()], 9 | server: {}, 10 | build: { 11 | lib: { 12 | entry: './src/VueAwesomeSidebar.ts', 13 | formats: ['es', 'cjs'], 14 | name: 'VueAwesomeSidebar', 15 | fileName: 'vue-awesome-sidebar' 16 | }, 17 | sourcemap:true, 18 | rollupOptions: { 19 | external: ['vue'], 20 | output: { 21 | globals: { 22 | vue: 'Vue' 23 | }, 24 | assetFileNames: (assetInfo) => { 25 | if (assetInfo.name == 'style.css') return 'vue-awesome-sidebar.css' 26 | return assetInfo.name 27 | } 28 | } 29 | } 30 | } 31 | }) 32 | -------------------------------------------------------------------------------- /src/scss/menu-scrollbar.scss: -------------------------------------------------------------------------------- 1 | $scroll-bar-width: 13px !default; 2 | 3 | .menu-wraper, 4 | .topContainer { 5 | &::-webkit-scrollbar { 6 | // transition: 2s; 7 | width: $scroll-bar-width; 8 | } 9 | &.compeleteCoolapseMenu::-webkit-scrollbar { 10 | width: $scroll-bar-width; 11 | } 12 | &.miniCoolapseMenu::-webkit-scrollbar { 13 | width: 0px; 14 | } 15 | &.miniCoolapseMenu { 16 | -ms-overflow-style: none; /* IE 11 */ 17 | scrollbar-width: none; /* Firefox 64 */ 18 | } 19 | &::-webkit-scrollbar-thumb { 20 | background-clip: content-box; 21 | border: 4px solid transparent; 22 | border-radius: 7px; 23 | box-shadow: inset 0 0 0 10px; 24 | } 25 | &::-webkit-scrollbar-button { 26 | width: 0; 27 | height: 0; 28 | display: none; 29 | } 30 | &::-webkit-scrollbar-corner { 31 | background-color: transparent; 32 | } 33 | .topContainer::-webkit-scrollbar { 34 | width: $scroll-bar-width; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/scss/types/_shared.scss: -------------------------------------------------------------------------------- 1 | $menu-item-simpleType-icon-height: 35px !default; 2 | $menu-item-fullyType-height: 44px !default; 3 | $label-font-size: 16px !default; 4 | $label-icon-size: 20px !default; 5 | 6 | .menu-iconS { 7 | font-size: $label-icon-size; 8 | width: $label-icon-size; // 9 | overflow: hidden; 10 | } 11 | .labelMiniS { 12 | font-size: $label-font-size; //d 13 | .rtl & { 14 | border-top-left-radius: 4px; 15 | border-bottom-left-radius: 4px; 16 | } 17 | .ltr & { 18 | border-top-right-radius: 4px; 19 | border-bottom-right-radius: 4px; 20 | } 21 | } 22 | 23 | .hoverClassS { 24 | transition: all 0.3s; 25 | } 26 | .topContainerS { 27 | .rtl & { 28 | border-top-left-radius: 7px; 29 | border-bottom-left-radius: 7px; 30 | } 31 | .ltr & { 32 | border-top-right-radius: 7px; 33 | border-bottom-right-radius: 7px; 34 | } 35 | } 36 | .labelS { 37 | width: 100%; 38 | .left { 39 | span { 40 | padding-left: 6px; 41 | padding-right: 6px; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | // { 2 | 3 | // "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | // "compilerOptions": { 5 | // "strictNullChecks": false, 6 | // "baseUrl": ".", 7 | // "paths": { 8 | // "@/*": ["./src/*"] 9 | // }, 10 | // "allowJs":true 11 | 12 | // }, 13 | // "references": [{ "path": "./tsconfig.node.json" }] 14 | // } 15 | { 16 | "compilerOptions": { 17 | "target": "esnext", 18 | "useDefineForClassFields": true, 19 | "module": "esnext", 20 | "moduleResolution": "node", 21 | "strict": true, 22 | "jsx": "preserve", 23 | "sourceMap": true, 24 | "resolveJsonModule": true, 25 | "esModuleInterop": true, 26 | "lib": ["esnext", "dom"], 27 | "skipLibCheck": true, 28 | "allowJs": true, 29 | "declaration": true, 30 | "isolatedModules": true, 31 | "paths": { 32 | "@": ["./src"], 33 | "@/*": ["./src/*"] 34 | } 35 | }, 36 | "paths": { 37 | "@": ["./src"], 38 | "@/*": ["./src/*"] 39 | }, 40 | "include": ["src/**/*"], 41 | "references": [{ "path": "./tsconfig.node.json" }] 42 | } 43 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 amirkian007 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue' 2 | import App from './App.vue' 3 | import 'material-icons/iconfont/material-icons.css' 4 | import { createRouter, createWebHistory } from 'vue-router' 5 | 6 | import MenuItemIcon from './components/MenuItemIcon.vue' 7 | const Home = { template: '
Home
' } 8 | const About = { template: '
About
' } 9 | const test = { template: '
test
' } 10 | const test2 = { template: '
test2
' } 11 | const test3 = { template: '
test3
' } 12 | const test4 = { template: '
test4
' } 13 | // 2. Define some routes 14 | // Each route should map to a component. 15 | // We'll talk about nested routes later. 16 | const routes = [ 17 | { path: '/', component: Home }, 18 | { path: '/a', component: About }, 19 | { path: '/a/b', component: test }, 20 | { path: '/a/b/c', component: test2 }, 21 | { path: '/a/b/c/d', component: test3 }, 22 | { path: '/k', component: test4 } 23 | ] 24 | 25 | // 3. Create the router instance and pass the `routes` option 26 | // You can pass in additional options here, but let's 27 | // keep it simple for now. 28 | const router = createRouter({ 29 | // 4. Provide the history implementation to use. We are using the hash history for simplicity here. 30 | strict: true, 31 | history: createWebHistory(''), 32 | routes // short for `routes: routes` 33 | }) 34 | 35 | console.log(App) 36 | console.log(App.setup) 37 | createApp(App).use(router).mount('#app') 38 | -------------------------------------------------------------------------------- /src/hooks/useClickOutSide.ts: -------------------------------------------------------------------------------- 1 | import { onBeforeUnmount, onMounted, watch, ref } from 'vue' 2 | 3 | export function useClickOutSide(target: any, callBack: any, isCollapsed: any) { 4 | if (!target) return 5 | 6 | const listner = (event: any) => { 7 | if (isCollapsed.value) { 8 | removeSideBarListner() 9 | return 10 | } 11 | if ( 12 | event.target == target.value || 13 | event.composedPath().includes(target.value) 14 | ) { 15 | return 16 | } 17 | callBack() 18 | } 19 | const removeSideBarListner = () => { 20 | window.removeEventListener('click', listner) 21 | } 22 | const addSideBarListner = () => { 23 | removeSideBarListner() 24 | setTimeout(() => { 25 | //push this to the end of call stack 26 | window.addEventListener('click', listner) 27 | }, 0) 28 | } 29 | 30 | onBeforeUnmount(removeSideBarListner) 31 | 32 | return { removeSideBarListner, addSideBarListner } 33 | } 34 | export function useAutoCollapse(target: number, callBack: any) { 35 | if (!target) return 36 | callBack(target > innerWidth) 37 | let initialWidth = window.innerWidth 38 | const listner = () => { 39 | if (initialWidth != window.innerWidth) { 40 | callBack(target > innerWidth) 41 | initialWidth = window.innerWidth 42 | } 43 | } 44 | window.addEventListener('resize', listner) 45 | onBeforeUnmount(() => { 46 | window.removeEventListener('resize', listner) 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /src/scss/types/simple.scss: -------------------------------------------------------------------------------- 1 | @import './shared'; 2 | 3 | .vsss-header, 4 | .vas-simple { 5 | width: 95%; 6 | } 7 | .vas-simple { 8 | .noIconWidth { 9 | width: calc(97% - 20px) !important; 10 | } 11 | .noIconwidthMiniMenu { 12 | width: calc(95% - 20px) !important; 13 | } 14 | .label, 15 | .labelMini, 16 | .labelminiSub { 17 | height: $menu-item-simpleType-icon-height; 18 | } 19 | .label { 20 | padding: 6px 8px; 21 | } 22 | } 23 | 24 | .vas-simple { 25 | margin-top: 1.5px; 26 | margin-bottom: 1.5px; 27 | border-radius: 4px; 28 | .menu-icon { 29 | @extend .menu-iconS; 30 | } 31 | .labelMini { 32 | border-radius: 4px; 33 | @extend .labelMiniS; 34 | > .left { 35 | margin-left: 7px; 36 | margin-right: 7px; 37 | align-items: center; 38 | } 39 | } 40 | .label { 41 | font-size: $label-font-size; 42 | > .left { 43 | margin-left: 7px; 44 | margin-right: 7px; 45 | align-items: center; 46 | } 47 | } 48 | .icons { 49 | margin-left: 7px; 50 | margin-right: 7px; 51 | } 52 | .hoverClass { 53 | @extend .hoverClassS; 54 | } 55 | .topContainer { 56 | @extend .topContainerS; 57 | } 58 | 59 | &.miniCollapseIconWidth { 60 | width: 70%; 61 | } 62 | &.MenuItemWidthOnMiniCollapse { 63 | width: 95%; 64 | } 65 | .label { 66 | height: $menu-item-simpleType-icon-height; 67 | border-radius: 4px; 68 | @extend .labelS; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { App } from 'vue' 2 | 3 | export interface MenuItemIcon { 4 | text?: string 5 | 6 | class?: string 7 | 8 | element?: string 9 | 10 | attributes?: object 11 | } 12 | 13 | export interface MenuItem { 14 | href: string | object 15 | 16 | name: string 17 | 18 | icon?: MenuItemIcon 19 | 20 | children?: Array 21 | 22 | class?: string 23 | 24 | activeClass?: boolean 25 | 26 | miniActiveClass?: boolean 27 | } 28 | 29 | export interface MenuHeaderItem { 30 | title: string 31 | 32 | class?: string 33 | 34 | attributes?: object 35 | } 36 | 37 | export interface MenuLine { 38 | LineShow: boolean 39 | 40 | class?: string 41 | 42 | attributes?: object 43 | 44 | element?: string 45 | } 46 | 47 | export class Menu { 48 | menu: Array 49 | 50 | menuType?: boolean 51 | 52 | collapsed?: boolean 53 | 54 | miniMenu?: boolean 55 | 56 | width?: string 57 | 58 | widthMiniMenu?: boolean 59 | 60 | removeIconSpace?: string 61 | 62 | closeOnClickOutSide?: boolean 63 | 64 | overLayerOnOpen?: boolean 65 | 66 | childrenOpenAnimation?: boolean 67 | 68 | postion?: boolean 69 | 70 | keepChildrenOpen?: boolean 71 | 72 | ChildrenOpenActiveRoute?: string 73 | checkButtonActive?: string 74 | vueRouterEnabel?: string 75 | BottomMiniMenuBtn?: string 76 | paddingTop?: string 77 | dark?: string 78 | rtl?: string 79 | } 80 | 81 | export default function install(app: App): void 82 | -------------------------------------------------------------------------------- /src/hooks/useAwsomeRouter.ts: -------------------------------------------------------------------------------- 1 | import { ref, computed, inject, watch, provide, reactive, toRefs } from 'vue' 2 | //import { useRoute } from 'vue-router'; 3 | 4 | export const initAwsomeRouter = (props: any, context: any) => { 5 | const { autoCollapse, collapsed, relative, width, widthCollapsed, rtl } = 6 | toRefs(props) 7 | const currentRoute = ref(window.location) 8 | 9 | function isSameUrl(url: any, location = currentRoute.value) { 10 | return ( 11 | location.href === location.origin + url || 12 | location.pathname + location.hash === url || 13 | location.pathname + location.search === url || 14 | location.href === url || 15 | location.hash === url 16 | ) 17 | } 18 | 19 | function extractChildrenRoutes(obj: any, keyToFind: any): any { 20 | if (!obj) return 21 | return Object.entries(obj).reduce( 22 | (acc: any, [key, value]: any) => 23 | key === keyToFind 24 | ? acc.concat(value) 25 | : typeof value === 'object' 26 | ? acc.concat(extractChildrenRoutes(value, keyToFind)) 27 | : acc, 28 | [] 29 | ) 30 | } 31 | 32 | // if(autoCollapse.value){ 33 | // } 34 | 35 | const updateCurrentRoute = (val: any) => { 36 | currentRoute.value = { ...val } 37 | } 38 | 39 | provide('currentRoute', currentRoute) 40 | provide('updateCurrentRoute', updateCurrentRoute) 41 | provide('isSameUrl', isSameUrl) 42 | provide('extractChildrenRoutes', extractChildrenRoutes) 43 | return { 44 | isSameUrl, 45 | extractChildrenRoutes, 46 | currentRoute, 47 | updateCurrentRoute 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/scss/types/fully.scss: -------------------------------------------------------------------------------- 1 | @import './shared'; 2 | 3 | .vsss-header, 4 | .vas-fully { 5 | width: 100%; 6 | } 7 | .vas-fully { 8 | .icons { 9 | margin-right: 10px; 10 | margin-left: 10px; 11 | } 12 | .label, 13 | .labelMini, 14 | .labelminiSub { 15 | height: $menu-item-fullyType-height; 16 | } 17 | } 18 | 19 | .vas-fully { 20 | .menu-icon { 21 | @extend .menu-iconS; 22 | } 23 | .labelMini { 24 | &.activeClass::before { 25 | content: ''; 26 | height: 100%; 27 | position: absolute; 28 | width: 5px; 29 | top: 0px; 30 | } 31 | .rtl & { 32 | &::before { 33 | right: 0px; 34 | } 35 | } 36 | .ltr & { 37 | &::before { 38 | left: 0px; 39 | } 40 | } 41 | @extend .labelMiniS; 42 | } 43 | .label { 44 | font-size: $label-font-size; //d 45 | &.activeClass::before { 46 | content: ''; 47 | height: 100%; 48 | position: absolute; 49 | width: 5px; 50 | top: 0px; 51 | } 52 | .rtl & { 53 | &::before { 54 | right: 0px; 55 | } 56 | } 57 | .ltr & { 58 | &::before { 59 | left: 0px; 60 | } 61 | } 62 | 63 | > .left { 64 | margin-right: 7px; 65 | margin-left: 7px; 66 | align-items: center; 67 | } 68 | } 69 | 70 | .hoverClass { 71 | @extend .hoverClassS; 72 | } 73 | .topContainer { 74 | @extend .topContainerS; 75 | } 76 | 77 | &.miniCollapseIconWidth { 78 | width: 100%; 79 | } 80 | &.MenuItemWidthOnMiniCollapse { 81 | width: 100%; 82 | } 83 | .label { 84 | height: $menu-item-fullyType-height; 85 | @extend .labelS; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-awesome-sidebar", 3 | "version": "1.2.4", 4 | "private": false, 5 | "main": "dist/vue-awesome-sidebar.cjs", 6 | "module": "dist/vue-awesome-sidebar.js", 7 | "type": "module", 8 | "description": "Modern Vue 3 Sidebar Module", 9 | "author": "AmirKian Adl ", 10 | "license": "MIT", 11 | "types": "./types/index.d.ts", 12 | "files": [ 13 | "dist", 14 | "src/scss", 15 | "types" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/amirkian007/vue-awesome-sidebar.git" 20 | }, 21 | "homepage": "https://amirkian007.github.io/vasmenu", 22 | "scripts": { 23 | "dev": "vite --host", 24 | "build": "vue-tsc --noEmit && vite build", 25 | "preview": "vite preview", 26 | "format": "prettier --write .", 27 | "build-demo": "vue-tsc --noEmit && vite build", 28 | "build-component": "" 29 | }, 30 | "keywords": [ 31 | "vue-awesome-sidebar", 32 | "vue", 33 | "sidenav", 34 | "navigation", 35 | "vue-sidebar", 36 | "vue awesome sidebar", 37 | "vue sidebar", 38 | "vue awesome", 39 | "vue sidbar", 40 | "vue sidbar component", 41 | "vue sidbar module", 42 | "vue navigate", 43 | "vue sidbar", 44 | "vue.js navigate", 45 | "vue.js sidbar", 46 | "vue navigation", 47 | "nuxt.js 3", 48 | "vue.js 3" 49 | ], 50 | "browserslist": [ 51 | "> 1%", 52 | "last 2 versions", 53 | "not ie <= 8" 54 | ], 55 | "devDependencies": { 56 | "rollup-plugin-terser": "^7.0.2", 57 | "vue": "^3.2.37", 58 | "vue-router": "4", 59 | "@vitejs/plugin-vue": "^3.0.0", 60 | "material-icons": "^1.11.8", 61 | "prettier": "^2.7.1", 62 | "sass": "^1.54.3", 63 | "typescript": "^4.6.4", 64 | "vite": "^3.0.0", 65 | "vue-tsc": "^0.38.4" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/scss/menu-item.scss: -------------------------------------------------------------------------------- 1 | @import './types/simple.scss'; 2 | @import './types/fully.scss'; 3 | 4 | %hoverPointer { 5 | @media (hover: hover) and (pointer: fine) { 6 | cursor: pointer; 7 | } 8 | @media (hover: none) and (pointer: coarse) { 9 | cursor: none; 10 | } 11 | } 12 | 13 | .menu-item-base { 14 | .menu-icon, 15 | .labelName { 16 | transition: color 0.3s ease; 17 | } 18 | .label .left { 19 | &.marginAuto { 20 | position: absolute; 21 | top: 50%; 22 | left: 50%; 23 | transform: translate(-50%, -50%); 24 | } 25 | } 26 | .labelMini .left { 27 | &.marginAuto { 28 | position: fixed; 29 | } 30 | } 31 | &.alignCenter { 32 | align-self: center; 33 | } 34 | position: relative; 35 | .labelMini { 36 | transition: width 0.35s, opacity 0.35s; 37 | background: none; 38 | flex-direction: row; 39 | justify-content: space-between; 40 | white-space: nowrap; 41 | display: flex; 42 | align-items: center; 43 | user-select: none; 44 | > .left { 45 | display: flex; 46 | } 47 | z-index: 851; 48 | @extend %hoverPointer; 49 | } 50 | .label { 51 | transform-style: preserve-3d; 52 | flex-direction: row; 53 | justify-content: space-between; 54 | white-space: nowrap; 55 | display: flex; 56 | align-items: center; 57 | user-select: none; 58 | position: relative; 59 | box-sizing: border-box; //r 60 | 61 | z-index: 853; 62 | .left { 63 | display: flex; 64 | &.marginAuto { 65 | margin: auto; 66 | } 67 | } 68 | 69 | @extend %hoverPointer; 70 | } 71 | .hoverClass { 72 | @extend %hoverPointer; 73 | } 74 | .topContainer { 75 | overflow-y: overlay; 76 | position: fixed; 77 | transition: width 0.3s ease; 78 | width: 250px; 79 | } 80 | .vasopacitiy { 81 | animation: myOpac 0s; 82 | animation-fill-mode: forwards; 83 | } 84 | @keyframes myOpac { 85 | from { 86 | opacity: 1; 87 | } 88 | to { 89 | opacity: 0; 90 | } 91 | } 92 | 93 | &.MenuItemWidthOnMiniCollapse { 94 | margin-left: auto; 95 | } 96 | .icons { 97 | content: ''; 98 | height: 1.25rem; 99 | min-width: 1.25rem; 100 | width: 1.25rem; 101 | } 102 | .rtl & { 103 | .icons { 104 | margin-right: auto; 105 | -webkit-transform: rotate(-90deg); 106 | transform: rotate(-90deg); 107 | } 108 | } 109 | .ltr & { 110 | .icons { 111 | margin-left: auto; 112 | -webkit-transform: rotate(90deg); 113 | transform: rotate(90deg); 114 | } 115 | } 116 | .icons.opened { 117 | padding: auto; 118 | .ltr & { 119 | -webkit-transform: rotate(180deg) !important; 120 | transform: rotate(180deg) !important; 121 | } 122 | .rtl & { 123 | -webkit-transform: rotate(-180deg) !important; 124 | transform: rotate(-180deg) !important; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/scss/_base.scss: -------------------------------------------------------------------------------- 1 | $overlayer-bg-color: rgba(0, 0, 0, 0.6) !default; 2 | $toggle-mini-btn-height: 50px !default; 3 | 4 | .vas-menu { 5 | height: 100vh; 6 | top: 0; 7 | overflow-x: hidden; 8 | // -webkit-overflow-scrolling: touch; 9 | z-index: 849; 10 | transition: all 0.3s; 11 | display: flex; 12 | flex-flow: column; 13 | .BlockBack { 14 | position: absolute; 15 | z-index: 852; 16 | height: 100%; 17 | width: 100%; 18 | border-radius: 4px; 19 | } 20 | .menu-wraper { 21 | flex: 1 1 auto; 22 | position: relative; 23 | display: flex; 24 | flex-flow: column; 25 | left: 0px; 26 | overflow-y: overlay; 27 | overflow-x: hidden; 28 | } 29 | .vas-footer { 30 | height: 100%; 31 | flex-flow: column; 32 | display: flex; 33 | flex: 0 1 auto; 34 | } 35 | .footer-wrapper { 36 | flex: 1 1 auto; 37 | } 38 | .TransitionC { 39 | transition: background-color 0.3s; 40 | } 41 | .bottomBtn { 42 | flex: 0 1 $toggle-mini-btn-height; 43 | position: -webkit-sticky; 44 | position: sticky; 45 | bottom: 0; 46 | width: 100%; 47 | display: block; 48 | z-index: 854; 49 | cursor: pointer; 50 | transition: 0.3s; 51 | display: flex; 52 | align-items: center; 53 | justify-content: center; 54 | :first-child { 55 | height: $toggle-mini-btn-height !important; 56 | } 57 | } 58 | 59 | .bottomBtnIcon { 60 | width: 20px; 61 | margin-left: 7px; 62 | transition: transform 0.3s; 63 | } 64 | 65 | &.rtl { 66 | .bottomBtnIcon { 67 | transform: rotate(-90deg); 68 | } 69 | .ssdSpin { 70 | transform: rotate(90deg); 71 | } 72 | } 73 | 74 | &.ltr { 75 | .bottomBtnIcon { 76 | transform: rotate(90deg); 77 | } 78 | .ssdSpin { 79 | transform: rotate(-90deg); 80 | } 81 | } 82 | 83 | .vsss-header { 84 | align-self: center; 85 | font-size: 13px; 86 | white-space: nowrap; 87 | text-transform: uppercase; 88 | padding-top: 12px; 89 | padding-left: 16px; 90 | padding-right: 16px; 91 | padding-bottom: 1px; 92 | font-weight: 600; 93 | width: 97%; 94 | } 95 | 96 | .items-container { 97 | height: fit-content; 98 | overflow: hidden; 99 | } 100 | 101 | .vas-hr { 102 | display: block; 103 | margin: 20px; 104 | unicode-bidi: isolate; 105 | margin-block-start: 0.5em; 106 | margin-block-end: 0.5em; 107 | margin-inline-start: auto; 108 | margin-inline-end: auto; 109 | overflow: hidden; 110 | border-style: inset; 111 | border-width: 1px; 112 | width: 80%; 113 | } 114 | 115 | .postIconOpenAnima { 116 | transition: -webkit-transform 300ms linear; 117 | transition: transform 300ms linear; 118 | transition: transform 300ms linear, -webkit-transform 300ms linear; 119 | height: 100%; 120 | } 121 | } 122 | .vas-fade-enter-active, 123 | .vas-fade-leave-active { 124 | transition: opacity 300ms ease; 125 | } 126 | 127 | .vas-fade-enter-from, 128 | .vas-fade-leave-to { 129 | opacity: 0; 130 | } 131 | .vas-over-layer { 132 | width: 100%; 133 | height: 100%; 134 | position: fixed; 135 | left: 0; 136 | top: 0; 137 | background-color: $overlayer-bg-color; 138 | z-index: 848; 139 | } 140 | -------------------------------------------------------------------------------- /src/hooks/useAwseomeSideBar.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ref, 3 | computed, 4 | inject, 5 | provide, 6 | onMounted, 7 | reactive, 8 | toRefs 9 | } from 'vue' 10 | 11 | export const initAwsomeSideBar = (props: any, context: any) => { 12 | const { 13 | menu, 14 | menuType, 15 | miniMenu: miniMenuProp, 16 | collapsed, 17 | animationDuration, 18 | width, 19 | widthMiniMenu, 20 | removeIconSpace, 21 | closeOnClickOutSide, 22 | overLayerOnOpen, 23 | childrenOpenAnimation, 24 | position, 25 | collapseBreakPoint, 26 | dark, 27 | vueRouterEnabel, 28 | keepChildrenOpen, 29 | checkButtonActive, 30 | ChildrenOpenActiveRoute, 31 | closeOpenMenuOnHrefPush, 32 | keepOneMenuOpenAtAtime, 33 | rtl 34 | } = toRefs(props) 35 | const isCollapsed = ref(collapsed.value) 36 | const menuMounted = ref(false) 37 | const MenuScroll = ref(false) 38 | const miniMenu = ref(miniMenuProp.value) 39 | const MenuHover = ref(false) 40 | const CurrantItemHover = ref(null) 41 | const CurranContainerHover = ref(null) 42 | const routerPushBlockList: any = ref('') 43 | 44 | const symbolId = Symbol("id") 45 | let id = 3 46 | 47 | const getRandomUid = () => { 48 | return id++ 49 | } 50 | 51 | function addIdToMenuItems(arr: any) { 52 | let array = [...arr] 53 | function backTrack(array: any) { 54 | for (let i = 0; i < array.length; i++) { 55 | array[i][symbolId] = getRandomUid() 56 | if (array[i].children) { 57 | backTrack(array[i].children) 58 | } 59 | } 60 | } 61 | backTrack(array) 62 | return array 63 | } 64 | 65 | function pushToRouterPush(id: any) { 66 | routerPushBlockList.value = id 67 | } 68 | 69 | const getSlotByName = (slotName: any) => { 70 | return context.slots.hasOwnProperty(slotName) 71 | ? context.slots[slotName] 72 | : null 73 | } 74 | 75 | const updateIsCollapsed = (val: boolean) => { 76 | isCollapsed.value = val 77 | } 78 | const updateMenuScroll = () => { 79 | MenuScroll.value = !MenuScroll.value 80 | } 81 | const updateMenuHover = (val: any) => { 82 | MenuHover.value = val 83 | } 84 | const updateCurrantItemHover = (id: any) => { 85 | CurrantItemHover.value = id 86 | } 87 | const updateCurranContainerHover = (id: any) => { 88 | CurranContainerHover.value = id 89 | } 90 | const menuDirection = computed(() => { 91 | return rtl.value ? 'right' : 'left' 92 | }) 93 | const emitOut = (event: any, item: any) => { 94 | context.emit(event, item) 95 | } 96 | const updateminiMenu = (val: boolean) => { 97 | miniMenu.value = val 98 | } 99 | let userAgentHeight = 100 | navigator.userAgent.indexOf('Firefox') != -1 101 | ? '-moz-max-content' 102 | : 'fit-content' 103 | 104 | onMounted(() => { 105 | menuMounted.value = true 106 | }) 107 | 108 | provide('sidebarProps', { 109 | menu, 110 | menuType, 111 | collapsed: isCollapsed, 112 | miniMenu, 113 | animationDuration, 114 | width, 115 | widthMiniMenu, 116 | removeIconSpace, 117 | closeOnClickOutSide, 118 | overLayerOnOpen, 119 | childrenOpenAnimation, 120 | position, 121 | collapseBreakPoint, 122 | vueRouterEnabel, 123 | checkButtonActive, 124 | ChildrenOpenActiveRoute, 125 | closeOpenMenuOnHrefPush, 126 | keepChildrenOpen, 127 | dark, 128 | rtl, 129 | keepOneMenuOpenAtAtime 130 | }) 131 | provide('getSlotByName', getSlotByName) 132 | provide('routerPushBlockList', routerPushBlockList) 133 | provide('pushToRouterPush', pushToRouterPush) 134 | provide('symbolId', symbolId) 135 | provide('browserAgent', userAgentHeight) 136 | provide('menuMounted', menuMounted) 137 | provide('miniMenu', miniMenu) 138 | provide('MenuScroll', MenuScroll) 139 | provide('MenuHover', MenuHover) 140 | provide('getRandomUid', getRandomUid) 141 | provide('updateCurrantItemHover', updateCurrantItemHover) 142 | provide('updateCurranContainerHover', updateCurranContainerHover) 143 | provide('CurrantItemHover', CurrantItemHover) 144 | provide('CurranContainerHover', CurranContainerHover) 145 | provide('menuDirection', menuDirection) 146 | provide('updateIsCollapsed', updateIsCollapsed) 147 | provide('emitOut', emitOut) 148 | return { 149 | getIsCollapsed: isCollapsed, 150 | getIsminiMenu: miniMenu, 151 | updateIsCollapsed, 152 | getSlotByName, 153 | updateminiMenu, 154 | menuMounted, 155 | updateMenuScroll, 156 | updateMenuHover, 157 | menuDirection, 158 | addIdToMenuItems 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 201 | 202 | 219 | 220 | 237 | -------------------------------------------------------------------------------- /src/scss/themes/dark-theme.scss: -------------------------------------------------------------------------------- 1 | //menu 2 | $menu-back-ground-color-dark: #0d1117 !default; 3 | $border-color-dark: rgba(170, 170, 170, 0.329) !default; 4 | $scroll-bar-color-dark: #686868 !default; 5 | $header-color-dark: #ffffffb3 !default; 6 | 7 | //menu item prepend icon 8 | $icon-color-dark: rgb(218, 221, 225) !default; 9 | $icon-active-color-dark: rgb(44, 122, 224) !default; 10 | $icon-mini-active-color-dark: rgb(44, 122, 224) !default; 11 | $icon-hover-color-dark: '' !default; 12 | 13 | //menu item 14 | $menu-item-bg-color-dark: none !default; 15 | $menu-item-hover-bg-dark: hsla(0, 0%, 100%, 0.05) !default; 16 | $menu-item-active-bg-color-dark: hsla(0, 0%, 100%, 0.05) !default; 17 | $mini-active-item-bg-color-dark: none !default; 18 | 19 | //menu item label 20 | $text-color-none-hover-dark: rgb(218, 221, 225) !default; 21 | $text-active-color-dark: rgb(44, 122, 224) !default; 22 | $text-mini-active-color-dark: rgb(44, 122, 224) !default; 23 | $text-hover-color-dark: none !default; 24 | 25 | //menu item append icon 26 | $append-icon-color-dark: rgb(218, 221, 225) !default; 27 | $append-active-icon-color-dark: rgb(218, 221, 225) !default; 28 | 29 | //horizental line 30 | $hr-line-color-dark: rgba(211, 211, 211, 0.548) !default; 31 | 32 | //bottomBtn for miniMenu 33 | $bottomBtn-bg-color-dark: #13161b !default; 34 | 35 | .vas-menu { 36 | &.dark-theme { 37 | background-color: $menu-back-ground-color-dark; 38 | .bottomBtn { 39 | background-color: $bottomBtn-bg-color-dark; 40 | } 41 | .vas-hr { 42 | border-color: $hr-line-color-dark; 43 | } 44 | &.rtl { 45 | border-left: 1px solid $border-color-dark; 46 | } 47 | &.ltr { 48 | border-right: 1px solid $border-color-dark; 49 | } 50 | ::-webkit-scrollbar-thumb { 51 | color: $scroll-bar-color-dark; 52 | } 53 | .vsss-header { 54 | color: $header-color-dark; 55 | } 56 | &.rtl { 57 | .topContainer { 58 | border-top: 1px solid $border-color-dark; 59 | border-bottom: 1px solid $border-color-dark; 60 | border-left: 1px solid $border-color-dark; 61 | background-color: $menu-back-ground-color-dark; 62 | } 63 | } 64 | &.ltr { 65 | .topContainer { 66 | border-top: 1px solid $border-color-dark; 67 | border-bottom: 1px solid $border-color-dark; 68 | border-right: 1px solid $border-color-dark; 69 | background-color: $menu-back-ground-color-dark; 70 | } 71 | } 72 | // .vas-simple { 73 | .hoverClass { 74 | background: $menu-item-hover-bg-dark; 75 | } 76 | .BlockBack { 77 | background-color: $menu-back-ground-color-dark; 78 | } 79 | .label { 80 | background-color: $menu-item-bg-color-dark; 81 | &.activeClass::before { 82 | background-color: $text-active-color-dark; 83 | } 84 | &.activeClass { 85 | background: $menu-item-active-bg-color-dark; 86 | color: $text-active-color-dark; 87 | .menu-icon { 88 | color: $icon-active-color-dark; 89 | } 90 | .icons { 91 | background: url('data:image/svg+xml;utf8,') 92 | 50%/2rem 2rem; 93 | -webkit-filter: url('data:image/svg+xml;utf8,'); 94 | filter: url('data:image/svg+xml;utf8,'); 95 | } 96 | } 97 | .menu-icon { 98 | color: $icon-color-dark; 99 | } 100 | 101 | &.miniActive { 102 | background: $mini-active-item-bg-color-dark; 103 | .labelName { 104 | color: $text-mini-active-color-dark; 105 | } 106 | .menu-icon { 107 | color: $icon-mini-active-color-dark; 108 | } 109 | } 110 | color: $text-color-none-hover-dark; 111 | &.labelHoverClass:hover { 112 | background-color: $menu-item-hover-bg-dark; 113 | .labelName { 114 | color: $text-hover-color-dark; 115 | } 116 | .menu-icon { 117 | color: $icon-hover-color-dark; 118 | } 119 | //color: $text-active-color-dark; 120 | } 121 | } 122 | .labelMini { 123 | &.activeClass::before { 124 | background-color: $text-active-color-dark; 125 | } 126 | overflow: hidden; 127 | background-color: $menu-item-hover-bg-dark; 128 | //background: rgb(54, 54, 54); 129 | // width: 30px; 130 | color: $text-color-none-hover-dark; 131 | &.activeClass { 132 | background-color: $menu-item-active-bg-color-dark; 133 | color: $text-active-color-dark; 134 | .menu-icon { 135 | color: $icon-active-color-dark; 136 | } 137 | } 138 | &.miniActive { 139 | background-color: $menu-item-hover-bg-dark; 140 | .labelName { 141 | color: $text-mini-active-color-dark; 142 | } 143 | .menu-icon { 144 | color: $icon-mini-active-color-dark; 145 | } 146 | } 147 | } 148 | .icons { 149 | background: url('data:image/svg+xml;utf8,') 150 | 50%/2rem 2rem; 151 | -webkit-filter: url('data:image/svg+xml;utf8,'); 152 | filter: url('data:image/svg+xml;utf8,'); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/scss/themes/white-theme.scss: -------------------------------------------------------------------------------- 1 | //menu 2 | $menu-back-ground-color-white: white !default; 3 | $border-color-white: #cfcfcf !default; 4 | $scroll-bar-color-white: rgb(184, 184, 184) !default; 5 | $header-color-white: #213547 !default; 6 | 7 | //menu item prepend icon 8 | $icon-color-white: rgb(28, 30, 33) !default; 9 | $icon-active-color-white: #2c7ae0 !default; 10 | $icon-mini-active-color-white: #2c7ae0 !default; 11 | $icon-hover-color-white: '' !default; 12 | 13 | //menu item 14 | $menu-item-bg-color-white: none !default; 15 | $menu-item-hover-bg-white: rgb(242, 242, 242) !default; 16 | $menu-item-active-bg-color-white: rgb(242, 242, 242) !default; 17 | $mini-active-item-bg-color-white: none !default; 18 | 19 | //menu item label 20 | $text-color-none-hover-white: rgb(28, 30, 33) !default; 21 | $text-active-color-white: #2c7ae0 !default; 22 | $text-mini-active-color-white: #2c7ae0 !default; 23 | $text-hover-color-white: none !default; 24 | 25 | //menu item append icon 26 | $append-icon-color-white: rgb(28, 30, 33) !default; 27 | $append-active-icon-color-white: rgb(28, 30, 33) !default; 28 | 29 | //horizental line 30 | $hr-line-color-white: rgba(211, 211, 211, 0.548) !default; 31 | 32 | //bottomBtn for miniMenu 33 | $bottomBtn-bg-color-white: rgba(228, 228, 228, 0.753) !default; 34 | 35 | .vas-menu { 36 | &.white-theme { 37 | background-color: $menu-back-ground-color-white; 38 | .bottomBtn { 39 | background-color: $bottomBtn-bg-color-white; 40 | } 41 | .vas-hr { 42 | border-color: $hr-line-color-white; 43 | } 44 | &.rtl { 45 | border-left: 1px solid $border-color-white; 46 | } 47 | &.ltr { 48 | border-right: 1px solid $border-color-white; 49 | } 50 | ::-webkit-scrollbar-thumb { 51 | color: $scroll-bar-color-white; 52 | } 53 | .topContainer::-webkit-scrollbar-thumb { 54 | color: $scroll-bar-color-white; 55 | } 56 | .vsss-header { 57 | color: $header-color-white; 58 | } 59 | &.rtl { 60 | .topContainer { 61 | border-top: 1px solid $border-color-white; 62 | border-bottom: 1px solid $border-color-white; 63 | border-left: 1px solid $border-color-white; 64 | background-color: $menu-back-ground-color-white; 65 | } 66 | } 67 | &.ltr { 68 | .topContainer { 69 | border-top: 1px solid $border-color-white; 70 | border-bottom: 1px solid $border-color-white; 71 | border-right: 1px solid $border-color-white; 72 | background-color: $menu-back-ground-color-white; 73 | } 74 | } 75 | // .vas-simple { 76 | .hoverClass { 77 | background: $menu-item-hover-bg-white; 78 | } 79 | .BlockBack { 80 | background-color: $menu-item-bg-color-white; 81 | } 82 | .label { 83 | background-color: $menu-item-bg-color-white; 84 | &.activeClass::before { 85 | background-color: $text-active-color-white; 86 | } 87 | &.activeClass { 88 | background: $menu-item-active-bg-color-white; 89 | color: $text-active-color-white; 90 | .menu-icon { 91 | color: $icon-active-color-white; 92 | } 93 | .icons { 94 | background: url('data:image/svg+xml;utf8,') 95 | 50%/2rem 2rem; 96 | -webkit-filter: url('data:image/svg+xml;utf8,'); 97 | filter: url('data:image/svg+xml;utf8,'); 98 | } 99 | } 100 | .menu-icon { 101 | color: $icon-color-white; 102 | } 103 | 104 | &.miniActive { 105 | background: $mini-active-item-bg-color-white; 106 | .labelName { 107 | color: $text-mini-active-color-white; 108 | } 109 | .menu-icon { 110 | color: $icon-mini-active-color-white; 111 | } 112 | } 113 | color: $text-color-none-hover-white; 114 | &.labelHoverClass:hover { 115 | background-color: $menu-item-hover-bg-white; 116 | .labelName { 117 | color: $text-hover-color-white; 118 | } 119 | .menu-icon { 120 | color: $icon-hover-color-white; 121 | } 122 | //color: $text-active-color-white; 123 | } 124 | } 125 | .labelMini { 126 | background-color: $menu-item-hover-bg-white; 127 | &.activeClass::before { 128 | background-color: $text-active-color-white; 129 | } 130 | overflow: hidden; 131 | //background: rgb(54, 54, 54); 132 | // width: 30px; 133 | color: $text-color-none-hover-white; 134 | &.activeClass { 135 | background-color: $menu-item-active-bg-color-white; 136 | color: $text-active-color-white; 137 | .menu-icon { 138 | color: $icon-active-color-white; 139 | } 140 | } 141 | &.miniActive { 142 | background: $menu-item-hover-bg-white; 143 | .labelName { 144 | color: $text-mini-active-color-white; 145 | } 146 | .menu-icon { 147 | color: $icon-mini-active-color-white; 148 | } 149 | } 150 | } 151 | .icons { 152 | background: url('data:image/svg+xml;utf8,') 153 | 50%/2rem 2rem; 154 | -webkit-filter: url('data:image/svg+xml;utf8,'); 155 | filter: url('data:image/svg+xml;utf8,'); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/components/Menu.vue: -------------------------------------------------------------------------------- 1 | 60 | 61 | 345 | 346 | 349 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vue Awesome Sidebar 3 | 4 | vue-wesome-sidebar 5 | 6 | ## About 7 | 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. 8 | 9 | ## Demo 10 | Check out Live demo at [**_amirkian007.github.io/vasmenu_**](https://amirkian007.github.io/vasmenu/) 11 | 12 | ## Features 13 | - Built with typescript and vite with 0 dependants. 14 | - Support for vue.js (3x) and nuxt.js (3x). 15 | - Customization support for every component slots , CSS and SASS. 16 | - Capable with Vue-router. 17 | - Multiple Menu types(more will be added in the future). 18 | - Complete RTL support. 19 | - Dark and White mode support. 20 | - Responsive design. 21 | 22 | # Table of Contents 23 | 24 | - [**_Demo_**](#demo) 25 | - [**_Installation_**](#installation) 26 | - [**_Basic Usage_**](#basic-usage) 27 | - [**_Api_**](#Api) 28 | - [**_Props_**](#props) 29 | - [**_Events_**](#events) 30 | - [**_Slots_**](#slots) 31 | - [**_Styling_**](#styling) 32 | - [**_Sass varibales_**](#sass-varibles) 33 | - [**_Css_**](#css-class) 34 | - [**_Author_**](#author) 35 | - [**_License_**](#license) 36 | 37 | 38 | # Installation 39 | 40 | ``` 41 | npm i vue-awesome-sidebar --save 42 | ``` 43 | or 44 | ``` 45 | yarn add vue-awesome-sidebar --save 46 | ``` 47 | 48 | Install the component globally. 49 | 50 | Vue js 3: 51 | ```js 52 | //main.js 53 | import { createApp } from 'vue' 54 | import App from './App.vue' 55 | import vueAwesomeSidebar from 'vue-awesome-sidebar' 56 | import 'vue-awesome-sidebar/dist/vue-awesome-sidebar.css' 57 | 58 | const app = createApp(App) 59 | app.use(vueAwesomeSidebar) 60 | app.mount("#app") 61 | ``` 62 | Nuxt js 3: 63 | ```js 64 | import vueAwesomeSidebar from "vue-awesome-sidebar"; 65 | import "vue-awesome-sidebar/dist/vue-awesome-sidebar.css"; 66 | export default defineNuxtPlugin((nuxtApp) => { 67 | nuxtApp.vueApp.use(vueAwesomeSidebar); 68 | }); 69 | ``` 70 | or Install the component loacally : 71 | ```js 72 | //App.vue 73 | import vueAwesomeSidebar from 'vue-awesome-sidebar' 74 | import 'vue-awesome-sidebar/dist/vue-awesome-sidebar.css' 75 | export default { 76 | components: { 77 | vueAwesomeSidebar 78 | } 79 | } 80 | ``` 81 | # Basic Usage 82 | 83 | a simple example would be like this : 84 | check out [**_props_**](#props) for properites 85 | 86 | NOTE : you have to load the icons separately like loading material-icons files with cdn 87 | 88 | ```html 89 | 90 | 98 | 99 | 145 | ``` 146 | 147 | ## Api 148 | 149 | ### Props 150 | 151 | | Prop | Type |Default| Description | 152 | |-----------------------|:-------:|:-----:|:--------------------------------------------------------------------------------------------------------| 153 | | menu | Array | null | required - Array list of [**_item properties_**](#menu-properties) | 154 | | menuType | string | simple| style of the menu can be either "fully" or "simple" | 155 | | collapsed | Boolean | false | sets menus collapsed state - should be used with v-model | 156 | | miniMenu | boolean | false | sets mini menus state - should be used with v-model | 157 | | width | string | 290px | sets width for menu | 158 | | widthMiniMenu | string | 65px | sets width for miniMenu | 159 | | autoCollapse | number | null | adds event listner to collapse menu when the given value(in px) is lower than the viewport width | 160 | | closeOnClickOutSide | Boolean | false | Adds event listner to collapse Menu when outside is clicked | 161 | | overLayerOnOpen | Boolean | false | Adds overlayer under the Menu when the menu is open - usefull on mobile | 162 | | childrenOpenAnimation | Boolean | true | opens menu items children with animation | 163 | | keepChildrenOpen | Boolean | flase | keeps children items opened when parent item is closed | 164 | | position | string | fixed | sets menu positiong - by default menu is fixed on viewport | 165 | |ChildrenOpenActiveRoute| Boolean | true |opens meneitem children on page-load if an item with active "href" inside and miniActive class is applied| 166 | | checkButtonActive | Boolean | true | checks if menuitems href is active, if so activeClass is added to it and miniActive class to the parent | 167 | | vueRouterEnabel | Boolean | true | when a meueitem is clicked vue-router will pushe the route to the items "href" property | 168 | | BottomMiniMenuBtn | Boolean | true | Adds mini menu toggle bottom to bottom of menu | 169 | | paddingTop | String | 0px | Adds padding to top of menu - usefull when using with app bar with higher z-index | 170 | | dark | Boolean | false | makes the theme of menu dark - color can be customized with sass vars | 171 | | rtl | Boolean | false | Makes the entire menu right to left align | 172 | |closeOpenMenuOnHrefPush| Boolean | false | close MenuItems with children that are expanded on router/herf push | 173 | |keepOneMenuOpenAtAtime | Boolean | false | keep one open menu at a time | 174 | 175 | ### menu properties 176 | 177 | ```ts 178 | interface MenuItem { 179 | href: string | object // vue-router Object 180 | name: string 181 | icon?: MenuItemIcon 182 | children?: Array< MenuItem | MenuHeaderItem > 183 | class?: string 184 | collapseOnClick?: boolean //collapses menu when clicked - this behavior can also be achieved with Events 185 | activeClass?: boolean 186 | miniActiveClass?: boolean 187 | } 188 | 189 | interface MenuItemIcon { 190 | text: string 191 | class?: string 192 | element?: string //defualt is 193 | attributes?: object 194 | } 195 | 196 | interface MenuHeaderItem { 197 | title: string 198 | class?: string 199 | attributes?: object 200 | } 201 | 202 | interface MenuLine { 203 | LineShow: boolean 204 | class?: string 205 | attributes?: object 206 | element?: string 207 | } 208 | ``` 209 | ### Events 210 | 211 | | Event Name | Description | 212 | |--------------------------------|:-----------------------------------------------------------------------| 213 | | `@item-click(MenuItem)` | fired when a menu item is clicked | 214 | |`@update:collapsed(isCollapsed)`| fired when menu collapse state changes - should be used with "v-model" | 215 | | `@update:miniMenu(isMiniMenu)` | fired when mini menu state changes - should be used with "v-model" | 216 | 217 | ### Slots 218 | 219 | ```html 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | ``` 235 | 236 | ## Styling 237 | 238 | ### Sass varibles 239 | to use sass varibles import the SCSS file insted of Css, then import custom varibles, 240 | example: 241 | ```scss 242 | //style.scss 243 | @import "custom-var.scss"; 244 | @import "vue-awesome-sidebar/src/scss/vue-awesome-sidebar.scss"; 245 | ``` 246 | ```js 247 | //main.js 248 | import vueAwesomeSidebar from 'vue-awesome-sidebar' 249 | //import 'vue-awesome-sidebar/dist/vue-awesome-sidebar.css' 250 | import './style.scss' 251 | ``` 252 | Sass varibles: 253 | ```scss 254 | //z-index of the menu components rage form 848-854 255 | 256 | //<--BASE--> 257 | $overlayer-bg-color: rgba(0, 0, 0, 0.6); 258 | $toggle-mini-btn-height: 50px; 259 | $menu-item-simpleType-icon-height: 35px; 260 | $menu-item-fullyType-height: 44px; 261 | $label-font-size: 16px;//may not work with slots 262 | $label-icon-size: 20px;//may not work with slots 263 | $scroll-bar-width: 13px; 264 | 265 | //<--COLORS--> 266 | //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 267 | //example :"$icon-color-dark : #000000 " for dark theme and "$icon-color-white : #fafafa " for white theme 268 | //note : may not work with slots depending on how the slots is used 269 | 270 | //Menu 271 | $menu-back-ground-color-white: white; -dark: #0d1117; //==> $menu-back-ground-color-dark:#0d1117 272 | $border-color-white: #cfcfcf; -dark: rgba(170, 170, 170, 0.329); 273 | $scroll-bar-color-white: rgb(184, 184, 184); -dark: #686868; 274 | $header-color-white: #213547; -dark: #ffffffde; 275 | 276 | //Menu item prepend icon 277 | $icon-color-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225); 278 | $icon-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224); 279 | $icon-mini-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224); 280 | $icon-hover-color-white: ''; -dark: ''; 281 | 282 | //Menu item 283 | $menu-item-bg-color-white: none; -dark: none; 284 | $menu-item-hover-bg-white: rgb(242, 242, 242); -dark: hsla(0, 0%, 100%, 0.05); 285 | $menu-item-active-bg-color-white: rgb(242, 242, 242); -dark: hsla(0, 0%, 100%, 0.05); 286 | $mini-active-item-bg-color-white: none; -dark: none; 287 | 288 | //Menu item label 289 | $text-color-none-hover-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225); 290 | $text-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224); 291 | $text-mini-active-color-white: #2c7ae0; -dark: rgb(44, 122, 224); 292 | $text-hover-color-white: none; -dark: none; 293 | 294 | //menu item append icon 295 | $append-icon-color-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225); 296 | $append-active-icon-color-white: rgb(28, 30, 33); -dark: rgb(218, 221, 225); 297 | 298 | //horizental line 299 | $hr-line-color-white: rgba(211, 211, 211, 0.548); -dark: rgba(211, 211, 211, 0.548); 300 | 301 | //bottomBtn for miniMenu 302 | $bottomBtn-bg-color-white: white; -dark: #13161b; 303 | ``` 304 | 305 | 306 | ### Css class 307 | 308 | ```scss 309 | //menu 310 | .vas-menu{} 311 | .menu-wraper{}//menu scroll wrapper 312 | .miniCoolapseMenu{} //for mini menu 313 | .compeleteCoolapseMenu{} //for collapsed menu 314 | .dark-theme{} 315 | .white-theme{} 316 | .vas-footer{} 317 | .bottomBtn{} // mini menutoggle button 318 | 319 | //menu item 320 | .menu-item-base{// wrapper for menu item ant children 321 | &.menuExpanded 322 | }//apllayed to all menuitem 323 | .menuExpanded{} 324 | .label{ 325 | .menu-icond{} 326 | .labelName{} 327 | .icons{} 328 | .postIconOpenAnima{} 329 | } 330 | .menuexpand{} 331 | .activeClass{} 332 | .miniActiveClass{} 333 | .labelHoverClass{} 334 | 335 | //container 336 | .items-container{} 337 | .topContainer{} 338 | ``` 339 | 340 | ## Contributing 341 | 342 | ``` bash 343 | $ pnpm i 344 | # dev server 345 | $ pnpm run dev 346 | ``` 347 | 348 | ## License 349 | 350 | vue-awesome-sidebar is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). -------------------------------------------------------------------------------- /src/components/MenuItem.vue: -------------------------------------------------------------------------------- 1 | 202 | 203 | 723 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | devDependencies: 8 | '@vitejs/plugin-vue': 9 | specifier: ^3.0.0 10 | version: 3.0.1(vite@3.0.4)(vue@3.2.37) 11 | material-icons: 12 | specifier: ^1.11.8 13 | version: 1.11.8 14 | prettier: 15 | specifier: ^2.7.1 16 | version: 2.7.1 17 | rollup-plugin-terser: 18 | specifier: ^7.0.2 19 | version: 7.0.2(rollup@2.77.2) 20 | sass: 21 | specifier: ^1.54.3 22 | version: 1.54.3 23 | typescript: 24 | specifier: ^4.6.4 25 | version: 4.7.4 26 | vite: 27 | specifier: ^3.0.0 28 | version: 3.0.4(sass@1.54.3) 29 | vue: 30 | specifier: ^3.2.37 31 | version: 3.2.37 32 | vue-router: 33 | specifier: '4' 34 | version: 4.1.5(vue@3.2.37) 35 | vue-tsc: 36 | specifier: ^0.38.4 37 | version: 0.38.9(typescript@4.7.4) 38 | 39 | packages: 40 | 41 | /@babel/code-frame@7.18.6: 42 | resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} 43 | engines: {node: '>=6.9.0'} 44 | dependencies: 45 | '@babel/highlight': 7.18.6 46 | dev: true 47 | 48 | /@babel/helper-string-parser@7.18.10: 49 | resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} 50 | engines: {node: '>=6.9.0'} 51 | dev: true 52 | 53 | /@babel/helper-validator-identifier@7.18.6: 54 | resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} 55 | engines: {node: '>=6.9.0'} 56 | dev: true 57 | 58 | /@babel/highlight@7.18.6: 59 | resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} 60 | engines: {node: '>=6.9.0'} 61 | dependencies: 62 | '@babel/helper-validator-identifier': 7.18.6 63 | chalk: 2.4.2 64 | js-tokens: 4.0.0 65 | dev: true 66 | 67 | /@babel/parser@7.18.11: 68 | resolution: {integrity: sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==} 69 | engines: {node: '>=6.0.0'} 70 | hasBin: true 71 | dependencies: 72 | '@babel/types': 7.18.10 73 | dev: true 74 | 75 | /@babel/types@7.18.10: 76 | resolution: {integrity: sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==} 77 | engines: {node: '>=6.9.0'} 78 | dependencies: 79 | '@babel/helper-string-parser': 7.18.10 80 | '@babel/helper-validator-identifier': 7.18.6 81 | to-fast-properties: 2.0.0 82 | dev: true 83 | 84 | /@esbuild/linux-loong64@0.14.54: 85 | resolution: {integrity: sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==} 86 | engines: {node: '>=12'} 87 | cpu: [loong64] 88 | os: [linux] 89 | requiresBuild: true 90 | dev: true 91 | optional: true 92 | 93 | /@jridgewell/gen-mapping@0.3.2: 94 | resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} 95 | engines: {node: '>=6.0.0'} 96 | dependencies: 97 | '@jridgewell/set-array': 1.1.2 98 | '@jridgewell/sourcemap-codec': 1.4.14 99 | '@jridgewell/trace-mapping': 0.3.15 100 | dev: true 101 | 102 | /@jridgewell/resolve-uri@3.1.0: 103 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 104 | engines: {node: '>=6.0.0'} 105 | dev: true 106 | 107 | /@jridgewell/set-array@1.1.2: 108 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 109 | engines: {node: '>=6.0.0'} 110 | dev: true 111 | 112 | /@jridgewell/source-map@0.3.2: 113 | resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} 114 | dependencies: 115 | '@jridgewell/gen-mapping': 0.3.2 116 | '@jridgewell/trace-mapping': 0.3.15 117 | dev: true 118 | 119 | /@jridgewell/sourcemap-codec@1.4.14: 120 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 121 | dev: true 122 | 123 | /@jridgewell/trace-mapping@0.3.15: 124 | resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==} 125 | dependencies: 126 | '@jridgewell/resolve-uri': 3.1.0 127 | '@jridgewell/sourcemap-codec': 1.4.14 128 | dev: true 129 | 130 | /@types/node@18.7.18: 131 | resolution: {integrity: sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==} 132 | dev: true 133 | 134 | /@vitejs/plugin-vue@3.0.1(vite@3.0.4)(vue@3.2.37): 135 | resolution: {integrity: sha512-Ll9JgxG7ONIz/XZv3dssfoMUDu9qAnlJ+km+pBA0teYSXzwPCIzS/e1bmwNYl5dcQGs677D21amgfYAnzMl17A==} 136 | engines: {node: ^14.18.0 || >=16.0.0} 137 | peerDependencies: 138 | vite: ^3.0.0 139 | vue: ^3.2.25 140 | dependencies: 141 | vite: 3.0.4(sass@1.54.3) 142 | vue: 3.2.37 143 | dev: true 144 | 145 | /@volar/code-gen@0.38.9: 146 | resolution: {integrity: sha512-n6LClucfA+37rQeskvh9vDoZV1VvCVNy++MAPKj2dT4FT+Fbmty/SDQqnsEBtdEe6E3OQctFvA/IcKsx3Mns0A==} 147 | dependencies: 148 | '@volar/source-map': 0.38.9 149 | dev: true 150 | 151 | /@volar/source-map@0.38.9: 152 | resolution: {integrity: sha512-ba0UFoHDYry+vwKdgkWJ6xlQT+8TFtZg1zj9tSjj4PykW1JZDuM0xplMotLun4h3YOoYfY9K1huY5gvxmrNLIw==} 153 | dev: true 154 | 155 | /@volar/vue-code-gen@0.38.9: 156 | resolution: {integrity: sha512-tzj7AoarFBKl7e41MR006ncrEmNPHALuk8aG4WdDIaG387X5//5KhWC5Ff3ZfB2InGSeNT+CVUd74M0gS20rjA==} 157 | dependencies: 158 | '@volar/code-gen': 0.38.9 159 | '@volar/source-map': 0.38.9 160 | '@vue/compiler-core': 3.2.37 161 | '@vue/compiler-dom': 3.2.37 162 | '@vue/shared': 3.2.37 163 | dev: true 164 | 165 | /@volar/vue-typescript@0.38.9: 166 | resolution: {integrity: sha512-iJMQGU91ADi98u8V1vXd2UBmELDAaeSP0ZJaFjwosClQdKlJQYc6MlxxKfXBZisHqfbhdtrGRyaryulnYtliZw==} 167 | dependencies: 168 | '@volar/code-gen': 0.38.9 169 | '@volar/source-map': 0.38.9 170 | '@volar/vue-code-gen': 0.38.9 171 | '@vue/compiler-sfc': 3.2.37 172 | '@vue/reactivity': 3.2.37 173 | dev: true 174 | 175 | /@vue/compiler-core@3.2.37: 176 | resolution: {integrity: sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg==} 177 | dependencies: 178 | '@babel/parser': 7.18.11 179 | '@vue/shared': 3.2.37 180 | estree-walker: 2.0.2 181 | source-map: 0.6.1 182 | dev: true 183 | 184 | /@vue/compiler-dom@3.2.37: 185 | resolution: {integrity: sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==} 186 | dependencies: 187 | '@vue/compiler-core': 3.2.37 188 | '@vue/shared': 3.2.37 189 | dev: true 190 | 191 | /@vue/compiler-sfc@3.2.37: 192 | resolution: {integrity: sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==} 193 | dependencies: 194 | '@babel/parser': 7.18.11 195 | '@vue/compiler-core': 3.2.37 196 | '@vue/compiler-dom': 3.2.37 197 | '@vue/compiler-ssr': 3.2.37 198 | '@vue/reactivity-transform': 3.2.37 199 | '@vue/shared': 3.2.37 200 | estree-walker: 2.0.2 201 | magic-string: 0.25.9 202 | postcss: 8.4.16 203 | source-map: 0.6.1 204 | dev: true 205 | 206 | /@vue/compiler-ssr@3.2.37: 207 | resolution: {integrity: sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==} 208 | dependencies: 209 | '@vue/compiler-dom': 3.2.37 210 | '@vue/shared': 3.2.37 211 | dev: true 212 | 213 | /@vue/devtools-api@6.4.4: 214 | resolution: {integrity: sha512-Ku31WzpOV/8cruFaXaEZKF81WkNnvCSlBY4eOGtz5WMSdJvX1v1WWlSMGZeqUwPtQ27ZZz7B62erEMq8JDjcXw==} 215 | dev: true 216 | 217 | /@vue/reactivity-transform@3.2.37: 218 | resolution: {integrity: sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg==} 219 | dependencies: 220 | '@babel/parser': 7.18.11 221 | '@vue/compiler-core': 3.2.37 222 | '@vue/shared': 3.2.37 223 | estree-walker: 2.0.2 224 | magic-string: 0.25.9 225 | dev: true 226 | 227 | /@vue/reactivity@3.2.37: 228 | resolution: {integrity: sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==} 229 | dependencies: 230 | '@vue/shared': 3.2.37 231 | dev: true 232 | 233 | /@vue/runtime-core@3.2.37: 234 | resolution: {integrity: sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==} 235 | dependencies: 236 | '@vue/reactivity': 3.2.37 237 | '@vue/shared': 3.2.37 238 | dev: true 239 | 240 | /@vue/runtime-dom@3.2.37: 241 | resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} 242 | dependencies: 243 | '@vue/runtime-core': 3.2.37 244 | '@vue/shared': 3.2.37 245 | csstype: 2.6.20 246 | dev: true 247 | 248 | /@vue/server-renderer@3.2.37(vue@3.2.37): 249 | resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} 250 | peerDependencies: 251 | vue: 3.2.37 252 | dependencies: 253 | '@vue/compiler-ssr': 3.2.37 254 | '@vue/shared': 3.2.37 255 | vue: 3.2.37 256 | dev: true 257 | 258 | /@vue/shared@3.2.37: 259 | resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} 260 | dev: true 261 | 262 | /acorn@8.8.0: 263 | resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} 264 | engines: {node: '>=0.4.0'} 265 | hasBin: true 266 | dev: true 267 | 268 | /ansi-styles@3.2.1: 269 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 270 | engines: {node: '>=4'} 271 | dependencies: 272 | color-convert: 1.9.3 273 | dev: true 274 | 275 | /anymatch@3.1.2: 276 | resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} 277 | engines: {node: '>= 8'} 278 | dependencies: 279 | normalize-path: 3.0.0 280 | picomatch: 2.3.1 281 | dev: true 282 | 283 | /binary-extensions@2.2.0: 284 | resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} 285 | engines: {node: '>=8'} 286 | dev: true 287 | 288 | /braces@3.0.2: 289 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 290 | engines: {node: '>=8'} 291 | dependencies: 292 | fill-range: 7.0.1 293 | dev: true 294 | 295 | /buffer-from@1.1.2: 296 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 297 | dev: true 298 | 299 | /chalk@2.4.2: 300 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 301 | engines: {node: '>=4'} 302 | dependencies: 303 | ansi-styles: 3.2.1 304 | escape-string-regexp: 1.0.5 305 | supports-color: 5.5.0 306 | dev: true 307 | 308 | /chokidar@3.5.3: 309 | resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} 310 | engines: {node: '>= 8.10.0'} 311 | dependencies: 312 | anymatch: 3.1.2 313 | braces: 3.0.2 314 | glob-parent: 5.1.2 315 | is-binary-path: 2.1.0 316 | is-glob: 4.0.3 317 | normalize-path: 3.0.0 318 | readdirp: 3.6.0 319 | optionalDependencies: 320 | fsevents: 2.3.2 321 | dev: true 322 | 323 | /color-convert@1.9.3: 324 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 325 | dependencies: 326 | color-name: 1.1.3 327 | dev: true 328 | 329 | /color-name@1.1.3: 330 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 331 | dev: true 332 | 333 | /commander@2.20.3: 334 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 335 | dev: true 336 | 337 | /csstype@2.6.20: 338 | resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} 339 | dev: true 340 | 341 | /esbuild-android-64@0.14.54: 342 | resolution: {integrity: sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==} 343 | engines: {node: '>=12'} 344 | cpu: [x64] 345 | os: [android] 346 | requiresBuild: true 347 | dev: true 348 | optional: true 349 | 350 | /esbuild-android-arm64@0.14.54: 351 | resolution: {integrity: sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==} 352 | engines: {node: '>=12'} 353 | cpu: [arm64] 354 | os: [android] 355 | requiresBuild: true 356 | dev: true 357 | optional: true 358 | 359 | /esbuild-darwin-64@0.14.54: 360 | resolution: {integrity: sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==} 361 | engines: {node: '>=12'} 362 | cpu: [x64] 363 | os: [darwin] 364 | requiresBuild: true 365 | dev: true 366 | optional: true 367 | 368 | /esbuild-darwin-arm64@0.14.54: 369 | resolution: {integrity: sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==} 370 | engines: {node: '>=12'} 371 | cpu: [arm64] 372 | os: [darwin] 373 | requiresBuild: true 374 | dev: true 375 | optional: true 376 | 377 | /esbuild-freebsd-64@0.14.54: 378 | resolution: {integrity: sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==} 379 | engines: {node: '>=12'} 380 | cpu: [x64] 381 | os: [freebsd] 382 | requiresBuild: true 383 | dev: true 384 | optional: true 385 | 386 | /esbuild-freebsd-arm64@0.14.54: 387 | resolution: {integrity: sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==} 388 | engines: {node: '>=12'} 389 | cpu: [arm64] 390 | os: [freebsd] 391 | requiresBuild: true 392 | dev: true 393 | optional: true 394 | 395 | /esbuild-linux-32@0.14.54: 396 | resolution: {integrity: sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==} 397 | engines: {node: '>=12'} 398 | cpu: [ia32] 399 | os: [linux] 400 | requiresBuild: true 401 | dev: true 402 | optional: true 403 | 404 | /esbuild-linux-64@0.14.54: 405 | resolution: {integrity: sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==} 406 | engines: {node: '>=12'} 407 | cpu: [x64] 408 | os: [linux] 409 | requiresBuild: true 410 | dev: true 411 | optional: true 412 | 413 | /esbuild-linux-arm64@0.14.54: 414 | resolution: {integrity: sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==} 415 | engines: {node: '>=12'} 416 | cpu: [arm64] 417 | os: [linux] 418 | requiresBuild: true 419 | dev: true 420 | optional: true 421 | 422 | /esbuild-linux-arm@0.14.54: 423 | resolution: {integrity: sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==} 424 | engines: {node: '>=12'} 425 | cpu: [arm] 426 | os: [linux] 427 | requiresBuild: true 428 | dev: true 429 | optional: true 430 | 431 | /esbuild-linux-mips64le@0.14.54: 432 | resolution: {integrity: sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==} 433 | engines: {node: '>=12'} 434 | cpu: [mips64el] 435 | os: [linux] 436 | requiresBuild: true 437 | dev: true 438 | optional: true 439 | 440 | /esbuild-linux-ppc64le@0.14.54: 441 | resolution: {integrity: sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==} 442 | engines: {node: '>=12'} 443 | cpu: [ppc64] 444 | os: [linux] 445 | requiresBuild: true 446 | dev: true 447 | optional: true 448 | 449 | /esbuild-linux-riscv64@0.14.54: 450 | resolution: {integrity: sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==} 451 | engines: {node: '>=12'} 452 | cpu: [riscv64] 453 | os: [linux] 454 | requiresBuild: true 455 | dev: true 456 | optional: true 457 | 458 | /esbuild-linux-s390x@0.14.54: 459 | resolution: {integrity: sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==} 460 | engines: {node: '>=12'} 461 | cpu: [s390x] 462 | os: [linux] 463 | requiresBuild: true 464 | dev: true 465 | optional: true 466 | 467 | /esbuild-netbsd-64@0.14.54: 468 | resolution: {integrity: sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==} 469 | engines: {node: '>=12'} 470 | cpu: [x64] 471 | os: [netbsd] 472 | requiresBuild: true 473 | dev: true 474 | optional: true 475 | 476 | /esbuild-openbsd-64@0.14.54: 477 | resolution: {integrity: sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==} 478 | engines: {node: '>=12'} 479 | cpu: [x64] 480 | os: [openbsd] 481 | requiresBuild: true 482 | dev: true 483 | optional: true 484 | 485 | /esbuild-sunos-64@0.14.54: 486 | resolution: {integrity: sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==} 487 | engines: {node: '>=12'} 488 | cpu: [x64] 489 | os: [sunos] 490 | requiresBuild: true 491 | dev: true 492 | optional: true 493 | 494 | /esbuild-windows-32@0.14.54: 495 | resolution: {integrity: sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==} 496 | engines: {node: '>=12'} 497 | cpu: [ia32] 498 | os: [win32] 499 | requiresBuild: true 500 | dev: true 501 | optional: true 502 | 503 | /esbuild-windows-64@0.14.54: 504 | resolution: {integrity: sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==} 505 | engines: {node: '>=12'} 506 | cpu: [x64] 507 | os: [win32] 508 | requiresBuild: true 509 | dev: true 510 | optional: true 511 | 512 | /esbuild-windows-arm64@0.14.54: 513 | resolution: {integrity: sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==} 514 | engines: {node: '>=12'} 515 | cpu: [arm64] 516 | os: [win32] 517 | requiresBuild: true 518 | dev: true 519 | optional: true 520 | 521 | /esbuild@0.14.54: 522 | resolution: {integrity: sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==} 523 | engines: {node: '>=12'} 524 | hasBin: true 525 | requiresBuild: true 526 | optionalDependencies: 527 | '@esbuild/linux-loong64': 0.14.54 528 | esbuild-android-64: 0.14.54 529 | esbuild-android-arm64: 0.14.54 530 | esbuild-darwin-64: 0.14.54 531 | esbuild-darwin-arm64: 0.14.54 532 | esbuild-freebsd-64: 0.14.54 533 | esbuild-freebsd-arm64: 0.14.54 534 | esbuild-linux-32: 0.14.54 535 | esbuild-linux-64: 0.14.54 536 | esbuild-linux-arm: 0.14.54 537 | esbuild-linux-arm64: 0.14.54 538 | esbuild-linux-mips64le: 0.14.54 539 | esbuild-linux-ppc64le: 0.14.54 540 | esbuild-linux-riscv64: 0.14.54 541 | esbuild-linux-s390x: 0.14.54 542 | esbuild-netbsd-64: 0.14.54 543 | esbuild-openbsd-64: 0.14.54 544 | esbuild-sunos-64: 0.14.54 545 | esbuild-windows-32: 0.14.54 546 | esbuild-windows-64: 0.14.54 547 | esbuild-windows-arm64: 0.14.54 548 | dev: true 549 | 550 | /escape-string-regexp@1.0.5: 551 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 552 | engines: {node: '>=0.8.0'} 553 | dev: true 554 | 555 | /estree-walker@2.0.2: 556 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 557 | dev: true 558 | 559 | /fill-range@7.0.1: 560 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 561 | engines: {node: '>=8'} 562 | dependencies: 563 | to-regex-range: 5.0.1 564 | dev: true 565 | 566 | /fsevents@2.3.2: 567 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 568 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 569 | os: [darwin] 570 | requiresBuild: true 571 | dev: true 572 | optional: true 573 | 574 | /function-bind@1.1.1: 575 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 576 | dev: true 577 | 578 | /glob-parent@5.1.2: 579 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 580 | engines: {node: '>= 6'} 581 | dependencies: 582 | is-glob: 4.0.3 583 | dev: true 584 | 585 | /has-flag@3.0.0: 586 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 587 | engines: {node: '>=4'} 588 | dev: true 589 | 590 | /has-flag@4.0.0: 591 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 592 | engines: {node: '>=8'} 593 | dev: true 594 | 595 | /has@1.0.3: 596 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 597 | engines: {node: '>= 0.4.0'} 598 | dependencies: 599 | function-bind: 1.1.1 600 | dev: true 601 | 602 | /immutable@4.1.0: 603 | resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} 604 | dev: true 605 | 606 | /is-binary-path@2.1.0: 607 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 608 | engines: {node: '>=8'} 609 | dependencies: 610 | binary-extensions: 2.2.0 611 | dev: true 612 | 613 | /is-core-module@2.10.0: 614 | resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} 615 | dependencies: 616 | has: 1.0.3 617 | dev: true 618 | 619 | /is-extglob@2.1.1: 620 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 621 | engines: {node: '>=0.10.0'} 622 | dev: true 623 | 624 | /is-glob@4.0.3: 625 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 626 | engines: {node: '>=0.10.0'} 627 | dependencies: 628 | is-extglob: 2.1.1 629 | dev: true 630 | 631 | /is-number@7.0.0: 632 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 633 | engines: {node: '>=0.12.0'} 634 | dev: true 635 | 636 | /jest-worker@26.6.2: 637 | resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} 638 | engines: {node: '>= 10.13.0'} 639 | dependencies: 640 | '@types/node': 18.7.18 641 | merge-stream: 2.0.0 642 | supports-color: 7.2.0 643 | dev: true 644 | 645 | /js-tokens@4.0.0: 646 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 647 | dev: true 648 | 649 | /magic-string@0.25.9: 650 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 651 | dependencies: 652 | sourcemap-codec: 1.4.8 653 | dev: true 654 | 655 | /material-icons@1.11.8: 656 | resolution: {integrity: sha512-PDvpRAtH7JTKJIuJgyry2MsfxxPfTj0RMBUNHkE+wzk+OBXuyltlAYqXZALtjHFqcOh7kNDe6guFLJ1r33VUbA==} 657 | dev: true 658 | 659 | /merge-stream@2.0.0: 660 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 661 | dev: true 662 | 663 | /nanoid@3.3.4: 664 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 665 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 666 | hasBin: true 667 | dev: true 668 | 669 | /normalize-path@3.0.0: 670 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 671 | engines: {node: '>=0.10.0'} 672 | dev: true 673 | 674 | /path-parse@1.0.7: 675 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 676 | dev: true 677 | 678 | /picocolors@1.0.0: 679 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 680 | dev: true 681 | 682 | /picomatch@2.3.1: 683 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 684 | engines: {node: '>=8.6'} 685 | dev: true 686 | 687 | /postcss@8.4.16: 688 | resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} 689 | engines: {node: ^10 || ^12 || >=14} 690 | dependencies: 691 | nanoid: 3.3.4 692 | picocolors: 1.0.0 693 | source-map-js: 1.0.2 694 | dev: true 695 | 696 | /prettier@2.7.1: 697 | resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} 698 | engines: {node: '>=10.13.0'} 699 | hasBin: true 700 | dev: true 701 | 702 | /randombytes@2.1.0: 703 | resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} 704 | dependencies: 705 | safe-buffer: 5.2.1 706 | dev: true 707 | 708 | /readdirp@3.6.0: 709 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 710 | engines: {node: '>=8.10.0'} 711 | dependencies: 712 | picomatch: 2.3.1 713 | dev: true 714 | 715 | /resolve@1.22.1: 716 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 717 | hasBin: true 718 | dependencies: 719 | is-core-module: 2.10.0 720 | path-parse: 1.0.7 721 | supports-preserve-symlinks-flag: 1.0.0 722 | dev: true 723 | 724 | /rollup-plugin-terser@7.0.2(rollup@2.77.2): 725 | resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} 726 | peerDependencies: 727 | rollup: ^2.0.0 728 | dependencies: 729 | '@babel/code-frame': 7.18.6 730 | jest-worker: 26.6.2 731 | rollup: 2.77.2 732 | serialize-javascript: 4.0.0 733 | terser: 5.15.0 734 | dev: true 735 | 736 | /rollup@2.77.2: 737 | resolution: {integrity: sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==} 738 | engines: {node: '>=10.0.0'} 739 | hasBin: true 740 | optionalDependencies: 741 | fsevents: 2.3.2 742 | dev: true 743 | 744 | /safe-buffer@5.2.1: 745 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 746 | dev: true 747 | 748 | /sass@1.54.3: 749 | resolution: {integrity: sha512-fLodey5Qd41Pxp/Tk7Al97sViYwF/TazRc5t6E65O7JOk4XF8pzwIW7CvCxYVOfJFFI/1x5+elDyBIixrp+zrw==} 750 | engines: {node: '>=12.0.0'} 751 | hasBin: true 752 | dependencies: 753 | chokidar: 3.5.3 754 | immutable: 4.1.0 755 | source-map-js: 1.0.2 756 | dev: true 757 | 758 | /serialize-javascript@4.0.0: 759 | resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} 760 | dependencies: 761 | randombytes: 2.1.0 762 | dev: true 763 | 764 | /source-map-js@1.0.2: 765 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 766 | engines: {node: '>=0.10.0'} 767 | dev: true 768 | 769 | /source-map-support@0.5.21: 770 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 771 | dependencies: 772 | buffer-from: 1.1.2 773 | source-map: 0.6.1 774 | dev: true 775 | 776 | /source-map@0.6.1: 777 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 778 | engines: {node: '>=0.10.0'} 779 | dev: true 780 | 781 | /sourcemap-codec@1.4.8: 782 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 783 | dev: true 784 | 785 | /supports-color@5.5.0: 786 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 787 | engines: {node: '>=4'} 788 | dependencies: 789 | has-flag: 3.0.0 790 | dev: true 791 | 792 | /supports-color@7.2.0: 793 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 794 | engines: {node: '>=8'} 795 | dependencies: 796 | has-flag: 4.0.0 797 | dev: true 798 | 799 | /supports-preserve-symlinks-flag@1.0.0: 800 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 801 | engines: {node: '>= 0.4'} 802 | dev: true 803 | 804 | /terser@5.15.0: 805 | resolution: {integrity: sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA==} 806 | engines: {node: '>=10'} 807 | hasBin: true 808 | dependencies: 809 | '@jridgewell/source-map': 0.3.2 810 | acorn: 8.8.0 811 | commander: 2.20.3 812 | source-map-support: 0.5.21 813 | dev: true 814 | 815 | /to-fast-properties@2.0.0: 816 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 817 | engines: {node: '>=4'} 818 | dev: true 819 | 820 | /to-regex-range@5.0.1: 821 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 822 | engines: {node: '>=8.0'} 823 | dependencies: 824 | is-number: 7.0.0 825 | dev: true 826 | 827 | /typescript@4.7.4: 828 | resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} 829 | engines: {node: '>=4.2.0'} 830 | hasBin: true 831 | dev: true 832 | 833 | /vite@3.0.4(sass@1.54.3): 834 | resolution: {integrity: sha512-NU304nqnBeOx2MkQnskBQxVsa0pRAH5FphokTGmyy8M3oxbvw7qAXts2GORxs+h/2vKsD+osMhZ7An6yK6F1dA==} 835 | engines: {node: ^14.18.0 || >=16.0.0} 836 | hasBin: true 837 | peerDependencies: 838 | less: '*' 839 | sass: '*' 840 | stylus: '*' 841 | terser: ^5.4.0 842 | peerDependenciesMeta: 843 | less: 844 | optional: true 845 | sass: 846 | optional: true 847 | stylus: 848 | optional: true 849 | terser: 850 | optional: true 851 | dependencies: 852 | esbuild: 0.14.54 853 | postcss: 8.4.16 854 | resolve: 1.22.1 855 | rollup: 2.77.2 856 | sass: 1.54.3 857 | optionalDependencies: 858 | fsevents: 2.3.2 859 | dev: true 860 | 861 | /vue-router@4.1.5(vue@3.2.37): 862 | resolution: {integrity: sha512-IsvoF5D2GQ/EGTs/Th4NQms9gd2NSqV+yylxIyp/OYp8xOwxmU8Kj/74E9DTSYAyH5LX7idVUngN3JSj1X4xcQ==} 863 | peerDependencies: 864 | vue: ^3.2.0 865 | dependencies: 866 | '@vue/devtools-api': 6.4.4 867 | vue: 3.2.37 868 | dev: true 869 | 870 | /vue-tsc@0.38.9(typescript@4.7.4): 871 | resolution: {integrity: sha512-Yoy5phgvGqyF98Fb4mYqboR4Q149jrdcGv5kSmufXJUq++RZJ2iMVG0g6zl+v3t4ORVWkQmRpsV4x2szufZ0LQ==} 872 | hasBin: true 873 | peerDependencies: 874 | typescript: '*' 875 | dependencies: 876 | '@volar/vue-typescript': 0.38.9 877 | typescript: 4.7.4 878 | dev: true 879 | 880 | /vue@3.2.37: 881 | resolution: {integrity: sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ==} 882 | dependencies: 883 | '@vue/compiler-dom': 3.2.37 884 | '@vue/compiler-sfc': 3.2.37 885 | '@vue/runtime-dom': 3.2.37 886 | '@vue/server-renderer': 3.2.37(vue@3.2.37) 887 | '@vue/shared': 3.2.37 888 | dev: true 889 | --------------------------------------------------------------------------------