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,206 @@
1
+ <template>
2
+ <view class="mu-section" :style="{ marginTop: formattedMarginTop }">
3
+ <!-- 标头区域 -->
4
+ <view class="mu-section__header" :style="{ padding }" @tap="handleHeaderClick">
5
+ <!-- 左侧装饰竖线 / 极光的 Pill / 图标 -->
6
+ <view
7
+ v-if="type === 'line' && showLine"
8
+ class="mu-section__line"
9
+ :style="lineStyle"
10
+ ></view>
11
+
12
+ <view v-else-if="type === 'pill'" class="mu-section__pill-dot" :style="pillStyle"></view>
13
+
14
+ <view v-if="icon" class="mu-section__icon">
15
+ <slot name="icon">
16
+ <mu-icon :name="icon" :size="iconSize" :color="iconColor || '#171717'" />
17
+ </slot>
18
+ </view>
19
+
20
+ <!-- 标题与副描述 -->
21
+ <view class="mu-section__title-wrap">
22
+ <text class="mu-section__title" :style="titleStyle">{{ title }}</text>
23
+ <text v-if="desc" class="mu-section__desc">{{ desc }}</text>
24
+ </view>
25
+
26
+ <!-- 右侧更多 / 操作按钮插槽 -->
27
+ <view v-if="rightText || arrow || $slots.right" class="mu-section__right mu-touchable-flat" @tap.stop="handleRightClick">
28
+ <slot name="right">
29
+ <text class="mu-section__right-text">{{ rightText }}</text>
30
+ <mu-icon v-if="arrow" name="chevron_right" :size="14" color="#94A3B8" style="margin-left: 4rpx;" />
31
+ </slot>
32
+ </view>
33
+ </view>
34
+
35
+ <!-- 板块内容主体 -->
36
+ <view v-if="$slots.default" class="mu-section__body">
37
+ <slot></slot>
38
+ </view>
39
+ </view>
40
+ </template>
41
+
42
+ <script setup>
43
+ import { computed } from 'vue'
44
+
45
+ const props = defineProps({
46
+ title: { type: String, default: '' },
47
+ desc: { type: String, default: '' },
48
+ rightText: { type: String, default: '' },
49
+ arrow: { type: Boolean, default: false }, // 右侧是否带右箭头
50
+ type: { type: String, default: 'line' }, // line (左侧竖条) | pill (圆点) | plain (无装饰)
51
+ showLine: { type: Boolean, default: true },
52
+ lineColor: { type: String, default: '' },
53
+ icon: { type: String, default: '' },
54
+ iconSize: { type: [Number, String], default: 20 },
55
+ iconColor: { type: String, default: '' },
56
+ padding: { type: String, default: '20rpx 0' },
57
+ marginTop: { type: [Number, String], default: '0' },
58
+ titleColor: { type: String, default: '' },
59
+ titleSize: { type: [Number, String], default: '' },
60
+ bold: { type: Boolean, default: true }
61
+ })
62
+
63
+ const emit = defineEmits(['click', 'click-right'])
64
+
65
+ const formattedMarginTop = computed(() => {
66
+ if (typeof props.marginTop === 'number') return `${props.marginTop}rpx`
67
+ if (typeof props.marginTop === 'string' && props.marginTop) {
68
+ return props.marginTop.includes('rpx') || props.marginTop.includes('px') ? props.marginTop : `${props.marginTop}rpx`
69
+ }
70
+ return '0'
71
+ })
72
+
73
+ const lineStyle = computed(() => {
74
+ if (props.lineColor) {
75
+ return { background: props.lineColor }
76
+ }
77
+ return { background: '#171717' }
78
+ })
79
+
80
+ const pillStyle = computed(() => {
81
+ if (props.lineColor) {
82
+ return { background: props.lineColor }
83
+ }
84
+ return { background: 'linear-gradient(135deg, #171717, #EC4899)' }
85
+ })
86
+
87
+ const titleStyle = computed(() => {
88
+ const style = {
89
+ fontWeight: props.bold ? '800' : '600'
90
+ }
91
+ if (props.titleColor) style.color = props.titleColor
92
+ if (props.titleSize) {
93
+ style.fontSize = typeof props.titleSize === 'number' ? `${props.titleSize}rpx` : props.titleSize
94
+ }
95
+ return style
96
+ })
97
+
98
+ function handleHeaderClick(e) {
99
+ emit('click', e)
100
+ }
101
+
102
+ function handleRightClick(e) {
103
+ emit('click-right', e)
104
+ }
105
+ </script>
106
+
107
+ <style lang="scss" scoped>
108
+ @import "@/uni.scss";
109
+
110
+ .mu-section {
111
+ width: 100%;
112
+ box-sizing: border-box;
113
+
114
+ &__header {
115
+ display: flex;
116
+ align-items: center;
117
+ position: relative;
118
+ width: 100%;
119
+ box-sizing: border-box;
120
+ }
121
+
122
+ &__line {
123
+ width: 8rpx;
124
+ height: 32rpx;
125
+ border-radius: 4rpx;
126
+ margin-right: 16rpx;
127
+ flex-shrink: 0;
128
+ }
129
+
130
+ &__pill-dot {
131
+ width: 16rpx;
132
+ height: 16rpx;
133
+ border-radius: 50%;
134
+ margin-right: 16rpx;
135
+ flex-shrink: 0;
136
+ box-shadow: 0 0 12rpx rgba(99, 102, 241, 0.4);
137
+ }
138
+
139
+ &__icon {
140
+ margin-right: 14rpx;
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: center;
144
+ flex-shrink: 0;
145
+ }
146
+
147
+ &__title-wrap {
148
+ flex: 1;
149
+ min-width: 0;
150
+ display: flex;
151
+ align-items: baseline;
152
+ gap: 16rpx;
153
+ }
154
+
155
+ &__title {
156
+ font-size: 32rpx;
157
+ color: $mu-text-primary;
158
+ letter-spacing: -0.5rpx;
159
+ line-height: 1.3;
160
+ }
161
+
162
+ &__desc {
163
+ font-size: 22rpx;
164
+ color: #94A3B8;
165
+ font-weight: 500;
166
+ line-height: 1.3;
167
+ }
168
+
169
+ &__right {
170
+ margin-left: 20rpx;
171
+ display: flex;
172
+ align-items: center;
173
+ cursor: pointer;
174
+ flex-shrink: 0;
175
+
176
+ &-text {
177
+ font-size: 24rpx;
178
+ color: #64748B;
179
+ font-weight: 600;
180
+ }
181
+ }
182
+
183
+ &__body {
184
+ width: 100%;
185
+ box-sizing: border-box;
186
+ }
187
+ }
188
+
189
+ .mu-dark, page.mu-dark {
190
+
191
+ .mu-section {
192
+ &__title { color: $mu-dark-text-primary; }
193
+ &__desc { color: $mu-dark-text-secondary; }
194
+ &__right-text { color: $mu-dark-text-secondary; }
195
+ }
196
+ }
197
+
198
+ @media (prefers-color-scheme: dark) {
199
+
200
+ .mu-section {
201
+ &__title { color: $mu-dark-text-primary; }
202
+ &__desc { color: $mu-dark-text-secondary; }
203
+ &__right-text { color: $mu-dark-text-secondary; }
204
+ }
205
+ }
206
+ </style>
@@ -0,0 +1,440 @@
1
+ <template>
2
+ <view class="mu-select" :class="[
3
+ `mu-select--${shape}`,
4
+ `mu-select--label-${labelPosition}`,
5
+ disabled && 'mu-select--disabled',
6
+ error && 'mu-select--error',
7
+ filled && 'mu-select--filled'
8
+ ]">
9
+ <!-- 标题 Label (包含必填红星与位置布局) -->
10
+ <view v-if="label || $slots.label" class="mu-select__label-box" :style="labelBoxStyle">
11
+ <text v-if="required" class="mu-select__required">*</text>
12
+ <slot name="label">
13
+ <text class="mu-select__label-text">{{ label }}</text>
14
+ </slot>
15
+ </view>
16
+
17
+ <!-- 下拉框主容器 Main Box -->
18
+ <view class="mu-select__main">
19
+ <view class="mu-select__wrap" @tap="toggleOpen">
20
+ <!-- 前缀图标与插槽 -->
21
+ <view v-if="prefixIcon || $slots.prefix" class="mu-select__prefix">
22
+ <slot name="prefix">
23
+ <mu-icon :name="prefixIcon" :size="16" color="#94A3B8" />
24
+ </slot>
25
+ </view>
26
+
27
+ <!-- 选中文本或 Placeholder -->
28
+ <text class="mu-select__text" :class="{ 'mu-select__text--placeholder': !selectedLabel }">
29
+ {{ selectedLabel || placeholder }}
30
+ </text>
31
+
32
+ <!-- 清除按钮 -->
33
+ <view v-if="clearable && selectedLabel" class="mu-select__clear" @tap.stop="onClear">
34
+ <mu-icon name="close" :size="12" color="#94A3B8" />
35
+ </view>
36
+
37
+ <!-- 右侧下拉箭头图标 -->
38
+ <view class="mu-select__arrow" :class="{ 'mu-select__arrow--active': isPickerOpen }">
39
+ <mu-icon name="chevron_down" :size="16" color="#94A3B8" />
40
+ </view>
41
+ </view>
42
+
43
+ <!-- 错误提示文本 -->
44
+ <text v-if="error" class="mu-select__error">{{ errorMessage }}</text>
45
+ </view>
46
+
47
+ <!-- 移动端底栏弹出选项 ActionSheet 面板 -->
48
+ <view v-if="isPickerOpen" class="mu-select__popup" @tap="closePicker">
49
+ <view class="mu-select__mask"></view>
50
+ <view class="mu-select__panel" @tap.stop>
51
+ <view class="mu-select__header">
52
+ <text class="mu-select__title">{{ title || label || '请选择' }}</text>
53
+ <view class="mu-select__close-icon" @tap="closePicker">
54
+ <mu-icon name="close" :size="16" color="#64748B" />
55
+ </view>
56
+ </view>
57
+
58
+ <!-- 隐藏硬边原生滚动条的平滑选项 Scroll 列表 -->
59
+ <scroll-view scroll-y :show-scrollbar="false" class="mu-select__options">
60
+ <view
61
+ v-for="(item, index) in options"
62
+ :key="index"
63
+ class="mu-select__option mu-touchable-flat"
64
+ :class="{
65
+ 'mu-select__option--active': isSelected(item),
66
+ 'mu-select__option--disabled': item.disabled
67
+ }"
68
+ @tap="handleSelectOption(item)"
69
+ >
70
+ <text class="mu-select__option-text">{{ getItemLabel(item) }}</text>
71
+ <mu-icon v-if="isSelected(item)" name="check" :size="16" color="#171717" />
72
+ </view>
73
+ </scroll-view>
74
+ </view>
75
+ </view>
76
+ </view>
77
+ </template>
78
+
79
+ <script setup>
80
+ import { ref, computed } from 'vue'
81
+
82
+ const props = defineProps({
83
+ modelValue: { type: [String, Number, Boolean], default: '' },
84
+ options: { type: Array, default: () => [] }, // 选项列表 [{ label: '苹果', value: 'apple' }] 或 ['苹果', '香蕉']
85
+ labelKey: { type: String, default: 'label' },
86
+ valueKey: { type: String, default: 'value' },
87
+ shape: { type: String, default: 'radius' }, // square (微直角) | radius (圆角) | round (全圆胶囊)
88
+ filled: { type: Boolean, default: false }, // 背景填充模式
89
+ label: { type: String, default: '' },
90
+ title: { type: String, default: '' },
91
+ labelPosition: { type: String, default: 'top' }, // top | left
92
+ labelWidth: { type: String, default: '' },
93
+ required: { type: Boolean, default: false },
94
+ placeholder: { type: String, default: '请选择' },
95
+ disabled: { type: Boolean, default: false },
96
+ clearable: { type: Boolean, default: false },
97
+ error: { type: Boolean, default: false },
98
+ errorMessage: { type: String, default: '' },
99
+ prefixIcon: { type: String, default: '' }
100
+ })
101
+
102
+ const emit = defineEmits(['update:modelValue', 'change', 'clear'])
103
+
104
+ const isPickerOpen = ref(false)
105
+
106
+ const labelBoxStyle = computed(() => {
107
+ if (props.labelPosition === 'left' && props.labelWidth) {
108
+ return { width: props.labelWidth }
109
+ }
110
+ return {}
111
+ })
112
+
113
+ function getItemLabel(item) {
114
+ if (typeof item === 'object' && item !== null) {
115
+ return (item[props.labelKey] !== undefined ? item[props.labelKey] : (item.label !== undefined ? item.label : ''))
116
+ }
117
+ return item
118
+ }
119
+
120
+ function getItemValue(item) {
121
+ if (typeof item === 'object' && item !== null) {
122
+ return (item[props.valueKey] !== undefined ? item[props.valueKey] : (item.value !== undefined ? item.value : item))
123
+ }
124
+ return item
125
+ }
126
+
127
+ const selectedLabel = computed(() => {
128
+ if (props.modelValue === '' || props.modelValue === null || props.modelValue === undefined) {
129
+ return ''
130
+ }
131
+ const target = props.options.find(item => getItemValue(item) === props.modelValue)
132
+ if (target) return getItemLabel(target)
133
+ return String(props.modelValue)
134
+ })
135
+
136
+ function isSelected(item) {
137
+ return getItemValue(item) === props.modelValue
138
+ }
139
+
140
+ function toggleOpen() {
141
+ if (props.disabled) return
142
+ isPickerOpen.value = !isPickerOpen.value
143
+ }
144
+
145
+ function closePicker() {
146
+ isPickerOpen.value = false
147
+ }
148
+
149
+ function handleSelectOption(item) {
150
+ if (item.disabled) return
151
+ const val = getItemValue(item)
152
+ emit('update:modelValue', val)
153
+ emit('change', val, item)
154
+ closePicker()
155
+ }
156
+
157
+ function onClear() {
158
+ emit('update:modelValue', '')
159
+ emit('clear')
160
+ }
161
+ </script>
162
+
163
+ <style lang="scss" scoped>
164
+ @import "@/uni.scss";
165
+
166
+ .mu-select {
167
+ margin-bottom: 24rpx;
168
+
169
+ &--disabled { opacity: $mu-opacity-disabled; }
170
+ &--error {
171
+ .mu-select__wrap {
172
+ border-color: $mu-error;
173
+ box-shadow: 0 0 14rpx rgba(244, 63, 94, 0.2);
174
+ }
175
+ }
176
+
177
+ /* Label 布局配置 */
178
+ &--label-top {
179
+ display: flex;
180
+ flex-direction: column;
181
+ }
182
+
183
+ &--label-left {
184
+ display: flex;
185
+ align-items: center;
186
+ .mu-select__label-box {
187
+ margin-bottom: 0;
188
+ margin-right: 20rpx;
189
+ flex-shrink: 0;
190
+ width: 140rpx;
191
+ }
192
+ .mu-select__main {
193
+ flex: 1;
194
+ min-width: 0;
195
+ }
196
+ }
197
+
198
+ &__label-box {
199
+ display: flex;
200
+ align-items: center;
201
+ margin-bottom: 12rpx;
202
+ }
203
+
204
+ &__required {
205
+ color: #F43F5E;
206
+ font-size: 26rpx;
207
+ font-weight: 800;
208
+ margin-right: 6rpx;
209
+ line-height: 1;
210
+ }
211
+
212
+ &__label-text {
213
+ font-size: 26rpx;
214
+ color: $mu-text-primary;
215
+ font-weight: 700;
216
+ line-height: 1.4;
217
+ }
218
+
219
+ &__main {
220
+ width: 100%;
221
+ }
222
+
223
+ &__wrap {
224
+ display: flex;
225
+ align-items: center;
226
+ border: 1rpx solid $mu-border;
227
+ padding: 0 20rpx;
228
+ height: 68rpx;
229
+ background: #ffffff;
230
+ transition: all $mu-duration $mu-ease;
231
+ cursor: pointer;
232
+ box-sizing: border-box;
233
+ }
234
+
235
+ /* 填充背景模式 (:filled="true") */
236
+ &--filled &__wrap {
237
+ background: rgba(241, 245, 249, 0.6);
238
+ border-color: transparent;
239
+ }
240
+
241
+ /* 形态定义 (方形 / 柔和圆角 / 全圆胶囊) */
242
+ &--square &__wrap {
243
+ border-radius: 6rpx;
244
+ }
245
+ &--radius &__wrap {
246
+ border-radius: 12rpx;
247
+ }
248
+ &--round &__wrap {
249
+ border-radius: 999rpx;
250
+ padding: 0 28rpx;
251
+ }
252
+
253
+ &__prefix {
254
+ margin-right: 16rpx;
255
+ display: flex;
256
+ align-items: center;
257
+ flex-shrink: 0;
258
+ }
259
+
260
+ &__text {
261
+ flex: 1;
262
+ font-size: 26rpx;
263
+ color: $mu-text-primary;
264
+ font-weight: 500;
265
+
266
+ &--placeholder {
267
+ color: #94A3B8;
268
+ font-weight: 400;
269
+ }
270
+ }
271
+
272
+ &__clear {
273
+ width: 32rpx;
274
+ height: 32rpx;
275
+ border-radius: 50%;
276
+ background: rgba(148, 163, 184, 0.15);
277
+ display: flex;
278
+ align-items: center;
279
+ justify-content: center;
280
+ cursor: pointer;
281
+ margin-left: 12rpx;
282
+ flex-shrink: 0;
283
+ }
284
+
285
+ &__arrow {
286
+ margin-left: 12rpx;
287
+ display: flex;
288
+ align-items: center;
289
+ justify-content: center;
290
+ transition: transform 0.25s $mu-ease;
291
+ flex-shrink: 0;
292
+
293
+ &--active {
294
+ transform: rotate(180deg);
295
+ }
296
+ }
297
+
298
+ &__error {
299
+ font-size: 22rpx;
300
+ color: $mu-error;
301
+ margin-top: 8rpx;
302
+ display: block;
303
+ }
304
+
305
+ /* 弹出选项 ActionSheet */
306
+ &__popup {
307
+ position: fixed;
308
+ top: 0;
309
+ left: 0;
310
+ right: 0;
311
+ bottom: 0;
312
+ width: 100vw;
313
+ height: 100vh;
314
+ z-index: $mu-z-modal;
315
+ display: flex;
316
+ flex-direction: column;
317
+ justify-content: flex-end;
318
+ }
319
+
320
+ &__mask {
321
+ position: absolute;
322
+ top: 0;
323
+ left: 0;
324
+ right: 0;
325
+ bottom: 0;
326
+ background: rgba(15, 23, 42, 0.6);
327
+ backdrop-filter: none !important;
328
+ }
329
+
330
+ &__panel {
331
+ position: relative;
332
+ z-index: 10;
333
+ background: #FFFFFF;
334
+ border-radius: 32rpx 32rpx 0 0;
335
+ max-height: 65vh;
336
+ display: flex;
337
+ flex-direction: column;
338
+ backdrop-filter: none !important;
339
+ /* 平滑减速滑动,彻底消除向上回弹弹跳动效 */
340
+ animation: mu-slide-up 0.28s cubic-bezier(0.25, 1, 0.5, 1);
341
+ }
342
+
343
+ &__header {
344
+ padding: 32rpx 36rpx 20rpx;
345
+ display: flex;
346
+ align-items: center;
347
+ justify-content: space-between;
348
+ border-bottom: 1rpx solid rgba(241, 245, 249, 0.9);
349
+ }
350
+
351
+ &__title {
352
+ font-size: 32rpx;
353
+ font-weight: 800;
354
+ color: $mu-text-primary;
355
+ }
356
+
357
+ &__close-icon {
358
+ padding: 8rpx;
359
+ cursor: pointer;
360
+ }
361
+
362
+ &__options {
363
+ max-height: 540rpx;
364
+ padding: 12rpx 0 32rpx;
365
+ }
366
+
367
+ &__option {
368
+ padding: 28rpx 36rpx;
369
+ display: flex;
370
+ align-items: center;
371
+ justify-content: space-between;
372
+ transition: background 0.15s ease;
373
+
374
+ &:active {
375
+ background: rgba(241, 245, 249, 0.8);
376
+ }
377
+
378
+ &--active {
379
+ .mu-select__option-text {
380
+ color: $mu-primary;
381
+ font-weight: 800;
382
+ }
383
+ }
384
+
385
+ &--disabled {
386
+ opacity: 0.4;
387
+ pointer-events: none;
388
+ }
389
+
390
+ &-text {
391
+ font-size: 28rpx;
392
+ color: $mu-text-primary;
393
+ font-weight: 500;
394
+ }
395
+ }
396
+ }
397
+
398
+ @keyframes mu-slide-up {
399
+ from { transform: translateY(100%); }
400
+ to { transform: translateY(0); }
401
+ }
402
+
403
+ .mu-dark, page.mu-dark {
404
+
405
+ .mu-select {
406
+ &__label-text { color: $mu-dark-text-primary; }
407
+ &__wrap {
408
+ background: rgba(255, 255, 255, 0.04);
409
+ border-color: $mu-dark-border;
410
+ }
411
+ &__text { color: $mu-dark-text-primary; }
412
+ &__panel {
413
+ background: #14141E !important;
414
+ border-top: 1rpx solid rgba(255, 255, 255, 0.1);
415
+ }
416
+ &__header { border-bottom-color: rgba(255, 255, 255, 0.06); }
417
+ &__title { color: $mu-dark-text-primary; }
418
+ &__option-text { color: $mu-dark-text-primary; }
419
+ }
420
+ }
421
+
422
+ @media (prefers-color-scheme: dark) {
423
+
424
+ .mu-select {
425
+ &__label-text { color: $mu-dark-text-primary; }
426
+ &__wrap {
427
+ background: rgba(255, 255, 255, 0.04);
428
+ border-color: $mu-dark-border;
429
+ }
430
+ &__text { color: $mu-dark-text-primary; }
431
+ &__panel {
432
+ background: #14141E !important;
433
+ border-top: 1rpx solid rgba(255, 255, 255, 0.1);
434
+ }
435
+ &__header { border-bottom-color: rgba(255, 255, 255, 0.06); }
436
+ &__title { color: $mu-dark-text-primary; }
437
+ &__option-text { color: $mu-dark-text-primary; }
438
+ }
439
+ }
440
+ </style>