20260720172840

This commit is contained in:
oneao committed 2026-07-20 17:28:47 +08:00
1 parent cda7f16d3a
commit 94207c77ff
3117 files changed
+201407 -1236

No files matched your search

@@ -0,0 +1,80 @@
# _semantic
## Source
```vue
<script setup lang="ts">
import { DeleteOutlined, DownOutlined, EditOutlined, SaveOutlined } from '@antdv-next/icons'
import { computed, h, ref } from 'vue'
import { SemanticPreview } from '@/components/semantic'
import { useComponentLocale } from '@/composables/use-locale'
import { locales } from '../locales'
const { t } = useComponentLocale(locales)
const semantics = computed(() => [
{ name: 'root', desc: t('root') },
{ name: 'itemTitle', desc: t('itemTitle') },
{ name: 'item', desc: t('item') },
{ name: 'itemContent', desc: t('itemContent') },
{ name: 'itemIcon', desc: t('itemIcon') },
])
const divRef = ref<HTMLDivElement | null>(null)
const items: any[] = [
{
key: '1',
type: 'group',
label: 'Group title',
children: [
{ key: '1-1', label: '1st menu item', icon: h(SaveOutlined) },
{ key: '1-2', label: '2nd menu item', icon: h(EditOutlined) },
],
},
{
key: 'SubMenu',
label: 'SubMenu',
children: [
{
key: 'g1',
label: 'Item 1',
type: 'group',
children: [
{ key: '1', label: 'Option 1' },
{ key: '2', label: 'Option 2' },
],
},
],
},
{ key: '3', type: 'divider' },
{ key: '4', label: 'Delete', icon: h(DeleteOutlined), danger: true },
]
</script>
<template>
<SemanticPreview
component-name="Dropdown"
:semantics="semantics"
>
<template #default="{ classes }">
<div ref="divRef" :style="{ height: '120px', position: 'absolute', top: '50px' }">
<a-dropdown
open
:menu="{ items }"
:styles="{ root: { width: '200px', zIndex: 1 } }"
:get-popup-container="() => divRef!"
:classes="classes"
>
<a @click.prevent>
<a-space>
Hover me
<DownOutlined />
</a-space>
</a>
</a-dropdown>
</div>
</template>
</SemanticPreview>
</template>
```
@@ -0,0 +1,121 @@
# Arrow pointing at the center
## Description (en-US)
Set `arrow` with `pointAtCenter: true`, the arrow will point to the center of the target element.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
const items: MenuItemType[] = [
{
key: '1',
label: '1st menu item',
},
{
key: '2',
label: '2nd menu item',
},
{
key: '3',
label: '3rd menu item',
},
]
const href: Record<string, string> = {
1: 'https://www.antgroup.com',
2: 'https://www.aliyun.com',
3: 'https://www.luohanacademy.com',
}
</script>
<template>
<a-space direction="vertical">
<a-space wrap>
<a-dropdown :menu="{ items }" placement="bottomLeft" :arrow="{ pointAtCenter: true }">
<a-button>bottomLeft</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="bottom" :arrow="{ pointAtCenter: true }">
<a-button>bottom</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="bottomRight" :arrow="{ pointAtCenter: true }">
<a-button>bottomRight</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</a-space>
<a-space wrap>
<a-dropdown :menu="{ items }" placement="topLeft" :arrow="{ pointAtCenter: true }">
<a-button>topLeft</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="top" :arrow="{ pointAtCenter: true }">
<a-button>top</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="topRight" :arrow="{ pointAtCenter: true }">
<a-button>topRight</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</a-space>
</a-space>
</template>
```
@@ -0,0 +1,121 @@
# Arrow
## Description (en-US)
You could display an arrow.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
const items: MenuItemType[] = [
{
key: '1',
label: '1st menu item',
},
{
key: '2',
label: '2nd menu item',
},
{
key: '3',
label: '3rd menu item',
},
]
const href: Record<string, string> = {
1: 'https://www.antgroup.com',
2: 'https://www.aliyun.com',
3: 'https://www.luohanacademy.com',
}
</script>
<template>
<a-space direction="vertical">
<a-space wrap>
<a-dropdown :menu="{ items }" placement="bottomLeft" arrow>
<a-button>bottomLeft</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="bottom" arrow>
<a-button>bottom</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="bottomRight" arrow>
<a-button>bottomRight</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</a-space>
<a-space wrap>
<a-dropdown :menu="{ items }" placement="topLeft" arrow>
<a-button>topLeft</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="top" arrow>
<a-button>top</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="topRight" arrow>
<a-button>topRight</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</a-space>
</a-space>
</template>
```
@@ -0,0 +1,60 @@
# Basic
## Description (en-US)
The most basic dropdown menu.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined, SmileOutlined } from '@antdv-next/icons'
const items: MenuItemType[] = [
{
key: '1',
label: '1st menu item',
},
{
key: '2',
label: '2nd menu item (disabled)',
icon: SmileOutlined,
disabled: true,
},
{
key: '3',
label: '3rd menu item (disabled)',
disabled: true,
},
{
key: '4',
danger: true,
label: 'a danger item',
},
]
const href: Record<string, string> = {
1: 'https://www.antgroup.com',
2: 'https://www.aliyun.com',
3: 'https://www.luohanacademy.com',
}
</script>
<template>
<a-dropdown :menu="{ items }">
<a @click.prevent>
<a-space>
Hover me
<DownOutlined />
</a-space>
</a>
<template #labelRender="item">
<template v-if="item && ['1', '2', '3'].includes(item.key as string)">
<a target="_blank" rel="noopener noreferrer" :href="href[item.key as string]">
{{ item?.label }}
</a>
</template>
</template>
</a-dropdown>
</template>
```
@@ -0,0 +1,47 @@
# Context Menu
## Description (en-US)
The default trigger mode is `hover`, you can change it to `contextMenu`. The pop-up menu position will follow the right-click position.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { theme } from 'antdv-next'
const items: MenuItemType[] = [
{
label: '1st menu item',
key: '1',
},
{
label: '2nd menu item',
key: '2',
},
{
label: '3rd menu item',
key: '3',
},
]
const { token } = theme.useToken()
</script>
<template>
<a-dropdown :menu="{ items }" :trigger="['contextmenu']">
<div
:style="{
color: token.colorTextTertiary,
background: token.colorBgLayout,
height: '200px',
textAlign: 'center',
lineHeight: '200px',
}"
>
Right Click on here
</div>
</a-dropdown>
</template>
```
@@ -0,0 +1,80 @@
# Custom dropdown
## Description (en-US)
Customize the dropdown menu via `popupRender`. If you don't need the Menu content, use the Popover component directly.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
import { theme } from 'antdv-next'
import { computed } from 'vue'
const items: MenuItemType[] = [
{
key: '1',
label: '1st menu item',
},
{
key: '2',
label: '2nd menu item (disabled)',
disabled: true,
},
{
key: '3',
label: '3rd menu item (disabled)',
disabled: true,
},
]
const href: Record<string, string> = {
1: 'https://www.antgroup.com',
2: 'https://www.aliyun.com',
3: 'https://www.luohanacademy.com',
}
const { token } = theme.useToken()
const contentStyle = computed(() => ({
backgroundColor: token.value.colorBgElevated,
borderRadius: token.value.borderRadiusLG,
boxShadow: token.value.boxShadowSecondary,
}))
const menuStyle = {
boxShadow: 'none',
}
</script>
<template>
<a-dropdown :menu="{ items }">
<template #popupRender="menu">
<div :style="contentStyle">
<component :is="menu" :style="menuStyle" />
<a-divider style="margin: 0" />
<a-space style="padding: 8px">
<a-button type="primary">
Click me!
</a-button>
</a-space>
</div>
</template>
<a @click.prevent>
<a-space>
Hover me
<DownOutlined />
</a-space>
</a>
<template #labelRender="item">
<template v-if="item && ['1', '2', '3'].includes(item.key as string)">
<a target="_blank" rel="noopener noreferrer" :href="href[item.key as string]">
{{ item?.label }}
</a>
</template>
</template>
</a-dropdown>
</template>
```
@@ -0,0 +1,135 @@
# Button with dropdown menu
## Description (en-US)
A button is on the left, and a related functional menu is on the right. You can set the icon property to modify the icon of right.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined, EllipsisOutlined, UserOutlined } from '@antdv-next/icons'
import { message } from 'antdv-next'
const [messageApi, ContextHolder] = message.useMessage()
function handleButtonClick(e: MouseEvent) {
messageApi.info('Click on left button.')
console.log('click left button', e)
}
function handleMenuClick(e: any) {
messageApi.info('Click on menu item.')
console.log('click', e)
}
const items: MenuItemType[] = [
{
label: '1st menu item',
key: '1',
icon: UserOutlined,
},
{
label: '2nd menu item',
key: '2',
icon: UserOutlined,
},
{
label: '3rd menu item',
key: '3',
icon: UserOutlined,
danger: true,
},
{
label: '4rd menu item',
key: '4',
icon: UserOutlined,
danger: true,
disabled: true,
},
]
const menuProps = {
items,
onClick: handleMenuClick,
}
</script>
<template>
<ContextHolder />
<a-space wrap>
<a-space-compact>
<a-button @click="handleButtonClick">
Dropdown
</a-button>
<a-dropdown :menu="menuProps" placement="bottomRight">
<a-button>
<template #icon>
<EllipsisOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
<a-space-compact>
<a-button @click="handleButtonClick">
Dropdown
</a-button>
<a-dropdown :menu="menuProps" placement="bottomRight">
<a-button>
<template #icon>
<UserOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
<a-space-compact>
<a-button disabled @click="handleButtonClick">
Dropdown
</a-button>
<a-dropdown :menu="menuProps" placement="bottomRight" disabled>
<a-button disabled>
<template #icon>
<EllipsisOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
<a-space-compact>
<a-tooltip title="tooltip">
<a-button @click="handleButtonClick">
With Tooltip
</a-button>
</a-tooltip>
<a-dropdown :menu="menuProps" placement="bottomRight">
<a-button loading />
</a-dropdown>
</a-space-compact>
<a-dropdown :menu="menuProps">
<a-button icon-placement="end" @click="handleButtonClick">
<template #icon>
<DownOutlined />
</template>
Button
</a-button>
</a-dropdown>
<a-space-compact>
<a-button danger @click="handleButtonClick">
Danger
</a-button>
<a-dropdown :menu="menuProps" placement="bottomRight">
<a-button danger>
<template #icon>
<EllipsisOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
</a-space>
</template>
```
@@ -0,0 +1,48 @@
# Click event
## Description (en-US)
An event will be triggered when you click menu items, in which you can make different operations according to item's key.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
import { message } from 'antdv-next'
const [messageApi, ContextHolder] = message.useMessage()
function onClick({ key }: any) {
messageApi.info(`Click on item ${key}`)
}
const items: MenuItemType[] = [
{
label: '1st menu item',
key: '1',
},
{
label: '2nd menu item',
key: '2',
},
{
label: '3rd menu item',
key: '3',
},
]
</script>
<template>
<ContextHolder />
<a-dropdown :menu="{ items }" @menu-click="onClick">
<a @click.prevent>
<a-space>
Hover me, Click menu item
<DownOutlined />
</a-space>
</a>
</a-dropdown>
</template>
```
@@ -0,0 +1,52 @@
# Extra node
## Description (en-US)
The dropdown menu with shortcut.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined, SettingOutlined } from '@antdv-next/icons'
const items: MenuItemType[] = [
{
key: '1',
label: 'My Account',
disabled: true,
},
{
type: 'divider',
},
{
key: '2',
label: 'Profile',
extra: '⌘P',
},
{
key: '3',
label: 'Billing',
extra: '⌘B',
},
{
key: '4',
label: 'Settings',
icon: SettingOutlined,
extra: '⌘S',
},
]
</script>
<template>
<a-dropdown :menu="{ items }">
<a @click.prevent>
<a-space>
Hover me
<DownOutlined />
</a-space>
</a>
</a-dropdown>
</template>
```
@@ -0,0 +1,59 @@
# Other elements
## Description (en-US)
Divider and disabled menu item.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
const items: MenuItemType[] = [
{
label: '1st menu item',
key: '0',
},
{
label: '2nd menu item',
key: '1',
},
{
type: 'divider',
},
{
label: '3rd menu item (disabled)',
key: '3',
disabled: true,
},
]
const href: Record<string, string> = {
0: 'https://www.antgroup.com',
1: 'https://www.aliyun.com',
}
</script>
<template>
<a-dropdown :menu="{ items }">
<a @click.prevent>
<a-space>
Hover me
<DownOutlined />
</a-space>
</a>
<template #labelRender="item">
<a
v-if="item && ['0', '1'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</template>
```
@@ -0,0 +1,88 @@
# Loading
## Description (en-US)
A loading indicator can be added to a button by setting the `loading` property.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined, EllipsisOutlined } from '@antdv-next/icons'
import { ref } from 'vue'
const items: MenuItemType[] = [
{
label: 'Submit and continue',
key: '1',
},
]
const loadings = ref<boolean[]>([])
function enterLoading(index: number) {
const nextLoadings = [...loadings.value]
nextLoadings[index] = true
loadings.value = nextLoadings
setTimeout(() => {
const resetLoadings = [...loadings.value]
resetLoadings[index] = false
loadings.value = resetLoadings
}, 6000)
}
</script>
<template>
<a-space direction="vertical">
<a-space-compact>
<a-button type="primary" loading>
Submit
</a-button>
<a-dropdown :menu="{ items }">
<a-button type="primary">
<template #icon>
<EllipsisOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
<a-space-compact size="small">
<a-button type="primary" loading>
Submit
</a-button>
<a-dropdown :menu="{ items }">
<a-button type="primary">
<template #icon>
<EllipsisOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
<a-space-compact>
<a-button type="primary" :loading="loadings[0]" @click="enterLoading(0)">
Submit
</a-button>
<a-dropdown :menu="{ items }">
<a-button type="primary">
<template #icon>
<EllipsisOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
<a-space-compact>
<a-button :loading="loadings[1]" @click="enterLoading(1)">
Submit
</a-button>
<a-dropdown :menu="{ items }">
<a-button>
<template #icon>
<DownOutlined />
</template>
</a-button>
</a-dropdown>
</a-space-compact>
</a-space>
</template>
```
@@ -0,0 +1,59 @@
# The way of hiding menu
## Description (en-US)
The default is to close the menu when you click on menu items, this feature can be turned off.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
import { ref } from 'vue'
const open = ref(false)
const items: MenuItemType[] = [
{
label: 'Clicking me will not close the menu.',
key: '1',
},
{
label: 'Clicking me will not close the menu also.',
key: '2',
},
{
label: 'Clicking me will close the menu.',
key: '3',
},
]
function handleMenuClick(info: { key: string }) {
if (info.key === '3') {
open.value = false
}
}
function handleOpenChange(nextOpen: boolean, info: { source: 'trigger' | 'menu' }) {
if (info.source === 'trigger' || nextOpen) {
open.value = nextOpen
}
}
</script>
<template>
<a-dropdown
:menu="{ items, onClick: handleMenuClick }"
:open="open"
@open-change="handleOpenChange"
>
<a @click.prevent>
<a-space>
Hover me
<DownOutlined />
</a-space>
</a>
</a-dropdown>
</template>
```
@@ -0,0 +1,121 @@
# Placement
## Description (en-US)
Support 6 placements.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
const items: MenuItemType[] = [
{
key: '1',
label: '1st menu item',
},
{
key: '2',
label: '2nd menu item',
},
{
key: '3',
label: '3rd menu item',
},
]
const href: Record<string, string> = {
1: 'https://www.antgroup.com',
2: 'https://www.aliyun.com',
3: 'https://www.luohanacademy.com',
}
</script>
<template>
<a-space direction="vertical">
<a-space wrap>
<a-dropdown :menu="{ items }" placement="bottomLeft">
<a-button>bottomLeft</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="bottom">
<a-button>bottom</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="bottomRight">
<a-button>bottomRight</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</a-space>
<a-space wrap>
<a-dropdown :menu="{ items }" placement="topLeft">
<a-button>topLeft</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="top">
<a-button>top</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
<a-dropdown :menu="{ items }" placement="topRight">
<a-button>topRight</a-button>
<template #labelRender="item">
<a
v-if="item && ['1', '2', '3'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</a-space>
</a-space>
</template>
```
@@ -0,0 +1,46 @@
# Selectable Menu
## Description (en-US)
Configure the `selectable` property in `menu` to enable selectable ability.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
const items: MenuItemType[] = [
{
key: '1',
label: 'Item 1',
},
{
key: '2',
label: 'Item 2',
},
{
key: '3',
label: 'Item 3',
},
]
</script>
<template>
<a-dropdown
:menu="{
items,
selectable: true,
defaultSelectedKeys: ['3'],
}"
>
<a-typography-link>
<a-space>
Selectable
<DownOutlined />
</a-space>
</a-typography-link>
</a-dropdown>
</template>
```
@@ -0,0 +1,113 @@
# Custom semantic dom styling
## Description (en-US)
## Source
```vue
<script setup lang="ts">
import type { DropdownProps, MenuItemType } from 'antdv-next'
import { DownOutlined, LogoutOutlined, SettingOutlined } from '@antdv-next/icons'
import { theme } from 'antdv-next'
const { token } = theme.useToken()
const items: MenuItemType[] = [
{
key: '1',
label: 'Profile',
},
{
key: '2',
label: 'Settings',
icon: SettingOutlined,
},
{
type: 'divider',
},
{
key: '3',
label: 'Logout',
icon: LogoutOutlined,
danger: true,
},
]
const classes: DropdownProps['classes'] = {
root: 'demo-dropdown-root',
}
const objectStyles: DropdownProps['styles'] = {
root: {
backgroundColor: '#ffffff',
border: '1px solid #d9d9d9',
borderRadius: '4px',
},
item: {
padding: '8px 12px',
fontSize: '14px',
},
itemTitle: {
fontWeight: '500',
},
itemIcon: {
color: '#1890ff',
marginRight: '8px',
},
itemContent: {
backgroundColor: 'transparent',
},
}
const functionStyles: DropdownProps['styles'] = (info) => {
const isClick = info.props.trigger?.includes('click')
if (isClick) {
return {
root: {
borderColor: '#1890ff',
borderRadius: '8px',
},
}
}
return {}
}
const sharedProps: DropdownProps = {
menu: { items },
placement: 'bottomLeft',
classes,
}
</script>
<template>
<a-flex gap="middle" wrap="wrap">
<a-space direction="vertical" size="large">
<a-dropdown v-bind="sharedProps" :styles="objectStyles">
<a-button>
<a-space>
Object Style
<DownOutlined />
</a-space>
</a-button>
</a-dropdown>
<a-dropdown v-bind="sharedProps" :styles="functionStyles" :trigger="['click']">
<a-button type="primary">
<a-space>
Function Style
<DownOutlined />
</a-space>
</a-button>
</a-dropdown>
</a-space>
</a-flex>
</template>
<style>
.demo-dropdown-root {
background-color: v-bind('token.colorFillAlter');
border: 1px solid v-bind('token.colorBorder');
border-radius: v-bind('`${token.borderRadius}px`');
}
</style>
```
@@ -0,0 +1,72 @@
# Cascading menu
## Description (en-US)
The menu has multiple levels.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
const items: MenuItemType[] = [
{
key: '1',
type: 'group',
label: 'Group title',
children: [
{
key: '1-1',
label: '1st menu item',
},
{
key: '1-2',
label: '2nd menu item',
},
],
},
{
key: '2',
label: 'sub menu',
children: [
{
key: '2-1',
label: '3rd menu item',
},
{
key: '2-2',
label: '4th menu item',
},
],
},
{
key: '3',
label: 'disabled sub menu',
disabled: true,
children: [
{
key: '3-1',
label: '5d menu item',
},
{
key: '3-2',
label: '6th menu item',
},
],
},
]
</script>
<template>
<a-dropdown :menu="{ items }">
<a @click.prevent>
<a-space>
Cascading menu
<DownOutlined />
</a-space>
</a>
</a-dropdown>
</template>
```
@@ -0,0 +1,58 @@
# Trigger mode
## Description (en-US)
The default trigger mode is `hover`, you can change it to `click`.
## Source
```vue
<script setup lang="ts">
import type { MenuItemType } from 'antdv-next'
import { DownOutlined } from '@antdv-next/icons'
const items: MenuItemType[] = [
{
label: '1st menu item',
key: '0',
},
{
label: '2nd menu item',
key: '1',
},
{
type: 'divider',
},
{
label: '3rd menu item',
key: '3',
},
]
const href: Record<string, string> = {
0: 'https://www.antgroup.com',
1: 'https://www.aliyun.com',
}
</script>
<template>
<a-dropdown :menu="{ items }" :trigger="['click']">
<a @click.prevent>
<a-space>
Click me
<DownOutlined />
</a-space>
</a>
<template #labelRender="item">
<a
v-if="item && ['0', '1'].includes(item.key as string)"
target="_blank"
rel="noopener noreferrer"
:href="href[item.key as string]"
>
{{ item?.label }}
</a>
</template>
</a-dropdown>
</template>
```
@@ -0,0 +1,89 @@
---
title: Dropdown
description: A dropdown list.
---
## When To Use
When there are more than a few options to choose from, you can wrap them in a `Dropdown`. By hovering or clicking on the trigger, a dropdown menu will appear, which allows you to choose an option and execute the relevant action.
## Examples
## Demos
| Demo | Path |
| --- | --- |
| Basic | demo/basic.md |
| Extra node | demo/extra.md |
| Placement | demo/placement.md |
| Arrow | demo/arrow.md |
| Other elements | demo/item.md |
| Arrow pointing at the center | demo/arrow-center.md |
| Trigger mode | demo/trigger.md |
| Click event | demo/event.md |
| Button with dropdown menu | demo/dropdown-button.md |
| Custom dropdown | demo/custom-dropdown.md |
| Cascading menu | demo/sub-menu.md |
| The way of hiding menu | demo/overlay-open.md |
| Context Menu | demo/context-menu.md |
| Loading | demo/loading.md |
| Selectable Menu | demo/selectable.md |
| Custom semantic dom styling | demo/style-class.md |
## API
### Props
Common props ref:[Common props](../../docs/vue/common-props.md)
| Property | Description | Type | Default | Version | [Global Config](../config-provider/docs.md#component-config) |
| --- | --- | --- | --- | --- | --- |
| classes | Customize class for each semantic structure inside the Dropdown component. Supports object or function | DropdownClassNamesType | - | - | ✓ |
| styles | Customize inline style for each semantic structure inside the Dropdown component. Supports object or function | DropdownStylesType | - | - | ✓ |
| menu | The menu props | MenuProps & &#123; activeKey?: VcMenuProps['activeKey'], onClick?: MenuEmits['click'] &#125; | - | - | × |
| autoFocus | Focus the first menu item when opened | boolean | - | - | × |
| arrow | Whether the dropdown arrow should be visible. Supports `pointAtCenter` | boolean \| DropdownArrowOptions | false | - | × |
| trigger | The trigger mode which executes the dropdown action. Note that hover can't be used on touchscreens | ('click' \| 'hover' \| 'contextmenu')[] | ['hover'] | - | × |
| popupRender | Customize popup content | (menu: VueNode) =&gt; VueNode | - | - | × |
| open | Whether the dropdown menu is currently open | boolean | - | - | × |
| disabled | Whether the dropdown menu is disabled | boolean | - | - | × |
| destroyOnHidden | Whether destroy dropdown when hidden | boolean | false | - | × |
| align | Popup align config | AlignType | - | - | × |
| getPopupContainer | To set the container of the dropdown menu. The default is to create a div element in body, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) =&gt; HTMLElement | () =&gt; document.body | - | × |
| prefixCls | Customize prefix class name | string | - | - | × |
| transitionName | Motion name of dropdown | string | - | - | × |
| placement | Placement of popup menu: `bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` `left` `leftTop` `leftBottom` `right` `rightTop` `rightBottom` | Placement | `bottomLeft` | left/right: 1.4.0 | × |
| forceRender | Force render dropdown overlay | boolean | - | - | × |
| mouseEnterDelay | Delay in seconds before showing dropdown | number | 0.15 | - | × |
| mouseLeaveDelay | Delay in seconds before hiding dropdown | number | 0.1 | - | × |
| openClassName | Class added to trigger when dropdown is open | string | - | - | × |
| autoAdjustOverflow | Whether to adjust dropdown placement automatically when dropdown is off screen | boolean \| AdjustOverflow | true | - | × |
### Events
| Event | Description | Type | Version |
| --- | --- | --- | --- |
| openChange | Called when the open state is changed. Not trigger when hidden by click item | (open: boolean, info: &#123; source: 'trigger' \| 'menu' &#125;) =&gt; void | - |
| menuClick | Callback when menu item clicked | MenuEmits['click'] | - |
### Slots
| Slot | Description | Type | Version |
|-------------|-------------------------|---------------------------| --- |
| popupRender | Customize popup content | (menu: VueNode) =&gt; any | - |
| labelRender | Customize label content | (item: Item) =&gt; any | - |
Dropdown also supports Menu slots (such as `labelRender`) via the Dropdown slots.
## Note
Please ensure that the child node of `Dropdown` accepts `mouseenter`, `mouseleave`, `focus`, `click` events.
## Semantic DOM
| _semantic | demo/_semantic.md |
## FAQ
### How to prevent Dropdown from being squeezed when it exceeds the screen horizontally?
You can use `width: max-content` style to handle this. ref [#43025](https://github.com/ant-design/ant-design/issues/43025#issuecomment-1594394135).
@@ -0,0 +1,27 @@
# dropdown Token
Use these variables through `theme.components.Dropdown`. This document lists definitions only and does not include values.
```vue
<a-config-provider
:theme="{
token: {
// Global token configuration
},
components: {
Dropdown: {
// Token name: value
},
},
}"
>
...
</a-config-provider>
```
## Token List
| Token | Type | Description |
| --- | --- | --- |
| `zIndexPopup` | `number` | z-index of dropdown |
| `paddingBlock` | `CSSProperties` | Vertical padding of dropdown |