oxy-uni-ui 1.2.3 → 2.0.0

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.
Files changed (235) hide show
  1. package/attributes.json +1 -1
  2. package/components/common/abstracts/variable.scss +353 -328
  3. package/components/common/util.ts +185 -32
  4. package/components/composables/index.ts +1 -0
  5. package/components/composables/usePopover.ts +24 -20
  6. package/components/composables/useVirtualScroll.ts +10 -9
  7. package/components/composables/useWindowResize.ts +35 -0
  8. package/components/oxy-action-sheet/index.scss +24 -11
  9. package/components/oxy-action-sheet/oxy-action-sheet.vue +27 -19
  10. package/components/oxy-action-sheet/types.ts +7 -0
  11. package/components/oxy-backtop/index.scss +3 -3
  12. package/components/oxy-backtop/oxy-backtop.vue +9 -6
  13. package/components/oxy-backtop/types.ts +7 -7
  14. package/components/oxy-badge/index.scss +4 -4
  15. package/components/oxy-badge/oxy-badge.vue +3 -3
  16. package/components/oxy-badge/types.ts +2 -2
  17. package/components/oxy-button/index.scss +5 -5
  18. package/components/oxy-button/oxy-button.vue +5 -1
  19. package/components/oxy-calendar/index.scss +11 -11
  20. package/components/oxy-calendar/oxy-calendar.vue +1 -0
  21. package/components/oxy-calendar/types.ts +5 -0
  22. package/components/oxy-calendar-view/month/index.scss +4 -4
  23. package/components/oxy-calendar-view/month/types.ts +36 -0
  24. package/components/oxy-calendar-view/monthPanel/index.scss +7 -7
  25. package/components/oxy-calendar-view/monthPanel/month-panel.vue +14 -8
  26. package/components/oxy-calendar-view/year/index.scss +4 -4
  27. package/components/oxy-calendar-view/yearPanel/index.scss +4 -4
  28. package/components/oxy-calendar-view/yearPanel/year-panel.vue +21 -5
  29. package/components/oxy-card/index.scss +2 -2
  30. package/components/oxy-cell/index.scss +8 -8
  31. package/components/oxy-checkbox/index.scss +7 -7
  32. package/components/oxy-checkbox-group/index.scss +2 -2
  33. package/components/oxy-circle/oxy-circle.vue +10 -7
  34. package/components/oxy-circle/types.ts +5 -5
  35. package/components/oxy-col/oxy-col.vue +2 -2
  36. package/components/oxy-col-picker/index.scss +4 -4
  37. package/components/oxy-col-picker/oxy-col-picker.vue +6 -5
  38. package/components/oxy-col-picker/types.ts +7 -2
  39. package/components/oxy-collapse/index.scss +2 -2
  40. package/components/oxy-collapse-item/oxy-collapse-item.vue +3 -3
  41. package/components/oxy-corner/index.scss +32 -32
  42. package/components/oxy-count-to/oxy-count-to.vue +3 -3
  43. package/components/oxy-curtain/index.scss +15 -15
  44. package/components/oxy-curtain/oxy-curtain.vue +4 -2
  45. package/components/oxy-curtain/types.ts +6 -1
  46. package/components/oxy-date-strip/oxy-date-strip.vue +2 -2
  47. package/components/oxy-date-strip/types.ts +1 -1
  48. package/components/oxy-date-strip-item/index.scss +3 -3
  49. package/components/oxy-datetime-picker/index.scss +11 -11
  50. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +1 -0
  51. package/components/oxy-datetime-picker/types.ts +5 -0
  52. package/components/oxy-drop-menu/index.scss +3 -3
  53. package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -3
  54. package/components/oxy-drop-menu-item/index.scss +1 -1
  55. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +4 -3
  56. package/components/oxy-drop-menu-item/types.ts +5 -0
  57. package/components/oxy-echarts/types.ts +6 -0
  58. package/components/oxy-fab/index.scss +8 -8
  59. package/components/oxy-fab/oxy-fab.vue +22 -3
  60. package/components/oxy-file-list/index.scss +24 -23
  61. package/components/oxy-file-list/oxy-file-list.vue +2 -2
  62. package/components/oxy-floating-panel/oxy-floating-panel.vue +13 -9
  63. package/components/oxy-floating-panel/{type.ts → types.ts} +8 -8
  64. package/components/oxy-footer/index.scss +19 -0
  65. package/components/oxy-footer/oxy-footer.vue +78 -0
  66. package/components/oxy-footer/types.ts +17 -0
  67. package/components/oxy-form-item/types.ts +22 -1
  68. package/components/oxy-gap/oxy-gap.vue +2 -2
  69. package/components/oxy-gap/types.ts +2 -2
  70. package/components/oxy-grid/oxy-grid.vue +1 -1
  71. package/components/oxy-grid/types.ts +1 -1
  72. package/components/oxy-grid-item/index.scss +1 -1
  73. package/components/oxy-grid-item/oxy-grid-item.vue +7 -5
  74. package/components/oxy-grid-item/types.ts +1 -1
  75. package/components/oxy-guidance/index.scss +75 -0
  76. package/components/oxy-guidance/oxy-guidance.vue +201 -0
  77. package/components/oxy-guidance/types.ts +33 -0
  78. package/components/oxy-icon/oxy-icon.vue +2 -2
  79. package/components/oxy-icon/types.ts +1 -1
  80. package/components/oxy-img/oxy-img.vue +4 -4
  81. package/components/oxy-img/types.ts +3 -3
  82. package/components/oxy-img-cropper/index.scss +12 -12
  83. package/components/oxy-img-cropper/oxy-img-cropper.vue +97 -52
  84. package/components/oxy-img-cropper/types.ts +2 -2
  85. package/components/oxy-img-lazy/oxy-img-lazy.vue +3 -3
  86. package/components/oxy-img-lazy/types.ts +3 -3
  87. package/components/oxy-index-anchor/index.scss +2 -2
  88. package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
  89. package/components/oxy-index-anchor/{type.ts → types.ts} +3 -0
  90. package/components/oxy-index-bar/index.scss +3 -3
  91. package/components/oxy-index-bar/oxy-index-bar.vue +3 -3
  92. package/components/oxy-index-bar/{type.ts → types.ts} +2 -2
  93. package/components/oxy-input/index.scss +1 -1
  94. package/components/oxy-input-number/index.scss +5 -5
  95. package/components/oxy-input-number/oxy-input-number.vue +2 -2
  96. package/components/oxy-input-number/types.ts +3 -2
  97. package/components/oxy-keyboard/index.scss +5 -5
  98. package/components/oxy-keyboard/key/index.scss +3 -3
  99. package/components/oxy-keyboard/key/index.vue +2 -2
  100. package/components/oxy-keyboard/key/types.ts +15 -0
  101. package/components/oxy-keyboard/oxy-keyboard.vue +1 -0
  102. package/components/oxy-keyboard/types.ts +5 -0
  103. package/components/oxy-link/index.scss +2 -2
  104. package/components/oxy-list/oxy-list.vue +4 -3
  105. package/components/oxy-loading/oxy-loading.vue +8 -4
  106. package/components/oxy-loading/types.ts +1 -1
  107. package/components/oxy-loadmore/index.scss +3 -3
  108. package/components/oxy-long-press-menu/index.scss +93 -0
  109. package/components/oxy-long-press-menu/oxy-long-press-menu.vue +338 -0
  110. package/components/oxy-long-press-menu/types.ts +34 -0
  111. package/components/oxy-message-box/index.scss +12 -11
  112. package/components/oxy-message-box/oxy-message-box.vue +11 -3
  113. package/components/oxy-message-box/types.ts +14 -0
  114. package/components/oxy-navbar/index.scss +2 -2
  115. package/components/oxy-navbar/oxy-navbar.vue +58 -13
  116. package/components/oxy-navbar/types.ts +8 -1
  117. package/components/oxy-navbar-capsule/types.ts +3 -0
  118. package/components/oxy-notice-bar/index.scss +3 -3
  119. package/components/oxy-notice-bar/oxy-notice-bar.vue +9 -5
  120. package/components/oxy-notice-bar/types.ts +3 -3
  121. package/components/oxy-notify/index.ts +1 -0
  122. package/components/oxy-notify/oxy-notify.vue +3 -2
  123. package/components/oxy-notify/types.ts +7 -0
  124. package/components/oxy-pagination/index.scss +1 -1
  125. package/components/oxy-password-input/oxy-password-input.vue +2 -2
  126. package/components/oxy-password-input/types.ts +1 -1
  127. package/components/oxy-picker/index.scss +45 -2
  128. package/components/oxy-picker/oxy-picker.vue +100 -14
  129. package/components/oxy-picker/types.ts +29 -1
  130. package/components/oxy-picker-view/index.scss +3 -3
  131. package/components/oxy-picker-view/oxy-picker-view.vue +4 -4
  132. package/components/oxy-popover/index.scss +9 -9
  133. package/components/oxy-popup/index.scss +2 -2
  134. package/components/oxy-popup/oxy-popup.vue +35 -2
  135. package/components/oxy-popup/types.ts +8 -1
  136. package/components/oxy-progress/index.scss +3 -3
  137. package/components/oxy-qrcode/draw.ts +398 -0
  138. package/components/oxy-qrcode/index.scss +2 -0
  139. package/components/oxy-qrcode/oxy-qrcode.vue +124 -0
  140. package/components/oxy-qrcode/qrcode.ts +936 -0
  141. package/components/oxy-qrcode/types.ts +42 -0
  142. package/components/oxy-radio/index.scss +10 -10
  143. package/components/oxy-radio-group/index.scss +2 -2
  144. package/components/oxy-rate/types.ts +4 -4
  145. package/components/oxy-resize/index.scss +2 -2
  146. package/components/oxy-resize/oxy-resize.vue +4 -4
  147. package/components/oxy-resize/types.ts +3 -0
  148. package/components/oxy-rich-text/index.scss +30 -29
  149. package/components/oxy-rich-text/mp-html/mp-html.vue +33 -24
  150. package/components/oxy-rich-text/mp-html/node/node.vue +30 -19
  151. package/components/oxy-rich-text/oxy-rich-text.vue +31 -31
  152. package/components/oxy-rich-text/types.ts +6 -1
  153. package/components/oxy-row/oxy-row.vue +3 -3
  154. package/components/oxy-row/types.ts +1 -1
  155. package/components/oxy-search/index.scss +3 -3
  156. package/components/oxy-segmented/index.scss +16 -16
  157. package/components/oxy-segmented/oxy-segmented.vue +23 -3
  158. package/components/oxy-select/index.scss +144 -68
  159. package/components/oxy-select/oxy-select.vue +85 -50
  160. package/components/oxy-select/types.ts +13 -1
  161. package/components/oxy-select-picker/index.scss +7 -7
  162. package/components/oxy-select-picker/oxy-select-picker.vue +1 -0
  163. package/components/oxy-select-picker/types.ts +2 -0
  164. package/components/oxy-sidebar-item/index.scss +1 -1
  165. package/components/oxy-signature/oxy-signature.vue +18 -10
  166. package/components/oxy-signature/types.ts +106 -13
  167. package/components/oxy-skeleton/oxy-skeleton.vue +6 -6
  168. package/components/oxy-skeleton/types.ts +1 -1
  169. package/components/oxy-slider/index.scss +3 -3
  170. package/components/oxy-sort-button/index.scss +8 -8
  171. package/components/oxy-status-tip/index.scss +4 -4
  172. package/components/oxy-status-tip/oxy-status-tip.vue +5 -5
  173. package/components/oxy-status-tip/types.ts +3 -3
  174. package/components/oxy-step/index.scss +14 -14
  175. package/components/oxy-sticky/oxy-sticky.vue +6 -6
  176. package/components/oxy-stream-render/types.ts +4 -1
  177. package/components/oxy-swipe-action/oxy-swipe-action.vue +27 -2
  178. package/components/oxy-swiper/oxy-swiper.vue +6 -6
  179. package/components/oxy-swiper/types.ts +5 -5
  180. package/components/oxy-switch/index.scss +8 -8
  181. package/components/oxy-switch/oxy-switch.vue +2 -2
  182. package/components/oxy-switch/types.ts +1 -1
  183. package/components/oxy-tab/index.scss +11 -1
  184. package/components/oxy-tabbar/index.scss +1 -1
  185. package/components/oxy-tabbar/oxy-tabbar.vue +39 -10
  186. package/components/oxy-table/index.scss +5 -5
  187. package/components/oxy-table/oxy-table.vue +8 -6
  188. package/components/oxy-table/types.ts +2 -2
  189. package/components/oxy-table-col/oxy-table-col.vue +3 -3
  190. package/components/oxy-table-col/types.ts +2 -2
  191. package/components/oxy-tabs/index.scss +43 -15
  192. package/components/oxy-tabs/oxy-tabs.vue +53 -19
  193. package/components/oxy-tabs/types.ts +15 -3
  194. package/components/oxy-tag/index.scss +15 -15
  195. package/components/oxy-text/index.scss +5 -1
  196. package/components/oxy-text/oxy-text.vue +76 -7
  197. package/components/oxy-text/types.ts +12 -0
  198. package/components/oxy-textarea/index.scss +6 -6
  199. package/components/oxy-toast/oxy-toast.vue +24 -8
  200. package/components/oxy-tooltip/index.scss +9 -9
  201. package/components/oxy-tree/index.scss +51 -15
  202. package/components/oxy-tree/oxy-tree.vue +13 -9
  203. package/components/oxy-tree/types.ts +12 -9
  204. package/components/oxy-upload/index.scss +21 -21
  205. package/components/oxy-upload/types.ts +2 -2
  206. package/components/oxy-verification-code/index.scss +6 -0
  207. package/components/oxy-verification-code/oxy-verification-code.vue +187 -0
  208. package/components/oxy-verification-code/types.ts +82 -0
  209. package/components/oxy-video-preview/index.scss +4 -4
  210. package/components/oxy-virtual-scroll/index.scss +4 -4
  211. package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +11 -7
  212. package/components/oxy-virtual-scroll/types.ts +14 -14
  213. package/components/oxy-voice-player/index.scss +908 -0
  214. package/components/oxy-voice-player/oxy-voice-player.vue +821 -0
  215. package/components/oxy-voice-player/types.ts +567 -0
  216. package/components/oxy-waterfall/oxy-waterfall.vue +6 -6
  217. package/components/oxy-waterfall/types.ts +6 -6
  218. package/components/oxy-watermark/oxy-watermark.vue +35 -13
  219. package/components/oxy-watermark/types.ts +14 -14
  220. package/global.d.ts +2 -0
  221. package/locale/lang/ar-SA.ts +3 -0
  222. package/locale/lang/en-US.ts +3 -0
  223. package/locale/lang/zh-CN.ts +3 -0
  224. package/package.json +97 -1
  225. package/tags.json +1 -1
  226. package/web-types.json +1 -1
  227. package/components/oxy-number-keyboard/index.scss +0 -78
  228. package/components/oxy-number-keyboard/key/index.scss +0 -81
  229. package/components/oxy-number-keyboard/key/index.vue +0 -78
  230. package/components/oxy-number-keyboard/key/types.ts +0 -11
  231. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +0 -151
  232. package/components/oxy-number-keyboard/types.ts +0 -83
  233. package/components/oxy-tree/components/tree-node-content.vue +0 -72
  234. package/components/oxy-tree/index.ts +0 -51
  235. package/oxy-uni-ui.zip +0 -0
@@ -52,11 +52,11 @@ export const tabsProps = {
52
52
  */
53
53
  autoLineWidth: makeBooleanProp(false),
54
54
  /**
55
- * 底部条宽度,单位像素
55
+ * 底部条宽度,支持 `px/rpx`
56
56
  */
57
57
  lineWidth: numericProp,
58
58
  /**
59
- * 底部条高度,单位像素
59
+ * 底部条高度,支持 `px/rpx`
60
60
  */
61
61
  lineHeight: numericProp,
62
62
  /**
@@ -80,7 +80,19 @@ export const tabsProps = {
80
80
  * 可选值:'auto' | 'always'
81
81
  * @default auto
82
82
  */
83
- slidable: makeStringProp<TabsSlidable>('auto')
83
+ slidable: makeStringProp<TabsSlidable>('auto'),
84
+ /**
85
+ * 是否开启胶囊模式
86
+ */
87
+ pills: makeBooleanProp(false),
88
+ /**
89
+ * 胶囊背景颜色
90
+ */
91
+ pillsColor: makeStringProp(''),
92
+ /**
93
+ * 是否开启全屏模式
94
+ */
95
+ fullscreen: makeBooleanProp(false)
84
96
  }
85
97
 
86
98
  export type TabsExpose = {
@@ -8,23 +8,23 @@
8
8
  background: transparent;
9
9
  color: $normalColor;
10
10
  border: 1px solid $normalColor;
11
- padding: 0 4px;
11
+ padding: 0 8rpx;
12
12
  }
13
13
  @include when(round) {
14
14
  line-height: 1.2;
15
15
  font-size: $-tag-fs;
16
- padding: 4px 11px;
16
+ padding: 8rpx 22rpx;
17
17
  background: transparent;
18
18
  color: if($normalColor != $-tag-info-color, $normalColor, $-tag-round-color);
19
19
  border: 1px solid if($normalColor != $-tag-info-color, $normalColor, $-tag-round-border-color);
20
20
  border-radius: $-tag-round-radius;
21
21
  }
22
22
  @include when(mark) {
23
- padding: 1px 6px;
23
+ padding: 2rpx 12rpx;
24
24
  border-radius: $-tag-mark-radius;
25
25
 
26
26
  @include when(plain) {
27
- padding: 0 6px;
27
+ padding: 0 12rpx;
28
28
  }
29
29
  }
30
30
  @include when(active) {
@@ -36,8 +36,8 @@
36
36
  font-size: $-tag-small-fs;
37
37
  display: inline-block;
38
38
  color: $-tag-color;
39
- padding: 0 3px;
40
- border-radius: 2px;
39
+ padding: 0 6rpx;
40
+ border-radius: 4rpx;
41
41
  transition: opacity .3s;
42
42
  vertical-align: middle;
43
43
  line-height: initial;
@@ -60,11 +60,11 @@
60
60
  @include when(icon) {
61
61
  font-size: $-tag-fs;
62
62
  line-height: 1.2;
63
- padding: 2px 5px;
63
+ padding: 4rpx 10rpx;
64
64
  }
65
65
  @include when(dynamic) {
66
66
  box-sizing: border-box;
67
- width: 88px;
67
+ width: 176rpx;
68
68
  transition: .3s;
69
69
 
70
70
  &:active {
@@ -77,7 +77,7 @@
77
77
  }
78
78
  @include edeep(icon) {
79
79
  display: inline-block;
80
- margin-right: 4px;
80
+ margin-right: 8rpx;
81
81
  font-size: $-tag-fs;
82
82
  line-height: 1.2;
83
83
  vertical-align: baseline;
@@ -87,9 +87,9 @@
87
87
  vertical-align: text-top;
88
88
  }
89
89
  @include e(add-text) {
90
- width: 60px;
91
- height: 14px;
92
- min-height: 14px;
90
+ width: 120rpx;
91
+ height: 28rpx;
92
+ min-height: 28rpx;
93
93
  display: inline-block;
94
94
  font-size: $-tag-fs;
95
95
  vertical-align: middle;
@@ -97,10 +97,10 @@
97
97
  }
98
98
  @include e(close) {
99
99
  display: inline-block;
100
- margin-left: 24px;
101
- margin-right: -4px;
100
+ margin-left: 48rpx;
101
+ margin-right: -8rpx;
102
102
  font-size: $-tag-close-size;
103
- height: 14px;
103
+ height: 28rpx;
104
104
  line-height: 1.1;
105
105
  vertical-align: text-bottom;
106
106
  color: $-tag-close-color;
@@ -34,4 +34,8 @@
34
34
  @include when(success) {
35
35
  color: $-text-success-color;
36
36
  }
37
- }
37
+
38
+ @include e(btn) {
39
+ color: $-text-primary-color;
40
+ }
41
+ }
@@ -1,8 +1,16 @@
1
1
  <template>
2
- <text @click="handleClick" :class="rootClass" :style="rootStyle">
2
+ <oxy-tooltip v-if="props.tooltip && isTextOverflow" :content="formattedText">
3
+ <text @click="handleClick" :class="`${rootClass} is-lines-${props.lines}`" :style="rootStyle">
4
+ <slot v-if="$slots.prefix || prefix" name="prefix">{{ prefix }}</slot>
5
+ <text>{{ formattedText }}</text>
6
+ <slot v-if="$slots.suffix || suffix" name="suffix">{{ suffix }}</slot>
7
+ </text>
8
+ </oxy-tooltip>
9
+ <text v-else :id="textId" @click="handleClick" :class="rootClass" :style="rootStyle">
3
10
  <slot v-if="$slots.prefix || prefix" name="prefix">{{ prefix }}</slot>
4
- <text>{{ formattedText }}</text>
11
+ <text>{{ props.toggleExpand && isTextOverflow && !expanded ? realText : formattedText }}</text>
5
12
  <slot v-if="$slots.suffix || suffix" name="suffix">{{ suffix }}</slot>
13
+ <text v-if="props.toggleExpand && isTextOverflow" class="oxy-text__btn" @click.stop="handleToggle">{{ expanded ? '收起' : '展开' }}</text>
6
14
  </text>
7
15
  </template>
8
16
 
@@ -18,15 +26,24 @@ export default {
18
26
  </script>
19
27
 
20
28
  <script lang="ts" setup>
21
- import { computed, ref, watch } from 'vue'
22
- import { isDef, objToStyle } from '../common/util'
29
+ import { computed, ref, watch, nextTick, getCurrentInstance } from 'vue'
30
+ import { isDef, objToStyle, uuid, getRect } from '../common/util'
23
31
  import { textProps } from './types'
24
32
  import dayjs from '../../dayjs'
33
+ import OxyTooltip from '../oxy-tooltip/oxy-tooltip.vue'
25
34
 
26
35
  // 获取组件的 props 和 emit 函数
27
36
  const props = defineProps(textProps)
28
37
  const emit = defineEmits(['click'])
29
38
 
39
+ const { proxy } = getCurrentInstance() as any
40
+ const textId = ref<string>(`oxy-text${uuid()}`)
41
+ const expanded = ref<boolean>(false)
42
+ const isTextOverflow = ref<boolean>(false)
43
+ const realText = ref<string>('')
44
+ const offset = ref<number>(0)
45
+ const showTooltip = ref<boolean>(false)
46
+
30
47
  // 存储文本类名的响应式变量
31
48
  const textClass = ref<string>('')
32
49
 
@@ -39,7 +56,9 @@ watch(
39
56
  color: props.color,
40
57
  bold: props.bold,
41
58
  lines: props.lines,
42
- format: props.format
59
+ format: props.format,
60
+ toggleExpand: props.toggleExpand,
61
+ tooltip: props.tooltip
43
62
  }),
44
63
  ({ type }) => {
45
64
  // 验证 type 属性
@@ -77,12 +96,12 @@ const rootStyle = computed(() => {
77
96
 
78
97
  // 计算文本类名的函数
79
98
  function computeTextClass() {
80
- const { type, color, bold, lines } = props
99
+ const { type, color, bold, lines, toggleExpand, tooltip } = props
81
100
  const textClassList: string[] = []
82
101
  if (!color) {
83
102
  textClassList.push(`is-${type}`)
84
103
  }
85
- if (isDef(lines)) {
104
+ if (isDef(lines) && !toggleExpand && !tooltip) {
86
105
  textClassList.push(`is-lines-${lines}`)
87
106
  }
88
107
  bold && textClassList.push('is-bold')
@@ -128,6 +147,56 @@ const formattedText = computed(() => {
128
147
  return formatText(`${text}`, format, mode)
129
148
  })
130
149
 
150
+ watch(
151
+ formattedText,
152
+ (value) => {
153
+ nextTick(() => {
154
+ if (props.toggleExpand || props.tooltip) {
155
+ realText.value = value
156
+ offset.value = realText.value.length
157
+ const view = uni.createSelectorQuery().in(proxy).select(`#${textId.value}`)
158
+ view
159
+ .fields({ computedStyle: ['fontSize', 'lineHeight'] }, (res: any) => {
160
+ getRect(`#${textId.value}`, true, proxy)
161
+ .then((rects: any) => {
162
+ if (res && Array.isArray(rects) && rects.length && props.lines) {
163
+ const lines = rects[0].height / Number.parseFloat(res.lineHeight.replace('px', ''))
164
+ isTextOverflow.value = lines > props.lines
165
+ if (props.toggleExpand && isTextOverflow.value) {
166
+ const size = Math.floor(rects[0].width / Number.parseFloat(res.fontSize.replace('px', '')))
167
+ // 中英文字符长度区分
168
+ const length = size * props.lines - 4
169
+ let realOffset = 0
170
+ let realLength = 0
171
+ for (let i = 0; i < offset.value; i++) {
172
+ if (realText.value.charCodeAt(i) > 127) {
173
+ realLength += 1
174
+ } else {
175
+ realLength += 0.5
176
+ }
177
+ realOffset++
178
+ if (realLength >= length) {
179
+ offset.value = realOffset
180
+ break
181
+ }
182
+ }
183
+ realText.value = `${value.substring(0, offset.value)}...`
184
+ }
185
+ }
186
+ })
187
+ .catch(() => {})
188
+ })
189
+ .exec()
190
+ }
191
+ })
192
+ },
193
+ { deep: true, immediate: true }
194
+ )
195
+
196
+ function handleToggle() {
197
+ expanded.value = !expanded.value
198
+ }
199
+
131
200
  // 处理点击事件
132
201
  function handleClick(event: Event) {
133
202
  emit('click', event)
@@ -79,6 +79,18 @@ export const textProps = {
79
79
  * 文本显示的行数,如果设置,超出此行数,将会显示省略号。最大值为5。
80
80
  */
81
81
  lines: Number,
82
+ /**
83
+ * 文本超出,展开收起显示全部
84
+ * 类型:boolean
85
+ * 默认值:false
86
+ */
87
+ toggleExpand: makeBooleanProp(false),
88
+ /**
89
+ * 文本超出,tooltip显示全部
90
+ * 类型:boolean
91
+ * 默认值:false
92
+ */
93
+ tooltip: makeBooleanProp(false),
82
94
  /**
83
95
  * 文本行高
84
96
  * 类型:string
@@ -144,11 +144,11 @@
144
144
  box-sizing: border-box;
145
145
 
146
146
  @include when(show-limit) {
147
- padding-bottom: 36px;
147
+ padding-bottom: 72rpx;
148
148
  }
149
149
 
150
150
  @include when(suffix) {
151
- padding-right: calc($-textarea-icon-size + 8px);
151
+ padding-right: calc($-textarea-icon-size + 16rpx);
152
152
  }
153
153
  }
154
154
 
@@ -164,7 +164,7 @@
164
164
  border: none;
165
165
  box-sizing: border-box;
166
166
  word-break: break-word;
167
- min-height: 24px;
167
+ min-height: 48rpx;
168
168
 
169
169
  &::-webkit-input-placeholder {
170
170
  color: $-input-placeholder-color;
@@ -198,12 +198,12 @@
198
198
 
199
199
  @include e(count) {
200
200
  position: absolute;
201
- bottom: 8px;
201
+ bottom: 16rpx;
202
202
  right: 0;
203
203
  font-size: $-textarea-count-fs;
204
204
  color: $-textarea-count-color;
205
205
  background: $-textarea-bg;
206
- line-height: 20px;
206
+ line-height: 40rpx;
207
207
  display: inline-flex;
208
208
  }
209
209
 
@@ -258,7 +258,7 @@
258
258
 
259
259
  @include when(auto-height) {
260
260
  &:not(.is-cell) {
261
- padding: 5px 0;
261
+ padding: 10rpx 0;
262
262
  }
263
263
 
264
264
  &::after {
@@ -31,8 +31,10 @@
31
31
  :class-prefix="classPrefix"
32
32
  :name="iconClass"
33
33
  ></oxy-icon>
34
- <!--文本-->
35
- <view v-if="msg" class="oxy-toast__msg">{{ msg }}</view>
34
+ <!--文本/插槽内容-->
35
+ <view v-if="hasContent" class="oxy-toast__msg">
36
+ <slot>{{ msg }}</slot>
37
+ </view>
36
38
  </view>
37
39
  </oxy-transition>
38
40
  </template>
@@ -54,13 +56,14 @@ import OxyLoading from '../oxy-loading/oxy-loading.vue'
54
56
  import OxyOverlay from '../oxy-overlay/oxy-overlay.vue'
55
57
  import OxyTransition from '../oxy-transition/oxy-transition.vue'
56
58
 
57
- import { computed, inject, onBeforeMount, ref, watch, type CSSProperties } from 'vue'
59
+ import { computed, inject, onBeforeMount, ref, useSlots, watch, type CSSProperties } from 'vue'
58
60
  import base64 from '../common/base64'
59
61
  import { defaultOptions, getToastOptionKey, toastIcon } from '.'
60
62
  import { toastProps, type ToastDirection, type ToastLoadingType, type ToastOptions, type ToastProps } from './types'
61
- import { addUnit, isDef, isFunction, objToStyle } from '../common/util'
63
+ import { withDefaultUnit, isDef, isFunction, objToStyle } from '../common/util'
62
64
 
63
65
  const props = defineProps(toastProps)
66
+ const slots = useSlots()
64
67
  const iconName = ref<string>('') // 图标类型
65
68
  const msg = ref<string>('') // 消息内容
66
69
  const position = ref<string>('middle')
@@ -124,10 +127,19 @@ const transitionStyle = computed(() => {
124
127
  return objToStyle(style)
125
128
  })
126
129
 
130
+ const hasCustomContent = computed(() => {
131
+ const slotNodes = slots.default?.()
132
+ return !!slotNodes?.length
133
+ })
134
+
135
+ const hasContent = computed(() => {
136
+ return !!msg.value || hasCustomContent.value
137
+ })
138
+
127
139
  const rootClass = computed(() => {
128
140
  return `oxy-toast ${props.customClass} oxy-toast--${position.value} ${
129
- (iconName.value !== 'loading' || msg.value) && (iconName.value || iconClass.value) ? 'oxy-toast--with-icon' : ''
130
- } ${iconName.value === 'loading' && !msg.value ? 'oxy-toast--loading' : ''} ${direction.value === 'vertical' ? 'is-vertical' : ''}`
141
+ (iconName.value !== 'loading' || hasContent.value) && (iconName.value || iconClass.value) ? 'oxy-toast--with-icon' : ''
142
+ } ${iconName.value === 'loading' && !hasContent.value ? 'oxy-toast--loading' : ''} ${direction.value === 'vertical' ? 'is-vertical' : ''}`
131
143
  })
132
144
 
133
145
  const svgStyle = computed(() => {
@@ -184,8 +196,12 @@ function mergeOptionsWithProps(option: ToastOptions, props: ToastProps) {
184
196
  zIndex.value = isDef(option.zIndex!) ? option.zIndex! : props.zIndex
185
197
  loadingType.value = isDef(option.loadingType!) ? option.loadingType! : props.loadingType
186
198
  loadingColor.value = isDef(option.loadingColor!) ? option.loadingColor! : props.loadingColor
187
- iconSize.value = isDef(option.iconSize) ? addUnit(option.iconSize) : isDef(props.iconSize) ? addUnit(props.iconSize) : undefined
188
- loadingSize.value = isDef(option.loadingSize) ? addUnit(option.loadingSize) : isDef(props.loadingSize) ? addUnit(props.loadingSize) : undefined
199
+ iconSize.value = isDef(option.iconSize) ? withDefaultUnit(option.iconSize) : isDef(props.iconSize) ? withDefaultUnit(props.iconSize) : undefined
200
+ loadingSize.value = isDef(option.loadingSize)
201
+ ? withDefaultUnit(option.loadingSize)
202
+ : isDef(props.loadingSize)
203
+ ? withDefaultUnit(props.loadingSize)
204
+ : undefined
189
205
  cover.value = isDef(option.cover!) ? option.cover! : props.cover
190
206
  classPrefix.value = isDef(option.classPrefix) ? option.classPrefix : props.classPrefix
191
207
  direction.value = isDef(option.direction) ? option.direction : props.direction
@@ -22,15 +22,15 @@
22
22
 
23
23
  @include edeep(pos) {
24
24
  position: absolute;
25
- min-width: 138px;
26
- min-height: 36px;
25
+ min-width: 276rpx;
26
+ min-height: 72rpx;
27
27
  font-size: $-tooltip-fs;
28
28
  backdrop-filter: blur($-tooltip-blur);
29
29
  background-clip: padding-box;
30
30
  border-radius: $-tooltip-radius;
31
31
  background: $-tooltip-bg;
32
32
  color: $-tooltip-color;
33
- text-align: center;
33
+ // text-align: center;
34
34
  box-sizing: border-box;
35
35
  z-index: $-tooltip-z-index;
36
36
  }
@@ -49,18 +49,18 @@
49
49
 
50
50
  @include e(inner) {
51
51
  padding: $-tooltip-padding;
52
- white-space: nowrap;
52
+ // white-space: nowrap;
53
53
  line-height: $-tooltip-line-height;
54
54
  }
55
55
 
56
56
  @include edeep(close-icon) {
57
- font-size: 12px;
57
+ font-size: 24rpx;
58
58
  position: absolute;
59
- right: -8px;
60
- top: -10px;
59
+ right: -16rpx;
60
+ top: -20rpx;
61
61
  transform: scale(0.5);
62
- padding: 10px;
62
+ padding: 20rpx;
63
63
  }
64
64
 
65
65
  @include triangleArrow($-tooltip-arrow-size, $-tooltip-bg);
66
- }
66
+ }
@@ -26,15 +26,18 @@
26
26
  .oxy-tree__search{
27
27
  display: flex;
28
28
  :deep(.oxy-button){
29
- min-width: 60px;
29
+ min-width: 120rpx;
30
30
  }
31
31
  :deep(.oxy-tree__search-input) {
32
32
  flex: 1;
33
33
  background-color: $-tree-search-input-color;
34
- padding: 6px 12px;
35
- border-radius: 4px;
36
- margin-bottom: 8px;
37
- margin-right: 12px;
34
+ padding: 12rpx 24rpx;
35
+ border-radius: 8rpx;
36
+ margin-bottom: 16rpx;
37
+ margin-right: 24rpx;
38
+ .oxy-input__icon{
39
+ background: transparent;
40
+ }
38
41
  }
39
42
  }
40
43
 
@@ -43,18 +46,20 @@
43
46
 
44
47
  .oxy-tree-node-content {
45
48
  display: flex;
46
- width: fit-content;
47
49
  width: 100%;
48
- white-space: nowrap;
49
50
  align-items: center;
51
+ box-sizing: border-box;
52
+ padding-right: $-tree-node-padding-right;
53
+ border-radius: $-tree-node-radius;
54
+ color: $-color-secondary;
55
+ font-size: $-tree-node-font-size;
56
+ transition: background-color .2s ease, color .2s ease, opacity .2s ease;
50
57
 
51
- &.expanded {
52
- :deep(.oxy-tree-node-icon) {
53
- transform: rotate(0deg);
58
+ &.is-leaf {
59
+ .oxy-tree-node-toggle {
60
+ pointer-events: none;
54
61
  }
55
- }
56
62
 
57
- &.is-leaf {
58
63
  :deep(.oxy-tree-node-icon) {
59
64
  opacity: 0;
60
65
  }
@@ -63,14 +68,31 @@
63
68
  &.is-current {
64
69
  background-color: $-tree-node-current-bg;
65
70
  color: $-tree-node-current-color;
71
+ font-weight: $-fw-medium;
72
+
73
+ :deep(.oxy-tree-node-icon) {
74
+ color: $-tree-node-icon-active-color;
75
+ }
76
+ }
77
+
78
+ &.checked {
79
+ :deep(.oxy-tree-node-icon) {
80
+ color: $-tree-node-icon-active-color;
81
+ }
66
82
  }
67
83
 
68
84
  &.is-disabled {
69
85
  color: $-tree-node-disabled-color;
86
+ opacity: $-button-disabled-opacity;
87
+
88
+ :deep(.oxy-tree-node-icon) {
89
+ color: $-tree-node-disabled-color;
90
+ }
70
91
  }
71
92
 
72
93
  :deep(.oxy-checkbox) {
73
- margin-right: 6px;
94
+ margin-right: $-size-side-padding-small;
95
+ flex-shrink: 0;
74
96
 
75
97
  .oxy-checkbox__label {
76
98
  display: none;
@@ -90,10 +112,24 @@
90
112
  }
91
113
 
92
114
  :deep(.oxy-tree-node-icon) {
93
- transform: rotate(-90deg);
115
+ color: $-tree-node-icon-color;
116
+ font-size: $-tree-node-icon-size;
117
+ transition: none;
118
+ }
119
+
120
+ .oxy-tree-node-toggle {
121
+ width: $-tree-node-icon-box-size;
122
+ height: 100%;
123
+ display: flex;
124
+ align-items: center;
125
+ justify-content: center;
126
+ margin-right: $-tree-node-icon-gap;
127
+ flex-shrink: 0;
94
128
  }
95
129
 
96
130
  .oxy-tree-node {
97
131
  flex: 1;
132
+ min-width: 0;
133
+ @include lineEllipsis;
98
134
  }
99
- }
135
+ }
@@ -17,13 +17,16 @@
17
17
 
18
18
  <view v-if="data.length" class="oxy-tree__virtual-scroll" :style="{ height: height }">
19
19
  <scroll-view class="oxy-tree__view" scroll-y :scroll-x="true" :scroll-top="scrollTop" @scroll="handleScroll">
20
- <view class="oxy-tree__container" :style="{ height: totalHeight + 'px' }">
21
- <view class="oxy-tree__items" :style="{ transform: `translateY(${virtualOffsetY}px)` }">
20
+ <view class="oxy-tree__container" :style="{ height: unitConvert(totalHeight, 0, { output: 'px' }) }">
21
+ <view class="oxy-tree__items" :style="{ transform: `translateY(${unitConvert(virtualOffsetY, 0, { output: 'px' })})` }">
22
22
  <view v-for="(item, index) in virtualData" :key="index">
23
23
  <view class="oxy-tree-node-content" :style="getNodeStyle(item)" :class="getNodeClass(item)" @click="handleNodeClick(item)">
24
24
  <!-- 兼容支付宝、微信小程序 -->
25
- <view @tap.stop="handleClickExpand(item)">
26
- <oxy-icon name="fill-arrow-down" custom-class="oxy-tree-node-icon" size="22px"></oxy-icon>
25
+ <view class="oxy-tree-node-toggle" @tap.stop="handleClickExpand(item)">
26
+ <oxy-icon
27
+ :name="expandedKeySet.has(item.key) ? 'chevron-down-circle' : 'chevron-right-circle'"
28
+ custom-class="oxy-tree-node-icon"
29
+ ></oxy-icon>
27
30
  </view>
28
31
  <oxy-checkbox
29
32
  v-if="showCheckbox"
@@ -49,7 +52,7 @@
49
52
 
50
53
  <!-- 回到顶部按钮 -->
51
54
  <view v-if="showBackToTop && showBackTopBtn" class="oxy-virtual-scroll__back-top" @click="scrollToTop">
52
- <oxy-icon name="backtop" color="#fff" size="20px"></oxy-icon>
55
+ <oxy-icon name="backtop" color="#fff" size="40rpx"></oxy-icon>
53
56
  </view>
54
57
  </view>
55
58
  </template>
@@ -71,6 +74,7 @@ import type { RawTreeNode, Tree, TreeInstance, TreeNode } from './types'
71
74
  import { treeProps, type TreeExpose } from './types'
72
75
  import { isSetsEqual, useTreeMethods } from './utils'
73
76
  import { useVirtualScroll } from '../composables/useVirtualScroll'
77
+ import { withDefaultUnit, unitConvert, unitConvertWithDefault } from '../common/util'
74
78
 
75
79
  // 获取组件的 props 和 emit 函数
76
80
  const props = defineProps(treeProps)
@@ -334,8 +338,8 @@ const updateValue = () => {
334
338
  }
335
339
  const getNodeStyle = (item: TreeNode) => {
336
340
  return {
337
- height: itemHeight.value,
338
- paddingLeft: `${(item.level - 1) * (props.indent || 16)}px`
341
+ height: withDefaultUnit(itemHeight.value, 'rpx'),
342
+ paddingLeft: withDefaultUnit((item.level - 1) * (props.indent || 16))
339
343
  }
340
344
  }
341
345
  const getNodeClass = (item: TreeNode) => {
@@ -384,8 +388,8 @@ const scrollToTop = () => {
384
388
  }
385
389
  const scrollToBottom = () => {
386
390
  const visibleCount = flattenTree.value.length
387
- const containerHeight = parseFloat(height.value || '0')
388
- const targetScrollTop = Math.max(visibleCount * parseFloat(itemHeight.value) - containerHeight, 0)
391
+ const containerHeight = unitConvert(height.value)
392
+ const targetScrollTop = Math.max(visibleCount * unitConvertWithDefault(itemHeight.value, { defaultUnit: 'rpx' }) - containerHeight, 0)
389
393
  virtualScrollToPosition(targetScrollTop)
390
394
  }
391
395
  const scrollToPosition = (position: number | string) => {
@@ -48,7 +48,7 @@ export const treeProps = {
48
48
  default: ''
49
49
  },
50
50
  emptyText: makeStringProp('暂无数据'),
51
- height: makeStringProp('300px'),
51
+ height: makeStringProp('600rpx'),
52
52
  /**
53
53
  * 是否显示回到顶部按钮
54
54
  * 类型:boolean
@@ -57,17 +57,20 @@ export const treeProps = {
57
57
  showBackToTop: makeBooleanProp(false),
58
58
  /**
59
59
  * 滚动多远显示backToTop
60
- * 类型:number
61
- * 默认值:'300px'
60
+ * 类型:string(支持 `px/rpx`,纯数字字符串按 rpx 处理)
61
+ * 默认值:'600rpx'
62
62
  */
63
- backToTopThreshold: makeStringProp('300px'),
63
+ backToTopThreshold: makeStringProp('600rpx'),
64
64
  /**
65
- * 单个项目高度
66
- * 类型:number
67
- * 默认值:'44px'
65
+ * 列表项的预估高度,需带单位
66
+ * @description 虚拟列表会根据此值计算占位高度,越准确滚动越平滑。支持如 '44px' 或 '88rpx',纯数字字符串按 rpx 处理。
67
+ * 默认值:'88rpx'
68
68
  */
69
- itemHeight: makeStringProp('44px'),
70
- indent: makeNumberProp(16),
69
+ itemHeight: makeStringProp('88rpx'),
70
+ /**
71
+ * 相邻级节点间的水平缩进,number 类型按 `rpx` 语义处理
72
+ */
73
+ indent: makeNumberProp(32),
71
74
  selectionLeafOnly: makeBooleanProp(false),
72
75
  filterMethod: {
73
76
  type: Function as PropType<(keyword: string, node: RawTreeNode) => boolean>,