Skip to content
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(badge): v15适配 #2826

Open
wants to merge 15 commits into
base: feat_v3.x
Choose a base branch
from
1 change: 1 addition & 0 deletions migrate-from-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,7 @@ plugins: [
- 修改 `max` 的最大值为99(之前为10000),比较贴合实际场景。
- 主题定制的 `css` 变量中,去掉和 `dot` 有关的其他值,只保留 `width`。其他值由 `width` 计算而来.
- 主题定制,增加包含 icon 情况下的样式变量。
- 新增 `size` 属性,dot 尺寸,当 dot 等于 `true` 时生效
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面的内容是 v2 的,可以删除了。


#### CircleProgress

Expand Down
3 changes: 2 additions & 1 deletion src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@
"sort": 4,
"show": true,
"taro": true,
"v14": true,
"author": "lzz"
},
{
Expand Down Expand Up @@ -1259,4 +1260,4 @@
]
}
]
}
}
5 changes: 3 additions & 2 deletions src/packages/badge/__test__/__snapshots__/badge.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ exports[`should match custom icon 1`] = `
>
<div
class="nut-badge-content nut-badge-icon"
style="top: 0px; right: 0px;"
>
<svg
aria-labelledby="Checklist"
Expand All @@ -32,8 +33,8 @@ exports[`should match snapshot 1`] = `
class="nut-badge"
>
<div
class="nut-badge-content nut-badge-sup nut-badge-one"
style="top: -4px; right: 8px;"
class="nut-badge-sup nut-badge-number nut-badge-one"
style="top: 0px; right: 0px;"
>
8
</div>
Expand Down
27 changes: 10 additions & 17 deletions src/packages/badge/__test__/badge.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ test('should match snapshot', () => {

test('should match value is string', () => {
const { container } = render(<Badge value="new" />)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
const badgeContent = container.querySelectorAll('.nut-badge-sup')[0]
expect(badgeContent).toHaveTextContent('new')
})

test('should match max size', () => {
const { container } = render(<Badge value={200} max={9} />)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
const badgeContent = container.querySelectorAll('.nut-badge-sup')[0]
expect(badgeContent.textContent).toBe('9+')
})

Expand All @@ -29,26 +29,20 @@ test('should match dot', () => {
})

test('should match top、right: bad number', () => {
const { container } = render(<Badge value={10} top="--10" right="0" />)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
expect(badgeContent).toHaveStyle({ top: '0px' })
})

test('should match top、right: have px', () => {
const { container } = render(<Badge value={10} top="-10" right="0" />)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
expect(badgeContent).toHaveStyle({ top: '10px', right: '0px' })
const { container } = render(<Badge value={10} top="10" right="0" />)
const badgeContent = container.querySelectorAll('.nut-badge-sup')[0]
expect(badgeContent).toHaveStyle({ top: '10px' })
})

test('should match top、right: float', () => {
const { container } = render(<Badge value={10} top="-10.8" right="0.5px" />)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
const { container } = render(<Badge value={10} top="10.8" right="0.5" />)
const badgeContent = container.querySelectorAll('.nut-badge-sup')[0]
expect(badgeContent).toHaveStyle({ top: '10.8px', right: '0.5px' })
})

test('should match custom color', () => {
const { container } = render(<Badge value={200} color="orange" />)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
const badgeContent = container.querySelectorAll('.nut-badge-sup')[0]
expect(badgeContent).toHaveStyle({ 'background-color': 'orange' })
})

Expand All @@ -61,10 +55,9 @@ test('should match custom color when fill = outline', () => {
const { container } = render(
<Badge value={200} color="orange" fill="outline" />
)
const badgeContent = container.querySelectorAll('.nut-badge-content')[0]
const badgeContent = container.querySelectorAll('.nut-badge-outline')[0]
expect(badgeContent).toHaveStyle({
border: '1px solid orange',
color: 'orange',
background: '#fff',
background: '#FFFFFF',
})
})
89 changes: 58 additions & 31 deletions src/packages/badge/badge.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,14 @@
position: relative;
display: inline-flex;
width: auto;
/* #ifdef harmony */
min-width: 1px;
/* #endif */
/* #ifndef harmony */
min-width: auto;
/* #endif */

&-icon {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
background: $badge-background-color;
padding: $badge-icon-padding;
text-align: center;
border: $badge-border;
border-radius: $badge-border-radius;
z-index: $badge-z-index;

.nut-icon {
Expand All @@ -27,53 +19,88 @@
}
}

&-sup,
&-icon {
border-radius: $badge-border-radius;
&::after {
content: '';
position: absolute;
top: -50%;
bottom: -50%;
left: -50%;
right: -50%;
transform: scale(0.5);
border: $badge-border;
border-radius: $badge-border-radius;
}
}

&-sup {
height: $badge-height;
position: absolute;
display: flex;
display: inline-flex;
justify-content: center;
align-items: center;
height: $badge-height;
min-width: $badge-min-width;
padding: $badge-padding;
box-sizing: border-box;
color: $badge-color;
font-size: $badge-font-size;
/* #ifdef harmony */
background: $color-primary;
line-height: 12px;
/* #endif */
/* #ifndef harmony */
background: $badge-background-color;
line-height: 11px;
/* #endif */
color: $badge-color;
padding: $badge-padding;
font-size: $badge-font-size;
font-weight: normal;
text-align: center;
border: $badge-border;
border-radius: $badge-border-radius;
min-width: $badge-min-width;
white-space: nowrap;
font-weight: normal;
vertical-align: middle;
background: $badge-background-color;
z-index: 1;
}

&-number {
font-family: 'JD';
line-height: 12px;
}

&-one {
height: $badge-height;
width: $badge-height;
padding: 0;
}

&-content {
/* #ifndef rn */
position: absolute;
transform: $badge-content-transform;
/* #endif */
}

&-dot {
width: $badge-dot-width;
height: $badge-dot-width;
border: $badge-dot-border;
border-radius: $badge-dot-width;
padding: 0;
border-radius: 50%;
&::after {
border: $badge-dot-border;
border-radius: 50%;
}
&-normal {
min-width: $badge-dot-width;
width: $badge-dot-width;
height: $badge-dot-width;
}
&-small {
min-width: $badge-dot-small-width;
width: $badge-dot-small-width;
height: $badge-dot-small-width;
}
&-large {
min-width: $badge-dot-large-width;
width: $badge-dot-large-width;
height: $badge-dot-large-width;
}
}

&-outline {
background: $color-primary-text;
border: 1px solid $color-primary;
color: $color-primary;
&::after {
border: $badge-outline-border;
}
}
}
57 changes: 20 additions & 37 deletions src/packages/badge/badge.taro.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
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 { 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'
import { harmony } from '@/utils/platform-taro'
import { BadgeProps } from './types'

export type BadgeFill = 'solid' | 'outline'
export interface BadgeProps extends BasicComponent {
value: ReactNode
dot: boolean
max: number
top: string | number
right: string | number
color: string
fill: BadgeFill
}
const defaultProps = {
...ComponentDefaults,
value: '',
dot: false,
max: 99,
top: '4',
right: '8',
top: 0,
right: 0,
color: '',
fill: 'solid',
size: 'large',
} as BadgeProps
export const Badge: FunctionComponent<Partial<BadgeProps>> = (props) => {
const rtl = useRtl()
Expand All @@ -47,6 +37,7 @@
right,
color,
fill,
size,
} = {
...defaultProps,
...props,
Expand Down Expand Up @@ -77,48 +68,40 @@
if (typeof value === 'string' && value) return value
}

const contentClasses = classNames(`${classPrefix}-content`, {
const contentClasses = classNames({
[`${classPrefix}-sup`]: isNumber() || isString() || dot,
[`${classPrefix}-number`]: isNumber(),
[`${classPrefix}-one`]:
typeof content() === 'string' && `${content()}`?.length === 1,
[`${classPrefix}-dot`]: dot,
[`${classPrefix}-dot-${size}`]: dot,
[`${classPrefix}-${fill}`]: fill === 'outline',
[`${classPrefix}-content`]: children,
})

useEffect(() => {
if (badgeRef.current) {
getPositionStyle()
}
}, [])

Check warning on line 86 in src/packages/badge/badge.taro.tsx

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has a missing dependency: 'getPositionStyle'. Either include it or remove the dependency array
const getPositionStyle = async () => {
const style: CSSProperties = {}
style.top = pxTransform(-Number(top) || 0)
if (rn()) {
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] = isHarmony
? pxTransform(Number(right))
: `${Number(right) || parseFloat(String(right)) || 0}px`
}
style.top = pxTransform(Number(top) || 0)
const dir = rtl ? 'left' : 'right'
style[dir] = isHarmony
? pxTransform(Number(right))
: `${Number(right) || 0}px`
setContentStyle(style)
}

const getStyle = () => {
const getCustomStyle = () => {
const style: CSSProperties = {}
if (color) {
if (fill === 'outline') {
style.color = color
isHarmony
? (style.backgroundColor = '#fff')
: (style.background = '#fff')
if (!color?.includes('gradient')) {
style.borderColor = color
}
? (style.backgroundColor = '#FFFFFF')
: (style.background = '#FFFFFF')
irisSong marked this conversation as resolved.
Show resolved Hide resolved
} else {
style.color = '#fff'
isHarmony ? (style.backgroundColor = color) : (style.background = color)
Expand All @@ -144,7 +127,7 @@
{!isIcon() && (
<View
className={contentClasses}
style={{ ...contentStyle, ...getStyle() }}
style={{ ...contentStyle, ...getCustomStyle() }}
>
{content()}
</View>
Expand Down
Loading
Loading