未验证 提交 7bed2230 编写于 作者: M mangov587 提交者: GitHub

feat: add SideNavBar (#198)

上级 c995270a
......@@ -257,6 +257,38 @@
"sort": 16,
"show": true,
"author": "liukun"
},
{
"version": "1.0.0",
"name": "SideNavBar",
"type": "component",
"cName": "侧边栏导航",
"desc": "用于内容选择和切换",
"sort": 9,
"show": true,
"author": "hx"
},
{
"version": "1.0.0",
"name": "SubSideNavBar",
"type": "component",
"cName": "侧边栏导航子组件",
"desc": "用于侧边栏导航的子组件",
"exportEmpty": true,
"sort": 10,
"show": false,
"author": "hx"
},
{
"version": "1.0.0",
"name": "SideNavBarItem",
"type": "component",
"cName": "侧边栏导航子组件",
"exportEmpty": true,
"desc": "用于侧边栏导航子组件",
"sort": 11,
"show": false,
"author": "hx"
}
]
},
......@@ -830,4 +862,4 @@
]
}
]
}
\ No newline at end of file
}
import React from 'react'
import { render } from '@testing-library/react'
import '@testing-library/jest-dom'
import Sidenavbar from '@/packages/sidenavbar'
const changeNarBar = jest.fn((vis: boolean) => {
console.log('changeNarBar>>>>', vis)
})
test('default props', () => {
const { container } = render(
<>
<Sidenavbar
title="首页"
visible
handleClose={() => {
changeNarBar(false)
}}
>
侧边栏内容
</Sidenavbar>
</>
)
expect(container.querySelector('.nut-popup')).toHaveClass('popup-left')
expect(container.querySelector('.nut-sidenavbar__title')).toHaveAttribute(
'style',
'padding-left: 20px;'
)
})
test('position should be right', () => {
const { container } = render(
<>
<Sidenavbar
title="首页"
visible
position="right"
handleClose={() => {
changeNarBar(false)
}}
>
侧边栏内容
</Sidenavbar>
</>
)
expect(container.querySelector('.nut-popup')).toHaveClass('popup-right')
})
test('offset should be 30', () => {
const { container } = render(
<>
<Sidenavbar
title="首页"
visible
position="left"
offset={30}
handleClose={() => {
changeNarBar(false)
}}
>
侧边栏内容
</Sidenavbar>
</>
)
expect(container.querySelector('.nut-sidenavbar__title')).toHaveAttribute(
'style',
'padding-left: 30px;'
)
})
import React, { useState } from 'react'
import SideNavBar from './index'
import SubSideNavBar from '@/packages/subsidenavbar'
import SideNavBarItem from '@/packages/sidenavbaritem'
import Cell from '@/packages/cell'
import Toast from '@/packages/toast'
type Position = 'left' | 'right'
type NavBarState = {
visible: boolean
position: Position
}
const SideNavBarDemo = () => {
const [navBarState, setNavBarState] = useState<NavBarState>({
visible: false,
position: 'left',
})
const [showThird, setShowThird] = useState(false)
const changeNarBar = (
visible: boolean,
position: Position = navBarState.position
) => {
setNavBarState({
visible,
position,
})
setShowThird(false)
}
const clickItem = (data: any) => {
const { title, ikey } = data
showThird && Toast.text(`title=${title},ikey=${ikey}`)
}
const clickTitle = (data: any) => {
const { title, ikey, isShow } = data
showThird && Toast.text(`title=${title},ikey=${ikey},isShow=${isShow}`)
}
return (
<>
<div className="demo">
<h2>基础用法</h2>
<Cell
title="左侧弹出"
isLink
onClick={() => {
changeNarBar(true, 'left')
}}
/>
<Cell
title="右侧弹出"
isLink
onClick={() => {
changeNarBar(true, 'right')
}}
/>
<h2>导航嵌套(建议最多三层),点击一级标题和一级内容1回调</h2>
<Cell
title="显示"
isLink
onClick={() => {
changeNarBar(true, 'right')
setShowThird(true)
}}
/>
<SideNavBar
title="首页"
visible={navBarState.visible}
position={navBarState.position}
handleClose={() => {
changeNarBar(false)
}}
>
<SubSideNavBar title="一级标题" ikey="1-0" titleClick={clickTitle}>
<SideNavBarItem title="一级内容1" ikey="1-01" click={clickItem} />
<SideNavBarItem title="一级内容2" ikey="1-02" />
<SubSideNavBar title="二级标题" ikey="2-0">
<SideNavBarItem title="二级内容1" ikey="2-01" />
<SideNavBarItem title="二级内容2" ikey="2-02" />
{showThird ? (
<SubSideNavBar title="三级标题" ikey="3-0">
<SideNavBarItem title="三级内容1" ikey="3-01" />
<SideNavBarItem title="三级内容2" ikey="3-02" />
</SubSideNavBar>
) : null}
</SubSideNavBar>
</SubSideNavBar>
<SubSideNavBar open={false} title="一级标题-2" ikey="1-1">
<SideNavBarItem title="一级内容2-1" ikey="1-11" />
<SideNavBarItem title="一级内容2-2" ikey="1-12" />
</SubSideNavBar>
</SideNavBar>
</div>
</>
)
}
export default SideNavBarDemo
# SideNavBar组件
### Intro
For content selection and switching
### Install
```tsx
import { SideNavBar,SubSideNavBar,SideNavBarItem } from '@nutui/nutui-react';
```
### Basic Usage
:::demo
```tsx
import React from "react";
import {Cell, SideNavBar,SubSideNavBar,SideNavBarItem } from '@nutui/nutui-react';
const App = () => {
const [navBarState, setNavBarState] = useState({
visible: false,
position: 'left',
})
const changeNarBar = (visible, position= navBarState.position) => {
setNavBarState({
visible,
position,
})
}
return (
<>
<Cell
title="left"
isLink
onClick={() => {
changeNarBar(true, 'left')
}}
/>
<Cell
title="right"
isLink
onClick={() => {
changeNarBar(true, 'right')
}}
/>
<SideNavBar
title="首页"
visible={navBarState.visible}
position={navBarState.position}
handleClose={() => {
changeNarBar(false)
}}
>
<SubSideNavBar title="Level 1 title" ikey="1-0" >
<SideNavBarItem title="Level 1 content-1" ikey="1-01" />
<SideNavBarItem title="Level 1 content-2" ikey="1-02" />
<SubSideNavBar title="Level 2 title" ikey="2-0">
<SideNavBarItem title="Level 2 content-1" ikey="2-01" />
<SideNavBarItem title="Level 2 content-2" ikey="2-02" />
</SubSideNavBar>
</SubSideNavBar>
</SideNavBar>
</>
);
};
export default App;
```
:::
### Nesting (up to three layers recommended)
:::demo
```tsx
import React from "react";
import {Cell,SideNavBar,SubSideNavBar,SideNavBarItem } from '@nutui/nutui-react';
const App = () => {
const [visible, setVisible] = useState(false)
const changeNarBar = (visible) => {
setVisible(visible)
}
const clickItem = ({ title, ikey }) => {
Toast.text(`title=${title},ikey=${ikey}`)
}
const clickTitle = ({ title, ikey, isShow }) => {
Toast.text(`title=${title},ikey=${ikey},isShow=${isShow}`)
}
return (
<>
<Cell
title="show"
isLink
onClick={() => {
changeNarBar(true)
}}
/>
<SideNavBar
title="首页"
visible={visible}
position='left'
handleClose={() => {
changeNarBar(false)
}}
>
<SubSideNavBar title="Level 1 title" ikey="1-0" titleClick={clickTitle}>
<SideNavBarItem title="Level 1 content-1" ikey="1-01" click={clickItem} />
<SideNavBarItem title="Level 1 content-2" ikey="1-02" />
<SubSideNavBar title="Level 2 title" ikey="2-0">
<SideNavBarItem title="Level 2 content-1" ikey="2-01" />
<SideNavBarItem title="Level 2 content-2" ikey="2-02" />
<SubSideNavBar title="Level 3 title" ikey="3-0">
<SideNavBarItem title="Level 3 content-1" ikey="3-01" />
<SideNavBarItem title="Level 3 content-2" ikey="3-02" />
</SubSideNavBar>
</SubSideNavBar>
</SubSideNavBar>
</SideNavBar>
</>
);
};
export default App;
```
:::
## API
### 1、SideNavBar
| Attribute | Description | Type | Default |
|--------------|----------------------------------|--------|------------------|
| visible |Whether the current component is displayed | boolean | false |
| title | Navigation title | String | - |
| width | Eject width -percentage | String | '80%' |
| position | Eject position | 'left'、'right' | 'left' |
| offset | Navigation indent width | number | 20 |
### 2、SubSideNavBar
| Attribute | Description | Type | Default |
|--------------|----------------------------------|--------|------------------|
| ikey | Navigation unique identifier | String、Number | |
| title | Navigation title | String | - |
| open | Whether navigation is expanded by default | Boolean | true |
### 3、SideNavBarItem
| Attribute | Description | Type | Default |
|--------------|----------------------------------|--------|------------------|
| ikey | Navigation unique identifier | String、Number | |
| title | Navigation title | String | - |
## Events
### 1、SideNavBar Events
| Event | Description | Arguments |
|----------------------|------------------------|--------------|
| handleClose | Click mask trigger | - |
### 2、SubSideNavBar Events
| Event | Description | Arguments |
|----------------------|--------------------------------------------|--------------|
| titleClick | Navigation Click,return{ title,ikey,isShow}| - |
### 3、SideNavBarItem Events
| Event | Description | Arguments |
|----------------------|--------------------------------------------|--------------|
| click | Navigation Click,return{ title,ikey} | - |
# SideNavBar组件
### 介绍
用于内容选择和切换
### 安装
```tsx
import { SideNavBar,SubSideNavBar,SideNavBarItem } from '@nutui/nutui-react';
```
## 代码演示
### 基础用法
:::demo
```tsx
import React from "react";
import {Cell, SideNavBar,SubSideNavBar,SideNavBarItem } from '@nutui/nutui-react';
const App = () => {
const [navBarState, setNavBarState] = useState({
visible: false,
position: 'left',
})
const changeNarBar = (visible, position= navBarState.position) => {
setNavBarState({
visible,
position,
})
}
return (
<>
<Cell
title="左侧弹出"
isLink
onClick={() => {
changeNarBar(true, 'left')
}}
/>
<Cell
title="右侧弹出"
isLink
onClick={() => {
changeNarBar(true, 'right')
}}
/>
<SideNavBar
title="首页"
visible={navBarState.visible}
position={navBarState.position}
handleClose={() => {
changeNarBar(false)
}}
>
<SubSideNavBar title="一级标题" ikey="1-0" >
<SideNavBarItem title="一级内容1" ikey="1-01" />
<SideNavBarItem title="一级内容2" ikey="1-02" />
<SubSideNavBar title="二级标题" ikey="2-0">
<SideNavBarItem title="二级内容1" ikey="2-01" />
<SideNavBarItem title="二级内容2" ikey="2-02" />
</SubSideNavBar>
</SubSideNavBar>
</SideNavBar>
</>
);
};
export default App;
```
:::
### 嵌套及回调
:::demo
```tsx
import React from "react";
import {Cell,SideNavBar,SubSideNavBar,SideNavBarItem } from '@nutui/nutui-react';
const App = () => {
const [visible, setVisible] = useState(false)
const changeNarBar = (visible) => {
setVisible(visible)
}
const clickItem = ({ title, ikey }) => {
Toast.text(`title=${title},ikey=${ikey}`)
}
const clickTitle = ({ title, ikey, isShow }) => {
Toast.text(`title=${title},ikey=${ikey},isShow=${isShow}`)
}
return (
<>
<Cell
title="显示"
isLink
onClick={() => {
changeNarBar(true)
}}
/>
<SideNavBar
title="首页"
visible={visible}
position='left'
handleClose={() => {
changeNarBar(false)
}}
>
<SubSideNavBar title="一级标题" ikey="1-0" titleClick={clickTitle}>
<SideNavBarItem title="一级内容1" ikey="1-01" click={clickItem} />
<SideNavBarItem title="一级内容2" ikey="1-02" />
<SubSideNavBar title="二级标题" ikey="2-0">
<SideNavBarItem title="二级内容1" ikey="2-01" />
<SideNavBarItem title="二级内容2" ikey="2-02" />
<SubSideNavBar title="三级标题" ikey="3-0">
<SideNavBarItem title="三级内容1" ikey="3-01" />
<SideNavBarItem title="三级内容2" ikey="3-02" />
</SubSideNavBar>
</SubSideNavBar>
</SubSideNavBar>
</SideNavBar>
</>
);
};
export default App;
```
:::
## API
### 1、SideNavBar
| 参数 | 说明 | 类型 | 默认值 |
|--------------|----------------------------------|--------|------------------|
| visible | 组件是否显示 | boolean | false |
| title | 整体标题 | String | - |
| width | 遮罩宽度百分比 | String | '80%' |
| position | 弹出位置 | 'left'、'right' | 'left' |
| offset | 缩进宽度 | number | 20 |
### 2、SubSideNavBar
| 参数 | 说明 | 类型 | 默认值 |
|--------------|----------------------------------|--------|------------------|
| ikey | 导航唯一标识 | String、Number | |
| title | 整体标题 | String | - |
| open | 导航是否默认展开 | Boolean | true |
### 3、SideNavBarItem
| 参数 | 说明 | 类型 | 默认值 |
|--------------|----------------------------------|--------|------------------|
| ikey | 导航唯一标识 | String、Number | |
| title | 整体标题 | String | - |
## Events
### 1、SideNavBar Events
| 事件名 | 说明 | 回调参数 |
|----------------------|------------------------|--------------|
| handleClose | 关闭遮罩时触发 | - |
### 2、SubSideNavBar Events
| 事件名 | 说明 | 回调参数 |
|----------------------|--------------------------------------------|--------------|
| titleClick | 导航点击,对象形式返回点击{ title,ikey,isShow}| - |
### 3、SideNavBarItem Events
| 事件名 | 说明 | 回调参数 |
|----------------------|--------------------------------------------|--------------|
| click | 导航点击,对象形式返回点击{ title,ikey} | - |
import { SideNavBar } from './sidenavbar'
export default SideNavBar
import { createContext } from 'react'
export const OffsetContext = createContext(20)
$nutSidenavbarItemHeight: 40px;
.nut-sidenavbar {
color: #1d1d21;
font-size: 14px;
height: 100%;
overflow: auto;
display: block;
background-color: #fff;
.arrow-icon {
position: absolute;
width: 0;
height: 0;
right: 16px;
top: 18px;
cursor: pointer;
}
.arrow-down {
border-top: 4px solid #909ca4;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
}
.arrow-up {
border-bottom: 4px solid #909ca4;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
}
&__head {
height: $nutSidenavbarItemHeight;
background: #eeeff2;
padding: 10px;
}
&__title {
height: $nutSidenavbarItemHeight;
padding: 10px 8px 10px 20px;
background: #f5f5f5;
}
&__content {
position: relative;
display: block;
}
&__list {
&.nutShow {
.nut-sidenavbar__content {
height: auto;
overflow: inherit;
}
}
&.nutHide {
.nut-sidenavbar__content {
height: 0;
overflow: hidden;
}
}
}
.border-bt {
position: relative;
&:after {
content: '';
position: absolute;
width: 100%;
height: 1px;
background: #eeeff2;
transform: scale(1, 0.5);
left: 0;
bottom: 0;
}
}
}
import React, { FunctionComponent } from 'react'
import { useConfig } from '@/packages/configprovider'
import Popup from '@/packages/popup'
import { SideNavBarProps } from './type'
import { handleClick } from './utils'
import { OffsetContext } from './offsetContext'
const defaultProps = {
showhead: false,
position: 'left',
width: '80%',
} as SideNavBarProps
export const SideNavBar: FunctionComponent<SideNavBarProps> = (props) => {
const { locale } = useConfig()
const {
title,
visible,
width,
position,
children,
className,
showhead,
handleClose,
...rest
} = {
...defaultProps,
...props,
}
const offset = props.offset ? Number(props.offset) : 20
return (
<Popup
visible={visible}
style={{ width, height: '100%' }}
position={position}
onClose={handleClose}
>
<div
className={className ? `${className} nut-sidenavbar` : 'nut-sidenavbar'}
{...rest}
>
<div className="nut-sidenavbar__content">
{/* {showhead ? <div className="nut-sidenavbar__head">📈</div> : null} */}
<div className="nut-sidenavbar__list nutShow" onClick={handleClick}>
<div
className="nut-sidenavbar__title border-bt "
style={{ paddingLeft: `${offset}px` }}
>
{title} <i className="arrow-icon arrow-down" />
</div>
<OffsetContext.Provider value={offset}>
<div className="nut-sidenavbar__content">{children}</div>
</OffsetContext.Provider>
</div>
</div>
</div>
</Popup>
)
}
SideNavBar.defaultProps = defaultProps
SideNavBar.displayName = 'NutSideNavBar'
type NavBarProps = {
showhead?: boolean
}
export interface SideNavBarProps
extends React.HTMLAttributes<HTMLDivElement>,
NavBarProps {
title: string
visible: boolean
width?: string
offset?: number
position?: 'left' | 'right'
handleClose: () => void
// showhead?: boolean
}
export type SideNavBarItemProps = {
title: string
ikey: string | number
click?: ({ title, ikey }: { title: string; ikey: string | number }) => void
}
export type SubNavBarProps = {
title: string
ikey: string | number
open?: boolean
titleClick?: ({
title,
ikey,
isShow,
}: {
title: string
ikey: string | number
isShow: boolean
}) => void
}
import { MouseEventHandler } from 'react'
const handleClick: MouseEventHandler<HTMLDivElement> = (e) => {
e.stopPropagation()
const isIcon = (e.target as HTMLDivElement).className.includes('arrow-icon')
const isTitle =
(e.target as HTMLDivElement).className.includes('__title') || isIcon
const currentClass = e.currentTarget.className
const isShow = currentClass.includes('nutShow')
const arrowIcon = e.currentTarget.querySelector('.arrow-icon') as Element
const iconClass = arrowIcon.className
if (isTitle) {
e.currentTarget.className = isShow
? currentClass.replace('nutShow', 'nutHide')
: currentClass.replace('nutHide', 'nutShow')
arrowIcon.className = isShow
? iconClass.replace('arrow-down', 'arrow-up')
: iconClass.replace('arrow-up', 'arrow-down')
}
}
export { handleClick }
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should match snapshot 1`] = `
<DocumentFragment>
<div
class="nut-subsidenavbar__item border-bt"
data-testid="sideNavBarItem-click"
>
一级内容1
</div>
</DocumentFragment>
`;
import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import SideNavBarItem from '@/packages/sidenavbaritem'
test('should match snapshot', () => {
const { asFragment } = render(
<SideNavBarItem
data-testid="sideNavBarItem-click"
title="一级内容1"
ikey="1-01"
/>
)
expect(asFragment()).toMatchSnapshot()
})
test('should emit click event', async () => {
const click = jest.fn(({ title, ikey }) => {
console.log('click>>>>', title, ikey)
})
const { getByTestId } = render(
<>
<SideNavBarItem
data-testid="sideNavBarItem-click"
title="一级内容1"
ikey="1-01"
click={click}
/>
</>
)
fireEvent.click(getByTestId('sideNavBarItem-click'))
expect(click).toBeCalled()
})
import { SideNavBarItem } from './sidenavbaritem'
export default SideNavBarItem
$nutSidenavbarItemHeight: 40px;
.nut-subsidenavbar {
&__item {
height: $nutSidenavbarItemHeight;
padding: 10px 8px 10px 55px;
}
}
import React, { FunctionComponent, MouseEventHandler } from 'react'
import { SideNavBarItemProps } from '../sidenavbar/type'
export const SideNavBarItem: FunctionComponent<SideNavBarItemProps> = (
props
) => {
const { title, ikey, children, click, ...rest } = props
const clickFn: MouseEventHandler<HTMLDivElement> = (e) => {
e.stopPropagation()
click && click({ title, ikey })
}
return (
<div
className="nut-subsidenavbar__item border-bt"
onClick={clickFn}
{...rest}
>
{title}
</div>
)
}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should match snapshot 1`] = `
<DocumentFragment>
<div
class="nut-subsidenavbar__list nutHide"
level="1"
>
<div
class="nut-subsidenavbar__title border-bt"
style="padding-left: 40px;"
>
一级标题
<i
class="arrow-icon arrow-up"
/>
</div>
<div
class="nut-subsidenavbar__content"
>
<div
class="nut-subsidenavbar__item border-bt"
style="padding-left: 60px;"
>
一级内容1
</div>
</div>
</div>
</DocumentFragment>
`;
import React from 'react'
// import * as renderer from 'react-test-renderer'
import { render, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import SubSideNavBar from '@/packages/subsidenavbar'
import SideNavBarItem from '@/packages/sidenavbaritem'
test('should match snapshot', () => {
const { asFragment } = render(
<SubSideNavBar title="一级标题" ikey="1-0" open={false}>
<SideNavBarItem title="一级内容1" ikey="1-01" />
</SubSideNavBar>
)
expect(asFragment()).toMatchSnapshot()
})
test('navigation should be hide', async () => {
const { container } = render(
<>
<SubSideNavBar
data-testid="SubSideNavBar-click"
title="一级标题"
ikey="1-0"
open={false}
>
<SideNavBarItem title="一级内容1" ikey="1-01" />
</SubSideNavBar>
</>
)
expect(container.querySelector('.nut-subsidenavbar__list')).toHaveClass(
'nutHide'
)
})
test('should emit titleClick event', async () => {
const titleClick = jest.fn(({ title, ikey, isShow }) => {
console.log('titleClick>>>>', title, ikey, isShow)
})
const { getByTestId } = render(
<>
<SubSideNavBar
data-testid="SubSideNavBar-click"
title="一级标题"
ikey="1-0"
titleClick={titleClick}
>
<SideNavBarItem title="一级内容1" ikey="1-01" />
</SubSideNavBar>
</>
)
fireEvent.click(getByTestId('SubSideNavBar-click'))
expect(titleClick).toBeCalled()
})
import { SubSideNavBar } from './subsidenavbar'
export default SubSideNavBar
$nutSidenavbarItemHeight: 40px;
.nut-subsidenavbar {
&__title {
height: $nutSidenavbarItemHeight;
padding: 10px 8px 10px 35px;
background: #f7f8fa;
}
&__list {
&.nutShow {
.nut-subsidenavbar__content {
height: auto;
overflow: inherit;
}
}
&.nutHide {
.nut-subsidenavbar__content {
height: 0;
overflow: hidden;
}
}
}
}
import React, {
FunctionComponent,
useRef,
useEffect,
useCallback,
MouseEventHandler,
useContext,
} from 'react'
import { SubNavBarProps } from '../sidenavbar/type'
import { handleClick } from '../sidenavbar/utils'
import { OffsetContext } from '../sidenavbar/offsetContext'
const defaultProps = {
open: true,
} as SubNavBarProps
export const SubSideNavBar: FunctionComponent<SubNavBarProps> = (props) => {
const { title, ikey, children, titleClick, open, ...rest } = {
...defaultProps,
...props,
}
// const offset = props.offset ? Number(props.offset) : 20
const offset = useContext(OffsetContext)
console.log('offset>>>>>>>', offset)
const listRef = useRef<HTMLDivElement>(null)
const setListLevel = useCallback(
(nodeList: HTMLCollection, level = 1) => {
const titleClass = nodeList[0].className
if (titleClass.includes('nut-subsidenavbar__title')) {
// const left = 15 + offset * level
const left = offset * (level + 1)
// eslint-disable-next-line no-param-reassign
;(nodeList[0] as HTMLElement).style.paddingLeft = `${left}px`
}
const childNodes =
nodeList[1] &&
nodeList[1].children &&
Array.from(nodeList[1].children).filter(
(item) => item.nodeType !== 3 && item.nodeType !== 8
)
childNodes.forEach((item) => {
const itemClass = item.className
if (itemClass.includes('nut-subsidenavbar__item')) {
// const left = 15 + offset * (level + 1)
const left = offset * (level + 2)
// eslint-disable-next-line no-param-reassign
;(item as HTMLElement).style.paddingLeft = `${left}px`
}
if (itemClass.includes('nut-subsidenavbar__list')) {
let level = item.getAttribute('level')
? Number(item.getAttribute('level'))
: 1
level += 1
item.setAttribute('level', level.toString())
item.children && setListLevel(item.children, level)
}
})
},
[offset]
)
const clickFn: MouseEventHandler<HTMLDivElement> = (e) => {
handleClick(e)
const currentClass = e.currentTarget.className
const isShow = currentClass.includes('nutShow')
titleClick && titleClick({ title, ikey, isShow })
}
useEffect(() => {
const childNodes = listRef.current?.children as HTMLCollection
listRef.current?.setAttribute('level', '1')
childNodes && setListLevel(childNodes)
}, [setListLevel])
const divClass = open
? 'nut-subsidenavbar__list nutShow'
: 'nut-subsidenavbar__list nutHide'
const iconClass = open ? 'arrow-icon arrow-down' : 'arrow-icon arrow-up'
return (
<div className={divClass} ref={listRef} onClick={clickFn} {...rest}>
<div className="nut-subsidenavbar__title border-bt">
{title} <i className={iconClass} />
</div>
<div className="nut-subsidenavbar__content">{children}</div>
</div>
)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册