Skip to content

Usage

Use the content slot to add menu items or any custom content to be displayed when the dropdown is opened.

Default

A basic dropdown menu with a trigger button and menu items. The dropdownId prop is required to uniquely identify each dropdown instance.

vue
<script setup lang="ts">
import { CLDropdownMenu, CLLink } from '@codeandfunction/callaloo'
</script>

<template>
  <CLDropdownMenu
    dropdown-id="default-dropdown"
    button-aria-label="Open menu"
    label="Menu">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>
</template>

Button Colors

Use the button-color prop to customize the trigger button's color.

vue

Button Variants

Use the button-variant prop to customize the trigger button's appearance.

vue

Button Sizes

Use the button-size prop to customize the trigger button's size.

vue

Button Icons

Use the icon-before prop to display an icon before the button label, or icon-after to display an icon after the label. Both props use the CLIconNames enum.

vue
<script setup lang="ts">
import { CLDropdownMenu, CLColors, CLColorVariants, CLIconNames, CLLink } from '@codeandfunction/callaloo'
</script>

<template>
  <CLDropdownMenu
    dropdown-id="icon-before-dropdown"
    :button-color="CLColors.Primary"
    :button-variant="CLColorVariants.Soft"
    :icon-before="CLIconNames.Menu"
    button-aria-label="Open menu"
    label="Menu">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>

  <CLDropdownMenu
    dropdown-id="icon-only-dropdown"
    :button-color="CLColors.Primary"
    :button-variant="CLColorVariants.Soft"
    :icon-before="CLIconNames.DotsVertical"
    :icon-after="undefined"
    button-aria-label="Open menu">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>

  <CLDropdownMenu
    dropdown-id="icon-after-dropdown"
    :button-color="CLColors.Primary"
    :button-variant="CLColorVariants.Soft"
    :icon-after="CLIconNames.ChevronDown"
    button-aria-label="Open menu"
    label="Options">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>
</template>

Placement

Use the placement prop to control where the dropdown menu appears relative to the trigger button. The property accepts values from the CLPlacement enum.

vue
<script setup lang="ts">
import { CLDropdownMenu, CLPlacement, CLLink } from '@codeandfunction/callaloo'
</script>

<template>
  <CLDropdownMenu
    dropdown-id="placement-bottom-dropdown"
    :placement="CLPlacement.BottomStart"
    button-aria-label="Open menu"
    label="Bottom Start">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>

  <CLDropdownMenu
    dropdown-id="placement-top-dropdown"
    :placement="CLPlacement.Top"
    button-aria-label="Open menu"
    label="Top">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>

  <CLDropdownMenu
    dropdown-id="placement-right-dropdown"
    :placement="CLPlacement.Right"
    button-aria-label="Open menu"
    label="Right">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>
</template>

Custom Content

The dropdown menu can contain any custom content using the content slot. Use the content-width prop to control the width of the dropdown container.

vue
<script setup lang="ts">
import {
  CLButton,
  CLColors,
  CLColorVariants,
  CLDropdownMenu,
  CLText,
  CLTextTypes
} from '@codeandfunction/callaloo'
</script>

<template>
  <CLDropdownMenu
    dropdown-id="custom-content-dropdown"
    :button-color="CLColors.Primary"
    button-aria-label="User settings"
    label="Settings"
    content-width="300px">
    <template #content>
      <div class="demo_dropdown_container">
        <CLText :type="CLTextTypes.Heading" style="margin-bottom: 0.5rem;">User Settings</CLText>
        <CLText :type="CLTextTypes.Body" style="margin-bottom: 1rem;">Manage your account preferences</CLText>
        <div style="display: flex; flex-direction: column; gap: 0.5rem;">
          <CLButton :color="CLColors.Primary" :variant="CLColorVariants.Ghost">Profile</CLButton>
          <CLButton :color="CLColors.Primary" :variant="CLColorVariants.Ghost">Preferences</CLButton>
          <CLButton :color="CLColors.Danger" :variant="CLColorVariants.Ghost">Logout</CLButton>
        </div>
      </div>
    </template>
  </CLDropdownMenu>
</template>

Event Handlers

Use the on-open-handler and on-close-handler props to execute callbacks when the dropdown is opened or closed.

vue
<script setup lang="ts">
import { CLDropdownMenu, CLLink } from '@codeandfunction/callaloo'

const handleOpen = () => {
  console.log('Dropdown opened')
}

const handleClose = () => {
  console.log('Dropdown closed')
}
</script>

<template>
  <CLDropdownMenu
    dropdown-id="events-dropdown"
    button-aria-label="Open menu"
    label="Menu with Events"
    :on-open-handler="handleOpen"
    :on-close-handler="handleClose">
    <template #content>
      <div class="demo_dropdown_container">
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 1</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 2</CLLink>
        <CLLink href="#" :underline="false" :on-click="(evt) => evt?.preventDefault()">Menu Item 3</CLLink>
      </div>
    </template>
  </CLDropdownMenu>
</template>

Props

Released under the MIT License.