Menu
Menus appear when users interact with a button, action, or other control. They can be opened from a variaty of elements, most commonly icon buttons, buttons, and text fields.
Use it to display a list of choices on a temporary surface, being more prominent and taking less space than a set of radio buttons.
Simple Menu
An example of a simple menu. Use divider
to wished menu item to separate list items into groups.
vue
<script setup lang="ts">
function doStuff() {
console.warn('Oh no!')
}
</script>
<template>
<div class="flex justify-between">
<BMenu left>
<template #button="{ open }">
<BBtn class="min-w-30">
{{ open ? 'open' : 'closed' }}
</BBtn>
</template>
<BMenuItem
icon="i-mdi:bone"
@click="doStuff"
>
Category 1
</BMenuItem>
<BMenuItem icon="i-mdi:bowl-mix">
Category 2
</BMenuItem>
<BMenuItem
icon="i-mdi:robot"
divider
>
Category 3
</BMenuItem>
<BMenuItem
to="/"
icon="i-mdi:lightning-bolt-circle"
>
Category 4
</BMenuItem>
</BMenu>
<BMenu>
<template #button="{ open }">
<BBtn
class="min-w-30"
variant="tonal"
color="tertiary"
>
{{ open ? 'open' : 'closed' }}
</BBtn>
</template>
<BMenuItem
icon="i-mdi:bone"
@click="doStuff"
>
Category 1
</BMenuItem>
<BMenuItem icon="i-mdi:bowl-mix">
Category 2
</BMenuItem>
<BMenuItem
icon="i-mdi:robot"
divider
>
Category 3
</BMenuItem>
<BMenuItem
to="/"
icon="i-mdi:lightning-bolt-circle"
>
Category 4
</BMenuItem>
</BMenu>
</div>
</template>
Selection
The BMenu
component can be used as a select dropdown with a bit of creativity
Selected:
vue
<script setup lang="ts">
import { useGroupModel } from 'bragi-vue'
const { options, select, value } = useGroupModel({
options: [
{ label: 'Monitor', icon: 'i-mdi:chart-line' },
{ label: 'Pipes', icon: 'i-mdi:gamepad-circle' },
{ label: 'System', icon: 'i-mdi:cog' },
{ label: 'Profile', icon: 'i-mdi:account-outline' },
],
multi: true,
})
</script>
<template>
<div class="flex justify-between">
<div class="bg-surface-variant text-surface-onvariant flex items-center px-3">
<strong>Selected: </strong> {{ value && Array.from(value)?.map(v => v.label) }}
</div>
<BMenu>
<template #button="{ open }">
<BBtn>
Options
<i
:class="{ 'rotate-180': open }"
class="i-mdi:chevron-down transition-transform -mr-2"
/>
</BBtn>
</template>
<BMenuItem
v-for="option in options"
:key="option.value.label"
@click="select(option.value)"
>
{{ option.value.label }}
<div class="flex-grow" />
<i
v-if="option.isSelected"
class="i-mdi:check ml-3"
/>
</BMenuItem>
</BMenu>
</div>
</template>
Router links
A menu item can act as a RouterLink
by setting the to
prop on the individual BMenuItem
components
Press here ->
vue
<script setup lang="ts">
const routes = [
{ label: 'Monitor', icon: 'i-mdi:chart-line', route: '/' },
{ label: 'Pipes', icon: 'i-mdi:gamepad-circle', route: '/' },
{ label: 'System', icon: 'i-mdi:cog', route: '/' },
{ label: 'Profile', icon: 'i-mdi:account-outline', route: '/' },
]
</script>
<template>
<div class="flex items-center justify-end">
<span class="mr-3">Press here -></span>
<BMenu>
<template #button="{ open }">
<BIconBtn
:variant="open ? 'outlined' : 'text'"
icon="i-mdi:dots-vertical"
/>
</template>
<BMenuItem
v-for="item in routes"
:key="item.label"
:icon="item.icon"
:to="item.route"
>
{{ item.label }}
</BMenuItem>
</BMenu>
</div>
</template>