feat: Added Navbar component
This commit is contained in:
@@ -47,11 +47,11 @@ function getComponents() {
|
|||||||
{ text: 'ListGroup', link: 'components/listGroup/listGroup.md' },
|
{ text: 'ListGroup', link: 'components/listGroup/listGroup.md' },
|
||||||
{ text: 'Toast', link: 'components/toast/toast.md' },
|
{ text: 'Toast', link: 'components/toast/toast.md' },
|
||||||
{ text: 'Modal', link: 'components/modal/modal.md' },
|
{ text: 'Modal', link: 'components/modal/modal.md' },
|
||||||
|
{ text: 'Navbar', link: 'components/navbar/navbar.md' },
|
||||||
|
|
||||||
{ text: '- Accordion', link: 'components/accordion/accordion.md' },
|
{ text: '- Accordion', link: 'components/accordion/accordion.md' },
|
||||||
{ text: '- Carousel', link: 'components/carousel/carousel.md' },
|
{ text: '- Carousel', link: 'components/carousel/carousel.md' },
|
||||||
{ text: '- Footer', link: 'components/footer/footer.md' },
|
{ text: '- Footer', link: 'components/footer/footer.md' },
|
||||||
{ text: '- Navbar', link: 'components/navbar/navbar.md' },
|
|
||||||
{ text: '- Pagination', link: 'components/pagination/pagination.md' },
|
{ text: '- Pagination', link: 'components/pagination/pagination.md' },
|
||||||
{ text: '- Progress', link: 'components/progress/progress.md' },
|
{ text: '- Progress', link: 'components/progress/progress.md' },
|
||||||
{ text: '- Rating', link: 'components/rating/rating.md' },
|
{ text: '- Rating', link: 'components/rating/rating.md' },
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vp-raw flex flex-col">
|
||||||
|
<Navbar>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink is-active>Home</NavbarLink>
|
||||||
|
<NavbarLink>Services</NavbarLink>
|
||||||
|
<NavbarLink>Pricing</NavbarLink>
|
||||||
|
<NavbarLink>Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
<template #right-side>
|
||||||
|
<button type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-3 md:mr-0 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Get started</button>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from '../../../../src/index'
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vp-raw flex flex-col">
|
||||||
|
<Navbar>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink is-active>Home</NavbarLink>
|
||||||
|
<NavbarLink>Services</NavbarLink>
|
||||||
|
<NavbarLink>Pricing</NavbarLink>
|
||||||
|
<NavbarLink>Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
<template #menu-icon>
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"></path></svg>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from '../../../../src/index'
|
||||||
|
</script>
|
||||||
@@ -1,8 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="vp-raw flex flex-col">
|
<div class="vp-raw flex flex-col">
|
||||||
<Navbar></Navbar>
|
<Navbar>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink isActive link="#">Home</NavbarLink>
|
||||||
|
<NavbarLink link="#">Services</NavbarLink>
|
||||||
|
<NavbarLink link="#">Pricing</NavbarLink>
|
||||||
|
<NavbarLink link="#">Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Navbar } from '../../../../src/index'
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from '../../../../src/index'
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
22
docs/components/navbar/examples/NavbarSolidExample.vue
Normal file
22
docs/components/navbar/examples/NavbarSolidExample.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div class="vp-raw flex flex-col">
|
||||||
|
<Navbar solid>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink is-active>Home</NavbarLink>
|
||||||
|
<NavbarLink>Services</NavbarLink>
|
||||||
|
<NavbarLink>Pricing</NavbarLink>
|
||||||
|
<NavbarLink>Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from '../../../../src/index'
|
||||||
|
</script>
|
||||||
@@ -1,15 +1,119 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import NavbarExample from './examples/NavbarExample.vue'
|
import NavbarExample from './examples/NavbarExample.vue'
|
||||||
|
import NavbarSolidExample from './examples/NavbarSolidExample.vue'
|
||||||
|
import NavbarActionButtonExample from './examples/NavbarActionButtonExample.vue'
|
||||||
|
import NavbarCustomMobileIconExample from './examples/NavbarCustomMobileIconExample.vue'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
# Vue Navbar Component - Flowbite
|
# Navbar Component – Flowbite
|
||||||
|
The navbar component can be used to show a list of navigation links positioned on the top side of your page based on multiple layouts, sizes, and dropdowns
|
||||||
|
|
||||||
|
## Default navbar
|
||||||
|
|
||||||
```vue
|
```vue
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Navbar } from 'flowbite-vue'
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from 'flowbite-vue'
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Navbar></Navbar>
|
<Navbar>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink isActive link="#">Home</NavbarLink>
|
||||||
|
<NavbarLink link="#">Services</NavbarLink>
|
||||||
|
<NavbarLink link="#">Pricing</NavbarLink>
|
||||||
|
<NavbarLink link="#">Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
</template>
|
</template>
|
||||||
```
|
```
|
||||||
|
|
||||||
<NavbarExample />
|
<NavbarExample />
|
||||||
|
|
||||||
|
## Solid navbar
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from 'flowbite-vue'
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Navbar solid>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink is-active>Home</NavbarLink>
|
||||||
|
<NavbarLink>Services</NavbarLink>
|
||||||
|
<NavbarLink>Pricing</NavbarLink>
|
||||||
|
<NavbarLink>Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
<NavbarSolidExample />
|
||||||
|
|
||||||
|
## Navbar with action button
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from 'flowbite-vue'
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Navbar>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink is-active>Home</NavbarLink>
|
||||||
|
<NavbarLink>Services</NavbarLink>
|
||||||
|
<NavbarLink>Pricing</NavbarLink>
|
||||||
|
<NavbarLink>Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
<template #right-side>
|
||||||
|
<button type="button" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-3 md:mr-0 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Get started</button>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
<NavbarActionButtonExample />
|
||||||
|
|
||||||
|
## Navbar with custom mobile icon
|
||||||
|
```vue
|
||||||
|
<script setup>
|
||||||
|
import { Navbar, NavbarLogo, NavbarCollapse, NavbarLink } from 'flowbite-vue'
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Navbar>
|
||||||
|
<template #logo>
|
||||||
|
<NavbarLogo link="https://www.google.com/" alt="Flowbite logo" image-url="https://flowbite.com/docs/images/logo.svg">
|
||||||
|
Flowbite
|
||||||
|
</NavbarLogo>
|
||||||
|
</template>
|
||||||
|
<template #default="{isShowMenu}">
|
||||||
|
<NavbarCollapse :isShowMenu="isShowMenu">
|
||||||
|
<NavbarLink is-active>Home</NavbarLink>
|
||||||
|
<NavbarLink>Services</NavbarLink>
|
||||||
|
<NavbarLink>Pricing</NavbarLink>
|
||||||
|
<NavbarLink>Contact</NavbarLink>
|
||||||
|
</NavbarCollapse>
|
||||||
|
</template>
|
||||||
|
<template #menu-icon>
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"></path></svg>
|
||||||
|
</template>
|
||||||
|
</Navbar>
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
<NavbarCustomMobileIconExample />
|
||||||
|
|||||||
19
package.json
19
package.json
@@ -32,8 +32,8 @@
|
|||||||
"typecheck": "vue-tsc --noEmit"
|
"typecheck": "vue-tsc --noEmit"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "^3",
|
"tailwindcss": "^3",
|
||||||
"tailwindcss": "^3"
|
"vue": "^3.2.41"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/lodash": "^4.14.182",
|
"@types/lodash": "^4.14.182",
|
||||||
@@ -41,30 +41,29 @@
|
|||||||
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
"@typescript-eslint/eslint-plugin": "^5.30.0",
|
||||||
"@typescript-eslint/parser": "^5.30.0",
|
"@typescript-eslint/parser": "^5.30.0",
|
||||||
"@vitejs/plugin-vue": "^2.3.3",
|
"@vitejs/plugin-vue": "^2.3.3",
|
||||||
"@vue/compiler-sfc": "^3.2.37",
|
|
||||||
"@vue/test-utils": "^2.0.0",
|
"@vue/test-utils": "^2.0.0",
|
||||||
"@vue/tsconfig": "^0.1.3",
|
"@vue/tsconfig": "^0.1.3",
|
||||||
"c8": "^7.11.3",
|
"c8": "^7.11.3",
|
||||||
"class-names": "^1.0.0",
|
|
||||||
"eslint": "^8.18.0",
|
"eslint": "^8.18.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-plugin-vue": "^9.1.1",
|
"eslint-plugin-vue": "^9.1.1",
|
||||||
"flowbite": "^1.4.2",
|
"flowbite": "^1.5.3",
|
||||||
"jsdom": "^20.0.0",
|
"jsdom": "^20.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"postcss": "^8.4.14",
|
"postcss": "^8.4.14",
|
||||||
"postcss-prefix-selector": "^1.16.0",
|
"postcss-prefix-selector": "^1.16.0",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
"tailwindcss": "^3",
|
"tailwindcss": "^3.1.8",
|
||||||
"tsc-alias": "^1.7.0",
|
"tsc-alias": "^1.7.0",
|
||||||
"typescript": "^4.7.3",
|
"typescript": "4.7.3",
|
||||||
"vite": "^2.4.3",
|
"vite": "^2.4.3",
|
||||||
"vitest": "^0.16.0",
|
"vitest": "^0.16.0",
|
||||||
"vue-eslint-parser": "^9.0.3",
|
"vue-eslint-parser": "^9.0.3",
|
||||||
"vue-tsc": "^0.30.0"
|
"vue-tsc": "0.30.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vueuse/core": "^8.9.1",
|
"@vueuse/core": "9.3.0",
|
||||||
"vitepress": "^1.0.0-alpha.4"
|
"classnames": "^2.3.2",
|
||||||
|
"vitepress": "1.0.0-alpha.19"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="bg-white border-gray-200 px-2 sm:px-4 py-2.5 rounded dark:bg-gray-800">
|
<nav :class="navbarClasses">
|
||||||
<div class="container flex flex-wrap justify-between items-center mx-auto">
|
<div class="container flex flex-wrap justify-between items-center mx-auto">
|
||||||
<a href="https://flowbite.com/" class="flex items-center">
|
<slot name="logo"/>
|
||||||
<!-- <img src="/docs/images/logo.svg" class="mr-3 h-6 sm:h-9" alt="Flowbite Logo" />-->
|
<button @click="toggleMobileMenu()" type="button" class="inline-flex items-center p-2 ml-3 text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600" aria-controls="navbar-default" aria-expanded="false">
|
||||||
<span class="self-center text-xl font-semibold whitespace-nowrap dark:text-white">Flowbite</span>
|
|
||||||
</a>
|
|
||||||
<button data-collapse-toggle="mobile-menu" type="button" class="inline-flex items-center p-2 ml-3 text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600" aria-controls="mobile-menu" aria-expanded="false">
|
|
||||||
<span class="sr-only">Open main menu</span>
|
<span class="sr-only">Open main menu</span>
|
||||||
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg>
|
<slot name="menu-icon">
|
||||||
<svg class="hidden w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
|
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"></path></svg>
|
||||||
|
</slot>
|
||||||
</button>
|
</button>
|
||||||
<div class="hidden w-full md:block md:w-auto" id="mobile-menu">
|
<slot name="default" :isShowMenu="isShowMenu" />
|
||||||
<ul class="flex flex-col mt-4 md:flex-row md:space-x-8 md:mt-0 md:text-sm md:font-medium">
|
<div v-if="slots['right-side']" class="flex md:order-2 hidden md:flex">
|
||||||
<li>
|
<slot name="right-side" />
|
||||||
<a href="#" class="block py-2 pr-4 pl-3 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0 dark:text-white" aria-current="page">Home</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">About</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Services</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" class="block py-2 pr-4 pl-3 text-gray-700 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent dark:border-gray-700">Pricing</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" class="block py-2 pr-4 pl-3 text-gray-700 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 md:p-0 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent">Contact</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, toRefs } from 'vue'
|
import { useSlots, ref, computed } from 'vue'
|
||||||
import type { PropType } from 'vue'
|
import { breakpointsTailwind, useBreakpoints, useToggle } from '@vueuse/core'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
border: {
|
sticky: {
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
children: {
|
|
||||||
type: Array,
|
|
||||||
default() {
|
|
||||||
return []
|
|
||||||
},
|
|
||||||
},
|
|
||||||
className: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
fluid: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
menuOpen: {
|
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
@@ -63,6 +29,36 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
solid: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
const slots = useSlots()
|
||||||
|
|
||||||
|
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||||
|
const isMobile = breakpoints.smaller('md')
|
||||||
|
const isShowMenuOnMobile = ref(false)
|
||||||
|
const toggleMobileMenu = useToggle(isShowMenuOnMobile)
|
||||||
|
const navbarBaseClasses = ' border-gray-200'
|
||||||
|
const navbarFloatClasses = 'fixed w-full z-20 top-0 left-0 border-b border-gray-200 dark:border-gray-600'
|
||||||
|
const navbarRoundedClasses = 'rounded'
|
||||||
|
const navbarSolidClasses = 'p-3 bg-gray-50 dark:bg-gray-800 dark:border-gray-700'
|
||||||
|
const navbarWhiteClasses = 'bg-white px-2 sm:px-4 py-2.5 dark:bg-gray-900'
|
||||||
|
|
||||||
|
const navbarClasses = computed(() => {
|
||||||
|
return classNames(
|
||||||
|
navbarBaseClasses,
|
||||||
|
props.sticky ? navbarFloatClasses : '',
|
||||||
|
props.rounded ? navbarRoundedClasses: '',
|
||||||
|
props.solid ? navbarSolidClasses : navbarWhiteClasses,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
const isShowMenu = computed(() => {
|
||||||
|
if(!isMobile) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return isShowMenuOnMobile.value
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
31
src/components/Navbar/NavbarCollapse.vue
Normal file
31
src/components/Navbar/NavbarCollapse.vue
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="menuClasses">
|
||||||
|
<ul :class="listClasses">
|
||||||
|
<slot name="default" />
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { breakpointsTailwind, useBreakpoints } from '@vueuse/core'
|
||||||
|
const breakpoints = useBreakpoints(breakpointsTailwind)
|
||||||
|
const isMobile = breakpoints.smaller('md')
|
||||||
|
const props = defineProps({
|
||||||
|
isShowMenu: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const menuClassesDefault = 'w-full md:block md:w-auto'
|
||||||
|
const listClassesDefault = 'flex flex-col p-4 mt-4 rounded-lg border border-gray-100 md:flex-row md:space-x-8 md:mt-0 md:text-sm md:font-medium md:border-0 dark:bg-gray-800 md:dark:bg-gray-900 dark:border-gray-700'
|
||||||
|
const mobileListClasses = 'bg-gray-50'
|
||||||
|
const menuClasses = computed(() => {
|
||||||
|
return classNames(menuClassesDefault, props.isShowMenu ? '': 'hidden')
|
||||||
|
})
|
||||||
|
const listClasses = computed(() => {
|
||||||
|
return classNames(listClassesDefault, isMobile.value ? mobileListClasses : '')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
61
src/components/Navbar/NavbarLink.ts
Normal file
61
src/components/Navbar/NavbarLink.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { defineComponent, h } from 'vue'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'NavbarLink',
|
||||||
|
props: {
|
||||||
|
link: {
|
||||||
|
type: String,
|
||||||
|
default: '/',
|
||||||
|
},
|
||||||
|
isActive: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: 'a',
|
||||||
|
},
|
||||||
|
linkAttr: {
|
||||||
|
type: String,
|
||||||
|
default: 'href',
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: [
|
||||||
|
'click',
|
||||||
|
],
|
||||||
|
setup(props, { slots, emit }) {
|
||||||
|
const currentPageClasses = 'bg-blue-700 md:bg-transparent text-white md:text-blue-700 dark:text-white'
|
||||||
|
const defaultStateClasses = 'text-gray-700 hover:bg-gray-100 md:hover:bg-transparent md:border-0 md:hover:text-blue-700 dark:text-gray-400 md:dark:hover:text-white dark:hover:bg-gray-700 dark:hover:text-white md:dark:hover:bg-transparent'
|
||||||
|
const defaultClasses = 'block py-2 pr-4 pl-3 rounded md:p-0'
|
||||||
|
const linkClasses = classNames(
|
||||||
|
defaultClasses,
|
||||||
|
props.isActive ? currentPageClasses : defaultStateClasses,
|
||||||
|
)
|
||||||
|
const handleClick = (event: Event) => {
|
||||||
|
if (props.disabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
emit('click', event)
|
||||||
|
}
|
||||||
|
return () =>
|
||||||
|
h('li', null, h(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
props.component,
|
||||||
|
{
|
||||||
|
...props,
|
||||||
|
class: linkClasses,
|
||||||
|
[props.linkAttr]: props.link,
|
||||||
|
onClick: handleClick,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () => slots.default && slots.default(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
},
|
||||||
|
})
|
||||||
60
src/components/Navbar/NavbarLogo.ts
Normal file
60
src/components/Navbar/NavbarLogo.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { defineComponent, h } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'NavbarLogo',
|
||||||
|
props: {
|
||||||
|
link: {
|
||||||
|
type: String,
|
||||||
|
default: '/',
|
||||||
|
},
|
||||||
|
imageUrl: {
|
||||||
|
type: String,
|
||||||
|
default: '/assets/logo.svg',
|
||||||
|
},
|
||||||
|
alt: {
|
||||||
|
type: String,
|
||||||
|
default: 'Logo',
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
type: [Object, String],
|
||||||
|
default: 'a',
|
||||||
|
},
|
||||||
|
linkAttr: {
|
||||||
|
type: String,
|
||||||
|
default: 'href',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: [
|
||||||
|
'click',
|
||||||
|
],
|
||||||
|
setup(props, { slots }) {
|
||||||
|
return () =>
|
||||||
|
h(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
props.component,
|
||||||
|
{
|
||||||
|
[props.linkAttr]: props.link,
|
||||||
|
class: 'flex items-center',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
default: () => [
|
||||||
|
h(
|
||||||
|
'img',
|
||||||
|
{
|
||||||
|
src: props.imageUrl,
|
||||||
|
class: 'mr-3 h-6 sm:h-10',
|
||||||
|
alt: props.alt,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
h(
|
||||||
|
'span',
|
||||||
|
{
|
||||||
|
class: 'self-center text-xl font-semibold whitespace-nowrap dark:text-white',
|
||||||
|
},
|
||||||
|
slots,
|
||||||
|
)],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -21,6 +21,9 @@ export { default as ListGroup } from './components/ListGroup/ListGroup.vue'
|
|||||||
export { default as ListGroupItem } from './components/ListGroup/components/ListGroupItem/ListGroupItem.vue'
|
export { default as ListGroupItem } from './components/ListGroup/components/ListGroupItem/ListGroupItem.vue'
|
||||||
export { default as Modal } from './components/Modal/Modal.vue'
|
export { default as Modal } from './components/Modal/Modal.vue'
|
||||||
export { default as Navbar } from './components/Navbar/Navbar.vue'
|
export { default as Navbar } from './components/Navbar/Navbar.vue'
|
||||||
|
export { default as NavbarLogo } from './components/Navbar/NavbarLogo'
|
||||||
|
export { default as NavbarCollapse } from './components/Navbar/NavbarCollapse.vue'
|
||||||
|
export { default as NavbarLink } from './components/Navbar/NavbarLink'
|
||||||
export { default as Pagination } from './components/Pagination/Pagination.vue'
|
export { default as Pagination } from './components/Pagination/Pagination.vue'
|
||||||
export { default as Progress } from './components/Progress/Progress.vue'
|
export { default as Progress } from './components/Progress/Progress.vue'
|
||||||
export { default as Rating } from './components/Rating/Rating.vue'
|
export { default as Rating } from './components/Rating/Rating.vue'
|
||||||
|
|||||||
Reference in New Issue
Block a user