uview-plus 3.8.113 → 3.8.119

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,38 +8,41 @@
8
8
  <view class="u-tabbar-item__content" :class="contentClassNames">
9
9
  <view class="u-tabbar-item__bubble" :class="bubbleClassNames">
10
10
  <view
11
+ ref="u-tabbar-item__icon--mid-button"
11
12
  class="u-tabbar-item__icon"
12
13
  :class="iconClassNames"
13
14
  >
14
- <view v-if="isMidButton" class="u-tabbar-item__mid-button-border">
15
+ <view v-if="isMidButton" class="u-tabbar-item__mid-button-border" :style="midButtonBorderStyle">
15
16
  <view class="u-tabbar-item__mid-button-border-circle" :style="midButtonBorderCircleStyle"></view>
16
17
  </view>
17
18
  <view v-if="isMidButton" class="u-tabbar-item__mid-button-inner"></view>
18
- <up-icon
19
- v-if="resolvedIconName"
20
- :name="resolvedIconName"
21
- :color="isMidButton ? resolvedMidButtonIconColor : (isActive ? resolvedActiveColor : resolvedInactiveColor)"
22
- :size="isMidButton ? midButtonIconSize : 24"
23
- :customStyle="midButtonIconStyle"
24
- ></up-icon>
25
- <template v-else>
26
- <slot
27
- v-if="isActive"
28
- name="active-icon"
29
- />
30
- <slot
31
- v-else
32
- name="inactive-icon"
33
- />
34
- </template>
35
- <u-badge
36
- absolute
37
- :offset="[0, dot ? '34rpx' : badge > 9 ? '14rpx' : '20rpx']"
38
- :customStyle="badgeStyle"
39
- :isDot="dot"
40
- :value="badge || (dot ? 1 : null)"
41
- :show="dot || badge > 0"
42
- ></u-badge>
19
+ <view class="u-tabbar-item__icon-content" :class="iconContentClassNames">
20
+ <up-icon
21
+ v-if="resolvedIconName"
22
+ :name="resolvedIconName"
23
+ :color="isMidButton ? resolvedMidButtonIconColor : (isActive ? resolvedActiveColor : resolvedInactiveColor)"
24
+ :size="isMidButton ? midButtonIconSize : 24"
25
+ :customStyle="midButtonIconStyle"
26
+ ></up-icon>
27
+ <template v-else>
28
+ <slot
29
+ v-if="isActive"
30
+ name="active-icon"
31
+ />
32
+ <slot
33
+ v-else
34
+ name="inactive-icon"
35
+ />
36
+ </template>
37
+ <u-badge
38
+ absolute
39
+ :offset="[0, dot ? '34rpx' : badge > 9 ? '14rpx' : '20rpx']"
40
+ :customStyle="badgeStyle"
41
+ :isDot="dot"
42
+ :value="badge || (dot ? 1 : null)"
43
+ :show="dot || badge > 0"
44
+ ></u-badge>
45
+ </view>
43
46
  </view>
44
47
 
45
48
  <slot name="text">
@@ -62,7 +65,8 @@
62
65
  import { props } from './props';
63
66
  import { mpMixin } from '../../libs/mixin/mpMixin';
64
67
  import { mixin } from '../../libs/mixin/mixin';
65
- import { addStyle, error } from '../../libs/function/index';
68
+ import { addStyle, error, sleep } from '../../libs/function/index';
69
+ import { calculateMidButtonBorderClipHeight } from './midButtonGeometry';
66
70
  /**
67
71
  * TabbarItem 底部导航栏子组件
68
72
  * @description 此组件提供了自定义tabbar的能力。
@@ -73,6 +77,13 @@
73
77
  * @property {Boolean} dot 是否显示圆点,将会覆盖badge参数(默认 false )
74
78
  * @property {String} text 描述文本
75
79
  * @property {Object | String} badgeStyle 控制徽标的位置,对象或者字符串形式,可以设置top和right属性(默认 'top: 6px;right:2px;' )
80
+ * @property {String} mode 模式,默认普通模式,midButton中间按钮模式
81
+ * @property {String} midButtonBgColor 中间按钮背景色
82
+ * @property {String} midButtonIconColor 中间按钮图标颜色
83
+ * @property {String | Number} midButtonIconSize 中间按钮图标大小(默认 26 )
84
+ * @property {String} midButtonBoxShadow 中间按钮外层阴影
85
+ * @property {String} midButtonInnerBoxShadow 中间按钮内层阴影
86
+ * @property {String | Number} midButtonOffsetY 中间按钮垂直偏移,负值为上移(默认 -10 )
76
87
  * @property {Object} customStyle 定义需要用到的外部样式
77
88
  *
78
89
  * @example <u-tabbar :value="value2" :placeholder="false" @change="name => value2 = name" :fixed="false" :safeAreaInsetBottom="false"><u-tabbar-item text="首页" icon="home" dot ></u-tabbar-item></u-tabbar>
@@ -83,6 +94,7 @@
83
94
  data() {
84
95
  return {
85
96
  isActive: false, // 是否处于激活状态
97
+ midButtonBorderClipHeightValue: 0,
86
98
  parentData: {
87
99
  value: null,
88
100
  activeColor: '',
@@ -94,7 +106,9 @@
94
106
  itemShape: 'default',
95
107
  iconScale: 1.1,
96
108
  textMode: 'always',
97
- borderColor: ''
109
+ borderColor: '',
110
+ border: true,
111
+ midButtonBorderTopOffset: 0.25
98
112
  }
99
113
  }
100
114
  },
@@ -154,9 +168,12 @@
154
168
  return `${this.resolvedMidButtonOffsetY}px`
155
169
  },
156
170
  midButtonBorderClipHeight() {
157
- const clipBaseHeight = this.hasMidButtonText ? 15.5 : 7
158
- const clipHeight = clipBaseHeight - this.resolvedMidButtonOffsetY
159
- return `${Math.min(Math.max(clipHeight, 0), 64)}px`
171
+ return `${this.midButtonBorderClipHeightValue}px`
172
+ },
173
+ midButtonBorderStyle() {
174
+ return {
175
+ height: this.midButtonBorderClipHeight
176
+ }
160
177
  },
161
178
  midButtonBorderCircleStyle() {
162
179
  return this.isMidButton && this.parentData.borderColor
@@ -180,7 +197,15 @@
180
197
  return [
181
198
  this.isMidButton ? 'u-tabbar-item__icon--mid-button' : '',
182
199
  `u-tabbar-item__icon--${this.resolvedStyleType}`,
183
- this.isActive && this.resolvedAnimationType !== 'none' ? `u-tabbar-item__icon--anim-${this.resolvedAnimationType}` : ''
200
+ this.isActive && this.resolvedAnimationType !== 'none' && !this.isMidButton ? `u-tabbar-item__icon--anim-${this.resolvedAnimationType}` : ''
201
+ ]
202
+ },
203
+ iconContentClassNames() {
204
+ return [
205
+ this.isMidButton ? 'u-tabbar-item__icon-content--mid-button' : '',
206
+ this.isMidButton && this.isActive && this.resolvedAnimationType !== 'none'
207
+ ? `u-tabbar-item__icon-content--anim-${this.resolvedAnimationType}`
208
+ : ''
184
209
  ]
185
210
  },
186
211
  contentClassNames() {
@@ -213,6 +238,20 @@
213
238
  created() {
214
239
  this.init()
215
240
  },
241
+ mounted() {
242
+ this.scheduleMidButtonBorderMeasure()
243
+ },
244
+ watch: {
245
+ mode() {
246
+ this.scheduleMidButtonBorderMeasure()
247
+ },
248
+ text() {
249
+ this.scheduleMidButtonBorderMeasure()
250
+ },
251
+ midButtonOffsetY() {
252
+ this.scheduleMidButtonBorderMeasure()
253
+ }
254
+ },
216
255
  emits: ["click", "change"],
217
256
  methods: {
218
257
  addStyle,
@@ -235,6 +274,28 @@
235
274
  updateFromParent() {
236
275
  // 重新初始化
237
276
  this.init()
277
+ this.scheduleMidButtonBorderMeasure()
278
+ },
279
+ scheduleMidButtonBorderMeasure() {
280
+ if (!this.isMidButton) return
281
+ this.$nextTick(() => this.updateMidButtonBorderClip())
282
+ },
283
+ async updateMidButtonBorderClip() {
284
+ if (!this.isMidButton || !this.parent) return
285
+ await sleep(20)
286
+ const [contentRect, circleRect] = await Promise.all([
287
+ this.parent.$uGetRect('.u-tabbar__content'),
288
+ this.$uGetRect('.u-tabbar-item__icon--mid-button')
289
+ ])
290
+ if ([contentRect, circleRect].some(rect => !rect || !Number.isFinite(rect.top) || rect.height <= 0)) return
291
+ const clipHeight = calculateMidButtonBorderClipHeight({
292
+ contentTop: contentRect.top,
293
+ circleTop: circleRect.top,
294
+ borderTopOffset: this.parentData.border ? this.parentData.midButtonBorderTopOffset : 0
295
+ })
296
+ if (clipHeight !== this.midButtonBorderClipHeightValue) {
297
+ this.midButtonBorderClipHeightValue = clipHeight
298
+ }
238
299
  },
239
300
  clickHandler() {
240
301
  this.$nextTick(() => {
@@ -281,6 +342,19 @@
281
342
  width: 100%;
282
343
  }
283
344
 
345
+ &-content {
346
+ @include flex;
347
+ align-items: center;
348
+ justify-content: center;
349
+
350
+ &--mid-button {
351
+ position: relative;
352
+ z-index: 2;
353
+ width: 100%;
354
+ height: 100%;
355
+ }
356
+ }
357
+
284
358
  &--anim-scale {
285
359
  transform: scale(var(--up-tabbar-icon-scale, 1.1));
286
360
  }
@@ -402,7 +476,7 @@
402
476
  transform: none;
403
477
  }
404
478
 
405
- .u-tabbar-item--lift.u-tabbar-item--active .u-tabbar-item__icon {
479
+ .u-tabbar-item--lift.u-tabbar-item--active .u-tabbar-item__icon:not(.u-tabbar-item__icon--mid-button) {
406
480
  transform: translateY(-6rpx) scale(1.04);
407
481
  }
408
482
 
@@ -439,7 +513,7 @@
439
513
  left: 0;
440
514
  top: 0;
441
515
  width: 64px;
442
- height: v-bind('midButtonBorderClipHeight');
516
+ height: 0;
443
517
  box-sizing: border-box;
444
518
  background: transparent;
445
519
  overflow: hidden;
@@ -447,15 +521,17 @@
447
521
  z-index: 0;
448
522
  }
449
523
 
450
- /* #ifdef APP-NVUE */
451
- .u-tabbar-item__mid-button-border {
452
- height: 15.5px;
524
+ .u-tabbar-item__icon-content--anim-scale {
525
+ transform: scale(var(--up-tabbar-icon-scale, 1.1));
453
526
  }
454
527
 
455
- .u-tabbar-item--mid-button-no-text .u-tabbar-item__mid-button-border {
456
- height: 7px;
528
+ .u-tabbar-item__icon-content--anim-lift {
529
+ transform: translateY(-6rpx) scale(var(--up-tabbar-icon-scale, 1.08));
530
+ }
531
+
532
+ .u-tabbar-item__icon-content--anim-swing {
533
+ transform: rotate(-10deg) scale(var(--up-tabbar-icon-scale, 1.08));
457
534
  }
458
- /* #endif */
459
535
 
460
536
  .u-tabbar-item__mid-button-border-circle {
461
537
  width: 64px;
@@ -497,7 +573,8 @@
497
573
  transform: translateY(-4rpx);
498
574
  }
499
575
 
500
- .u-tabbar-item--anim-pulse .u-tabbar-item__icon {
576
+ .u-tabbar-item--anim-pulse .u-tabbar-item__icon:not(.u-tabbar-item__icon--mid-button),
577
+ .u-tabbar-item__icon-content--anim-pulse {
501
578
  animation: u-tabbar-item-pulse 1.4s ease-in-out infinite;
502
579
  }
503
580
 
@@ -1,3 +1,16 @@
1
+ /* #ifdef MP-WEIXIN */
2
+ :host {
3
+ --up-tag-close-bg-color: #c8c9cc;
4
+ }
5
+
6
+ @media (prefers-color-scheme: dark) {
7
+ :host {
8
+ --up-tag-close-bg-color: #4b5563;
9
+ }
10
+ }
11
+ /* #endif */
12
+
13
+ /* #ifndef MP-WEIXIN */
1
14
  :root,
2
15
  page,
3
16
  body {
@@ -19,3 +32,4 @@ body {
19
32
  [data-up-theme='dark'] {
20
33
  --up-tag-close-bg-color: #4b5563;
21
34
  }
35
+ /* #endif */
@@ -6,7 +6,6 @@
6
6
  @tap="clickHandler"
7
7
  :class="classes"
8
8
  :style="[mergeStyle]"
9
- @touchmove="noop"
10
9
  >
11
10
  <slot />
12
11
  </view>