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>
|
<template>
|
||||||
<a
|
<button
|
||||||
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"
|
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 />
|
<slot />
|
||||||
</a>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "BitinflowButton",
|
name: "BitinflowButton",
|
||||||
|
|
||||||
emits: ['click'],
|
emits: ['click'],
|
||||||
|
|
||||||
methods: {
|
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>
|
<template>
|
||||||
<a class="hover:bg-primary-500 rounded-lg text-center text-xs py-4 flex flex-col space-y-2" href="#">
|
<nuxt-link
|
||||||
<i :class="['fal text-xl', icon]"></i>
|
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>
|
<span>
|
||||||
<slot />
|
<slot />
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</nuxt-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<header class="bg-white relative shadow sm:hidden z-10">
|
<header class="bg-white relative shadow sm:hidden z-10">
|
||||||
<div class="container flex justify-between items-center py-4">
|
<div class="container flex justify-between items-center py-4">
|
||||||
<img
|
<img
|
||||||
src="/img/icon-light.svg"
|
src="https://cdn.bitinflow.com/ui/images/brand/icon.svg"
|
||||||
class="h-4"
|
class="h-4"
|
||||||
alt="bitinflow"
|
alt="bitinflow"
|
||||||
>
|
>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
class="h-8 w-8 rounded-full"
|
class="h-8 w-8 rounded-full"
|
||||||
alt="profile"
|
alt="profile"
|
||||||
src="/img/avatar.jpg"
|
src="/img/avatar.jpg"
|
||||||
/>
|
>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
<button
|
<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">
|
<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">
|
<button @click="toggleDarkMode">
|
||||||
<img
|
<img
|
||||||
src="/img/icon-light.svg"
|
src="https://cdn.bitinflow.com/ui/images/brand/icon-light.svg"
|
||||||
class="h-8 w-auto"
|
class="h-8 w-auto"
|
||||||
alt="Logo"
|
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>
|
<template>
|
||||||
<bitinflow-button class="flex items-center gap-2">
|
<bitinflow-button-link
|
||||||
<i :class="['fal', icon]" /> <slot />
|
class="flex items-center gap-2"
|
||||||
</bitinflow-button>
|
:to="to"
|
||||||
|
>
|
||||||
|
<i :class="['fal', icon]" />
|
||||||
|
<slot />
|
||||||
|
</bitinflow-button-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BitinflowButton from "./BitinflowButton.vue";
|
import BitinflowButtonLink from "./BitinflowButtonLink.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "BitinflowSecondLevelLink",
|
name: "BitinflowSecondLevelLink",
|
||||||
components: {BitinflowButton},
|
components: {BitinflowButtonLink},
|
||||||
props: {
|
props: {
|
||||||
icon: {
|
icon: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'fa-arrow-up-right-from-square'
|
default: 'fa-arrow-up-right-from-square'
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
<!-- eslint-disable vue/require-explicit-emits -->
|
||||||
<template>
|
<template>
|
||||||
<nav
|
<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">
|
<span class="font-semibold px-4">
|
||||||
<slot name="title" />
|
<slot name="title" />
|
||||||
</span>
|
</span>
|
||||||
@@ -8,24 +10,26 @@
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div v-if="hasCreateListener">
|
||||||
<bitinflow-second-level-link
|
<bitinflow-second-level-button
|
||||||
class="bg-zinc-100 hover:bg-zinc-200 dark:bg-base-500 dark:hover:bg-base-600"
|
class="bg-zinc-100 hover:bg-zinc-200 dark:bg-base-500 dark:hover:bg-base-600"
|
||||||
icon="fa-plus"
|
icon="fa-plus"
|
||||||
|
@click="$emit('create')"
|
||||||
>
|
>
|
||||||
Create Resource
|
Create Resource
|
||||||
</bitinflow-second-level-link>
|
</bitinflow-second-level-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import BitinflowSecondLevelLink from "./BitinflowSecondLevelLink.vue";
|
import BitinflowSecondLevelButton from "./BitinflowSecondLevelButton.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "BitinflowSecondLevelMenu",
|
name: "BitinflowSecondLevelMenu",
|
||||||
components: {BitinflowSecondLevelLink},
|
components: {BitinflowSecondLevelButton},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
items: {
|
items: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -34,7 +38,13 @@ export default {
|
|||||||
{name: 'Test', href: 'Test'}
|
{name: 'Test', href: 'Test'}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
hasCreateListener() {
|
||||||
|
return this.$attrs && this.$attrs.onCreate;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -11,27 +11,29 @@
|
|||||||
<nav class="bg-white dark:bg-base-700 py-4">
|
<nav class="bg-white dark:bg-base-700 py-4">
|
||||||
<div class="container mx-auto px-4 lg:px-16">
|
<div class="container mx-auto px-4 lg:px-16">
|
||||||
<div class="hidden xl:block space-x-4">
|
<div class="hidden xl:block space-x-4">
|
||||||
<bitinflow-button
|
<bitinflow-button-link
|
||||||
v-for="item in thirdLevelLinks"
|
v-for="item in thirdLevelLinks"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
|
:to="resolve(item.to)"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
:class="['far', item.icon]"
|
:class="['far', item.icon]"
|
||||||
class="icon"
|
class="icon"
|
||||||
/> {{ link.name }}
|
/> {{ item.name }}
|
||||||
</bitinflow-button>
|
</bitinflow-button-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col xl:hidden">
|
<div class="flex flex-col xl:hidden">
|
||||||
<select
|
<select
|
||||||
v-model="link"
|
v-model="link"
|
||||||
class="bg-white"
|
class="bg-white dark:bg-base-700 outline-none"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
v-for="item in thirdLevelLinks"
|
v-for="item in thirdLevelLinks"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
:value="item.to"
|
:value="resolve(item.to)"
|
||||||
|
:selected="link === item.to"
|
||||||
>
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</option>
|
</option>
|
||||||
@@ -45,23 +47,27 @@
|
|||||||
<script>
|
<script>
|
||||||
import {mapState} from "pinia";
|
import {mapState} from "pinia";
|
||||||
import {useMenuStore} from "../stores/menu";
|
import {useMenuStore} from "../stores/menu";
|
||||||
import BitinflowButton from "./BitinflowButton.vue";
|
import BitinflowButtonLink from "./BitinflowButtonLink.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "BitinflowThirdLevelMenu",
|
name: "BitinflowThirdLevelMenu",
|
||||||
components: {BitinflowButton},
|
components: {BitinflowButtonLink},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
link: ''
|
link: this.$route.path
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useMenuStore, ['thirdLevelLinks'])
|
...mapState(useMenuStore, ['thirdLevelLinks', 'thirdLevelProps'])
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onChange(event) {
|
onChange(event) {
|
||||||
this.link = event.target.value
|
this.link = event.target.value
|
||||||
this.$router.push(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) {
|
if (options.thirdLevelLinks) {
|
||||||
menu.updateThirdLevelLinks(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', {
|
export const useMenuStore = defineStore('menu', {
|
||||||
state: () => {
|
state: () => {
|
||||||
return {
|
return {
|
||||||
thirdLevelLinks: [] as Array<ThirdLevelLink>
|
thirdLevelLinks: [] as Array<ThirdLevelLink>,
|
||||||
|
thirdLevelProps: [] as Object,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
updateThirdLevelLinks(links: Array<ThirdLevelLink>) {
|
updateThirdLevelLinks(links: Array<ThirdLevelLink>) {
|
||||||
this.thirdLevelLinks = links;
|
this.thirdLevelLinks = links;
|
||||||
},
|
},
|
||||||
|
updateThirdLevelProps(props: Object) {
|
||||||
|
this.thirdLevelProps = props;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export interface MenuOptions {
|
export interface MenuOptions {
|
||||||
thirdLevelLinks: Array<ThirdLevelLink>;
|
thirdLevelLinks: Array<ThirdLevelLink>;
|
||||||
|
thirdLevelProps: Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThirdLevelLink {
|
export interface ThirdLevelLink {
|
||||||
|
|||||||
Reference in New Issue
Block a user