mirror of
https://github.com/bitinflow/ui.git
synced 2026-03-13 13:45:59 +00:00
Ui fixes and new features
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<a
|
||||
href="#"
|
||||
<button
|
||||
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"
|
||||
@click="click"
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "BitinflowButton",
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
methods: {
|
||||
|
||||
33
src/runtime/components/BitinflowButtonLink.vue
Normal file
33
src/runtime/components/BitinflowButtonLink.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<nuxt-link
|
||||
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"
|
||||
:to="to"
|
||||
>
|
||||
<slot />
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "BitinflowButton",
|
||||
|
||||
props: {
|
||||
to: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
emits: ['click'],
|
||||
|
||||
methods: {
|
||||
click() {
|
||||
this.$emit('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,10 +1,13 @@
|
||||
<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>
|
||||
<nuxt-link
|
||||
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]" />
|
||||
<span>
|
||||
<slot />
|
||||
</span>
|
||||
</a>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<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"
|
||||
src="https://cdn.bitinflow.com/ui/images/brand/icon.svg"
|
||||
class="h-4"
|
||||
alt="bitinflow"
|
||||
>
|
||||
@@ -35,7 +35,7 @@
|
||||
class="h-8 w-8 rounded-full"
|
||||
alt="profile"
|
||||
src="/img/avatar.jpg"
|
||||
/>
|
||||
>
|
||||
</nuxt-link>
|
||||
|
||||
<button
|
||||
@@ -72,7 +72,7 @@
|
||||
<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"
|
||||
src="https://cdn.bitinflow.com/ui/images/brand/icon-light.svg"
|
||||
class="h-8 w-auto"
|
||||
alt="Logo"
|
||||
>
|
||||
|
||||
25
src/runtime/components/BitinflowSecondLevelButton.vue
Normal file
25
src/runtime/components/BitinflowSecondLevelButton.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<bitinflow-button
|
||||
class="flex items-center gap-2 w-full"
|
||||
@click="$emit('click')"
|
||||
>
|
||||
<i :class="['fal', icon]" />
|
||||
<slot />
|
||||
</bitinflow-button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BitinflowButton from "./BitinflowButton.vue";
|
||||
|
||||
export default {
|
||||
name: "BitinflowSecondLevelLink",
|
||||
components: {BitinflowButton},
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'fa-arrow-up-right-from-square'
|
||||
}
|
||||
},
|
||||
emits: ['click']
|
||||
}
|
||||
</script>
|
||||
@@ -1,19 +1,27 @@
|
||||
<template>
|
||||
<bitinflow-button class="flex items-center gap-2">
|
||||
<i :class="['fal', icon]" /> <slot />
|
||||
</bitinflow-button>
|
||||
<bitinflow-button-link
|
||||
class="flex items-center gap-2"
|
||||
:to="to"
|
||||
>
|
||||
<i :class="['fal', icon]" />
|
||||
<slot />
|
||||
</bitinflow-button-link>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BitinflowButton from "./BitinflowButton.vue";
|
||||
import BitinflowButtonLink from "./BitinflowButtonLink.vue";
|
||||
|
||||
export default {
|
||||
name: "BitinflowSecondLevelLink",
|
||||
components: {BitinflowButton},
|
||||
components: {BitinflowButtonLink},
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'fa-arrow-up-right-from-square'
|
||||
},
|
||||
to: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<!-- eslint-disable vue/require-explicit-emits -->
|
||||
<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">
|
||||
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>
|
||||
@@ -8,24 +10,26 @@
|
||||
<div class="flex flex-col gap-2">
|
||||
<slot />
|
||||
</div>
|
||||
<div>
|
||||
<bitinflow-second-level-link
|
||||
<div v-if="hasCreateListener">
|
||||
<bitinflow-second-level-button
|
||||
class="bg-zinc-100 hover:bg-zinc-200 dark:bg-base-500 dark:hover:bg-base-600"
|
||||
icon="fa-plus"
|
||||
@click="$emit('create')"
|
||||
>
|
||||
Create Resource
|
||||
</bitinflow-second-level-link>
|
||||
</bitinflow-second-level-button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BitinflowSecondLevelLink from "./BitinflowSecondLevelLink.vue";
|
||||
import BitinflowSecondLevelButton from "./BitinflowSecondLevelButton.vue";
|
||||
|
||||
export default {
|
||||
name: "BitinflowSecondLevelMenu",
|
||||
components: {BitinflowSecondLevelLink},
|
||||
components: {BitinflowSecondLevelButton},
|
||||
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
@@ -34,7 +38,13 @@ export default {
|
||||
{name: 'Test', href: 'Test'}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
hasCreateListener() {
|
||||
return this.$attrs && this.$attrs.onCreate;
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -11,27 +11,29 @@
|
||||
<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">
|
||||
<bitinflow-button
|
||||
<bitinflow-button-link
|
||||
v-for="item in thirdLevelLinks"
|
||||
:key="item.name"
|
||||
:to="resolve(item.to)"
|
||||
>
|
||||
<i
|
||||
:class="['far', item.icon]"
|
||||
class="icon"
|
||||
/> {{ link.name }}
|
||||
</bitinflow-button>
|
||||
/> {{ item.name }}
|
||||
</bitinflow-button-link>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col xl:hidden">
|
||||
<select
|
||||
v-model="link"
|
||||
class="bg-white"
|
||||
class="bg-white dark:bg-base-700 outline-none"
|
||||
@change="onChange"
|
||||
>
|
||||
<option
|
||||
v-for="item in thirdLevelLinks"
|
||||
:key="item.name"
|
||||
:value="item.to"
|
||||
:value="resolve(item.to)"
|
||||
:selected="link === item.to"
|
||||
>
|
||||
{{ item.name }}
|
||||
</option>
|
||||
@@ -45,23 +47,27 @@
|
||||
<script>
|
||||
import {mapState} from "pinia";
|
||||
import {useMenuStore} from "../stores/menu";
|
||||
import BitinflowButton from "./BitinflowButton.vue";
|
||||
import BitinflowButtonLink from "./BitinflowButtonLink.vue";
|
||||
|
||||
export default {
|
||||
name: "BitinflowThirdLevelMenu",
|
||||
components: {BitinflowButton},
|
||||
components: {BitinflowButtonLink},
|
||||
data() {
|
||||
return {
|
||||
link: ''
|
||||
link: this.$route.path
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(useMenuStore, ['thirdLevelLinks'])
|
||||
...mapState(useMenuStore, ['thirdLevelLinks', 'thirdLevelProps'])
|
||||
},
|
||||
methods: {
|
||||
onChange(event) {
|
||||
this.link = event.target.value
|
||||
this.$router.push(event.target.value)
|
||||
},
|
||||
resolve(to) {
|
||||
// replace all :params with the actual values
|
||||
return to.replace(/:([^/]+)/g, (_, param) => this.thirdLevelProps[param])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,7 @@ export const useMenu = (options: MenuOptions) => {
|
||||
if (options.thirdLevelLinks) {
|
||||
menu.updateThirdLevelLinks(options.thirdLevelLinks)
|
||||
}
|
||||
if (options.thirdLevelProps) {
|
||||
menu.updateThirdLevelProps(options.thirdLevelProps)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,16 @@ import {ThirdLevelLink} from "../../types";
|
||||
export const useMenuStore = defineStore('menu', {
|
||||
state: () => {
|
||||
return {
|
||||
thirdLevelLinks: [] as Array<ThirdLevelLink>
|
||||
thirdLevelLinks: [] as Array<ThirdLevelLink>,
|
||||
thirdLevelProps: [] as Object,
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updateThirdLevelLinks(links: Array<ThirdLevelLink>) {
|
||||
this.thirdLevelLinks = links;
|
||||
},
|
||||
updateThirdLevelProps(props: Object) {
|
||||
this.thirdLevelProps = props;
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export interface MenuOptions {
|
||||
thirdLevelLinks: Array<ThirdLevelLink>;
|
||||
thirdLevelProps: Object;
|
||||
}
|
||||
|
||||
export interface ThirdLevelLink {
|
||||
|
||||
Reference in New Issue
Block a user