Skip to content

Commit cdb5b71

Browse files
jby0107jarmywang
andauthored
fix(badge): fix ribbon overflow (Tencent#3074)
* fix(badge): fixed the overflow problem of ribbon badge fix Tencent#3063 * fix(badge): update snap * chore: update snap * fix(badge): create badge shape with clip-path, fixing the precision issue of the current method * refactor(badge): simplifie inline style * fix(badge): update snap --------- Co-authored-by: jarmywang <awangjianjun9@gmail.com>
1 parent f500334 commit cdb5b71

File tree

3 files changed

+26
-37
lines changed

3 files changed

+26
-37
lines changed

src/badge/badge.less

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
.@{prefix}-badge {
2121
position: relative;
22-
display: inline-block;
23-
vertical-align: top;
22+
display: inline-flex;
23+
align-items: start;
2424

2525
&--basic {
2626
z-index: 100;
@@ -55,35 +55,16 @@
5555
&__ribbon {
5656
&-outer {
5757
position: absolute;
58+
overflow: hidden;
5859
top: 0;
5960
right: 0;
60-
}
61-
62-
&--before,
63-
&--after {
64-
content: '';
65-
position: absolute;
66-
width: 0;
67-
height: 0;
68-
bottom: 0;
69-
border-bottom: @badge-basic-height solid @badge-color;
70-
}
71-
72-
&--before {
73-
left: calc(-1 * @badge-basic-height + 1rpx);
74-
border-left: @badge-basic-height solid transparent;
75-
}
76-
77-
&--after {
78-
right: calc(-1 * @badge-basic-height + 1rpx);
79-
border-right: @badge-basic-height solid transparent;
61+
background-color: @badge-color;
8062
}
8163
}
8264

8365
&--ribbon {
8466
display: inline-block;
85-
transform: rotate(45deg);
86-
transform-origin: center center;
67+
transform-origin: top left;
8768
border-radius: 0;
8869
// padding: 0;
8970
}

src/badge/badge.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { SuperComponent, wxComponent } from '../common/src/index';
22
import config from '../common/config';
33
import props from './props';
44
import type { TdBadgeProps } from './type';
5-
import { uniqueFactory } from '../common/utils';
5+
import { getRect, uniqueFactory } from '../common/utils';
66

77
const { prefix } = config;
88
const name = `${prefix}-badge`;
@@ -26,11 +26,29 @@ export default class Badge extends SuperComponent {
2626
value: '',
2727
labelID: '',
2828
descriptionID: '',
29+
// ribbon
30+
ribbonStyle: '',
31+
ribbonOuterStyle: '',
2932
};
3033

3134
lifetimes = {
3235
ready() {
3336
const uniqueID = getUniqueID();
37+
if (this.properties.shape === 'ribbon') {
38+
getRect(this, `.${prefix}-badge--ribbon`).then((rect) => {
39+
const outerBoundingRect = rect.width / Math.SQRT2 + rect.height * Math.SQRT2; // 外接矩形的宽度:height * cos45deg + width / cos45deg
40+
const translateX = rect.width - rect.width / Math.SQRT2 + outerBoundingRect - rect.width; // 旋转后的位移:原宽度 - 旋转后的宽度 + 外接矩形的宽度 - 原宽度
41+
const ribbonHeightHypotenuse = rect.height * Math.SQRT2; // 斜边的长度:height * sin45deg
42+
const ribbonWidthCatheti = rect.width / Math.SQRT2; // 直角边的长度:width / sin45deg
43+
this.setData({
44+
ribbonStyle: `transform: translateX(${translateX}px) rotate(45deg);`,
45+
ribbonOuterStyle: `width: ${outerBoundingRect}px; height: ${outerBoundingRect}px;
46+
clip-path: polygon(0 0, ${ribbonHeightHypotenuse}px 0,
47+
${outerBoundingRect}px ${ribbonWidthCatheti}px,
48+
${outerBoundingRect}px ${ribbonWidthCatheti + ribbonHeightHypotenuse}px);`,
49+
});
50+
});
51+
}
3452

3553
this.setData({
3654
labelID: `${uniqueID}_label`,

src/badge/badge.wxml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
-->
99

1010
<view
11-
style="{{_._style([style, customStyle])}}"
11+
style="{{_._style([style, customStyle, ribbonOuterStyle])}}"
1212
class="{{this.getBadgeOuterClass({shape})}} class {{prefix}}-class"
1313
aria-labelledby="{{labelID}}"
1414
aria-describedby="{{descriptionID}}"
@@ -24,21 +24,11 @@
2424
wx:if="{{this.isShowBadge({dot,count,showZero})}}"
2525
id="{{descriptionID}}"
2626
class="{{this.getBadgeInnerClass({dot, size, shape, count})}} {{prefix}}-has-count {{prefix}}-class-count"
27-
style="{{this.getBadgeStyles({color, offset})}}"
27+
style="{{_._style([this.getBadgeStyles({color, offset}), ribbonStyle])}}"
2828
aria-hidden="true"
2929
aria-label="{{ ariaLabel || _.getBadgeAriaLabel({dot, count, maxCount}) }}"
3030
>
31-
<view
32-
wx:if="{{shape == 'ribbon'}}"
33-
class="t-badge__ribbon--before"
34-
style="{{color ? 'border-color: ' + color : ''}}"
35-
/>
3631
{{ this.getBadgeValue({dot, count, maxCount}) }}
37-
<view
38-
wx:if="{{shape == 'ribbon'}}"
39-
class="t-badge__ribbon--after"
40-
style="{{color ? 'border-color: ' + color : ''}}"
41-
/>
4232
</view>
4333
<slot name="count" />
4434
</view>

0 commit comments

Comments
 (0)