feat: menu items icon add arg
parent
760c4c2695
commit
eba8f6b960
|
@ -22,8 +22,9 @@ Horizontal top navigation menu.
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { h, ref } from 'vue';
|
import { h, ref } from 'vue';
|
||||||
import { MailOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons-vue';
|
import { MailOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { MenuProps } from 'ant-design-vue';
|
||||||
const current = ref<string[]>(['mail']);
|
const current = ref<string[]>(['mail']);
|
||||||
const items = ref([
|
const items = ref<MenuProps['items']>([
|
||||||
{
|
{
|
||||||
key: 'mail',
|
key: 'mail',
|
||||||
icon: () => h(MailOutlined),
|
icon: () => h(MailOutlined),
|
||||||
|
|
|
@ -66,14 +66,14 @@ More layouts with navigation: [Layout](/components/layout).
|
||||||
|
|
||||||
#### MenuItemType
|
#### MenuItemType
|
||||||
|
|
||||||
| Param | Description | Type | Default value | Version |
|
| Param | Description | Type | Default value | Version |
|
||||||
| -------- | ------------------------------------ | ------- | ------------- | ------- |
|
| --- | --- | --- | --- | --- |
|
||||||
| danger | Display the danger style | boolean | false | |
|
| danger | Display the danger style | boolean | false | |
|
||||||
| disabled | Whether menu item is disabled | boolean | false | |
|
| disabled | Whether menu item is disabled | boolean | false | |
|
||||||
| icon | The icon of the menu item | VueNode | - | |
|
| icon | The icon of the menu item | VueNode \| (item: MenuItemType) => VNode | - | |
|
||||||
| key | Unique ID of the menu item | string | - | |
|
| key | Unique ID of the menu item | string | - | |
|
||||||
| label | Menu label | VueNode | - | |
|
| label | Menu label | VueNode | - | |
|
||||||
| title | Set display title for collapsed item | string | - | |
|
| title | Set display title for collapsed item | string | - | |
|
||||||
|
|
||||||
#### SubMenuType
|
#### SubMenuType
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ More layouts with navigation: [Layout](/components/layout).
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| children | Sub-menus or sub-menu items | [ItemType\[\]](#ItemType) | - | |
|
| children | Sub-menus or sub-menu items | [ItemType\[\]](#ItemType) | - | |
|
||||||
| disabled | Whether sub-menu is disabled | boolean | false | |
|
| disabled | Whether sub-menu is disabled | boolean | false | |
|
||||||
| icon | Icon of sub menu | VueNode\|()=>VueNode | - | |
|
| icon | Icon of sub menu | VueNode \| (item: SubMenuType) => VueNode | - | |
|
||||||
| key | Unique ID of the sub-menu | string | - | |
|
| key | Unique ID of the sub-menu | string | - | |
|
||||||
| label | Menu label | VueNode | - | |
|
| label | Menu label | VueNode | - | |
|
||||||
| popupClassName | Sub-menu class name, not working when `mode="inline"` | string | - | |
|
| popupClassName | Sub-menu class name, not working when `mode="inline"` | string | - | |
|
||||||
|
|
|
@ -67,14 +67,14 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Vn4XSqJFAxcAAA
|
||||||
|
|
||||||
### MenuItemType
|
### MenuItemType
|
||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| -------- | ------------------------ | -------------------- | ------ | ---- |
|
| -------- | ------------------------ | -------------------------------------- | ------ | ---- |
|
||||||
| danger | 展示错误状态样式 | boolean | false | |
|
| danger | 展示错误状态样式 | boolean | false | |
|
||||||
| disabled | 是否禁用 | boolean | false | |
|
| disabled | 是否禁用 | boolean | false | |
|
||||||
| icon | 菜单图标 | VueNode\|()=>VueNode | - | |
|
| icon | 菜单图标 | VueNode\|(item: MenuItemType)=>VueNode | - | |
|
||||||
| key | item 的唯一标志 | string | - | |
|
| key | item 的唯一标志 | string | - | |
|
||||||
| label | 菜单项标题 | VueNode | - | |
|
| label | 菜单项标题 | VueNode | - | |
|
||||||
| title | 设置收缩时展示的悬浮标题 | string | - | |
|
| title | 设置收缩时展示的悬浮标题 | string | - | |
|
||||||
|
|
||||||
#### SubMenuType
|
#### SubMenuType
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Vn4XSqJFAxcAAA
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| children | 子菜单的菜单项 | [ItemType\[\]](#ItemType) | - | |
|
| children | 子菜单的菜单项 | [ItemType\[\]](#ItemType) | - | |
|
||||||
| disabled | 是否禁用 | boolean | false | |
|
| disabled | 是否禁用 | boolean | false | |
|
||||||
| icon | 菜单图标 | VueNode\|()=>VueNode | - | |
|
| icon | 菜单图标 | VueNode\|(item: SubMenuType)=>VueNode | - | |
|
||||||
| key | 唯一标志 | string | - | |
|
| key | 唯一标志 | string | - | |
|
||||||
| label | 菜单项标题 | VueNode | - | |
|
| label | 菜单项标题 | VueNode | - | |
|
||||||
| popupClassName | 子菜单样式,`mode="inline"` 时无效 | string | - | |
|
| popupClassName | 子菜单样式,`mode="inline"` 时无效 | string | - | |
|
||||||
|
|
|
@ -4,9 +4,13 @@ import { computed, defineComponent } from 'vue';
|
||||||
import PropTypes from '../../_util/vue-types';
|
import PropTypes from '../../_util/vue-types';
|
||||||
import { useInjectMenu } from './hooks/useMenuContext';
|
import { useInjectMenu } from './hooks/useMenuContext';
|
||||||
import { useMeasure } from './hooks/useKeyPath';
|
import { useMeasure } from './hooks/useKeyPath';
|
||||||
|
import type { ItemType } from './interface';
|
||||||
|
import { objectType } from '../../_util/type';
|
||||||
|
|
||||||
export const menuItemGroupProps = () => ({
|
export const menuItemGroupProps = () => ({
|
||||||
title: PropTypes.any,
|
title: PropTypes.any,
|
||||||
|
// Internal user prop
|
||||||
|
originItemValue: objectType<ItemType>(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type MenuItemGroupProps = Partial<ExtractPropTypes<ReturnType<typeof menuItemGroupProps>>>;
|
export type MenuItemGroupProps = Partial<ExtractPropTypes<ReturnType<typeof menuItemGroupProps>>>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { flattenChildren, getPropsSlot, isValidElement } from '../../_util/props-util';
|
import { flattenChildren, isValidElement } from '../../_util/props-util';
|
||||||
import PropTypes from '../../_util/vue-types';
|
import PropTypes from '../../_util/vue-types';
|
||||||
import type { ExtractPropTypes, PropType } from 'vue';
|
import type { ExtractPropTypes, PropType } from 'vue';
|
||||||
import {
|
import {
|
||||||
|
@ -13,12 +13,13 @@ import { useInjectKeyPath, useMeasure } from './hooks/useKeyPath';
|
||||||
import { useInjectFirstLevel, useInjectMenu } from './hooks/useMenuContext';
|
import { useInjectFirstLevel, useInjectMenu } from './hooks/useMenuContext';
|
||||||
import { cloneElement } from '../../_util/vnode';
|
import { cloneElement } from '../../_util/vnode';
|
||||||
import Tooltip from '../../tooltip';
|
import Tooltip from '../../tooltip';
|
||||||
import type { MenuInfo } from './interface';
|
import type { ItemType, MenuInfo } from './interface';
|
||||||
import KeyCode from '../../_util/KeyCode';
|
import KeyCode from '../../_util/KeyCode';
|
||||||
import useDirectionStyle from './hooks/useDirectionStyle';
|
import useDirectionStyle from './hooks/useDirectionStyle';
|
||||||
import Overflow from '../../vc-overflow';
|
import Overflow from '../../vc-overflow';
|
||||||
import devWarning from '../../vc-util/devWarning';
|
import devWarning from '../../vc-util/devWarning';
|
||||||
import type { MouseEventHandler } from '../../_util/EventInterface';
|
import type { MouseEventHandler } from '../../_util/EventInterface';
|
||||||
|
import { objectType } from '../../_util/type';
|
||||||
|
|
||||||
let indexGuid = 0;
|
let indexGuid = 0;
|
||||||
export const menuItemProps = () => ({
|
export const menuItemProps = () => ({
|
||||||
|
@ -33,6 +34,8 @@ export const menuItemProps = () => ({
|
||||||
onClick: Function as PropType<MouseEventHandler>,
|
onClick: Function as PropType<MouseEventHandler>,
|
||||||
onKeydown: Function as PropType<MouseEventHandler>,
|
onKeydown: Function as PropType<MouseEventHandler>,
|
||||||
onFocus: Function as PropType<MouseEventHandler>,
|
onFocus: Function as PropType<MouseEventHandler>,
|
||||||
|
// Internal user prop
|
||||||
|
originItemValue: objectType<ItemType>(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type MenuItemProps = Partial<ExtractPropTypes<ReturnType<typeof menuItemProps>>>;
|
export type MenuItemProps = Partial<ExtractPropTypes<ReturnType<typeof menuItemProps>>>;
|
||||||
|
@ -215,7 +218,7 @@ export default defineComponent({
|
||||||
optionRoleProps['aria-selected'] = selected.value;
|
optionRoleProps['aria-selected'] = selected.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const icon = getPropsSlot(slots, props, 'icon');
|
const icon = props.icon ?? slots.icon?.(props);
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
{...tooltipProps}
|
{...tooltipProps}
|
||||||
|
@ -248,7 +251,7 @@ export default defineComponent({
|
||||||
title={typeof title === 'string' ? title : undefined}
|
title={typeof title === 'string' ? title : undefined}
|
||||||
>
|
>
|
||||||
{cloneElement(
|
{cloneElement(
|
||||||
typeof icon === 'function' ? icon() : icon,
|
typeof icon === 'function' ? icon(props.originItemValue) : icon,
|
||||||
{
|
{
|
||||||
class: `${prefixCls.value}-item-icon`,
|
class: `${prefixCls.value}-item-icon`,
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,7 +28,8 @@ import devWarning from '../../vc-util/devWarning';
|
||||||
import isValid from '../../_util/isValid';
|
import isValid from '../../_util/isValid';
|
||||||
import type { MouseEventHandler } from '../../_util/EventInterface';
|
import type { MouseEventHandler } from '../../_util/EventInterface';
|
||||||
import type { Key } from '../../_util/type';
|
import type { Key } from '../../_util/type';
|
||||||
import type { MenuTheme } from './interface';
|
import { objectType } from '../../_util/type';
|
||||||
|
import type { ItemType, MenuTheme } from './interface';
|
||||||
|
|
||||||
let indexGuid = 0;
|
let indexGuid = 0;
|
||||||
|
|
||||||
|
@ -46,6 +47,9 @@ export const subMenuProps = () => ({
|
||||||
onMouseenter: Function as PropType<MouseEventHandler>,
|
onMouseenter: Function as PropType<MouseEventHandler>,
|
||||||
onMouseleave: Function as PropType<MouseEventHandler>,
|
onMouseleave: Function as PropType<MouseEventHandler>,
|
||||||
onTitleClick: Function as PropType<(e: MouseEvent, key: Key) => void>,
|
onTitleClick: Function as PropType<(e: MouseEvent, key: Key) => void>,
|
||||||
|
|
||||||
|
// Internal user prop
|
||||||
|
originItemValue: objectType<ItemType>(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type SubMenuProps = Partial<ExtractPropTypes<ReturnType<typeof subMenuProps>>>;
|
export type SubMenuProps = Partial<ExtractPropTypes<ReturnType<typeof subMenuProps>>>;
|
||||||
|
@ -224,7 +228,7 @@ export default defineComponent({
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{cloneElement(
|
{cloneElement(
|
||||||
typeof icon === 'function' ? icon() : icon,
|
typeof icon === 'function' ? icon(props.originItemValue) : icon,
|
||||||
{
|
{
|
||||||
class: `${prefixCls.value}-item-icon`,
|
class: `${prefixCls.value}-item-icon`,
|
||||||
},
|
},
|
||||||
|
@ -247,7 +251,7 @@ export default defineComponent({
|
||||||
);
|
);
|
||||||
const baseTitleNode = () => {
|
const baseTitleNode = () => {
|
||||||
const subMenuPrefixClsValue = subMenuPrefixCls.value;
|
const subMenuPrefixClsValue = subMenuPrefixCls.value;
|
||||||
const icon = getPropsSlot(slots, props, 'icon');
|
const icon = props.icon ?? slots.icon?.(props);
|
||||||
const expandIcon = props.expandIcon || slots.expandIcon || menuExpandIcon.value;
|
const expandIcon = props.expandIcon || slots.expandIcon || menuExpandIcon.value;
|
||||||
const title = renderTitle(getPropsSlot(slots, props, 'title'), icon);
|
const title = renderTitle(getPropsSlot(slots, props, 'title'), icon);
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -9,19 +9,19 @@ import ItemGroup from '../ItemGroup';
|
||||||
import MenuDivider from '../Divider';
|
import MenuDivider from '../Divider';
|
||||||
import MenuItem from '../MenuItem';
|
import MenuItem from '../MenuItem';
|
||||||
import type { Key } from '../../../_util/type';
|
import type { Key } from '../../../_util/type';
|
||||||
|
import type { VNode } from 'vue';
|
||||||
import { ref, shallowRef, watch } from 'vue';
|
import { ref, shallowRef, watch } from 'vue';
|
||||||
import type { MenuProps } from '../Menu';
|
import type { MenuProps } from '../Menu';
|
||||||
import type { StoreMenuInfo } from './useMenuContext';
|
import type { StoreMenuInfo } from './useMenuContext';
|
||||||
|
|
||||||
export interface MenuItemType extends VcMenuItemType {
|
export interface MenuItemType extends VcMenuItemType {
|
||||||
danger?: boolean;
|
danger?: boolean;
|
||||||
icon?: any;
|
icon?: VNode | ((item: MenuItemType) => VNode);
|
||||||
title?: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SubMenuType extends Omit<VcSubMenuType, 'children'> {
|
export interface SubMenuType extends Omit<VcSubMenuType, 'children'> {
|
||||||
icon?: any;
|
icon?: VNode | ((item: SubMenuType) => VNode);
|
||||||
theme?: 'dark' | 'light';
|
|
||||||
children: ItemType[];
|
children: ItemType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ function convertItemsToNodes(
|
||||||
const childrenNodes = convertItemsToNodes(children, store, parentMenuInfo);
|
const childrenNodes = convertItemsToNodes(children, store, parentMenuInfo);
|
||||||
// Group
|
// Group
|
||||||
return (
|
return (
|
||||||
<ItemGroup key={mergedKey} {...restProps} title={label}>
|
<ItemGroup key={mergedKey} {...restProps} title={label} originItemValue={opt}>
|
||||||
{childrenNodes}
|
{childrenNodes}
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
);
|
);
|
||||||
|
@ -84,7 +84,7 @@ function convertItemsToNodes(
|
||||||
parentKeys: [].concat(parentKeys, mergedKey),
|
parentKeys: [].concat(parentKeys, mergedKey),
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<SubMenu key={mergedKey} {...restProps} title={label}>
|
<SubMenu key={mergedKey} {...restProps} title={label} originItemValue={opt}>
|
||||||
{childrenNodes}
|
{childrenNodes}
|
||||||
</SubMenu>
|
</SubMenu>
|
||||||
);
|
);
|
||||||
|
@ -97,7 +97,7 @@ function convertItemsToNodes(
|
||||||
menuInfo.isLeaf = true;
|
menuInfo.isLeaf = true;
|
||||||
store.set(mergedKey, menuInfo);
|
store.set(mergedKey, menuInfo);
|
||||||
return (
|
return (
|
||||||
<MenuItem key={mergedKey} {...restProps}>
|
<MenuItem key={mergedKey} {...restProps} originItemValue={opt}>
|
||||||
{label}
|
{label}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue