Skip to content

Commit

Permalink
feat(menu): menu
Browse files Browse the repository at this point in the history
  • Loading branch information
ming680 committed Jul 7, 2024
1 parent 8a688dd commit f5972d7
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 36 deletions.
20 changes: 17 additions & 3 deletions src/menu/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Component, OmiDOMAttributes, tag } from 'omi';
import { bind, Component, OmiDOMAttributes, signal, tag } from 'omi';

import classname, { getClassPrefix } from '../_util/classname';
import { getChildrenArray, hasSlot } from '../_util/component';
import { StyledProps } from '../common';
import { DEFAULT_MENU_WIDTH } from './_util/constant';
import { menuDefaultProps } from './defaultProps';
import { TdMenuProps } from './type';
import { MenuValue, TdMenuProps } from './type';

export interface MenuProps extends TdMenuProps, StyledProps, OmiDOMAttributes {}

Expand All @@ -15,12 +15,26 @@ export default class Menu extends Component<MenuProps> {

static defaultProps = {};

active = signal<MenuValue>('');

provide = {
active: this.active,
onChange: this.handleChange,
};

@bind
handleChange(value: MenuValue) {
this.fire('change', value);
}

render() {
const { className, style, width, collapsed } = {
const { className, style, width, collapsed, value } = {
...menuDefaultProps,
...this.props,
};

this.active.value = value;

const classPrefix = getClassPrefix();
const menuWidthArr = Array.isArray(width) ? width : [width, DEFAULT_MENU_WIDTH[1]];

Expand Down
42 changes: 35 additions & 7 deletions src/menu/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, tag } from 'omi';
import { bind, Component, tag } from 'omi';

import classname, { getClassPrefix } from '../_util/classname';
import { convertToLightDomNode } from '../_util/lightDom';
Expand All @@ -8,25 +8,53 @@ import { TdMenuItemProps } from './type';
export interface MenuItemProps extends TdMenuItemProps, StyledProps {}

@tag('t-menu-item')
export default class Menu extends Component<MenuItemProps> {
export default class MenuItem extends Component<MenuItemProps> {
static isLightDOM = true;

inject = ['active', 'onChange'];

constructor() {
super();
this.addEventListener('click', this.handleClick);
}

@bind
handleClick(evt: MouseEvent) {
if (!(evt instanceof MouseEvent)) {
// 防止死循环 下面还会 fire('click') 又触发了当前函数的执行
return;
}
// 阻止自定义dom上绑定的onClick原生事件
evt.stopImmediatePropagation();
if (this.props.disabled) {
return;
}
this.fire('click', {
context: this,
value: this.props.value,
});
this.injection.onChange?.(this.props.value);
}

uninstalled() {
this.removeEventListener('click', this.handleClick);
}

render() {
const { label, icon, className, disabled, href, target } = this.props;
const { label, icon, className, disabled, href, target, value } = this.props;

const classPrefix = getClassPrefix();

const lightIcon = convertToLightDomNode(icon);

this.className = classname(`${classPrefix}-menu__item`, className, {
[`${classPrefix}-is-disabled`]: disabled,
// [`${classPrefix}-is-active`]: value === active,
[`${classPrefix}-is-active`]: value === this.injection.active.value,
[`${classPrefix}-menu__item--plain`]: !icon,
});

const lightIcon = convertToLightDomNode(icon);

return (
<>
{icon}
{lightIcon}
{href ? (
<a href={href} target={target} className={classname(`${classPrefix}-menu__item-link`)}>
Expand Down
20 changes: 18 additions & 2 deletions src/menu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,35 @@ usage: { title: '', description: '' }
spline: base
---

### 基础使用
### 可收起的侧边导航

{{ base }}
在侧边导航上提供收起按钮,点击后可以将侧边栏最小化,常见于带有图标的侧边导航。

{{ closable-side }}

## API

### Menu Props

名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
className | String | - | 类名 | N
collapsed | Boolean | false | 是否收起菜单 | N
logo | TElement | - | 站点 LOGO。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
operations | TElement | - | 导航操作区域。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
value | String / Number | - | 激活菜单项。TS 类型:`MenuValue` `type MenuValue = string \| number`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/menu/type.ts) | N
width | String / Number / Array | '232px' | 菜单宽度。值类型为数组时,分别表示菜单展开和折叠的宽度。[ 展开时的宽度, 折叠时的宽度 ],示例:['200px', '80px']。TS 类型:`string \| number \| Array<string \| number>` | N
onChange | Function | | TS 类型:`(evt: CustomEvent<MenuValue>) => void`<br/>激活菜单项发生变化时触发 | N


### MenuItem Props


名称 | 类型 | 默认值 | 说明 | 必传
-- | -- | -- | -- | --
disabled | Boolean | - | 是否禁用菜单项展开/收起/跳转等功能 | N
href | String | - | 跳转链接 | N
icon | TElement | - | 图标。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
target | String | - | 链接或路由跳转方式。可选项:_blank/_self/_parent/_top | N
value | String / Number | - | 菜单项唯一标识。TS 类型:`MenuValue` | N
onClick | Function | | TS 类型:`(evt: CustomEvent<{ e: MouseEvent, value: MenuValue }>) => void`<br/>点击时触发 | N
13 changes: 0 additions & 13 deletions src/menu/_example/base.tsx

This file was deleted.

40 changes: 40 additions & 0 deletions src/menu/_example/closable-side.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import 'tdesign-web-components/button';
import 'tdesign-web-components/icon';
import 'tdesign-web-components/menu';

import { Component, signal } from 'omi';

export default class CloseableSide extends Component {
collapsed = signal(false);

active = signal('0');

render() {
return (
<t-menu
value={this.active.value}
collapsed={this.collapsed.value}
onChange={(evt) => {
this.active.value = evt.detail;
}}
>
<span slot="logo">LOGO</span>
<t-menu-item label="仪表盘" value="0" icon={<t-icon name="app" />} />
<t-menu-item label="资源列表" value="1" icon={<t-icon name="code" />} />
<t-menu-item label="调度平台" value="2" icon={<t-icon name="file" />} />
<t-menu-item label="精准监控" value="3" icon={<t-icon name="user" />} />
<t-menu-item label="根目录" value="4" icon={<t-icon name="rollback" />} />
<t-menu-item label="消息区" value="5" icon={<t-icon name="mail" />} />
<t-button
slot="operations"
variant="text"
shape="square"
icon={<t-icon name="view-list" />}
onClick={() => {
this.collapsed.value = !this.collapsed.value;
}}
/>
</t-menu>
);
}
}
13 changes: 2 additions & 11 deletions src/menu/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ export interface TdMenuProps {
* @default false
*/
collapsed?: boolean;
/**
* 同级别互斥展开
* @default false
*/
expandMutex?: boolean;
/**
* 激活菜单项
*/
Expand All @@ -23,11 +18,7 @@ export interface TdMenuProps {
/**
* 激活菜单项发生变化时触发
*/
onChange?: (value: MenuValue) => void;
/**
* 展开的菜单项发生变化时触发
*/
onExpand?: (value: Array<MenuValue>) => void;
onChange?: (value: CustomEvent<MenuValue>) => void;
}

export interface TdMenuItemProps {
Expand Down Expand Up @@ -59,7 +50,7 @@ export interface TdMenuItemProps {
/**
* 点击时触发
*/
onClick?: (context: { e: HTMLElement; value: MenuValue }) => void;
onClick?: (event: CustomEvent<{ e: HTMLElement; value: MenuValue }>) => void;
}

export type MenuValue = string | number;

0 comments on commit f5972d7

Please sign in to comment.