-
Notifications
You must be signed in to change notification settings - Fork 266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(radio): v14 #2786
feat(radio): v14 #2786
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,24 @@ | ||||||||||||||||||||||||||||||||||||||||||
import { createElement } from 'react' | ||||||||||||||||||||||||||||||||||||||||||
import { mergeProps } from '@/utils/merge-props' | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
interface IconProps { | ||||||||||||||||||||||||||||||||||||||||||
tag: any | ||||||||||||||||||||||||||||||||||||||||||
classPrefix: string | ||||||||||||||||||||||||||||||||||||||||||
name: 'normal' | 'disabled' | 'checked' | 'checked-disabled' | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+4
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 建议改进 IconProps 接口中 tag 属性的类型定义 目前 建议修改如下: interface IconProps {
- tag: any
+ tag: keyof JSX.IntrinsicElements | React.ComponentType
classPrefix: string
name: 'normal' | 'disabled' | 'checked' | 'checked-disabled'
} 📝 Committable suggestion
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 看这个类型可不可以使用 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @irisSong,可以使用这个类型定义。将 interface IconProps {
tag: keyof JSX.IntrinsicElements | React.ComponentType
classPrefix: string
name: 'normal' | 'disabled' | 'checked' | 'checked-disabled'
} 这样修改后,代码会更加严谨,有助于捕获类型错误。
Comment on lines
+4
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 建议改进 IconProps 接口中 tag 属性的类型定义 目前 建议修改如下: interface IconProps {
- tag: any
+ tag: keyof JSX.IntrinsicElements | React.ComponentType
classPrefix: string
name: 'normal' | 'disabled' | 'checked' | 'checked-disabled'
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
const Icon = (props: Partial<IconProps>) => { | ||||||||||||||||||||||||||||||||||||||||||
const { tag, classPrefix, name } = mergeProps( | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
tag: 'div', | ||||||||||||||||||||||||||||||||||||||||||
classPrefix: 'nut-radio-self', | ||||||||||||||||||||||||||||||||||||||||||
name: 'normal', | ||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||
props | ||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||
return createElement<{ className: string }>(tag, { | ||||||||||||||||||||||||||||||||||||||||||
className: `${classPrefix} ${classPrefix}-${name}`, | ||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
export default Icon |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,11 @@ | ||
import React, { FC, useContext } from 'react' | ||
import { | ||
CheckChecked, | ||
CheckDisabled, | ||
CheckNormal, | ||
} from '@nutui/icons-react-taro' | ||
import classNames, { Mapping } from 'classnames' | ||
import { ITouchEvent, View } from '@tarojs/components' | ||
import RadioContext from '../radiogroup/context' | ||
import { BasicComponent, ComponentDefaults } from '@/utils/typings' | ||
import { usePropsValue } from '@/utils/use-props-value' | ||
import { RadioPosition, RadioShape } from '@/packages/radio/types' | ||
import Icon from '@/packages/radio/icon' | ||
|
||
export interface RadioProps extends BasicComponent { | ||
disabled: boolean | ||
|
@@ -88,26 +84,33 @@ export const Radio: FC< | |
} | ||
const renderIcon = () => { | ||
const { icon, activeIcon } = props | ||
|
||
function renderIconByDisabledProperty() { | ||
return disabled ? ( | ||
<Icon name="checked-disabled" tag={View} /> | ||
) : ( | ||
<Icon name="checked" tag={View} /> | ||
) | ||
} | ||
|
||
if (disabled && !checkedStatement) { | ||
return <CheckDisabled className={classNames(color())} /> | ||
return <Icon name="disabled" tag={View} /> | ||
} | ||
if (checkedStatement) { | ||
return React.isValidElement(activeIcon) ? ( | ||
React.cloneElement<any>(activeIcon, { | ||
...activeIcon.props, | ||
className: classNames(color()), | ||
}) | ||
) : ( | ||
<CheckChecked className={classNames(color())} /> | ||
) | ||
return React.isValidElement(activeIcon) | ||
? React.cloneElement<any>(activeIcon, { | ||
...activeIcon.props, | ||
className: classNames(color()), | ||
}) | ||
: renderIconByDisabledProperty() | ||
} | ||
return React.isValidElement(icon) ? ( | ||
React.cloneElement<any>(icon, { | ||
...icon.props, | ||
className: classNames(color()), | ||
}) | ||
) : ( | ||
<CheckNormal className={classNames(color())} /> | ||
<Icon name="normal" tag={View} /> | ||
Comment on lines
+95
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 优化图标渲染逻辑的条件判断 当前的条件判断结构较为复杂,建议重构以提高可读性和可维护性。 建议采用以下方式重构: - if (disabled && !checkedStatement) {
- return <Icon name="disabled" tag={View} />
- }
- if (checkedStatement) {
- return React.isValidElement(activeIcon)
- ? React.cloneElement<any>(activeIcon, {
- ...activeIcon.props,
- className: classNames(color()),
- })
- : renderIconByDisabledProperty()
- }
- return React.isValidElement(icon) ? (
- React.cloneElement<any>(icon, {
- ...icon.props,
- className: classNames(color()),
- })
- ) : (
- <Icon name="normal" tag={View} />
- )
+ const getIcon = () => {
+ if (disabled && !checkedStatement) return 'disabled'
+ if (checkedStatement) return disabled ? 'checked-disabled' : 'checked'
+ return 'normal'
+ }
+
+ const customIcon = checkedStatement ? activeIcon : icon
+ if (React.isValidElement(customIcon)) {
+ return React.cloneElement<any>(customIcon, {
+ ...customIcon.props,
+ className: classNames(color()),
+ })
+ }
+
+ return <Icon name={getIcon()} tag={View} />
|
||
) | ||
} | ||
const renderLabel = () => { | ||
|
@@ -117,7 +120,7 @@ export const Radio: FC< | |
return ( | ||
<> | ||
{renderIcon()} | ||
<View className={labelcls}>{children}</View> | ||
{children ? <View className={labelcls}>{children}</View> : null} | ||
</> | ||
) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
import React, { FunctionComponent, MouseEventHandler, useContext } from 'react' | ||
import { CheckChecked, CheckNormal, CheckDisabled } from '@nutui/icons-react' | ||
import classNames from 'classnames' | ||
import RadioContext from '../radiogroup/context' | ||
import { BasicComponent, ComponentDefaults } from '@/utils/typings' | ||
import { usePropsValue } from '@/utils/use-props-value' | ||
import { RadioPosition, RadioShape } from '@/packages/radio/types' | ||
import Icon from '@/packages/radio/icon' | ||
|
||
export interface RadioProps extends BasicComponent { | ||
disabled: boolean | ||
|
@@ -83,26 +83,33 @@ export const Radio: FunctionComponent< | |
} | ||
const renderIcon = () => { | ||
const { icon, activeIcon } = props | ||
|
||
function renderIconByDisabledProperty() { | ||
return disabled ? ( | ||
<Icon name="checked-disabled" /> | ||
) : ( | ||
<Icon name="checked" /> | ||
) | ||
} | ||
|
||
if (disabled && !checkedStatement) { | ||
return <CheckDisabled className={classNames(color())} /> | ||
return <Icon name="disabled" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 建议统一图标渲染的条件判断结构 当前的条件判断结构较为分散,建议统一处理逻辑以提高可读性。 建议重构为: -if (disabled && !checkedStatement) {
- return <Icon name="disabled" />
-}
-if (checkedStatement) {
- return React.isValidElement(activeIcon)
- ? React.cloneElement<any>(activeIcon, {
- ...activeIcon.props,
- className: classNames(color()),
- })
- : renderIconByDisabledProperty()
-}
-return React.isValidElement(icon) ? (
- React.cloneElement<any>(icon, {
- ...icon.props,
- className: classNames(color()),
- })
-) : (
- <Icon name="normal" />
-)
+const renderIcon = () => {
+ if (disabled && !checkedStatement) {
+ return <Icon name="disabled" />
+ }
+
+ const currentIcon = checkedStatement ? activeIcon : icon
+ if (React.isValidElement(currentIcon)) {
+ return React.cloneElement<any>(currentIcon, {
+ ...currentIcon.props,
+ className: classNames(color()),
+ })
+ }
+
+ if (checkedStatement) {
+ return renderCheckedIcon()
+ }
+
+ return <Icon name="normal" />
+} Also applies to: 99-104, 112-112 |
||
} | ||
if (checkedStatement) { | ||
return React.isValidElement(activeIcon) ? ( | ||
React.cloneElement<any>(activeIcon, { | ||
...activeIcon.props, | ||
className: classNames(color()), | ||
}) | ||
) : ( | ||
<CheckChecked className={classNames(color())} /> | ||
) | ||
return React.isValidElement(activeIcon) | ||
? React.cloneElement<any>(activeIcon, { | ||
...activeIcon.props, | ||
className: classNames(color()), | ||
}) | ||
: renderIconByDisabledProperty() | ||
} | ||
return React.isValidElement(icon) ? ( | ||
React.cloneElement<any>(icon, { | ||
...icon.props, | ||
className: classNames(color()), | ||
}) | ||
) : ( | ||
<CheckNormal className={classNames(color())} /> | ||
<Icon name="normal" /> | ||
Comment on lines
+94
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 建议简化图标渲染逻辑 当前的图标渲染逻辑包含多层嵌套条件,可以通过提取通用逻辑来简化代码。 建议重构如下: -if (disabled && !checkedStatement) {
- return <Icon name="disabled" />
-}
-if (checkedStatement) {
- return React.isValidElement(activeIcon)
- ? React.cloneElement<any>(activeIcon, {
- ...activeIcon.props,
- className: classNames(color()),
- })
- : renderIconByDisabledProperty()
-}
-return React.isValidElement(icon) ? (
- React.cloneElement<any>(icon, {
- ...icon.props,
- className: classNames(color()),
- })
-) : (
- <Icon name="normal" />
-)
+const iconName = getIconName(disabled, checkedStatement)
+const customIcon = checkedStatement ? activeIcon : icon
+
+return React.isValidElement(customIcon)
+ ? React.cloneElement<any>(customIcon, {
+ ...customIcon.props,
+ className: classNames(color()),
+ })
+ : <Icon name={iconName} /> 需要在组件外部添加辅助函数: function getIconName(disabled: boolean, checked: boolean): string {
if (disabled && !checked) return 'disabled'
if (checked) return disabled ? 'checked-disabled' : 'checked'
return 'normal'
} |
||
) | ||
} | ||
const renderLabel = () => { | ||
|
@@ -112,7 +119,7 @@ export const Radio: FunctionComponent< | |
return ( | ||
<> | ||
{renderIcon()} | ||
<div className={labelcls}>{children}</div> | ||
{children ? <div className={labelcls}>{children}</div> : null} | ||
</> | ||
) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个不支持了吗