mirror of
https://github.com/bitinflow/ui-old.git
synced 2026-03-13 13:45:57 +00:00
Initial commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.idea
|
||||||
76
README.md
Normal file
76
README.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# bitinflow UI Kit
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
The main goal of this package is to provide a clean & simple usage of common components in bitinflow brand.
|
||||||
|
|
||||||
|
## Example Skeleton
|
||||||
|
|
||||||
|
This example skeleton provides the default ui experience for dashboards, featuring first-, second- &
|
||||||
|
third-level menus.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<FloatingBanner></FloatingBanner>
|
||||||
|
<FirstLevelMenu>
|
||||||
|
<template v-slot:top>
|
||||||
|
<FirstLevelLink icon="fa-home">Home</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-location-dot">Pull Zones</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-bucket">Buckets</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-meteor">Spaces</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-globe">Domains</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-list">Zones</FirstLevelLink>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot:bottom>
|
||||||
|
<FirstLevelLink icon="fa-wallet">Billing</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-fingerprint">Account</FirstLevelLink>
|
||||||
|
<FirstLevelLink icon="fa-arrow-right-from-bracket">Logout</FirstLevelLink>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<SecondLevelMenu>
|
||||||
|
<template v-slot:title>Domains</template>
|
||||||
|
|
||||||
|
<SecondLevelLink icon="fa-globe">example.com</SecondLevelLink>
|
||||||
|
<SecondLevelLink icon="fa-globe">example.com</SecondLevelLink>
|
||||||
|
<SecondLevelLink icon="fa-globe">example.com</SecondLevelLink>
|
||||||
|
<SecondLevelLink icon="fa-globe">example.com</SecondLevelLink>
|
||||||
|
</SecondLevelMenu>
|
||||||
|
|
||||||
|
<FlexAuto>
|
||||||
|
<ScreenScrollContainer>
|
||||||
|
<ThirdLevelMenu>
|
||||||
|
<template v-slot:title>Test</template>
|
||||||
|
</ThirdLevelMenu>
|
||||||
|
<Container>
|
||||||
|
<HeroCard>
|
||||||
|
<div class="text-3xl">Yeet!</div>
|
||||||
|
</HeroCard>
|
||||||
|
<Card>
|
||||||
|
<CardHeader>Test</CardHeader>
|
||||||
|
<CardBody>Test</CardBody>
|
||||||
|
</Card>
|
||||||
|
<Card>
|
||||||
|
<CardHeader>Test</CardHeader>
|
||||||
|
<CardBody>Test</CardBody>
|
||||||
|
</Card>
|
||||||
|
</Container>
|
||||||
|
</ScreenScrollContainer>
|
||||||
|
</FlexAuto>
|
||||||
|
</FirstLevelMenu>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Card from "@bitinflow/ui/components/Card";
|
||||||
|
import CardHeader from "@bitinflow/ui/components/CardHeader";
|
||||||
|
import CardBody from "@bitinflow/ui/components/CardBody";
|
||||||
|
import SecondLevelMenu from "@bitinflow/ui/components/SecondLevelMenu";
|
||||||
|
import FloatingBanner from "@bitinflow/ui/components/FloatingBanner";
|
||||||
|
import FirstLevelMenu from "@bitinflow/ui/components/FirstLevelMenu";
|
||||||
|
import ScreenScrollContainer from "@bitinflow/ui/components/ScreenScrollContainer";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {FloatingBanner, ScreenScrollContainer, FirstLevelMenu, SecondLevelMenu, CardBody, CardHeader, Card},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
21
components/Button.vue
Normal file
21
components/Button.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<a href="#" class="truncate text-black dark:text-white hover:bg-zinc-100 dark:bg-base-700 dark:hover:bg-base-600 dark:text-white rounded-lg px-4 py-2">
|
||||||
|
<slot/>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Button",
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
click() {
|
||||||
|
this.$emit('click');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
15
components/Card.vue
Normal file
15
components/Card.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bg-white text-black dark:bg-base-700 dark:text-white rounded shadow mb-8">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Card"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
15
components/CardBody.vue
Normal file
15
components/CardBody.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-8 rounded-b">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "CardBody"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
17
components/CardHeader.vue
Normal file
17
components/CardHeader.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div class="py-4 px-8 border-b dark:border-base-800 rounded-t">
|
||||||
|
<div class="text-xl font-medium">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "CardHeader"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
15
components/Container.vue
Normal file
15
components/Container.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container mx-auto px-4 lg:px-16 py-8 space-y-8">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Container"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
20
components/FirstLevelLink.vue
Normal file
20
components/FirstLevelLink.vue
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<template>
|
||||||
|
<a class="hover:bg-primary-500 rounded-lg text-center text-xs py-4 flex flex-col space-y-2" href="#">
|
||||||
|
<i :class="['fal text-xl', icon]"></i>
|
||||||
|
<span>
|
||||||
|
<slot/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "FirstLevelLink",
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: 'fa-arrow-up-right-from-square'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
105
components/FirstLevelMenu.vue
Normal file
105
components/FirstLevelMenu.vue
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bg-gray-100 dark:bg-base min-h-screen flex flex-col relative">
|
||||||
|
<!-- Overlay -->
|
||||||
|
<div ref="overlay" class="sm:hidden hidden bg-gray-800 opacity-50 w-full min-h-screen absolute z-10"></div>
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="bg-white relative shadow sm:hidden z-10">
|
||||||
|
<div class="container flex justify-between items-center py-4">
|
||||||
|
<img src="/img/icon-light.svg" class="h-4" alt="bitinflow">
|
||||||
|
|
||||||
|
<div class="flex items-center space-x-4">
|
||||||
|
<nuxt-link v-for="link in secondaryMenu" :key="link.name" :to="link.to">
|
||||||
|
<i :class="link.icon" class="icon"/> {{ link.name }}
|
||||||
|
</nuxt-link>
|
||||||
|
|
||||||
|
<nuxt-link class="inline-block flex" to="/">
|
||||||
|
<img class="h-8 w-8 rounded-full" alt="profile" src="/img/avatar.jpg"/>
|
||||||
|
</nuxt-link>
|
||||||
|
|
||||||
|
<button @click="toggleMenu" class="focus-within:outline-none pl-4">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Sidenav with Content -->
|
||||||
|
<div class="flex flex-grow">
|
||||||
|
<!-- Sidenav -->
|
||||||
|
<nav ref="sidebar"
|
||||||
|
class="flex h-screen flex-col w-36 bg-base-800 dark:border-r dark:border-base text-gray-100 shadow sm:relative
|
||||||
|
absolute inset-y-0 transform -translate-x-full sm:translate-x-0 transition transition-transform z-20">
|
||||||
|
<!-- logo -->
|
||||||
|
<div class="flex-none bg-primary-500 h-16 sm:h-20 py-3 sm:py-6 text-white flex flex-initial justify-center">
|
||||||
|
<button @click="toggleDarkMode">
|
||||||
|
<img src="/img/icon-light.svg" class="h-8 w-auto" alt="Logo">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-auto flex flex-col overflow-y-auto py-6 space-y-6">
|
||||||
|
<!-- nav -->
|
||||||
|
<nav class="primary flex flex-grow flex-col space-y-4 px-6">
|
||||||
|
<slot name="top"/>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<nav class="flex flex-initial flex-col space-y-4 px-6">
|
||||||
|
<slot name="bottom"/>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="flex-none"></div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<main class="flex flex-1">
|
||||||
|
<slot/>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "FirstLevelMenu",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
primaryMenu: [
|
||||||
|
{name: 'Home', icon: 'fal fa-home', to: '/', exact: true},
|
||||||
|
{name: 'Buckets', icon: 'fal fa-bucket', to: '/buckets', exact: false},
|
||||||
|
{name: 'Domains', icon: 'fal fa-globe', to: '/domains', exact: false},
|
||||||
|
{name: 'Spaces', icon: 'fal fa-meteor', to: '/spaces', exact: false},
|
||||||
|
{name: 'Zones', icon: 'fal fa-list-ul', to: '/zones', exact: false},
|
||||||
|
],
|
||||||
|
secondaryMenu: [
|
||||||
|
{name: 'Logout', icon: 'fal fa-sign-out', to: '/logout'},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleMenu() {
|
||||||
|
this.$refs.overlay.classList.toggle('hidden');
|
||||||
|
this.$refs.sidebar.classList.toggle('-translate-x-full');
|
||||||
|
},
|
||||||
|
closeMenu() {
|
||||||
|
this.$refs.overlay.classList.add('hidden');
|
||||||
|
this.$refs.sidebar.classList.add('-translate-x-full');
|
||||||
|
},
|
||||||
|
toggleDarkMode() {
|
||||||
|
document.body.classList.toggle('dark')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.nuxt-link-active {
|
||||||
|
background: #00BFA5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nuxt-link-active:hover {
|
||||||
|
background: #004F44;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
15
components/FlexAuto.vue
Normal file
15
components/FlexAuto.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex-auto">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "Flex"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
44
components/FloatingBanner.vue
Normal file
44
components/FloatingBanner.vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div class="fixed inset-x-0 bottom-0 pb-2 sm:pb-5 z-[100]">
|
||||||
|
<div class="mx-auto max-w-7xl px-2 sm:px-6 lg:px-8">
|
||||||
|
<div class="rounded-lg bg-primary-500 p-2 shadow-lg sm:p-3">
|
||||||
|
<div class="flex flex-wrap items-center justify-between">
|
||||||
|
<div class="flex w-0 flex-1 items-center">
|
||||||
|
<span class="flex rounded-lg bg-primary-800 p-2">
|
||||||
|
<!-- Heroicon name: outline/megaphone -->
|
||||||
|
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M10.34 15.84c-.688-.06-1.386-.09-2.09-.09H7.5a4.5 4.5 0 110-9h.75c.704 0 1.402-.03 2.09-.09m0 9.18c.253.962.584 1.892.985 2.783.247.55.06 1.21-.463 1.511l-.657.38c-.551.318-1.26.117-1.527-.461a20.845 20.845 0 01-1.44-4.282m3.102.069a18.03 18.03 0 01-.59-4.59c0-1.586.205-3.124.59-4.59m0 9.18a23.848 23.848 0 018.835 2.535M10.34 6.66a23.847 23.847 0 008.835-2.535m0 0A23.74 23.74 0 0018.795 3m.38 1.125a23.91 23.91 0 011.014 5.395m-1.014 8.855c-.118.38-.245.754-.38 1.125m.38-1.125a23.91 23.91 0 001.014-5.395m0-3.46c.495.413.811 1.035.811 1.73 0 .695-.316 1.317-.811 1.73m0-3.46a24.347 24.347 0 010 3.46" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<p class="ml-3 truncate font-medium text-white">
|
||||||
|
<span class="md:hidden">We announced a new product!</span>
|
||||||
|
<span class="hidden md:inline">Big news! We're excited to announce a brand new product.</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="order-3 mt-2 w-full flex-shrink-0 sm:order-2 sm:mt-0 sm:w-auto">
|
||||||
|
<a href="#" class="flex items-center justify-center rounded-md border border-transparent bg-white px-4 py-2 text-sm font-medium text-primary-500 shadow-sm hover:bg-zinc-200">Learn more</a>
|
||||||
|
</div>
|
||||||
|
<div class="order-2 flex-shrink-0 sm:order-3 sm:ml-2">
|
||||||
|
<button type="button" class="-mr-1 flex rounded-md p-2 hover:bg-primary-500 focus:outline-none focus:ring-2 focus:ring-white">
|
||||||
|
<span class="sr-only">Dismiss</span>
|
||||||
|
<!-- Heroicon name: outline/x-mark -->
|
||||||
|
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "FloatingBanner"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
15
components/HeroCard.vue
Normal file
15
components/HeroCard.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bg-gradient-to-tr from-primary-600 to-primary-400 text-white rounded shadow p-8">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "HeroCard"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
15
components/ScreenScrollContainer.vue
Normal file
15
components/ScreenScrollContainer.vue
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<template>
|
||||||
|
<div class="overflow-y-auto h-screen">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "ScreenScrollContainer"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
17
components/SecondLevelLink.vue
Normal file
17
components/SecondLevelLink.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<Button class="flex items-center gap-2">
|
||||||
|
<i :class="['fal', icon]"></i> <slot/>
|
||||||
|
</Button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SecondLevelLink",
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: 'fa-arrow-up-right-from-square'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
43
components/SecondLevelMenu.vue
Normal file
43
components/SecondLevelMenu.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<nav class="w-64 bg-white text-black shadow dark:bg-base-700 dark:text-white dark:border-base-900 dark:border-l
|
||||||
|
flex flex-col overflow-y-auto h-screen absolute sm:relative transform -translate-x-full sm:translate-x-0 pt-10 pb-4 px-4 space-y-2">
|
||||||
|
<span class="font-semibold px-4">
|
||||||
|
<slot name="title"/>
|
||||||
|
</span>
|
||||||
|
<div class="flex flex-col gap-2 justify-between flex-1">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<SecondLevelLink class="bg-zinc-100 hover:bg-zinc-200 dark:bg-base-500 dark:hover:bg-base-600"
|
||||||
|
icon="fa-plus">
|
||||||
|
Create Resource
|
||||||
|
</SecondLevelLink>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "SecondLevelMenu",
|
||||||
|
props: {
|
||||||
|
items: {
|
||||||
|
type: Array,
|
||||||
|
default: [
|
||||||
|
{name: 'Test', href: 'Test'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.nuxt-link-active {
|
||||||
|
background: #f3f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .nuxt-link-active {
|
||||||
|
background: #464649;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
62
components/ThirdLevelMenu.vue
Normal file
62
components/ThirdLevelMenu.vue
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex-1 dark:border-l dark:border-base shadow text-black dark:text-white">
|
||||||
|
<div class="bg-white border-b dark:bg-base-600 dark:border-base">
|
||||||
|
<div class="container mx-auto px-4 lg:px-16 py-10">
|
||||||
|
<div class="text-3xl font-semibold">
|
||||||
|
<slot name="title"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="bg-white dark:bg-base-700 py-4">
|
||||||
|
<div class="container mx-auto px-4 lg:px-16">
|
||||||
|
<div class="hidden xl:block space-x-4">
|
||||||
|
<Button v-for="link in thirdLevelLinks">
|
||||||
|
<i :class="link.icon" class="icon"></i> {{ link.name }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col xl:hidden">
|
||||||
|
<select @change="onChange" v-model="link" class="bg-white">
|
||||||
|
<option v-for="link in thirdLevelLinks" v-bind:key="link.name" :to="link.to" :value="link.to">
|
||||||
|
{{ link.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {useMenuStore} from "../stores/menu";
|
||||||
|
import {mapState} from "pinia";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ThirdLevelMenu",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
link: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useMenuStore, ['thirdLevelLinks'])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(event) {
|
||||||
|
this.link = event.target.value
|
||||||
|
this.$router.push(event.target.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.nuxt-link-active {
|
||||||
|
background: #f3f3f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .nuxt-link-active {
|
||||||
|
background: #464649;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
8
composables/app.js
Normal file
8
composables/app.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import {useMenuStore} from "~/stores/menu";
|
||||||
|
|
||||||
|
export const useMenu = (data) => {
|
||||||
|
const menu = useMenuStore()
|
||||||
|
if (data.thirdLevelLinks) {
|
||||||
|
menu.updateThirdLevelLinks(data.thirdLevelLinks)
|
||||||
|
}
|
||||||
|
}
|
||||||
11
package.json
Normal file
11
package.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "@bitinflow/ui",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Bitinflow UI Kit",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "René Preuß <rene@bitinflow.com>",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user