提交 c5bc5c01 编写于 作者: H hanyuxinting

feat: rate 组件拆分icon

上级 e91eb2f6
import React, { FunctionComponent, useEffect, useState } from 'react'
import classNames from 'classnames'
import { StarFillN } from '@nutui/icons-react'
import bem from '@/utils/bem'
import Icon from '@/packages/icon'
import { BasicComponent, ComponentDefaults } from '@/utils/typings'
......@@ -12,8 +12,7 @@ export interface RateProps extends BasicComponent {
iconSize: string | number
activeColor: string
voidColor: string
checkedIcon: string
uncheckedIcon: string
checkedIcon: React.ReactNode
disabled: boolean
readonly: boolean
allowHalf: boolean
......@@ -29,8 +28,7 @@ const defaultProps = {
iconSize: 18,
activeColor: '',
voidColor: '',
checkedIcon: 'star-fill-n',
uncheckedIcon: 'star-n',
checkedIcon: null,
disabled: false,
readonly: false,
allowHalf: false,
......@@ -47,14 +45,11 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
activeColor,
voidColor,
checkedIcon,
uncheckedIcon,
disabled,
readonly,
allowHalf,
spacing,
onChange,
iconClassPrefix,
iconFontClassName,
} = {
...defaultProps,
...props,
......@@ -81,6 +76,18 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
return Number.isNaN(Number(value)) ? String(value) : `${value}px`
}
const renderIcon = (size: string | number = iconSize, color: string) => {
return React.isValidElement(checkedIcon) ? (
React.cloneElement<any>(checkedIcon, {
...checkedIcon.props,
width: size,
height: size,
color,
})
) : (
<StarFillN width={size} height={size} color={color} />
)
}
const onClick = (e: React.MouseEvent, index: number) => {
e.preventDefault()
e.stopPropagation()
......@@ -91,7 +98,6 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
}
value = Math.max(value, Number(minimizeValue))
setScore(value)
onChange && onChange(value)
}
const onHalfClick = (event: any, n: number) => {
......@@ -111,45 +117,21 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
onClick={(event) => onClick(event, n)}
style={{ marginRight: pxCheck(spacing) }}
>
<Icon
classPrefix={iconClassPrefix}
fontClassName={iconFontClassName}
size={iconSize}
<div
className={classNames(bi('icon'), {
[bi('icon--disabled')]: disabled || n > score,
})}
name={n <= score ? checkedIcon : uncheckedIcon}
color={n <= score ? activeColor : voidColor}
/>
>
{renderIcon(iconSize, n <= score ? activeColor : voidColor)}
</div>
{allowHalf && score > n - 1 && (
<Icon
classPrefix={iconClassPrefix}
fontClassName={iconFontClassName}
<div
className={` ${bi('half')} ${bi('icon')} ${bi('icon--half')}`}
onClick={(event) => onHalfClick(event, n)}
className={`${bi('icon')} ${bi('icon--half')}`}
color={n <= score ? activeColor : voidColor}
size={iconSize}
name={checkedIcon}
/>
)}
{/* {allowHalf && score > n - 1 && (
<Icon classPrefix={iconClassPrefix} fontClassName={iconFontClassName}
className={`${bi('icon')} ${bi('icon--half')}`}
color={n <= score ? activeColor : voidColor}
size={iconSize}
name={checkedIcon}
/>
>
{renderIcon(iconSize, n <= score ? activeColor : voidColor)}
</div>
)}
{allowHalf && score < n - 1 && (
<Icon classPrefix={iconClassPrefix} fontClassName={iconFontClassName}
className={`${bi('icon')} ${bi('icon--disabled')} ${bi(
'icon--half'
)}`}
color={voidColor}
size={iconSize}
name={uncheckedIcon}
/>
)} */}
</div>
)
})}
......
......@@ -76,6 +76,19 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
return Number.isNaN(Number(value)) ? String(value) : `${value}px`
}
const renderIcon = (size: string | number = iconSize, color: string) => {
return React.isValidElement(checkedIcon) ? (
React.cloneElement<any>(checkedIcon, {
...checkedIcon.props,
width: size,
height: size,
color,
})
) : (
<StarFillN width={size} height={size} color={color} />
)
}
const onClick = (e: React.MouseEvent, index: number) => {
e.preventDefault()
e.stopPropagation()
......@@ -83,17 +96,20 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
let value = 0
if (!(index === 1 && score === index)) {
value = index
if (allowHalf) {
if ((e?.target as Element).className.includes('__icon--half')) {
value -= 0.5
}
}
}
value = Math.max(value, Number(minimizeValue))
setScore(value)
onChange && onChange(value)
}
const onHalfClick = (event: any, n: number) => {
event.preventDefault()
event.stopPropagation()
const value = Math.max(Number(minimizeValue), n - 0.5)
setScore(value)
onChange && onChange(value)
}
return (
<div className={classNames(b(), className)} style={style}>
{countArray.map((n) => {
......@@ -104,44 +120,21 @@ export const Rate: FunctionComponent<Partial<RateProps>> = (props) => {
onClick={(event) => onClick(event, n)}
style={{ marginRight: pxCheck(spacing) }}
>
<>
{checkedIcon || (
<StarFillN
width={iconSize}
height={iconSize}
color={n <= score ? activeColor : voidColor}
className={classNames(bi('icon'), {
[bi('icon--disabled')]: disabled || n > score,
})}
/>
)}
{(allowHalf && score > n - 1 && (
<div className={` ${bi('half')}`}>
{checkedIcon || (
<StarFillN
width={iconSize}
height={iconSize}
color={n <= score ? activeColor : voidColor}
className={`${bi('icon')} ${bi('icon--half')}`}
/>
)}
</div>
)) ||
(allowHalf && score < n - 1 && (
<div>
{checkedIcon || (
<StarFillN
width={iconSize}
height={iconSize}
color={voidColor}
className={`${bi('icon')} ${bi('icon--disabled')} ${bi(
'icon--half'
)}`}
/>
)}
</div>
))}
</>
<div
className={classNames(bi('icon'), {
[bi('icon--disabled')]: disabled || n > score,
})}
>
{renderIcon(iconSize, n <= score ? activeColor : voidColor)}
</div>
{allowHalf && score > n - 1 && (
<div
className={` ${bi('half')} ${bi('icon')} ${bi('icon--half')}`}
onClick={(event) => onHalfClick(event, n)}
>
{renderIcon(iconSize, n <= score ? activeColor : voidColor)}
</div>
)}
</div>
)
})}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册