muzhiyu-ui 1.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 (96) hide show
  1. package/README.md +202 -0
  2. package/components/muzhiyu/mu-action-sheet/mu-action-sheet.vue +335 -0
  3. package/components/muzhiyu/mu-alert/mu-alert.vue +220 -0
  4. package/components/muzhiyu/mu-back-top/mu-back-top.vue +161 -0
  5. package/components/muzhiyu/mu-badge/mu-badge.vue +150 -0
  6. package/components/muzhiyu/mu-barcode/mu-barcode.vue +100 -0
  7. package/components/muzhiyu/mu-blank/mu-blank.vue +30 -0
  8. package/components/muzhiyu/mu-bottom-nav/mu-bottom-nav.vue +331 -0
  9. package/components/muzhiyu/mu-bubble/mu-bubble.vue +316 -0
  10. package/components/muzhiyu/mu-button/mu-button.vue +431 -0
  11. package/components/muzhiyu/mu-calendar/mu-calendar.vue +429 -0
  12. package/components/muzhiyu/mu-car-input/mu-car-input.vue +209 -0
  13. package/components/muzhiyu/mu-card/mu-card.vue +317 -0
  14. package/components/muzhiyu/mu-cascader/mu-cascader.vue +336 -0
  15. package/components/muzhiyu/mu-cell/mu-cell.vue +368 -0
  16. package/components/muzhiyu/mu-checkbox/mu-checkbox.vue +116 -0
  17. package/components/muzhiyu/mu-checkbox-group/mu-checkbox-group.vue +40 -0
  18. package/components/muzhiyu/mu-code-input/mu-code-input.vue +264 -0
  19. package/components/muzhiyu/mu-collapse/mu-collapse.vue +316 -0
  20. package/components/muzhiyu/mu-color-picker/mu-color-picker.vue +466 -0
  21. package/components/muzhiyu/mu-config/index.js +34 -0
  22. package/components/muzhiyu/mu-config/mu-config.vue +54 -0
  23. package/components/muzhiyu/mu-countdown/mu-countdown.vue +338 -0
  24. package/components/muzhiyu/mu-cropper/mu-cropper.vue +415 -0
  25. package/components/muzhiyu/mu-date-picker/mu-date-picker.vue +290 -0
  26. package/components/muzhiyu/mu-datetime/mu-datetime.vue +262 -0
  27. package/components/muzhiyu/mu-divider/mu-divider.vue +229 -0
  28. package/components/muzhiyu/mu-drawer/mu-drawer.vue +172 -0
  29. package/components/muzhiyu/mu-dropdown/mu-dropdown.vue +215 -0
  30. package/components/muzhiyu/mu-dropdown-top/mu-dropdown-top.vue +243 -0
  31. package/components/muzhiyu/mu-empty/mu-empty.vue +217 -0
  32. package/components/muzhiyu/mu-fab/mu-fab.vue +324 -0
  33. package/components/muzhiyu/mu-footer/mu-footer.vue +21 -0
  34. package/components/muzhiyu/mu-form/mu-form.vue +170 -0
  35. package/components/muzhiyu/mu-grid/mu-grid.vue +95 -0
  36. package/components/muzhiyu/mu-grid-item/mu-grid-item.vue +247 -0
  37. package/components/muzhiyu/mu-html/mu-html.vue +145 -0
  38. package/components/muzhiyu/mu-icon/mu-icon.vue +822 -0
  39. package/components/muzhiyu/mu-image-grid/mu-image-grid.vue +225 -0
  40. package/components/muzhiyu/mu-image-preview/mu-image-preview.vue +286 -0
  41. package/components/muzhiyu/mu-index-list/mu-index-list.vue +381 -0
  42. package/components/muzhiyu/mu-input/mu-input.vue +570 -0
  43. package/components/muzhiyu/mu-input-number/mu-input-number.vue +193 -0
  44. package/components/muzhiyu/mu-keyboard/mu-keyboard.vue +415 -0
  45. package/components/muzhiyu/mu-list/mu-list.vue +89 -0
  46. package/components/muzhiyu/mu-loading/mu-loading.vue +124 -0
  47. package/components/muzhiyu/mu-loading-page/mu-loading-page.vue +529 -0
  48. package/components/muzhiyu/mu-loadmore/mu-loadmore.vue +26 -0
  49. package/components/muzhiyu/mu-modal/mu-modal.vue +298 -0
  50. package/components/muzhiyu/mu-navbar/mu-navbar.vue +223 -0
  51. package/components/muzhiyu/mu-nomore/mu-nomore.vue +107 -0
  52. package/components/muzhiyu/mu-notice-bar/mu-notice-bar.vue +284 -0
  53. package/components/muzhiyu/mu-notify/mu-notify.vue +202 -0
  54. package/components/muzhiyu/mu-overlay/mu-overlay.vue +94 -0
  55. package/components/muzhiyu/mu-pagination/mu-pagination.vue +330 -0
  56. package/components/muzhiyu/mu-password-input/mu-password-input.vue +119 -0
  57. package/components/muzhiyu/mu-picker/mu-picker.vue +297 -0
  58. package/components/muzhiyu/mu-popup/mu-popup.vue +297 -0
  59. package/components/muzhiyu/mu-progress/mu-progress.vue +156 -0
  60. package/components/muzhiyu/mu-pull-refresh/mu-pull-refresh.vue +54 -0
  61. package/components/muzhiyu/mu-qrcode/mu-qrcode.vue +340 -0
  62. package/components/muzhiyu/mu-qrcode/qrcode.js +2237 -0
  63. package/components/muzhiyu/mu-radio/mu-radio.vue +125 -0
  64. package/components/muzhiyu/mu-radio-group/mu-radio-group.vue +37 -0
  65. package/components/muzhiyu/mu-rate/mu-rate.vue +103 -0
  66. package/components/muzhiyu/mu-search/mu-search.vue +320 -0
  67. package/components/muzhiyu/mu-section/mu-section.vue +206 -0
  68. package/components/muzhiyu/mu-select/mu-select.vue +440 -0
  69. package/components/muzhiyu/mu-share-sheet/mu-share-sheet.vue +269 -0
  70. package/components/muzhiyu/mu-sidebar/mu-sidebar.vue +304 -0
  71. package/components/muzhiyu/mu-signature/mu-signature.vue +449 -0
  72. package/components/muzhiyu/mu-skeleton/mu-skeleton.vue +225 -0
  73. package/components/muzhiyu/mu-slider/mu-slider.vue +228 -0
  74. package/components/muzhiyu/mu-space/mu-space.vue +84 -0
  75. package/components/muzhiyu/mu-steps/mu-steps.vue +311 -0
  76. package/components/muzhiyu/mu-sticky/mu-sticky.vue +57 -0
  77. package/components/muzhiyu/mu-swipe-cell/mu-swipe-cell.vue +281 -0
  78. package/components/muzhiyu/mu-swiper/mu-swiper.vue +107 -0
  79. package/components/muzhiyu/mu-switch/mu-switch.vue +99 -0
  80. package/components/muzhiyu/mu-tabbar/mu-tabbar.vue +382 -0
  81. package/components/muzhiyu/mu-table/mu-table.vue +420 -0
  82. package/components/muzhiyu/mu-tabs/mu-tabs.vue +339 -0
  83. package/components/muzhiyu/mu-tag/mu-tag.vue +65 -0
  84. package/components/muzhiyu/mu-text-ellipsis/mu-text-ellipsis.vue +54 -0
  85. package/components/muzhiyu/mu-timeline/mu-timeline.vue +166 -0
  86. package/components/muzhiyu/mu-tips/mu-tips.vue +36 -0
  87. package/components/muzhiyu/mu-toast/mu-toast.vue +151 -0
  88. package/components/muzhiyu/mu-transfer/mu-transfer.vue +114 -0
  89. package/components/muzhiyu/mu-tree/mu-tree.vue +263 -0
  90. package/components/muzhiyu/mu-upload/mu-upload.vue +415 -0
  91. package/components/muzhiyu/mu-waterfall/mu-waterfall.vue +321 -0
  92. package/components/muzhiyu/mu-watermark/mu-watermark.vue +60 -0
  93. package/index.js +83 -0
  94. package/package.json +38 -0
  95. package/utils/index.js +600 -0
  96. package/utils/request.js +265 -0
@@ -0,0 +1,269 @@
1
+ <template>
2
+ <view v-if="visible" class="mu-share-sheet" @tap.stop>
3
+ <view class="mu-share-sheet__mask" :class="{ 'mu-share-sheet__mask--show': showAnim }" @tap="close"></view>
4
+ <view class="mu-share-sheet__panel" :class="{ 'mu-share-sheet__panel--show': showAnim }">
5
+ <view v-if="title" class="mu-share-sheet__header">
6
+ <text class="mu-share-sheet__title">{{ title }}</text>
7
+ </view>
8
+
9
+ <view class="mu-share-sheet__body">
10
+ <view v-for="(row, ri) in shareRows" :key="ri" class="mu-share-sheet__row">
11
+ <view
12
+ v-for="(item, idx) in row"
13
+ :key="idx"
14
+ class="mu-share-sheet__item mu-touchable-flat"
15
+ @tap="onSelect(item)"
16
+ >
17
+ <view class="mu-share-sheet__icon" :style="{ background: item.color || '#171717' }">
18
+ <!-- 图片图标 -->
19
+ <image v-if="item.img || item.image" class="mu-share-sheet__img" :src="item.img || item.image" mode="aspectFit" />
20
+ <!-- 矢量图标 -->
21
+ <mu-icon v-else-if="item.icon" :name="item.icon" :size="24" color="#ffffff" />
22
+ <!-- 单字备份图标 -->
23
+ <text v-else class="mu-share-sheet__icon-text">{{ getItemShortText(item) }}</text>
24
+ </view>
25
+ <text class="mu-share-sheet__name">{{ item.name || item.text }}</text>
26
+ </view>
27
+ </view>
28
+ </view>
29
+
30
+ <view v-if="showCancel" class="mu-share-sheet__footer mu-touchable-flat" @tap="close">
31
+ <text class="mu-share-sheet__cancel">{{ cancelText }}</text>
32
+ </view>
33
+ </view>
34
+ </view>
35
+ </template>
36
+
37
+ <script setup>
38
+ /**
39
+ * mu-share-sheet 分享面板
40
+ * @description 底部弹出式多渠道分享面板,支持矢量图标、图片图标、单字微缩图标与多行排版
41
+ * @property {boolean} show - 是否显示面板
42
+ * @property {string} title - 标题
43
+ * @property {Array} options - 分享选项集合 [{name, icon, img, color}]
44
+ * @property {boolean} showCancel - 是否显示取消按键
45
+ * @property {string} cancelText - 取消按键文本
46
+ * @property {number} colCount - 每行显示的渠道列数 (默认 4)
47
+ * @event {Function} select - 选中某个分享渠道时触发
48
+ * @event {Function} close - 面板关闭时触发
49
+ */
50
+ import { ref, computed, watch, nextTick } from 'vue'
51
+
52
+ const props = defineProps({
53
+ show: { type: Boolean, default: false },
54
+ title: { type: String, default: '分享至' },
55
+ options: {
56
+ type: Array,
57
+ default: () => [
58
+ { name: '微信好友', icon: 'message-circle', color: '#07C160' },
59
+ { name: '朋友圈', icon: 'aperture', color: '#07C160' },
60
+ { name: 'QQ 好友', icon: 'send', color: '#12B7F5' },
61
+ { name: '新浪微博', icon: 'share-2', color: '#E6162D' },
62
+ { name: '复制链接', icon: 'copy', color: '#171717' },
63
+ { name: '生成海报', icon: 'image', color: '#6366F1' }
64
+ ]
65
+ },
66
+ showCancel: { type: Boolean, default: true },
67
+ cancelText: { type: String, default: '取消' },
68
+ colCount: { type: Number, default: 4 }
69
+ })
70
+
71
+ const emit = defineEmits(['update:show', 'select', 'close'])
72
+ const visible = ref(false)
73
+ const showAnim = ref(false)
74
+
75
+ watch(() => props.show, (v) => {
76
+ if (v) {
77
+ visible.value = true
78
+ nextTick(() => { setTimeout(() => { showAnim.value = true }, 20) })
79
+ } else {
80
+ showAnim.value = false
81
+ setTimeout(() => { visible.value = false }, 300)
82
+ }
83
+ })
84
+
85
+ const shareRows = computed(() => {
86
+ const rows = []
87
+ const opts = props.options || []
88
+ for (let i = 0; i < opts.length; i += props.colCount) {
89
+ rows.push(opts.slice(i, i + props.colCount))
90
+ }
91
+ return rows
92
+ })
93
+
94
+ function getItemShortText(item) {
95
+ const str = item.name || item.text || ''
96
+ return str.charAt(0)
97
+ }
98
+
99
+ function onSelect(item) {
100
+ emit('select', item)
101
+ close()
102
+ }
103
+
104
+ function close() {
105
+ emit('update:show', false)
106
+ showAnim.value = false
107
+ setTimeout(() => {
108
+ visible.value = false
109
+ emit('close')
110
+ }, 300)
111
+ }
112
+ </script>
113
+
114
+ <style lang="scss" scoped>
115
+ @import "@/uni.scss";
116
+
117
+ .mu-share-sheet {
118
+ position: fixed;
119
+ top: 0;
120
+ left: 0;
121
+ right: 0;
122
+ bottom: 0;
123
+ z-index: $mu-z-popup;
124
+
125
+ &__mask {
126
+ position: absolute;
127
+ top: 0;
128
+ left: 0;
129
+ right: 0;
130
+ bottom: 0;
131
+ background: rgba(15, 23, 42, 0.45);
132
+ backdrop-filter: blur(8px);
133
+ opacity: 0;
134
+ transition: opacity 0.3s ease;
135
+
136
+ &--show {
137
+ opacity: 1;
138
+ }
139
+ }
140
+
141
+ &__panel {
142
+ position: absolute;
143
+ left: 0;
144
+ right: 0;
145
+ bottom: 0;
146
+ background: #FFFFFF;
147
+ border-radius: 36rpx 36rpx 0 0;
148
+ transform: translateY(100%);
149
+ transition: transform 0.3s cubic-bezier(0.25, 1, 0.5, 1);
150
+ padding-bottom: env(safe-area-inset-bottom, 0);
151
+ box-shadow: 0 -12rpx 40rpx rgba(15, 23, 42, 0.12);
152
+ overflow: hidden;
153
+
154
+ &--show {
155
+ transform: translateY(0);
156
+ }
157
+ }
158
+
159
+ &__header {
160
+ padding: 32rpx 36rpx 20rpx;
161
+ text-align: center;
162
+ border-bottom: 1rpx solid rgba(226, 232, 240, 0.7);
163
+ }
164
+
165
+ &__title {
166
+ font-size: 26rpx;
167
+ color: #64748B;
168
+ font-weight: 700;
169
+ letter-spacing: -0.3rpx;
170
+ }
171
+
172
+ &__body {
173
+ padding: 36rpx 24rpx 12rpx;
174
+ }
175
+
176
+ &__row {
177
+ display: flex;
178
+ justify-content: flex-start;
179
+ margin-bottom: 24rpx;
180
+ }
181
+
182
+ &__item {
183
+ display: flex;
184
+ flex-direction: column;
185
+ align-items: center;
186
+ width: 25%;
187
+ padding: 8rpx 0;
188
+ cursor: pointer;
189
+ }
190
+
191
+ &__icon {
192
+ width: 104rpx;
193
+ height: 104rpx;
194
+ border-radius: 28rpx;
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ margin-bottom: 14rpx;
199
+ box-shadow: 0 8rpx 20rpx rgba(15, 23, 42, 0.1);
200
+ transition: transform 0.15s ease;
201
+
202
+ &:active {
203
+ transform: scale(0.92);
204
+ }
205
+ }
206
+
207
+ &__img {
208
+ width: 52rpx;
209
+ height: 52rpx;
210
+ }
211
+
212
+ &__icon-text {
213
+ font-size: 32rpx;
214
+ color: #ffffff;
215
+ font-weight: 800;
216
+ }
217
+
218
+ &__name {
219
+ font-size: 24rpx;
220
+ color: $mu-text-primary;
221
+ font-weight: 600;
222
+ text-align: center;
223
+ }
224
+
225
+ &__footer {
226
+ padding: 28rpx 0;
227
+ border-top: 14rpx solid #F1F5F9;
228
+ text-align: center;
229
+ cursor: pointer;
230
+ background: #ffffff;
231
+
232
+ &:active {
233
+ background: rgba(99, 102, 241, 0.04);
234
+ }
235
+ }
236
+
237
+ &__cancel {
238
+ font-size: 28rpx;
239
+ color: #64748B;
240
+ font-weight: 800;
241
+ }
242
+ }
243
+
244
+ .mu-dark, page.mu-dark {
245
+
246
+ .mu-share-sheet {
247
+ &__mask { background: rgba(0, 0, 0, 0.65); }
248
+ &__panel { background: #12121A !important; }
249
+ &__header { border-color: rgba(255, 255, 255, 0.08); }
250
+ &__title { color: #94A3B8; }
251
+ &__name { color: #FFFFFF !important; }
252
+ &__footer { background: #12121A !important; border-top-color: #08080C; }
253
+ &__cancel { color: #94A3B8; }
254
+ }
255
+ }
256
+
257
+ @media (prefers-color-scheme: dark) {
258
+
259
+ .mu-share-sheet {
260
+ &__mask { background: rgba(0, 0, 0, 0.65); }
261
+ &__panel { background: #12121A !important; }
262
+ &__header { border-color: rgba(255, 255, 255, 0.08); }
263
+ &__title { color: #94A3B8; }
264
+ &__name { color: #FFFFFF !important; }
265
+ &__footer { background: #12121A !important; border-top-color: #08080C; }
266
+ &__cancel { color: #94A3B8; }
267
+ }
268
+ }
269
+ </style>
@@ -0,0 +1,304 @@
1
+ <template>
2
+ <view class="mu-sidebar" :style="{ width: formattedWidth }">
3
+ <scroll-view scroll-y class="mu-sidebar__scroll">
4
+ <view
5
+ v-for="(item, index) in options"
6
+ :key="index"
7
+ class="mu-sidebar__item"
8
+ :class="[
9
+ activeIndex === index && 'mu-sidebar__item--active',
10
+ `mu-sidebar__item--icon-${iconPosition}`
11
+ ]"
12
+ @tap="onSelect(item, index)"
13
+ >
14
+ <view
15
+ v-if="activeIndex === index"
16
+ class="mu-sidebar__indicator"
17
+ :style="{ background: indicatorColor || '#171717' }"
18
+ ></view>
19
+
20
+ <mu-badge :count="getItemBadge(item)" :dot="getItemDot(item)">
21
+ <view class="mu-sidebar__content" :class="[`mu-sidebar__content--${iconPosition}`]">
22
+ <!-- 矢量图标 -->
23
+ <mu-icon
24
+ v-if="isVectorIcon(item)"
25
+ :name="getItemIcon(item)"
26
+ :size="iconSize"
27
+ :color="index === activeIndex ? (activeColor || '#171717') : '#64748B'"
28
+ class="mu-sidebar__icon"
29
+ />
30
+ <!-- 图片图标 (如阿水/奈雪/瑞幸餐饮点餐菜单分类图标) -->
31
+ <image
32
+ v-else-if="getItemImage(item)"
33
+ class="mu-sidebar__img"
34
+ :style="{ width: `${iconSize}rpx`, height: `${iconSize}rpx` }"
35
+ :src="getItemImage(item)"
36
+ mode="aspectFit"
37
+ />
38
+
39
+ <text class="mu-sidebar__text" :style="getTextStyle(index)">
40
+ {{ getItemText(item) }}
41
+ </text>
42
+ </view>
43
+ </mu-badge>
44
+ </view>
45
+ </scroll-view>
46
+ </view>
47
+ </template>
48
+
49
+ <script setup>
50
+ /**
51
+ * mu-sidebar 侧边导航
52
+ * @description 垂直导航栏,支持矢量图标/PNG图片(上下结构/平滑凹弧线过渡)、数字徽章与双向联动
53
+ * @property {Array} options - 导航项 [{name, icon, image, badge, dot}] 或 string[]
54
+ * @property {number} active - 当前激活索引
55
+ * @property {number|string} width - 宽度 rpx
56
+ * @property {number|string} iconSize - 图标尺寸 rpx
57
+ * @property {string} iconPosition - 图标与文字相对位置 ('top' 上下结构 | 'left' 左右结构)
58
+ * @property {string} activeColor - 激活颜色
59
+ * @property {string} indicatorColor - 指示条颜色
60
+ * @event {Function} change - 切换事件 (item, index)
61
+ */
62
+ import { ref, computed, watch } from 'vue'
63
+
64
+ const props = defineProps({
65
+ options: { type: Array, default: () => [] },
66
+ active: { type: Number, default: 0 },
67
+ width: { type: [Number, String], default: 180 },
68
+ iconSize: { type: [Number, String], default: 36 },
69
+ iconPosition: { type: String, default: 'top' }, // top (默认上下展示) | left (左右展示)
70
+ activeColor: { type: String, default: '' },
71
+ indicatorColor: { type: String, default: '#171717' }
72
+ })
73
+
74
+ const emit = defineEmits(['update:active', 'change'])
75
+ const activeIndex = ref(props.active)
76
+
77
+ const formattedWidth = computed(() => {
78
+ if (typeof props.width === 'number') return `${props.width}rpx`
79
+ if (typeof props.width === 'string') {
80
+ if (props.width.endsWith('rpx') || props.width.endsWith('px')) return props.width
81
+ return `${props.width}rpx`
82
+ }
83
+ return '180rpx'
84
+ })
85
+
86
+ watch(() => props.active, (v) => { activeIndex.value = v })
87
+
88
+ function getItemText(item) {
89
+ if (typeof item === 'object' && item !== null) {
90
+ return item.name || item.title || item.label || String(item)
91
+ }
92
+ return String(item)
93
+ }
94
+
95
+ function getItemBadge(item) {
96
+ if (typeof item === 'object' && item !== null) return item.badge
97
+ return 0
98
+ }
99
+
100
+ function getItemDot(item) {
101
+ if (typeof item === 'object' && item !== null) return item.dot || false
102
+ return false
103
+ }
104
+
105
+ function getItemIcon(item) {
106
+ if (typeof item === 'object' && item !== null) return item.icon || ''
107
+ return ''
108
+ }
109
+
110
+ function getItemImage(item) {
111
+ if (typeof item === 'object' && item !== null) return item.image || item.img || ''
112
+ return ''
113
+ }
114
+
115
+ function isVectorIcon(item) {
116
+ const iconStr = getItemIcon(item)
117
+ if (!iconStr) return false
118
+ return !iconStr.includes('/') && !/\.(png|jpg|jpeg|gif|svg|webp)$/i.test(iconStr)
119
+ }
120
+
121
+ function getTextStyle(index) {
122
+ if (index === activeIndex.value && props.activeColor) {
123
+ return { color: props.activeColor }
124
+ }
125
+ return {}
126
+ }
127
+
128
+ function onSelect(item, index) {
129
+ activeIndex.value = index
130
+ emit('update:active', index)
131
+ emit('change', item, index)
132
+ }
133
+ </script>
134
+
135
+ <style lang="scss" scoped>
136
+ @import "@/uni.scss";
137
+
138
+ .mu-sidebar {
139
+ height: 100%;
140
+ background: #F1F5F9;
141
+
142
+ &__scroll {
143
+ height: 100%;
144
+ }
145
+
146
+ &__item {
147
+ position: relative;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ padding: 24rpx 12rpx;
152
+ background: #F1F5F9;
153
+ transition: all 0.2s ease;
154
+ cursor: pointer;
155
+
156
+ &--active {
157
+ background: #FFFFFF !important;
158
+ font-weight: 700;
159
+ z-index: 2;
160
+
161
+ .mu-sidebar__text {
162
+ color: #171717;
163
+ font-weight: 700;
164
+ }
165
+
166
+ /* 右侧右上角与右下角倒角弧度 (与右侧白色内容区极奢凹弧度过渡) */
167
+ &::before {
168
+ content: '';
169
+ position: absolute;
170
+ top: -24rpx;
171
+ right: 0;
172
+ width: 24rpx;
173
+ height: 24rpx;
174
+ background: transparent;
175
+ border-bottom-right-radius: 24rpx;
176
+ box-shadow: 8rpx 8rpx 0 8rpx #FFFFFF;
177
+ pointer-events: none;
178
+ z-index: 2;
179
+ }
180
+
181
+ &::after {
182
+ content: '';
183
+ position: absolute;
184
+ bottom: -24rpx;
185
+ right: 0;
186
+ width: 24rpx;
187
+ height: 24rpx;
188
+ background: transparent;
189
+ border-top-right-radius: 24rpx;
190
+ box-shadow: 8rpx -8rpx 0 8rpx #FFFFFF;
191
+ pointer-events: none;
192
+ z-index: 2;
193
+ }
194
+ }
195
+ }
196
+
197
+ &__indicator {
198
+ position: absolute;
199
+ left: 0;
200
+ top: 50%;
201
+ transform: translateY(-50%);
202
+ width: 6rpx;
203
+ height: 36rpx;
204
+ border-radius: 0 6rpx 6rpx 0;
205
+ z-index: 3;
206
+ }
207
+
208
+ &__content {
209
+ display: flex;
210
+ align-items: center;
211
+ justify-content: center;
212
+
213
+ &--top {
214
+ flex-direction: column;
215
+ gap: 8rpx;
216
+ }
217
+
218
+ &--left {
219
+ flex-direction: row;
220
+ gap: 10rpx;
221
+ }
222
+ }
223
+
224
+ &__icon {
225
+ flex-shrink: 0;
226
+ }
227
+
228
+ &__img {
229
+ flex-shrink: 0;
230
+ display: block;
231
+ }
232
+
233
+ &__text {
234
+ font-size: 24rpx;
235
+ color: #64748B;
236
+ text-align: center;
237
+ line-height: 1.3;
238
+ }
239
+ }
240
+
241
+ .mu-dark, page.mu-dark {
242
+
243
+ .mu-sidebar {
244
+ background: #0D0D14 !important;
245
+
246
+ &__item {
247
+ background: #0D0D14 !important;
248
+
249
+ &--active {
250
+ background: #181824 !important;
251
+
252
+ &::before {
253
+ box-shadow: 8rpx 8rpx 0 8rpx #181824 !important;
254
+ }
255
+
256
+ &::after {
257
+ box-shadow: 8rpx -8rpx 0 8rpx #181824 !important;
258
+ }
259
+
260
+ .mu-sidebar__text {
261
+ color: #FFFFFF !important;
262
+ font-weight: 700;
263
+ }
264
+ }
265
+ }
266
+
267
+ &__text {
268
+ color: #94A3B8;
269
+ }
270
+ }
271
+ }
272
+
273
+ @media (prefers-color-scheme: dark) {
274
+
275
+ .mu-sidebar {
276
+ background: #0D0D14 !important;
277
+
278
+ &__item {
279
+ background: #0D0D14 !important;
280
+
281
+ &--active {
282
+ background: #181824 !important;
283
+
284
+ &::before {
285
+ box-shadow: 8rpx 8rpx 0 8rpx #181824 !important;
286
+ }
287
+
288
+ &::after {
289
+ box-shadow: 8rpx -8rpx 0 8rpx #181824 !important;
290
+ }
291
+
292
+ .mu-sidebar__text {
293
+ color: #FFFFFF !important;
294
+ font-weight: 700;
295
+ }
296
+ }
297
+ }
298
+
299
+ &__text {
300
+ color: #94A3B8;
301
+ }
302
+ }
303
+ }
304
+ </style>