浏览代码

Merge pull request #1618 from DouyinFE/feat-NavExpandIcon

feat: Nav add Footer onClick & expandIcon
代强 2 年之前
父节点
当前提交
838b3a67bf

+ 39 - 41
content/navigation/navigation/index-en-US.md

@@ -263,8 +263,8 @@ import { Link } from "react-router-dom";
                 items: ["Dashboard", "Nothing Here"]
             }
         ]}
-    ></Nav>
-}
+    ></Nav>;
+};
 ```
 
 
@@ -728,34 +728,35 @@ function NavApp (props = {}) {
 
 ### Nav
 
-| Properties          | Type                                                                                                                                                                                       | Description                                                                                                                      | Default    |
-| ------------------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -------------------------------------------------------------------------------------------------------------------------------- | ---------- |
-| bodyStyle           | Custom style for navigation item list                                                                                                                                                      | object                                                                                                                           |            |
-| className           | Style name of outermost element                                                                                                                                                            | boolean                                                                                                                          |            |
-| defaultIsCollapsed  | Whether the default is put away, valid only when `mode = "vertical"`                                                                                                                       | boolean                                                                                                                          | false      |
-| defaultOpenKeys     | Initially open sub navigation `itemKey` array, valid only `mode = "vertical"`and the sidebar is in an expanded state                                                                       | string[]                                                                                                                         | []         |
-| defaultSelectedKeys | Originally selected navigation item `itemKey` array                                                                                                                                        | string[]                                                                                                                         | []         |
-| footer              | The bottom area configure objects or elements, see [Nav.Footer](#Nav.Footer)                                                                                                               | object\|ReactNode                                                                                                                |            |
-| getPopupContainer   | Dropdown's getPopupContainer config of vertical collapsed Nav or horizontal Nav. >= v2.24     | Function |                      |
-| header              | Head area configuration objects or elements, see [Nav.Header](#Nav.Header)                                                                                                                 | object\|ReactNode                                                                                                                |            |
-| isCollapsed         | A controlled attribute of whether it is in a put-away state, valid only when `mode = "vertical"`                                                                                           | boolean                                                                                                                          |            |
-| items               | Navigate the list of items, each item can continue with the items property. If it is a string array, each item is taken as text and itemKey                                                | object\|string[]\|[Item](#Nav.Item)[]\|[Sub](#Nav.Sub)[]                                                                         |            |
-| mode                | Navigation type, currently supports horizontal and vertical, optional value: `vertical`\                                                                                                   |`horizontal`                                                                                      | string                                                                                                                           | `vertical` |
-| onClick             | Trigger when clicking on any navigation item | <ApiType detail='({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) => void'>(itemKey, event, isOpen) => void</ApiType>           | () = > {}  |
-| onCollapseChange    | The callback when the state changes.                                                                                                                                                       | <ApiType detail='(isCollapsed: boolean) => void'>(isCollapsed) => void </ApiType>                                                                                         | () = > {}  |
-| onOpenChange        | Triggers when switching the hidden state of a sub navigation project                                                                                                                       |<ApiType detail='({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void'> ({itemKey, openKeys, event, isOpen}) => void </ApiType>                                         | () = > {}  |
-| onSelect            | Triggers the first time you select an optional navigation project, where the selected Items field version > = 0.17.0 is supported                                                          | <ApiType detail='({ itemKey: string, selectedKeys: string[], selectedItems: Item[], domEvent: MouseEvent, isOpen: boolean }) => void'>(onSelectProps) => void </ApiType>  | () = > {}  |
-| openKeys            | Controlled open sub navigation `itemKey` array, expanded with `onOpenChange` callback control sub navigation items, valid only `mode = "vertical"`and the sidebar is in an unfolding state | string[]                                                                                                                         |            |
-| renderWrapper       | Custom navigation item outer component  >=2.24.0                                                                                                                                           |<ApiType detail='(data:{ itemElement:ReactElement, isSubNav:boolean, isInSubNav:boolean, props:SubNavProps\| ItemProps }) => ReactNode'>(data) => ReactNode</ApiType>  | |
-| prefixCls           | classsname prefix                                                                                                                                                                          | string                                                                                                                                                              | `semi`                  |
-| selectedKeys        | Controlled navigation item `itemKey` array, with `onSelect` callback control navigation item selection                                                                                     | string[]                                                                                                                         |            |
-| style               | Custom styles for outermost elements                                                                                                                                                       | object                                                                                                                           |            |
-| subNavCloseDelay    | Delay of sub navigation floating layer closure. Effective when the limit is true or mode is "limit" in MS                                                                                  | number                                                                                                                           | 100        |
-| subNavOpenDelay     | The delay displayed by the sub navigation floating layer. Effective when the input is true or mode is "selected" in MS                                                                     | number                                                                                                                           | 0          |
-| tooltipHideDelay    | The latency hidden by tooltip is valid when it is true in MS                                                                                                                               | number                                                                                                                           | 100        |
-| tooltipShowDelay    | The delay displayed by tooltip is valid when it is true in MS                                                                                                                              | number                                                                                                                           | 0          |
-| limitIndent         | To lift the indentation limit, you can use level to customize the indentation of navigation items. The horizontal mode can only be true >=1.27.0                                           | boolean                                                                                                                          | true       |
-| toggleIconPosition  | Parent navigation item arrow position with child navigation items >=1.27.0                                                                                                                 | 'left' \| 'right'                                                                                                                | 'right'    |
+| Properties          | Type                                                                                                                                                                                       | Description                                                                                                                                                              | Default   |
+| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- |
+| bodyStyle           | Custom style for navigation item list                                                                                                                                                      | object                                                                                                                                                                   |           |
+| className           | Style name of outermost element                                                                                                                                                            | boolean                                                                                                                                                                  |           |
+| defaultIsCollapsed  | Whether the default is put away, valid only when `mode = "vertical"`                                                                                                                       | boolean                                                                                                                                                                  | false     |
+| defaultOpenKeys     | Initially open sub navigation `itemKey` array, valid only `mode = "vertical"`and the sidebar is in an expanded state                                                                       | string[]                                                                                                                                                                 | []        |
+| defaultSelectedKeys | Originally selected navigation item `itemKey` array                                                                                                                                        | string[]                                                                                                                                                                 | []        |
+| expandIcon          | Default Arrow Icon             | ReactNode                                                       |         |
+| footer              | The bottom area configure objects or elements, see [Nav.Footer](#Nav.Footer)                                                                                                               | object\|ReactNode                                                                                                                                                        |           |
+| getPopupContainer   | Dropdown's getPopupContainer config of vertical collapsed Nav or horizontal Nav. >= v2.24                                                                                                  | Function                                                                                                                                                                 |           |
+| header              | Head area configuration objects or elements, see [Nav.Header](#Nav.Header)                                                                                                                 | object\|ReactNode                                                                                                                                                        |           |
+| isCollapsed         | A controlled attribute of whether it is in a put-away state, valid only when `mode = "vertical"`                                                                                           | boolean                                                                                                                                                                  |           |
+| items               | Navigate the list of items, each item can continue with the items property. If it is a string array, each item is taken as text and itemKey                                                | object\|string[]\|[Item](#Nav.Item)[]\|[Sub](#Nav.Sub)[]                                                                                                                 |           |
+| mode                | Navigation type, currently supports horizontal and vertical, optional value: `vertical`\                                                                                                   | `horizontal`                                                                                                                                                             | string    | `vertical` |
+| onClick             | Trigger when clicking on any navigation item                                                                                                                                               | <ApiType detail='({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) => void'>(itemKey, event, isOpen) => void</ApiType>                                        | () = > {} |
+| onCollapseChange    | The callback when the state changes.                                                                                                                                                       | <ApiType detail='(isCollapsed: boolean) => void'>(isCollapsed) => void </ApiType>                                                                                        | () = > {} |
+| onOpenChange        | Triggers when switching the hidden state of a sub navigation project                                                                                                                       | <ApiType detail='({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void'> ({itemKey, openKeys, event, isOpen}) => void </ApiType>      | () = > {} |
+| onSelect            | Triggers the first time you select an optional navigation project, where the selected Items field version > = 0.17.0 is supported                                                          | <ApiType detail='({ itemKey: string, selectedKeys: string[], selectedItems: Item[], domEvent: MouseEvent, isOpen: boolean }) => void'>(onSelectProps) => void </ApiType> | () = > {} |
+| openKeys            | Controlled open sub navigation `itemKey` array, expanded with `onOpenChange` callback control sub navigation items, valid only `mode = "vertical"`and the sidebar is in an unfolding state | string[]                                                                                                                                                                 |           |
+| renderWrapper       | Custom navigation item outer component  >=2.24.0                                                                                                                                           | <ApiType detail='(data:{ itemElement:ReactElement, isSubNav:boolean, isInSubNav:boolean, props:SubNavProps\| ItemProps }) => ReactNode'>(data) => ReactNode</ApiType>    |           |
+| prefixCls           | classsname prefix                                                                                                                                                                          | string                                                                                                                                                                   | `semi`    |
+| selectedKeys        | Controlled navigation item `itemKey` array, with `onSelect` callback control navigation item selection                                                                                     | string[]                                                                                                                                                                 |           |
+| style               | Custom styles for outermost elements                                                                                                                                                       | object                                                                                                                                                                   |           |
+| subNavCloseDelay    | Delay of sub navigation floating layer closure. Effective when the limit is true or mode is "limit" in MS                                                                                  | number                                                                                                                                                                   | 100       |
+| subNavOpenDelay     | The delay displayed by the sub navigation floating layer. Effective when the input is true or mode is "selected" in MS                                                                     | number                                                                                                                                                                   | 0         |
+| tooltipHideDelay    | The latency hidden by tooltip is valid when it is true in MS                                                                                                                               | number                                                                                                                                                                   | 100       |
+| tooltipShowDelay    | The delay displayed by tooltip is valid when it is true in MS                                                                                                                              | number                                                                                                                                                                   | 0         |
+| limitIndent         | To lift the indentation limit, you can use level to customize the indentation of navigation items. The horizontal mode can only be true >=1.27.0                                           | boolean                                                                                                                                                                  | true      |
+| toggleIconPosition  | Parent navigation item arrow position with child navigation items >=1.27.0                                                                                                                 | 'left' \| 'right'                                                                                                                                                        | 'right'   |
 
 ### Nav.Item
 
@@ -804,13 +805,14 @@ function NavApp (props = {}) {
 
 ### Nav.Footer
 
-| Properties     | Description                                                                                                                       | Type                                      | Default | Version |
-| -------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------- | ------- |
-| children       | Sub element                                                                                                                       | ReactNode                                 |         |         |
-| className      | Outermost style name                                                                                                              | string                                    |         |         |
-| collapseButton | Whether to display the bottom "collapse sidebar" button, only work when mode="vertical" and the children parameter of the Footer component is empty | boolean\|ReactNode      | false   |         |
-| collapseText   | Title of the collapse button                                                                                                      | (collapsed:boolean) => string\|ReactNode |         | 0.35.0  |
-| style          | Outermost style                                                                                                                   | object                                    |         |         |
+| Properties     | Description                                                                                                                                         | Type                                     | Default | Version |
+| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------- | ------- |
+| children       | Sub element                                                                                                                                         | ReactNode                                |         |         |
+| className      | Outermost style name                                                                                                                                | string                                   |         |         |
+| collapseButton | Whether to display the bottom "collapse sidebar" button, only work when mode="vertical" and the children parameter of the Footer component is empty | boolean\|ReactNode                       | false   |         |
+| collapseText   | Title of the collapse button                                                                                                                        | (collapsed:boolean) => string\|ReactNode |         | 0.35.0  |
+| style          | Outermost style                                                                                                                                     | object                                   |         |         |
+| onClick        | Click callback                                                                                                                             | (event) => void                                   |         |         |
 
 ## Accessibility
 - ### Keyboard and Focus
@@ -828,10 +830,6 @@ function NavApp (props = {}) {
 ## Design Tokens
 <DesignToken/>
 
-<!-- ## Related Material
-```material
-2, 43, 312
-``` -->
 ## Related Material
 <semi-material-list code="2, 312"></semi-material-list>
 

+ 7 - 6
content/navigation/navigation/index.md

@@ -744,8 +744,9 @@ function NavApp (props = {}) {
 | defaultIsCollapsed  | 默认是否处于收起状态,仅 `mode = "vertical"` 时有效                                                    | boolean                                                                                                                                                             | false                   |
 | defaultOpenKeys     | 初始打开的子导航 `itemKey` 数组,仅 `mode = "vertical"` 且侧边栏处于展开状态时有效                               | string[]                                                                                                                                                            | []                      |
 | defaultSelectedKeys | 初始选中的导航项 `itemKey` 数组                                                                   | string[]                                                                                                                                                            | []                      |
+| expandIcon          | 默认下拉箭头Icon, v>=2.36                                                                 | ReactNode                                                                                                                                                     |                       |
 | footer              | 底部区域配置对象或元素,详见 [Nav.Footer](#Nav.Footer)                                                | object\                                                                                                                                                             | ReactNode               |                      |
-| getPopupContainer   | 垂直 Nav 折叠或 水平 Nav中 Dropdown 的 getPopupContainer 配置,可指定弹出层容器, >=2.24.0                        | Function |                      |
+| getPopupContainer   | 垂直 Nav 折叠或 水平 Nav中 Dropdown 的 getPopupContainer 配置,可指定弹出层容器, v>=2.24.0                        | Function |                      |
 | header              | 头部区域配置对象或元素,详见 [Nav.Header](#Nav.Header)                                                | object\                                                                                                                                                             | ReactNode               |                      |
 | isCollapsed         | 是否处于收起状态的受控属性,仅 `mode = "vertical"` 时有效                                                 | boolean                                                                                                                                                             |                         |
 | items               | 导航项目列表,每一项可以继续带有 items 属性。如果为 string 数组,则会取每一项作为 text 和 itemKey                         | object\| string[]\| [Item](#Nav.Item)[] \| [Sub](#Nav.Sub)[] |  |
@@ -753,19 +754,19 @@ function NavApp (props = {}) {
 | mode                | 导航类型,目前支持横向与竖直,可选值:`vertical`/                                                          | `horizontal`                                                                                                                                                        | string                  | `vertical`           |
 | openKeys            | 受控的打开的子导航 `itemKey` 数组,配合 `onOpenChange` 回调控制子导航项展开,仅 `mode = "vertical"` 且侧边栏处于展开状态时有效 | string[]                                                                                                                                                            |                         |
 | prefixCls           | 类名前缀                                                                                    | string                                                                                                                                                              | `semi`                  |
-| renderWrapper       | 自定义导航项外层组件  >=2.24.0                                                                    |  <ApiType detail='(data:{ itemElement:ReactElement, isSubNav:boolean, isInSubNav:boolean, props:SubNavProps\| ItemProps }) => ReactNode'>(data) => ReactNode</ApiType>  | |
+| renderWrapper       | 自定义导航项外层组件,v>=2.24.0                                                                    |  <ApiType detail='(data:{ itemElement:ReactElement, isSubNav:boolean, isInSubNav:boolean, props:SubNavProps\| ItemProps }) => ReactNode'>(data) => ReactNode</ApiType>  | |
 | selectedKeys        | 受控的导航项 `itemKey` 数组,配合 `onSelect` 回调控制导航项选择                                             | string[]                                                                                                                                                            |                         |
 | style               | 最外层元素的自定义样式                                                                             | CSSProperties                                                                                                                                                       |                         |
 | subNavCloseDelay    | 子导航浮层关闭的延迟。collapse 为 true 或 mode 为 "horizontal" 时有效,单位为 ms                             | number                                                                                                                                                              | 100                     |
 | subNavMotion        | 子导航折叠动画                                                                                 | boolean                                                                                                                                                             | true                    |
 | subNavOpenDelay     | 子导航浮层显示的延迟。collapse 为 true 或 mode 为 "horizontal" 时有效,单位为 ms                             | number                                                                                                                                                              | 0                       |
-| toggleIconPosition  | 带有子导航项的的父级导航项箭头位置 >=1.27.0                                                              | 'left' \                                                                                                                                                            | 'right'                 | 'right'              |
+| toggleIconPosition  | 带有子导航项的的父级导航项箭头位置 v>=1.27.0                                                              | 'left' \                                                                                                                                                            | 'right'                 | 'right'              |
 | tooltipHideDelay    | tooltip 隐藏的延迟,collapse 为 true 时有效,单位为 ms                                                | number                                                                                                                                                              | 100                     |
 | tooltipShowDelay    | tooltip 显示的延迟,collapse 为 true 时有效,单位为 ms                                                | number                                                                                                                                                              | 0                       |
 | onClick             | 点击任意导航项时触发                                                                              | <ApiType detail='({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) => void'>(itemKey, event, isOpen) => void</ApiType>                                   | () => {}                |
 | onCollapseChange    | 收起状态变化时的回调                                                                              | <ApiType detail='(isCollapsed: boolean) => void'>(isCollapsed)=> void </ApiType>                                                                                       | () => {}                |
-| onOpenChange        | 切换某个子导航项目显隐状态时触发                                                                        | <ApiType detail='({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void'> ({itemKey, openKeys, event, isOpen})=>{}</ApiType>      | () => {}                |
-| onSelect            | 第一次选中某个可选中导航项目时触发,其中 selectedItems 这个字段版本 >= 0.17.0 后才支持                                | <ApiType detail='({ itemKey: string, selectedKeys: string[], selectedItems: Item[], domEvent: MouseEvent, isOpen: boolean }) => void'>(onSelectProps)=>{}</ApiType> | () => {}                |
+| onOpenChange        | 切换某个子导航项目显隐状态时触发                                                                    | <ApiType detail='({ itemKey: string, openKeys: string[], domEvent: MouseEvent, isOpen: boolean }) => void'> ({itemKey, openKeys, event, isOpen})=>{}</ApiType>      | () => {}                |
+| onSelect            | 第一次选中某个可选中导航项目时触发                                                                   | <ApiType detail='({ itemKey: string, selectedKeys: string[], selectedItems: Item[], domEvent: MouseEvent, isOpen: boolean }) => void'>(onSelectProps)=>{}</ApiType> | () => {}                |
 
 ### Nav.Item
 
@@ -821,7 +822,7 @@ function NavApp (props = {}) {
 | collapseButton | 是否展示底部“收起侧边栏”按钮,mode="vertical" 且 Footer 组件的 children 参数为空才有效果 | boolean\|ReactNode                        | false  |          
 | collapseText   | “收起”按钮的文案                                                                         | (collapsed:boolean) => string\|ReactNode |        |
 | style          | 最外层样式                                                                               | CSSProperties                                    |        |  
-
+| onClick        | 点击事件回调                                                                             | (event) => void                              |        |  
 
 ## Accessibility
 - ### 键盘和焦点

+ 8 - 4
packages/semi-ui/navigation/Footer.tsx

@@ -5,13 +5,14 @@ import cls from 'classnames';
 import { strings, cssClasses } from '@douyinfe/semi-foundation/navigation/constants';
 import CollapseButton from './CollapseButton';
 import '@douyinfe/semi-foundation/navigation/navigation.scss';
-
+import { noop } from 'lodash';
 import NavContext, { NavContextType } from './nav-context';
 import { BaseProps } from '../_base/baseComponent';
 
 export interface NavFooterProps extends BaseProps {
     collapseButton?: React.ReactNode;
-    collapseText?: (collapsed?: boolean) => React.ReactNode
+    collapseText?: (collapsed?: boolean) => React.ReactNode;
+    onClick?: (event: React.MouseEvent) => void
 }
 
 export default class NavFooter extends PureComponent<NavFooterProps> {
@@ -23,10 +24,12 @@ export default class NavFooter extends PureComponent<NavFooterProps> {
         className: PropTypes.string,
         collapseButton: PropTypes.oneOfType([PropTypes.node, PropTypes.bool]),
         collapseText: PropTypes.func,
+        onClick: PropTypes.func,
     };
 
     static defaultProps = {
         collapseButton: false,
+        onClick: noop,
     };
 
     context: NavContextType;
@@ -54,7 +57,7 @@ export default class NavFooter extends PureComponent<NavFooterProps> {
     };
 
     render() {
-        const { style, className, collapseButton } = this.props;
+        const { style, className, collapseButton, onClick } = this.props;
         let { children } = this.props;
         const { isCollapsed, mode } = this.context;
 
@@ -67,7 +70,8 @@ export default class NavFooter extends PureComponent<NavFooterProps> {
         });
 
         return (
-            <div className={wrapCls} style={style}>
+            // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
+            <div className={wrapCls} style={style} onClick={onClick}>
                 {children}
             </div>
         );

+ 4 - 24
packages/semi-ui/navigation/SubNav.tsx

@@ -19,12 +19,6 @@ import NavContext, { NavContextType } from './nav-context';
 import { times, get } from 'lodash';
 import Collapsible from "../collapsible";
 import CSSAnimation from "../_cssAnimation";
-
-export interface ToggleIcon {
-    open?: string;
-    closed?: string
-}
-
 export interface SubNavProps extends BaseProps {
     disabled?: boolean;
     dropdownStyle?: React.CSSProperties;
@@ -38,7 +32,7 @@ export interface SubNavProps extends BaseProps {
     onMouseEnter?: React.MouseEventHandler<HTMLLIElement>;
     onMouseLeave?: React.MouseEventHandler<HTMLLIElement>;
     text?: React.ReactNode;
-    toggleIcon?: ToggleIcon
+    expandIcon?: React.ReactNode
 }
 
 export interface SubNavState {
@@ -73,16 +67,6 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
          * Nested child elements
          */
         children: PropTypes.node,
-        /**
-         * The icon name of the right control switch (on and off status)
-         */
-        toggleIcon: PropTypes.oneOfType([
-            PropTypes.any,
-            PropTypes.shape({
-                open: PropTypes.string,
-                closed: PropTypes.string,
-            }),
-        ]),
         style: PropTypes.object,
         /**
          * Icon name on the left
@@ -105,10 +89,6 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         isCollapsed: false,
         isOpen: false,
         maxHeight: numbers.DEFAULT_SUBNAV_MAX_HEIGHT,
-        toggleIcon: {
-            open: <IconChevronUp aria-hidden={true} />,
-            closed: <IconChevronDown aria-hidden={true} />,
-        },
         disabled: false,
     };
 
@@ -207,7 +187,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
     }
 
     renderTitleDiv() {
-        const { text, icon, itemKey, indent, disabled, level } = this.props;
+        const { text, icon, itemKey, indent, disabled, level, expandIcon } = this.props;
 
         const { mode, isInSubNav, isCollapsed, prefixCls, subNavMotion, limitIndent } = this.context;
 
@@ -231,7 +211,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
             if (isInSubNav) {
                 toggleIconType = <IconChevronRight aria-hidden={true} />;
             } else {
-                toggleIconType = <IconChevronDown aria-hidden={true} />;
+                toggleIconType = expandIcon ? expandIcon : <IconChevronDown aria-hidden={true} />;
                 // Horizontal mode does not require animation fix#1198
                 // withTransition = true;
             }
@@ -239,7 +219,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
             if (subNavMotion) {
                 withTransition = true;
             }
-            toggleIconType = <IconChevronDown aria-hidden={true} />;
+            toggleIconType = expandIcon ? expandIcon : <IconChevronDown aria-hidden={true} />;
         }
 
         let placeholderIcons = null;

+ 51 - 0
packages/semi-ui/navigation/_story/CustomIcon/index.jsx

@@ -0,0 +1,51 @@
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconUser, IconStar, IconSetting, IconPlus, IconTriangleUp, IconTriangleDown } from '@douyinfe/semi-icons';
+
+export default function ArrowIcon() {
+    const items = [
+        { itemKey: 'user', text: '用户管理', icon: <IconUser />, disabled: true },
+        { itemKey: 'union', text: '公会中心', icon: <IconStar /> },
+        {
+            text: '任务平台',
+            icon: <IconSetting />,
+            itemKey: 'job',
+            disabled: true,
+            items: [{ itemKey: 'job_manage', text: '任务管理', disabled: true }, '用户任务查询'],
+        },
+        {
+            text: '收藏夹',
+            icon: <IconStar />,
+            itemKey: 'star',
+            items: [{ itemKey: 'like', text: '我的喜欢', disabled: true }, '点赞'],
+        },
+    ];
+
+    return (
+        <div>
+            <Nav
+                bodyStyle={{ height: 380 }}
+                items={items}
+                defaultOpenKeys={['job', 'star']}
+                defaultSelectedKeys={['user']}
+                expandIcon={<IconTriangleDown />}
+                onSelect={data => console.log('trigger onSelect: ', data)}
+                onClick={data => console.log('trigger onClick: ', data)}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+            <Nav
+                bodyStyle={{ width: 520 }}
+                items={items}
+                mode='horizontal'
+                defaultOpenKeys={['job', 'star']}
+                defaultSelectedKeys={['user']}
+                expandIcon={<IconTriangleDown />}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        </div>
+    );
+}

+ 6 - 0
packages/semi-ui/navigation/_story/navigation.stories.jsx

@@ -12,6 +12,7 @@ import ItemsChange from './ItemsChange';
 import DisabledNav from './DisabledNav';
 import Button from '../../button';
 import GetPopupNav from './Popup';
+import CustomArrowIcon from './CustomIcon';
 
 import {
   IconMail,
@@ -334,3 +335,8 @@ export const PopupDemo = () => <GetPopupNav />;
 PopupDemo.story = {
   name: 'getPopupContainer'
 }
+
+export const CustomArrowIconDemo = () => <CustomArrowIcon></CustomArrowIcon>
+CustomArrowIconDemo.story = {
+  name: 'CustomArrowIcon'
+}

+ 12 - 2
packages/semi-ui/navigation/index.tsx

@@ -20,7 +20,7 @@ export type { CollapseButtonProps } from './CollapseButton';
 export type { NavFooterProps } from './Footer';
 export type { NavHeaderProps } from './Header';
 export type { NavItemProps } from './Item';
-export type { ToggleIcon, SubNavProps } from './SubNav';
+export type { SubNavProps } from './SubNav';
 export type Mode = 'vertical' | 'horizontal';
 
 export interface OnSelectedData {
@@ -47,6 +47,7 @@ export interface NavProps extends BaseProps {
     defaultIsCollapsed?: boolean;
     defaultOpenKeys?: React.ReactText[];
     defaultSelectedKeys?: React.ReactText[];
+    expandIcon?: React.ReactNode;
     footer?: React.ReactNode | NavFooterProps;
     header?: React.ReactNode | NavHeaderProps;
     isCollapsed?: boolean;
@@ -113,11 +114,13 @@ class Nav extends BaseComponent<NavProps, NavState> {
     static Footer = Footer;
 
     static propTypes = {
+        collapseIcon: PropTypes.node,
         // Initial expanded SubNav navigation key array
         defaultOpenKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
         openKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
         // Initial selected navigation key array
         defaultSelectedKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
+        expandIcon: PropTypes.node,
         selectedKeys: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
         // Navigation type, now supports vertical, horizontal
         mode: PropTypes.oneOf([...strings.MODE]),
@@ -261,12 +264,19 @@ class Nav extends BaseComponent<NavProps, NavState> {
      * @returns {JSX.Element}
      */
     renderItems(items: (SubNavPropsWithItems | NavItemPropsWithItems)[] = [], level = 0) {
+        const { expandIcon, collapseIcon } = this.props;
         const finalDom = (
             <>
                 {items.map((item, idx) => {
                     if (Array.isArray(item.items) && item.items.length) {
                         return (
-                            <SubNav key={item.itemKey || String(level) + idx} {...item as SubNavPropsWithItems} level={level}>
+                            <SubNav
+                                key={item.itemKey || String(level) + idx}
+                                {...item as SubNavPropsWithItems}
+                                level={level}
+                                expandIcon={expandIcon}
+                                collapseIcon={collapseIcon}
+                            >
                                 {this.renderItems(item.items as (SubNavPropsWithItems | NavItemPropsWithItems)[], level + 1)}
                             </SubNav>
                         );

+ 0 - 79
yarn.lock

@@ -1646,15 +1646,6 @@
     "@douyinfe/semi-animation-styled" "2.23.2"
     classnames "^2.2.6"
 
-"@douyinfe/[email protected]":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-react/-/semi-animation-react-2.34.2.tgz#d59f12dfe43d50c19728bef7c53a095cdf519dd5"
-  integrity sha512-Fi6RyX2yPikvbJpgbF9YtYBFjAycFNOsGG44bcEWfS1zzNzpoCEsQYfmTHQ+jcl1izXi4un7MEBmx3tM1KnPuA==
-  dependencies:
-    "@douyinfe/semi-animation" "2.12.0"
-    "@douyinfe/semi-animation-styled" "2.23.2"
-    classnames "^2.2.6"
-
 "@douyinfe/[email protected]":
   version "2.23.2"
   resolved "https://registry.npmjs.org/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.23.2.tgz"
@@ -1675,13 +1666,6 @@
   dependencies:
     bezier-easing "^2.1.0"
 
-"@douyinfe/[email protected]":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation/-/semi-animation-2.34.2.tgz#c6f4de670672a78313a6c2468fca29f47ac2a91c"
-  integrity sha512-Cvs4OJq8fM072XyiU17YbI4CLTSPmcRpzCfkKRYe3ZpI9YM7Mu2KEP7OgB2Bdgr5njgjxzsR1fjIbxQV4Zjz4Q==
-  dependencies:
-    bezier-easing "^2.1.0"
-
 "@douyinfe/[email protected]":
   version "2.33.1"
   resolved "https://registry.npmjs.org/@douyinfe/semi-foundation/-/semi-foundation-2.33.1.tgz#1dfe6233e35a4ed768cb580b0c9a677d1c34ffba"
@@ -1696,20 +1680,6 @@
     memoize-one "^5.2.1"
     scroll-into-view-if-needed "^2.2.24"
 
-"@douyinfe/[email protected]":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-foundation/-/semi-foundation-2.34.2.tgz#a8a63a6762b7c1bd0a0138047956134128c31c68"
-  integrity sha512-vOwjRKm42lt5p5sNyYzHR74QWPm7khGKLMjky/vAgI0ysF3XPUXmsm5IkyRRAurXIkuSPba4hKffIa2X7JC8Xw==
-  dependencies:
-    "@douyinfe/semi-animation" "2.12.0"
-    async-validator "^3.5.0"
-    classnames "^2.2.6"
-    date-fns "^2.29.3"
-    date-fns-tz "^1.3.8"
-    lodash "^4.17.21"
-    memoize-one "^5.2.1"
-    scroll-into-view-if-needed "^2.2.24"
-
 "@douyinfe/[email protected]", "@douyinfe/semi-icons@latest":
   version "2.33.1"
   resolved "https://registry.yarnpkg.com/@douyinfe/semi-icons/-/semi-icons-2.33.1.tgz#8e2871d9bc0ab7e12df74e3c71802d53d69b7425"
@@ -1717,23 +1687,11 @@
   dependencies:
     classnames "^2.2.6"
 
-"@douyinfe/[email protected]", "@douyinfe/semi-icons@^2.0.0":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-icons/-/semi-icons-2.34.2.tgz#ce694334a621c286d7b52923b84907d4cb3f86b3"
-  integrity sha512-XiQVr14fFxveF//0qQvh7uzmXbMraRl+7P+/zYr09x7N7DnyidmQQgSUhCiU/5IXQ/yJUA+e2/SfXcZsuui0nw==
-  dependencies:
-    classnames "^2.2.6"
-
 "@douyinfe/[email protected]":
   version "2.33.1"
   resolved "https://registry.npmjs.org/@douyinfe/semi-illustrations/-/semi-illustrations-2.33.1.tgz#530ab851f4dc32a52221c4067c778c800b9b55d7"
   integrity sha512-tTTUN8QwnQiF++sk4VBNzfkG87aYZ4iUeqk2ys8/ymVUmCZQ7y46ys020GO1MfPHRR47OMFPI82FVcH1WQtE3g==
 
-"@douyinfe/[email protected]":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-illustrations/-/semi-illustrations-2.34.2.tgz#6e5fdb875a7dbd54b49036ba9154d2594feedbb1"
-  integrity sha512-NO5A9catlhxLakhUYlm0izc4VD93BHRWTl9SaUJIHVghnm3sRZPnLWI2YLGQbJVyTpA2F78cGu3qEjw3ObRrmQ==
-
 "@douyinfe/[email protected]":
   version "2.23.2"
   resolved "https://registry.npmjs.org/@douyinfe/semi-scss-compile/-/semi-scss-compile-2.23.2.tgz#30884bb194ee9ae1e81877985e5663c3297c1ced"
@@ -1807,38 +1765,6 @@
   dependencies:
     glob "^7.1.6"
 
-"@douyinfe/[email protected]":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-theme-default/-/semi-theme-default-2.34.2.tgz#7ec1005e03de6e4d1dd399d24a2a427824c460e7"
-  integrity sha512-954ytIhtIZrttVSDhxAk27vLaioSh0ikugl2ml37mhngbU7Dz+zDv+hFd8Y6SLpSNzRYQm63WgvkHgykPrIodQ==
-  dependencies:
-    glob "^7.1.6"
-
-"@douyinfe/semi-ui@^2.0.0":
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui/-/semi-ui-2.34.2.tgz#d5a07e3e3d9aa0ee8a5bbd3b73f41319386f27c5"
-  integrity sha512-kuco5bZhckUuWWV4myDMcza52PtimJ8RJobwl0rvxa2k2z5kF/tNT7DjH1NBtyKLMkKDNaCaAMaOTSohQ89XuQ==
-  dependencies:
-    "@douyinfe/semi-animation" "2.34.2"
-    "@douyinfe/semi-animation-react" "2.34.2"
-    "@douyinfe/semi-foundation" "2.34.2"
-    "@douyinfe/semi-icons" "2.34.2"
-    "@douyinfe/semi-illustrations" "2.34.2"
-    "@douyinfe/semi-theme-default" "2.34.2"
-    async-validator "^3.5.0"
-    classnames "^2.2.6"
-    copy-text-to-clipboard "^2.1.1"
-    date-fns "^2.29.3"
-    date-fns-tz "^1.3.8"
-    lodash "^4.17.21"
-    prop-types "^15.7.2"
-    react-resizable "^1.8.0"
-    react-sortable-hoc "^2.0.0"
-    react-window "^1.8.2"
-    resize-observer-polyfill "^1.5.1"
-    scroll-into-view-if-needed "^2.2.24"
-    utility-types "^3.10.0"
-
 "@douyinfe/semi-ui@latest":
   version "2.33.1"
   resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui/-/semi-ui-2.33.1.tgz#3234ca96eb3560b8299bc9750fbe59446522d9bb"
@@ -11228,11 +11154,6 @@ eslint-plugin-react@^7.20.6, eslint-plugin-react@^7.24.0:
     semver "^6.3.0"
     string.prototype.matchall "^4.0.6"
 
-eslint-plugin-semi-design@^2.33.0:
-  version "2.34.2"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-semi-design/-/eslint-plugin-semi-design-2.34.2.tgz#af2fdb2dad0bb04faf26eed00ae0c911f04949f1"
-  integrity sha512-6hDrYmjTMElEKRwQT829bUkH9A7Kb6ln0BR6jEO3i+6DvHwGBQJLKP1pSRGZBXzsW+Yqz15nnQZLFcNUPN7Iaw==
-
 eslint-rule-composer@^0.3.0:
   version "0.3.0"
   resolved "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz"