Skip to content
On this page

Menu

Accessible dropdown menu. Can be used as a list of buttons, links, checkboxes or radios.

Usage

See using components for detailed instructions.

js
import {
  CMenu,
  CMenuBtn,
  CMenuItem,
  CMenuLink,
  CMenuList,
  CMenuSeparator,
} from 'chusho';

Config

The options below are to be set in the global configuration at the following location:

js
{
    components: {
        menu: {
            class: ({ open, modelValue, open, disabled, multiple, variant }) => {},
        },
        menuBtn: {
            class: ({ disabled, active, variant }) => {},
        },
        menuList: {
            class: ({ transition, variant }) => {},
            transition: {},
        },
        menuItem: {
            class: ({ role, selected, value, disabled, variant }) => {},
        },
        menuLink: {
            class: ({ href, to, disabled, variant }) => {},
        },
        menuSeparator: {
            class: ({ variant }) => {},
        },
    },
}

class

Classes applied to the component root element, except when the prop bare is set to true. See styling components.

  • type: Array<String | Object> | Object | String | (props: Object) => {}
  • default: null

Example

Using the CMenuItem component:

js
class({ role, selected }) {
    return ['menu-item', {
        'menu-item--selected': selected,
        'menu-item--checkbox': role === 'menuitemcheckbox',
        'menu-item--radio': role === 'menuitemradio',
    }]
}

transition

Apply a common transition to all menu lists. The object can contain any Vue built-in transition component props.

  • type: object
  • default: null

Example

js
{ name: 'fade', mode: 'out-in' }

API

NameTypeDefaultDescription
Props
variant string|array|objectundefined

Useful when used in the component config class option, to style it conditionally. See styling components.

bare booleanfalse

Disable class inheritance from the component config. See styling components.

modelValue anyundefined

Bind the Menu value with the parent component.

open booleanfalse

Bind the MenuList opening state with the parent component.

disabled booleanfalse

Prevent opening the menu.

multiple booleanfalse

Allow to select multiple items within the menu.

Events
update:modelValue
When the selected value(s) change.
ArgumentTypeDescription
modelValueany

The selected item value, or an array of selected items values when multiple is true.

update:open
When the popup opens or closes.
ArgumentTypeDescription
openboolean

Whether the popup is open or not.

Slots
default
Binding nameTypeDescription
openboolean

Whether the popup is open or not.

Examples

Simplest

Manually handle the item behavior using the select event.

template
<CMenu>
  <CMenuBtn>Toggle menu</CMenuBtn>
  <CMenuList>
    <CMenuItem @select="() => { /* Do something */ }">Item 1</CMenuItem>
    <CMenuItem @select="() => { /* Do something */ }">Item 2</CMenuItem>
  </CMenuList>
</CMenu>

Navigate to the given route. You can replace to by href for regular links.

template
<CMenu>
  <CMenuBtn>Toggle menu</CMenuBtn>
  <CMenuList>
    <CMenuLink to="/url-1">Link 1</CMenuLink>
    <CMenuLink to="/url-2">Link 2</CMenuLink>
  </CMenuList>
</CMenu>

Selectable

Let the user select one of the items and update the v-model accordingly.

vue
<template>
  <CMenu v-model="value">
    <CMenuBtn>Choose your weapon</CMenuBtn>
    <CMenuList>
      <CMenuItem
        v-for="item in items"
        :key="item.value"
        :value="item.id"
        :disabled="item.disabled"
      >
        {{ item.label }}
      </CMenuItem>
    </CMenuList>
  </CMenu>
</template>

<script setup>
import { ref } from 'vue';

const value = ref(null);
const items = [
  {
    label: 'Banana',
    id: 1,
  },
  {
    label: 'Apple',
    id: 2,
  },
  {
    label: 'Bananapple',
    id: 3,
    disabled: true,
  },
];
</script>

Multi selectable

Let the user select many items and update the v-model accordingly. In this scenario the value must be an array.

vue
<template>
  <CMenu v-model="value" multiple>
    <CMenuBtn>Choose your weapons</CMenuBtn>
    <CMenuList>
      <CMenuItem
        v-for="item in items"
        :key="item.value"
        :value="item.id"
        :disabled="item.disabled"
      >
        {{ item.label }}
      </CMenuItem>
    </CMenuList>
  </CMenu>
</template>

<script setup>
import { ref } from 'vue';

const value = ref([]);
const items = [
  {
    label: 'Banana',
    id: 1,
  },
  {
    label: 'Apple',
    id: 2,
  },
  {
    label: 'Bananapple',
    id: 3,
    disabled: true,
  },
];
</script>

Released under the MIT License.