@wikicasa-dev/components · Overlays · preferred

BaseDropDown

Toggle button with an attached dropdown panel for menus, link lists and custom filter content.

import BaseDropDown from "@wikicasa-dev/components/UIKit/BaseDropDown";

Use for anything that opens a panel under (or above) a trigger: a language switcher, a user menu, a "more actions" menu on a listing card, a breadcrumb sub-menu, or a panel of custom filter controls. It handles open/close, outside click, Escape and arrow-key navigation. To choose a form value use AccessibleSelect (built on this component) instead.

The default trigger is a button showing btnLabel (plus a chevron with withArrowIcon). Replace it via the btn_slot slot and call toggleDropdown() yourself. Panel content goes in the default slot; its slot props are isOpen, toggleDropdown, activeIdx, selectedIdx, setActiveIdx, setSelectedIdx.

Usage

<script setup lang="ts">
import BaseDropDown from "@wikicasa-dev/components/UIKit/BaseDropDown";
import SelectItem from "@wikicasa-dev/components/UIKit/BaseSelect/SelectItem";

const cities = [
  { label: "Milano", href: "/vendita-case/milano" },
  { label: "Roma", href: "/vendita-case/roma" },
  { label: "Torino", href: "/vendita-case/torino" },
];
</script>

<template>
  <BaseDropDown btn-label="Città vicine" with-arrow-icon dropdown-element="ul">
    <template #default="{ activeIdx, setActiveIdx, toggleDropdown }">
      <SelectItem
        v-for="(city, idx) in cities"
        :key="city.href"
        :idx="idx"
        :active="activeIdx === idx"
        @mouseover="setActiveIdx(idx)"
        @click="toggleDropdown()"
      >
        <a :href="city.href">{{ city.label }}</a>
      </SelectItem>
    </template>
  </BaseDropDown>
</template>

Do / Don't

  • Do use dropdown-element="ul" with <li> children (SelectItem) for lists; arrow keys move activeIdx over the panel's direct children, and Enter clicks the <a> inside the active one.
  • Do keep activateKeyboardController on for menus; pass :close-keys="['Escape']" when the panel contains inputs, so Enter doesn't close it.
  • Do set direction="up" when the trigger sits near the bottom of the screen (e.g. footer language switcher).
  • Do use v-model:open to control or observe the open state; keepState ("opened" / "closed") locks it.
  • Do give a custom btn_slot trigger a real <button> with an aria-label (if icon-only) and :aria-expanded="isOpen".
  • Don't use it as a modal or tooltip; it is positioned inline under the trigger (isAbsolute), not portaled.

Styling hooks

  • .uikit-dropdown-content (the panel): --dropdown-max-height (220px), --dropdown-min-width (90px), --dropdown-border-color, --dropdown-border-{top,right,bottom,left}-width, --dropdown-border-{top-left,top-right,bottom-left,bottom-right}-radius. It also carries data-side="up|down".
  • class styles the root; btnClasses / labelClasses the default trigger; dropdownClasses the panel (z-index, width, offset); arrowWidth / arrowStrokeColor the chevron.

API

Generated from the component's types. Do not edit by hand.

Props

Name Type Default Required Description
dropdownAttrs Record<string, unknown>
dropdownClasses ClassTypeProp ""
btnClasses ClassTypeProp ""
withArrowIcon boolean false
btnLabel string ""
labelClasses ClassTypeProp ""
direction "down" | "up" "down"
arrowWidth number 12
arrowStrokeColor #${string} undefined
isAbsolute boolean true
closeWhenClickedOutside boolean true
dropdownElement "div" | "ol" | "ul" "div"
keepState "" | "closed" | "opened" ""
activateKeyboardController boolean true
closeKeys false | string[] ["Escape", "Enter"] List of keys that will close the dropdown.
dataCy string ""
resetKeyboardController boolean false
open boolean false

Events

Name Payload
click
update:open [value: boolean]
update:resetKeyboardController [value: boolean]

v-model

  • v-model:resetKeyboardController (boolean)
  • v-model:open (boolean)

Slots

Name Slot props
btn_slot { toggleDropdown: () => void; isOpen: boolean; activeIdx: number; setActiveIdx: (idx?: Nullable<number> | undefined) => void; setSelectedIdx: (idx?: Nullable<number> | undefined) => void; }
default { isOpen: boolean; toggleDropdown: () => void; activeIdx: number; selectedIdx: number; setActiveIdx: (idx?: Nullable<number> | undefined) => void; setSelectedIdx: (idx?: Nullable<number> | undefined) => void; }

Exposed (template ref)

Name Type
activeIdx number
selectedIdx number
getRootElement () => HTMLDivElement | null
getContentElement () => HTMLElement | null