提交 298f4b4f 编写于 作者: L liuzhuangzhuang1

feat: 增加tag组件和badge组件

上级 f3a1e83f
...@@ -351,6 +351,36 @@ ...@@ -351,6 +351,36 @@
"sort": 4, "sort": 4,
"show": true, "show": true,
"author": "oasis" "author": "oasis"
},
{
"version": "1.0.0",
"name": "Tag",
"type": "component",
"cName": "标签",
"desc": "用于标记和分类。",
"sort": 4,
"show": true,
"author": "lzz"
},
{
"version": "1.0.0",
"name": "Badge",
"type": "component",
"cName": "徽标",
"desc": "在图标或文字右上角的红色圆点、数字或者文字,表示有新内容或者待处理的信息。",
"sort": 4,
"show": true,
"author": "lzz"
},
{
"version": "1.0.0",
"name": "Popover",
"type": "component",
"cName": "气泡弹出框",
"desc": "点击或在元素上悬停鼠标,弹出气泡卡片浮层。",
"sort": 4,
"show": true,
"author": "lzz"
} }
] ]
}, },
......
.nut-badge {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
margin-right: 40px;
.slot-icons {
position: absolute;
background: $badge-background-color;
border-radius: 7px;
top: -20%;
right: -20%;
padding: 0 5px;
text-align: center;
border-radius: 14px;
z-index: 1;
}
.sup {
position: absolute;
background: $badge-background-color;
border-radius: 7px;
padding: 0 5px;
text-align: center;
border-radius: 14px;
font-size: $badge-font-size;
font-weight: normal;
color: $badge-default-background-color;
line-height: 16px;
}
.nut-badge__content {
transform: translateY(-50%) translateX(100%);
}
.is-dot {
width: 7px;
height: 7px;
border-radius: 7px;
padding: 0;
}
}
import React, {
CSSProperties,
FunctionComponent,
MouseEventHandler,
useEffect,
useState,
} from 'react'
import './badge.scss'
import Icon from '@/packages/icon'
export interface BadgeProps {
value: any
dot: boolean
max: Number
top: string
right: string
zIndex: string
color: string
icons: any
}
export type BadgeType = 'default' | 'primary' | 'success' | 'warning' | 'danger'
const defaultProps = {
value: '',
dot: false,
max: 10000,
top: '0',
right: '0',
zIndex: '0',
color: '',
icons: '',
} as BadgeProps
export const Badge: FunctionComponent<Partial<BadgeProps>> = (props) => {
const { value, children, dot, max, top, right, zIndex, color, icons } = {
...defaultProps,
...props,
}
const content = () => {
if (dot) return
const value = props.value
const max = props.max
if (typeof value === 'number' && typeof max === 'number') {
return max < value ? `${max}+` : value
}
return value
}
const getStyle = () => {
const style: CSSProperties = {}
style.top = `${top}px`
style.right = `${right}px`
style.zIndex = zIndex
style.background = color
return style
}
return (
<div className="nut-badge">
{icons != '' && (
<div className="slot-icons">
<Icon className="_icon" name={icons} color="#ffffff" size="12"></Icon>
</div>
)}
<div>{children}</div>
<div className={`${dot ? 'is-dot' : ''} nut-badge__content sup`} style={getStyle()}>
{content()}
</div>
</div>
)
}
Badge.defaultProps = defaultProps
Badge.displayName = 'NutBadge'
import React, { useState } from 'react'
import { Badge } from './badge'
import Cell from '@/packages/cell'
import CellGroup from '@/packages/cellgroup'
import Avatar from '@/packages/avatar'
const BadgeDemo = () => {
return (
<>
<div className="demo">
<CellGroup title="默认用法">
<Cell>
<Badge value={8}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={76}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value="NEW">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge dot>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
</Cell>
</CellGroup>
<CellGroup title="最大值">
<Cell>
<Badge value={200} max={9}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={200} max={20}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={200} max={99}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
</Cell>
</CellGroup>
<CellGroup title="自定义颜色">
<Cell>
<Badge
value={8}
color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)"
>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge
value={76}
color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)"
>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge
value="NEW"
color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)"
>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge
dot
color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)"
>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
</Cell>
</CellGroup>
<CellGroup title="自定义徽标内容">
<Cell>
<Badge icons="checklist">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge icons="link">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge icons="download">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
</Cell>
</CellGroup>
<CellGroup title="自定义位置">
<Cell>
<Badge value={8} top="5" right="5">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={76} top="10" right="10">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value="NEW">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
</Cell>
</CellGroup>
<CellGroup title="独立展示">
<Cell>
<Badge value={8}></Badge>
<Badge value={76}></Badge>
<Badge value="NEW"></Badge>
</Cell>
</CellGroup>
</div>
</>
)
}
export default BadgeDemo
# Badge 徽标
### 介绍
出现在图标或文字右上角的红色圆点、数字或者文字,表示有新内容或者待处理的信息。
### 安装
``` javascript
import { Badge } from '@nutui/nutui';
```
## 代码实例
### 基本用法
```tsx
<Badge value={8}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={76}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value="NEW">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge dot>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
```
### 最大值
```tsx
<Badge value={200} max={9}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={200} max={20}>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={200} max={99}>>
<Avatar icon="my" shape="square"></Avatar>
</Badge>
```
### 自定义颜色
```tsx
<Badge value={8} color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={76} color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value="NEW" color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge dot color="linear-gradient(315deg, rgba(73,143,242,1) 0%,rgba(73,101,242,1) 100%)">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
```
### 自定义徽标内容
```tsx
<Badge icon="checklist">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge icon="link">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge icon="download">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
```
### 自定义位置
```tsx
<Badge value={8} top="5" right="5">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value={76} top="10" right="10">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
<Badge value="NEW">
<Avatar icon="my" shape="square"></Avatar>
</Badge>
```
### 独立展示
```tsx
<Badge value={8}> </Badge>
<Badge value={76}> </Badge>
<Badge value="NEW"> </Badge>
```
## API
### Props
| 字段 | 说明 | 类型 | 默认值 |
|---------|--------------------------------------------|---------|-----------|
| value | 显示的内容 | String | - |
| max | value 为数值时,最大值 | Number | `10000` |
| z-index | 徽标的 z-index 值 | Number | `10` |
| dot | 是否为小点 | Boolean | `false` |
| hidden | 是否隐藏 | Boolean | `false` |
| top | 上下偏移量,支持单位设置,可设置为:5px 等 | Number | `0` |
| right | 左右偏移量,支持单位设置,可设置为:5px 等 | Number | `0` |
| color | 徽标背景颜色 | String | `#fa2c19` |
| icons | 徽标自定义 | String | - |
import { Badge } from './badge'
export default Badge
import Avatar from './avatar'
import Button from './button'
import Cell from './cell'
import Icon from './icon'
import Price from './price'
import Overlay from './overlay'
import Divider from './divider'
import Drag from './drag'
import Collapse from './collapse'
import Toast from './toast'
import BackTop from './backtop'
import Range from './range'
import Infiniteloading from './infiniteloading'
import Steps from './steps'
import CircleProgress from './circleprogress'
import NavBar from './navbar'
import Tabbar from './tabbar'
import InputNumber from './inputnumber'
import Elevator from './elevator'
import Rate from './rate'
import Uploader from './uploader'
import Input from './input'
import TextArea from './textarea'
import CheckBox from './checkbox'
import Tag from './tag'
import Badge from './badge'
import Signature from './signature'
export {
Avatar,
Button,
Cell,
Icon,
Price,
Overlay,
Divider,
Drag,
Collapse,
Toast,
BackTop,
Range,
Infiniteloading,
Steps,
CircleProgress,
NavBar,
Tabbar,
InputNumber,
Elevator,
Rate,
Uploader,
Input,
TextArea,
CheckBox,
Tag,
Badge,
Signature,
}
import React, { useState } from 'react'
import { Tag } from './tag'
import Cell from '@/packages/cell'
import CellGroup from '@/packages/cellgroup'
const TagDemo = () => {
const [isShow, setIsShow] = useState(true)
const close = () => {
setIsShow(false)
}
return (
<>
<div className="demo">
<CellGroup title="基础用法">
<Cell title="primary类型" extra={<Tag type="primary">标签</Tag>}></Cell>
<Cell title="success类型" extra={<Tag type="success">标签</Tag>}></Cell>
<Cell title="danger类型" extra={<Tag type="danger">标签</Tag>}></Cell>
<Cell title="warning类型" extra={<Tag type="warning">标签</Tag>}></Cell>
</CellGroup>
<CellGroup title="样式风格">
<Cell title="空心样式" extra={<Tag plain>标签</Tag>}></Cell>
<Cell
title="圆角样式"
extra={
<Tag round type="primary">
标签
</Tag>
}
></Cell>
<Cell
title="标记样式"
extra={
<Tag mark type="primary">
标签
</Tag>
}
></Cell>
<Cell
title="可关闭标签"
extra={
<Tag isShow={isShow} closeable onClick={close} type="primary">
标签
</Tag>
}
></Cell>
</CellGroup>
<CellGroup title="自定义">
<Cell title="背景颜色" extra={<Tag color="#FA685D">标签</Tag>}></Cell>
<Cell
title="文字颜色"
extra={
<Tag color="#E9E9E9" textColor="#999999">
标签
</Tag>
}
></Cell>
<Cell
title="空心颜色"
extra={
<Tag color="#FA2400" plain>
标签
</Tag>
}
></Cell>
</CellGroup>
</div>
</>
)
}
export default TagDemo
# Tag 标签
### 介绍
用于标记和分类的标签。
### 安装
``` javascript
import { Tag } from '@nutui/nutui';
```
## 代码实例
### 基础用法
```tsx
<Tag type="primary">标签</Tag>
<Tag type="success">标签</Tag>
<Tag type="danger">标签</Tag>
<Tag type="warning">标签</Tag>
```
### 空心样式
```tsx
<Tag plain>标签</Tag>
```
### 圆角样式
```tsx
<Tag round type="primary">标签</Tag>
```
### 标记样式
```tsx
<Tag mark type="primary">标签</Tag>
```
### 可关闭标签
```tsx
<Tag isShow={isShow} closeable onClick={close} type="primary">标签</Tag>
```
### 自定义颜色
```tsx
<Tag color="#FA685D">标签</Tag>
<Tag color="#E9E9E9" text-color="#999999">标签</Tag>
<Tag color="#FA2400" plain>标签</Tag>
```
## API
### Props
| 字段 | 说明 | 类型 | 默认值 |
|------------|--------------------------------------------------|---------|-----------|
| type | 标签类型,可选值为primary success danger warning | String | `default` |
| color | 标签颜色 | String | - |
| text-color | 文本颜色,优先级高于color属性 | String | `white` |
| plain | 是否为空心样式 | Boolean | `false` |
| round | 是否为圆角样式 | Boolean | `false` |
| mark | 是否为标记样式 | Boolean | `false` |
| closeable | 是否为可关闭标签 | Boolean | `false` |
### Event
| 事件名称 | 说明 | 回调参数 |
|----------|----------|----------|
| close | 关闭事件 | event |
import { Tag } from './tag'
export default Tag
.nut-tag {
padding: 0 4px;
border-radius: 4px;
._icon {
vertical-align: middle;
margin-left: 4px;
}
&--default {
color: $tag-default-color;
background: $tag-default-background-color;
border: $tag-border-width solid transparent;
}
&--primary {
color: $tag-default-color;
background: $tag-primary-background-color;
border: $tag-border-width solid transparent;
}
&--success {
color: $tag-default-color;
background: $tag-success-background-color;
border: $tag-border-width solid transparent;
}
&--danger {
color: $tag-default-color;
background: $tag-danger-background-color;
border: $tag-border-width solid transparent;
}
&--warning {
color: $tag-default-color;
background: $tag-warning-background-color;
border: $tag-border-width solid transparent;
}
&--plain {
color: $tag-plain-color;
background: $tag-plain-background-color;
border: $tag-border-width solid $tag-plain-color;
}
&--round {
border-radius: 8px;
}
&--mark {
border-radius: 0 12px 12px 0;
}
&--close {
margin-left: 4px;
cursor: pointer;
}
}
import React, {
CSSProperties,
FunctionComponent,
MouseEventHandler,
useEffect,
useState,
} from 'react'
import './tag.scss'
import classNames from 'classnames'
import Icon from '@/packages/icon'
export interface TagProps {
type: TagType
color: string
textColor: string
plain: boolean
round: boolean
mark: boolean
closeable: boolean
isShow: boolean
prefixCls: string
onClick: (e: MouseEvent) => void
}
export type TagType = 'default' | 'primary' | 'success' | 'warning' | 'danger'
const defaultProps = {
type: 'default',
color: '',
textColor: '',
plain: false,
round: false,
mark: false,
closeable: false,
isShow: true,
prefixCls: 'nut-tag',
onClick: (e: MouseEvent) => {},
} as TagProps
export const Tag: FunctionComponent<Partial<TagProps>> = (props) => {
const {
color,
plain,
type,
round,
prefixCls,
children,
mark,
closeable,
textColor,
isShow,
onClick,
} = {
...defaultProps,
...props,
}
const [btnName, setBtnName] = useState('')
useEffect(() => {
setBtnName(classes())
}, [type, color, textColor, plain, round, mark, closeable, prefixCls, isShow, onClick])
const classes = () => {
const prefixCls = 'nut-tag'
return `${prefixCls}
${type ? `${prefixCls}--${type}` : ''}
${plain ? `${prefixCls}--plain` : ''}
${round ? `${prefixCls}--round` : ''}
${mark ? `${prefixCls}--mark` : ''}
${closeable ? `${prefixCls}--close` : ''}`
}
const handleClick = (e: any) => {
if (props.onClick) {
props.onClick(e)
}
}
const getStyle = () => {
const style: CSSProperties = {}
if (textColor) {
style.color = textColor
if (plain) {
style.background = '#fff'
} else {
if (color) {
style.background = color
}
}
} else {
if (color) {
style.color = '#fff'
style.background = color
}
}
return style
}
return (
<div>
{closeable ? (
isShow ? (
<div className={`${btnName}`} style={getStyle()} onClick={(e) => handleClick(e)}>
{children && <span className="text">{children}</span>}
{closeable && (
<Icon className="_icon" name="close" size="12" onClick={(e) => handleClick(e)}></Icon>
)}
</div>
) : (
''
)
) : (
<div className={`${btnName}`} style={getStyle()} onClick={(e) => handleClick(e)}>
{children && <span className="text">{children}</span>}
</div>
)}
</div>
)
}
Tag.defaultProps = defaultProps
Tag.displayName = 'NutTag'
...@@ -267,5 +267,32 @@ $fixednav-font-color: $black; ...@@ -267,5 +267,32 @@ $fixednav-font-color: $black;
$fixednav-index: 201; $fixednav-index: 201;
$fixednav-btn-bg: linear-gradient(135deg, rgba(250, 25, 44, 1) 0%, rgba(250, 63, 25, 1) 100%); $fixednav-btn-bg: linear-gradient(135deg, rgba(250, 25, 44, 1) 0%, rgba(250, 63, 25, 1) 100%);
// Tag
$tag-font-size: 12px !default;
$tag-default-background-color: #000000 !default;
$tag-primary-background-color: #3460fa !default;
$tag-success-background-color: #4fc08d !default;
$tag-danger-background-color: linear-gradient(
135deg,
rgba(242, 20, 12, 1) 0%,
rgba(232, 34, 14, 1) 69.83950099728881%,
rgba(242, 77, 12, 1) 100%
) !default;
$tag-warning-background-color: #f3812e !default;
$tag-default-color: #ffffff !default;
$tag-border-width: 1px !default;
$tag-plain-background-color: #fff !default;
$tag-plain-color: rgb(250, 36, 0) !default;
//badge
$badge-background-color: linear-gradient(
135deg,
$primary-color 0%,
$primary-color-end 100%
) !default;
$badge-font-size: $font-size-1 !default;
$badge-default-background-color: rgba(255, 255, 255, 1) !default;
@import './mixins/index'; @import './mixins/index';
@import './animation/index'; @import './animation/index';
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册