-
Notifications
You must be signed in to change notification settings - Fork 255
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
fix(badge): 四端适配 #2620
base: dev-harmony
Are you sure you want to change the base?
fix(badge): 四端适配 #2620
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 | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1,8 +1,18 @@ | ||||||||||
import React, { CSSProperties, FunctionComponent, ReactNode } from 'react' | ||||||||||
import React, { | ||||||||||
CSSProperties, | ||||||||||
FunctionComponent, | ||||||||||
ReactNode, | ||||||||||
useEffect, | ||||||||||
useRef, | ||||||||||
useState, | ||||||||||
} from 'react' | ||||||||||
import classNames from 'classnames' | ||||||||||
import { View } from '@tarojs/components' | ||||||||||
import { BasicComponent, ComponentDefaults } from '@/utils/typings' | ||||||||||
import { useRtl } from '@/packages/configprovider/index.taro' | ||||||||||
import pxTransform from '@/utils/px-transform' | ||||||||||
import { getRectByTaro } from '@/utils/get-rect-by-taro' | ||||||||||
import { harmony, rn } from '@/utils/platform-taro' | ||||||||||
|
||||||||||
export type BadgeFill = 'solid' | 'outline' | ||||||||||
export interface BadgeProps extends BasicComponent { | ||||||||||
|
@@ -42,9 +52,9 @@ export const Badge: FunctionComponent<Partial<BadgeProps>> = (props) => { | |||||||||
...props, | ||||||||||
} | ||||||||||
const classPrefix = 'nut-badge' | ||||||||||
const classes = classNames(classPrefix, className, { | ||||||||||
[`${classPrefix}-${fill}`]: fill === 'outline', | ||||||||||
}) | ||||||||||
const classes = classNames(classPrefix, className) | ||||||||||
const badgeRef = useRef(null) | ||||||||||
const [contentStyle, setContentStyle] = useState({}) | ||||||||||
|
||||||||||
function content() { | ||||||||||
if (dot || typeof value === 'object' || value === 0) return null | ||||||||||
|
@@ -66,41 +76,73 @@ export const Badge: FunctionComponent<Partial<BadgeProps>> = (props) => { | |||||||||
if (typeof value === 'string' && value) return value | ||||||||||
} | ||||||||||
|
||||||||||
const contentClasses = classNames( | ||||||||||
{ [`${classPrefix}-dot`]: dot }, | ||||||||||
`${classPrefix}-content`, | ||||||||||
{ [`${classPrefix}-sup`]: isNumber() || isString() || dot }, | ||||||||||
{ | ||||||||||
[`${classPrefix}-one`]: | ||||||||||
typeof content() === 'string' && `${content()}`?.length === 1, | ||||||||||
const contentClasses = classNames(`${classPrefix}-content`, { | ||||||||||
[`${classPrefix}-sup`]: isNumber() || isString() || dot, | ||||||||||
[`${classPrefix}-one`]: | ||||||||||
typeof content() === 'string' && `${content()}`?.length === 1, | ||||||||||
[`${classPrefix}-dot`]: dot, | ||||||||||
[`${classPrefix}-${fill}`]: fill === 'outline', | ||||||||||
}) | ||||||||||
|
||||||||||
useEffect(() => { | ||||||||||
if (badgeRef.current) { | ||||||||||
getPositionStyle() | ||||||||||
} | ||||||||||
) | ||||||||||
const getStyle = () => { | ||||||||||
}, [badgeRef.current]) | ||||||||||
const getPositionStyle = async () => { | ||||||||||
const style: CSSProperties = {} | ||||||||||
style.top = `${Number(top) || parseFloat(String(top)) || 0}px` | ||||||||||
const dir = rtl ? 'left' : 'right' | ||||||||||
style[dir] = `${Number(right) || parseFloat(String(right)) || 0}px` | ||||||||||
style.top = pxTransform(Number(-top) || 0) | ||||||||||
if (rn()) { | ||||||||||
Comment on lines
+94
to
+95
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. [问题] 'style.top' 的计算方式可能不正确 在第 94 行, 建议先将 修改为: - style.top = pxTransform(Number(-top) || 0)
+ style.top = pxTransform(-Number(top) || 0) 📝 Committable suggestion
Suggested change
|
||||||||||
const reacts = await getRectByTaro(badgeRef.current) | ||||||||||
style.left = | ||||||||||
reacts?.width && reacts?.width > Number(right) | ||||||||||
? pxTransform(reacts.width - Number(right)) | ||||||||||
: 0 | ||||||||||
} else { | ||||||||||
const dir = rtl ? 'left' : 'right' | ||||||||||
style[dir] = harmony() | ||||||||||
? pxTransform(Number(right)) | ||||||||||
: `${Number(right) || parseFloat(String(right)) || 0}px` | ||||||||||
} | ||||||||||
setContentStyle(style) | ||||||||||
} | ||||||||||
|
||||||||||
const getStyle = () => { | ||||||||||
const style: CSSProperties = {} | ||||||||||
if (color) { | ||||||||||
if (fill === 'outline') { | ||||||||||
style.color = color | ||||||||||
style.background = '#fff' | ||||||||||
style.backgroundColor = '#fff' | ||||||||||
if (!color?.includes('gradient')) { | ||||||||||
style.border = `1px solid ${color}` | ||||||||||
style.borderColor = color | ||||||||||
Comment on lines
+115
to
+117
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 [建议] 避免在样式中硬编码颜色值,提升组件的可定制性 在第 115 行, 建议允许通过属性传入背景颜色,或者使用一个默认值,同时提供自定义的可能性: - style.backgroundColor = '#fff'
+ style.backgroundColor = backgroundColor || '#fff' 并在 export interface BadgeProps extends BasicComponent {
// 其他属性...
backgroundColor?: string
} |
||||||||||
} | ||||||||||
} else { | ||||||||||
style.color = '#fff' | ||||||||||
style.background = color | ||||||||||
style.backgroundColor = color | ||||||||||
} | ||||||||||
} | ||||||||||
return style | ||||||||||
} | ||||||||||
|
||||||||||
return ( | ||||||||||
<View className={classes} style={style}> | ||||||||||
{isIcon() && <View className={`${classPrefix}-icon`}>{value}</View>} | ||||||||||
<View className={classes} style={style} ref={badgeRef}> | ||||||||||
{isIcon() && ( | ||||||||||
<View | ||||||||||
className={classNames(`${classPrefix}-content`, { | ||||||||||
[`${classPrefix}-icon`]: true, | ||||||||||
[`${classPrefix}-icon-rtl`]: rtl, | ||||||||||
})} | ||||||||||
style={contentStyle} | ||||||||||
> | ||||||||||
{value} | ||||||||||
</View> | ||||||||||
)} | ||||||||||
{children} | ||||||||||
{!isIcon() && ( | ||||||||||
<View className={contentClasses} style={getStyle()}> | ||||||||||
<View | ||||||||||
className={contentClasses} | ||||||||||
style={{ ...contentStyle, ...getStyle() }} | ||||||||||
> | ||||||||||
{content()} | ||||||||||
</View> | ||||||||||
)} | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,32 @@ | ||
import { User } from '@nutui/icons-react-taro' | ||
import { Avatar, Badge, Cell } from '@nutui/nutui-react-taro' | ||
import React from 'react' | ||
import pxTransform from '@/utils/px-transform' | ||
import { harmonyAndRn } from '@/utils/platform-taro' | ||
|
||
const Demo2 = () => { | ||
const isRnAndHarmony = harmonyAndRn() | ||
const renderChildren = () => { | ||
return ( | ||
<> | ||
{isRnAndHarmony ? ( | ||
<Avatar shape="square">N</Avatar> | ||
) : ( | ||
<Avatar icon={<User />} shape="square" /> | ||
)} | ||
</> | ||
) | ||
} | ||
return ( | ||
<Cell> | ||
<Badge style={{ marginInlineEnd: '40px' }} value={200} max={9}> | ||
<Avatar icon={<User />} shape="square" /> | ||
<Badge style={{ marginRight: pxTransform(40) }} value={200} max={9}> | ||
{renderChildren()} | ||
</Badge> | ||
<Badge style={{ marginInlineEnd: '40px' }} value={200} max={20}> | ||
<Avatar icon={<User />} shape="square" /> | ||
<Badge style={{ marginRight: pxTransform(40) }} value={200} max={20}> | ||
{renderChildren()} | ||
</Badge> | ||
<Badge style={{ marginInlineEnd: '40px' }} value={200} max={99}> | ||
<Avatar icon={<User />} shape="square" /> | ||
<Badge style={{ marginRight: pxTransform(40) }} value={200} max={99}> | ||
{renderChildren()} | ||
Comment on lines
+22
to
+29
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. 💡 Codebase verification 确认修改有效,但发现其他文件仍使用 此次对
🔗 Analysis chainBadge 组件更新提高了代码复用性,但需注意 RTL 布局 Badge 组件的更新很好地利用了 然而,将
import { I18nManager } from 'react-native';
// ...
<Badge
style={{
[I18nManager.isRTL ? 'marginLeft' : 'marginRight']: pxTransform(40),
}}
value={200}
max={9}
>
{renderChildren()}
</Badge>
为了确保这个变更不会影响其他使用 为了确保代码库中没有其他地方使用 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# 描述:检查代码库中是否还有其他地方使用了 marginInlineEnd
rg --type typescript --type javascript 'marginInlineEnd'
Length of output: 91 Script: #!/bin/bash
# 描述:检查代码库中是否还有其他地方使用了 marginInlineEnd
rg 'marginInlineEnd' -g '*.ts' -g '*.tsx'
Length of output: 4985 |
||
</Badge> | ||
</Cell> | ||
) | ||
|
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.
[问题] 使用 'badgeRef.current' 作为 useEffect 的依赖可能无法如预期工作
在第 87-91 行,使用
badgeRef.current
作为useEffect
的依赖项可能不会在badgeRef.current
变化时触发更新。React 的useRef
的current
属性变化不会引发组件重新渲染,因此依赖于它的useEffect
可能无法按预期执行。建议修改为在组件挂载后执行一次,或者根据需要使用其他依赖项触发
getPositionStyle
。可以将依赖数组改为空数组,确保在组件挂载后执行一次:
📝 Committable suggestion