-
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 all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ import Demo3 from './demos/taro/demo3' | |
import Demo4 from './demos/taro/demo4' | ||
import Demo5 from './demos/taro/demo5' | ||
import Demo6 from './demos/taro/demo6' | ||
import Demo7 from './demos/taro/demo7' | ||
import Demo8 from './demos/taro/demo8' | ||
import Demo9 from './demos/taro/demo9' | ||
import Demo10 from './demos/taro/demo10' | ||
|
@@ -23,7 +22,6 @@ const RadioDemo = () => { | |
'74fc5d8a': '基础用法', | ||
bb7486f4: '选项', | ||
c1bae1ec: '水平使用', | ||
'8a2e2847': '自定义尺寸', | ||
'70ffa5d8': '自定义图标', | ||
'70ffa5d9': '自定义图标,通过Group实现列表形式', | ||
'0f261484': '触发事件', | ||
|
@@ -37,7 +35,6 @@ const RadioDemo = () => { | |
'74fc5d8a': '基礎用法', | ||
bb7486f4: '選項', | ||
c1bae1ec: '水準使用', | ||
'8a2e2847': '自定義尺寸', | ||
'70ffa5d8': '自定義圖標', | ||
'70ffa5d9': '自定義圖標,通過Group實現列表形式', | ||
'0f261484': '觸發事件', | ||
|
@@ -51,7 +48,6 @@ const RadioDemo = () => { | |
'74fc5d8a': 'Basic Usage', | ||
bb7486f4: 'Options', | ||
c1bae1ec: 'Horizontal use', | ||
'8a2e2847': 'Custom size', | ||
'70ffa5d8': 'Custom Icon', | ||
'70ffa5d9': 'Custom Icon, render list in Group mode', | ||
'0f261484': 'Trigger Event', | ||
|
@@ -87,10 +83,6 @@ const RadioDemo = () => { | |
</Cell> | ||
<View className="h2">{translated.c1bae1ec}</View> | ||
<Demo6 /> | ||
<View className="h2">{translated['8a2e2847']}</View> | ||
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. 这个不支持了吗 |
||
<Cell> | ||
<Demo7 /> | ||
</Cell> | ||
<View className="h2">{translated['70ffa5d8']}</View> | ||
<Cell> | ||
<Demo8 /> | ||
|
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 @@ | |
} | ||
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 @@ | |
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.
💡 Codebase verification
测试用例中的类名与组件实现不一致
根据 Radio 组件的源码实现,选中状态使用的是
nut-radio-icon-checked
类名,而不是测试用例中使用的nut-radio-self-checked
。测试用例需要更新以匹配实际的组件实现。src/packages/radio/__test__/radio.spec.tsx
中,将.nut-radio-self-checked
更改为.nut-radio-icon-checked
🔗 Analysis chain
请验证选中状态的类名更改是否与组件实现一致
测试用例中将选中状态的类名从
nut-icon-CheckChecked
更改为nut-radio-self-checked
,这个改动需要确保与 Radio 组件的实现保持同步。Let me gather more information about the Radio component implementation to verify the class name change.
Let me try a different approach to find the class name usage in the Radio component.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 263
Script:
Length of output: 66
Script:
Length of output: 4313