Prechádzať zdrojové kódy

fix: navigation number itemkey can't expand , close #2316

* fix: fixed expansion of itemKey of type number
* chore: update Nav ItemKey type define
* docs: remove uesless version text
* fix: use include to judge isOpen, handle numebr & string in same logic
---------

Co-authored-by: pointhalo <[email protected]>
changlin0_0 1 rok pred
rodič
commit
ef8a3a5a97

+ 1 - 0
.storybook/base/base.js

@@ -86,6 +86,7 @@ module.exports = {
         config.resolve.alias = {
             '@douyinfe/semi-foundation': resolve('packages/semi-foundation'),
             '@douyinfe/semi-icons': resolve('packages/semi-icons/src'),
+            '@douyinfe/semi-icons-lab': resolve('packages/semi-icons-lab/src'),
             '@douyinfe/semi-ui': resolve('packages/semi-ui'),
             '@douyinfe/semi-theme-default': resolve('packages/semi-theme-default'),
             '@douyinfe/semi-illustrations': resolve('packages/semi-illustrations/src'),

+ 14 - 14
content/navigation/navigation/index-en-US.md

@@ -760,16 +760,16 @@ function NavApp (props = {}) {
 
 ### Nav.Item
 
-| Properties   | Description                                                                                                       | Type                                                                 | Default  | Version |
+| Properties   | Description                                                                                                       | Type                                                                 | Default  |
 | ------------ | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------- | ------- |
-| disabled     | Disabled state                                                                                                    | boolean                                                              | false    | 1.17.0  |
-| icon         | Navigation project icon name or component                                                                         | ReactNode                                                            |          |         |
-| indent       | If the icon is empty, keep its space or not. Only effective for first level navigation                            | boolean                                                              | false    |         |
-| itemKey      | Navigation project only key                                                                                       | string                                                               | ""       |         |
-| level        | The nesting level of the current item. When limitIndent is true, it is used to customize the indentation position | number                                                               |          | 1.27.0  |
-| link         | Navigation item href link, when imported, the navigation item will be wrapped with an a tag                       | string                                                               | -        | 1.0.0   |
-| linkOptions  | Parameters transparently passed to the a tag                                                                      | object                                                               | -        | 1.0.0   |
-| text         | Navigation project copy or element                                                                                | string \| ReactNode                                                  | ""       |         |
+| disabled     | Disabled state                                                                                                    | boolean                                                              | false    |
+| icon         | Navigation project icon name or component                                                                         | ReactNode                                                            |          | 
+| indent       | If the icon is empty, keep its space or not. Only effective for first level navigation                            | boolean                                                              | false    |
+| itemKey      | Unique item identifier, no duplication allowed                                                                    | string                                                               | ""       |
+| level        | The nesting level of the current item. When limitIndent is true, it is used to customize the indentation position | number                                                               |          |
+| link         | Navigation item href link, when imported, the navigation item will be wrapped with an a tag                       | string                                                               | -        |
+| linkOptions  | Parameters transparently passed to the a tag                                                                      | object                                                               | -        |
+| text         | Navigation project copy or element                                                                                | string \| ReactNode                                                  | ""       |
 | onClick      | Callback of click                                                                                                 | function({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) | () => {} |
 | onMouseEnter | Callback of mouse enter event                                                                                     | function(e) => {}                                                    | () => {} |
 | onMouseLeave | Callback of mouse leave event                                                                                     | function(e) => {}                                                    | () => {} |
@@ -778,14 +778,14 @@ function NavApp (props = {}) {
 
 | Properties    | Description                                                                                                       | Type                | Default  |
 | ------------- | ----------------------------------------------------------------------------------------------------------------- | ------------------- | -------- |
-| disabled      | Disabled state                                                                                                    | boolean             | false    | 1.17.0 |
-| dropdownStyle | Style of dropdown layer                                                                                           | CSSProperties       |          |        |
+| disabled      | Disabled state                                                                                                    | boolean             | false    |
+| dropdownStyle | Style of dropdown layer                                                                                           | CSSProperties       |          |
 | icon          | Navigation project icon name or component                                                                         | ReactNode           |          |
 | indent        | If the icon is empty, keep its space or not. Only effective for first level navigation                            | boolean             | false    |
 | isCollapsed   | Whether it is a controlled attribute in the collapsed state, only `mode = "vertical"`                             | boolean             | false    |
 | isOpen        | Control open state                                                                                                | boolean             | false    |
 | itemKey       | Navigation project only key                                                                                       | string              | ""       |
-| level         | The nesting level of the current item. When limitIndent is true, it is used to customize the indentation position | number              | 1.27.0   |
+| level         | The nesting level of the current item. When limitIndent is true, it is used to customize the indentation position | number              |          |
 | maxHeight     | max height                                                                                                        | number              | 999      |
 | text          | Navigation project copy or component                                                                              | string \| ReactNode | ""       |
 | onMouseEnter  | Callback of mouse enter event                                                                                     | function(e) => {}   | () => {} |
@@ -797,8 +797,8 @@ function NavApp (props = {}) {
 | ----------- | ------------------------------------------------------------------------------------------- | ------------------- | ------- | ------- |
 | children    | Sub element                                                                                 | ReactNode           |         |         |
 | className   | Outermost style name                                                                        | string              |         |         |
-| link        | Navigation item href link, when imported, the navigation item will be wrapped with an a tag | string              | -       | 1.0.0   |
-| linkOptions | Parameters transparently passed to the a tag                                                | object              | -       | 1.0.0   |
+| link        | Navigation item href link, when imported, the navigation item will be wrapped with an a tag | string              | -       |         |
+| linkOptions | Parameters transparently passed to the a tag                                                | object              | -       |         |
 | logo        | Logo, can be a string or component                                                          | string \| ReactNode |         |         |
 | style       | Outermost style                                                                             | object              |         |         |
 | text        | Logo copy, which can be a string or component                                               | string \| ReactNode |         |         |

+ 76 - 76
content/navigation/navigation/index.md

@@ -673,92 +673,92 @@ function NavApp (props = {}) {
 
 ### Nav
 
-| 属性                  | 描述                                                                                      | 类型                                                                                                                                                                  | 默认值                     |
-|---------------------|-----------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|
-| bodyStyle           | 导航项列表的自定义样式                                                                             | CSSProperties                                                                                                                                                       |                         |
-| className           | 最外层元素的样式名                                                                               | string                                                                                                                                                              |                         |
-| 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 配置,可指定弹出层容器 这会改变浮层 DOM 树位置,但不会改变视图渲染位置。 , 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)[] |  |
-| limitIndent         | 解除缩进限制,可使用 level 自定义导航项缩进,水平模式只能为true >=1.27.0                                          | boolean                                                                                                                                                             | true                    |
-| mode                | 导航类型,目前支持横向与竖直,可选值:`vertical`/                                                          | `horizontal`                                                                                                                                                        | string                  | `vertical`           |
-| openKeys            | 受控的打开的子导航 `itemKey` 数组,配合 `onOpenChange` 回调控制子导航项展开,仅 `mode = "vertical"` 且侧边栏处于展开状态时有效 | string[]                                                                                                                                                            |                         |
-| prefixCls           | 类名前缀                                                                                    | string                                                                                                                                                              | `semi`                  |
-| 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  | 带有子导航项的的父级导航项箭头位置 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            | 第一次选中某个可选中导航项目时触发                                                                       | <ApiType detail='({ itemKey: string, selectedKeys: string[], selectedItems: Item[], domEvent: MouseEvent, isOpen: boolean }) => void'>(onSelectProps)=>{}</ApiType> | () => {}                |
+| 属性                | 描述                                                                                                                                          | 类型                                                                                                                                                                  | 默认值     |
+| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| bodyStyle           | 导航项列表的自定义样式                                                                                                                        | CSSProperties                                                                                                                                                         |            |
+| className           | 最外层元素的样式名                                                                                                                            | string                                                                                                                                                                |            |
+| 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 配置,可指定弹出层容器 这会改变浮层 DOM 树位置,但不会改变视图渲染位置。 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)[]                                                                                                          |            |
+| limitIndent         | 解除缩进限制,可使用 level 自定义导航项缩进,水平模式只能为true                                                                  | boolean                                                                                                                                                               | true       |
+| mode                | 导航类型,目前支持横向与竖直,可选值:`vertical`或`horizontal`                                                                                | string                                                                                                                                                                | `vertical` |
+| openKeys            | 受控的打开的子导航 `itemKey` 数组,配合 `onOpenChange` 回调控制子导航项展开,仅 `mode = "vertical"` 且侧边栏处于展开状态时有效                | string[]                                                                                                                                                              |            |
+| prefixCls           | 类名前缀                                                                                                                                      | string                                                                                                                                                                | `semi`     |
+| 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  | 带有子导航项的的父级导航项箭头位置,可选 `left`或 `right`                                                                                  | string    | '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            | 第一次选中某个可选中导航项目时触发                                                                                                            | <ApiType detail='({ itemKey: string, selectedKeys: string[], selectedItems: Item[], domEvent: MouseEvent, isOpen: boolean }) => void'>(onSelectProps)=>{}</ApiType>   | () => {}   |
 
 ### Nav.Item
 
-| 属性        | 描述                                               | 类型              | 默认值 | 版本          |
-|-------------|--------------------------------------------------|-------------------|--------|---------------|
-| disabled    | 是否禁用                                           | boolean | false     | 1.17.0              |
-| icon        | 导航项目图标                             | ReactNode |      |               |
-| indent      | 如果 icon 为空,是否保留其占位,仅对一级导航生效       | boolean           | false  |               |
-| itemKey     | 导航项目唯一 key                                   | string            | ""     |               |
-| level       | 当前项所在嵌套层级,limitIndent 为 true时,用于自定义缩进位置| number | | 1.27.0 | 
-| link        | 导航项 href 链接,传入时导航项整体会包裹一个 a 标签 | string            | -      | 1.0.0 |
-| linkOptions | 透传给 a 标签的参数                                | object            | -      | 1.0.0 |
-| text        | 导航项目文案或元素                                 | string\|ReactNode | ""     |               |
-| onClick     | 点击任意导航项时触发 |function({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) |  () => {}   | 
-| onMouseEnter| mouse enter 时触发 |function(e) => {} | () => {}   | 
-| onMouseLeave| mouse leave 时触发 |function(e) => {} | () => {}   | 
+| 属性         | 描述                                                          | 类型                                                                 | 默认值   |
+| ------------ | ------------------------------------------------------------- | -------------------------------------------------------------------- | -------- |
+| disabled     | 是否禁用                                                      | boolean                                                              | false    |
+| icon         | 导航项目图标                                                  | ReactNode                                                            |          |
+| indent       | 如果 icon 为空,是否保留其占位,仅对一级导航生效              | boolean                                                              | false    |
+| itemKey      | 导航项目唯一 key                                              | string                                                               | ""       |
+| level        | 当前项所在嵌套层级,limitIndent 为 true时,用于自定义缩进位置 | number                                                               |          |
+| link         | 导航项 href 链接,传入时导航项整体会包裹一个 a 标签           | string                                                               | -        |
+| linkOptions  | 透传给 a 标签的参数                                           | object                                                               | -        |
+| text         | 导航项目文案或元素                                            | string\|ReactNode                                                    | ""       |
+| onClick      | 点击任意导航项时触发                                          | <ApiType detail='({ itemKey: string, domEvent: MouseEvent, isOpen: boolean }) => void'>({itemKey, domEvent, isOpen}) => void</ApiType> | () => {} |
+| onMouseEnter | mouse enter 时触发                                            | function(e) => {}                                                    | () => {} |
+| onMouseLeave | mouse leave 时触发                                            | function(e) => {}                                                    | () => {} |
 
 ### Nav.Sub
 
-| 属性    | 描述                           | 类型              | 默认值 |
-| ------- | ------------------------------ | ----------------- | ------ |
-| disabled    | 是否禁用                                           | boolean | false     | 1.17.0             |
-| dropdownStyle | 弹出层的 style                                           | CSSProperties |     |              |
-| icon    | 导航项目图标       | ReactNode |      |
-| indent  | 如果 icon 为空,是否保留其占位,仅对一级导航生效 | boolean           | false  |
-| isCollapsed         |  是否处于收起状态的受控属性,仅 `mode = "vertical"`      | boolean  |    false        |
-| isOpen         |  是否打开      | boolean  |    false        |
-| itemKey | 导航项目唯一 key               | string            | ""     |
-| level       | 当前项所在嵌套层级,limitIndent 为 true时,用于自定义缩进位置| number | 0 | 1.27.0 |
-| maxHeight       | 最大高度 | number | 999 |
-| text    | 导航项目文案或组件             | string\|ReactNode | ""     |
-| onMouseEnter| mouse enter 时触发 |function(e) => {} | () => {}   | 
-| onMouseLeave| mouse leave 时触发 |function(e) => {} | () => {}   | 
+| 属性          | 描述                                                          | 类型              | 默认值   |
+| ------------- | ------------------------------------------------------------- | ----------------- | -------- |
+| disabled      | 是否禁用                                                      | boolean           | false    |  |
+| dropdownStyle | 弹出层的 style                                                | CSSProperties     |          |  |
+| icon          | 导航项目图标                                                  | ReactNode         |          |
+| indent        | 如果 icon 为空,是否保留其占位,仅对一级导航生效              | boolean           | false    |
+| isCollapsed   | 是否处于收起状态的受控属性,仅 `mode = "vertical"`            | boolean           | false    |
+| isOpen        | 是否打开                                                      | boolean           | false    |
+| itemKey       | 导航项目唯一 key                                              | string            | -        |
+| level         | 当前项所在嵌套层级,limitIndent 为 true时,用于自定义缩进位置 | number            | 0        |  |
+| maxHeight     | 最大高度                                                      | number            | 999      |
+| text          | 导航项目文案或组件                                            | string\|ReactNode | ""       |
+| onMouseEnter  | mouse enter 时触发                                            | function(e) => {} | () => {} |
+| onMouseLeave  | mouse leave 时触发                                            | function(e) => {} | () => {} |
 
 ### Nav.Header
 
-| 属性        | 描述                                               | 类型              | 默认值 | 版本          |
-|-------------|--------------------------------------------------|-------------------|--------|---------------|
-| children    | 子元素                                             | ReactNode         |        |               |
-| className   | 最外层样式名                                       | string            |        |               |
-| link        | 导航项 href 链接,传入时导航项整体会包裹一个 a 标签 | string            | -      | 1.0.0 |
-| linkOptions | 透传给 a 标签的参数                                | object            | -      | 1.0.0 |
-| logo        | Logo                         | ReactNode |        |               |
-| style       | 最外层样式                                         | CSSProperties            |        |               |
-| text        | Logo 文案                       | ReactNode |        |               |
+| 属性        | 描述                                                | 类型          | 默认值 |
+| ----------- | --------------------------------------------------- | ------------- | ------ |
+| children    | 子元素                                              | ReactNode     |        |
+| className   | 最外层样式名                                        | string        |        |
+| link        | 导航项 href 链接,传入时导航项整体会包裹一个 a 标签 | string        | -      |
+| linkOptions | 透传给 a 标签的参数                                 | object        | -      |
+| logo        | Logo                                                | ReactNode     |        |
+| style       | 最外层样式                                          | CSSProperties |        |
+| text        | Logo 文案                                           | ReactNode     |        |
 
 ### Nav.Footer
 
-| 属性           | 描述                                                                                     | 类型                                      | 默认值 |
-| -------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------- | ------ |
-| children       | 子元素                                                                                   | ReactNode                                 |        |         
-| className      | 最外层样式名                                                                             | string                                    |        |      
-| collapseButton | 是否展示底部“收起侧边栏”按钮,mode="vertical" 且 Footer 组件的 children 参数为空才有效果 | boolean\|ReactNode                        | false  |          
-| collapseText   | “收起”按钮的文案                                                                         | (collapsed:boolean) => string\|ReactNode |        |
-| style          | 最外层样式                                                                               | CSSProperties                                    |        |  
-| onClick        | 点击事件回调                                                                             | (event) => void                              |        |  
+| 属性           | 描述                                                                                     | 类型                             | 默认值 |
+| -------------- | ---------------------------------------------------------------------------------------- | -------------------------------- | ------ |
+| children       | 子元素                                                                                   | ReactNode                        |        |
+| className      | 最外层样式名                                                                             | string                           |        |
+| collapseButton | 是否展示底部“收起侧边栏”按钮,mode="vertical" 且 Footer 组件的 children 参数为空才有效果 | boolean\|ReactNode               | false  |
+| collapseText   | “收起”按钮的文案                                                                         | (collapsed:boolean) => ReactNode |        |
+| style          | 最外层样式                                                                               | CSSProperties                    |        |
+| onClick        | 点击事件回调                                                                             | (event) => void                  |        |
 
 ## Accessibility
 - ### 键盘和焦点
@@ -773,8 +773,8 @@ function NavApp (props = {}) {
 - 导航栏菜单使用句子大小写格式
 - 尽量精简
 
-| ✅ 推荐用法 | ❌ 不推荐用法 |   
-| --- | --- | 
+| ✅ 推荐用法    | ❌ 不推荐用法  |
+| ------------- | ------------- |
 | Appeal center | Appeal Center |
 
 

+ 8 - 8
packages/semi-foundation/navigation/foundation.ts

@@ -1,6 +1,6 @@
 import BaseFoundation, { DefaultAdapter } from '../base/foundation';
 import NavItem from './NavItem';
-import { ItemProps } from './itemFoundation';
+import { ItemProps, ItemKey } from './itemFoundation';
 import { strings } from './constants';
 import { get } from 'lodash';
 import isNullOrUndefined from '../utils/isNullOrUndefined';
@@ -10,18 +10,18 @@ export interface ItemKey2ParentKeysMap {
 }
 
 export interface OnClickData {
-    itemKey: string | number;
+    itemKey: ItemKey;
     domEvent: any;
     isOpen: boolean
 }
 
 export interface OnSelectData extends OnClickData {
-    selectedKeys: (string | number)[];
+    selectedKeys: ItemKey[];
     selectedItems: ItemProps[]
 }
 
 export interface OnOpenChangeData extends OnClickData {
-    openKeys: (string | number)[]
+    openKeys: ItemKey[]
 }
 
 export interface NavItemType {
@@ -52,7 +52,7 @@ export default class NavigationFoundation<P = Record<string, any>, S = Record<st
     }
 
     /* istanbul ignore next */
-    static getZeroParentKeys(itemKeysMap = {}, ...itemKeys: (string | number)[]) {
+    static getZeroParentKeys(itemKeysMap = {}, ...itemKeys: ItemKey[]) {
         const willAddKeys = [];
         if (itemKeys.length) {
             for (const itemKey of itemKeys) {
@@ -182,7 +182,7 @@ export default class NavigationFoundation<P = Record<string, any>, S = Record<st
         return [...willOpenKeys];
     }
 
-    getShouldOpenKeys(itemKeysMap: ItemKey2ParentKeysMap = {}, selectedKeys: (string | number)[] = []) {
+    getShouldOpenKeys(itemKeysMap: ItemKey2ParentKeysMap = {}, selectedKeys: ItemKey[] = []) {
         const willOpenKeySet = new Set();
 
         if (Array.isArray(selectedKeys) && selectedKeys.length) {
@@ -202,7 +202,7 @@ export default class NavigationFoundation<P = Record<string, any>, S = Record<st
 
     destroy() {}
 
-    selectLevelZeroParentKeys(itemKeysMap: ItemKey2ParentKeysMap, itemKeys: (string | number)[]) {
+    selectLevelZeroParentKeys(itemKeysMap: ItemKey2ParentKeysMap, itemKeys: ItemKey[]) {
         const _itemKeysMap = isNullOrUndefined(itemKeysMap) ? this.getState('itemKeysMap') : itemKeysMap;
         // console.log(itemKeysMap);
 
@@ -236,7 +236,7 @@ export default class NavigationFoundation<P = Record<string, any>, S = Record<st
     }
 
     /* istanbul ignore next */
-    judgeIfOpen(openKeys: (string | number)[], items: NavItemType[]): boolean {
+    judgeIfOpen(openKeys: ItemKey[], items: NavItemType[]): boolean {
         let shouldBeOpen = false;
 
         const _openKeys = Array.isArray(openKeys) ? openKeys : openKeys && [openKeys];

+ 6 - 4
packages/semi-foundation/navigation/itemFoundation.ts

@@ -17,10 +17,12 @@ export interface ItemProps {
     children?: any
 }
 
+export type ItemKey = string | number;
+
 export interface SelectedItemProps<Props = ItemProps> {
-    itemKey: string | number;
+    itemKey: ItemKey;
     text?: any;
-    selectedKeys?: string | number[];
+    selectedKeys?: ItemKey[];
     selectedItems?: Props[];
     domEvent?: any
 }
@@ -29,8 +31,8 @@ export interface ItemAdapter<P = Record<string, any>, S = Record<string, any>> e
     cloneDeep(value: any, customizer?: (value: any) => void): any;
     updateTooltipShow(showTooltip: boolean): void;
     updateSelected(selected: boolean): void;
-    updateGlobalSelectedKeys(keys: string[]): void;
-    getSelectedKeys(): string[];
+    updateGlobalSelectedKeys(keys: ItemKey[]): void;
+    getSelectedKeys(): ItemKey[];
     getSelectedKeysIsControlled(): boolean;
     notifyGlobalOnSelect(item: SelectedItemProps): void;
     notifyGlobalOnClick(item: SelectedItemProps): void;

+ 6 - 5
packages/semi-ui/navigation/Item.tsx

@@ -9,6 +9,7 @@ import { cloneDeep, isSemiIcon } from '../_utils';
 import ItemFoundation, {
     ItemAdapter,
     ItemProps,
+    ItemKey,
     SelectedItemProps
 } from '@douyinfe/semi-foundation/navigation/itemFoundation';
 import { cssClasses, strings } from '@douyinfe/semi-foundation/navigation/constants';
@@ -18,13 +19,12 @@ import NavContext, { NavContextType } from './nav-context';
 import Dropdown from '../dropdown';
 
 const clsPrefix = `${cssClasses.PREFIX}-item`;
-
-export interface NavItemProps extends ItemProps, BaseProps {
+interface NavItemProps extends ItemProps, BaseProps {
     children?: React.ReactNode;
     disabled?: boolean;
     forwardRef?: (ele: HTMLLIElement) => void;
     icon?: React.ReactNode;
-    itemKey?: React.ReactText;
+    itemKey?: ItemKey;
     level?: number;
     link?: string;
     linkOptions?: React.AnchorHTMLAttributes<HTMLAnchorElement>;
@@ -39,14 +39,15 @@ export interface NavItemProps extends ItemProps, BaseProps {
     onMouseLeave?: React.MouseEventHandler<HTMLLIElement>
 }
 
-export interface SelectedData extends SelectedItemProps<NavItemProps> {
+interface SelectedData extends SelectedItemProps<NavItemProps> {
     text?: React.ReactNode
 }
 
-export interface NavItemState {
+interface NavItemState {
     tooltipShow: boolean
 }
 
+export type { NavItemProps, ItemKey, NavItemState, SelectedData };
 export default class NavItem extends BaseComponent<NavItemProps, NavItemState> {
     static contextType = NavContext;
 

+ 8 - 6
packages/semi-ui/navigation/SubNav.tsx

@@ -14,7 +14,7 @@ import NavItem from './Item';
 import Dropdown, { DropdownProps } from '../dropdown';
 import NavContext, { NavContextType } from './nav-context';
 
-import { times, get } from 'lodash';
+import { times, get, isNumber, isString } from 'lodash';
 import Collapsible from "../collapsible";
 import CSSAnimation from "../_cssAnimation";
 export interface SubNavProps extends BaseProps {
@@ -141,8 +141,10 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
             notifyGlobalOnSelect: (...args) => this._invokeContextFunc('onSelect', ...args),
             notifyGlobalOnClick: (...args) => this._invokeContextFunc('onClick', ...args),
             getIsSelected: itemKey => Boolean(!isNullOrUndefined(itemKey) && get(this.context, 'selectedKeys', []).includes(String(itemKey))),
-            getIsOpen: () =>
-                Boolean(this.context && this.context.openKeys && this.context.openKeys.includes(String(this.props.itemKey))),
+            getIsOpen: () => {
+                const { itemKey } = this.props;
+                return Boolean(this.context && this.context.openKeys && this.context.openKeys.includes(this.props.itemKey));
+            }
         };
     }
 
@@ -172,8 +174,8 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
         const isOpen = this.adapter.getIsOpen();
 
         const iconElem = React.isValidElement(icon) ? (withTransition ? (
-            <CSSAnimation animationState={isOpen?"enter":"leave"} startClassName={`${cssClasses.PREFIX}-icon-rotate-${isOpen?"180":"0"}`}>
-                {({ animationClassName })=>{
+            <CSSAnimation animationState={isOpen ? "enter" : "leave"} startClassName={`${cssClasses.PREFIX}-icon-rotate-${isOpen ? "180" : "0"}`}>
+                {({ animationClassName }) => {
                     // @ts-ignore
                     return React.cloneElement(icon, { size: iconSize, className: animationClassName });
                 }}
@@ -275,7 +277,7 @@ export default class SubNav extends BaseComponent<SubNavProps, SubNavState> {
                     className={subNavCls}
                 >
                     {children}
-                </ul>: null
+                </ul> : null
             }
         </Collapsible>;
 

+ 40 - 0
packages/semi-ui/navigation/__test__/navigation.test.js

@@ -271,4 +271,44 @@ describe(`Navigation`, () => {
         expect(onCollapseChange.called).toBeTruthy();
         expect(onCollapseChange.getCall(0).args[0]).toEqual(true);
     });
+
+    it(`test itemKey is a number type expansion`, async () => {
+        const onSelect = sinon.spy(noop);
+        const onOpenChange = sinon.spy(noop);
+        const onCollapseChange = sinon.spy(noop);
+        const onClick = sinon.spy(noop);
+
+        const nav = mount(
+            <Nav
+                bodyStyle={{ height: 320 }}
+                items={[
+                    { itemKey: 'user', text: '用户管理', icon: 'user' },
+                    { itemKey: 'union', text: '公会中心', icon: 'star' },
+                    {
+                        text: '任务平台',
+                        icon: 'setting',
+                        itemKey: 2,
+                        items: ['任务管理', '用户任务查询'],
+                    },
+                ]}
+                onSelect={onSelect}
+                onOpenChange={onOpenChange}
+                onCollapseChange={onCollapseChange}
+                onClick={onClick}
+                footer={{
+                    collapseButton: true,
+                }}
+            />
+        );
+
+        const subTitle = nav.find(`.${BASE_CLASS_PREFIX}-navigation-sub-title`);
+        subTitle.simulate('click');
+        expect(onClick.called).toBeTruthy();
+        expect(onOpenChange.called).toBeTruthy();
+        expect(onClick.getCall(0).args[0].itemKey).toEqual(2);
+        expect(onOpenChange.getCall(0).args[0].itemKey).toEqual(2);
+        expect(
+            document.querySelectorAll(`.${BASE_CLASS_PREFIX}-navigation-item-sub .${BASE_CLASS_PREFIX}-navigation-sub-open`).length > 0
+        ).toBeTruthy();
+    });
 });

+ 28 - 0
packages/semi-ui/navigation/_story/NumberItemKey/index.jsx

@@ -0,0 +1,28 @@
+import React from 'react';
+import { Nav } from '@douyinfe/semi-ui';
+import { IconSemiLogo } from '@douyinfe/semi-icons';
+import { IconDescriptions, IconIntro, IconTree, IconAvatar, IconTreeSelect, IconTabs } from '@douyinfe/semi-icons-lab';
+
+export default function NumberItemKey() {
+    const [openKeys, setOpenKeys] = useState([]);
+    return (
+        <Nav
+            bodyStyle={{ height: 320 }}
+            openKeys={openKeys}
+            onOpenChange={props => setOpenKeys(props.openKeys)}
+            items={[
+                { itemKey: 1, text: '用户管理', icon: <IconAvatar /> },
+                { itemKey: 2, text: '活动管理', icon: <IconDescriptions /> },
+                {
+                    text: '任务平台',
+                    icon: <IconTree />,
+                    itemKey: 3,
+                    items: ['任务管理', '用户任务查询'],
+                },
+            ]}
+            onSelect={data => console.log('trigger onSelect: ', data)}
+            onClick={data => console.log('trigger onClick: ', data)}
+        />
+    );
+};
+

+ 3 - 1
packages/semi-ui/navigation/_story/navigation.stories.jsx

@@ -15,6 +15,7 @@ import GetPopupNav from './Popup';
 import CustomArrowIcon from './CustomIcon';
 import FixedSelectedKeys from './FixedSelectedKeys';
 import FixedOpenKeys from './FixedOpenKeys';
+import NumberItemKey from './NumberItemKey';
 
 import {
   IconMail,
@@ -41,7 +42,8 @@ export default {
 
 export {
   FixedSelectedKeys,
-  FixedOpenKeys
+  FixedOpenKeys,
+  NumberItemKey
 }
 
 export const Default = () => {

+ 8 - 9
packages/semi-ui/navigation/index.tsx

@@ -8,7 +8,7 @@ import NavigationFoundation, { NavigationAdapter } from '@douyinfe/semi-foundati
 import { strings, cssClasses, numbers } from '@douyinfe/semi-foundation/navigation/constants';
 
 import SubNav, { SubNavProps } from './SubNav';
-import Item, { NavItemProps } from './Item';
+import Item, { NavItemProps, ItemKey } from './Item';
 import Footer, { NavFooterProps } from './Footer';
 import Header, { NavHeaderProps } from './Header';
 import NavContext from './nav-context';
@@ -19,18 +19,17 @@ import { getDefaultPropsFromGlobalConfig } from "../_utils";
 export type { CollapseButtonProps } from './CollapseButton';
 export type { NavFooterProps } from './Footer';
 export type { NavHeaderProps } from './Header';
-export type { NavItemProps } from './Item';
+export type { NavItemProps, ItemKey } from './Item';
 export type { SubNavProps } from './SubNav';
 export type Mode = 'vertical' | 'horizontal';
 
 export interface OnSelectedData {
-    itemKey: React.ReactText;
+    itemKey: ItemKey;
     selectedKeys: React.ReactText[];
     selectedItems: (NavItemProps | SubNavProps)[];
     domEvent: React.MouseEvent;
     isOpen: boolean
 }
-
 export interface SubNavPropsWithItems extends SubNavProps {
     items?: (SubNavPropsWithItems | string)[]
 }
@@ -66,10 +65,10 @@ export interface NavProps extends BaseProps {
     tooltipHideDelay?: number;
     tooltipShowDelay?: number;
     getPopupContainer?: () => HTMLElement;
-    onClick?: (data: { itemKey?: React.ReactText; domEvent?: MouseEvent; isOpen?: boolean }) => void;
+    onClick?: (data: { itemKey?: ItemKey; domEvent?: MouseEvent; isOpen?: boolean }) => void;
     onCollapseChange?: (isCollapse: boolean) => void;
     onDeselect?: (data?: any) => void;
-    onOpenChange?: (data: { itemKey?: (string | number); openKeys?: (string | number)[]; domEvent?: MouseEvent; isOpen?: boolean }) => void;
+    onOpenChange?: (data: { itemKey?: ItemKey; openKeys?: ItemKey[]; domEvent?: MouseEvent; isOpen?: boolean }) => void;
     onSelect?: (data: OnSelectedData) => void;
     renderWrapper?: ({ itemElement, isSubNav, isInSubNav, props }: { itemElement: ReactElement;isInSubNav: boolean; isSubNav: boolean; props: NavItemProps | SubNavProps }) => ReactNode
 }
@@ -77,10 +76,10 @@ export interface NavProps extends BaseProps {
 export interface NavState {
     isCollapsed: boolean;
     // calc state
-    openKeys: (string | number)[];
+    openKeys: ItemKey[];
     items: any[];
-    itemKeysMap: { [itemKey: string]: (string | number)[] };
-    selectedKeys: (string | number)[]
+    itemKeysMap: { [itemKey: string]: ItemKey[] };
+    selectedKeys: ItemKey[]
 }
 
 function createAddKeysFn(context: Nav, keyName: string | number) {

+ 3 - 3
packages/semi-ui/navigation/nav-context.ts

@@ -1,16 +1,16 @@
 import React from 'react';
 
-import type { NavProps } from './index';
+import type { NavProps, ItemKey } from './index';
 import { Locale } from '../locale/interface';
  
 import type { DropdownProps } from '../dropdown';
 export interface NavContextType {
     isCollapsed?: boolean;
     mode?: NavProps['mode'];
-    openKeys?: string[];
+    openKeys?: ItemKey[];
     onCollapseChange?: NavProps['onCollapseChange'];
     prefixCls?: string;
-    selectedKeys?: string[];
+    selectedKeys?: ItemKey[];
     toggleIconPosition?: string;
     selectedKeysIsControlled?: boolean;
     openKeysIsControlled?: boolean;