未验证 提交 eb2be568 编写于 作者: L lkjh3214 提交者: GitHub

feat: indicator 组件 (#158)


* feat: 添加indicator单元测试

* fix: review问题修复
Co-authored-by: Nlkjh3214 <13121007159@163.com>
上级 2145394f
......@@ -236,6 +236,16 @@
"exportEmpty": true,
"desc": "选项卡切换子组件",
"author": "张晶发"
},
{
"version": "1.0.0",
"name": "Indicator",
"type": "component",
"cName": "指示器",
"desc": "显示一个任务或流程的进度,常用于开通流程。",
"sort": 16,
"show": true,
"author": "liukun"
}
]
},
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should match snapshot 1`] = `
<DocumentFragment>
<div
class="nut-indicator demo1"
>
<div
class="nut-indicator__dot"
/>
<div
class="nut-indicator__dot"
/>
<div
class="nut-indicator__number"
>
03
</div>
</div>
</DocumentFragment>
`;
import * as React from 'react'
import { render } from '@testing-library/react'
import '@testing-library/jest-dom'
import { useState } from 'react'
import { Indicator } from '../indicator'
import Button from '@/packages/button'
import Cell from '@/packages/cell'
import Row from '@/packages/row'
import Col from '@/packages/col'
test('should match snapshot', () => {
const { asFragment } = render(
<Indicator className="demo1" size={3} current={3} />
)
expect(asFragment()).toMatchSnapshot()
})
test('should be shown when passing size and current', () => {
const { container, getByTestId } = render(
<Cell>
<Row>
<Col span="12">
<Button size="small" type="primary">
主要按钮
</Button>
</Col>
<Col span="12">
<Indicator
data-testid="indicator"
className="aa"
block
align="right"
size={6}
current={5}
/>
</Col>
</Row>
</Cell>
)
expect(getByTestId('indicator')).toHaveClass('aa')
expect(container.querySelectorAll('.nut-indicator__dot')).toHaveLength(5)
expect(container.querySelectorAll('.nut-indicator__number')).toHaveLength(1)
})
test('should be shown when passing block and align and fillZero', () => {
const IndicatorDemo = () => {
const [loading, setLoading] = useState(false)
return (
<Cell>
<Indicator block fillZero align="center" size={6} current={5} />
</Cell>
)
}
const { container } = render(<IndicatorDemo />)
const wrapper = container.querySelector('.nut-indicator')
expect(wrapper).toHaveClass('nut-indicator__align__center')
expect(wrapper).toHaveClass('nut-indicator__block')
expect(container.querySelector('.nut-indicator__number')).toHaveTextContent(
'05'
)
})
import React from 'react'
import { Indicator } from './indicator'
import Cell from '@/packages/cell'
import Row from '@/packages/row'
import Col from '@/packages/col'
import Button from '@/packages/button'
const IndicatorDemo = () => {
return (
<>
<div className="demo">
<h2>基础用法</h2>
<Cell>
<Indicator className="demo1" size={3} current={3} />
</Cell>
<Cell>
<Row>
<Col span="12">
<Button size="small" type="primary">
主要按钮
</Button>
</Col>
<Col span="12">
<Indicator block align="right" size={6} current={5} />
</Col>
</Row>
</Cell>
<h2>block用法</h2>
<Cell>
<Indicator block align="center" size={6} current={5} />
</Cell>
<Cell>
<Indicator block align="left" size={6} current={1} />
</Cell>
<Cell>
<Indicator block align="right" size={6} current={5} />
</Cell>
<h2>不补0</h2>
<Cell>
<Indicator fillZero={false} size={6} current={5} />
</Cell>
</div>
</>
)
}
export default IndicatorDemo
# Indicator 指示器
### 介绍
显示一个任务或流程的进度,常用于开通流程。
### 安装
```javascript
import { Indicator } from '@nutui/nutui-react'
```
### 基础用法
:::demo
```tsx
import React from "react";
import { Indicator, Cell, Button } from '@nutui/nutui-react';
const App = () => {
return (
<Cell>
<Indicator size={3} current={3}>
</Indicator>
</Cell>
<Cell>
<Row>
<Col span="12">
<Button size="small" type="primary">
主要按钮
</Button>
</Col>
<Col span="12">
<Indicator block={true} align="right" size={6} current={5}>
</Indicator>
</Col>
</Row>
</Cell>
);
};
export default App;
```
:::
### block用法
`block`为true时,将表现为块级元素,可通过`align`,设置对齐方式
:::demo
```tsx
import React from "react";
import { Indicator, Cell } from '@nutui/nutui-react';
const App = () => {
return (
<Cell>
<Indicator block={true} align="center" size={6} current={5}>
</Indicator>
</Cell>
<Cell>
<Indicator block={true} align="left" size={6} current={1}>
</Indicator>
</Cell>
<Cell>
<Indicator block={true} align="right" size={6} current={5}>
</Indicator>
</Cell>
);
};
export default App;
```
:::
### 不补0
:::demo
```tsx
import React from "react";
import { Indicator, Cell } from '@nutui/nutui-react';
const App = () => {
return (
<Cell>
<Indicator fillZero={false} size={6} current={5}>
</Indicator>
</Cell>
);
};
export default App;
```
:::
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
|--------------|----------------------------------|--------|------------------|
| current | 当前步骤 | Number | 1 |
| size | 步骤长度 | Number | 3 |
| block | 是否启用块级布局 | Boolean | false |
| align | 对齐方式,仅在block为true时生效, 可选值 'left', 'right', 'center'| String | left |
| fillZero | 单数前面是否补0 | Boolean | true |
import { Indicator } from './indicator'
export default Indicator
.nut-indicator {
&__block {
display: block;
width: 100%;
}
&__align__left {
text-align: left;
}
&__align__right {
text-align: right;
}
&__align__center {
text-align: center;
}
&__dot,
&__number {
margin: 0 4px;
&:first-child {
margin-left: 0;
}
&:last-child {
margin-right: 0;
}
}
&__dot {
display: inline-block;
vertical-align: middle;
width: $indicator-dot-size;
height: $indicator-dot-size;
border-radius: 50%;
background-color: $indicator-dot-color;
}
&__number {
display: inline-block;
position: relative;
width: $indicator-size;
height: $indicator-size;
text-align: center;
font-size: $indicator-number-font-size;
line-height: $indicator-size;
color: $indicator-white;
vertical-align: middle;
border: 1px solid $indicator-white;
border-radius: 50%;
background-color: $indicator-color;
box-shadow: 0 0 1px 1px $indicator-color;
}
}
import React, { FunctionComponent, ReactNode, useEffect } from 'react'
import classNames from 'classnames'
import bem from '@/utils/bem'
export interface IndicatorProps {
size: number
current: number
block: boolean
align: 'left' | 'right' | 'center'
fillZero: boolean
}
const defaultProps = {
size: 3,
current: 1,
block: false,
align: 'center',
fillZero: true,
} as IndicatorProps
export const Indicator: FunctionComponent<
Partial<IndicatorProps> & React.HTMLAttributes<HTMLDivElement>
> = (props) => {
const {
size,
current,
block,
align,
fillZero,
children,
className,
...rest
} = {
...defaultProps,
...props,
}
const b = bem('indicator')
const classes = classNames(
{
[`${b('block')}`]: block,
[`${b('align')}__${align}`]: block && align,
},
b('')
)
const renderEles = () => {
const childs: ReactNode[] = []
for (let item = 1; item <= size; item++) {
childs.push(
item === current ? (
<div key={item} className={b('number')}>
{fillZero && item < 10 ? `0${item}` : item}
</div>
) : (
<div key={item} className={b('dot')} />
)
)
}
return childs
}
useEffect(() => {}, [])
return (
<div className={`${classes} ${className}`} {...rest}>
{renderEles()}
</div>
)
}
Indicator.defaultProps = defaultProps
Indicator.displayName = 'NutIndicator'
......@@ -409,6 +409,16 @@ $empty-description-color: #666666 !default;
$empty-description-font-size: 14px !default;
$empty-description-line-height: 20px !default;
$empty-description-padding: 0 40px !default;
// indicator
$indicator-color: $primary-color !default;
$indicator-dot-color: $disable-color !default;
$indicator-white: $white !default;
$indicator-size: 18px !default;
$indicator-dot-size: calc($indicator-size / 3) !default;
$indicator-border-size: $indicator-size + 2 !default;
$indicator-number-font-size: 10px !default;
// circleProgress
$circleprogress-primary-color: $primary-color !default;
$circleprogress-path-color: #e5e9f2 !default;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册