<BaseDropdown />
· An options or a contextual menu.
<template>
<BaseDropdown variant="default" label="Default dropdown">
<BaseDropdownItem>Leads</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Reports</BaseDropdownItem>
<BaseDropdownItem>
Settings
<template #end>
<BaseKbd size="sm">
<span class="text-xs font-mono">⌘</span>
</BaseKbd>
<BaseKbd size="sm">
<span class="text-xs font-mono px-0.5">P</span>
</BaseKbd>
</template>
</BaseDropdownItem>
</BaseDropdown>
</template>
This component has optional sub components that you can use to create your dropdown menu. You can customize the dropdown's visual style by using the available props.
<template>
<BaseDropdown>
<BaseDropdownLabel>
<!-- Label goes here -->
</BaseDropdownLabel>
<!-- Sub dropdown -->
<BaseDropdownSub>
<template #title>
<!-- Sub dropdown title goes here -->
</template>
<BaseDropdownLabel>
<!-- Sub dropdown label goes here -->
</BaseDropdownLabel>
<BaseDropdownItem>
<!-- Sub dropdown item content goes here -->
</BaseDropdownItem>
</BaseDropdownSub>
<!-- Separator item -->
<BaseDropdownSeparator />
<BaseDropdownItem>
<!-- Item content goes here -->
</BaseDropdownItem>
<!-- Checkbox item -->
<BaseDropdownCheckbox />
<!-- Radio group -->
<BaseDropdownRadioGroup>
<!-- Radio item -->
<BaseDropdownRadio />
</BaseDropdownRadioGroup>
<!-- Menu top arrow -->
<BaseDropdownArrow />
</BaseDropdown>
</template>
This component has props that you can use to modify its visual style.
Prop | Type |
---|---|
label default: "" | string The label to display for the dropdown. |
disabled default: - | boolean Disables the dropdown. |
variant default: "default" | "default" | "primary" | "none" | "muted" The variant of the dropdown content |
rounded default: "md" | "none" | "md" | "sm" | "lg" | "full" The radius of the dropdown button. |
bindings default: {} | { content?: DropdownMenuContentProps; trigger?: DropdownMenuTriggerProps; portal?: DropdownMenuPortalProps; } Optional bindings to pass to the inner components. |
classes default: {} | { content?: string | string[]; } Optional classes to pass to the inner components. |
default-open default: - | boolean The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state. |
open default: - | boolean The controlled open state of the menu. Can be used as `v-model:open`. |
dir default: - | Direction_3 The reading direction of the combobox when applicable. If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode. |
modal default: - | boolean The modality of the dropdown menu. When set to `true`, interaction with outside elements will be disabled and only menu content will be visible to screen readers. |
Event | Emitted Value Type |
---|---|
update:open | [payload: boolean] |
Slot | Type |
---|---|
#default | any |
#button | any |
#label | any |
Prop | Type |
---|---|
title default: "" | string The title to display for the dropdown item. |
text default: "" | string The text to display for the dropdown item. |
variant default: - | "default" | "primary" | "none" | "muted" The hover color of the dropdown-item inner elements. |
rounded default: - | "none" | "md" | "sm" | "lg" | "full" The radius of the dropdown-item. |
disabled default: - | boolean When `true`, prevents the user from interacting with the item. |
text-value default: - | string Optional text used for typeahead purposes. By default the typeahead behavior will use the `.textContent` of the item. <br> Use this when the content is complex, or you have non-textual content inside. |
as-child default: - | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
as default: - | AsTag | Component The element or component this component should render as. Can be overwritten by `asChild`. |
Event | Emitted Value Type |
---|---|
select | [event: Event] |
Slot | Type |
---|---|
#default | any |
#title | any |
#text | any |
#start | any |
#end | any |
Prop | Type |
---|---|
title default: - | string The title to display for the dropdown item. |
text default: - | string The text to display for the dropdown item. |
variant default: - | "default" | "primary" | "none" | "muted" The variant of the dropdown content |
rounded default: - | "none" | "md" | "sm" | "lg" | "full" The radius of the dropdown button. |
bindings default: - | { trigger?: DropdownMenuSubTriggerProps; content?: DropdownMenuSubContentProps; portal?: DropdownMenuPortalProps; } Optional bindings to pass to the inner components. |
default-open default: - | boolean The open state of the dropdown menu when it is initially rendered. Use when you do not need to control its open state. |
open default: - | boolean The controlled open state of the menu. Can be used as `v-model:open`. |
Event | Emitted Value Type |
---|---|
update:open | [payload: boolean] |
Slot | Type |
---|---|
#default | any |
#title | any |
#text | any |
Model | Type |
---|---|
model-value | CheckedState The controlled checked state of the item. Can be used as `v-model`. |
Prop | Type |
---|---|
title default: "" | string The title to display for the dropdown item. |
text default: "" | string The text to display for the dropdown item. |
variant default: - | "default" | "primary" | "none" | "muted" The hover color of the dropdown-item inner elements. |
rounded default: - | "none" | "md" | "sm" | "lg" The radius of the dropdown-item. |
bindings default: {} | { indicator?: DropdownMenuItemIndicatorProps; } Optional bindings to pass to the inner components. |
disabled default: - | boolean When `true`, prevents the user from interacting with the item. |
text-value default: - | string Optional text used for typeahead purposes. By default the typeahead behavior will use the `.textContent` of the item. <br> Use this when the content is complex, or you have non-textual content inside. |
as-child default: - | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
as default: - | AsTag | Component The element or component this component should render as. Can be overwritten by `asChild`. |
Event | Emitted Value Type |
---|---|
select | [event: Event] |
Slot | Type |
---|---|
#default | any |
#title | any |
#text | any |
#end | any |
Model | Type |
---|---|
model-value | string The value of the selected item in the group. |
Prop | Type |
---|---|
as-child default: - | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
as default: - | AsTag | Component The element or component this component should render as. Can be overwritten by `asChild`. |
Slot | Type |
---|---|
#default | any |
Prop | Type |
---|---|
title default: - | string The title to display for the dropdown item. |
text default: - | string The text to display for the dropdown item. |
variant default: - | "default" | "primary" | "none" | "muted" The hover color of the dropdown-item inner elements. |
rounded default: - | "none" | "md" | "sm" | "lg" The radius of the dropdown-item. |
bindings default: {} | { indicator?: DropdownMenuItemIndicatorProps; } Optional bindings to pass to the inner components. |
value default: - | string The unique value of the item. |
disabled default: - | boolean When `true`, prevents the user from interacting with the item. |
text-value default: - | string Optional text used for typeahead purposes. By default the typeahead behavior will use the `.textContent` of the item. <br> Use this when the content is complex, or you have non-textual content inside. |
as-child default: - | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
as default: - | AsTag | Component The element or component this component should render as. Can be overwritten by `asChild`. |
Event | Emitted Value Type |
---|---|
select | [event: Event] |
Slot | Type |
---|---|
#default | any |
#text | any |
#end | any |
Prop | Type |
---|---|
as-child default: - | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our [Composition](https://www.reka-ui.com/docs/guides/composition) guide for more details. |
as default: - | AsTag | Component The element or component this component should render as. Can be overwritten by `asChild`. |
Your can override the component default CSS variables in your main.css
file.
@theme {
/* Default dropdown menu variables */
--color-portal-default-bg: var(--color-white);
--color-portal-default-border: var(--color-muted-300);
--color-portal-default-item-bg-active: var(--color-muted-100);
--color-portal-default-item-text: var(--color-input-default-text);
--color-portal-default-item-text-active: var(--color-primary-base);
/* Muted dropdown menu variables */
--color-portal-muted-bg: var(--color-muted-50);
--color-portal-muted-border: var(--color-muted-300);
--color-portal-muted-item-bg-active: var(--color-muted-200);
--color-portal-muted-item-text: var(--color-input-muted-text);
--color-portal-muted-item-text-active: var(--color-primary-base);
}
Use the variant
prop to control the colors of the dropdown menu.
<template>
<BaseDropdown variant="primary" label="Primary dropdown">
<BaseDropdownItem>Leads</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Reports</BaseDropdownItem>
<BaseDropdownItem>
Settings
<template #end>
<BaseKbd size="sm">
<span class="text-xs font-mono">⌘</span>
</BaseKbd>
<BaseKbd size="sm">
<span class="text-xs font-mono px-0.5">P</span>
</BaseKbd>
</template>
</BaseDropdownItem>
</BaseDropdown>
</template>
You can nest other dropdowns inside a dropdown item, as well as checkboxes and radio buttons.
<script setup lang="ts">
const checkedOne = ref(false)
const checkedTwo = ref(false)
const selection = ref('first')
</script>
<template>
<div class="flex w-full justify-start gap-8">
<BaseDropdown label="Inner Submenus">
<BaseDropdownLabel>Label</BaseDropdownLabel>
<BaseDropdownSub>
<template #title>
Profile
</template>
<BaseDropdownLabel>Label</BaseDropdownLabel>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>General</BaseDropdownItem>
<BaseDropdownItem>Billing</BaseDropdownItem>
<BaseDropdownItem>Support</BaseDropdownItem>
</BaseDropdownSub>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownSub>
<template #title>
Settings
</template>
<BaseDropdownLabel>Label</BaseDropdownLabel>
<BaseDropdownItem>General</BaseDropdownItem>
<BaseDropdownItem>Users</BaseDropdownItem>
<BaseDropdownItem>Permissions</BaseDropdownItem>
<BaseDropdownItem>Security</BaseDropdownItem>
</BaseDropdownSub>
</BaseDropdown>
<BaseDropdown label="Radio">
<BaseDropdownRadioGroup v-model="selection">
<BaseDropdownRadioItem value="first">
First
<template #end>
<div class="flex gap-0.5">
<BaseKbd variant="default" size="sm">
alt
</BaseKbd>
<BaseKbd variant="default" size="sm">
1
</BaseKbd>
</div>
</template>
</BaseDropdownRadioItem>
<BaseDropdownRadioItem value="second">
Second
<template #end>
<div class="flex gap-0.5">
<BaseKbd variant="default" size="sm">
alt
</BaseKbd>
<BaseKbd variant="default" size="sm">
2
</BaseKbd>
</div>
</template>
</BaseDropdownRadioItem>
<BaseDropdownRadioItem value="third">
Third
<template #end>
<div class="flex gap-0.5">
<BaseKbd variant="default" size="sm">
alt
</BaseKbd>
<BaseKbd variant="default" size="sm">
3
</BaseKbd>
</div>
</template>
</BaseDropdownRadioItem>
</BaseDropdownRadioGroup>
</BaseDropdown>
<BaseDropdown label="Checkbox">
<BaseDropdownCheckbox
v-model="checkedOne"
title="Profile"
/>
<BaseDropdownCheckbox
title="Projects"
disabled
/>
<BaseDropdownCheckbox
v-model="checkedTwo"
title="Team"
/>
</BaseDropdown>
</div>
</template>
Use the spacing and arrow options to control the dropdown's position.
<template>
<BaseDropdown
label="Default spacing"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
</BaseDropdown>
<BaseDropdown
label="With top arrow"
:bindings="{ content: { sideOffset: 0 } }"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
<BaseDropdownArrow />
</BaseDropdown>
<BaseDropdown
label="With more spacing"
:bindings="{ content: { sideOffset: 10 } }"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
</BaseDropdown>
</template>
Use the DropdownLabel
component to add a label to the dropdown menu. Mix and match with different options to create a unique dropdown.
<template>
<BaseDropdown header-label="My Team" variant="button" label="Dropdown" orientation="start">
<BaseDropdownItem to="#" title="Lana Jensen" text="Software Engineer" color="default" rounded="sm">
<template #start>
<BaseAvatar src="/img/avatars/4.svg" size="xs" />
</template>
</BaseDropdownItem>
<BaseDropdownItem to="#" title="Shawn Miller" text="Product Manager" color="default" rounded="sm">
<template #start>
<BaseAvatar src="/img/avatars/3.svg" size="xs" />
</template>
</BaseDropdownItem>
<BaseDropdownItem to="#" title="John Marynski" text="Sales Manager" color="default" rounded="sm">
<template #start>
<BaseAvatar src="/img/avatars/18.svg" size="xs" />
</template>
</BaseDropdownItem>
<BaseDropdownSeparator />
<BaseDropdownItem to="#" title="Garry Porter" text="CEO - Founder" color="default" rounded="sm">
<template #start>
<BaseAvatar src="/img/avatars/6.svg" size="xs" />
</template>
</BaseDropdownItem>
</BaseDropdown>
</template>
Use the #button
slot to customize the dropdown button.
<template>
<BaseDropdown
:bindings="{
content: {
sideOffset: 0,
},
}"
>
<template #button>
<BaseButton
variant="primary"
size="icon-sm"
rounded="full"
class="group"
>
<Icon name="ph:plus" class="block text-base transition-transform group-data-[state=open]:rotate-45" />
</BaseButton>
</template>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
<BaseDropdownArrow :width="16" :height="8" />
</BaseDropdown>
</template>
Use the :bindings
prop to control the dropdown's content alignment.
<template>
<BaseDropdown
label="End align" :bindings="{
content: {
align: 'end',
sideOffset: 5,
},
}"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
</BaseDropdown>
</template>
Use the :bindings
prop to control the popping side
of the dropdown menu.
<template>
<BaseDropdown
label="End align" :bindings="{
content: {
align: 'end',
sideOffset: 5,
},
}"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
</BaseDropdown>
</template>
Use the #start
slot to insert an icon inside a dropdown item.
<template>
<BaseDropdown label="Dropdown" rounded="md">
<BaseDropdownItem
title="Profile"
text="View your profile"
class="w-72"
>
<template #start>
<Icon name="solar:user-rounded-linear" class="me-2 block text-[1.15rem]" />
</template>
</BaseDropdownItem>
<BaseDropdownItem
title="Projects"
text="View your projects"
>
<template #start>
<Icon name="solar:case-linear" class="me-2 block text-[1.15rem]" />
</template>
</BaseDropdownItem>
<BaseDropdownItem
title="Team"
text="Manage your team"
>
<template #start>
<Icon name="solar:widget-3-linear" class="me-2 block text-[1.15rem]" />
</template>
</BaseDropdownItem>
<BaseDropdownSeparator />
<BaseDropdownItem
title="Settings"
text="Set your preferences"
>
<template #start>
<Icon name="solar:settings-linear" class="me-2 block text-[1.15rem]" />
</template>
</BaseDropdownItem>
</BaseDropdown>
</template>
Use the #start
slot to insert an avatar inside a dropdown item.
<template>
<BaseDropdown label="Dropdown" rounded="md">
<BaseDropdownItem
title="Lana Jensen"
text="Software Engineer"
class="w-80"
>
<template #start>
<BaseAvatar
src="/img/people/36.jpg"
size="xs"
/>
</template>
</BaseDropdownItem>
<BaseDropdownItem
title="Shawn Miller"
text="Product Manager"
>
<template #start>
<BaseAvatar
src="/img/people/18.jpg"
size="xs"
/>
</template>
</BaseDropdownItem>
<BaseDropdownItem
title="John Marynski"
text="Sales Manager"
>
<template #start>
<BaseAvatar
src="/img/people/16.jpg"
size="xs"
/>
</template>
</BaseDropdownItem>
<BaseDropdownItem
title="Garry Porter"
text="CEO - Founder"
>
<template #start>
<BaseAvatar
src="/img/people/6.jpg"
size="xs"
/>
</template>
</BaseDropdownItem>
</BaseDropdown>
</template>
By disabling the portal
mode, the dropdown will be rendered inside the component.
<template>
<BaseDropdown
label="Fixed position" :bindings="{
portal: {
disabled: true,
},
content: {
positionStrategy: 'fixed',
},
}"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
</BaseDropdown>
<BaseDropdown
label="Absolute position" :bindings="{
portal: {
disabled: true,
},
content: {
positionStrategy: 'absolute',
},
}"
>
<BaseDropdownItem>Profile</BaseDropdownItem>
<BaseDropdownItem>Projects</BaseDropdownItem>
<BaseDropdownItem>Team</BaseDropdownItem>
<BaseDropdownItem>Settings</BaseDropdownItem>
</BaseDropdown>
</template>